Skip to main content

numra_ode/
lib.rs

1// Allow some clippy lints that are prevalent in numerical code
2#![allow(clippy::assign_op_pattern)]
3#![allow(clippy::needless_range_loop)]
4#![allow(clippy::manual_memcpy)]
5#![allow(clippy::collapsible_else_if)]
6#![allow(clippy::single_match)]
7#![allow(clippy::too_many_arguments)]
8#![allow(clippy::excessive_precision)]
9#![allow(clippy::manual_clamp)]
10#![allow(clippy::identity_op)]
11#![allow(clippy::erasing_op)]
12
13//! # Numra ODE Solvers
14//!
15//! This crate provides a comprehensive suite of ODE solvers for solving
16//! initial value problems of the form:
17//!
18//! ```text
19//! dy/dt = f(t, y),  y(t0) = y0
20//! ```
21//!
22//! ## Available Solvers
23//!
24//! ### Explicit Runge-Kutta (Non-stiff)
25//! - [`DoPri5`] - Dormand-Prince 5(4) with dense output
26//! - [`Tsit5`] - Tsitouras 5(4), efficient with FSAL
27//! - [`Vern6`] - Verner 6(5), high accuracy
28//! - [`Vern7`] - Verner 7(6), higher accuracy
29//! - [`Vern8`] - Verner 8(7), very high accuracy
30//!
31//! ### Implicit Runge-Kutta (Stiff)
32//! - [`Radau5`] - Radau IIA 3-stage, L-stable (5th order)
33//! - [`Esdirk32`] - ESDIRK 3-stage, 2nd order
34//! - [`Esdirk43`] - ESDIRK 4-stage, 3rd order
35//! - [`Esdirk54`] - ESDIRK 5-stage, 4th order (L-stable)
36//!
37//! ### Multistep Methods (Stiff)
38//! - [`Bdf`] - BDF orders 1-5 with variable order
39//!
40//! ### Automatic Selection
41//! - [`auto_solve`] / [`auto_solve_with_hints`] - Automatic solver selection
42//!   based on problem characteristics
43//!
44//! ## Example
45//!
46//! ```rust
47//! use numra_ode::{OdeProblem, DoPri5, Solver, SolverOptions};
48//!
49//! // Define the Lorenz system
50//! fn lorenz(t: f64, y: &[f64], dydt: &mut [f64]) {
51//!     let sigma = 10.0;
52//!     let rho = 28.0;
53//!     let beta = 8.0 / 3.0;
54//!     dydt[0] = sigma * (y[1] - y[0]);
55//!     dydt[1] = y[0] * (rho - y[2]) - y[1];
56//!     dydt[2] = y[0] * y[1] - beta * y[2];
57//! }
58//!
59//! // Create problem
60//! let y0 = vec![1.0, 1.0, 1.0];
61//! let problem = OdeProblem::new(lorenz, 0.0, 20.0, y0.clone());
62//!
63//! // Solve with DoPri5
64//! let options = SolverOptions::default();
65//! let result = DoPri5::solve(&problem, 0.0, 20.0, &y0, &options).unwrap();
66//!
67//! println!("Final state: {:?}", result.y_final());
68//! ```
69//!
70//! Author: Moussa Leblouba
71//! Date: 9 February 2026
72//! Modified: 2 May 2026
73
74pub mod auto;
75pub mod bdf;
76pub mod dae_init;
77pub mod dense;
78pub mod dopri5;
79pub mod error;
80pub mod esdirk;
81pub mod events;
82pub mod index_reduction;
83pub mod problem;
84pub mod radau5;
85pub mod sensitivity;
86pub mod solver;
87pub mod step_control;
88pub mod t_eval;
89pub mod tsit5;
90pub mod uncertainty;
91pub mod verner;
92
93pub use dense::DenseOutput;
94pub use error::SolverError;
95pub use problem::{DaeProblem, OdeProblem, OdeSystem};
96pub use solver::{Solver, SolverOptions, SolverResult, SolverStats};
97pub use step_control::{PIController, StepController};
98
99// Explicit methods
100pub use dopri5::DoPri5;
101pub use tsit5::Tsit5;
102pub use verner::{Vern6, Vern7, Vern8};
103
104// Implicit methods
105pub use bdf::Bdf;
106pub use esdirk::{Esdirk32, Esdirk43, Esdirk54};
107pub use radau5::Radau5;
108
109// Automatic selection
110pub use auto::{auto_solve, auto_solve_with_hints, Accuracy, SolverHints, Stiffness};
111
112pub use sensitivity::{
113    solve_forward_sensitivity, solve_forward_sensitivity_with, AugmentedSystem, ClosureSystem,
114    ParametricOdeSystem, SensitivityResult,
115};
116
117pub use dae_init::{compute_consistent_initial, compute_consistent_initial_tol};
118
119pub use index_reduction::{
120    analyze_dae_index, analyze_system, detect_structure, reduce_dae_problem, reduce_index,
121    DaeIndexInfo, DaeStructure, ReducedDaeSystem,
122};
123
124pub use uncertainty::{
125    solve_monte_carlo, solve_trajectory, solve_with_uncertainty, UncertainParam,
126    UncertainSolverResult, UncertaintyMode,
127};
128
129pub use numra_core::{Scalar, Vector};