![]() |
LINE Solver (C++)
Templated C++ port of the LINE queueing solver
|
Integration controls. More...
#include <line/util/lsoda.h>
Public Attributes | |
| double | rtol = 1e-6 |
| relative tolerance, applied to every component | |
| double | atol = 1e-6 |
| absolute tolerance, applied to every component | |
| std::vector< double > | rtol_vec |
| Per-component tolerances. | |
| std::vector< double > | atol_vec |
| double | h_init = 0.0 |
| initial step; 0 lets LSODA choose | |
| double | h_min = 0.0 |
| smallest admissible step; 0 means no bound | |
| double | h_max = 0.0 |
| largest admissible step; 0 means no bound | |
| std::size_t | max_steps = 10000000 |
| internal steps between output points | |
| int | max_order_nonstiff = 12 |
| Adams order cap (mxordn). | |
| int | max_order_stiff = 5 |
| BDF order cap (mxords). | |
| bool | force_stiff = false |
| Start on BDF and never switch to Adams. | |
| std::function< bool(double, const std::vector< double > &)> | step_stop |
| A test consulted after every ACCEPTED STEP, ending the integration when it returns true and holding the state for the rest of the grid. | |
Integration controls.
max_steps defaults to the JAR's value, not LSODA's own. Upstream defaults to mxstep = 500, which a stiff fluid model exhausts long before the horizon and then reports istate = -1; LSODAExt exists in the JAR precisely to raise it, and this default keeps the two in step.
| double line::LsodaOptions::atol = 1e-6 |
absolute tolerance, applied to every component
Definition at line 66 of file lsoda.h.
Referenced by line::cache::cache_miss_rmf_expansion_transient(), line::fluid::fluid_integrate_leg(), line::fluid::fluid_passage_time(), line::api::infer_fluid_ps_rt_likelihood(), line::fluid::solver_fluid_kp_core(), and line::fluid::solver_fluid_transient().
| bool line::LsodaOptions::force_stiff = false |
Start on BDF and never switch to Adams.
LSODA starts on Adams and switches only when its own detector says the problem is stiff, and that detector needs pdlast, the dominant eigenvalue read off the CORRECTOR's convergence rate. AT A FIXED POINT the corrector converges on the del <= 100*pnorm*ETA branch before pdest is ever formed, so pdlast stays 0, scaleh's stability guard never binds, h runs up to h_max, and a high-order Adams-Moulton outside its stability region WANDERS around the fixed point instead of settling on it – which is where a fluid solver spends most of its time. The JAR pins it for exactly this reason (LSODA.setForceStiff(true)), MATLAB and native Python carry the same flag, and MATLAB's own stiff slot is ode15s, a BDF/NDF method, so pinning is also what matches the reference.
NOT THE DEFAULT HERE, and the reason is measured: pinning BDF means a finite-difference Jacobian from the first step, and LSODA sizes that increment as max(sqrt(eps)*|y_j|, r0/ewt_j), which collapses to ~1e-19 for a component sitting at exactly zero under a tight atol. Robertson started at (1, 0, 0) with atol (1e-6, 1e-10, 1e-6) diverges that way. A fluid drift is not that problem, but a general-purpose default must not carry the hazard.
| double line::LsodaOptions::h_init = 0.0 |
| double line::LsodaOptions::h_max = 0.0 |
largest admissible step; 0 means no bound
Definition at line 78 of file lsoda.h.
Referenced by line::fluid::solver_fluid_kp_core().
| double line::LsodaOptions::h_min = 0.0 |
| int line::LsodaOptions::max_order_nonstiff = 12 |
| int line::LsodaOptions::max_order_stiff = 5 |
| std::size_t line::LsodaOptions::max_steps = 10000000 |
internal steps between output points
Definition at line 79 of file lsoda.h.
Referenced by line::fluid::fluid_lsoda().
| double line::LsodaOptions::rtol = 1e-6 |
relative tolerance, applied to every component
Definition at line 65 of file lsoda.h.
Referenced by line::cache::cache_miss_rmf_expansion_transient(), line::fluid::fluid_integrate_leg(), line::fluid::fluid_passage_time(), line::api::infer_fluid_ps_rt_likelihood(), line::fluid::solver_fluid_kp_core(), and line::fluid::solver_fluid_transient().
| std::vector<double> line::LsodaOptions::rtol_vec |
Per-component tolerances.
Empty means "use the scalars above"; otherwise the vector must have one entry per equation and overrides its scalar. A stiff model whose components live on different scales needs this – Robertson is the standard example, with atol 1e-10 on the fast species and 1e-6 on the other two.
| std::function<bool(double, const std::vector<double>&)> line::LsodaOptions::step_stop |
A test consulted after every ACCEPTED STEP, ending the integration when it returns true and holding the state for the rest of the grid.
WHY THE OPTION EXISTS. lsoda_integrate reports at output times only, and a window whose drift has reached a fixed point has nothing left to report: f(y*) = 0 means y is that state for every later t, so the remaining span is known. Without this the step controller grinds – a stiff controller handed a state it is already at cannot pick a step – and the window never returns. See solver_fluid.h and FLUID_FIXED_POINT_GUARD (MATLAB).
Empty by default, and the integration then runs exactly as it always has: the itask = 1 loop below is untouched, so no existing caller changes. Set, it selects the stepwise driver, which reproduces the same output grid one accepted step at a time through LsodaStepper.