use crate::gravity::interactions::{j2_acceleration, relativistic_correction, total_acceleration};
use crate::{CelestialBody, Vec3};
const TEST_PARTICLE_MASS: f64 = 1e20;
fn dm_halo_acceleration(body: &CelestialBody) -> Vec3 {
let r_vec = body.position;
let r = r_vec.magnitude();
if r < 1.0 {
return Vec3::ZERO;
}
let rho_local = crate::darkmatter::halo::local_dm_density();
let m_enc = crate::darkmatter::halo::dm_enclosed_mass_uniform(rho_local, r);
let factor = darkmatter::constants::physical::G * m_enc / (r * r * r);
r_vec * (-factor)
}
pub fn compute_accelerations(bodies: &mut [CelestialBody]) {
let snapshot: Vec<CelestialBody> = bodies.to_vec();
let massive_indices: Vec<usize> = snapshot
.iter()
.enumerate()
.filter(|(_, b)| b.mass >= TEST_PARTICLE_MASS)
.map(|(i, _)| i)
.collect();
for body in bodies.iter_mut() {
let mut acc = Vec3::ZERO;
if body.mass >= TEST_PARTICLE_MASS {
for &mi in &massive_indices {
if snapshot[mi].id == body.id {
continue;
}
acc +=
crate::gravity::interactions::gravitational_acceleration(body, &snapshot[mi]);
}
} else {
for &mi in &massive_indices {
acc +=
crate::gravity::interactions::gravitational_acceleration(body, &snapshot[mi]);
}
}
if let Some(parent_id) = body.id.parent()
&& let Some(parent) = snapshot.iter().find(|b| b.id == parent_id)
{
acc += j2_acceleration(body, parent);
}
acc += dm_halo_acceleration(body);
body.acceleration = acc;
}
}
pub fn compute_accelerations_relativistic(bodies: &mut [CelestialBody]) {
let snapshot: Vec<CelestialBody> = bodies.to_vec();
let massive_indices: Vec<usize> = snapshot
.iter()
.enumerate()
.filter(|(_, b)| b.mass >= TEST_PARTICLE_MASS)
.map(|(i, _)| i)
.collect();
for body in bodies.iter_mut() {
let mut acc = Vec3::ZERO;
if body.mass >= TEST_PARTICLE_MASS {
for &mi in &massive_indices {
if snapshot[mi].id == body.id {
continue;
}
acc +=
crate::gravity::interactions::gravitational_acceleration(body, &snapshot[mi]);
}
} else {
for &mi in &massive_indices {
acc +=
crate::gravity::interactions::gravitational_acceleration(body, &snapshot[mi]);
}
}
if let Some(parent_id) = body.id.parent()
&& let Some(parent) = snapshot.iter().find(|b| b.id == parent_id)
{
acc += j2_acceleration(body, parent);
acc += relativistic_correction(body, parent);
}
acc += dm_halo_acceleration(body);
body.acceleration = acc;
}
}
pub fn compute_pure_gravitational(bodies: &mut [CelestialBody]) {
let snapshot: Vec<CelestialBody> = bodies.to_vec();
for (i, body) in bodies.iter_mut().enumerate() {
body.acceleration = total_acceleration(&snapshot[i], &snapshot);
}
}
pub fn total_system_energy(bodies: &[CelestialBody]) -> f64 {
crate::config::parameters::total_energy(bodies)
}
pub fn total_system_angular_momentum(bodies: &[CelestialBody]) -> Vec3 {
crate::config::parameters::total_angular_momentum(bodies)
}
pub fn barycenter(bodies: &[CelestialBody]) -> (Vec3, Vec3) {
crate::config::parameters::system_barycenter(bodies)
}