librebound-sys 4.6.0

Raw FFI bindings and safe RAII wrappers for the REBOUND N-body integrator
Documentation
//! Raw FFI bindings to the REBOUND C library.
//!
//! `reb_simulation` is treated as an opaque type. Field access goes through
//! thin C helpers compiled in `helpers.c`.

use libc::{c_double, c_int, c_uint, c_void};

// ---------------------------------------------------------------------------
// reb_particle — the only REBOUND struct we reproduce in full.
// Passed by value in reb_simulation_add and returned by ASSIST routines.
// ---------------------------------------------------------------------------

/// REBOUND particle: position, velocity, acceleration, mass, radius, hash.
///
/// Layout matches `struct reb_particle` in `rebound.h` on LP64 platforms.
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct reb_particle {
    pub x: c_double,
    pub y: c_double,
    pub z: c_double,
    pub vx: c_double,
    pub vy: c_double,
    pub vz: c_double,
    pub ax: c_double,
    pub ay: c_double,
    pub az: c_double,
    pub m: c_double,
    pub r: c_double,
    pub last_collision: c_double,
    pub c: *mut c_void, // reb_treecell*
    pub hash: u32,
    pub ap: *mut c_void,
    pub sim: *mut c_void, // reb_simulation*
}

impl Default for reb_particle {
    fn default() -> Self {
        Self {
            x: 0.0,
            y: 0.0,
            z: 0.0,
            vx: 0.0,
            vy: 0.0,
            vz: 0.0,
            ax: 0.0,
            ay: 0.0,
            az: 0.0,
            m: 0.0,
            r: 0.0,
            last_collision: 0.0,
            c: std::ptr::null_mut(),
            hash: 0,
            ap: std::ptr::null_mut(),
            sim: std::ptr::null_mut(),
        }
    }
}

// ---------------------------------------------------------------------------
// Opaque types — fields accessed only through C helpers.
// ---------------------------------------------------------------------------

/// Opaque REBOUND simulation.
#[repr(C)]
pub struct reb_simulation {
    _opaque: [u8; 0],
}

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

// REBOUND integrator IDs (from enum in reb_simulation)
pub const REB_INTEGRATOR_IAS15: c_int = 0;
pub const REB_INTEGRATOR_WHFAST: c_int = 1;

// REBOUND gravity modes
pub const REB_GRAVITY_NONE: c_int = 0;
pub const REB_GRAVITY_BASIC: c_int = 1;

// REBOUND status codes
pub const REB_STATUS_SUCCESS: c_int = 0;
pub const REB_STATUS_RUNNING: c_int = -1;
pub const REB_STATUS_GENERIC_ERROR: c_int = 1;
pub const REB_STATUS_NO_PARTICLES: c_int = 2;
pub const REB_STATUS_ENCOUNTER: c_int = 3;
pub const REB_STATUS_ESCAPE: c_int = 4;
pub const REB_STATUS_USER: c_int = 5;
pub const REB_STATUS_SIGINT: c_int = 6;
pub const REB_STATUS_COLLISION: c_int = 7;

// ---------------------------------------------------------------------------
// REBOUND functions
// ---------------------------------------------------------------------------

unsafe extern "C" {
    // Simulation lifecycle
    pub fn reb_simulation_create() -> *mut reb_simulation;
    pub fn reb_simulation_free(r: *mut reb_simulation);

    // Particle management
    pub fn reb_simulation_add(r: *mut reb_simulation, pt: reb_particle);

    // Integration
    pub fn reb_simulation_integrate(r: *mut reb_simulation, tmax: c_double) -> c_int;
    pub fn reb_simulation_step(r: *mut reb_simulation);
    pub fn reb_simulation_synchronize(r: *mut reb_simulation);

    // Variational equations
    pub fn reb_simulation_add_variation_1st_order(
        r: *mut reb_simulation,
        testparticle: c_int,
    ) -> c_int;

    // Integrator reset: frees IAS15 scratch arrays (b/e/br/er/csb/csx/csv/csa0
    // plus g/x0/v0/a0/at/map). Required between orbit reuses to clear
    // cross-orbit carryover in the compensated-summation and predictor state.
    pub fn reb_integrator_ias15_reset(r: *mut reb_simulation);
}

// ---------------------------------------------------------------------------
// C helper functions (from src/helpers.c)
// ---------------------------------------------------------------------------

unsafe extern "C" {
    // reb_simulation field accessors
    pub fn assist_rs_sim_get_t(r: *const reb_simulation) -> c_double;
    pub fn assist_rs_sim_set_t(r: *mut reb_simulation, t: c_double);
    pub fn assist_rs_sim_get_dt(r: *const reb_simulation) -> c_double;
    pub fn assist_rs_sim_set_dt(r: *mut reb_simulation, dt: c_double);
    pub fn assist_rs_sim_get_N(r: *const reb_simulation) -> c_uint;
    pub fn assist_rs_sim_get_steps_done(r: *const reb_simulation) -> u64;
    pub fn assist_rs_ias15_zero_state(r: *mut reb_simulation);
    pub fn assist_rs_sim_get_N_var(r: *const reb_simulation) -> c_int;
    pub fn assist_rs_sim_get_N_active(r: *const reb_simulation) -> c_int;
    pub fn assist_rs_sim_set_N_active(r: *mut reb_simulation, n: c_int);
    pub fn assist_rs_sim_get_particles(r: *const reb_simulation) -> *mut reb_particle;
    pub fn assist_rs_sim_get_exact_finish_time(r: *const reb_simulation) -> c_int;
    pub fn assist_rs_sim_set_exact_finish_time(r: *mut reb_simulation, v: c_int);
    pub fn assist_rs_sim_get_force_is_velocity_dependent(r: *const reb_simulation) -> c_uint;
    pub fn assist_rs_sim_get_status(r: *const reb_simulation) -> c_int;
    pub fn assist_rs_sim_get_extras(r: *const reb_simulation) -> *mut c_void;
    pub fn assist_rs_sim_get_integrator(r: *const reb_simulation) -> c_int;
    pub fn assist_rs_sim_set_integrator(r: *mut reb_simulation, i: c_int);
    pub fn assist_rs_sim_get_gravity(r: *const reb_simulation) -> c_int;
    pub fn assist_rs_sim_set_gravity(r: *mut reb_simulation, g: c_int);
    pub fn assist_rs_sim_get_ias15_epsilon(r: *const reb_simulation) -> c_double;
    pub fn assist_rs_sim_set_ias15_epsilon(r: *mut reb_simulation, eps: c_double);
    pub fn assist_rs_sim_get_ias15_min_dt(r: *const reb_simulation) -> c_double;
    pub fn assist_rs_sim_set_ias15_min_dt(r: *mut reb_simulation, min_dt: c_double);
    pub fn assist_rs_sim_get_ias15_adaptive_mode(r: *const reb_simulation) -> c_int;
    pub fn assist_rs_sim_set_ias15_adaptive_mode(r: *mut reb_simulation, mode: c_int);
    pub fn assist_rs_sim_get_ias15_iterations_max_exceeded(r: *const reb_simulation) -> u64;
}