use nalgebra::SVector; use super::ode::ODE; pub mod dormand_prince; // pub mod rosenbrock; /// Integrator Trait pub trait Integrator { const ORDER: usize; const STAGES: usize; const ADAPTIVE: bool; const DENSE: bool; /// Returns a new y value, then possibly an error value, and possibly a dense output /// coefficient set fn step

( &self, ode: &ODE, h: f64, ) -> (SVector, Option, Option>>); fn interpolate( &self, t_start: f64, t_end: f64, dense: &[SVector], t: f64, ) -> SVector; } #[cfg(test)] mod tests { use super::dormand_prince::*; use super::*; use approx::assert_relative_eq; use nalgebra::Vector3; #[test] fn test_dopri() { type Params = (); fn derivative(_t: f64, y: Vector3, _p: &Params) -> Vector3 { y } let y0 = Vector3::new(1.0, 1.0, 1.0); let mut ode = ODE::new(&derivative, 0.0, 4.0, y0, ()); let dp45 = DormandPrince45::new().a_tol(1e-12).r_tol(1e-4); // Test that y'(t) = y(t) solves to y(t) = e^t for rkf54 // and also that the error seems reasonable let step = 0.001; while ode.t < ode.t_end { let (new_y, err, _) = dp45.step(&ode, step); ode.y = new_y; ode.t += step; assert_relative_eq!(ode.y[0], ode.t.exp(), max_relative = 0.01); assert!(err.unwrap() < 1.0); } } }