Skip to content

Commit 7bb83f8

Browse files
authored
Merge pull request #91 from Axect/features/ode
FIX: Correct adaptive step size exponent for embedded RK methods
2 parents 8acb504 + 36c7089 commit 7bb83f8

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

src/numerical/ode.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,12 @@ pub trait ButcherTableau {
290290
fn max_step_iter(&self) -> usize {
291291
unimplemented!()
292292
}
293+
294+
/// Order of the lower-order solution for adaptive step size control.
295+
/// The exponent `1/(order+1)` is used in the step size formula.
296+
fn order(&self) -> usize {
297+
4
298+
}
293299
}
294300

295301
impl<BU: ButcherTableau> ODEIntegrator for BU {
@@ -324,7 +330,7 @@ impl<BU: ButcherTableau> ODEIntegrator for BU {
324330
error = error.max(dt * s.abs())
325331
}
326332

327-
let factor = (self.tol() / error).powf(0.2);
333+
let factor = (self.tol() / error).powf(1.0 / (self.order() as f64 + 1.0));
328334
let new_dt = self.safety_factor() * dt * factor;
329335
let new_dt = new_dt.clamp(self.min_step_size(), self.max_step_size());
330336

@@ -558,6 +564,9 @@ impl ButcherTableau for BS23 {
558564
fn max_step_iter(&self) -> usize {
559565
self.max_step_iter
560566
}
567+
fn order(&self) -> usize {
568+
2
569+
}
561570
}
562571

563572
/// Runge-Kutta-Fehlberg 4/5th order integrator.
@@ -1098,9 +1107,7 @@ impl ButcherTableau for RKF78 {
10981107
],
10991108
];
11001109

1101-
// Coefficients for the 7th order solution (propagated solution)
1102-
// BU_i = BE_i (8th order) - ErrorCoeff_i
1103-
// ErrorCoeff_i = [-41/840, 0, ..., 0, -41/840 (for k11), 41/840 (for k12), 41/840 (for k13)]
1110+
// Coefficients for the 8th order solution (propagated via local extrapolation)
11041111
const BU: &'static [f64] = &[
11051112
0.0,
11061113
0.0,
@@ -1117,8 +1124,8 @@ impl ButcherTableau for RKF78 {
11171124
41.0 / 840.0,
11181125
];
11191126

1120-
// Coefficients for the 8th order solution (used for error estimation)
1121-
// These are from the y[i+1] formula in the MATLAB description
1127+
// Synthetic coefficients for error estimation
1128+
// BU - BE yields the Fehlberg error formula: 41/840 * (k1 + k11 - k12 - k13)
11221129
const BE: &'static [f64] = &[
11231130
41.0 / 840.0,
11241131
0.0,
@@ -1150,6 +1157,9 @@ impl ButcherTableau for RKF78 {
11501157
fn max_step_iter(&self) -> usize {
11511158
self.max_step_iter
11521159
}
1160+
fn order(&self) -> usize {
1161+
7
1162+
}
11531163
}
11541164

11551165
// ┌─────────────────────────────────────────────────────────┐

0 commit comments

Comments
 (0)