differential_equations/tableau/
radau.rs

1//! Radau Implicit Runge-Kutta methods.
2
3use crate::{tableau::ButcherTableau, traits::Real};
4
5const SQRT_6: f64 = 2.449489743;
6
7impl<T: Real> ButcherTableau<T, 2> {
8    /// Butcher Tableau for the Radau IIA method of order 3.
9    ///
10    /// # Overview
11    /// This provides a 2-stage, implicit Runge-Kutta method (Radau IIA) with:
12    /// - Primary order: 3
13    /// - Embedded order: None (this implementation does not include an embedded error estimate)
14    /// - Number of stages: 2
15    ///
16    /// # Interpolation
17    /// - This standard Radau IIA order 3 implementation does not provide coefficients for dense output (interpolation).
18    ///
19    /// # Notes
20    /// - Radau IIA methods are A-stable and L-stable, making them suitable for stiff differential equations.
21    /// - Being implicit, they generally require solving a system of algebraic equations at each step.
22    ///
23    /// # Butcher Tableau
24    /// ```text
25    /// 1/3 |  5/12  -1/12
26    /// 1   |  3/4    1/4
27    /// ----|---------------
28    ///     |  3/4    1/4
29    /// ```
30    ///
31    /// # References
32    /// - Hairer, E., Nørsett, S. P., & Wanner, G. (1993). *Solving Ordinary Differential Equations I: Nonstiff Problems*. Springer.
33    /// - Hairer, E., & Wanner, G. (1996). *Solving Ordinary Differential Equations II: Stiff and Differential-Algebraic Problems*. Springer.
34    pub fn radau_iia_3() -> Self {
35        let mut c = [0.0; 2];
36        let mut a = [[0.0; 2]; 2];
37        let mut b = [0.0; 2];
38
39        c[0] = 1.0 / 3.0;
40        c[1] = 1.0;
41
42        a[0][0] = 5.0 / 12.0;
43        a[0][1] = -1.0 / 12.0;
44        a[1][0] = 3.0 / 4.0;
45        a[1][1] = 1.0 / 4.0;
46
47        b[0] = 3.0 / 4.0;
48        b[1] = 1.0 / 4.0;
49
50        let c = c.map(|x| T::from_f64(x).unwrap());
51        let a = a.map(|row| row.map(|x| T::from_f64(x).unwrap()));
52        let b = b.map(|x| T::from_f64(x).unwrap());
53
54        Self {
55            c,
56            a,
57            b,
58            bh: None,
59            bi: None,
60            er: None,
61        }
62    }
63}
64
65impl<T: Real> ButcherTableau<T, 3> {
66    /// Butcher Tableau for the Radau IIA method of order 5.
67    ///
68    /// # Overview
69    /// This provides a 3-stage, implicit Runge-Kutta method (Radau IIA) with:
70    /// - Primary order: 5
71    /// - Embedded order: None (this implementation does not include an embedded error estimate)
72    /// - Number of stages: 3
73    ///
74    /// # Interpolation
75    /// - This standard Radau IIA order 5 implementation does not provide coefficients for dense output (interpolation).
76    ///
77    /// # Notes
78    /// - Radau IIA methods are A-stable and L-stable, making them highly suitable for stiff differential equations.
79    /// - Being implicit, they generally require solving a system of algebraic equations at each step.
80    /// - The `c` values are the roots of `P_s(2x-1) - P_{s-1}(2x-1) = 0` where `P_s` is the s-th Legendre polynomial.
81    ///   For s=3, the c values are `(2/5 - sqrt(6)/10)`, `(2/5 + sqrt(6)/10)`, and `1`.
82    ///
83    /// # Butcher Tableau
84    /// ```text
85    /// c1 | a11 a12 a13
86    /// c2 | a21 a22 a23
87    /// c3 | a31 a32 a33
88    /// ---|------------
89    ///    | b1  b2  b3
90    /// ```
91    /// Where:
92    /// c1 = 2/5 - sqrt(6)/10
93    /// c2 = 2/5 + sqrt(6)/10
94    /// c3 = 1
95    ///
96    /// a11 = 11/45 - 7*sqrt(6)/360
97    /// a12 = 37/225 - 169*sqrt(6)/1800
98    /// a13 = -2/225 + sqrt(6)/75
99    ///
100    /// a21 = 37/225 + 169*sqrt(6)/1800
101    /// a22 = 11/45 + 7*sqrt(6)/360
102    /// a23 = -2/225 - sqrt(6)/75
103    ///
104    /// a31 = 4/9 - sqrt(6)/36
105    /// a32 = 4/9 + sqrt(6)/36
106    /// a33 = 1/9
107    ///
108    /// b1 = 4/9 - sqrt(6)/36
109    /// b2 = 4/9 + sqrt(6)/36
110    /// b3 = 1/9
111    ///
112    /// # References
113    /// - Hairer, E., Nørsett, S. P., & Wanner, G. (1993). *Solving Ordinary Differential Equations I: Nonstiff Problems*. Springer.
114    /// - Hairer, E., & Wanner, G. (1996). *Solving Ordinary Differential Equations II: Stiff and Differential-Algebraic Problems*. Springer.
115    pub fn radau_iia_5() -> Self {
116        let mut c = [0.0; 3];
117        let mut a = [[0.0; 3]; 3];
118        let mut b = [0.0; 3];
119
120        c[0] = 2.0 / 5.0 - SQRT_6 / 10.0;
121        c[1] = 2.0 / 5.0 + SQRT_6 / 10.0;
122        c[2] = 1.0;
123
124        a[0][0] = 11.0 / 45.0 - 7.0 * SQRT_6 / 360.0;
125        a[0][1] = 37.0 / 225.0 - 169.0 * SQRT_6 / 1800.0;
126        a[0][2] = -2.0 / 225.0 + SQRT_6 / 75.0;
127
128        a[1][0] = 37.0 / 225.0 + 169.0 * SQRT_6 / 1800.0;
129        a[1][1] = 11.0 / 45.0 + 7.0 * SQRT_6 / 360.0;
130        a[1][2] = -2.0 / 225.0 - SQRT_6 / 75.0;
131
132        a[2][0] = 4.0 / 9.0 - SQRT_6 / 36.0;
133        a[2][1] = 4.0 / 9.0 + SQRT_6 / 36.0;
134        a[2][2] = 1.0 / 9.0;
135
136        b[0] = 4.0 / 9.0 - SQRT_6 / 36.0;
137        b[1] = 4.0 / 9.0 + SQRT_6 / 36.0;
138        b[2] = 1.0 / 9.0;
139
140        let c = c.map(|x| T::from_f64(x).unwrap());
141        let a = a.map(|row| row.map(|x| T::from_f64(x).unwrap()));
142        let b = b.map(|x| T::from_f64(x).unwrap());
143
144        Self {
145            c,
146            a,
147            b,
148            bh: None,
149            bi: None,
150            er: None,
151        }
152    }
153}