conspire/math/integrate/ode/implicit/trapezoidal/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::math::{
5 Scalar, Tensor, TensorArray, TensorVec,
6 integrate::{
7 FixedStep, ImplicitFirstOrder, ImplicitZerothOrder, IntegrationError, OdeIntegrator,
8 },
9};
10use std::{
11 fmt::Debug,
12 ops::{Add, Mul, Sub},
13};
14
15#[doc = include_str!("doc.md")]
16#[derive(Debug, Default)]
17pub struct Trapezoidal {
18 dt: Scalar,
20}
21
22impl<Y, U> OdeIntegrator<Y, U> for Trapezoidal
23where
24 Y: Tensor,
25 U: TensorVec<Item = Y>,
26{
27}
28
29impl FixedStep for Trapezoidal {
30 fn dt(&self) -> Scalar {
31 self.dt
32 }
33}
34
35impl<Y, U> ImplicitZerothOrder<Y, U> for Trapezoidal
36where
37 Y: Tensor,
38 for<'a> &'a Y: Mul<Scalar, Output = Y> + Add<&'a Y, Output = Y> + Sub<&'a Y, Output = Y>,
39 U: TensorVec<Item = Y>,
40{
41 fn residual(
42 &self,
43 mut function: impl FnMut(Scalar, &Y) -> Result<Y, IntegrationError>,
44 t: Scalar,
45 y: &Y,
46 t_trial: Scalar,
47 y_trial: &Y,
48 dt: Scalar,
49 ) -> Result<Y, String> {
50 Ok(y_trial - y - (function(t, y)? + function(t_trial, y_trial)?) * (0.5 * dt))
51 }
52}
53
54impl<Y, J, U> ImplicitFirstOrder<Y, J, U> for Trapezoidal
55where
56 Y: Tensor,
57 for<'a> &'a Y: Mul<Scalar, Output = Y> + Add<&'a Y, Output = Y> + Sub<&'a Y, Output = Y>,
58 J: Tensor + TensorArray,
59 U: TensorVec<Item = Y>,
60{
61 fn hessian(
62 &self,
63 mut jacobian: impl FnMut(Scalar, &Y) -> Result<J, IntegrationError>,
64 _t: Scalar,
65 _y: &Y,
66 t_trial: Scalar,
67 y_trial: &Y,
68 dt: Scalar,
69 ) -> Result<J, String> {
70 Ok(J::identity() - jacobian(t_trial, y_trial)? * (0.5 * dt))
71 }
72}