rebound-bind 5.0.0

Low-level Rust FFI bindings for the REBOUND N-body simulation C library.
Documentation
use rebound_bind::{
    REB_STATUS_REB_STATUS_SUCCESS, reb_particle, reb_simulation_add, reb_simulation_create,
    reb_simulation_energy, reb_simulation_free, reb_simulation_integrate,
    reb_simulation_move_to_com,
};

fn particle(m: f64, x: f64, y: f64, z: f64, vx: f64, vy: f64, vz: f64) -> reb_particle {
    reb_particle {
        x,
        y,
        z,
        vx,
        vy,
        vz,
        ax: 0.0,
        ay: 0.0,
        az: 0.0,
        m,
        r: 0.0,
        name: std::ptr::null(),
        ap: std::ptr::null_mut(),
        sim: std::ptr::null_mut(),
    }
}

#[test]
fn creates_default_simulation() {
    unsafe {
        let sim = reb_simulation_create();
        assert!(!sim.is_null());

        assert_eq!((*sim).N, 0);
        assert_eq!((*sim).t, 0.0);
        assert_eq!((*sim).G, 1.0);
        assert_eq!((*sim).dt, 0.001);

        reb_simulation_free(sim);
    }
}

#[test]
fn adds_particles_and_updates_parent_pointer() {
    unsafe {
        let sim = reb_simulation_create();
        assert!(!sim.is_null());

        reb_simulation_add(sim, particle(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
        reb_simulation_add(sim, particle(0.001, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0));

        assert_eq!((*sim).N, 2);
        assert!(!(*sim).particles.is_null());
        assert_eq!((*(*sim).particles.add(0)).sim, sim);
        assert_eq!((*(*sim).particles.add(1)).sim, sim);
        assert_eq!((*(*sim).particles.add(1)).x, 1.0);

        reb_simulation_free(sim);
    }
}

#[test]
fn integrates_simple_two_body_system() {
    unsafe {
        let sim = reb_simulation_create();
        assert!(!sim.is_null());

        (*sim).dt = 0.01;

        reb_simulation_add(sim, particle(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
        reb_simulation_add(sim, particle(0.001, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0));
        reb_simulation_move_to_com(sim);

        let initial_energy = reb_simulation_energy(sim);
        let status = reb_simulation_integrate(sim, 0.1);
        let final_energy = reb_simulation_energy(sim);

        assert_eq!(status, REB_STATUS_REB_STATUS_SUCCESS);
        assert!(((*sim).t - 0.1).abs() < 1e-12);
        assert!((*sim).steps_done > 0);
        assert!((final_energy - initial_energy).abs() < 1e-8);

        reb_simulation_free(sim);
    }
}