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);
}