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`] - Automatic solver selection based on problem characteristics
42//!
43//! ## Example
44//!
45//! ```rust
46//! use numra_ode::{OdeProblem, DoPri5, Solver, SolverOptions};
47//!
48//! // Define the Lorenz system
49//! fn lorenz(t: f64, y: &[f64], dydt: &mut [f64]) {
50//! let sigma = 10.0;
51//! let rho = 28.0;
52//! let beta = 8.0 / 3.0;
53//! dydt[0] = sigma * (y[1] - y[0]);
54//! dydt[1] = y[0] * (rho - y[2]) - y[1];
55//! dydt[2] = y[0] * y[1] - beta * y[2];
56//! }
57//!
58//! // Create problem
59//! let y0 = vec![1.0, 1.0, 1.0];
60//! let problem = OdeProblem::new(lorenz, 0.0, 20.0, y0.clone());
61//!
62//! // Solve with DoPri5
63//! let options = SolverOptions::default();
64//! let result = DoPri5::solve(&problem, 0.0, 20.0, &y0, &options).unwrap();
65//!
66//! println!("Final state: {:?}", result.y_final());
67//! ```
68//!
69//! Author: Moussa Leblouba
70//! Date: 9 February 2026
71//! Modified: 2 May 2026
72
73pub mod auto;
74pub mod bdf;
75pub mod dae_init;
76pub mod dense;
77pub mod dopri5;
78pub mod error;
79pub mod esdirk;
80pub mod events;
81pub mod index_reduction;
82pub mod problem;
83pub mod radau5;
84pub mod sensitivity;
85pub mod solver;
86pub mod step_control;
87pub mod t_eval;
88pub mod tsit5;
89pub mod uncertainty;
90pub mod verner;
91
92pub use dense::DenseOutput;
93pub use error::SolverError;
94pub use problem::{DaeProblem, OdeProblem, OdeSystem};
95pub use solver::{Solver, SolverOptions, SolverResult, SolverStats};
96pub use step_control::{PIController, StepController};
97
98// Explicit methods
99pub use dopri5::DoPri5;
100pub use tsit5::Tsit5;
101pub use verner::{Vern6, Vern7, Vern8};
102
103// Implicit methods
104pub use bdf::Bdf;
105pub use esdirk::{Esdirk32, Esdirk43, Esdirk54};
106pub use radau5::Radau5;
107
108// Automatic selection
109pub use auto::{auto_solve, auto_solve_with_hints, Accuracy, Auto, SolverHints, Stiffness};
110
111pub use sensitivity::{
112 solve_forward_sensitivity, solve_forward_sensitivity_with, AugmentedSystem, ClosureSystem,
113 ParametricOdeSystem, SensitivityResult,
114};
115
116pub use dae_init::{compute_consistent_initial, compute_consistent_initial_tol};
117
118pub use index_reduction::{
119 analyze_dae_index, analyze_system, detect_structure, reduce_dae_problem, reduce_index,
120 DaeIndexInfo, DaeStructure, ReducedDaeSystem,
121};
122
123pub use uncertainty::{
124 solve_monte_carlo, solve_trajectory, solve_with_uncertainty, UncertainParam,
125 UncertainSolverResult, UncertaintyMode,
126};
127
128pub use numra_core::{Scalar, Vector};