Source Implementation

How the source components stamp, and the quirks in the non-ideal ones.

The models are derived under sources. This page covers only the code.

Ideal sources

VoltageSource requests one virtual node, which carries the source current as the extra unknown, and stamps the constraint rows that fix the terminal voltage difference. CurrentSource requests none and contributes only to the right hand side.

ControlledVoltageSource and ControlledCurrentSource are the same components with their reference supplied as an attribute rather than a parameter, so another component or an interface can drive them. The reference is read during the pre-step, which is why it is the previous step’s value.

VoltageSourceNorton

Stamps directly rather than through a virtual node. mnaCompApplySystemMatrixStamp adds mConductance to both diagonal entries and subtracts it from the two off-diagonal entries, guarded by terminalNotGrounded, and mnaCompApplyRightSideVectorStamp sets the equivalent current mIntfVoltage / mResistance with opposite signs at the two terminals.

mConductance is computed in setParameters as 1 / resistance, so calling setParameters is mandatory before the run and a zero resistance is a division by zero rather than an ideal source.

VoltageSourceRamp

A composite wrapping a VoltageSource whose reference it rewrites each step in updateState(time). Three regimes: before mSwitchTime the reference is unchanged; during mRampTime the added voltage is interpolated linearly while the added frequency is blended by a raised sine 0.5 + 0.5 * sin(pi * t / T - pi/2); afterwards both are fully applied.

The two are blended differently on purpose. A linear frequency interpolation applied as a phase offset would step the phase at both ends of the ramp; the raised sine has zero derivative at both ends, so the frequency contribution enters and leaves smoothly. The consequence is that the instantaneous frequency during the ramp is not the linear interpolation between the two values, and reading mAddSrcFreq as “the frequency at the midpoint” is wrong.

Note also that the added frequency term is applied as mAddSrcFreq * time, using absolute simulation time rather than time since the switch, so the phase contribution depends on when in the run the ramp occurs.

ProfileVoltageSource

Holds a std::filesystem::path, a sample vector and an index, and reads the file in readFromFile at construction. It implements DAEInterface in addition to the MNA hooks.

The samples are stepped by index rather than interpolated against simulation time, so the profile’s sample rate and the simulation step must match for the waveform to have the intended duration. It is bound in Python and constructing it with a file that is not a readable sample list raises rather than crashing, which is covered by a test.

Source

Under dpsim-models/src/{SP,DP,EMT}/. Availability per domain is in model availability.