1use crate::traits::{Real, State};
4use std::fmt::{Debug, Display};
5
6#[derive(PartialEq, Clone)]
8pub enum Error<T, Y>
9where
10 T: Real,
11 Y: State<T>,
12{
13 BadInput { msg: String },
15
16 MaxSteps { t: T, y: Y },
18
19 StepSize { t: T, y: Y },
21
22 Stiffness { t: T, y: Y },
24
25 OutOfBounds { t_interp: T, t_prev: T, t_curr: T },
27
28 NoLags,
30
31 InsufficientHistory { t_delayed: T, t_prev: T, t_curr: T },
33}
34
35impl<T, Y> Display for Error<T, Y>
36where
37 T: Real + Display,
38 Y: State<T> + Display,
39{
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 match self {
42 Self::BadInput { msg } => write!(
43 f,
44 "Bad input: {}. Check your problem definition, dimensions, and solver options.",
45 msg
46 ),
47 Self::MaxSteps { t, y } => {
48 write!(
49 f,
50 "Maximum step count reached at (t, y) = ({}, {}). Try increasing max_steps, relaxing tolerances, or shortening the integration interval.",
51 t, y
52 )
53 }
54 Self::StepSize { t, y } => write!(
55 f,
56 "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.",
57 t, y
58 ),
59 Self::Stiffness { t, y } => write!(
60 f,
61 "Stiffness detected at (t, y) = ({}, {}). Switch to a stiff method (e.g., DIRK or IRK) or relax tolerances to improve stability.",
62 t, y
63 ),
64 Self::OutOfBounds {
65 t_interp,
66 t_prev,
67 t_curr,
68 } => {
69 write!(
70 f,
71 "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.",
72 t_interp, t_prev, t_curr
73 )
74 }
75 Self::NoLags => write!(
76 f,
77 "Invalid DDE configuration: number of lags L must be > 0. If there are no delays, use an ODE solver instead."
78 ),
79 Self::InsufficientHistory {
80 t_delayed,
81 t_prev,
82 t_curr,
83 } => {
84 write!(
85 f,
86 "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.",
87 t_delayed, t_prev, t_curr
88 )
89 }
90 }
91 }
92}
93
94impl<T, Y> Debug for Error<T, Y>
95where
96 T: Real + Debug,
97 Y: State<T> + Debug,
98{
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 match self {
101 Self::BadInput { msg } => write!(
102 f,
103 "Bad input: {}. Check your problem definition, dimensions, and solver options.",
104 msg
105 ),
106 Self::MaxSteps { t, y } => {
107 write!(
108 f,
109 "Maximum step count reached at (t, y) = ({:?}, {:?}). Try increasing max_steps, relaxing tolerances, or shortening the integration interval.",
110 t, y
111 )
112 }
113 Self::StepSize { t, y } => {
114 write!(
115 f,
116 "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.",
117 t, y
118 )
119 }
120 Self::Stiffness { t, y } => {
121 write!(
122 f,
123 "Stiffness detected at (t, y) = ({:?}, {:?}). Switch to a stiff method (e.g., DIRK or IRK) or relax tolerances to improve stability.",
124 t, y
125 )
126 }
127 Self::OutOfBounds {
128 t_interp,
129 t_prev,
130 t_curr,
131 } => {
132 write!(
133 f,
134 "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.",
135 t_interp, t_prev, t_curr
136 )
137 }
138 Self::NoLags => write!(
139 f,
140 "Invalid DDE configuration: number of lags L must be > 0. If there are no delays, use an ODE solver instead."
141 ),
142 Self::InsufficientHistory {
143 t_delayed,
144 t_prev,
145 t_curr,
146 } => {
147 write!(
148 f,
149 "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.",
150 t_delayed, t_prev, t_curr
151 )
152 }
153 }
154 }
155}
156
157impl<T, Y> std::error::Error for Error<T, Y>
158where
159 T: Real + Debug + Display,
160 Y: State<T> + Debug + Display,
161{
162}