use crate::constants::physical::{C, HBAR};
use std::f64::consts::PI;
pub const ALPHA_EM: f64 = 1.0 / 137.035_999;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DarkPhoton {
pub mass_gev: f64,
pub kinetic_mixing: f64,
}
impl DarkPhoton {
pub fn mass_kg(&self) -> f64 {
self.mass_gev * 1.782_661_92e-27
}
pub fn decay_width_to_electrons_gev(&self) -> f64 {
let me_gev = 0.000_511;
if self.mass_gev < 2.0 * me_gev {
return 0.0;
}
let beta = (1.0 - 4.0 * me_gev * me_gev / (self.mass_gev * self.mass_gev)).sqrt();
self.kinetic_mixing * self.kinetic_mixing * ALPHA_EM * self.mass_gev / 3.0
* (1.0 + 2.0 * me_gev * me_gev / (self.mass_gev * self.mass_gev))
* beta
}
pub fn lifetime_seconds(&self) -> f64 {
let width = self.decay_width_to_electrons_gev();
if width <= 0.0 {
return f64::INFINITY;
}
HBAR / (width * 1.782_661_92e-27 * C * C)
}
pub fn decay_length_meters(&self, gamma_lorentz: f64) -> f64 {
let tau = self.lifetime_seconds();
if tau.is_infinite() {
return f64::INFINITY;
}
C * tau * gamma_lorentz
}
pub fn production_cross_section_cm2(&self, s_gev2: f64) -> f64 {
let eps2 = self.kinetic_mixing * self.kinetic_mixing;
let m2 = self.mass_gev * self.mass_gev;
4.0 * PI * ALPHA_EM * ALPHA_EM * eps2 * s_gev2
/ ((s_gev2 - m2).powi(2)
+ (self.decay_width_to_electrons_gev() * self.mass_gev).powi(2))
* 0.389_379e-27
}
}
pub fn kinetic_mixing_from_loop(coupling: f64, mass_heavy_gev: f64) -> f64 {
coupling * ALPHA_EM / (6.0 * PI) * (mass_heavy_gev / 1.0).ln()
}
pub fn dark_fine_structure_constant(g_dark: f64) -> f64 {
g_dark * g_dark / (4.0 * PI)
}
pub fn portal_coupling_higgs(lambda_hp: f64, v_higgs_gev: f64, v_dark_gev: f64) -> f64 {
lambda_hp * v_higgs_gev * v_dark_gev
}
pub fn invisible_branching_ratio(width_invisible_gev: f64, width_visible_gev: f64) -> f64 {
width_invisible_gev / (width_invisible_gev + width_visible_gev)
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ChameleonField {
pub coupling_matter: f64,
pub lambda_scale_ev: f64,
pub n_power: f64,
}
impl ChameleonField {
pub fn effective_mass_ev(&self, rho_kg_m3: f64) -> f64 {
let rho_ev4 = rho_kg_m3 / 1.782_661_92e-36 * 1e9;
let lambda4 = self.lambda_scale_ev.powi(4);
let n = self.n_power;
((n + 1.0)
* lambda4
* (self.coupling_matter * rho_ev4 / lambda4).powf((n + 2.0) / (n + 1.0)))
.powf(0.5 / (n + 2.0))
}
pub fn compton_wavelength_meters(&self, rho_kg_m3: f64) -> f64 {
let m_ev = self.effective_mass_ev(rho_kg_m3);
if m_ev <= 0.0 {
return f64::INFINITY;
}
HBAR / (m_ev * 1.782_661_92e-36 * C)
}
pub fn thin_shell_factor(&self, rho_inside: f64, rho_outside: f64, radius: f64) -> f64 {
let phi_inside = self.field_value_ev(rho_inside);
let phi_outside = self.field_value_ev(rho_outside);
let delta_phi = (phi_outside - phi_inside).abs();
let m_pl_ev = 1.221e28;
delta_phi / (self.coupling_matter * m_pl_ev * radius)
}
fn field_value_ev(&self, rho_kg_m3: f64) -> f64 {
let rho_ev4 = rho_kg_m3 / 1.782_661_92e-36 * 1e9;
let lambda4 = self.lambda_scale_ev.powi(4);
let n = self.n_power;
lambda4.powf(1.0 / (n + 1.0)) / (self.coupling_matter * rho_ev4).powf(1.0 / (n + 1.0))
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SymmetronField {
pub mu_gev: f64,
pub lambda_coupling: f64,
pub m_scale_gev: f64,
}
impl SymmetronField {
pub fn critical_density_kg_m3(&self) -> f64 {
self.mu_gev * self.mu_gev * self.m_scale_gev * self.m_scale_gev * 1.782_661_92e-27
/ (HBAR.powi(3) * C.powi(3))
* 1e-18
}
pub fn symmetry_restored(&self, rho_kg_m3: f64) -> bool {
rho_kg_m3 > self.critical_density_kg_m3()
}
pub fn vev_gev(&self, rho_kg_m3: f64) -> f64 {
let rho_crit = self.critical_density_kg_m3();
if rho_kg_m3 >= rho_crit {
return 0.0;
}
(self.mu_gev * self.mu_gev / self.lambda_coupling * (1.0 - rho_kg_m3 / rho_crit)).sqrt()
}
pub fn effective_mass_gev(&self, rho_kg_m3: f64) -> f64 {
let rho_crit = self.critical_density_kg_m3();
if rho_kg_m3 >= rho_crit {
return (self.mu_gev * self.mu_gev * (rho_kg_m3 / rho_crit - 1.0)).sqrt();
}
(2.0 * self.mu_gev * self.mu_gev * (1.0 - rho_kg_m3 / rho_crit)).sqrt()
}
}
pub fn yukawa_potential(g: f64, r: f64, m_mediator_kg: f64) -> f64 {
let inv_range = m_mediator_kg * C / HBAR;
-g * g / (4.0 * PI * r) * (-inv_range * r).exp()
}
pub fn mediator_range_meters(mass_gev: f64) -> f64 {
HBAR / (mass_gev * 1.782_661_92e-27 * C)
}
pub fn sommerfeld_enhancement(alpha: f64, v_over_c: f64) -> f64 {
let x = PI * alpha / v_over_c;
x / (1.0 - (-2.0 * x).exp())
}
pub fn dark_sector_temperature(xi: f64, t_photon_gev: f64) -> f64 {
xi * t_photon_gev
}
pub fn delta_neff_from_dark_radiation(g_star_dark: f64, xi: f64) -> f64 {
g_star_dark * (xi).powi(4) * 4.0 / 7.0
}