Engines
spicelab abstracts SPICE engines behind a small orchestrator. You provide
a circuit plus one or more AnalysisSpecs; the library takes care of invoking
the chosen engine, collecting artefacts, and normalising the output.
Selecting an engine
from spicelab.core.types import AnalysisSpec
from spicelab.engines import run_simulation
tran = AnalysisSpec("tran", {"tstep": 1e-6, "tstop": 1e-3})
handle = run_simulation(circuit, [tran], engine="ngspice")
print(handle.dataset().data_vars)
engine accepts "ngspice", "ltspice", "xyce" (or the explicit *-cli
aliases). For lower-level access, call get_simulator(name).
Command-line examples honour the --engine flag and the SPICELAB_ENGINE
environment variable.
Binary discovery
The CLI adapters search the PATH and fall back to environment variables:
| Engine | Environment variable |
|---|---|
| NGSpice | SPICELAB_NGSPICE |
| LTspice | SPICELAB_LTSPICE or LTSPICE_EXE |
| Xyce | SPICELAB_XYCE |
Set the variable to the absolute path of the executable when auto-discovery
fails. Missing binaries raise EngineBinaryNotFound with install hints.
Ngspice shared backend & callbacks
NgSpiceSharedSimulator loads the libngspice dynamic library to stream
transient data back into Python (on_tran_point) and to drive external sources
from user code. Configure it via:
- install the shared library (e.g.
brew install libngspiceorsudo apt install libngspice0-dev), - export
SPICELAB_NGSPICE_SHAREDto the.so/.dylib/.dllpath, and - use
NgSpiceSharedSimulator()directly orrun_simulation(..., engine="ngspice-shared").
The shared adapter is optimised for per-point control loops. On an M3 Pro laptop
the closed-loop example (examples/closed_loop.py) completes ~2 000 transient
steps with callbacks in ≈32 ms (~16 µs per step); your numbers will vary with
platform, circuit size, and callback complexity. When you need higher
throughput—and can tolerate the lack of fine-grained feedback—fall back to the
process adapter (engine="ngspice"), which still supports batching, sweeps,
and caching but runs headless without callbacks.
Tip: keep AnalysisSpec.tstep as large as the control loop allows and perform
vectorised work inside the callback to reduce cross-language overhead.
Output formats
| Engine | Output | Notes |
|---|---|---|
| NGSpice | ASCII RAW | Control block forces ASCII. |
| LTspice | ASCII RAW | The adapter passes -b and discovers the generated RAW/log files. |
| Xyce | PRN / CSV | Parsed into canonical xarray datasets. |
handle.dataset() always returns an xarray.Dataset with canonical coordinates
(time, freq, optional step) and signal names (V(node), I(element)).
Parallelism & caching
- pass
workers>1torun_simulation(orrun_value_sweep/run_param_grid/monte_carlo) to enable thread pools. - set
cache_dirto a persistent location to reuse hashed job results across runs.
Troubleshooting
- Binary not found – install the engine and/or set the environment variable.
- LTspice still writes binary RAW – update to the latest LTspice build; on macOS the CLI always emits ASCII.
- xarray missing – install optional dependency (
pip install xarray).