transient ¤
Transient solvers to be used with Diffrax.
Classes:
| Name | Description |
|---|---|
BDF2FactorizedTransientSolver | BDF2 upgrade of :class: |
BDF2RefactoringTransientSolver | BDF2 upgrade of :class: |
BDF2VectorizedTransientSolver | BDF2 upgrade of :class: |
FactorizedTransientSolver | Transient solver using a Modified Newton (frozen-Jacobian) scheme. |
RefactoringTransientSolver | Transient solver with full Newton (quadratic) convergence using |
SDIRK3FactorizedTransientSolver | 3rd-order A-stable SDIRK3 solver with frozen-Jacobian Newton across all stages. |
SDIRK3RefactoringTransientSolver | 3rd-order A-stable SDIRK3 solver with KLU refactor at each Newton iteration. |
SDIRK3VectorizedTransientSolver | 3rd-order A-stable SDIRK3 solver using full Newton-Raphson at each stage. |
TrapFactorizedTransientSolver | Trapezoidal upgrade of :class: |
TrapRefactoringTransientSolver | Trapezoidal upgrade of :class: |
TrapVectorizedTransientSolver | Trapezoidal-rule transient solver — circulax's default integrator. |
VectorizedTransientSolver | Transient solver that works strictly on FLAT (Real) vectors. |
Functions:
| Name | Description |
|---|---|
free_numeric | Dispatch free to the correct backend based on handle type. |
setup_transient | Configures and returns a function for executing transient analysis. |
BDF2FactorizedTransientSolver ¤
Bases: FactorizedTransientSolver
BDF2 upgrade of :class:FactorizedTransientSolver (frozen-Jacobian Newton).
Factors J_eff once at the predictor state and reuses it across all Newton iterations, trading quadratic convergence for cheaper per-iteration cost. The BDF2 Jacobian scaling α₀/h is used when factoring.
BDF2RefactoringTransientSolver ¤
Bases: RefactoringTransientSolver
BDF2 upgrade of :class:RefactoringTransientSolver (KLU refactor per iteration).
Full quadratic Newton convergence via klujax.refactor at each iteration, combined with BDF2 time discretisation for 2nd-order accuracy.
BDF2VectorizedTransientSolver ¤
Bases: VectorizedTransientSolver
BDF2 upgrade of :class:VectorizedTransientSolver.
Implements variable-step BDF2 via the companion method. On the first step Backward Euler is used automatically; from step 2 onward BDF2 is activated. The Jacobian scaling changes from 1/h (BE) to α₀/h (BDF2) where α₀ = (1 + 2ω)/(1 + ω) and ω = h_n/h_{n-1}.
solver_state is a 3-tuple (y_nm1, h_nm1, q_nm1). h_nm1 is initialised to +inf so that ω = 0 on the first step, making the BDF2 formula reduce to Backward Euler via IEEE 754 arithmetic (no branching). q_nm1 caches Q(y_{n-1}) to avoid recomputing it each step.
FactorizedTransientSolver ¤
Bases: VectorizedTransientSolver
Transient solver using a Modified Newton (frozen-Jacobian) scheme.
At each timestep the system Jacobian is assembled and factored once at a predicted state, then reused across all Newton iterations. Compared to a full Newton-Raphson solver this trades quadratic convergence for a much cheaper per-iteration cost — one triangular solve instead of a full factorisation — making it efficient for circuits where the Jacobian varies slowly between steps.
Convergence is linear rather than quadratic, so newton_max_steps is set higher than a standard Newton solver would require. Adaptive damping min(1, 0.5 / max|δy|) is applied at each iteration to stabilise convergence in stiff or strongly nonlinear regions.
Both real and complex assembly paths are supported; the complex path concatenates real and imaginary parts into a single real-valued vector, allowing purely real linear algebra kernels to be reused for frequency-domain-style analyses.
Requires a :class:~circulax.solvers.linear.KLUSplitFactorSolver as the linear_solver — use analyze_circuit(..., backend="klu_split_factor").
RefactoringTransientSolver ¤
Bases: FactorizedTransientSolver
Transient solver with full Newton (quadratic) convergence using klujax.refactor.
At each timestep the Jacobian is factored once at the predicted state to allocate the numeric handle. Each Newton iteration then calls klujax.refactor — which reuses the existing memory and fill-reducing permutation but recomputes L/U values for the current iterate J(y_k) — followed by a triangular solve. This gives full quadratic Newton convergence at a fraction of the cost of re-factoring from scratch each iteration.
Convergence is quadratic so newton_max_steps is set to 20, matching :class:VectorizedTransientSolver. Adaptive damping min(1, 0.5 / max|δy|) is applied at each iteration to stabilise convergence in stiff or strongly nonlinear regions.
Requires :class:~circulax.solvers.linear.KLUSplitQuadratic as the linear_solver — use analyze_circuit(..., backend="klu_split").
SDIRK3FactorizedTransientSolver ¤
Bases: FactorizedTransientSolver
3rd-order A-stable SDIRK3 solver with frozen-Jacobian Newton across all stages.
Factors J_eff = dF/dy + (1/(γh))·dQ/dy once at the predictor state, then reuses it for all Newton iterations in all three SDIRK stages. This is the recommended backend for large sparse circuits — the single factorisation is shared across all stages because SDIRK's constant diagonal γ gives the same effective Jacobian at every stage.
SDIRK3RefactoringTransientSolver ¤
Bases: RefactoringTransientSolver
3rd-order A-stable SDIRK3 solver with KLU refactor at each Newton iteration.
Provides full quadratic Newton convergence via klujax.refactor within each stage, combined with SDIRK3 time discretisation for 3rd-order accuracy.
SDIRK3VectorizedTransientSolver ¤
Bases: VectorizedTransientSolver
3rd-order A-stable SDIRK3 solver using full Newton-Raphson at each stage.
Uses Alexander's L-stable 3-stage SDIRK tableau with the companion method. Each timestep performs 3 sequential Newton solves (one per stage) with the Jacobian reassembled at every iteration. The same solver_state 2-tuple (y_prev, dt_prev) as Backward Euler is used — SDIRK3 is a one-step method.
TrapFactorizedTransientSolver ¤
Bases: FactorizedTransientSolver
Trapezoidal upgrade of :class:FactorizedTransientSolver.
Factors J_eff once at the predictor and reuses the factorisation across the Newton iteration.
TrapRefactoringTransientSolver ¤
Bases: RefactoringTransientSolver
Trapezoidal upgrade of :class:RefactoringTransientSolver.
Refactors the KLU factorisation at every Newton iteration (full quadratic convergence).
TrapVectorizedTransientSolver ¤
Bases: VectorizedTransientSolver
Trapezoidal-rule transient solver — circulax's default integrator.
2nd-order A-stable with zero numerical damping at all frequencies. Preserves limit-cycle frequencies exactly, unlike BDF2/BE which introduce L²-stable damping that pulls oscillator frequencies.
Use BDF2 instead if you see trapezoidal ringing (sawtooth at 2·dt) on circuits with very sharp digital edges.
VectorizedTransientSolver ¤
Bases: AbstractSolver
Transient solver that works strictly on FLAT (Real) vectors.
Delegates complexity handling to the 'linear_solver' strategy.
free_numeric ¤
Dispatch free to the correct backend based on handle type.
klujax.KLUHandleManager exposes .close(), which calls the backend's FFI free function. Duck-typing is used so handles are freed correctly without isinstance checks against concrete backend types.
Source code in circulax/solvers/transient.py
setup_transient ¤
setup_transient(
groups: list,
linear_strategy: CircuitLinearSolver,
transient_solver: AbstractSolver = None,
) -> Callable[..., Solution]
Configures and returns a function for executing transient analysis.
This function acts as a factory, preparing a transient solver that is pre-configured with the circuit's linear strategy. It returns a callable that executes the time-domain simulation using diffrax.diffeqsolve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
groups | list | A list of component groups that define the circuit. | required |
linear_strategy | CircuitLinearSolver | The configured linear solver strategy, typically obtained from | required |
transient_solver | optional | The transient solver class to use. If None, | None |
Returns:
| Type | Description |
|---|---|
Callable[..., Solution] | Callable[..., Any]: A function that executes the transient analysis. |
Callable[..., Solution] | This returned function accepts the following arguments: t0 (float): The start time of the simulation. t1 (float): The end time of the simulation. dt0 (float): The initial time step for the solver. y0 (ArrayLike): The initial state vector of the system. saveat (diffrax.SaveAt, optional): Specifies time points at which to save the solution. Defaults to None. max_steps (int, optional): The maximum number of steps the solver can take. Defaults to 100000. throw (bool, optional): If True, the solver will raise an error on failure. Defaults to False. term (diffrax.AbstractTerm, optional): The term defining the ODE. Defaults to a zero-value ODETerm. stepsize_controller (diffrax.AbstractStepSizeController, optional): The step size controller. Defaults to |
Source code in circulax/solvers/transient.py
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 | |