1extern crate maths_traits;
46
47use maths_traits::algebra::module_like::*;
48use maths_traits::analysis::metric::*;
49use maths_traits::analysis::real::*;
50
51type Eval<'a,R,S> = &'a dyn Fn(R,S) -> S;
52
53pub trait Integrator {
54 fn init<R:Real, S:VectorSpace<R>, F:Fn(R, S) -> S>(&self, state: S, _dt:R, _force: F) -> Box<[S]> {Box::new([state])}
55 fn step<R:Real, S:VectorSpace<R>, F:Fn(R, S) -> S>(&self, time:R, state: &mut [S], dt:R, force: F) -> S;
56}
57
58pub trait Integrates<R:Real, S:VectorSpace<R>> {
59 fn init(&self, state: S, _dt:R, _force:Eval<R,S>) -> Box<[S]> {Box::new([state])}
60 fn step(&self, time:R, state: &mut [S], dt:R, force:Eval<R,S>) -> S;
61}
62
63impl<I:Integrator, R:Real, S:VectorSpace<R>> Integrates<R,S> for I {
64 fn init(&self, state: S, dt:R, force:Eval<R,S>) -> Box<[S]> {
65 Integrator::init(self, state, dt, &*force)
66 }
67 fn step(&self, time:R, state: &mut [S], dt:R, force:Eval<R,S>) -> S {
68 Integrator::step(self, time, state, dt, &*force)
69 }
70}
71
72pub trait VelIntegrator {
73 fn init_with_vel<
74 R:Real, S:VectorSpace<R>, V:Fn(R,S)->S, F:Fn(R,S)->S
75 > (&self, state: S, _dt:R, _vel:V, _force:F) -> Box<[S]> {Box::new([state])}
76
77 fn step_with_vel<
78 R:Real, S:VectorSpace<R>, V:Fn(R,S)->S, F:Fn(R,S)->S
79 >(&self, time:R, state: &mut [S], dt:R, velocity:V, force:F) -> S;
80}
81
82pub trait VelIntegrates<R:Real, S:VectorSpace<R>> {
83 fn init_with_vel(&self, state: S, _dt:R, _vel:Eval<R,S>, _force:Eval<R,S>) -> Box<[S]> {Box::new([state])}
84 fn step_with_vel(&self, time:R, state: &mut [S], dt:R, vel:Eval<R,S>, force:Eval<R,S>) -> S;
85}
86
87impl<I:VelIntegrator, R:Real, S:VectorSpace<R>> VelIntegrates<R,S> for I {
88 fn init_with_vel(&self, state: S, dt:R, vel:Eval<R,S>, force:Eval<R,S>) -> Box<[S]> {
89 VelIntegrator::init_with_vel(self, state, dt, &*vel, &*force)
90 }
91 fn step_with_vel(&self, time:R, state: &mut [S], dt:R, vel:Eval<R,S>, force:Eval<R,S>) -> S {
92 VelIntegrator::step_with_vel(self, time, state, dt, &*vel, &*force)
93 }
94}
95
96pub trait AdaptiveIntegrator {
97 fn adaptive_init<R:Real, S:VectorSpace<R>, M:Metric<S,R>, F:Fn(R, S) -> S>(&self, t0:R, state: S, _ds:R, _force:F, _d:M) -> Box<[(R,S)]>{
98 Box::new([(t0, state)])
99 }
100 fn adaptive_step<R:Real, S:VectorSpace<R>, M:Metric<S,R>, F:Fn(R, S) -> S>(&self, state: &mut [(R,S)], ds:R, force:F, d:M) -> (R,S);
101}
102
103pub use runge_kutta::*;
104pub mod runge_kutta;
105
106#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
107pub struct VelocityVerlet;
108
109impl VelIntegrator for VelocityVerlet {
110 fn init_with_vel<R:Real, S:VectorSpace<R>, V:Fn(R,S)->S, F:Fn(R,S)->S>(
111 &self, state: S, _dt:R, _vel:V, _force:F
112 ) -> Box<[S]> {
113 Box::new([state, S::zero()])
114 }
115
116 fn step_with_vel<R:Real, S:VectorSpace<R>, V:Fn(R,S)->S, F:Fn(R,S)->S>(
117 &self, time:R, state: &mut [S], dt:R, velocity:V, force:F
118 ) -> S {
119
120 let (s1, rest) = state.split_first_mut().unwrap();
121 let (a1, _) = rest.split_first_mut().unwrap();
122
123 let mid =
124 s1.clone() +
125 a1.clone()*dt.clone() +
126 velocity(time.clone(), a1.clone()) * (dt.clone()*dt.clone()*R::repr(0.5));
127
128 *s1 += a1.clone()*(dt.clone()*R::repr(0.5));
129 *a1 = force(time.clone() + dt.clone(), mid);
130 *s1 += a1.clone()*(dt.clone()*R::repr(0.5));
131
132 s1.clone()
133 }
134}