Stopping
There are two methods to halt the solver when a certain condition is met: you can either stop at a specific time or stop when a certain event occurs.
Stopping at a specific time is straightforward, as you can use the set_stop_time
method on the OdeSolverMethod
trait and then just check if the return value of the step
method is Ok(OdeSolverStopReason::TstopReached)
Stopping at a certain event requires you to set a root function in your system of equations, see Root Finding for more information. During time-stepping, you can check if the solver has discovered a root by checking if the return value of the step
method is Ok(OdeSolverStopReason::RootFound)
. RootFound
holds the time at which the root was found, and you can use the interpolate
method to obtain the solution at that time.
use diffsol::{OdeEquations, OdeSolverMethod, OdeSolverStopReason};
pub fn solve_match_step<'a, Solver, Eqn>(solver: &mut Solver)
where
Solver: OdeSolverMethod<'a, Eqn>,
Eqn: OdeEquations<T = f64> + 'a,
{
solver.set_stop_time(10.0).unwrap();
loop {
match solver.step() {
Ok(OdeSolverStopReason::InternalTimestep) => continue,
Ok(OdeSolverStopReason::TstopReached) => break,
Ok(OdeSolverStopReason::RootFound(_t)) => break,
Err(e) => panic!("Solver failed to converge: {}", e),
}
}
println!("Solver stopped at time: {}", solver.state().t);
}