Adaptive stepsize seems to be working
This commit is contained in:
67
src/ode.rs
Normal file
67
src/ode.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
use nalgebra::SVector;
|
||||
|
||||
/// A System trait.
|
||||
///
|
||||
/// The user will have to define their own system. They are free to add params to their system
|
||||
/// definition and use those in the derivative function
|
||||
pub trait SystemTrait<T,const D: usize> {
|
||||
fn derivative(&self, t: T, y: SVector<T,D>) -> SVector<T,D>;
|
||||
}
|
||||
|
||||
/// The basic ODE object that will be passed around. The type (T) and the size (D) will be
|
||||
/// determined upon creation of the object
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ODE<T,F, const D: usize> where F: SystemTrait<T,D>{
|
||||
pub f: F,
|
||||
pub y: SVector<T,D>,
|
||||
pub t: T,
|
||||
pub t0: T,
|
||||
pub t_end: T,
|
||||
pub h: T,
|
||||
pub finished: bool,
|
||||
}
|
||||
|
||||
impl<T, F, const D: usize> ODE<T,F,D>
|
||||
where
|
||||
F: SystemTrait<T,D>,
|
||||
T: Copy + From<f64>,
|
||||
f64: From<T>,
|
||||
{
|
||||
pub fn new(f: F, t0: T, t_end: T, y0: SVector<T,D>) -> Self {
|
||||
Self {
|
||||
f: f,
|
||||
y: y0,
|
||||
t: t0,
|
||||
t0: t0,
|
||||
t_end: t_end,
|
||||
h: 0.001.into(),
|
||||
finished: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use nalgebra::Vector3;
|
||||
|
||||
#[test]
|
||||
fn test_ode_creation() {
|
||||
struct System {}
|
||||
|
||||
impl SystemTrait<f64,3> for System {
|
||||
fn derivative(&self, _t: f64, y: Vector3<f64>) -> Vector3<f64> { -y }
|
||||
}
|
||||
|
||||
let system = System {};
|
||||
let y0 = Vector3::new(1.0, 0.0, 0.0);
|
||||
let ode = ODE::new(system, 0.0, 10.0, y0);
|
||||
|
||||
assert!(ode.f.derivative(0.0, y0) == Vector3::new(-1.0, 0.0, 0.0));
|
||||
assert!(ode.y == Vector3::new(1.0, 0.0, 0.0));
|
||||
assert!(ode.t == 0.0);
|
||||
assert!(!ode.finished);
|
||||
assert!(ode.t_end == 10.0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user