Class Rodas
M y' = f(x,y), including a SINGULAR mass matrix (index-1 DAE).
PORTED THIRD-PARTY CODE -- do not edit to fix a LINE bug; fix the caller.
Source: E. Hairer and G. Wanner, rodas.f / dc_decsol.f /
decsol.f, version of October 28, 1996, as published with "Solving
Ordinary Differential Equations II. Stiff and Differential-Algebraic
Problems", Springer Series in Computational Mathematics 14. Licence in
matlab/lib/thirdparty/rodas/LICENSE, which covers every port of it in
this repository.
WHY THIS EXISTS IN THE JAR. The fluid solver integrates with LSODA
(LSODAExt), which solves y' = f and
cannot carry a mass matrix at all -- let alone a singular one. The dae
method writes population conservation as an ALGEBRAIC row, one per closed
chain, so its transient is an index-1 DAE with a singular M and has no LSODA
route. RODAS is a fixed sequence of six linear solves against one real matrix
rather than an iteration with a convergence policy, so a port has no
iteration history to diverge on -- which is what lets MATLAB, C++, native
Python and this agree in the last digits on that route. See
_kb/06-solver-catalog.md.
THE TRANSLATION IS INDEX-FOR-INDEX. Every array here is allocated one longer than it needs to be and addressed from 1, exactly as the Fortran does, and the loop bounds are the Fortran's own. That is deliberate: a 0-based rewrite of 2000 lines of Fortran is where an off-by-one hides, and it would be invisible until it changed an answer nobody has a reference for. Index 0 of every internal array is unused. The CALLBACKS are the exception and are 0-based, because they are the boundary a Java caller actually writes; the copy at that boundary is O(n) against the O(n^3) factorisation it sits next to.
EVERY REDUCTION IS A SEQUENTIAL LOOP, as the Fortran accumulates it -- the error norm and the inner sums of DECOMR and SLVROD. Reassociating them would change the last bits, which is enough to move a step-size decision and desynchronise the whole trajectory from the other three codebases.
Reachable IJOB values are 1..5 (and 11..15 when m1 > 0, the second
order form); RODAS itself never selects 6 or 7, which belong to RADAU5's
Hessenberg option and are absent here rather than transliterated dead.
Java 8: no var, no List.of, no switch expressions.
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classCONTRO: the third-order interpolant RODAS carries over the step just accepted.static interfacedf/dx, for a non-autonomous system.static interfaceThe right hand side f(x,y).static interfacedf/dy.static interfaceThe mass matrix.static final classThe Fortran switches, with rodas.f's own defaults.static final classWhere the integration ended, and what it cost.static classRaised for an input rodas.f itself rejects before integrating.static interfaceCalled after each accepted step wheniout != 0; negative stops. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intIDID: more than NMAX steps were needed.static final intIDID: the matrix was repeatedly singular.static final intIDID: SOLOUT asked for the integration to stop.static final intIDID: the step size became too small.static final intIDID: the integration reached XEND. -
Method Summary
Modifier and TypeMethodDescriptionstatic Rodas.Resultintegrate(int n, Rodas.Fcn fcn, double x, double[] y, double xend, double h, double[] rtol, double[] atol, int itol, Rodas.Options opt) IntegrateM y' = f(x,y)fromxtoxend.
-
Field Details
-
IDID_SUCCESS
public static final int IDID_SUCCESSIDID: the integration reached XEND.- See Also:
-
IDID_SOLOUT_STOP
public static final int IDID_SOLOUT_STOPIDID: SOLOUT asked for the integration to stop.- See Also:
-
IDID_NMAX
public static final int IDID_NMAXIDID: more than NMAX steps were needed.- See Also:
-
IDID_STEP_TOO_SMALL
public static final int IDID_STEP_TOO_SMALLIDID: the step size became too small.- See Also:
-
IDID_SINGULAR
public static final int IDID_SINGULARIDID: the matrix was repeatedly singular.- See Also:
-
-
Method Details
-
integrate
public static Rodas.Result integrate(int n, Rodas.Fcn fcn, double x, double[] y, double xend, double h, double[] rtol, double[] atol, int itol, Rodas.Options opt) IntegrateM y' = f(x,y)fromxtoxend.- Parameters:
n- dimension of the systemfcn- the right hand sidex- initial abscissay- initial state, length n, 0-based; modified in placexend- final abscissah- initial step size guess (0 means 1e-6)rtol- relative tolerance, length 1 (itol 0) or n (itol 1)atol- absolute tolerance, same shape as rtolitol- 0 scalar tolerances, 1 one per equationopt- the Fortran switches; null for all defaults- Returns:
- where the integration ended and what it cost
-