Skip to content

Transient analyses and responses ​

Time-domain problems, integration rules, saved states, and response derivatives.

See the API overview for other analyses and conventions for units and array ordering.

JosephsonCircuits.BackwardEuler Type
julia
BackwardEuler()

Backward Euler on the flux and on its rate: first order and strongly damping, a deliberately dissipative reference for checking that a result does not depend on the stepping rule.

source
JosephsonCircuits.GaussLegendre Type
julia
GaussLegendre()

The two stage Gauss-Legendre collocation on the flux and its rate, the default of transientsolve: fourth order, A-stable, symplectic, and free of numerical damping, so a lossless LC oscillation keeps its energy and a resonator's angular frequency w is warped by (w dt)^4/720 rather than the trapezoidal rule's (w dt)^2/12. Each step solves the two stage equations together, by Newton on one complex factorization of the stage matrix at a frozen junction stiffness, refreshed as the trapezoidal rule's is. Not L-stable: an unresolved fast mode is not damped, as the trapezoidal rule does not damp it.

Along a direction of the state without capacitance the equations are algebraic. Where a resistor acts along it the rate is what the constraint determines, read from it at the endpoint, and converges at fourth order as the rest of the state does. Where none does the constraint is on the flux alone: a junction on the direction or a source driving it makes it nonlinear or moving, and each step projects its endpoint onto it, while a linear constraint no source drives is an invariant of the rule and holds by itself. The rate along every such direction is not the rule's, whose update carries the rounding of every stage solve forward along it, but is read from the differentiated constraint wherever the state is reported, as the trapezoidal rule's is; where a scattering block is on a direction, whose states move the constraint at a rate the reading would have to solve for with the block's port currents, the rate along the projected directions is the derivative of the cubic through the state, the two stages and the projected endpoint, third order. The tangent and the adjoint of a Gauss-Legendre solve differentiate the full stage equations, the projection and the readings included, and are exact for the recorded steps: each step's linearized stage equations, the real matrix of both stages at the step's recorded phases with the blocks' coupling at the stages' weights, are factorized at the step and solved once for every direction, the adjoint's by the transpose of the same matrix.

source
JosephsonCircuits.TransientBatchSolution Type
julia
TransientBatchSolution

Result of transientsolve on a vector of problems: the arrays of a TransientSolution with the conditions as the trailing dimension, voltage[port, time, condition], flux[state, time, condition], finalflux[state, condition], phases[junction, stage, time, condition], stages[state, stage, time, condition]; problems holds the batch. Indexing, solution[j], is the ordinary solution of condition j, a view of the batch's arrays, on which the demodulation, the tangent, the adjoint and the noise run as on any solution.

stats counts the factorizations and the retries of the condition which needed the most, since each condition refreshes its own factorization, and the Newton corrections of the chunk which iterated longest: the conditions of a chunk are corrected together until the last of them has converged, so that count falls as a host batch split across threads makes its chunks smaller, while the results do not change.

source
JosephsonCircuits.TransientReuse Type
julia
TransientReuse()

What a transient solve builds and a later solve, tangent or adjoint of the same problem at the same step, rule and backend takes over rather than building again: the scaled TransientSystem with its Jacobian plan, the factorization of the step matrix as it was left, the Krylov workspace of the iterative step, and the workspaces of the Gauss-Legendre tangent and adjoint, one per chunk of conditions, with their stage factorizations and the stepper a record of checkpoints is replayed on, taken over by a later tangent or adjoint of the same shape and, for a sensitivity, the same components in the same order; and for the noise and the gain on the host, the reuses of the other threads' workers, kept the same way. Pass one as reuse to transientsolve, transienttangent and transientadjoint. The kept system serves every problem of one compiled circuit driving the same targets, the problems of one batch (see transientproblem), so a sweep of drives keeps it; a solve of another circuit, or at another step, rule or backend, replaces it. The counterpart of the harmonic balance solver's reuse between the solves of an hbcache. The kept objects are mutable and belong to one solve at a time: do not share a reuse between concurrent solves.

source
JosephsonCircuits.TransientSolution Type
julia
TransientSolution

