Source code for pathsim.solvers.rkdp54

########################################################################################
##
##                EXPLICIT ADAPTIVE TIMESTEPPING RUNGE-KUTTA INTEGRATORS
##                                (solvers/rkdp54.py)
##
##                                 Milan Rother 2024
##
########################################################################################

# IMPORTS ==============================================================================

from ._rungekutta import ExplicitRungeKutta


# SOLVERS ==============================================================================

[docs] class RKDP54(ExplicitRungeKutta): """Dormand-Prince 5(4) pair (DOPRI5). Seven stages, 5th order with embedded 4th order error estimate. The industry-standard adaptive explicit solver and the basis of MATLAB's ``ode45``. Has the FSAL property (not exploited in this implementation, so all seven stages are evaluated each step). Characteristics --------------- * Order: 5 (propagating) / 4 (embedded) * Stages: 7 * Explicit, adaptive timestep Note ---- Recommended default for non-stiff block diagrams. Handles smooth nonlinear dynamics, coupled oscillators, and signal-processing chains efficiently. If the simulation warns about excessive step rejections or very small timesteps, the system is likely stiff and an implicit solver (``ESDIRK43``, ``GEAR52A``) should be used instead. For very tight tolerances on smooth problems, ``RKV65`` or ``RKDP87`` can be more efficient per unit accuracy. References ---------- .. [1] Dormand, J. R., & Prince, P. J. (1980). "A family of embedded Runge-Kutta formulae". Journal of Computational and Applied Mathematics, 6(1), 19-26. :doi:`10.1016/0771-050X(80)90013-3` .. [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 = 7 #order of scheme and embedded method self.n = 5 self.m = 4 #flag adaptive timestep solver self.is_adaptive = True #intermediate evaluation times self.eval_stages = [0.0, 1/5, 3/10, 4/5, 8/9, 1.0, 1.0] #extended butcher table self.BT = { 0: [ 1/5], 1: [ 3/40, 9/40], 2: [ 44/45, -56/15, 32/9], 3: [19372/6561, -25360/2187, 64448/6561, -212/729], 4: [ 9017/3168, -355/33, 46732/5247, 49/176, -5103/18656], 5: [ 35/384, 0, 500/1113, 125/192, -2187/6784, 11/84], 6: [ 35/384, 0, 500/1113, 125/192, -2187/6784, 11/84] } #coefficients for local truncation error estimate self.TR = [71/57600, 0, - 71/16695, 71/1920, -17253/339200, 22/525, -1/40]