RKF78
A high-precision Runge-Kutta-Fehlberg 7(8) ODE integrator in Rust.
Why RKF78?
RKF78 is an 8th-order embedded Runge-Kutta method with 7th-order error estimation — one of the highest-order single-step integrators in common use. It takes large, accurate steps on smooth problems, making it ideal when you need high precision without a huge step count.
- Zero runtime dependencies — No nalgebra, no BLAS, no math libraries. Just Rust.
- Const-generic
[T; N]arrays — Compile-time state dimension, zero heap allocation during integration. - Generic over f32/f64 — One codebase, two precision levels.
- NASA-heritage coefficients — From the original 1968 Fehlberg paper (NASA TR R-287).
- Event detection — Brent's method + Hermite cubic interpolation for precise zero-crossing location, simultaneous multi-event support, Stop/Continue actions.
- Dense output — Hermite cubic interpolation between steps for continuous trajectory evaluation.
- Step observer — Callback after each accepted step for custom recording or analysis.
- GPU batch propagation — Thousands of parallel integrations via
wgpucompute shaders.
When to use RKF78
RKF78 excels on smooth, non-stiff ODE systems where high accuracy is needed:
- Orbital mechanics and trajectory propagation
- Oscillators, wave equations, vibration analysis
- Celestial mechanics and N-body problems
- Chemical kinetics (non-stiff regimes)
- Control system simulation
- Any
dy/dt = f(t, y)where you need better than 4th-order accuracy
If your problem is stiff (e.g., fast chemical reactions, circuit transients with widely-separated time scales), use an implicit method instead.
Quick Start
use ;
// Define your ODE system: y'' + y = 0 (harmonic oscillator)
let sys = Oscillator ;
let tol = new;
let mut solver = new;
let y0 = ; // y(0) = 1, y'(0) = 0
let config = new;
let = solver.integrate.unwrap;
Event Detection
Detect when a user-defined function crosses zero during integration.
use ;
let event = ThresholdCrossing ;
let config = EventConfig ;
let int_config = new;
let = solver.integrate_to_event.unwrap;
match result
For simultaneous events, implement MultiEventFunction<T, N, M> and use integrate_with_multi_events().
Events can also be configured with EventAction::Continue to record all crossings without stopping.
Dense Output
Record the full trajectory and evaluate at arbitrary times:
let = solver.integrate_dense.unwrap;
// Evaluate anywhere in [t0, tf] via Hermite cubic interpolation
let y_mid = solution.eval.unwrap;
let dy_mid = solution.eval_derivative.unwrap;
Step Observer
Inspect each accepted step during integration:
use StepObserver;
;
let mut tracker = MaxErrorTracker;
let = solver.integrate_with_observer.unwrap;
Tolerance Selection
| Precision Level | atol |
rtol |
Use Case |
|---|---|---|---|
| High | 1e-12 |
1e-12 |
Reference solutions, precision analysis |
| Standard | 1e-10 |
1e-10 |
General engineering analysis |
| Fast | 1e-6 |
1e-6 |
Quick surveys, parameter sweeps |
For mixed-unit state vectors (e.g., position in km and velocity in km/s), use per-component tolerances via Tolerances::with_components().
Algorithm Details
For a full explanation of the mathematics — Butcher tableau, error estimation, step-size control, and Brent's method — see docs/algorithm.md.
Building and Testing
GPU Batch Propagation
With the gpu feature, RKF78 can propagate thousands of trajectories in parallel on the GPU using wgpu compute shaders. The GPU solver uses f32 precision — suitable for Monte Carlo studies, parameter sweeps, and trade studies where throughput matters more than last-digit precision.
Users supply their own WGSL force model, which is prepended to the RKF78 compute shader at pipeline creation time.
use ;
let propagator = new?;
let = propagator.propagate_batch?;
See examples/gpu_two_body.rs for a complete example with a Keplerian force model.
Examples
| Example | Description |
|---|---|
| Harmonic Oscillator | Basic integration with exact-solution comparison |
| Dense Output | Continuous trajectory evaluation via Hermite interpolation |
| Step Observer | Recording integration progress with a callback |
| Two-Body Orbit | Keplerian orbit with per-component tolerances |
| Event Detection | Zero-crossing detection with Stop and Continue actions |
| GPU Two-Body | GPU batch propagation of multiple orbits |
See examples/README.md for a suggested reading order.
References
- Fehlberg, E. (1968). "Classical Fifth-, Sixth-, Seventh-, and Eighth-Order Runge-Kutta Formulas with Stepsize Control". NASA TR R-287.
- Hairer, E., Norsett, S.P., & Wanner, G. (1993). "Solving Ordinary Differential Equations I". Springer.
- Brent, R.P. (1973). "Algorithms for Minimization without Derivatives". Prentice-Hall.
Development
This project was co-developed with Claude, an AI assistant by Anthropic.
License
Licensed under the MIT License.