darkmatter 0.0.1

Dark matter simulation engine — gravitational fields, particle dynamics, halo stability, and cosmological constants
Documentation
use crate::constants::physical::G;
use std::f64::consts::PI;

pub fn perihelion_precession_rate(
    rho_dm_kg_m3: f64,
    orbital_radius: f64,
    orbital_velocity: f64,
) -> f64 {
    let m_enclosed = 4.0 / 3.0 * PI * rho_dm_kg_m3 * orbital_radius.powi(3);
    let f_dm = G * m_enclosed / (orbital_radius * orbital_radius);
    f_dm / (orbital_velocity * orbital_velocity) * 2.0 * PI
}

pub fn dm_enclosed_mass(rho_dm: f64, radius: f64) -> f64 {
    4.0 / 3.0 * PI * rho_dm * radius.powi(3)
}

pub fn orbital_velocity_correction(rho_dm_kg_m3: f64, r: f64, m_central: f64) -> f64 {
    let m_dm = dm_enclosed_mass(rho_dm_kg_m3, r);
    let v_total = (G * (m_central + m_dm) / r).sqrt();
    let v_kepler = (G * m_central / r).sqrt();
    v_total - v_kepler
}

pub fn secular_perturbation_eccentricity(
    rho_dm_kg_m3: f64,
    a: f64,
    m_central: f64,
    e: f64,
    age_s: f64,
) -> f64 {
    let m_dm = dm_enclosed_mass(rho_dm_kg_m3, a);
    let omega_k = (G * m_central / (a * a * a)).sqrt();
    let de_dt = m_dm / m_central * omega_k * e;
    de_dt * age_s
}

pub fn dynamical_friction_on_planet(
    rho_dm: f64,
    m_planet: f64,
    v_planet: f64,
    ln_lambda: f64,
) -> f64 {
    4.0 * PI * G * G * m_planet * m_planet * rho_dm * ln_lambda / (v_planet * v_planet * v_planet)
}

pub fn orbital_decay_timescale(m_planet: f64, v_planet: f64, rho_dm: f64, ln_lambda: f64) -> f64 {
    let f_df = dynamical_friction_on_planet(rho_dm, m_planet, v_planet, ln_lambda);
    m_planet * v_planet / f_df
}

pub fn dm_disk_surface_density_limit(
    orbital_period_change_fraction: f64,
    m_central: f64,
    a: f64,
    observation_time: f64,
) -> f64 {
    let omega = (G * m_central / (a * a * a)).sqrt();
    orbital_period_change_fraction * m_central / (PI * a * a * omega * observation_time)
}

pub fn ephemeris_constraint_rho(
    position_uncertainty_m: f64,
    orbital_radius: f64,
    m_central: f64,
    observation_time: f64,
) -> f64 {
    let orbital_freq = (G * m_central / (orbital_radius.powi(3))).sqrt();
    3.0 * m_central * position_uncertainty_m
        / (4.0
            * PI
            * G
            * orbital_radius.powi(3)
            * observation_time
            * observation_time
            * orbital_radius
            * orbital_freq)
}

pub fn pioneer_anomaly_like_acceleration(rho_dm: f64, r: f64) -> f64 {
    4.0 * PI * G * rho_dm * r / 3.0
}

pub const CASSINI_BOUND_RHO: f64 = 1e-20;