Struct diffsol::ode_solver::equations::OdeSolverEquations
source · pub struct OdeSolverEquations<M, Rhs, Init, Mass = UnitCallable<M>, Root = UnitCallable<M>>where
M: Matrix,
Rhs: NonLinearOp<M = M, V = M::V, T = M::T>,
Mass: LinearOp<M = M, V = M::V, T = M::T>,
Root: NonLinearOp<M = M, V = M::V, T = M::T>,
Init: ConstantOp<M = M, V = M::V, T = M::T>,{ /* private fields */ }
Expand description
This struct implements the ODE equation trait OdeEquations for a given right-hand side op, mass op, optional root op, and initial condition function. While the crate::OdeBuilder struct is the easiest way to define an ODE problem, occasionally a user might want to use their own structs that define the equations instead of closures or the DiffSL languave, and this can be done using OdeSolverEquations.
The main traits that you need to implement are the crate::Op and NonLinearOp trait, which define a nonlinear operator or function F
that maps an input vector x
to an output vector y
, (i.e. y = F(x)
).
Once you have implemented this trait, you can then pass an instance of your struct to the rhs
argument of the Self::new method. Once you have created an instance of OdeSolverEquations, you can then use crate::OdeSolverProblem::new to create a problem.
For example:
use std::rc::Rc;
use diffsol::{Bdf, OdeSolverState, OdeSolverMethod, NonLinearOp, OdeSolverEquations, OdeSolverProblem, Op, UnitCallable, ConstantClosure};
type M = nalgebra::DMatrix<f64>;
type V = nalgebra::DVector<f64>;
struct MyProblem;
impl Op for MyProblem {
type V = V;
type T = f64;
type M = M;
fn nstates(&self) -> usize {
1
}
fn nout(&self) -> usize {
1
}
}
// implement rhs equations for the problem
impl NonLinearOp for MyProblem {
fn call_inplace(&self, x: &V, _t: f64, y: &mut V) {
y[0] = -0.1 * x[0];
}
fn jac_mul_inplace(&self, x: &V, _t: f64, v: &V, y: &mut V) {
y[0] = -0.1 * v[0];
}
}
let rhs = Rc::new(MyProblem);
// use the provided constant closure to define the initial condition
let init_fn = |p: &V, _t: f64| V::from_vec(vec![1.0]);
let init = Rc::new(ConstantClosure::new(init_fn, Rc::new(V::from_vec(vec![]))));
// we don't have a mass matrix or root function, so we can set to None
let mass: Option<Rc<UnitCallable<M>>> = None;
let root: Option<Rc<UnitCallable<M>>> = None;
let p = Rc::new(V::from_vec(vec![]));
let eqn = OdeSolverEquations::new(rhs, mass, root, init, p);
let rtol = 1e-6;
let atol = V::from_vec(vec![1e-6]);
let t0 = 0.0;
let h0 = 0.1;
let with_sensitivity = false;
let sensitivity_error_control = false;
let problem = OdeSolverProblem::new(eqn, rtol, atol, t0, h0, with_sensitivity, sensitivity_error_control).unwrap();
let mut solver = Bdf::default();
let t = 0.4;
let state = OdeSolverState::new(&problem, &solver).unwrap();
solver.set_problem(state, &problem);
while solver.state().unwrap().t <= t {
solver.step().unwrap();
}
let y = solver.interpolate(t);
Implementations§
source§impl<M, Rhs, Init, Mass, Root> OdeSolverEquations<M, Rhs, Init, Mass, Root>where
M: Matrix,
Rhs: NonLinearOp<M = M, V = M::V, T = M::T>,
Mass: LinearOp<M = M, V = M::V, T = M::T>,
Root: NonLinearOp<M = M, V = M::V, T = M::T>,
Init: ConstantOp<M = M, V = M::V, T = M::T>,
impl<M, Rhs, Init, Mass, Root> OdeSolverEquations<M, Rhs, Init, Mass, Root>where
M: Matrix,
Rhs: NonLinearOp<M = M, V = M::V, T = M::T>,
Mass: LinearOp<M = M, V = M::V, T = M::T>,
Root: NonLinearOp<M = M, V = M::V, T = M::T>,
Init: ConstantOp<M = M, V = M::V, T = M::T>,
Trait Implementations§
source§impl<M, Rhs, Init, Mass, Root> OdeEquations for OdeSolverEquations<M, Rhs, Init, Mass, Root>where
M: Matrix,
Rhs: NonLinearOp<M = M, V = M::V, T = M::T>,
Mass: LinearOp<M = M, V = M::V, T = M::T>,
Root: NonLinearOp<M = M, V = M::V, T = M::T>,
Init: ConstantOp<M = M, V = M::V, T = M::T>,
impl<M, Rhs, Init, Mass, Root> OdeEquations for OdeSolverEquations<M, Rhs, Init, Mass, Root>where
M: Matrix,
Rhs: NonLinearOp<M = M, V = M::V, T = M::T>,
Mass: LinearOp<M = M, V = M::V, T = M::T>,
Root: NonLinearOp<M = M, V = M::V, T = M::T>,
Init: ConstantOp<M = M, V = M::V, T = M::T>,
type T = <M as MatrixCommon>::T
type V = <M as MatrixCommon>::V
type M = M
type Rhs = Rhs
type Mass = Mass
type Root = Root
type Init = Init
fn root(&self) -> Option<&Rc<Self::Root>>
source§fn init(&self) -> &Rc<Self::Init>
fn init(&self) -> &Rc<Self::Init>
y(t)
, where t
is the initial timesource§fn set_params(&mut self, p: Self::V)
fn set_params(&mut self, p: Self::V)
set_params
must always be called before calling any of the other functions in this trait.Auto Trait Implementations§
impl<M, Rhs, Init, Mass, Root> Freeze for OdeSolverEquations<M, Rhs, Init, Mass, Root>
impl<M, Rhs, Init, Mass, Root> RefUnwindSafe for OdeSolverEquations<M, Rhs, Init, Mass, Root>where
Rhs: RefUnwindSafe,
Init: RefUnwindSafe,
<M as MatrixCommon>::V: RefUnwindSafe,
Mass: RefUnwindSafe,
Root: RefUnwindSafe,
impl<M, Rhs, Init, Mass = UnitCallable<M>, Root = UnitCallable<M>> !Send for OdeSolverEquations<M, Rhs, Init, Mass, Root>
impl<M, Rhs, Init, Mass = UnitCallable<M>, Root = UnitCallable<M>> !Sync for OdeSolverEquations<M, Rhs, Init, Mass, Root>
impl<M, Rhs, Init, Mass, Root> Unpin for OdeSolverEquations<M, Rhs, Init, Mass, Root>
impl<M, Rhs, Init, Mass, Root> UnwindSafe for OdeSolverEquations<M, Rhs, Init, Mass, Root>where
Rhs: RefUnwindSafe,
Init: RefUnwindSafe,
<M as MatrixCommon>::V: RefUnwindSafe,
Mass: RefUnwindSafe,
Root: RefUnwindSafe,
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
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read moresource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.