Source code for pathsim.solvers.rkbs32
########################################################################################
##
## EXPLICIT ADAPTIVE TIMESTEPPING RUNGE-KUTTA INTEGRATORS
## (solvers/rkbs32.py)
##
## Milan Rother 2024
##
########################################################################################
# IMPORTS ==============================================================================
from ._rungekutta import ExplicitRungeKutta
# SOLVERS ==============================================================================
[docs]
class RKBS32(ExplicitRungeKutta):
"""Bogacki-Shampine 3(2) pair. Four-stage, 3rd order with FSAL property.
The underlying method of MATLAB's ``ode23``. The First-Same-As-Last
(FSAL) property makes the effective cost three stages per accepted step.
Characteristics
---------------
* Order: 3 (propagating) / 2 (embedded)
* Stages: 4 (3 effective with FSAL)
* Explicit, adaptive timestep
Note
----
A good default when moderate accuracy suffices and per-step cost matters
more than large step sizes. Fewer stages than 5th order pairs, so faster
per step but needs more steps for the same global error. In a PathSim
block diagram with smooth, non-stiff dynamics and relaxed tolerances this
is often the most efficient explicit choice. Switch to ``RKDP54`` when
tighter tolerances are required.
References
----------
.. [1] Bogacki, P., & Shampine, L. F. (1989). "A 3(2) pair of
Runge-Kutta formulas". Applied Mathematics Letters, 2(4),
321-325. :doi:`10.1016/0893-9659(89)90079-7`
.. [2] Shampine, L. F., & Reichelt, M. W. (1997). "The MATLAB ODE
Suite". SIAM Journal on Scientific Computing, 18(1), 1-22.
:doi:`10.1137/S1064827594276424`
"""
def __init__(self, *solver_args, **solver_kwargs):
super().__init__(*solver_args, **solver_kwargs)
#number of stages in RK scheme
self.s = 4
#order of scheme and embedded method
self.n = 3
self.m = 2
#flag adaptive timestep solver
self.is_adaptive = True
#intermediate evaluation times
self.eval_stages = [0.0, 1/2, 3/4, 1.0]
#extended butcher table
self.BT = {
0: [1/2],
1: [0.0 , 3/4],
2: [2/9 , 1/3, 4/9],
3: [2/9 , 1/3, 4/9]
}
#coefficients for truncation error estimate
self.TR = [-5/72, 1/12, 1/9, -1/8]