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
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 | |