radau5_step_audit/
radau5_step_audit.rs1use numra_ode::problem::OdeProblem;
7use numra_ode::radau5::Radau5;
8use numra_ode::solver::{Solver, SolverOptions};
9
10fn run<F>(name: &str, rhs: F, t0: f64, tf: f64, y0: Vec<f64>, rtol: f64, atol: f64)
11where
12 F: Fn(f64, &[f64], &mut [f64]) + Copy,
13{
14 let problem = OdeProblem::new(rhs, t0, tf, y0.clone());
15 let opts = SolverOptions::default().rtol(rtol).atol(atol);
16 let res = Radau5::solve(&problem, t0, tf, &y0, &opts).expect("solve failed");
17 println!(
18 "{:<32} acc={:>4} rej={:>3} rhs={:>5} jac={:>3} lu={:>4}",
19 name,
20 res.stats.n_accept,
21 res.stats.n_reject,
22 res.stats.n_eval,
23 res.stats.n_jac,
24 res.stats.n_lu,
25 );
26}
27
28fn main() {
29 println!("Radau5 step-count audit (after corrections)");
30 println!("--------------------------------------------");
31
32 run(
33 "stiff decay (rtol=1e-2)",
34 |_, y, dy| dy[0] = -100.0 * y[0],
35 0.0,
36 0.1,
37 vec![1.0],
38 1e-2,
39 1e-4,
40 );
41
42 run(
43 "exponential (rtol=1e-6)",
44 |_, y, dy| dy[0] = y[0],
45 0.0,
46 1.0,
47 vec![1.0],
48 1e-6,
49 1e-8,
50 );
51
52 run(
53 "linear 2D (rtol=1e-4)",
54 |_, y, dy| {
55 dy[0] = -y[0] + y[1];
56 dy[1] = -y[0] - y[1];
57 },
58 0.0,
59 1.0,
60 vec![1.0, 0.0],
61 1e-4,
62 1e-6,
63 );
64
65 let mu_mild = 10.0;
66 run(
67 "van der Pol mu=10 (rtol=1e-4)",
68 move |_, y, dy| {
69 dy[0] = y[1];
70 dy[1] = mu_mild * (1.0 - y[0] * y[0]) * y[1] - y[0];
71 },
72 0.0,
73 2.0,
74 vec![2.0, 0.0],
75 1e-4,
76 1e-6,
77 );
78
79 let mu_stiff = 100.0;
80 run(
81 "van der Pol mu=100 (rtol=1e-3)",
82 move |_, y, dy| {
83 dy[0] = y[1];
84 dy[1] = mu_stiff * (1.0 - y[0] * y[0]) * y[1] - y[0];
85 },
86 0.0,
87 20.0,
88 vec![2.0, 0.0],
89 1e-3,
90 1e-5,
91 );
92}