Circuit Overview and First Workflow
Circuit-domain preparation workflows from netlist or spectrum inputs into Builder-ready artifacts.
Use this chapter when the starting point is a circuit description rather than Builder-ready frequency-response or impulse-response data. It establishes the Circuit-to-Runtime boundary and the shortest supported first workflow. Detailed authoring, API, solver, format, and element contracts continue in separate canonical chapters.
Purpose
Use Circuit SDK to compile circuit-domain inputs into TDSE-ready matrices, series waveforms, probes, region definitions, and high-level workflow outputs. It is the bridge from netlists, RAW files, and NPORT references into Builder and Runtime workflows.
Circuit SDK is the product-facing circuit workflow and execution surface. ModelSpace is the underlying data, package, study, result, and evidence core used by promoted Circuit SDK workflows. Historical retired product names are archive-only and are not part of active release, tool, or customer-facing surfaces.
Prerequisites
- A built
tdseCLI or linked Circuit SDK library. - A SPICE-like netlist, RAW file, or NBM manifest.
- A known port list such as
1,0or1,0;2,0.
5-Minute Path
tdse circuit matrix --netlist-kind text --netlist "R1 1 0 50" --matrix y --ports 1,0 --w0 0 --dw 100 --nfreq 3 --out-data y.csv --json-out -
Expected Output Sample:
circuit matrix: success
resolved_port_count=1
out-data=y.csv
Production Path
For production use, compile once and reuse the handle when embedding through C
or C++; archive diagnostics JSON, resolved ports, grid settings, and any
manifest SHA. Prefer workflow APIs when the desired output is a .pack, and
drop to compile/compute APIs when you need intermediate matrices or probes.
Related Docs
Read this chapter in three passes if you need to:
- get one common task working from the CLI
- embed the circuit through the C API
- tune advanced behavior such as solver policy, planning, or performance
Start with the shortest supported path that matches your question. If your goal
is a qualified .pack with minimal glue, jump to the workflow path first. If
your goal is circuit visibility, start with the CLI matrix / probe flows. Drop
to the lower-level C API only when you need explicit phase control or
intermediate artifacts.
For most integrations, Circuit SDK falls into one of these roles:
| Integration goal | Recommended starting surface |
|---|---|
netlist or RAW -> .pack as fast as possible | workflow API |
| inspect matrices or probes before building a pack | CLI matrix / probe path |
| embed circuit compilation and sweeps inside host code | compile-then-compute C API |
What Circuit SDK Owns
Imagine you have a circuit - maybe a SPICE netlist from your PDK, maybe a PSS/E RAW case from a grid study, maybe a custom deck with frequency-dependent NPORT elements. You need to get that circuit into TDSE so Builder can produce a runtime pack. But Builder doesn't understand circuits. It understands frequency-domain matrices and time-domain source waveforms.
Circuit SDK bridges that gap. It takes circuit descriptions, compiles them into a solvable form, and produces the outputs Builder needs: Y and Z matrices over frequency, VOC and ISC time sequences, and probe data for validation. It also handles RAW import - converting PSS/E power-system cases into circuit netlists.
Circuit Input Circuit SDK Builder Runtime
(netlist, RAW) -> Y/Z, VOC/ISC, -> .pack file -> step loop
probe outputs
The separation between layers is deliberate:
-
Circuit SDK owns circuit parsing, solve orchestration, and circuit-domain validation. It knows about nodes, branches, and MNA stamping. It may orchestrate a Builder handoff and pack generation, but it does not own Runtime Pack semantics or the Runtime lifecycle.
-
Builder converts validated frequency-domain data into a runtime pack. It knows about rational fitting and passivity enforcement. It does not know about circuits.
-
Runtime executes the pack against a host solver. It knows about time stepping and conductance matrices. It does not know about circuits or fitting.
This layering means you can swap any piece independently. Use a different circuit tool to produce Y matrices? Feed them directly to Builder. Want to use the circuit solver without Builder? Circuit SDK's probe and series commands give you standalone access.
When to Use It
You should reach for Circuit SDK when your source data begins as:
- A SPICE-like netlist (
.cir,.sp, or text) - A PSS/E RAW case file that needs conversion
- A circuit deck containing
NPORTelements that reference Touchstone files (.ynp,.znp,.y2p,.s2p, etc.)
The typical workflow is: compile a netlist, run one or more compute operations, then hand the results to Builder. But you can also use Circuit SDK standalone - for circuit validation, for exploring frequency response, or for generating probe data.
What It Produces
Every Circuit SDK operation falls into one of these categories:
-
Frequency-domain matrices:
Y(jomega)orZ(jomega)over a user-specified frequency grid. These are the primary input to Builder'sh_from_spectrum. -
Source-side time sequences: Open-circuit voltage (
VOC) or short-circuit current (ISC) waveforms. These define the Norton/Thevenin equivalents that drive the TDSE model in a host solver. -
Probe outputs: Internal node voltages or branch currents, in either AC (frequency sweep) or transient (time-domain) form. Probes let you inspect what's happening inside the circuit without extracting full port matrices.
-
Diagnostics: Structured data describing parser behavior, solver backend selection, matrix conditioning, and policy decisions. Every result struct carries a diagnostics block.
Header Map
Most users only need tdse/circuit.h. Pull in narrower headers only when you are using those features directly:
| Header | Purpose |
|---|---|
tdse/circuit.h | Umbrella include - pulls in everything |
tdse/circuit/common.h | Handle lifecycle, error codes, core data types |
tdse/circuit/compile.h | Netlist compilation, compiled info queries |
tdse/circuit/compute.h | Matrix sweeps, port series, probes, region preparation |
tdse/circuit/raw.h | RAW import and conversion (PSS/E ->netlist) |
tdse/circuit/policy.h | Solver policy and backend selection |
tdse/circuit/diagnostics.h | Diagnostics, policy tracing, solver statistics |
tdse/circuit/planning.h | Adaptive sweep planning and tail-vs-nfreq analysis |
tdse/circuit/seq.h | Sequence network import (.seq files) and fault analysis |
tdse/circuit/nport.h, nport.hpp | Touchstone/N-port loading and parameter conversion |
tdse/circuit/backend_job.h | Exact-release backend EMT job request/result contract used by ModelSpace execution |
tdse/circuit/host_simulator_bridge.h | Host-neutral HSM v0 preparation; no branded adapter |
tdse/circuit/init.h | Struct initializers, convenience helpers, macros |
tdse/circuit.hpp | C++ wrapper with RAII and exception-based errors |
tdse/circuit/workflow.h, workflow.hpp | High-level workflows (e.g. tdse_circuit_workflow_netlist_to_pack) |
For most integration work, treat this table as a lookup aid rather than required reading. The shorter top-level N-port and workflow include names remain compatibility aliases only; new code should use the canonical paths shown above. Backend jobs belong to the same-release Circuit/ModelSpace workflow and carry no independent shared-library ABI promise. The host-simulator bridge stops at host-neutral subnetwork preparation; PSCAD, EMTP, HYPERSIM, and RTDS adapters are outside the 1.0 product scope.
Quick Start
Before diving into the full API, here is the shortest path from a netlist to a
frequency-domain matrix. If you have a SPICE file called my_circuit.cir and you want
its Y matrix at DC plus four positive frequencies:
tdse circuit matrix \
--netlist-kind file --netlist my_circuit.cir \
--matrix y --ports "1,0" \
--w0 0 --dw 100 --nfreq 5 \
--out-data matrix.csv --json-out -
This single command compiles the netlist, solves the circuit at each frequency, extracts
the port admittance, and writes the results to matrix.csv. The --json-out - flag
prints a machine-readable envelope to stdout - you will want this in any automated
workflow.
The output CSV contains one row per frequency, with the real and imaginary parts of each
Y matrix element in interleaved order: re(Y11), im(Y11), re(Y12), im(Y12), ....
For runnable examples of every CLI command and C API pattern, see the Examples Guide.
Choose Your Path
Use this table before reading deeper:
| If you need to... | Read first | Then use |
|---|---|---|
turn a netlist or RAW case into a .pack with minimum glue | Recommended Workflow API Path | Examples Guide |
| get a Y or Z matrix for Builder | Circuit Authoring Workflows | Builder Handoff |
| convert a PSS/E RAW case | RAW Import | Builder Handoff |
| inspect internal circuit behavior | probe workflow | Diagnostics |
| embed the circuit in host code | Circuit API | Embedding in a Host Solver |
| tune backend choice or sweep strategy | Solver Policy | Advanced Tuning and Performance |
For exhaustive CLI flags and machine-readable CLI outputs, use CLI Reference. This chapter keeps the command examples and the circuit-side meaning, not every CLI contract detail.
Common End-To-End Paths
Most users do not need this whole chapter at once. They need one of these short paths:
| Starting point | Short path |
|---|---|
| SPICE-like netlist -> Builder pack | matrix -> Builder handoff -> Runtime create |
| PSS/E RAW case -> Builder pack | raw-to-netlist -> matrix -> Builder handoff |
| netlist -> validation data only | probe or series -> diagnostics review |
If your goal is a .pack file, stay focused on matrix generation and Builder handoff first. Probe and series workflows are more useful when you are validating the circuit model or debugging a mismatch.
Minimal Integration Decision
Before writing code, decide which side of the boundary needs to own intermediate artifacts:
-
if the host only needs a qualified
.pack, use the workflow path -
if the host must archive or inspect Y/Z, VOC/ISC, or probe outputs, use Circuit directly
-
if the host must control every phase boundary, use compile-then-compute and then hand off to Builder explicitly
Recommended Workflow API Path
If your real goal is "turn this netlist or RAW case into a qualified .pack
with as little hand-stitched glue as possible," prefer the workflow API before
you build your own Circuit -> Builder orchestration.
The public workflow surface covers three common starting points:
tdse_circuit_workflow_netlist_to_pack(...)tdse_circuit_workflow_raw_to_pack(...)tdse_circuit_workflow_yz_matrix_to_pack(...)
For every *_to_pack request, a nonzero builder_plan.target_dt must be the
canonical double(dt_ns) / 1e9 representation of a positive integer number of
nanoseconds. Use zero for automatic planning; the workflow canonicalizes its
derived value before Builder handoff. This restriction belongs to the Runtime
Pack boundary and does not apply to ordinary Circuit frequency or transient
calculations that do not emit a pack.
Why this path is valuable:
- it keeps Builder planning inputs in one request object
- it records whether the grid or sweep plan was auto-derived
- it returns passivity and round-trip verification in the same result
- it gives you one status surface that still preserves underlying Circuit, Builder, Runtime, and N-port outcomes
Use the workflow API when:
- you want the shortest supported path from circuit input to
.pack - your host does not need to intercept every intermediate matrix artifact
- you want one qualification result that already includes pack-quality signals
Drop down to manual Circuit + Builder handoff only when you need to:
-
archive intermediate Y or Z matrices explicitly
-
inject a custom Builder correction or tail-processing sequence outside the workflow defaults
-
debug a mismatch by isolating compile, sweep, Builder conversion, and Runtime verification as separate phases
For a runnable public example, start with workflow_cpp_quickstart in the
Examples Guide.
Workflow ownership split:
-
workflow / Circuit / Builder own circuit compilation, planning, and pack construction
-
the host owns source-file selection, workflow parameters, artifact archival, and the later Runtime embedding choice
Mental Model
Before you start writing code, it helps to understand the two fundamental patterns in Circuit SDK.
The compile-then-compute pattern. You compile a netlist once, which gives you a handle - an opaque object that holds the parsed and analyzed circuit. That handle is then reused across as many compute calls as you need. Compilation is the expensive step (parsing, topology analysis, MNA construction). Compute calls are relatively cheap, and you can run them with different parameters - different frequency grids, different ports, different time steps - against the same handle.
compile_from_netlist(&req, &result) -> handle
| |-- compute_port_fsweep(handle, ...) -> Y or Z matrix
|-- compute_port_series(handle, ...) -> VOC or ISC time series
|-- compute_probes(handle, ...) -> internal voltage/current
`-- compute_port_fsweep(handle, ...) -> another sweep, same handle
The two-output pattern. Compute APIs with caller-owned variable-sized output use a two-call pattern: first call with NULL/zero output buffers to query the required size, then a second call with an allocated buffer to receive the data.
| Function | NULL-buffer returns | Undersized non-NULL returns | required_*_count populated? |
|---|---|---|---|
compute_port_fsweep | TDSE_STATUS_OK | TDSE_STATUS_INVALID_ARG | Yes |
compute_port_series | TDSE_STATUS_OK | TDSE_STATUS_INVALID_ARG | Yes |
compute_probes | TDSE_STATUS_OK | TDSE_STATUS_INVALID_ARG | Yes |
prepare_region | TDSE_STATUS_OK | TDSE_STATUS_INVALID_ARG | Yes |
| RAW import with caller-owned buffers | TDSE_STATUS_BUFFER_TOO_SMALL | TDSE_STATUS_BUFFER_TOO_SMALL | Yes |
SEQ and other import APIs expose type-specific ownership contracts; do not assume every data-producing API uses the compute-buffer convention.
Continue by Task
- Circuit Authoring Workflows
- RAW Import
- Circuit API and Host Integration
- Circuit Solver Selection and Performance
- Element Reference
- Circuit Co-Simulation Product Workflow
- Integration Playbooks
