# Sweeps, Corners, and Monte Carlo After a single simulation is stable, use Monata to run structured exploration: parameter sweeps, PVT corners, and statistical variation. ## Parameter Sweeps `ParameterSweep` creates one `SimTask` per parameter value. ```python from monata.sim.core import ParameterSweep, TranSpec sweep = ParameterSweep( circuit, TranSpec(stop=10e-9), output_names=["out"], ) sweep.sweep("w_p", [0.5e-6, 1e-6, 2e-6, 4e-6]) results = sweep.run() values = results.values() delays = results.extract(propagation_delay) ``` Use one-dimensional sweeps for early sensitivity checks. Use two-dimensional sweeps when you need an interaction map between two variables. ```python sweep.sweep("w_p", [0.5e-6, 1e-6], param2="w_n", values2=[0.25e-6, 0.5e-6]) results = sweep.run() result = results.result_at(1e-6, 0.5e-6) ``` `ParameterSweep` is a mutable builder. Calling `sweep()` again replaces the previous sweep definition, including clearing a previous second axis when the new sweep is one-dimensional. ## Corners `CornerMatrix` expands temperatures, voltages, and model corners into a list of simulation tasks. ```python from monata.sim.core import CornerMatrix, TranSpec corners = CornerMatrix(circuit, TranSpec(stop=10e-9), output_names=["out"]) corners.add_temperatures(-40, 27, 125) corners.add_model_corners( tt="models/tt.lib", ss="models/ss.lib", ff="models/ff.lib", ) corner_results = corners.run() ``` For the native ngspice backend, temperature corners emit `.temp`, model corners emit `.include` for the selected model file, and voltage corners mutate matching voltage sources through `source.V` overrides. Process/model-deck corners need a concrete model file or techlib projection; otherwise the backend fails explicitly with `metadata["reason"] == "unsupported_corner"`. Use specs to summarize corners instead of manually inspecting every waveform. ```python table = specs.evaluate_all(corner_results) worst_corner, worst_delay = specs.worst_corner("tpd", corner_results) ``` ## Monte Carlo Monte Carlo analysis is for statistical variation. Use it after nominal and corner behavior are understood. Typical Monte Carlo flow: 1. Define variations for device or process parameters. 2. Generate repeated simulation tasks. 3. Evaluate the same metric for every result. 4. Summarize yield, histogram, and worst-case behavior. `MonteCarlo.run()` builds one `SimTask` per sample and submits the batch through the executor. Seeded Monte Carlo runs are reproducible. `add_mismatch()` is not implemented in the current milestone and raises `NotImplementedError` instead of silently ignoring mismatch input. ## Execution Guidance Sweeps and corners can create many independent tasks. Use `LocalExecutor` with an explicit worker count when running locally: ```python from monata.sim.core import LocalExecutor executor = LocalExecutor(max_workers=8) corner_results = corners.run(executor=executor) ``` Keep the first run small. Expand the matrix only after the metric functions and backend configuration are proven.