darkmatter 0.0.2

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

pub fn merger_timescale_boylan_kolchin(
    m_host: f64,
    m_sat: f64,
    r_vir: f64,
    v_vir: f64,
    circularity: f64,
    orbital_energy: f64,
) -> f64 {
    let mass_ratio = m_sat / m_host;
    let a = 0.94 * circularity.powf(0.60) + 0.60;
    let b = 0.90;
    a / (mass_ratio.powf(b) * (mass_ratio + 1.0).ln()) * r_vir / v_vir * orbital_energy.powf(0.1)
}

pub fn major_merger_criterion(mass_ratio: f64) -> bool {
    mass_ratio > 0.25
}

pub fn minor_merger_criterion(mass_ratio: f64) -> bool {
    mass_ratio > 0.01 && mass_ratio <= 0.25
}

pub fn tidal_stream_morphology(mass_ratio: f64) -> &'static str {
    if mass_ratio > 0.25 {
        "shell"
    } else if mass_ratio > 0.05 {
        "stream"
    } else {
        "thin_stream"
    }
}

pub fn dm_halo_merger_rate_fakhouri(m_halo_solar: f64, z: f64, xi: f64) -> f64 {
    let a = 0.0104;
    let alpha = 0.133;
    let beta = -1.995;
    let gamma_z = 0.263;
    let eta = 0.0993;
    a * (m_halo_solar / 1e12).powf(alpha)
        * xi.powf(beta)
        * (-(xi / eta).powi(2)).exp()
        * (1.0 + z).powf(gamma_z)
}

pub fn stripped_dm_fraction(m_sub_initial: f64, m_sub_final: f64) -> f64 {
    (m_sub_initial - m_sub_final) / m_sub_initial
}

pub fn intergalactic_dm_bridge_density(
    m1: f64,
    m2: f64,
    separation: f64,
    r_from_midpoint: f64,
) -> f64 {
    let m_eff = (m1 * m2).sqrt();
    let rho_bridge = G * m_eff / (C * C * separation * separation);
    rho_bridge * (-r_from_midpoint * r_from_midpoint / (separation * separation * 0.1)).exp()
}

pub fn post_merger_relaxation_time(m_merged: f64, r_vir: f64) -> f64 {
    2.0 * PI * r_vir / (G * m_merged / r_vir).sqrt()
}

pub fn sloshing_amplitude(mass_ratio: f64, v_impact: f64, r_core: f64) -> f64 {
    mass_ratio * v_impact * v_impact * r_core / (G * 1e14 * SOLAR_MASS)
}

pub fn phase_mixing_timescale(sigma_v: f64, r: f64) -> f64 {
    r / sigma_v
}

pub fn halo_response_to_merger(m_ratio: f64) -> &'static str {
    if m_ratio > 0.3 {
        "violent_relaxation"
    } else if m_ratio > 0.1 {
        "moderate_heating"
    } else {
        "minor_perturbation"
    }
}