9 Ordinary Differential Equation

9.1 Introduce ODE Trait & Structure

9.1.1 ODE Trait

  • ODE structures are divided by two kinds

    • ExplicitODE
    • ImplicitODE
  • ODE trait is given as

    pub trait ODE {
        type Records;
        type Vector;
        type Param;
        type ODEMethod;
    
        fn mut_update(&mut self);
        fn integrate(&mut self) -> Self::Records;
        fn set_initial_condition<T: Real>(&mut self, init: State<T>) -> &mut Self;
        fn set_boundary_condition<T: Real>(
            &mut self,
            bound1: (State<T>, BoundaryCondition),
            bound2: (State<T>, BoundaryCondition),
        ) -> &mut Self;
        fn set_step_size(&mut self, dt: f64) -> &mut Self;
        fn set_method(&mut self, method: Self::ODEMethod) -> &mut Self;
        fn set_stop_condition(&mut self, f: fn(&Self) -> bool) -> &mut Self;
        fn set_times(&mut self, n: usize) -> &mut Self;
        fn check_enough(&self) -> bool;
    }
  • Records : The type to save results of ODE. Usually Matrix is used.
  • Vector : Vector can be below things.
    • Vec<f64> : Used for ExplicitODE
    • Vec<Dual> : Used for ImplicitODE
  • Param : Also it can be f64 or Dual
  • ODEMethod : Method for solving ODE
    • ExMethod : Explicit method
      • Euler : Euler first order
      • RK4 : Runge Kutta 4th order
    • ImMethod : Implicit method (to be implemented)
      • BDF : Backward Euler 1st order
      • GL4 : Gauss Legendre 4th order

9.1.2 State<T> structure

  • To use ODE trait, you should understand State<T> first.

    #[derive(Debug, Clone, Default)]
    pub struct State<T: Real> {
        pub param: T,
        pub value: Vec<T>,
        pub deriv: Vec<T>,
    }
  • T can be f64 or Dual
  • param is parameter for ODE. Usually it is represented by time.
  • value is value of each node.
  • deriv is value of derivative of each node.

For example,

\[ \frac{dy_n}{dt} = f(t, y_n) \]

  • \(t\) is param
  • \(y_n\) is value
  • \(f(t,y_n)\) is deriv

Methods for State<T> are as follows.

  • to_f64(&self) -> State<f64>
  • to_dual(&self) -> State<Dual>
  • new(T, Vec<T>, Vec<T>) -> Self

9.1.3 ExplicitODE struct

ExplicitODE is given as follow :

#[derive(Clone)]
pub struct ExplicitODE {
    state: State<f64>,
    func: fn(&mut State<f64>),
    step_size: f64,
    method: ExMethod,
    init_cond: State<f64>,
    bound_cond1: (State<f64>, BoundaryCondition),
    bound_cond2: (State<f64>, BoundaryCondition),
    stop_cond: fn(&Self) -> bool,
    times: usize,
    to_use: HashMap<ToUse, bool>,
}
  • state : Current param, value, derivative
  • func : Function to update state
  • init_cond : Initial condition
  • bound_cond1 : If boundary problem, then first boundary condition
  • bound_cond2 : second boundary condition
  • stop_cond : Stop condition (stop before times)
  • times : How many times do you want to update?
  • to_use : Just check whether information is enough