Result of transientsolve. times is in seconds; voltage holds the port voltages in Volts and incident and outgoing the real instantaneous power waves in sqrt(W), one row per port in the order of the port numbers, as harmonic balance's port axis, and one column per saved time. initialflux, initialrate, finalflux and finalrate always hold the first and the last scaled state, and finalwaves and finalstates the rest of the last, the waves leaving each line port over the delay window before the end as (port, column) and the states of the rational blocks, or nothing without lines or blocks, so that transientstate(solution) is the state to continue from whatever was recorded. With record = :phases or :states, phases holds the junction phases the tangent and the adjoint read, at every saved time under the trapezoidal rule and at the two stages of each step under GaussLegendre, as (junction, stage, time), under GaussLegendre endphases the phases at every saved time of the junctions on the algebraic directions the rule projects, nothing under the other rules, and endrates the rate across them read from the differentiated constraints, or nothing without any, and linewaves the wave leaving each port of each transmission line at every step, as (port, time) in sqrt(W), or nothing without lines, or with checkpoints when the history before each of them, kept as their waves, is smaller than the record, which is kept instead once the longest delay exceeds the checkpoint interval, and history the waves leaving each line port over the delay window before the start, which the lines read after it; on the solve's backend as every record is; with record = :states, flux and rate hold the scaled node fluxes and their rates at every saved time as well, and under GaussLegendre stages the two stage increments of the step ending at each saved time, as (state, stage, time), which the sensitivity to a component value reads, and blockstates the rational blocks' states at every saved time; with record = :checkpoints, checkpoints holds the state and the stage predictor every checkpointevery steps, from which the responses replay the steps between, so that a record of any length costs the checkpoints and one window of phases. initialwaves and initialstates are the lines' waves and the blocks' states the solve started from, which the noise reads. stats counts the steps, the Newton corrections, the numeric factorizations, the retries of a rejected correction after a fresh factorization at its base point, and the Krylov iterations. The arrays live on the backend of the solve.

source
JosephsonCircuits.TransientSource Type
julia
TransientSource(target, current)

A real instantaneous current in Amperes, a number or a callable current(t) of the time in seconds. An integer target is a port number: a Norton source injects the current into the port's first (positive) terminal, and the port's termination is part of the compiled circuit already. A string or symbol names a CurrentSource component, whose constant value the waveform replaces, and which drives its current through itself from its first terminal to its second: it draws the current from the node at its first terminal and delivers it to the node at its second, the opposite sense of a port source. Several sources on one target add. Unlike a harmonic balance source the callable returns the physical waveform, not a Fourier coefficient, and it must be deterministic, since the tangent and the adjoint evaluate it again on the recorded grid.

source
JosephsonCircuits.TransientState Type
julia
TransientState

The state a transient starts from or ends at, in the solver's units: the scaled node fluxes flux/phi0 with the auxiliary currents of the coupled inductors and the scattering blocks appended in the problem's fixed units Lscale*i/phi0, their rates, the history of the wave leaving each port of each transmission line in sqrt(W), two per line in compiled order, as the columns of waves at the spacing wavesdt ending at the start, or a single column the lines carry unchanged before the start, and the states of the rational blocks. Built by transientstate, from the physical node fluxes and voltages of a problem or from the end of a solution, and given to transientsolve as initialstate, which takes nothing else, since a bare pair of arrays does not say which units it is in. A state does not depend on the step: a history recorded at one step is read at another through the same interpolation the lines read their history with.

source
JosephsonCircuits.TransientStepError Type
julia
TransientStepError(step, time, conditions, cause)

The error transientsolve throws when a step cannot be taken: the index step of the step, the time in seconds it ends at, the conditions of the batch which failed it, [1] for a single problem, the others having converged at that step, and its cause, :newton when the Newton solve of the step did not converge within iterations corrections, or :projection when the projection of its endpoint onto the algebraic constraints did not. A smaller dt, or an initial state consistent with the circuit, is the remedy.

source
JosephsonCircuits.Trapezoidal Type
julia
Trapezoidal()

The trapezoidal rule on the flux and on its rate (Newmark with the averaging parameters): second order, and free of numerical damping, so a lossless LC oscillation keeps its energy. One implicit equation per step, and with BackwardEuler a rule which takes a linearsolver. Along an algebraic direction of the state, one without capacitance or conductance, each endpoint is projected onto a constraint a junction or a source touches, as under GaussLegendre, since the constraint's rows weigh little in the step's residual and the rule's average of the two ends would carry what the Newton leaves to the next end with its sign reversed; and the rate is read from the differentiated constraint wherever the state is reported, since the rule's rate update carries the rounding of every step forward along it undamped.

