pub trait OdeSolverMethod<'a, Eqn>: Clonewhere
Self: Sized,
Eqn: 'a + OdeEquations,{
type State: OdeSolverState<Eqn::V>;
Show 18 methods
// Required methods
fn problem(&self) -> &'a OdeSolverProblem<Eqn>;
fn checkpoint(&mut self) -> Self::State;
fn set_state(&mut self, state: Self::State);
fn into_state(self) -> Self::State;
fn state(&self) -> StateRef<'_, Eqn::V>;
fn state_mut(&mut self) -> StateRefMut<'_, Eqn::V>;
fn jacobian(&self) -> Option<Ref<'_, Eqn::M>>;
fn mass(&self) -> Option<Ref<'_, Eqn::M>>;
fn step(&mut self) -> Result<OdeSolverStopReason<Eqn::T>, DiffsolError>;
fn set_stop_time(&mut self, tstop: Eqn::T) -> Result<(), DiffsolError>;
fn interpolate(&self, t: Eqn::T) -> Result<Eqn::V, DiffsolError>;
fn interpolate_out(&self, t: Eqn::T) -> Result<Eqn::V, DiffsolError>;
fn interpolate_sens(&self, t: Eqn::T) -> Result<Vec<Eqn::V>, DiffsolError>;
fn order(&self) -> usize;
// Provided methods
fn solve(
&mut self,
final_time: Eqn::T,
) -> Result<(<Eqn::V as DefaultDenseMatrix>::M, Vec<Eqn::T>), DiffsolError>
where Eqn::V: DefaultDenseMatrix,
Self: Sized { ... }
fn solve_dense(
&mut self,
t_eval: &[Eqn::T],
) -> Result<<Eqn::V as DefaultDenseMatrix>::M, DiffsolError>
where Eqn::V: DefaultDenseMatrix,
Self: Sized { ... }
fn solve_with_checkpointing(
&mut self,
final_time: Eqn::T,
max_steps_between_checkpoints: Option<usize>,
) -> Result<(Checkpointing<'a, Eqn, Self>, <Eqn::V as DefaultDenseMatrix>::M, Vec<Eqn::T>), DiffsolError>
where Eqn::V: DefaultDenseMatrix,
Self: Sized { ... }
fn solve_dense_with_checkpointing(
&mut self,
t_eval: &[Eqn::T],
max_steps_between_checkpoints: Option<usize>,
) -> Result<(Checkpointing<'a, Eqn, Self>, <Eqn::V as DefaultDenseMatrix>::M), DiffsolError>
where Eqn::V: DefaultDenseMatrix,
Self: Sized { ... }
}
Expand description
Trait for ODE solver methods. This is the main user interface for the ODE solvers.
The solver is responsible for stepping the solution (given in the OdeSolverState
), and interpolating the solution at a given time.
However, the solver does not own the state, so the user is responsible for creating and managing the state. If the user
wants to change the state, they should call set_problem
again.
§Example
use diffsol::{ OdeSolverMethod, OdeSolverProblem, OdeSolverState, OdeEquationsImplicit, DefaultSolver };
fn solve_ode<'a, Eqn>(solver: &mut impl OdeSolverMethod<'a, Eqn>, t: Eqn::T) -> Eqn::V
where
Eqn: OdeEquationsImplicit + 'a,
Eqn::M: DefaultSolver,
{
while solver.state().t <= t {
solver.step().unwrap();
}
solver.interpolate(t).unwrap()
}
Required Associated Types§
type State: OdeSolverState<Eqn::V>
Required Methods§
Sourcefn problem(&self) -> &'a OdeSolverProblem<Eqn>
fn problem(&self) -> &'a OdeSolverProblem<Eqn>
Get the current problem
Sourcefn checkpoint(&mut self) -> Self::State
fn checkpoint(&mut self) -> Self::State
Take a checkpoint of the current state of the solver, returning it to the user. This is useful if you want to use this
state in another solver or problem but want to keep this solver active. If you don’t need to use this solver again, you can use take_state
instead.
Note that this will force a reinitialisation of the internal Jacobian for the solver, if it has one.
Sourcefn set_state(&mut self, state: Self::State)
fn set_state(&mut self, state: Self::State)
Replace the current state of the solver with a new state.
Sourcefn into_state(self) -> Self::State
fn into_state(self) -> Self::State
Take the current state of the solver, if it exists, returning it to the user. This is useful if you want to use this
state in another solver or problem. Note that this will unset the current problem and solver state, so you will need to call
set_problem
again before calling step
or solve
.
Sourcefn state_mut(&mut self) -> StateRefMut<'_, Eqn::V>
fn state_mut(&mut self) -> StateRefMut<'_, Eqn::V>
Get a mutable reference to the current state of the solver
Note that calling this will cause the next call to step
to perform some reinitialisation to take into
account the mutated state, this could be expensive for multi-step methods.
Sourcefn jacobian(&self) -> Option<Ref<'_, Eqn::M>>
fn jacobian(&self) -> Option<Ref<'_, Eqn::M>>
Returns the current jacobian matrix of the solver, if it has one Note that this will force a full recalculation of the Jacobian.
Sourcefn mass(&self) -> Option<Ref<'_, Eqn::M>>
fn mass(&self) -> Option<Ref<'_, Eqn::M>>
Returns the current mass matrix of the solver, if it has one Note that this will force a full recalculation of the mass matrix.
Sourcefn step(&mut self) -> Result<OdeSolverStopReason<Eqn::T>, DiffsolError>
fn step(&mut self) -> Result<OdeSolverStopReason<Eqn::T>, DiffsolError>
Step the solution forward by one step, altering the internal state of the solver.
The return value is a Result
containing the reason for stopping the solver, possible reasons are:
InternalTimestep
: The solver has taken a step forward in time, the internal state of the solver is at time self.state().tRootFound(t_root)
: The solver has found a root at timet_root
. Note that the internal state of the solver is at the internal time stepself.state().t
, not at timet_root
.TstopReached
: The solver has reached the stop time set by Self::set_stop_time, the internal state of the solver is at timetstop
, which is the same asself.state().t
Sourcefn set_stop_time(&mut self, tstop: Eqn::T) -> Result<(), DiffsolError>
fn set_stop_time(&mut self, tstop: Eqn::T) -> Result<(), DiffsolError>
Set a stop time for the solver. The solver will stop when the internal time reaches this time.
Once it stops, the stop time is unset. If tstop
is at or before the current internal time, an error is returned.
Sourcefn interpolate(&self, t: Eqn::T) -> Result<Eqn::V, DiffsolError>
fn interpolate(&self, t: Eqn::T) -> Result<Eqn::V, DiffsolError>
Interpolate the solution at a given time. This time should be between the current time and the last solver time step
Sourcefn interpolate_out(&self, t: Eqn::T) -> Result<Eqn::V, DiffsolError>
fn interpolate_out(&self, t: Eqn::T) -> Result<Eqn::V, DiffsolError>
Interpolate the integral of the output function at a given time. This time should be between the current time and the last solver time step
Sourcefn interpolate_sens(&self, t: Eqn::T) -> Result<Vec<Eqn::V>, DiffsolError>
fn interpolate_sens(&self, t: Eqn::T) -> Result<Vec<Eqn::V>, DiffsolError>
Interpolate the sensitivity vectors at a given time. This time should be between the current time and the last solver time step
Provided Methods§
Sourcefn solve(
&mut self,
final_time: Eqn::T,
) -> Result<(<Eqn::V as DefaultDenseMatrix>::M, Vec<Eqn::T>), DiffsolError>
fn solve( &mut self, final_time: Eqn::T, ) -> Result<(<Eqn::V as DefaultDenseMatrix>::M, Vec<Eqn::T>), DiffsolError>
Using the provided state, solve the problem up to time final_time
Returns a Vec of solution values at timepoints chosen by the solver.
After the solver has finished, the internal state of the solver is at time final_time
.
Sourcefn solve_dense(
&mut self,
t_eval: &[Eqn::T],
) -> Result<<Eqn::V as DefaultDenseMatrix>::M, DiffsolError>
fn solve_dense( &mut self, t_eval: &[Eqn::T], ) -> Result<<Eqn::V as DefaultDenseMatrix>::M, DiffsolError>
Using the provided state, solve the problem up to time t_eval[t_eval.len()-1]
Returns a Vec of solution values at timepoints given by t_eval
.
After the solver has finished, the internal state of the solver is at time t_eval[t_eval.len()-1]
.
fn solve_with_checkpointing( &mut self, final_time: Eqn::T, max_steps_between_checkpoints: Option<usize>, ) -> Result<(Checkpointing<'a, Eqn, Self>, <Eqn::V as DefaultDenseMatrix>::M, Vec<Eqn::T>), DiffsolError>
Sourcefn solve_dense_with_checkpointing(
&mut self,
t_eval: &[Eqn::T],
max_steps_between_checkpoints: Option<usize>,
) -> Result<(Checkpointing<'a, Eqn, Self>, <Eqn::V as DefaultDenseMatrix>::M), DiffsolError>
fn solve_dense_with_checkpointing( &mut self, t_eval: &[Eqn::T], max_steps_between_checkpoints: Option<usize>, ) -> Result<(Checkpointing<'a, Eqn, Self>, <Eqn::V as DefaultDenseMatrix>::M), DiffsolError>
Solve the problem and write out the solution at the given timepoints, using checkpointing so that the solution can be interpolated at any timepoint. See Self::solve_dense for a similar method that does not use checkpointing.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.