pub const K_EFF_RB87: f64 = 4.0 * core::f64::consts::PI / 780.241e-9;
pub fn phase_sensitivity(k_eff: f64, t: f64) -> f64 {
k_eff * t * t
}
pub fn aharonov_bohm_rate(m: f64, source: f64, r: f64) -> f64 {
m * metrology::G * source / (metrology::HBAR * r)
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct AtomInterferometer {
pub t: f64,
pub contrast: f64,
pub atoms: f64,
pub cycle: f64,
}
impl AtomInterferometer {
pub fn phase(&self, a: f64) -> f64 {
2.0 * K_EFF_RB87 * a * self.t * self.t
}
pub fn phase_noise(&self) -> f64 {
1.0 / (self.contrast * self.atoms.sqrt())
}
pub fn acceleration_noise(&self) -> f64 {
self.phase_noise() / (2.0 * K_EFF_RB87 * self.t * self.t)
}
pub fn acceleration_asd(&self) -> f64 {
self.acceleration_noise() * self.cycle.sqrt()
}
pub fn gradient_noise(&self, baseline: f64) -> f64 {
std::f64::consts::SQRT_2 * self.phase_noise() / (2.0 * K_EFF_RB87 * baseline * self.t * self.t)
}
pub fn gradient_asd(&self, baseline: f64) -> f64 {
self.gradient_noise(baseline) * self.cycle.sqrt()
}
}
#[cfg(test)]
mod tests {
use super::*;
fn close(a: f64, b: f64, rel: f64) -> bool {
(a - b).abs() <= rel * b.abs()
}
#[test]
fn published_instruments() {
let carioqa = AtomInterferometer { t: 1.0, contrast: 0.8, atoms: 1e5, cycle: 3.5 };
assert!(close(carioqa.phase_noise(), 3.95e-3, 0.01));
assert!(close(carioqa.acceleration_asd(), 2.3e-10, 0.01));
assert!(close(AtomInterferometer { atoms: 1e6, ..carioqa }.acceleration_asd(), 7.3e-11, 0.01));
let grice = AtomInterferometer { t: 0.5, contrast: 0.43, atoms: 5e5, cycle: 2.0 };
assert!(close(grice.acceleration_asd(), 5.8e-10, 0.01));
let tri = AtomInterferometer { t: 5.0, contrast: 1.0, atoms: 1e6, cycle: 1.0 };
assert!(close(tri.gradient_noise(0.5), 3.5e-12, 0.01));
assert!(close(tri.phase(2.7e-6 * 0.5), 1087.0, 0.001));
}
#[test]
fn phase_and_potential() {
let s = phase_sensitivity(K_EFF_RB87, 0.160);
assert!((s / 4.123_07e5 - 1.0).abs() < 1e-5 && (s * metrology::G0 / 4.043e6 - 1.0).abs() < 1e-3);
let rb = 86.909 * metrology::AMU;
assert!((aharonov_bohm_rate(rb, 1.25, 0.07) / 1.631 - 1.0).abs() < 1e-3);
assert!((aharonov_bohm_rate(rb, 1.25, 0.14) / aharonov_bohm_rate(rb, 1.25, 0.07) - 0.5).abs() < 1e-12);
}
}