use qtty_core::units::area::SquareMeter;
use qtty_core::units::dimensionless::Ratio;
use qtty_core::units::length::Kilometer;
use qtty_core::units::mass::Kilogram;
use qtty_core::units::time::Second;
use qtty_core::units::volume::CubicKilometer;
use qtty_core::{Per, Prod, Quantity};
pub type KmPerSecond = Per<Kilometer, Second>;
pub type KmPerSeconds = Quantity<KmPerSecond>;
pub type KmPerSecondSquared = Per<Per<Kilometer, Second>, Second>;
pub type KmPerSecondsSquared = Quantity<KmPerSecondSquared>;
pub type InverseSecond = Per<Ratio, Second>;
pub type InverseSeconds = Quantity<InverseSecond>;
pub type AreaToMassUnit = Per<SquareMeter, Kilogram>;
pub type AreaToMass = Quantity<AreaToMassUnit>;
pub type GravitationalParameterUnit = Per<CubicKilometer, Prod<Second, Second>>;
pub type GravitationalParameter = Quantity<GravitationalParameterUnit>;
pub const GM_EARTH: GravitationalParameter = GravitationalParameter::new(398_600.441_8);
pub const GM_SUN: GravitationalParameter = GravitationalParameter::new(1.327_124_400_18e11);
pub const GM_MOON: GravitationalParameter = GravitationalParameter::new(4.902_800_066e3);
pub const SPEED_OF_LIGHT_KM_S: KmPerSeconds = KmPerSeconds::new(299_792.458);
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DragCoefficient(f64);
impl DragCoefficient {
#[inline]
pub fn new(value: f64) -> Self {
Self(value)
}
#[inline]
pub fn value(self) -> f64 {
self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SrpCoefficient(f64);
impl SrpCoefficient {
#[inline]
pub fn new(value: f64) -> Self {
Self(value)
}
#[inline]
pub fn value(self) -> f64 {
self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct J2Coefficient(f64);
impl J2Coefficient {
#[inline]
pub fn new(value: f64) -> Self {
Self(value)
}
#[inline]
pub fn value(self) -> f64 {
self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct StokesCoefficient(f64);
impl StokesCoefficient {
#[inline]
pub fn new(value: f64) -> Self {
Self(value)
}
#[inline]
pub fn value(self) -> f64 {
self.0
}
}
#[cfg(all(test, feature = "std"))]
mod tests {
use super::*;
use qtty_core::units::length::Kilometers;
use qtty_core::units::time::Seconds;
#[test]
fn gm_earth_value() {
assert!((GM_EARTH.value() - 398_600.441_8).abs() < 1e-3);
}
#[test]
fn gm_sun_order_of_magnitude() {
assert!(GM_SUN.value() > 1e11 && GM_SUN.value() < 1.4e11);
}
#[test]
fn gm_moon_order_of_magnitude() {
assert!(GM_MOON.value() > 4_000.0 && GM_MOON.value() < 6_000.0);
}
#[test]
fn drag_coefficient_roundtrip() {
let cd = DragCoefficient::new(2.2);
assert!((cd.value() - 2.2).abs() < 1e-15);
}
#[test]
fn srp_coefficient_roundtrip() {
let cr = SrpCoefficient::new(1.5);
assert!((cr.value() - 1.5).abs() < 1e-15);
}
#[test]
fn j2_coefficient_roundtrip() {
let j2 = J2Coefficient::new(1.082_635_9e-3);
assert!((j2.value() - 1.082_635_9e-3).abs() < 1e-20);
}
#[test]
fn stokes_coefficient_roundtrip() {
let c = StokesCoefficient::new(-0.484_165_4e-3);
assert!((c.value() - (-0.484_165_4e-3)).abs() < 1e-20);
}
#[test]
fn km_per_second_squared_dimensional() {
let a: Quantity<KmPerSecondSquared> = Quantity::new(2.0);
let t = Seconds::new(3.0);
let v: KmPerSeconds = a * t;
assert!((v.value() - 6.0).abs() < 1e-12);
let d: Kilometers = v * Seconds::new(1.0);
assert!((d.value() - 6.0).abs() < 1e-12);
}
}