use crate::consts;
use crate::mathtypes::*;
pub fn gr_schwarzschild_accel(pos_gcrf: &Vector3, vel_gcrf: &Vector3, mu_e: f64) -> Vector3 {
let r2 = pos_gcrf.norm_squared();
let r = r2.sqrt();
let v2 = vel_gcrf.norm_squared();
let rdotv = pos_gcrf.dot(vel_gcrf);
let c2 = consts::C * consts::C;
let factor = mu_e / (c2 * r2 * r);
let radial_coeff = 4.0 * mu_e / r - v2;
factor * (radial_coeff * pos_gcrf + 4.0 * rdotv * vel_gcrf)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn schwarzschild_at_geo_has_expected_magnitude() {
let r = consts::GEO_R;
let v = (consts::MU_EARTH / r).sqrt();
let pos = numeris::vector![r, 0.0, 0.0];
let vel = numeris::vector![0.0, v, 0.0];
let a = gr_schwarzschild_accel(&pos, &vel, consts::MU_EARTH);
let mag = a.norm();
assert!(
(1e-11..1e-8).contains(&mag),
"GR accel at GEO = {:e} m/s², expected ~few×1e-10",
mag
);
}
#[test]
fn schwarzschild_at_leo_has_expected_magnitude() {
let r = consts::EARTH_RADIUS + 500.0e3;
let v = (consts::MU_EARTH / r).sqrt();
let pos = numeris::vector![r, 0.0, 0.0];
let vel = numeris::vector![0.0, v, 0.0];
let a = gr_schwarzschild_accel(&pos, &vel, consts::MU_EARTH);
let mag = a.norm();
assert!(
(1e-10..1e-7).contains(&mag),
"GR accel at 500 km LEO = {:e} m/s², expected ~1e-9",
mag
);
}
#[test]
fn schwarzschild_points_inward_on_circular_orbit() {
let r = consts::EARTH_RADIUS + 1000.0e3;
let v = (consts::MU_EARTH / r).sqrt();
let pos = numeris::vector![r, 0.0, 0.0];
let vel = numeris::vector![0.0, v, 0.0];
let a = gr_schwarzschild_accel(&pos, &vel, consts::MU_EARTH);
assert!(a[1].abs() < 1e-20);
assert!(a[2].abs() < 1e-20);
assert!(a[0] > 0.0);
}
}