use crate::constants::physical::{C, G, SOLAR_MASS};
use std::f64::consts::PI;
pub fn cluster_total_mass_from_velocity_dispersion(sigma_v: f64, r_vir: f64) -> f64 {
3.0 * sigma_v * sigma_v * r_vir / G
}
pub fn virial_radius_from_mass(m_200: f64, rho_crit: f64) -> f64 {
(3.0 * m_200 / (4.0 * PI * 200.0 * rho_crit)).powf(1.0 / 3.0)
}
pub fn virial_mass_from_radius(r_200: f64, rho_crit: f64) -> f64 {
4.0 / 3.0 * PI * 200.0 * rho_crit * r_200.powi(3)
}
pub fn nfw_concentration_cluster(m_200_solar: f64, z: f64) -> f64 {
let m14 = m_200_solar / 1e14;
3.67 * m14.powf(-0.095) * (1.0 + z).powf(-0.71)
}
pub fn hydrostatic_mass(r: f64, t_gas_kelvin: f64, dt_dr: f64, rho_gas: f64, drho_dr: f64) -> f64 {
let k_b = 1.381e-23;
let mu = 0.6;
let mp = 1.673e-27;
-k_b * r * r / (G * mu * mp) * (dt_dr / t_gas_kelvin + drho_dr / rho_gas) * t_gas_kelvin
}
pub fn caustic_mass(r: f64, amplitude_sq: f64) -> f64 {
amplitude_sq * r / (2.0 * G)
}
pub fn splashback_radius(r_200: f64, accretion_rate: f64) -> f64 {
r_200 * (1.0 + 0.18 * accretion_rate).recip()
}
pub fn cluster_mass_from_weak_lensing(tangential_shear: f64, sigma_cr: f64, r: f64) -> f64 {
PI * r * r * tangential_shear * sigma_cr
}
pub fn nfw_mass_profile(rho_s: f64, r_s: f64, r: f64) -> f64 {
let x = r / r_s;
4.0 * PI * rho_s * r_s.powi(3) * ((1.0 + x).ln() - x / (1.0 + x))
}
pub fn cluster_baryon_fraction(m_gas: f64, m_stars: f64, m_total: f64) -> f64 {
(m_gas + m_stars) / m_total
}
pub fn dark_matter_fraction_cluster(m_total: f64, m_gas: f64, m_stars: f64) -> f64 {
1.0 - (m_gas + m_stars) / m_total
}
pub fn mass_temperature_relation(t_kev: f64) -> f64 {
1e14 * (t_kev / 5.0).powf(1.5) * SOLAR_MASS
}
pub fn mass_richness_relation(n_galaxies: f64) -> f64 {
1e14 * (n_galaxies / 40.0).powf(1.3) * SOLAR_MASS
}
pub fn mass_luminosity_relation(l_x_erg_s: f64) -> f64 {
1e14 * (l_x_erg_s / 1e44).powf(0.6) * SOLAR_MASS
}
pub fn concentration_mass_relation_duffy(m_200_solar: f64, z: f64) -> f64 {
5.71 * (m_200_solar / 2e12).powf(-0.084) * (1.0 + z).powf(-0.47)
}
pub fn relativistic_mass_correction(m_newtonian: f64, r: f64) -> f64 {
let rs = 2.0 * G * m_newtonian / (C * C);
m_newtonian * (1.0 + rs / (2.0 * r))
}
pub fn velocity_dispersion_to_temperature(sigma_v: f64, mu: f64) -> f64 {
let mp = 1.673e-27;
let k_b = 1.381e-23;
mu * mp * sigma_v * sigma_v / k_b
}