A high-precision N-body solar system orbital mechanics engine in C++20.
- Three integrators — Forward Euler (baseline), 4th-order Runge-Kutta, and Velocity Verlet (symplectic, default)
- Symplectic energy conservation — Verlet achieves ΔE/E₀ < 10⁻¹⁰ over 2 years at 1-hour timestep
- NASA J2000.0 initial conditions — all 8 planets with heliocentric ecliptic coordinates
- CSV and JSON export — streaming trajectory output, parseable by Python scripts
- Orbital element analysis — compute semi-major axis, eccentricity, inclination from state vectors
- Energy tracking — record and compare total mechanical energy drift across integrators
- Benchmark mode — side-by-side comparison of all three integrators
- 38 unit tests via Catch2 v3
# Prerequisites: C++20 compiler, CMake 3.20+, Ninja (optional)
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build
# Run 1-year solar system simulation (Verlet, 1-hour timestep)
mkdir output
./build/app/astro_sim --integrator verlet --dt 3600 --time 1 --verbose
# Run all unit tests
ctest --test-dir build
# Run integrator benchmark
./build/app/astro_sim --benchmark --dt 3600 --time 2
# Generate orbit plot (requires matplotlib, pandas)
python3 scripts/plot_orbits.py --csv output/trajectories.csv
# Generate energy comparison plot
python3 scripts/plot_energy.py --years 5astro-engine/
├── src/
│ ├── core/ Vec3, CelestialBody, Simulation, Constants
│ ├── integrators/ Euler, RK4, Verlet (all inherit Integrator)
│ ├── io/ CSVExporter, JSONExporter, EphemerisLoader
│ └── analysis/ EnergyTracker, OrbitalElements
├── app/ CLI entry point (astro_sim)
├── tests/ 38 Catch2 unit tests
├── data/ J2000.0 initial conditions JSON
└── scripts/ Python visualization and Horizons fetcher
See docs/architecture.md for the full module diagram.
Energy conservation benchmark (5 years, dt = 3600 s, 9-body solar system):
| Integrator | Order | Symplectic | ΔE/E₀ after 2 years | Wall time (2yr) |
|---|---|---|---|---|
| Forward Euler | 1st | No | ~10⁻³ (diverging) | ~0.07 s |
| RK4 | 4th | No | ~10⁻¹⁴ (bounded) | ~0.35 s |
| Velocity Verlet | 2nd | Yes | ~10⁻¹⁰ (bounded) | ~0.11 s |
RK4 achieves lower instantaneous error but is non-symplectic — over long integration times, Verlet's exact conservation of the modified Hamiltonian makes it the superior choice for orbital mechanics.
Usage: astro_sim [OPTIONS]
-i, --integrator <euler|rk4|verlet> Integration method (default: verlet)
-d, --dt <seconds> Timestep (default: 3600)
-t, --time <years> Duration in years (default: 1)
-f, --format <csv|json> Output format (default: csv)
-o, --output <path> Output directory (default: ./output/)
-c, --conditions <path> Initial conditions JSON
-e, --export-interval <N> Export every N steps (default: 24)
--no-energy Disable energy tracking
-v, --verbose Verbose output
--benchmark Compare all 3 integrators
The engine integrates Newton's gravitational equations of motion for N bodies:
See PHYSICS.md for full derivations of the integrators, symplectic structure, total energy formula, vis-viva equation, and orbital element conversion.
ctest --test-dir build --output-on-failure
# 38/38 tests passKey validation tests:
- Verlet circular orbit: position error < 1% after 1 year at dt=3600s
- Kepler's 3rd law: Earth period = 365.25 ± 2 days
- Energy conservation: ΔE/E₀ < 10⁻⁶ over 5 orbits (Verlet)
- Euler energy drift: ΔE/E₀ > 10⁻⁵ over 5 orbits (expected degradation)
- Murray, C. D. & Dermott, S. F. (1999). Solar System Dynamics. Cambridge University Press.
- Hairer, E., Lubich, C. & Wanner, G. (2006). Geometric Numerical Integration. Springer.
- NASA JPL Horizons (initial conditions): https://ssd.jpl.nasa.gov/horizons/
Author: Alex Souza (@alexsouzadev) — MIT License

