ida/traits.rs
1//! Basic traits for problem specification
2
3use ndarray::prelude::*;
4
5/// Model specification
6pub trait ModelSpec: Clone {
7 type Scalar: num_traits::Float;
8 type Dim: Dimension;
9 fn model_size(&self) -> <Ix1 as Dimension>::Pattern;
10}
11
12pub trait Residual: ModelSpec {
13 /// Nonlinear residual function
14 //fn residual<'a, S>(&mut self, v: &'a mut ArrayBase<S, Ix1>) -> &'a mut ArrayBase<S, Ix1>
15 //where
16 //S: ndarray::DataMut<Elem = Self::Scalar>;
17
18 /// This function computes the problem residual for given values of the independent variable t, state vector y, and derivative ˙y. Arguments tt is the current value of the independent variable.
19 ///
20 /// # Arguments
21 ///
22 /// * `tt` is the current value of the independent variable.
23 /// * `yy` is the current value of the dependent variable vector, `y(t)`.
24 /// * `yp` is the current value of `y'(t)`.
25 /// * `rr` is the output residual vector `F(t, y, y')`.
26 ///
27 /// An IDAResFn function type should return a value of 0 if successful, a positive value if a recoverable error occurred (e.g. yy has an illegal value), or a negative value if a nonrecoverable error occurred. In the last case, the integrator halts. If a recoverable error occurred, the integrator will attempt to correct and retry.
28 fn res<S1, S2, S3>(
29 &self,
30 tt: Self::Scalar,
31 yy: ArrayBase<S1, Ix1>,
32 yp: ArrayBase<S2, Ix1>,
33 rr: ArrayBase<S3, Ix1>,
34 ) where
35 S1: ndarray::Data<Elem = Self::Scalar>,
36 S2: ndarray::Data<Elem = Self::Scalar>,
37 S3: ndarray::DataMut<Elem = Self::Scalar>;
38}
39
40pub trait Jacobian: ModelSpec {
41 /// This function computes the Jacobian matrix J of the DAE system (or an approximation to it)
42 ///
43 /// # Arguments
44 ///
45 /// * `tt` is the current value of the independent variable `t`.
46 /// * `cj` is the scalar in the system Jacobian, proportional to the inverse of the step size (α in Eq. (2.5)).
47 /// * `yy` is the current value of the dependent variable vector, `y(t)`.
48 /// * `yp` is the current value of `y'(t)`.
49 /// * `rr` is the current value of the residual vector `F(t, y, y')`.
50 /// * `jac` is the output (approximate) Jacobian matrix, `J = ∂F/∂y + cj ∂F/∂y'`.
51 ///
52 /// # Return value
53 ///
54 /// Should return 0 if successful, a positive value if a recoverable error occurred, or a
55 /// negative value if a nonrecoverable error occurred. In the case of a recoverable eror
56 /// return, the integrator will attempt to recover by reducing the stepsize, and hence changing α in
57 fn jac<S1, S2, S3, S4>(
58 &self,
59 tt: Self::Scalar,
60 cj: Self::Scalar,
61 yy: ArrayBase<S1, Ix1>,
62 yp: ArrayBase<S2, Ix1>,
63 rr: ArrayBase<S3, Ix1>,
64 jac: ArrayBase<S4, Ix2>,
65 ) where
66 S1: ndarray::Data<Elem = Self::Scalar>,
67 S2: ndarray::Data<Elem = Self::Scalar>,
68 S3: ndarray::Data<Elem = Self::Scalar>,
69 S4: ndarray::DataMut<Elem = Self::Scalar>;
70}
71
72pub trait Root: ModelSpec {
73 fn num_roots(&self) -> usize {
74 0
75 }
76
77 fn root<S1, S2, S3>(
78 &self,
79 t: Self::Scalar,
80 y: ArrayBase<S1, Ix1>,
81 yp: ArrayBase<S2, Ix1>,
82 gout: ArrayBase<S3, Ix1>,
83 ) where
84 S1: ndarray::Data<Elem = Self::Scalar>,
85 S2: ndarray::Data<Elem = Self::Scalar>,
86 S3: ndarray::DataMut<Elem = Self::Scalar>,
87 {
88 }
89}
90
91/// Core implementation for explicit schemes
92pub trait IdaProblem: Residual + Jacobian + Root {}
93
94impl<T> IdaProblem for T where T: Residual + Jacobian + Root {}