pub struct SolverSensi<UserData, F, FS, const N: usize, const N_SENSI: usize> { /* private fields */ }
Expand description
The ODE solver with sensitivities.
§Type Arguments
-
F
is the type of the right-hand side function -
FS
is the type of the sensitivities right-hand side function -
UserData
is the type of the supplementary arguments for the right-hand-side. If unused, should be()
. -
N
is the “problem size”, that is the dimension of the state space. -
N_SENSI
is the number of sensitivities computed
Implementations§
Source§impl<UserData, F, FS, const N: usize, const N_SENSI: usize> Solver<UserData, F, FS, N, N_SENSI>
impl<UserData, F, FS, const N: usize, const N_SENSI: usize> Solver<UserData, F, FS, N, N_SENSI>
Sourcepub fn new(
method: LinearMultistepMethod,
f: F,
f_sens: FS,
t0: Realtype,
y0: &[Realtype; N],
y_s0: &[[Realtype; N]; N_SENSI],
rtol: Realtype,
atol: AbsTolerance<N>,
atol_sens: SensiAbsTolerance<N, N_SENSI>,
user_data: UserData,
) -> Result<Self>
pub fn new( method: LinearMultistepMethod, f: F, f_sens: FS, t0: Realtype, y0: &[Realtype; N], y_s0: &[[Realtype; N]; N_SENSI], rtol: Realtype, atol: AbsTolerance<N>, atol_sens: SensiAbsTolerance<N, N_SENSI>, user_data: UserData, ) -> Result<Self>
Creates a new solver.
Examples found in repository?
examples/oscillator_sensi.rs (lines 34-45)
3fn main() {
4 let y0 = [0., 1.];
5 //define the right-hand-side
6 fn f(_t: Realtype, y: &[Realtype; 2], ydot: &mut [Realtype; 2], k: &Realtype) -> RhsResult {
7 *ydot = [y[1], -y[0] * k];
8 RhsResult::Ok
9 }
10 //define the sensitivity function for the right hand side
11 fn fs(
12 _t: Realtype,
13 y: &[Realtype; 2],
14 _ydot: &[Realtype; 2],
15 ys: [&[Realtype; 2]; N_SENSI],
16 ysdot: [&mut [Realtype; 2]; N_SENSI],
17 k: &Realtype,
18 ) -> RhsResult {
19 // Mind that when indexing sensitivities, the first index
20 // is the parameter index, and the second the state variable
21 // index
22 *ysdot[0] = [ys[0][1], -ys[0][0] * k];
23 *ysdot[1] = [ys[1][1], -ys[1][0] * k];
24 *ysdot[2] = [ys[2][1], -ys[2][0] * k - y[0]];
25 RhsResult::Ok
26 }
27
28 const N_SENSI: usize = 3;
29
30 // the sensitivities in order are d/dy0[0], d/dy0[1] and d/dk
31 let ys0 = [[1., 0.], [0., 1.], [0., 0.]];
32
33 //initialize the solver
34 let mut solver = SolverSensi::new(
35 LinearMultistepMethod::Adams,
36 f,
37 fs,
38 0.,
39 &y0,
40 &ys0,
41 1e-4,
42 AbsTolerance::scalar(1e-4),
43 SensiAbsTolerance::scalar([1e-4; N_SENSI]),
44 1e-2,
45 )
46 .unwrap();
47 //and solve
48 let ts: Vec<_> = (1..100).collect();
49 println!("0,{},{}", y0[0], y0[1]);
50 for &t in &ts {
51 let (_tret, &[x, xdot], [&[dy0_dy00, dy1_dy00], &[dy0_dy01, dy1_dy01], &[dy0_dk, dy1_dk]]) =
52 solver.step(t as _, StepKind::Normal).unwrap();
53 println!(
54 "{},{},{},{},{},{},{},{},{}",
55 t, x, xdot, dy0_dy00, dy1_dy00, dy0_dy01, dy1_dy01, dy0_dk, dy1_dk
56 );
57 }
58}
Sourcepub fn step(
&mut self,
tout: Realtype,
step_kind: StepKind,
) -> Result<(Realtype, &[Realtype; N], [&[Realtype; N]; N_SENSI])>
pub fn step( &mut self, tout: Realtype, step_kind: StepKind, ) -> Result<(Realtype, &[Realtype; N], [&[Realtype; N]; N_SENSI])>
Takes a step according to step_kind
(see StepKind
).
Returns a tuple (t_out,&y(t_out),[&dy_dp(tout)])
where t_out
is the time
reached by the solver as dictated by step_kind
, y(t_out)
is an
array of the state variables at that time, and the i-th dy_dp(tout)
is an array
of the sensitivities of all variables with respect to parameter i.
Examples found in repository?
examples/oscillator_sensi.rs (line 52)
3fn main() {
4 let y0 = [0., 1.];
5 //define the right-hand-side
6 fn f(_t: Realtype, y: &[Realtype; 2], ydot: &mut [Realtype; 2], k: &Realtype) -> RhsResult {
7 *ydot = [y[1], -y[0] * k];
8 RhsResult::Ok
9 }
10 //define the sensitivity function for the right hand side
11 fn fs(
12 _t: Realtype,
13 y: &[Realtype; 2],
14 _ydot: &[Realtype; 2],
15 ys: [&[Realtype; 2]; N_SENSI],
16 ysdot: [&mut [Realtype; 2]; N_SENSI],
17 k: &Realtype,
18 ) -> RhsResult {
19 // Mind that when indexing sensitivities, the first index
20 // is the parameter index, and the second the state variable
21 // index
22 *ysdot[0] = [ys[0][1], -ys[0][0] * k];
23 *ysdot[1] = [ys[1][1], -ys[1][0] * k];
24 *ysdot[2] = [ys[2][1], -ys[2][0] * k - y[0]];
25 RhsResult::Ok
26 }
27
28 const N_SENSI: usize = 3;
29
30 // the sensitivities in order are d/dy0[0], d/dy0[1] and d/dk
31 let ys0 = [[1., 0.], [0., 1.], [0., 0.]];
32
33 //initialize the solver
34 let mut solver = SolverSensi::new(
35 LinearMultistepMethod::Adams,
36 f,
37 fs,
38 0.,
39 &y0,
40 &ys0,
41 1e-4,
42 AbsTolerance::scalar(1e-4),
43 SensiAbsTolerance::scalar([1e-4; N_SENSI]),
44 1e-2,
45 )
46 .unwrap();
47 //and solve
48 let ts: Vec<_> = (1..100).collect();
49 println!("0,{},{}", y0[0], y0[1]);
50 for &t in &ts {
51 let (_tret, &[x, xdot], [&[dy0_dy00, dy1_dy00], &[dy0_dy01, dy1_dy01], &[dy0_dk, dy1_dk]]) =
52 solver.step(t as _, StepKind::Normal).unwrap();
53 println!(
54 "{},{},{},{},{},{},{},{},{}",
55 t, x, xdot, dy0_dy00, dy1_dy00, dy0_dy01, dy1_dy01, dy0_dk, dy1_dk
56 );
57 }
58}
Trait Implementations§
Auto Trait Implementations§
impl<UserData, F, FS, const N: usize, const N_SENSI: usize> Freeze for Solver<UserData, F, FS, N, N_SENSI>
impl<UserData, F, FS, const N: usize, const N_SENSI: usize> RefUnwindSafe for Solver<UserData, F, FS, N, N_SENSI>
impl<UserData, F, FS, const N: usize, const N_SENSI: usize> !Send for Solver<UserData, F, FS, N, N_SENSI>
impl<UserData, F, FS, const N: usize, const N_SENSI: usize> !Sync for Solver<UserData, F, FS, N, N_SENSI>
impl<UserData, F, FS, const N: usize, const N_SENSI: usize> Unpin for Solver<UserData, F, FS, N, N_SENSI>
impl<UserData, F, FS, const N: usize, const N_SENSI: usize> UnwindSafe for Solver<UserData, F, FS, N, N_SENSI>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more