use crate::{
matrix::Matrix, ode_solver::problem::OdeSolverSolution, OdeBuilder, OdeEquations,
OdeSolverProblem, Vector,
};
use num_traits::Zero;
pub fn robertson_sens<M: Matrix + 'static>(
use_coloring: bool,
) -> (
OdeSolverProblem<impl OdeEquations<M = M, V = M::V, T = M::T>>,
OdeSolverSolution<M::V>,
) {
let problem = OdeBuilder::new()
.p([0.04, 1.0e4, 3.0e7])
.rtol(1e-4)
.atol([1.0e-8, 1.0e-6, 1.0e-6])
.use_coloring(use_coloring)
.sensitivities_error_control(true)
.build_ode_with_mass_and_sens(
|x: &M::V, p: &M::V, _t: M::T, y: &mut M::V| {
y[0] = -p[0] * x[0] + p[1] * x[1] * x[2];
y[1] = p[0] * x[0] - p[1] * x[1] * x[2] - p[2] * x[1] * x[1];
y[2] = x[0] + x[1] + x[2] - M::T::from(1.0);
},
|x: &M::V, p: &M::V, _t: M::T, v: &M::V, y: &mut M::V| {
y[0] = -p[0] * v[0] + p[1] * v[1] * x[2] + p[1] * x[1] * v[2];
y[1] = p[0] * v[0]
- p[1] * v[1] * x[2]
- p[1] * x[1] * v[2]
- M::T::from(2.0) * p[2] * x[1] * v[1];
y[2] = v[0] + v[1] + v[2];
},
|x: &M::V, _p: &M::V, _t: M::T, v: &M::V, y: &mut M::V| {
y[0] = -v[0] * x[0] + v[1] * x[1] * x[2];
y[1] = v[0] * x[0] - v[1] * x[1] * x[2] - v[2] * x[1] * x[1];
y[2] = M::T::zero();
},
|x: &M::V, _p: &M::V, _t: M::T, beta: M::T, y: &mut M::V| {
y[0] = x[0] + beta * y[0];
y[1] = x[1] + beta * y[1];
y[2] = beta * y[2];
},
|_x: &M::V, _p: &M::V, _t: M::T, _v: &M::V, y: &mut M::V| {
y.fill(M::T::zero());
},
|_p: &M::V, _t: M::T| M::V::from_vec(vec![1.0.into(), 0.0.into(), 0.0.into()]),
|_p: &M::V, _t: M::T, _v: &M::V, y: &mut M::V| {
y.fill(M::T::zero());
},
)
.unwrap();
let mut soln = OdeSolverSolution::default();
let data = vec![
(vec![1.0, 0.0, 0.0], 0.0),
(vec![9.8517e-01, 3.3864e-05, 1.4794e-02], 0.4),
(vec![9.0553e-01, 2.2406e-05, 9.4452e-02], 4.0),
(vec![7.1579e-01, 9.1838e-06, 2.8420e-01], 40.0),
(vec![4.5044e-01, 3.2218e-06, 5.4956e-01], 400.0),
(vec![1.8320e-01, 8.9444e-07, 8.1680e-01], 4000.0),
(vec![3.8992e-02, 1.6221e-07, 9.6101e-01], 40000.0),
(vec![4.9369e-03, 1.9842e-08, 9.9506e-01], 400000.0),
(vec![5.1674e-04, 2.0684e-09, 9.9948e-01], 4000000.0),
(vec![5.2009e-05, 2.0805e-10, 9.9995e-01], 4.0000e+07),
(vec![5.2012e-06, 2.0805e-11, 9.9999e-01], 4.0000e+08),
(vec![5.1850e-07, 2.0740e-12, 1.0000e+00], 4.0000e+09),
(vec![4.8641e-08, 1.9456e-13, 1.0000e+00], 4.0000e+10),
];
for (values, time) in data {
soln.push(
M::V::from_vec(values.into_iter().map(|v| v.into()).collect()),
time.into(),
);
}
(problem, soln)
}