source
JosephsonCircuits.WRspice Type
julia
WRspice(; executable = nothing, dphimax = 0.01, jjaccel = true,
    maxdata = 2e9)

WRSPICE as the stepping rule of transientsolve, for cross checking the package's own rules against an independent simulator. The problem's circuit is written as a WRSPICE netlist with each junction an instance of the jj model (see exportnetlist) and each drive a current source — a constant one for a waveform given as a number, and a piecewise linear one through the waveform's samples on the grid of dt for a callable — and the simulation runs through the wrspice executable in a temporary directory and is read back as a TransientSolution holding the times, the port voltages and the port waves, and with record = :phases the junction phases from the phase nodes of the jj instances, as (junction, time) on the junction axis every solver uses, in the branch orientation of the package. transientdemodulate and transientiq then read the solution as they read one stepped by the package.

A run keeps those traces and no others: the terminals of the ports, and the phase nodes of the junctions when they are recorded. WRSPICE would otherwise write every node of the circuit at every print point, which is a gigabyte of a record nothing reads for every thousand nodes and every hundred thousand points.

WRSPICE integrates with its own adaptive internal steps: dt is the grid the sources are sampled on and the output is printed on, and dphimax, the largest junction phase change WRSPICE allows per internal step, controls the accuracy in place of the Newton tolerances, which do not apply. jjaccel selects WRSPICE's accelerated convergence testing for Josephson circuits, and maxdata its limit on the exported data in kilobytes. executable is the path of the wrspice executable, or nothing for the one wrspice_cmd finds; loading the XicTools_jll package provides one.

Supported are the circuits of transientproblem without scattering blocks, with the sinusoidal junction relation only, from the zero initial state under WRSPICE's own initial conditions, with record = :ports or :phases. An ideal TransmissionLine is written as the SPICE lossless line element; the wave record linewaves stays empty, since WRSPICE keeps the line histories to itself. The junctions of every run share one jj model, whose subgap loss is small but not zero (vm = 9.9 of exportnetlist), where the package's junctions are lossless. The solution's final state fields are NaN, since WRSPICE does not hand over a state, and the tangent, the adjoint and the noise need a solution of the package's own rules. Its stats count the steps of the grid, as the package's rules count theirs, whatever is saved; WRSPICE's own internal steps are not reported.

Examples

julia
p = transientproblem(circuit, circuitdefs;
    sources = [TransientSource(1, t -> Ip*sin(wp*t))])
native = transientsolve(p, (0.0, 100e-9); dt = 1e-12)
spice = transientsolve(p, (0.0, 100e-9); dt = 1e-12, method = WRspice())
transientdemodulate(native, 2, wp), transientdemodulate(spice, 2, wp)
source
JosephsonCircuits.transientadjoint Method
julia
transientadjoint(batch::TransientBatchSolution, weights; quantity, targets, sink)

The adjoint of every condition of a batch for the same weights, all conditions on one pass: the arrays of the single adjoint with the conditions as the trailing dimension, and a sink's columns holding the objectives of a condition contiguously, condition after condition. On the host the conditions are split across the threads of the session when the currents are stored, as the solve splits them; a call with a sink or a stagesink runs on one thread.

source
JosephsonCircuits.transientadjoint Method
julia
transientadjoint(solution, weights; quantity = :outgoing, targets = the ports,
    factorization = nothing, reuse = nothing, sink = nothing, stagesink = nothing,
    components = String[])

