Initialisation
Each solver has an internal state that holds information like the current state vector, the gradient of the state vector, the current time, and the current step size. When you create a solver using the bdf
or sdirk
methods on the OdeSolverProblem
struct, the solver will be initialised with an initial state based on the initial conditions of the problem as well as satisfying any algebraic constraints. An initial time step will also be chosen based on your provided equations.
Each solver's state struct implements the OdeSolverState
trait, and if you wish to manually create and setup a state, you can use the methods on this trait to do so.
For example, say that you wish to bypass the initialisation of the state as you already have the algebraic constraints and so don't need to solve for them. You can use the new_without_initialise
method on the OdeSolverState
trait to create a new state without initialising it. You can then use the as_mut
method to get a mutable reference to the state and set the values manually.
use crate::{problem_implicit, LS};
use diffsol::{BdfState, OdeSolverState, RkState};
pub fn create_solvers_uninit() {
let problem = problem_implicit();
// Create a non-initialised state and manually set the values before
// creating the solver
let mut state = RkState::new_without_initialise(&problem).unwrap();
// ... set the state values manually
state.as_mut().y[0] = 0.1;
let _solver = problem.tr_bdf2_solver::<LS>(state);
// Do the same for a BDF solver
let mut state = BdfState::new_without_initialise(&problem).unwrap();
state.as_mut().y[0] = 0.1;
let _solver = problem.bdf_solver::<LS>(state);
}
Note that each state struct has a as_ref
and as_mut
methods that return a StateRef
or StateRefMut
struct respectively. These structs provide a solver-independent way to access the state values so you can use the same code with different solvers.