differential_equations/
error.rs

1//! NumericalMethod Trait for Differential Equation NumericalMethods
2
3use crate::traits::{Real, State};
4use std::fmt::{Debug, Display};
5
6/// Error for Differential Equation NumericalMethods
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 { t_interp, t_prev, t_curr } => {
58                write!(f, "Interpolation Error: t_interp {} is not within the previous and current step: t_prev {}, t_curr {}", t_interp, t_prev, t_curr)
59            }
60        }
61    }
62}
63
64impl<T, V> Debug for Error<T, V>
65where
66    T: Real + Debug,
67    V: State<T> + Debug,
68{
69    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70        match self {
71            Self::BadInput { msg } => write!(f, "Bad Input: {}", msg),
72            Self::MaxSteps { t, y } => {
73                write!(f, "Maximum steps reached at (t, y) = ({:?}, {:?})", t, y)
74            }
75            Self::StepSize { t, y } => {
76                write!(f, "Step size too small at (t, y) = ({:?}, {:?})", t, y)
77            }
78            Self::Stiffness { t, y } => {
79                write!(f, "Stiffness detected at (t, y) = ({:?}, {:?})", t, y)
80            }
81            Self::OutOfBounds { t_interp, t_prev, t_curr } => {
82                write!(f, "Interpolation Error: t_interp {:?} is not within the previous and current step: t_prev {:?}, t_curr {:?}", t_interp, t_prev, t_curr)
83            }
84        }
85    }
86}
87
88impl<T, V> std::error::Error for Error<T, V>
89where
90    T: Real + Debug + Display,
91    V: State<T> + Debug + Display,
92{
93}