The exact discrete adjoint of sum(weights .* getproperty(solution, quantity)) on the recorded grid, weights having one row per port and one column per recorded time and quantity being :voltage, :incident or :outgoing; a third dimension of weights is a set of objectives propagated together on each step's factorization. Returns (currents, initialflux, initialrate, initialwaves, initialstates, sensitivity): the derivatives with respect to a Norton current at every target (a port number or a component name, see transientinjection) and recorded time, in Amperes, including the direct feedthrough of a port's current into its wave; with respect to the scaled initial flux and rate; under GaussLegendre with respect to the lines' prehistory and the rational blocks' initial states, the cotangents of the third and fourth members of the tangent's initialstate, or nothing without them; and with respect to the relative values of the named components, (component, objective), as transientsensitivity perturbs them, or nothing without any; all with the objectives as the trailing dimension. For a consistent perturbation the contraction equals the weighted output of transienttangent; a complex demodulation is two real objectives, and a time integral carries its quadrature weights in weights. The derivative along a target that drives a net current into a subnetwork no element connects to ground, a current source between it and the rest of the circuit, depends on which node of the subnetwork the solver takes as its flux reference: only a combination of the targets whose currents cancel there means anything, as the sum along two sources of one waveform into it and out of it, and a target that no such combination includes is refused. With a sink, a function sink(k, values), the currents are not stored: each column, a targets by objectives matrix on the backend valid until the next call, is handed to the sink once it is final, in decreasing recorded time, and currents is nothing; a contraction over a long record then needs no memory per time. With a stagesink as well, a function stagesink(k, i, values), the multipliers of the two stages of each Gauss-Legendre step from k to k + 1 go to it as they are, at their stage times, in a buffer which, like the sink's columns, is valid until the next call, and the grid columns hold only what the grid reads; that pair is the transpose of the staged form of the tangent's currents, and it is what the noise contracts.

source
JosephsonCircuits.transientdemodulate Method
julia
transientdemodulate(solution, port, frequency; quantity = :outgoing,
    window = t -> 1.0)

The complex peak amplitude of the saved trace of port at the angular frequency in rad/s: the integral of 2*window(t)*trace(t)*exp(-im*frequency*t) over the integral of window, by trapezoidal quadrature on the saved samples. quantity is :voltage, :incident or :outgoing. A smooth window suppresses leakage from a strong pump; the saved rate must resolve the carrier. On a device solution the port trace is downloaded once.

source
JosephsonCircuits.transientproblem Function
julia
transientproblem(circuit, circuitdefs = Dict(); sources = ())

Compile a circuit for integration in time: the same compiler and numericmatrices as harmonic balance, at one mode, with the mutually coupled inductors promoted to auxiliary branch currents and the floating inductive subnetworks gauge fixed as hbnlsolve does. sources is a tuple or vector of TransientSources; the netlist's constant CurrentSource components keep their constant values unless a source names them. The circuit may be a typed Circuit or a compiled circuit.

Supported are real, constant resistors, capacitors, inductors, mutual inductors, Josephson junctions and nonlinear inductors with a polynomial current-phase relation (see PolynomialCPR), current sources and ports. Frequency dependent or complex values are rejected, since they need a causal realization in time, which a block may carry: a ScatteringParameters block with a constant real matrix is realized as it is, a RationalScattering block and a pumped block fitted for time with RationalScattering(block, npoles) by their states, see TransientBlock, and an ideal TransmissionLine by its delay, see TransientLine; circuits with blocks or lines step under GaussLegendre. Any other block is rejected.

source
JosephsonCircuits.transientproblem Method
julia
transientproblem(problem::TransientProblem; sources)

The compiled circuit of problem under other sources, without compiling again: the same matrices and augmentation, new bound drives. The problems of one batch must drive the same targets in the same order, which this gives when sources differ only in their waveforms.

source
JosephsonCircuits.transientsensitivity Method
julia
transientsensitivity(solution, names; factorization = nothing,
    reuse = nothing, outputsink = nothing)

The derivative of the port responses of a recorded transient, or of every condition of a TransientBatchSolution on one pass, with respect to a relative perturbation r of the value of each component names names (p -> r*p at r = 1), as Ssensitivity of hblinsolve is of the scattering parameters. Returns (voltage, incident, outgoing, finalflux, finalrate, finalwaves, finalstates) as transienttangent does, with the components as the trailing dimension, before the conditions of a batch. The components supported are those of the linearized solve, C, L, R and Lj with numeric values and no mutual coupling. The equations of a step are differentiated as they were taken, so the derivative is exact for the recorded steps; a capacitor, inductor or resistor reads the recorded states, record = :states, or record = :checkpoints under GaussLegendre, which replays them, while a junction reads the phases every record holds. The adjoint counterpart is the components keyword of transientadjoint, whose sensitivity is the derivative of its objective with respect to the same perturbations.

source
JosephsonCircuits.transientsolve Method
julia
transientsolve(problems::AbstractVector{TransientProblem}, tspan; dt,
    method = GaussLegendre(), backend = CPU(), factorization = nothing,
    reuse = nothing, initialstate = transientstate of each, saveevery = 1,
    record = :ports, checkpointevery = 0, rtol = 1e-9, atol = 1e-10,
    iterations = 15, maxsteps = 10^7)

