Skip to main content

conspire/math/integrate/error/
mod.rs

1#[cfg(test)]
2mod test;
3
4use crate::math::{Scalar, Style, StyledError, assert::AssertionError, styled_error};
5use std::fmt::{Debug, Display};
6
7/// Possible errors encountered when integrating.
8pub enum IntegrationError {
9    InconsistentInitialConditions,
10    InitialTimeNotLessThanFinalTime,
11    Intermediate(String),
12    LengthTimeLessThanTwo,
13    MinimumStepSizeReached(Scalar, String),
14    MinimumStepSizeUpstream(Scalar, String, String),
15    TimeStepNotSet(Scalar, Scalar, String),
16    Upstream(String, String),
17}
18
19impl IntegrationError {
20    pub fn upstream(error: impl Display, context: &(impl Debug + ?Sized)) -> Self {
21        Self::Upstream(format!("{error}"), format!("{context:?}"))
22    }
23}
24
25impl From<String> for IntegrationError {
26    fn from(error: String) -> Self {
27        Self::Intermediate(error)
28    }
29}
30
31impl StyledError for IntegrationError {
32    fn message(&self, style: &Style) -> String {
33        let (h, c) = (style.headline, style.frame);
34        match self {
35            Self::InconsistentInitialConditions => {
36                format!("{h}The initial condition z_0 is not consistent with g(t_0, y_0).")
37            }
38            Self::InitialTimeNotLessThanFinalTime => {
39                format!("{h}The initial time must precede the final time.")
40            }
41            Self::Intermediate(message) => message.to_string(),
42            Self::LengthTimeLessThanTwo => {
43                format!("{h}The time must contain at least two entries.")
44            }
45            Self::MinimumStepSizeReached(dt_min, integrator) => {
46                format!(
47                    "{h}Minimum time step ({dt_min:?}) reached.{c}\n\
48                    In integrator: {integrator}."
49                )
50            }
51            Self::MinimumStepSizeUpstream(dt_min, error, integrator) => {
52                format!(
53                    "{error}{c}\n\
54                    Causing error: {h}Minimum time step ({dt_min:?}) reached.{c}\n\
55                    In integrator: {integrator}."
56                )
57            }
58            Self::TimeStepNotSet(t0, tf, integrator) => {
59                format!(
60                    "{h}A positive time step must be set within [{t0:?}, {tf:?}].{c}\n\
61                    In integrator: {integrator}."
62                )
63            }
64            Self::Upstream(error, integrator) => {
65                format!(
66                    "{error}{c}\n\
67                    In integrator: {integrator}."
68                )
69            }
70        }
71    }
72}
73
74styled_error!(IntegrationError);
75
76impl From<IntegrationError> for String {
77    fn from(error: IntegrationError) -> Self {
78        format!("{}", error)
79    }
80}
81
82impl From<IntegrationError> for AssertionError {
83    fn from(error: IntegrationError) -> Self {
84        AssertionError {
85            message: error.to_string(),
86        }
87    }
88}