differential_equations/methods/erk/dormandprince/
mod.rs

1//! Runge-Kutta solvers with support for dense output, embedded error estimation, and fixed steps.
2
3mod ordinary;
4mod delay;
5
6use super::ExplicitRungeKutta;
7use crate::methods::{DormandPrince, Ordinary, Delay};
8
9use crate::{
10    traits::{CallBackData, Real, State},
11    tableau::ButcherTableau,
12};
13
14// Macro for adaptive step constructors
15macro_rules! impl_erk_dormand_prince_constructor {
16    ($method_name:ident, $order_val:expr, $s_val:expr, $m_val:expr, $doc:expr) => {
17        impl<E, T: Real, V: State<T>, D: CallBackData> ExplicitRungeKutta<E, DormandPrince, T, V, D, $order_val, $s_val, $m_val> {
18            #[doc = $doc]
19            pub fn $method_name() -> Self {
20                let tableau = ButcherTableau::<T, $s_val, $m_val>::$method_name();
21                let c = tableau.c;
22                let a = tableau.a;
23                let b = tableau.b;
24                let bh = tableau.bh;
25                let er = tableau.er;
26                let bi = tableau.bi;
27                let fsal = true; // DOP methods are FSAL by definition, also this isn't used in implementation because its assumed but just for consistency
28
29                ExplicitRungeKutta {
30                    c,
31                    a,
32                    b,
33                    bh,
34                    er,
35                    bi,
36                    fsal, 
37                    ..Default::default()
38                }
39            }
40        }
41    };
42}
43
44// Adaptive step methods (embedded error estimation, cubic Hermite interpolation)
45impl_erk_dormand_prince_constructor!(dop853, 8, 12, 16, "Creates the DOP853 method (8th order, 12 stages, 4 dense output stages).");
46impl_erk_dormand_prince_constructor!(dopri5, 5, 7, 7, "Creates the DOPRI5 method (5th order, 7 stages).");