The same circuit under every drive condition of problems, built by transientproblem(problem; sources) so that they share one compiled circuit and drive the same targets, stepped as one system under GaussLegendre: the states are matrices with the conditions as columns, every product takes all conditions in one call, the junction stiffness and the factorization are one per condition, KLU on the CPU and the uniform cuDSS batch on a device, and the Newton engine accepts and refreshes per condition. On a device this is where the throughput lies, since the launches of a step serve every condition. initialstate is one TransientState for all conditions or a vector of them. Returns a TransientBatchSolution, whose solution[j] is the ordinary solution of condition j.

On the host the conditions are also split across the threads of the session and their chunks stepped at once, since the conditions of a batch are independent of one another. The whole step parallelizes that way, not only the assembly, the factorization and the solve, and the chunks fill the arrays of the batch in place, so the split costs no copy and changes no result: any layout of chunks gives the same bits. Start Julia with -t to use it. A device keeps the one chunk its uniform batch already is.

source
JosephsonCircuits.transientsolve Method
julia
transientsolve(problem, tspan; dt, method = GaussLegendre(), backend = CPU(),
    factorization = nothing, linearsolver = nothing, reuse = nothing,
    initialstate = transientstate(problem), saveevery = 1,
    record = :ports, checkpointevery = 0, rtol = 1e-9, atol = 1e-10,
    iterations = 15, maxsteps = 10^7)

Integrate the circuit in physical time on a uniform grid of step at most dt, shortened slightly to land on tspan[2]. method is the stepping rule, GaussLegendre by default, fourth order, or Trapezoidal, second order at the same step, or BackwardEuler, the two rules which take a linearsolver, or WRspice to run the same problem through the WRSPICE simulator and read its output back as the same solution; backend is where the solve runs, and factorization the sparse factorization, KLU on the CPU and cuDSS on a CUDA device by default, or on the CPU LUfactorization or QRfactorization, which factorizes anew wherever the others refactorize; a BlockFactorization, which takes node blocks of harmonic balance modes, is refused. reuse, a TransientReuse, carries the system and its factorization, the Krylov workspace and the responses' workspaces to a later solve, tangent or adjoint of the same problem at the same step, rule and backend. The Jacobian's pattern is fixed and its symbolic analysis done once; a linear circuit factorizes once. atol and rtol control the Newton residual of a step, not the temporal error, row by row: each row of the step's residual is converged to atol plus rtol times the magnitudes of the terms it sums at the step's start, such as its drive, its capacitive rate term and its stiffness on the state, so a weak signal is converged relative to itself whatever a bias on another node carries; a bias on the signal's own node sets that row's scale, and rtol must then be lowered by the ratio of the bias to the signal. atol is absolute, in the units of the scaled equations, where a current I is Lscale*I/phi0 with Lscale the problem's inductance scale and phi0 the reduced flux quantum, so that it is a current of atol*phi0/Lscale; a row whose terms are weaker than that is converged to atol alone, so lower it for a weaker drive. iterations bounds the corrections of a step, the names hbnlsolve uses, where rtol is relative to the initial residual instead; a step that fails throws a TransientStepError.

