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