public class ExplicitRK45Solver extends ContinuousODESolver
For an ODE of the form:
dx(t)/dt = f(x(t), t), x(0) = x0it does the following:
K0 = f(x(n), tn); K1 = f(x(n) + 0.2*K0*h, tn + 0.2*h); K2 = f(x(n) + (3.0/40*K0 + 9.0/40*K1)*h, tn + 0.3*h); K3 = f(x(n) + (0.3*K0 - 0.9*K1 + 1.2*K2)*h, tn + 0.6*h); K4 = f(x(n) + (-11/54*K0 + 5.0/2*K1 -70/27*K2 + 35/27*K3)*h, tn + 1.0*h); K5 = f(x(n) + (1631/55296*K0 + 175/512*K1 + 575/13824*K2 + 3544275/110592*K3 + 253/4096*K4)*h, tn + 7/8*h); x(n+1) = x(n)+(37/378*K0 + 250/621*K2 + 125.0/594*K3 + 512.0/1771*K5)*h;, and error control:
LTE = [(37.0/378 - 2825.0/27648)*K0 + (250.0/621 - 18575.0/48384)*K2 + (125.0/594 - 13525.0/55296)*K3 + (0.0 - 277.0/14336)*K4 + (512.0/1771 - 0.25)*K5]*h.
If the LTE is less than the error tolerance, then this step size h is considered successful, and the next integration step size h' is predicted as:
h' = h * Math.pow((ErrorTolerance/LTE), 1.0/5.0)This is a fourth order method, but uses a fifth order procedure to estimate the local truncation error.
It takes 6 steps for this solver to resolve a state with an integration step size.
Green (hyzheng) |
Green (hyzheng) |
Modifier and Type | Field and Description |
---|---|
protected static double[] |
_TIME_INCREMENTS
The ratio of time increments within one integration step.
|
_director
Constructor and Description |
---|
ExplicitRK45Solver() |
Modifier and Type | Method and Description |
---|---|
protected int |
_getRound()
Return the current round.
|
protected double |
_getRoundTimeIncrement()
Get the current round factor.
|
protected boolean |
_isStepFinished()
Return true if the current integration step is finished.
|
protected void |
_reset()
Reset the solver, indicating to it that we are starting an
integration step.
|
protected void |
_setRound(int round)
Set the round for the next integration step.
|
int |
getIntegratorAuxVariableCount()
Return the number of time increments plus one (to store the
truncation error).
|
void |
integratorIntegrate(ContinuousIntegrator integrator)
Fire the given integrator.
|
boolean |
integratorIsAccurate(ContinuousIntegrator integrator)
Return true if the integration is accurate for the given
integrator.
|
double |
integratorSuggestedStepSize(ContinuousIntegrator integrator)
Predict the next step size for the integrators executed under this
solver.
|
_debug, _isDebugging, _makeSolverOf
protected static final double[] _TIME_INCREMENTS
public final int getIntegratorAuxVariableCount()
getIntegratorAuxVariableCount
in class ContinuousODESolver
public void integratorIntegrate(ContinuousIntegrator integrator) throws IllegalActionException
integratorIntegrate
in class ContinuousODESolver
integrator
- The integrator of that calls this method.IllegalActionException
- If there is no director, or can not
read input, or can not send output.public boolean integratorIsAccurate(ContinuousIntegrator integrator)
integratorIsAccurate
in class ContinuousODESolver
integrator
- The integrator of that calls this method.public double integratorSuggestedStepSize(ContinuousIntegrator integrator)
integratorSuggestedStepSize
in class ContinuousODESolver
integrator
- The integrator that calls this method.protected int _getRound()
_getRound
in class ContinuousODESolver
protected final double _getRoundTimeIncrement()
_getRoundTimeIncrement
in class ContinuousODESolver
ContinuousODESolver._isStepFinished()
protected final boolean _isStepFinished()
_isStepFinished
in class ContinuousODESolver
_reset()
protected final void _reset()
_reset
in class ContinuousODESolver
protected void _setRound(int round)
_setRound
in class ContinuousODESolver
round
- The round for the next integration step.ContinuousODESolver.getIntegratorAuxVariableCount()