## ode_solvers

Numerical methods to solve ordinary differential equations (ODEs) in Rust

### 5 unstable releases

✓ Uses Rust 2018 edition

 0.3.0 Mar 22, 2019 Feb 20, 2019 Oct 20, 2018 Sep 25, 2018 Sep 11, 2018

#60 in Math

BSD-3-Clause

65KB
1.5K SLoC

# ODE-solvers

Numerical methods to solve ordinary differential equations (ODEs) in Rust.

## Installation

To start using the crate in a project, the following dependency must be added in the project's Cargo.toml file:

``````[dependencies]
ode-solvers = "0.3.0"
``````

Then, in the main file, add

``````use ode-solvers::*;
``````

## Type alias definition

The numerical integration methods implemented in the crate support multi-dimensional systems. In order to define the dimension of the system, declare a type alias for the state vector. For instance

``````type State = Vector3<f64>;
``````

The state representation of the system is based on the VectorN<T,D> structure defined in the nalgebra crate. For convenience, ode-solvers re-exports six types to work with systems of dimension 1 to 6: Vector1<T>,..., Vector6<T>. For higher dimensions, the user should import the nalgebra crate and define a VectorN<T,D> where the second type parameter of VectorN is a dimension name defined in nalgebra. Note that the type T must be f64. For instance, for a 9-dimensional system, one would have:

``````type State = VectorN<f64, nalgebra::U9>;
``````

## System definition

The system of first order ODEs must be defined in the `system` method of the `System<V>` trait. Typically, this trait is defined for a structure containing some parameters of the model. The signature of the `System<V>` trait is:

``````pub trait System<V> {
fn system(&self, x: f64, y: &V, dy: &mut V);
fn solout(&self, _x: f64, _y: &V, _dy: &V) -> bool {
false
}
}
``````

where `system` must contain the ODEs: the second argument is the independent variable (usually time), the third one is a vector containing the dependent variable(s), and the fourth one contains the derivative(s) of y with respect to x. The method `solout` is called after each successful integration step and stops the integration whenever it is evaluated as true. The implementation of that method is optional. See the examples for implementation details.

## Method selection

The following explicit Runge-Kutta methods are implemented in the current version of the crate:

Method Name Order Error estimate order Dense output order
Dormand-Prince Dopri5 5 4 4
Dormand-Prince Dop853 8 (5, 3) 7

These methods are defined in the modules dopri5 and dop853. The first step is to bring the desired module into scope:

``````use ode_solvers::dopri5::*;
``````

Then, a structure is created using the new or the from_param method of the corresponding struct. Refer to the API documentation for a description of the input arguments.

``````let mut stepper = Dopri5::new(system, x0, x_end, dx, y0, rtol, atol);
``````

The system is integrated using

``````let res = stepper.integrate();
``````

and the results are retrieved with

``````let x_out = stepper.x_out();
let y_out = stepper.y_out();
``````

See the homepage for more details.

## Acknowledgments

The algorithms implemented in this crate were originally implemented in FORTRAN by E. Hairer and G. Wanner, Université de Genève, Switzerland. This Rust implementation has been adapted from the C version written by J. Colinge, Université de Genève, Switzerland and the C++ version written by Blake Ashby, Stanford University, USA.

~3MB
~54K SLoC