withStamp
withStamp(
block,stamp):object
Defined in: packages/compiler/src/couple.ts:473
A new stamp, added to a block whose linear/controlFree are re-derived rather than
assumed unchanged — the same rule lowerRegion itself follows, so a stamp this stage adds
cannot silently leave a block claiming a solver cost or a control independence its own
stamps contradict.
Exported for dangling-active-terminal.ts’s implicit op-amp bias synthesis, which adds a
stamp to an already-linked block for the same reason this stage does: a block’s derived
fields must never describe a stamps array it does not have.
Parameters
Section titled “Parameters”auxCount
Section titled “auxCount”number
Extra unknowns for voltage sources and op-amp outputs.
controlFree
Section titled “controlFree”boolean
No stamp here reads a control, so this block’s coefficients do not change when a knob moves.
The other half of “may this be factored once at load”. linear alone is not
enough and the difference is not bookkeeping: gate 1c measured a state-space
realisation derived at one control position and evaluated at another to be wrong
by 80% of the signal (4.19e-02 against a 5.23e-02 reference RMS). So a
precomputation gated on linear alone would be exact on the fixture that derived
it and wrong on the same circuit one knob-turn later.
Also from the stamps, because a control-bearing device need not lower to a
control-bearing stamp: a switched jack’s port-engage contact becomes a plain
conductance.
eliminate
Section titled “eliminate”boolean
True when symbolic elimination (DK reduction) is admitted for this block. Admitted when the block is nonlinear and the reduction ratio (unknowns / portCount) >= 4.0.
string
inputNode
Section titled “inputNode”number | null
Null when this region does not contain the circuit’s input jack.
"mna"
linear
Section titled “linear”boolean
No stamp here has to be re-evaluated inside a Newton loop, so the block solves in
a single pass. Read by the runtime to choose between one solve and the iteration
cap, and derived from the stamps rather than from the region’s device list — see
stampNeedsNewton.
Stated positively rather than as nonlinear because it is a licence: the
false case costs iterations, and the true case is what later build steps are
allowed to exploit. A flag whose safe default is false should read as the thing
being claimed.
nodeCount
Section titled “nodeCount”number
How many node unknowns this block solves. Always nodeIds.length — the two are
set together at the single site that builds them (lowerRegion), and this one
exists because the runtime reads it in its innermost loops.
nodeIds
Section titled “nodeIds”readonly number[]
Row index -> the source NodeId that row stands for. nodeIds[0] is always
GROUND, because the runtime pins row 0 and starts its gmin loop at 1.
A block’s rows are numbered 0..nodeCount-1, not by the node ids the document
authored. They used to be the same thing: the row index was the authored id,
so a block’s matrix was sized by the largest node label in its region rather than
by how many nodes it has. Two things then inflated it independently — a document
numbering a net 900 (jhs-424-gain-stage labels its +10 V rail that, and got a
909-unknown matrix for a 30-node circuit), and a multi-region document, where
regions are node-disjoint but each one’s matrix still spanned the global id
range up to its own maximum (boss-os-2: 46 regions, the driven one sized 354).
Corpus-wide that was 77,062 analog rows where 4,829 nodes exist, and the padding
rows carried nothing but gmin.
This array is the inverse map, and it is not optional bookkeeping: several
consumers bridge a solved row back to a declared net — the ngspice deck names
(scripts/lib/program-to-spice.ts, which must stay in the same namespace as
source-to-spice.ts or parity compares two different nodes and still reports
agreement), the declared-rail check in report-transistor-bias.ts, and the node
labels report-signal-path.ts and render-v2-audio.ts --held print. Use
blockNodeIndex for the forward direction.
Every node of every device in the region is kept, including terminals no device
law stamps (an op-amp’s vcc/vee). The renumbering is a bijection on the
region’s node set, so no node is removed and nothing about what the block models
changes.
operatingPointSeeds
Section titled “operatingPointSeeds”readonly OperatingPointSeed[]
Where the operating-point solve starts, for nodes whose initial value decides which of several DC solutions the block settles into. Empty for the ordinary case of a circuit with one solution.
outputNode
Section titled “outputNode”number | null
Null when this region does not contain the circuit’s output jack.
sparseSchedule
Section titled “sparseSchedule”SparseSchedule | null
Compile-time static sparse elimination schedule. Derived once at compile time and emitted on the program as data.
stampPartition
Section titled “stampPartition”Compile-time stamp partition for linear/nonlinear, control, and constant stamps. Derived once at compile time and emitted on the program as data.
stamps
Section titled “stamps”readonly Stamp[]
stateCount
Section titled “stateCount”number
Returns
Section titled “Returns”auxCount
Section titled “auxCount”
readonlyauxCount:number
Extra unknowns for voltage sources and op-amp outputs.
controlFree
Section titled “controlFree”
readonlycontrolFree:boolean
No stamp here reads a control, so this block’s coefficients do not change when a knob moves.
The other half of “may this be factored once at load”. linear alone is not
enough and the difference is not bookkeeping: gate 1c measured a state-space
realisation derived at one control position and evaluated at another to be wrong
by 80% of the signal (4.19e-02 against a 5.23e-02 reference RMS). So a
precomputation gated on linear alone would be exact on the fixture that derived
it and wrong on the same circuit one knob-turn later.
Also from the stamps, because a control-bearing device need not lower to a
control-bearing stamp: a switched jack’s port-engage contact becomes a plain
conductance.
eliminate
Section titled “eliminate”
readonlyeliminate:boolean
True when symbolic elimination (DK reduction) is admitted for this block. Admitted when the block is nonlinear and the reduction ratio (unknowns / portCount) >= 4.0.
readonlyid:string
inputNode
Section titled “inputNode”
readonlyinputNode:number|null
Null when this region does not contain the circuit’s input jack.
readonlykind:"mna"
linear
Section titled “linear”
readonlylinear:boolean
No stamp here has to be re-evaluated inside a Newton loop, so the block solves in
a single pass. Read by the runtime to choose between one solve and the iteration
cap, and derived from the stamps rather than from the region’s device list — see
stampNeedsNewton.
Stated positively rather than as nonlinear because it is a licence: the
false case costs iterations, and the true case is what later build steps are
allowed to exploit. A flag whose safe default is false should read as the thing
being claimed.
nodeCount
Section titled “nodeCount”
readonlynodeCount:number
How many node unknowns this block solves. Always nodeIds.length — the two are
set together at the single site that builds them (lowerRegion), and this one
exists because the runtime reads it in its innermost loops.
nodeIds
Section titled “nodeIds”
readonlynodeIds: readonlynumber[]
Row index -> the source NodeId that row stands for. nodeIds[0] is always
GROUND, because the runtime pins row 0 and starts its gmin loop at 1.
A block’s rows are numbered 0..nodeCount-1, not by the node ids the document
authored. They used to be the same thing: the row index was the authored id,
so a block’s matrix was sized by the largest node label in its region rather than
by how many nodes it has. Two things then inflated it independently — a document
numbering a net 900 (jhs-424-gain-stage labels its +10 V rail that, and got a
909-unknown matrix for a 30-node circuit), and a multi-region document, where
regions are node-disjoint but each one’s matrix still spanned the global id
range up to its own maximum (boss-os-2: 46 regions, the driven one sized 354).
Corpus-wide that was 77,062 analog rows where 4,829 nodes exist, and the padding
rows carried nothing but gmin.
This array is the inverse map, and it is not optional bookkeeping: several
consumers bridge a solved row back to a declared net — the ngspice deck names
(scripts/lib/program-to-spice.ts, which must stay in the same namespace as
source-to-spice.ts or parity compares two different nodes and still reports
agreement), the declared-rail check in report-transistor-bias.ts, and the node
labels report-signal-path.ts and render-v2-audio.ts --held print. Use
blockNodeIndex for the forward direction.
Every node of every device in the region is kept, including terminals no device
law stamps (an op-amp’s vcc/vee). The renumbering is a bijection on the
region’s node set, so no node is removed and nothing about what the block models
changes.
operatingPointSeeds
Section titled “operatingPointSeeds”
readonlyoperatingPointSeeds: readonlyOperatingPointSeed[]
Where the operating-point solve starts, for nodes whose initial value decides which of several DC solutions the block settles into. Empty for the ordinary case of a circuit with one solution.
outputNode
Section titled “outputNode”
readonlyoutputNode:number|null
Null when this region does not contain the circuit’s output jack.
sparseSchedule
Section titled “sparseSchedule”
readonlysparseSchedule:SparseSchedule|null
Compile-time static sparse elimination schedule. Derived once at compile time and emitted on the program as data.
stampPartition
Section titled “stampPartition”
readonlystampPartition:StampPartition
Compile-time stamp partition for linear/nonlinear, control, and constant stamps. Derived once at compile time and emitted on the program as data.
stamps
Section titled “stamps”
readonlystamps: readonlyStamp[]
stateCount
Section titled “stateCount”
readonlystateCount:number