differential_equations/
error.rs

1//! NumericalMethod Trait for Differential Equations Crate
2
3use crate::traits::{Real, State};
4use std::fmt::{Debug, Display};
5
6/// Error for Differential Equations Crate
7///
8/// # Variants
9/// * `BadInput` - NumericalMethod input was bad.
10/// * `MaxSteps` - NumericalMethod reached maximum steps.
11/// * `StepSize` - NumericalMethod terminated due to step size converging too small of a value.
12/// * `Stiffness` - NumericalMethod terminated due to stiffness.
13///
14#[derive(PartialEq, Clone)]
15pub enum Error<T, V>
16where
17    T: Real,
18    V: State<T>,
19{
20    /// NumericalMethod input was bad
21    BadInput {
22        msg: String, // if input is bad, return this with reason
23    },
24    MaxSteps {
25        // If the solver reaches the maximum number of steps
26        t: T, // Time at which the solver reached maximum steps
27        y: V, // Solution at time t
28    },
29    StepSize {
30        t: T, // Time at which step size became too small
31        y: V, // Solution at time t
32    },
33    Stiffness {
34        t: T, // Time at which stiffness was detected
35        y: V, // Solution at time t
36    },
37    OutOfBounds {
38        t_interp: T, // Time to interpolate at
39        t_prev: T,   // Time of previous step
40        t_curr: T,   // Time of current step
41    },
42}
43
44impl<T, V> Display for Error<T, V>
45where
46    T: Real + Display,
47    V: State<T> + Display,
48{
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        match self {
51            Self::BadInput { msg } => write!(f, "Bad Input: {}", msg),
52            Self::MaxSteps { t, y } => {
53                write!(f, "Maximum steps reached at (t, y) = ({}, {})", t, y)
54            }
55            Self::StepSize { t, y } => write!(f, "Step size too small at (t, y) = ({}, {})", t, y),
56            Self::Stiffness { t, y } => write!(f, "Stiffness detected at (t, y) = ({}, {})", t, y),
57            Self::OutOfBounds {
58                t_interp,
59                t_prev,
60                t_curr,
61            } => {
62                write!(
63                    f,
64                    "Interpolation Error: t_interp {} is not within the previous and current step: t_prev {}, t_curr {}",
65                    t_interp, t_prev, t_curr
66                )
67            }
68        }
69    }
70}
71
72impl<T, V> Debug for Error<T, V>
73where
74    T: Real + Debug,
75    V: State<T> + Debug,
76{
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        match self {
79            Self::BadInput { msg } => write!(f, "Bad Input: {}", msg),
80            Self::MaxSteps { t, y } => {
81                write!(f, "Maximum steps reached at (t, y) = ({:?}, {:?})", t, y)
82            }
83            Self::StepSize { t, y } => {
84                write!(f, "Step size too small at (t, y) = ({:?}, {:?})", t, y)
85            }
86            Self::Stiffness { t, y } => {
87                write!(f, "Stiffness detected at (t, y) = ({:?}, {:?})", t, y)
88            }
89            Self::OutOfBounds {
90                t_interp,
91                t_prev,
92                t_curr,
93            } => {
94                write!(
95                    f,
96                    "Interpolation Error: t_interp {:?} is not within the previous and current step: t_prev {:?}, t_curr {:?}",
97                    t_interp, t_prev, t_curr
98                )
99            }
100        }
101    }
102}
103
104impl<T, V> std::error::Error for Error<T, V>
105where
106    T: Real + Debug + Display,
107    V: State<T> + Debug + Display,
108{
109}