use core::f64::consts::PI;
use metrology::{C, E_CHARGE, G, G0};
pub fn ion_wind_thrust(current: f64, gap: f64, mobility: f64) -> f64 {
current * gap / mobility
}
pub fn ion_mobility(mass: f64, collision_rate: f64) -> f64 {
E_CHARGE / (2.0 * mass * collision_rate)
}
pub fn ballistic_thrust(current: f64, voltage: f64, mass: f64, charge: f64) -> f64 {
current * (2.0 * mass * voltage / charge).sqrt()
}
pub fn photon_thrust(power: f64) -> f64 {
power / C
}
pub fn shawyer_thrust(power: f64, q: f64, design: f64) -> f64 {
2.0 * power * q * design / C
}
pub fn buoyancy_force(air_density: f64, volume: f64, warming: f64, temperature: f64) -> f64 {
air_density * volume * G0 * warming / temperature
}
pub fn mach_effect_thrust(omega: f64, m0: f64, kp: f64, ke: f64, x0: f64, v0: f64, rho0: f64) -> f64 {
4.0 * PI * omega.powi(6) * m0 * kp * kp * ke * x0.powi(3) * v0.powi(4) / (8.0 * PI * G * rho0 * C * C)
}
pub fn mach_effect_gr_bound(m: f64, l: f64, f: f64) -> f64 {
G * m / (l * C * C) * (2.0 * PI * f * l / C).powi(2)
}
#[cfg(test)]
mod tests {
use super::*;
use metrology::AMU;
fn close(a: f64, b: f64, rel: f64) -> bool {
(a / b - 1.0).abs() < rel
}
#[test]
fn lifters_are_ion_wind() {
assert!(close(ion_wind_thrust(1e-3, 0.04, 2.5e-4), 0.16, 1e-9));
let n2 = 28.0134 * AMU;
assert!(close(ion_mobility(n2, 1e10), 1.72e-4, 5e-3));
assert!(ion_wind_thrust(1e-3, 0.04, 2.5e-4) / ballistic_thrust(1e-3, 3e4, n2, E_CHARGE) > 1e3);
}
#[test]
fn emdrive_and_its_artefacts() {
assert!(close(photon_thrust(1e3), 3.336e-6, 1e-3));
assert!(close(shawyer_thrust(11.0, 741.0, 0.56), 3.04e-5, 5e-3));
assert!(close(shawyer_thrust(60.0, 7123.0, 0.56), 1.60e-3, 5e-3));
assert!(close(buoyancy_force(1.2, 0.15f64.powi(3), 1.0, 293.0), 1.36e-4, 5e-3));
}
#[test]
fn woodward_predicts_a_tenth_of_a_micronewton() {
let omega = 2.0 * PI * 32_350.0;
let printed = mach_effect_thrust(omega, 0.046, 1.0, 1.0, 0.019, 100.0, 7.9e3) / (4.0 * PI);
assert!(close(printed, 1.87e21, 5e-3));
let si = mach_effect_thrust(omega, 0.046, 3.2e-10, 4e-11, 0.019, 100.0, 7.9e3);
assert!(close(si / (4.0 * PI), 7.66e-9, 5e-3) && close(si, 9.62e-8, 5e-3));
}
#[test]
fn machian_term_in_general_relativity() {
assert!(close(mach_effect_gr_bound(0.1, 0.01, 5e4), 8.15498e-37, 1e-5));
}
}