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"
}
}