use crate::constants::physical::{C, K_B};
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DarkMatterParticle {
pub mass_kg: f64,
pub position: [f64; 3],
pub velocity: [f64; 3],
}
impl DarkMatterParticle {
pub fn new(mass_kg: f64, position: [f64; 3], velocity: [f64; 3]) -> Self {
Self {
mass_kg,
position,
velocity,
}
}
pub fn kinetic_energy(&self) -> f64 {
let v2 = self.velocity[0] * self.velocity[0]
+ self.velocity[1] * self.velocity[1]
+ self.velocity[2] * self.velocity[2];
0.5 * self.mass_kg * v2
}
pub fn speed(&self) -> f64 {
let v2 = self.velocity[0] * self.velocity[0]
+ self.velocity[1] * self.velocity[1]
+ self.velocity[2] * self.velocity[2];
v2.sqrt()
}
pub fn lorentz_factor(&self) -> f64 {
let v = self.speed();
let beta = v / C;
1.0 / (1.0 - beta * beta).sqrt()
}
pub fn relativistic_mass(&self) -> f64 {
self.mass_kg * self.lorentz_factor()
}
pub fn momentum(&self) -> [f64; 3] {
[
self.mass_kg * self.velocity[0],
self.mass_kg * self.velocity[1],
self.mass_kg * self.velocity[2],
]
}
pub fn advance(&mut self, dt: f64, acceleration: [f64; 3]) {
self.velocity[0] += acceleration[0] * dt;
self.velocity[1] += acceleration[1] * dt;
self.velocity[2] += acceleration[2] * dt;
self.position[0] += self.velocity[0] * dt;
self.position[1] += self.velocity[1] * dt;
self.position[2] += self.velocity[2] * dt;
}
pub fn distance_to(&self, other: &DarkMatterParticle) -> f64 {
let dx = self.position[0] - other.position[0];
let dy = self.position[1] - other.position[1];
let dz = self.position[2] - other.position[2];
(dx * dx + dy * dy + dz * dz).sqrt()
}
}
pub fn maxwell_boltzmann_speed_rms(temperature: f64, mass_kg: f64) -> f64 {
(3.0 * K_B * temperature / mass_kg).sqrt()
}
pub fn maxwell_boltzmann_speed_peak(temperature: f64, mass_kg: f64) -> f64 {
(2.0 * K_B * temperature / mass_kg).sqrt()
}
pub fn velocity_dispersion_1d(temperature: f64, mass_kg: f64) -> f64 {
(K_B * temperature / mass_kg).sqrt()
}
pub fn jeans_mass(temperature: f64, particle_mass_kg: f64, density: f64) -> f64 {
let cs = velocity_dispersion_1d(temperature, particle_mass_kg);
let g = crate::constants::physical::G;
let pi = std::f64::consts::PI;
(pi / 6.0) * density * (pi * cs * cs / (g * density)).powf(1.5)
}
pub fn free_streaming_length(mass_gev: f64, temperature_k: f64) -> f64 {
let mass_kg = crate::constants::physical::gev_to_kg(mass_gev);
let v_th = maxwell_boltzmann_speed_rms(temperature_k, mass_kg);
let t_eq = crate::constants::cosmic::REDSHIFT_MATTER_RADIATION_EQ;
let h_si = crate::constants::cosmic::HUBBLE_CONSTANT_SI;
v_th / (h_si * (1.0 + t_eq).sqrt())
}