conspire/math/integrate/ode/explicit/fixed_step/ralston/
mod.rs

1#[cfg(test)]
2mod test;
3
4use crate::math::{
5    Scalar, Tensor, TensorVec, Vector,
6    integrate::{Explicit, FixedStep, FixedStepExplicit, IntegrationError, OdeSolver},
7};
8use std::ops::{Add, Mul};
9
10#[doc = include_str!("doc.md")]
11#[derive(Debug, Default)]
12pub struct Ralston {
13    /// Fixed value for the time step.
14    dt: Scalar,
15}
16
17impl<Y, U> OdeSolver<Y, U> for Ralston
18where
19    Y: Tensor,
20    U: TensorVec<Item = Y>,
21{
22}
23
24impl FixedStep for Ralston {
25    fn dt(&self) -> Scalar {
26        self.dt
27    }
28}
29
30impl<Y, U> Explicit<Y, U> for Ralston
31where
32    Self: OdeSolver<Y, U>,
33    Y: Tensor,
34    for<'a> &'a Y: Mul<Scalar, Output = Y> + Add<Y, Output = Y>,
35    U: TensorVec<Item = Y>,
36{
37    const SLOPES: usize = 2;
38    fn integrate(
39        &self,
40        function: impl FnMut(Scalar, &Y) -> Result<Y, String>,
41        time: &[Scalar],
42        initial_condition: Y,
43    ) -> Result<(Vector, U, U), IntegrationError> {
44        self.integrate_fixed_step(function, time, initial_condition)
45    }
46}
47
48impl<Y, U> FixedStepExplicit<Y, U> for Ralston
49where
50    Self: OdeSolver<Y, U>,
51    Y: Tensor,
52    for<'a> &'a Y: Mul<Scalar, Output = Y> + Add<Y, Output = Y>,
53    U: TensorVec<Item = Y>,
54{
55    fn step(
56        &self,
57        mut function: impl FnMut(Scalar, &Y) -> Result<Y, String>,
58        y: &Y,
59        t: Scalar,
60        dt: Scalar,
61        k: &mut [Y],
62        y_trial: &mut Y,
63    ) -> Result<(), String> {
64        *y_trial = &k[0] * (0.75 * dt) + y;
65        k[1] = function(t + 0.75 * dt, y_trial)?;
66        *y_trial = (&k[0] + &k[1] * 2.0) * (dt / 3.0) + y;
67        Ok(())
68    }
69}