darkmatter 0.0.2

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

pub fn circular_velocity_dm(enclosed_mass: f64, r: f64) -> f64 {
    (G * enclosed_mass / r).sqrt()
}

pub fn total_rotation_velocity(v_disk: f64, v_bulge: f64, v_gas: f64, v_dm: f64) -> f64 {
    (v_disk * v_disk + v_bulge * v_bulge + v_gas * v_gas + v_dm * v_dm).sqrt()
}

pub fn disk_velocity_exponential(v_max_disk: f64, r: f64, r_d: f64) -> f64 {
    let y = r / (2.0 * r_d);
    let i0 = crate::utils::math::bessel_i0(y);
    let i1 = crate::utils::math::bessel_i1(y);
    let k0 = crate::utils::math::bessel_k0(y);
    let k1 = crate::utils::math::bessel_k1(y);
    v_max_disk * (2.0 * y * y * (i0 * k0 - i1 * k1)).sqrt()
}

pub fn bulge_velocity_hernquist(total_mass: f64, r: f64, a: f64) -> f64 {
    (G * total_mass * r / ((r + a) * (r + a))).sqrt()
}

pub fn nfw_rotation_velocity(rho_s: f64, r_s: f64, r: f64) -> f64 {
    let m = crate::halos::profiles::nfw_enclosed_mass(r, rho_s, r_s);
    (G * m / r).sqrt()
}

pub fn isothermal_rotation_velocity(sigma_v: f64) -> f64 {
    (2.0_f64).sqrt() * sigma_v
}

pub fn burkert_rotation_velocity(rho_0: f64, r_0: f64, r: f64) -> f64 {
    let m = crate::halos::profiles::burkert_enclosed_mass(r, rho_0, r_0);
    (G * m / r).sqrt()
}

#[derive(Clone, Debug, PartialEq)]
pub struct RotationCurveData {
    pub radii: Vec<f64>,
    pub velocities: Vec<f64>,
    pub errors: Vec<f64>,
}

impl RotationCurveData {
    pub fn new(radii: Vec<f64>, velocities: Vec<f64>, errors: Vec<f64>) -> Self {
        Self {
            radii,
            velocities,
            errors,
        }
    }

    pub fn chi_squared_nfw(&self, rho_s: f64, r_s: f64, v_baryon: &[f64]) -> f64 {
        self.radii
            .iter()
            .zip(self.velocities.iter())
            .zip(self.errors.iter())
            .zip(v_baryon.iter())
            .map(|(((r, v_obs), err), v_bar)| {
                let v_dm = nfw_rotation_velocity(rho_s, r_s, *r);
                let v_model = (v_dm * v_dm + v_bar * v_bar).sqrt();
                let diff = v_obs - v_model;
                diff * diff / (err * err)
            })
            .sum()
    }
}