Time-Domain System Equivalent logoTime-Domain System EquivalentLinear dynamics, solved faster.Discuss Integration

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 tdse CLI or linked Circuit SDK library.
  • A SPICE-like netlist, RAW file, or NBM manifest.
  • A known port list such as 1,0 or 1,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.

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 goalRecommended starting surface
netlist or RAW -> .pack as fast as possibleworkflow API
inspect matrices or probes before building a packCLI matrix / probe path
embed circuit compilation and sweeps inside host codecompile-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 NPORT elements 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) or Z(jomega) over a user-specified frequency grid. These are the primary input to Builder's h_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:

HeaderPurpose
tdse/circuit.hUmbrella include - pulls in everything
tdse/circuit/common.hHandle lifecycle, error codes, core data types
tdse/circuit/compile.hNetlist compilation, compiled info queries
tdse/circuit/compute.hMatrix sweeps, port series, probes, region preparation
tdse/circuit/raw.hRAW import and conversion (PSS/E ->netlist)
tdse/circuit/policy.hSolver policy and backend selection
tdse/circuit/diagnostics.hDiagnostics, policy tracing, solver statistics
tdse/circuit/planning.hAdaptive sweep planning and tail-vs-nfreq analysis
tdse/circuit/seq.hSequence network import (.seq files) and fault analysis
tdse/circuit/nport.h, nport.hppTouchstone/N-port loading and parameter conversion
tdse/circuit/backend_job.hExact-release backend EMT job request/result contract used by ModelSpace execution
tdse/circuit/host_simulator_bridge.hHost-neutral HSM v0 preparation; no branded adapter
tdse/circuit/init.hStruct initializers, convenience helpers, macros
tdse/circuit.hppC++ wrapper with RAII and exception-based errors
tdse/circuit/workflow.h, workflow.hppHigh-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 firstThen use
turn a netlist or RAW case into a .pack with minimum glueRecommended Workflow API PathExamples Guide
get a Y or Z matrix for BuilderCircuit Authoring WorkflowsBuilder Handoff
convert a PSS/E RAW caseRAW ImportBuilder Handoff
inspect internal circuit behaviorprobe workflowDiagnostics
embed the circuit in host codeCircuit APIEmbedding in a Host Solver
tune backend choice or sweep strategySolver PolicyAdvanced 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 pointShort path
SPICE-like netlist -> Builder packmatrix -> Builder handoff -> Runtime create
PSS/E RAW case -> Builder packraw-to-netlist -> matrix -> Builder handoff
netlist -> validation data onlyprobe 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

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.

FunctionNULL-buffer returnsUndersized non-NULL returnsrequired_*_count populated?
compute_port_fsweepTDSE_STATUS_OKTDSE_STATUS_INVALID_ARGYes
compute_port_seriesTDSE_STATUS_OKTDSE_STATUS_INVALID_ARGYes
compute_probesTDSE_STATUS_OKTDSE_STATUS_INVALID_ARGYes
prepare_regionTDSE_STATUS_OKTDSE_STATUS_INVALID_ARGYes
RAW import with caller-owned buffersTDSE_STATUS_BUFFER_TOO_SMALLTDSE_STATUS_BUFFER_TOO_SMALLYes

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