use metrology::{C, G};
pub fn memory_0pn(m1: f64, m2: f64, d: f64, x: f64, theta: f64) -> f64 {
let m = G * (m1 + m2) / (C * C);
let eta = m1 * m2 / (m1 + m2).powi(2);
let (s, c) = theta.sin_cos();
2.0 * eta * m * x / d * s * s * (17.0 + c * c) / 96.0
}
pub fn pta_memory_residual(t: f64, t0: f64, h0: f64, psi: f64, alpha: f64, l: f64) -> f64 {
let b = 0.5 * (2.0 * psi).cos() * (1.0 - alpha.cos());
let ramp = |since: f64| since.max(0.0);
let ti = t0 + l / C * (1.0 + alpha.cos());
b * h0 * (ramp(t - t0) - ramp(t - ti))
}
#[cfg(test)]
mod tests {
use super::*;
use core::f64::consts::FRAC_PI_2;
use metrology::{MPC, PARSEC, SOLAR_MASS, YEAR};
#[test]
fn binary_memory() {
let h = memory_0pn(1e9 * SOLAR_MASS, 1e9 * SOLAR_MASS, 1e3 * MPC, 1.0 / 6.0, FRAC_PI_2);
assert!((h / 1.41236e-15 - 1.0).abs() < 1e-5);
assert_eq!(memory_0pn(36.0 * SOLAR_MASS, 29.0 * SOLAR_MASS, 410.0 * MPC, 1.0 / 6.0, 0.0), 0.0);
}
#[test]
fn pulsar_ramp() {
let r = pta_memory_residual(5.0 * YEAR, 0.0, 1e-14, 0.0, FRAC_PI_2, 1e3 * PARSEC);
assert!((r / 0.78894e-6 - 1.0).abs() < 1e-5);
assert_eq!(pta_memory_residual(-1.0, 0.0, 1e-14, 0.0, FRAC_PI_2, 1e3 * PARSEC), 0.0);
let l = 1e3 * PARSEC;
let after = |dt: f64| pta_memory_residual(l / C + dt, 0.0, 1e-14, 0.0, FRAC_PI_2, l);
assert!((after(10.0 * YEAR) - after(20.0 * YEAR)).abs() < 1e-18);
}
}