differential_equations/
error.rs

1//! Errors for Differential Equations Crate
2
3use std::fmt::{Debug, Display};
4
5use crate::traits::{Real, State};
6
7/// Error for Differential Equations Crate
8#[derive(PartialEq, Clone)]
9pub enum Error<T, Y>
10where
11    T: Real,
12    Y: State<T>,
13{
14    /// NumericalMethod input was bad
15    BadInput { msg: String },
16
17    /// Maximum steps reached
18    MaxSteps { t: T, y: Y },
19
20    /// Step size became too small
21    StepSize { t: T, y: Y },
22
23    /// Stiffness detected
24    Stiffness { t: T, y: Y },
25
26    /// Out of bounds error
27    OutOfBounds { t_interp: T, t_prev: T, t_curr: T },
28
29    /// DDE requires at least one lag (L > 0)
30    NoLags,
31
32    /// Not enough history retained to evaluate a delayed state
33    InsufficientHistory { t_delayed: T, t_prev: T, t_curr: T },
34
35    /// General linear algebra error
36    LinearAlgebra { msg: String },
37}
38
39impl<T, Y> Display for Error<T, Y>
40where
41    T: Real + Display,
42    Y: State<T> + Display,
43{
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        match self {
46            Self::BadInput { msg } => write!(
47                f,
48                "Bad input: {}. Check your problem definition, dimensions, and solver options.",
49                msg
50            ),
51            Self::MaxSteps { t, y } => {
52                write!(
53                    f,
54                    "Maximum step count reached at (t, y) = ({}, {}). Try increasing max_steps, relaxing tolerances, or shortening the integration interval.",
55                    t, y
56                )
57            }
58            Self::StepSize { t, y } => write!(
59                f,
60                "Step size became too small at (t, y) = ({}, {}). This often indicates stiffness or overly tight tolerances. Consider using a stiff solver (DIRK/IRK), relaxing rtol/atol, or rescaling the problem.",
61                t, y
62            ),
63            Self::Stiffness { t, y } => write!(
64                f,
65                "Stiffness detected at (t, y) = ({}, {}). Switch to a stiff method (e.g., DIRK or IRK) or relax tolerances to improve stability.",
66                t, y
67            ),
68            Self::OutOfBounds {
69                t_interp,
70                t_prev,
71                t_curr,
72            } => {
73                write!(
74                    f,
75                    "Interpolation error: requested t_interp {} is outside the last step: [t_prev {}, t_curr {}]. Dense output is only valid within a completed step; request t within this interval or use t_eval to sample during integration.",
76                    t_interp, t_prev, t_curr
77                )
78            }
79            Self::NoLags => write!(
80                f,
81                "Invalid DDE configuration: number of lags L must be > 0. If there are no delays, use an ODE solver instead."
82            ),
83            Self::InsufficientHistory {
84                t_delayed,
85                t_prev,
86                t_curr,
87            } => {
88                write!(
89                    f,
90                    "Insufficient history to interpolate at delayed time {} (window: [t_prev {}, t_curr {}]). Possible causes: max_delay is too small or history pruning is too aggressive, or steps advanced before enough history accumulated. Consider increasing max_delay, providing a longer initial history, or reducing maximum step size.",
91                    t_delayed, t_prev, t_curr
92                )
93            }
94            Self::LinearAlgebra { msg } => write!(f, "Linear algebra error: {}", msg),
95        }
96    }
97}
98
99impl<T, Y> Debug for Error<T, Y>
100where
101    T: Real + Debug,
102    Y: State<T> + Debug,
103{
104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105        match self {
106            Self::BadInput { msg } => write!(
107                f,
108                "Bad input: {}. Check your problem definition, dimensions, and solver options.",
109                msg
110            ),
111            Self::MaxSteps { t, y } => {
112                write!(
113                    f,
114                    "Maximum step count reached at (t, y) = ({:?}, {:?}). Try increasing max_steps, relaxing tolerances, or shortening the integration interval.",
115                    t, y
116                )
117            }
118            Self::StepSize { t, y } => {
119                write!(
120                    f,
121                    "Step size became too small at (t, y) = ({:?}, {:?}). This often indicates stiffness or overly tight tolerances. Consider using a stiff solver (DIRK/IRK), relaxing rtol/atol, or rescaling the problem.",
122                    t, y
123                )
124            }
125            Self::Stiffness { t, y } => {
126                write!(
127                    f,
128                    "Stiffness detected at (t, y) = ({:?}, {:?}). Switch to a stiff method (e.g., DIRK or IRK) or relax tolerances to improve stability.",
129                    t, y
130                )
131            }
132            Self::OutOfBounds {
133                t_interp,
134                t_prev,
135                t_curr,
136            } => {
137                write!(
138                    f,
139                    "Interpolation error: requested t_interp {:?} is outside the last step: [t_prev {:?}, t_curr {:?}]. Dense output is only valid within a completed step; request t within this interval or use t_eval to sample during integration.",
140                    t_interp, t_prev, t_curr
141                )
142            }
143            Self::NoLags => write!(
144                f,
145                "Invalid DDE configuration: number of lags L must be > 0. If there are no delays, use an ODE solver instead."
146            ),
147            Self::InsufficientHistory {
148                t_delayed,
149                t_prev,
150                t_curr,
151            } => {
152                write!(
153                    f,
154                    "Insufficient history to interpolate at delayed time {:?} (window: [t_prev {:?}, t_curr {:?}]). Possible causes: max_delay is too small or history pruning is too aggressive, or steps advanced before enough history accumulated. Consider increasing max_delay, providing a longer initial history, or reducing maximum step size.",
155                    t_delayed, t_prev, t_curr
156                )
157            }
158            Self::LinearAlgebra { msg } => write!(f, "Linear algebra error: {}", msg),
159        }
160    }
161}
162
163impl<T, Y> std::error::Error for Error<T, Y>
164where
165    T: Real + Debug + Display,
166    Y: State<T> + Debug + Display,
167{
168}