darkmatter 0.0.2

Dark matter simulation engine — gravitational fields, particle dynamics, halo stability, and cosmological constants
Documentation
use darkmatter::candidates::fuzzy_dm::{
    FuzzyDarkMatter, condensation_fraction, core_halo_mass_relation_solar, dynamical_heating_rate,
    granule_mass_solar, gravitational_pressure, interference_fringe_scale_kpc, occupation_number,
    quantum_jeans_wavenumber, quantum_pressure, soliton_central_density, soliton_density_profile,
    soliton_mass_solar, superradiance_rate, suppression_transfer_function,
};

fn approx_eq(a: f64, b: f64, rel_tol: f64) -> bool {
    if a == 0.0 && b == 0.0 {
        return true;
    }
    let denom = a.abs().max(b.abs());
    (a - b).abs() / denom < rel_tol
}

#[test]
fn struct_basic() {
    let fdm = FuzzyDarkMatter { mass_ev: 1e-22 };
    assert!(fdm.mass_kg() > 0.0);
    assert!(approx_eq(fdm.m22(), 1.0, 1e-6));
    assert!(fdm.compton_wavelength_m() > 0.0);
}

#[test]
fn de_broglie() {
    let fdm = FuzzyDarkMatter { mass_ev: 1e-22 };
    let lambda = fdm.de_broglie_wavelength_kpc(200.0);
    assert!(lambda > 0.0);
    assert!(lambda < 100.0);
}

#[test]
fn jeans_scales() {
    let fdm = FuzzyDarkMatter { mass_ev: 1e-22 };
    let rho = 1e-25;
    let l_j = fdm.jeans_length_kpc(rho);
    let m_j = fdm.jeans_mass_solar(rho);
    assert!(l_j > 0.0);
    assert!(m_j > 0.0);
}

#[test]
fn soliton() {
    let fdm = FuzzyDarkMatter { mass_ev: 1e-22 };
    let r_c = fdm.soliton_core_radius_kpc(1e12);
    assert!(r_c > 0.0);
    assert!(r_c < 10.0);

    let rho_c = soliton_central_density(1e-22, r_c);
    assert!(rho_c > 0.0);

    let rho_r = soliton_density_profile(0.5, rho_c, r_c);
    assert!(rho_r > 0.0);
    assert!(rho_r <= rho_c);

    let m_sol = soliton_mass_solar(rho_c, r_c);
    assert!(m_sol > 0.0);
}

#[test]
fn core_halo_relation() {
    let m_core = core_halo_mass_relation_solar(1e-22, 1e12);
    assert!(m_core > 0.0);
    assert!(m_core < 1e12);
}

#[test]
fn quantum_vs_gravitational_pressure() {
    let mass_ev = 1e-22;
    let rho = 1e-25;
    let r = 3.0857e19;
    let p_q = quantum_pressure(mass_ev, rho, r);
    let p_g = gravitational_pressure(rho, r);
    assert!(p_q > 0.0);
    assert!(p_g > 0.0);
}

#[test]
fn jeans_wavenumber() {
    let k_j = quantum_jeans_wavenumber(1e-22, 1e-25);
    assert!(k_j > 0.0);
}

#[test]
fn suppression() {
    let t1 = suppression_transfer_function(0.01, 1e-22);
    let t2 = suppression_transfer_function(100.0, 1e-22);
    assert!(t1 < t2);
    assert!(t2 > 0.0);
}

#[test]
fn interference_fringe() {
    let scale = interference_fringe_scale_kpc(1e-22, 200.0);
    assert!(scale > 0.0);
}

#[test]
fn granule_mass() {
    let m_g = granule_mass_solar(1e-22, 1e-25, 200.0);
    assert!(m_g > 0.0);
}

#[test]
fn dynamical_heating() {
    let rate = dynamical_heating_rate(1e-22, 1e-25, 200.0);
    assert!(rate > 0.0);
}

#[test]
fn superradiance() {
    let rate = superradiance_rate(1e-12, 10.0, 0.9);
    assert!(rate >= 0.0);
}

#[test]
fn occupation_number_positive() {
    let n_occ = occupation_number(1e-25, 1e-22, 200.0);
    assert!(n_occ > 0.0);
}

#[test]
fn condensation() {
    let f = condensation_fraction(1.0, 10.0);
    assert!(f > 0.0);
    assert!(f < 1.0);

    let f_above = condensation_fraction(20.0, 10.0);
    assert_eq!(f_above, 0.0);
}

#[test]
fn half_mode_mass() {
    let fdm = FuzzyDarkMatter { mass_ev: 1e-22 };
    let m_hm = fdm.half_mode_mass_solar();
    assert!(m_hm > 0.0);
}