[][src]Module nyx_space::propagators

Provides all the propagators / integrators available in nyx.

Custom derivative function example

extern crate nalgebra;
extern crate nyx_space as nyx;
use nalgebra::{U1, U3, Vector6};

fn two_body_dynamics(_t: f64, state: &Vector6<f64>) -> Vector6<f64> {
    let radius = state.fixed_slice::<U3, U1>(0, 0);
    let velocity = state.fixed_slice::<U3, U1>(3, 0);
    let body_acceleration = (-398_600.441500000015366822 / radius.norm().powi(3)) * radius;
    Vector6::from_iterator(velocity.iter().chain(body_acceleration.iter()).cloned())
}

fn main() {
    use std::f64;
    use nyx::propagators::{Dormand45, error_ctrl, Options, Propagator};
    let prop_time = 24.0 * 3_600.0;
    let accuracy = 1e-12;
    let min_step = 0.1;
    let max_step = 30.0;
    // Initial spacecraft state
    let mut init_state =
        Vector6::from_row_slice(&[-2436.45, -2436.45, 6891.037, 5.088611, -5.088611, 0.0]);
    // Final expected spaceraft state
    let rslt = Vector6::from_row_slice(&[
        -5971.194191821826,
        3945.506657649147,
        2864.636612371127,
        0.049096952217479194,
        -4.1850933148636145,
        5.848940870294863,
    ]);

    let mut cur_t = 0.0;
    let mut prop = Propagator::new::<Dormand45>(&Options::with_adaptive_step(0.1, 30.0, 1e-12));
    loop {
        let (t, state) = prop.derive(
            cur_t,
            &init_state,
            two_body_dynamics,
            error_ctrl::rss_state_pos_vel,
        );
        if t < prop_time {
            // We haven't passed the time based stopping condition.
            cur_t = t;
            init_state = state;
        } else {
            // At this point, we've passed the condition, so let's switch to a fixed step of _exactly_ the
            // previous time step minus the amount by which we overshot. This allows us to propagate in time for
            // _exactly_ the time we want to propagate for.
            let prev_details = prop.latest_details().clone();
            let overshot = t - prop_time;
            prop.set_fixed_step(prev_details.step - overshot);
            // Take one final step
            let (t, state) = prop.derive(
                cur_t,
                &init_state,
                two_body_dynamics,
                error_ctrl::rss_state_pos_vel,
            );

            assert!(
                (t - prop_time).abs() < 1e-12,
                "propagated for {} instead of {}",
                t,
                prop_time
            );

            // Let's check that, prior to the refined step, we either hit the accuracy wanted,
            // or we are using the minimum step size.
            if prev_details.error > accuracy {
                assert!(prev_details.step - min_step < f64::EPSILON);
            }

            assert_eq!(state, rslt, "leo prop failed");
            break;
        }
    }
}

Re-exports

pub use super::RK;

Modules

error_ctrl

Provides different methods for controlling the error computation of the integrator.

Structs

CashKarp45

CashKarp45 is a Runge Kutta Cash Karp integrator.

Dormand45

Dormand45 is a Dormand-Prince integrator.

Dormand78

Dormand78 is a Dormand-Prince integrator.

Fehlberg45

Fehlberg45 is a Runge Kutta Fehlberg integrator.

IntegrationDetails

Stores the details of the previous integration step of a given propagator. Access as my_prop.clone().latest_details().

Options

Options stores the integrator options, including the minimum and maximum step sizes, and the max error size.

Propagator

Includes the options, the integrator details of the previous step, and the set of coefficients used for the monomorphic instance. WARNING: must be stored in a mutuable variable.

RK2Fixed

RK2Fixed is a fixed step RK4 (or midpoint method).

RK4Fixed

RK4Fixed is a fixed step RK4.

RK89

RK89 is a Runge Kutta 8-9 integrator.

Verner56

Verner56 is an RK Verner integrator of order 5-6.

Traits

RK

The RK trait defines a Runge Kutta integrator.