use core::f64::consts::PI;
use metrology::{E_CHARGE as E, G, HBAR, K_B, M_E, M_H, M_P, MU_0 as MU0};
pub fn bennett_temperature(current: f64, line_density: f64, z: f64) -> f64 {
MU0 * current * current / (8.0 * PI * line_density * (1.0 + z) * E)
}
pub fn bennett_line_density(current: f64, t_sum: f64) -> f64 {
MU0 * current * current / (8.0 * PI * t_sum * E)
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Resistivity {
Perpendicular,
Parallel,
}
pub fn pease_braginskii(ln_lambda: f64, z: f64, resistivity: Resistivity) -> f64 {
let c = match resistivity {
Resistivity::Perpendicular => 9.71e3,
Resistivity::Parallel => 1.96 * 9.71e3,
};
let sigma0 = c / E.powf(1.5); let a = 1.69e-38 / E.sqrt(); PI / MU0 * (48.0 * ln_lambda / (sigma0 * a)).sqrt() * (1.0 + z) / z
}
pub fn lee_peak_current(v0: f64, l0: f64, c0: f64) -> f64 {
let z0 = (l0 / c0).sqrt();
v0 / (z0 + 7e-3 + 0.1 * z0)
}
pub fn lee_yield(peak_ma: f64) -> f64 {
1.8e10 * peak_ma.powf(3.8)
}
pub fn snowplow_speed(current: f64, a: f64, b: f64, rho: f64, fm: f64, fc: f64) -> f64 {
let c = b / a;
fc / fm.sqrt() * (MU0 * c.ln() / (4.0 * PI * PI * (c * c - 1.0) * rho)).sqrt() * current / a
}
pub fn cyclotron_energy(b: f64) -> f64 {
HBAR * E * b / M_E / E
}
pub fn ostriker_line_mass(t: f64, mu: f64) -> f64 {
2.0 * K_B * t / (mu * M_H) / G
}
pub fn equal_attraction_drift() -> f64 {
M_P * (4.0 * PI * G / MU0).sqrt() / E
}
pub fn magnetic_over_gravitational(current: f64, line_mass: f64) -> f64 {
MU0 * current * current / (4.0 * PI) / (G * line_mass * line_mass)
}
#[cfg(test)]
mod tests {
use super::*;
fn close(a: f64, b: f64, rel: f64) -> bool {
(a / b - 1.0).abs() < rel
}
#[test]
fn bennett_and_pease_braginskii() {
assert!(close(2.0 * bennett_temperature(1e6, 1e20, 1.0) / 1e3, 3.12, 0.005));
let n = 1e23 * PI * 3e-3 * 3e-3;
assert!(close(bennett_temperature(200e3, n, 1.0), 2200.0, 0.02));
assert!(close(bennett_line_density(1e6, 2000.0) * 2000.0 * E, MU0 * 1e12 / (8.0 * PI), 1e-12));
assert!(close(pease_braginskii(10.0, 1.0, Resistivity::Perpendicular), 1.37e6, 0.01));
assert!(close(pease_braginskii(10.0, 1.0, Resistivity::Parallel), 0.98e6, 0.01));
}
#[test]
fn lee_model() {
for (c0, published) in [(1e-6, 152e3), (10e-6, 447e3), (100e-6, 1156e3), (1e-3, 2321e3), (10e-3, 3407e3)] {
assert!(close(lee_peak_current(30e3, 30e-9, c0), published, 0.015), "{c0}");
}
assert!(close(lee_yield(1.1), 2.6e10, 0.01));
let v = snowplow_speed(1e6, 0.028, 0.05, 1.6e24 * 3.343_583_772e-27, 0.1, 0.7);
assert!((5e4..3e5).contains(&v), "{v}");
}
#[test]
fn the_pinch_and_its_gravitational_twin() {
assert!(close(cyclotron_energy(1e5), 11.58, 0.005));
assert!(close(ostriker_line_mass(10.0, 2.3) * 3.0857e16 / 1.989e30, 16.6, 0.01));
assert!(close(equal_attraction_drift(), 2.70e-10, 0.005));
let line_mass = bennett_line_density(1e6, 2000.0) * 3.343_583_772e-27;
assert!(close(magnetic_over_gravitational(1e6, line_mass), 5.5e27, 0.02));
}
}