Skip to content

Commit 921857e

Browse files
committed
Implement constants module to store shared numerical values
1 parent d881e19 commit 921857e

4 files changed

Lines changed: 72 additions & 15 deletions

File tree

src/constants.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use crate::dop_shared::FloatNumber;
2+
3+
/// Stiffness detection thresholds for different methods
4+
pub mod stiffness {
5+
use super::FloatNumber;
6+
7+
/// Stiffness threshold for DOPRI5 method
8+
/// Based on Hairer & Wanner, "Solving Ordinary Differential Equations II"
9+
pub fn dopri5_threshold<T: FloatNumber>() -> T {
10+
T::from(3.25).unwrap()
11+
}
12+
13+
/// Stiffness threshold for DOP853 method
14+
/// Based on Hairer & Wanner, "Solving Ordinary Differential Equations II"
15+
pub fn dop853_threshold<T: FloatNumber>() -> T {
16+
T::from(6.1).unwrap()
17+
}
18+
19+
/// Maximum consecutive stiffness detections before error
20+
pub const MAX_STIFF_ITERATIONS: u32 = 15;
21+
22+
/// Number of non-stiff steps needed to reset stiffness counter
23+
pub const NON_STIFF_RESET_COUNT: u32 = 6;
24+
}
25+
26+
/// Initial step size computation constants
27+
pub mod initial_step {
28+
use super::FloatNumber;
29+
30+
/// Minimum tolerance for initial step computation
31+
pub fn min_tolerance<T: FloatNumber>() -> T {
32+
T::from(1.0e-10).unwrap()
33+
}
34+
35+
/// Default initial step when tolerance conditions not met
36+
pub fn default_initial_step<T: FloatNumber>() -> T {
37+
T::from(1.0e-6).unwrap()
38+
}
39+
40+
/// Safety factor for initial step estimation
41+
pub fn safety_factor<T: FloatNumber>() -> T {
42+
T::from(0.01).unwrap()
43+
}
44+
}
45+
46+
/// Dense output interpolation constants
47+
pub mod dense_output {
48+
use super::FloatNumber;
49+
50+
/// Floating point tolerance for endpoint detection
51+
pub fn endpoint_tolerance<T: FloatNumber>() -> T {
52+
T::from(1.0e-9).unwrap()
53+
}
54+
}

src/dop853.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Explicit Runge-Kutta method with Dormand-Prince coefficients of order 8(5,3) and dense output of order 7.
22
33
use crate::butcher_tableau::dopri853;
4+
use crate::constants::{dense_output, initial_step, stiffness};
45
use crate::controller::Controller;
56
use crate::dop_shared::*;
67

@@ -210,11 +211,11 @@ where
210211
}
211212

212213
// Compute h0
213-
let tol = T::from(1.0E-10).unwrap();
214-
let mut h0 = if d0 < tol || d1 < tol {
215-
T::from(1.0E-6).unwrap()
214+
let tol = initial_step::min_tolerance();
215+
let mut h0: T = if d0 < tol || d1 < tol {
216+
initial_step::default_initial_step()
216217
} else {
217-
T::from(0.01).unwrap() * (d0 / d1).sqrt()
218+
initial_step::safety_factor::<T>() * (d0 / d1).sqrt()
218219
};
219220

220221
h0 = h0.min(self.controller.h_max());
@@ -377,18 +378,18 @@ where
377378
T::zero()
378379
};
379380

380-
if h_lamb > T::from(6.1).unwrap() {
381+
if h_lamb > stiffness::dop853_threshold() {
381382
non_stiff = 0;
382383
iasti += 1;
383-
if iasti == 15 {
384+
if iasti == stiffness::MAX_STIFF_ITERATIONS {
384385
self.h_old = self.h;
385386
return Err(IntegrationError::StiffnessDetected {
386387
x: f64::from(self.x),
387388
});
388389
}
389390
} else {
390391
non_stiff += 1;
391-
if non_stiff == 6 {
392+
if non_stiff == stiffness::NON_STIFF_RESET_COUNT {
392393
iasti = 0;
393394
}
394395
}
@@ -528,7 +529,7 @@ where
528529
}
529530

530531
// Ensure the last point is added if it's within floating point error of x_end.
531-
if (self.xd - self.x_end).abs() < T::from(1e-9).unwrap() {
532+
if (self.xd - self.x_end).abs() < dense_output::endpoint_tolerance() {
532533
let theta = (self.x_end - self.x_old) / self.h_old;
533534
let theta1 = T::one() - theta;
534535
let y_out = self.compute_y_out(theta, theta1);

src/dopri5.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Explicit Runge-Kutta method with Dormand-Prince coefficients of order 5(4) and dense output of order 4.
22
33
use crate::butcher_tableau::dopri54;
4+
use crate::constants::{dense_output, initial_step, stiffness};
45
use crate::continuous_output_model::ContinuousOutputModel;
56
use crate::controller::Controller;
67
use crate::dop_shared::*;
@@ -202,11 +203,11 @@ where
202203
}
203204

204205
// Compute h0
205-
let tol = T::from(1.0E-10).unwrap();
206+
let tol = initial_step::min_tolerance();
206207
let mut h0 = if d0 < tol || d1 < tol {
207-
T::from(1.0E-6).unwrap()
208+
initial_step::default_initial_step()
208209
} else {
209-
T::from(0.01).unwrap() * (d0 / d1).sqrt()
210+
initial_step::safety_factor::<T>() * (d0 / d1).sqrt()
210211
};
211212

212213
h0 = h0.min(self.controller.h_max());
@@ -383,18 +384,18 @@ where
383384
T::zero()
384385
};
385386

386-
if h_lamb > T::from(3.25).unwrap() {
387+
if h_lamb > stiffness::dopri5_threshold() {
387388
iasti += 1;
388389
non_stiff = 0;
389-
if iasti == 15 {
390+
if iasti == stiffness::MAX_STIFF_ITERATIONS {
390391
self.h_old = self.h;
391392
return Err(IntegrationError::StiffnessDetected {
392393
x: f64::from(self.x),
393394
});
394395
}
395396
} else {
396397
non_stiff += 1;
397-
if non_stiff == 6 {
398+
if non_stiff == stiffness::NON_STIFF_RESET_COUNT {
398399
iasti = 0;
399400
}
400401
}
@@ -468,7 +469,7 @@ where
468469
}
469470

470471
// Ensure the last point is added if it's within floating point error of x_end.
471-
if (self.xd - self.x_end).abs() < T::from(1e-9).unwrap() {
472+
if (self.xd - self.x_end).abs() < dense_output::endpoint_tolerance() {
472473
let theta = (self.x_end - self.x_old) / self.h_old;
473474
let theta1 = T::one() - theta;
474475
let y_out = self.compute_y_out(theta, theta1);

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use nalgebra as na;
99

1010
// Declare modules
1111
pub mod butcher_tableau;
12+
mod constants;
1213
pub mod continuous_output_model;
1314
pub mod controller;
1415
pub mod dop853;

0 commit comments

Comments
 (0)