With linearsolver = GMRES() (or another of the package's Krylov solvers) under Trapezoidal or BackwardEuler each Newton correction is solved iteratively and matrix free, with the last factorization of the step matrix as the preconditioner, to a relative residual of 1e-4 within the solver's restart length and restart budget (GMRES(; restart, maxrestarts), the defaults of GMRES() for another solver): the factorization is then refreshed only when a solve takes more than four iterations or fails, the iteration count saying it has drifted, rather than at every step the junction phases move. The Krylov workspace and the preconditioner persist for the whole solve.

By default only the port outputs and the first and last states are kept, which is what the port responses need; saveevery decimates the saved samples without changing the grid and keeps both endpoints. record = :phases with saveevery = 1 records the junction phases at every step, the least transienttangent, transientadjoint and the noise need, record = :states the whole flux and rate history as well, and record = :checkpoints, under GaussLegendre, only the state every checkpointevery steps (the square root of the step count by default), from which the responses replay the steps between at the cost of one more solve, so the memory of a record of any length is bounded; the solve refactorizes at every checkpoint, as the replay starts each window, so that the replay retraces it exactly. initialstate is the TransientState of transientstate, from physical values or from the end of another solution; the solver checks that it satisfies the algebraic equations of the circuit at the start, each to the tolerances of a step relative to its own terms.

source
JosephsonCircuits.transientstate Method
julia
transientstate(problem; flux = zeros(...), voltage = zeros(...),
    linecurrents = zeros(...))
transientstate(solution)

The initial state of a transient, a TransientState, from the node fluxes in Weber and the node voltages in Volts, in the compiled node order without ground: the scaled fluxes flux/phi0, augmented with the auxiliary currents the coupled inductors' constitutive equations imply and normalized into the gauge of the floating subnetworks, and the scaled flux rates voltage/phi0 with the auxiliary rates the same equations imply. The default is the zero state. transientsolve checks that a state satisfies the algebraic equations of the circuit at the start; it does not project one that does not. With transmission lines the waves leaving the ports of each line come from the port voltages and linecurrents, the direct current into the first port of each line, zero by default; before the start the lines carry those waves unchanged.

From a solution, the state at its end, to start another solve from: its final fluxes and rates, the waves leaving each line port over the delay window before the end, which is what the lines read after the start, so a continuation is the uninterrupted solve to the solver's tolerance at the same step and to the interpolation of the history at another, and the final states of the rational blocks, which every solve of the package's rules keeps whatever it records.

source
JosephsonCircuits.transienttangent Method
julia
transienttangent(batch::TransientBatchSolution, currents; targets, initialstate)

The tangent of every condition of a batch along the same currents, all conditions on one pass: the arrays of the single tangent with the conditions as the trailing dimension. The initial perturbation is one tuple for every condition, or one per condition with the conditions as a trailing dimension of its arrays. On the host the conditions are split across the threads of the session when the outputs are stored, as the solve splits them; an outputsink or a statesink receives the columns of every condition at each time, so a call with one runs on one thread.

source
JosephsonCircuits.transienttangent Method
julia
transienttangent(solution, currents; targets = the ports,
    initialstate = nothing, factorization = nothing, reuse = nothing,
    outputsink = nothing, statesink = nothing)

The tangent of a recorded transient along a perturbation: currents[q, k] is an additional Norton current in Amperes at target q (a port number, or a component name, see transientinjection) at recorded time k, and initialstate an optional tuple of perturbations at the start: of the scaled flux and rate, (flux, rate), each (state, direction), and under GaussLegendre optionally of the waves the lines carried before it, (line port, prehistory column, direction), and of the rational blocks' states, (state, direction), as its third and fourth members, each with a trailing dimension of the conditions of a batch when it differs between them. A third dimension of currents is a set of directions propagated together, each step's factorization serving them all. The currents into a subnetwork no element connects to ground, which current sources alone feed, must cancel at every recorded time and at every stage the rule reads, as the solve requires of its sources: a tangent along a net current into one is refused. Under GaussLegendre a current on the grid is read at the stage times through a cubic Lagrange stencil, through the line between the step's grid values on a record shorter than four points; a current given as currents[q, s, k, direction], with s = 1 its value at recorded time k and s = 2, 3 its values at the two stage times of the step from k to k + 1, is read as it is, so a pulse keeps its support and a tone its exact phase at the stages; the trapezoidal rule reads the grid values of either form. The rate of a current on the grid, which the reading of the rate along an algebraic direction carries, is that of the cubic through four grid values, of the quadratic through three or of the line through two. Returns (voltage, incident, outgoing, finalflux, finalrate, finalwaves, finalstates) in the units of the solve, on its backend, with the directions as the trailing dimension, under GaussLegendre finalwaves the waves leaving each line port over the delay window before the end, (line port, column, direction) as the third member of initialstate takes them, so that a tangent of the next record continues this one, and finalstates the rational blocks' states at the end, each nothing without lines or blocks or under another rule; with an outputsink, a function outputsink(k, voltage, incident, outgoing) receiving the three port by direction matrices of recorded time k on the backend, valid until the next call, the histories are not stored and those three are nothing, so a measurement of a long record needs no memory per time. A statesink(k, flux, rate, states, waves) receives the tangent's state at each recorded time k in the same way, its scaled fluxes and rates, its blocks' states as finalstates holds them and under GaussLegendre the waves leaving its line ports at the time as finalwaves holds them, state or port by direction, each nothing without blocks or lines. The linearization is about the full recorded state, so the loaded junction phases enter every response; both the trajectory and its grid are held fixed.

source