use core::f64::consts::PI;
use metrology::{EPS_0, HBAR};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Flux {
Standard,
LiBaker,
}
pub fn wave_flux(h: f64, f: f64, convention: Flux) -> f64 {
let standard = gravitational::laboratory::wave_flux(h, f);
match convention {
Flux::Standard => standard,
Flux::LiBaker => 4.0 * standard,
}
}
pub fn strain_from_flux(flux: f64, f: f64, convention: Flux) -> f64 {
(flux / wave_flux(1.0, f, convention)).sqrt()
}
pub fn graviton_rate(flux: f64, area: f64, f: f64) -> f64 {
flux * area / (HBAR * 2.0 * PI * f)
}
pub fn interference_rate(n0: f64, n_gw: f64) -> f64 {
2.0 * (n0 * n_gw).sqrt()
}
pub fn shot_noise_time(n_gw: f64, snr: f64) -> f64 {
snr * snr / (4.0 * n_gw)
}
pub const VACUUM_BREAKDOWN: f64 = 1e9;
pub fn pais_flux(f_g: f64, sigma: f64, v: f64) -> f64 {
f_g * sigma * sigma / EPS_0 * v
}
pub fn surface_field(sigma: f64) -> f64 {
sigma / EPS_0
}
pub fn pais_conversion(b: f64, l: f64, power: f64) -> (f64, f64) {
let si = gravitational::hf::gertsenshtein_probability(b, l) * power;
(si * metrology::MU_0, si)
}
#[cfg(test)]
mod tests {
use super::*;
fn close(a: f64, b: f64, rel: f64) -> bool {
(a / b - 1.0).abs() < rel
}
#[test]
fn baker_strain_is_half_the_standard_one() {
assert!(close(strain_from_flux(3.53, 4.915e9, Flux::LiBaker), 4.80e-28, 2e-3));
assert!(close(strain_from_flux(3.53, 4.915e9, Flux::Standard), 9.60e-28, 2e-3));
}
#[test]
fn li_detector_numbers_reproduce() {
let flux = wave_flux(1e-30, 5e9, Flux::LiBaker);
assert!(close(graviton_rate(flux, PI * 0.05 * 0.05, 5e9), 3.77e16, 5e-3));
assert!(close(interference_rate(1.24e22, 2.56e-18), 3.54e2, 1e-2));
let standard = gravitational::hf::coherent_photon_rate(1.0, 0.01, 3.0, 6.0, 5e9, 1e-30);
assert!(close(standard, 3.20e-19, 2e-3));
assert!(close(2.56e-18 / standard, 8.0, 0.01));
assert!(close(shot_noise_time(2.56e-18, 2.0), 3.9e17, 1e-2));
assert!(close(shot_noise_time(standard, 2.0), 3.12e18, 1e-2));
}
#[test]
fn pais_numbers_need_impossible_fields() {
assert!(close(pais_flux(1.0, 5e4, 2.0 * 3142.0), 1.77e24, 5e-3));
assert!(close(surface_field(5e4) / VACUUM_BREAKDOWN, 5.65e6, 5e-3));
assert!(close(pais_flux(1.0, VACUUM_BREAKDOWN * EPS_0, 2.0 * 3142.0), 5.56e10, 5e-3));
let (as_used, si) = pais_conversion(1e10, 1.0, 1e33);
assert!(close(as_used, 1.04e10, 1e-2));
assert!(close(si, 8.3e15, 1e-2));
}
}