conspire/math/integrate/field/state/
mod.rs1use super::{
2 Integrable,
3 adaptive::{integrate_rkmk, integrate_rkmk_adaptive},
4};
5use crate::math::{
6 Derivative, Differentiable, Quantity, Scalar, TensorVec,
7 integrate::{ButcherTableau, EmbeddedTableau, IntegrationError, Times},
8};
9use crate::units::Time;
10use std::ops::Mul;
11
12pub type EvolvedState<M, T = Time, Y = Quantity> =
14 <<M as StateEvolution<T, Y>>::Field as Integrable>::Point;
15
16pub type EvolvedIncrement<M, T = Time, Y = Quantity> =
18 <<M as StateEvolution<T, Y>>::Field as Integrable>::Increment;
19
20pub trait StateEvolution<T = Time, Y = Quantity>
28where
29 <Self::Field as Integrable>::Increment: Differentiable<T>,
30{
31 type Field: Integrable;
33 type Drive;
35 fn initial_state(&self) -> <Self::Field as Integrable>::Point;
37 fn state_rate(
39 &self,
40 time: Quantity<T>,
41 drive: &Self::Drive,
42 state: &<Self::Field as Integrable>::Point,
43 ) -> Result<Derivative<<Self::Field as Integrable>::Increment, T>, String>;
44}
45
46pub fn integrate_rkmk_state<M, Tab, U, T, Y>(
49 model: &M,
50 mut drive: impl FnMut(Quantity<T>) -> M::Drive,
51 time: &[Quantity<T>],
52) -> Result<(Times<T>, U), IntegrationError>
53where
54 M: StateEvolution<T, Y>,
55 Tab: ButcherTableau,
56 EvolvedState<M, T, Y>: Clone,
57 EvolvedIncrement<M, T, Y>: Clone + Differentiable<T>,
58 T: Copy,
59 Quantity<T>: Mul<Scalar, Output = Quantity<T>>,
60 for<'a> &'a Derivative<EvolvedIncrement<M, T, Y>, T>:
61 Mul<Quantity<T>, Output = EvolvedIncrement<M, T, Y>>,
62 U: TensorVec<Item = EvolvedState<M, T, Y>>,
63{
64 let initial = model.initial_state();
65 integrate_rkmk::<M::Field, Tab, U, T>(
66 |t, state| model.state_rate(t, &drive(t), state),
67 time,
68 initial,
69 )
70}
71
72pub fn integrate_rkmk_state_adaptive<M, Tab, U, T, Y>(
77 model: &M,
78 mut drive: impl FnMut(Quantity<T>) -> M::Drive,
79 time: &[Quantity<T>],
80 abs_tol: Scalar,
81 rel_tol: Scalar,
82) -> Result<(Times<T>, U), IntegrationError>
83where
84 M: StateEvolution<T, Y>,
85 Tab: EmbeddedTableau,
86 EvolvedState<M, T, Y>: Clone,
87 EvolvedIncrement<M, T, Y>: Clone + Differentiable<T>,
88 T: Copy,
89 Quantity<T>: Mul<Scalar, Output = Quantity<T>>,
90 for<'a> &'a Derivative<EvolvedIncrement<M, T, Y>, T>:
91 Mul<Quantity<T>, Output = EvolvedIncrement<M, T, Y>>,
92 U: TensorVec<Item = EvolvedState<M, T, Y>>,
93{
94 let initial = model.initial_state();
95 integrate_rkmk_adaptive::<M::Field, Tab, U, T>(
96 |t, state| model.state_rate(t, &drive(t), state),
97 time,
98 initial,
99 abs_tol,
100 rel_tol,
101 )
102}
103
104