Skip to main content

diffsol/ode_solver/
config.rs

1use crate::{OdeSolverOptions, Scalar};
2
3pub trait OdeSolverConfig<T> {
4    fn as_base_ref(&self) -> OdeSolverConfigRef<'_, T>;
5    fn as_base_mut(&mut self) -> OdeSolverConfigMut<'_, T>;
6}
7pub struct OdeSolverConfigRef<'a, T> {
8    pub minimum_timestep: &'a T,
9    pub maximum_error_test_failures: &'a usize,
10    pub maximum_timestep_growth: &'a T,
11    pub minimum_timestep_shrink: &'a T,
12}
13
14pub struct OdeSolverConfigMut<'a, T> {
15    pub minimum_timestep: &'a mut T,
16    pub maximum_error_test_failures: &'a mut usize,
17    pub maximum_timestep_growth: &'a mut T,
18    pub minimum_timestep_shrink: &'a mut T,
19}
20
21#[derive(Debug, Clone)]
22pub struct BdfConfig<T> {
23    pub minimum_timestep: T,
24    pub maximum_error_test_failures: usize,
25    pub maximum_newton_fails: usize,
26    pub maximum_timestep_growth: T,
27    pub minimum_timestep_growth: T,
28    pub maximum_timestep_shrink: T,
29    pub minimum_timestep_shrink: T,
30    pub maximum_newton_iterations: usize,
31}
32
33impl<T: Scalar> OdeSolverConfig<T> for BdfConfig<T> {
34    fn as_base_ref(&self) -> OdeSolverConfigRef<'_, T> {
35        OdeSolverConfigRef {
36            minimum_timestep: &self.minimum_timestep,
37            maximum_error_test_failures: &self.maximum_error_test_failures,
38            maximum_timestep_growth: &self.maximum_timestep_growth,
39            minimum_timestep_shrink: &self.minimum_timestep_shrink,
40        }
41    }
42
43    fn as_base_mut(&mut self) -> OdeSolverConfigMut<'_, T> {
44        OdeSolverConfigMut {
45            minimum_timestep: &mut self.minimum_timestep,
46            maximum_error_test_failures: &mut self.maximum_error_test_failures,
47            maximum_timestep_growth: &mut self.maximum_timestep_growth,
48            minimum_timestep_shrink: &mut self.minimum_timestep_shrink,
49        }
50    }
51}
52
53impl<T: Scalar> BdfConfig<T> {
54    pub fn new(ode_options: &OdeSolverOptions<T>) -> Self {
55        Self {
56            minimum_timestep: ode_options.min_timestep,
57            maximum_error_test_failures: ode_options.max_error_test_failures,
58            maximum_newton_fails: ode_options.max_nonlinear_solver_failures,
59            maximum_timestep_growth: ode_options
60                .max_timestep_growth
61                .unwrap_or_else(|| T::from_f64(2.0).unwrap()),
62            minimum_timestep_growth: ode_options
63                .min_timestep_growth
64                .unwrap_or_else(|| T::from_f64(2.0).unwrap()),
65            maximum_timestep_shrink: ode_options
66                .max_timestep_shrink
67                .unwrap_or_else(|| T::from_f64(0.9).unwrap()),
68            minimum_timestep_shrink: ode_options
69                .min_timestep_shrink
70                .unwrap_or_else(|| T::from_f64(0.5).unwrap()),
71            maximum_newton_iterations: ode_options.max_nonlinear_solver_iterations,
72        }
73    }
74}
75
76#[derive(Debug, Clone)]
77pub struct SdirkConfig<T> {
78    pub minimum_timestep: T,
79    pub maximum_error_test_failures: usize,
80    pub maximum_timestep_growth: T,
81    pub minimum_timestep_growth: T,
82    pub minimum_timestep_shrink: T,
83    pub maximum_timestep_shrink: T,
84    pub maximum_newton_iterations: usize,
85    pub maximum_newton_fails: usize,
86}
87
88impl<T: Scalar> SdirkConfig<T> {
89    pub fn new(ode_options: &OdeSolverOptions<T>) -> Self {
90        Self {
91            minimum_timestep: ode_options.min_timestep,
92            maximum_error_test_failures: ode_options.max_error_test_failures,
93            maximum_timestep_growth: ode_options
94                .max_timestep_growth
95                .unwrap_or_else(|| T::from_f64(2.0).unwrap()),
96            minimum_timestep_growth: ode_options
97                .min_timestep_growth
98                .unwrap_or_else(|| T::from_f64(2.0).unwrap()),
99            maximum_timestep_shrink: ode_options
100                .max_timestep_shrink
101                .unwrap_or_else(|| T::from_f64(0.9).unwrap()),
102            minimum_timestep_shrink: ode_options
103                .min_timestep_shrink
104                .unwrap_or_else(|| T::from_f64(0.5).unwrap()),
105            maximum_newton_iterations: ode_options.max_nonlinear_solver_iterations,
106            maximum_newton_fails: ode_options.max_nonlinear_solver_failures,
107        }
108    }
109}
110
111impl<T: Scalar> OdeSolverConfig<T> for SdirkConfig<T> {
112    fn as_base_ref(&self) -> OdeSolverConfigRef<'_, T> {
113        OdeSolverConfigRef {
114            minimum_timestep: &self.minimum_timestep,
115            maximum_error_test_failures: &self.maximum_error_test_failures,
116            maximum_timestep_growth: &self.maximum_timestep_growth,
117            minimum_timestep_shrink: &self.minimum_timestep_shrink,
118        }
119    }
120
121    fn as_base_mut(&mut self) -> OdeSolverConfigMut<'_, T> {
122        OdeSolverConfigMut {
123            minimum_timestep: &mut self.minimum_timestep,
124            maximum_error_test_failures: &mut self.maximum_error_test_failures,
125            maximum_timestep_growth: &mut self.maximum_timestep_growth,
126            minimum_timestep_shrink: &mut self.minimum_timestep_shrink,
127        }
128    }
129}
130
131#[derive(Debug, Clone)]
132pub struct ExplicitRkConfig<T> {
133    pub minimum_timestep: T,
134    pub maximum_error_test_failures: usize,
135    pub maximum_timestep_growth: T,
136    pub minimum_timestep_growth: T,
137    pub minimum_timestep_shrink: T,
138    pub maximum_timestep_shrink: T,
139}
140
141impl<T: Scalar> ExplicitRkConfig<T> {
142    pub fn new(ode_options: &OdeSolverOptions<T>) -> Self {
143        Self {
144            minimum_timestep: ode_options.min_timestep,
145            maximum_error_test_failures: ode_options.max_error_test_failures,
146            maximum_timestep_growth: ode_options
147                .max_timestep_growth
148                .unwrap_or_else(|| T::from_f64(2.0).unwrap()),
149            minimum_timestep_growth: ode_options
150                .min_timestep_growth
151                .unwrap_or_else(|| T::from_f64(1.0).unwrap()),
152            maximum_timestep_shrink: ode_options
153                .max_timestep_shrink
154                .unwrap_or_else(|| T::from_f64(1.0).unwrap()),
155            minimum_timestep_shrink: ode_options
156                .min_timestep_shrink
157                .unwrap_or_else(|| T::from_f64(0.5).unwrap()),
158        }
159    }
160}
161
162impl<T: Scalar> OdeSolverConfig<T> for ExplicitRkConfig<T> {
163    fn as_base_ref(&self) -> OdeSolverConfigRef<'_, T> {
164        OdeSolverConfigRef {
165            minimum_timestep: &self.minimum_timestep,
166            maximum_error_test_failures: &self.maximum_error_test_failures,
167            maximum_timestep_growth: &self.maximum_timestep_growth,
168            minimum_timestep_shrink: &self.minimum_timestep_shrink,
169        }
170    }
171
172    fn as_base_mut(&mut self) -> OdeSolverConfigMut<'_, T> {
173        OdeSolverConfigMut {
174            minimum_timestep: &mut self.minimum_timestep,
175            maximum_error_test_failures: &mut self.maximum_error_test_failures,
176            maximum_timestep_growth: &mut self.maximum_timestep_growth,
177            minimum_timestep_shrink: &mut self.minimum_timestep_shrink,
178        }
179    }
180}