Repository navigation
v0.3.0 — ic= initial conditions, --out-every, a real silent-wrong-answer fix
Third checkpoint release — 6 commits since v0.2.0, one real silent-wrong-answer bug closed and
two new capabilities. See README.md for the architecture rationale and
book/dev-guide/src/design-decisions.md/docs/journal/ for the reasoning behind each of these.
Highlights
- Fixed a real silent-wrong-answer bug:
kind=sig2physconverters have no terminals and
stamp nothing into the MNA system — they're named values consumed by reference (a source's
own value field, a switch'sgate=/ctrl=), never a circuit node. Because block names and
circuit node names are separate namespaces, wiring a converter's name onto an element line
(R1 VDRV 0 1k) built a perfectly ordinary undriven node — KCL solved it fine to 0, so the
run silently reportedV(VDRV) = 0right next to the block's own correct, non-zero output
column, in both--mode dcand--mode transient.DaeError::Sig2PhysUsedAsCircuitNode
(reject_sig2phys_wired_into_circuit) now catches this before any system is built, in both
modes, naming the converter, the offending element, and the node token as written. ic=initial conditions are now honored end to end:general-mnav0.1.0 gained real
ic=support onC/L(see its own release notes); this release is the seam that actually
uses it —resolve_initial_statecentralizes the decision across all four transient entry
points (simulate_transient,simulate_transient_with_ideal_switches, the closed-loop runner,
the streamed block-graph runner), so a run given no explicitx_initialnow starts from
whateveric=the netlist declares instead of always from rest, falling back to rest only when
the netlist declares none. An explicitx_initialfrom the caller still always wins.--out-every Ndecimates CSV/raw output without coarsening the timestep: every step is
still taken and the solution is bit-identical, only 1-in-N resolved points are written — for a
case like verifying zero-voltage switching, where the integration step has to resolve a sub-
picosecond hard-discharge time but a multi-microsecond commutation window doesn't need every
point written to disk.kind=measurestill sees every point regardless of--out-every(only
the file, not the measurement, is thinned — decimating a measurement's own input would change
its answer, not just its size). Tested by asserting kept rows are byte-for-byte the full run's
rows at those indices, not just that the output shrank.
Fixed since v0.2.0: the two v0.2.0-era doc pages (resolve_initial_state's own doc comment,
DaeError::InitialCondition) that described the old solved-operating-point ic= semantics —
now backwards, since general-mna moved to a true assignment — were corrected alongside the
seam that consumes it.