cosmocalc/
units.rs

1use anyhow::anyhow;
2
3pub mod dimensionless;
4pub mod energy;
5pub mod length;
6pub(crate) mod macros;
7pub mod mass;
8pub mod temperature;
9pub mod time;
10pub mod traits;
11
12pub use dimensionless::DimensionlessFloat;
13pub use traits::FloatingPointUnit;
14
15// Continuous positive quantities that are dimensionless (e.g. ratios like the omegas)
16pub type DimensionlessPositiveFloat = PositiveFloat;
17
18// Hubble parameter units
19pub type KmPerSecPerMpc = f64;
20pub type HInvKmPerSecPerMpc = f64;
21
22// Densities
23pub type KilogramsPerMeter3 = PositiveFloat;
24
25// Constant units
26// TODO: Work out a better way to handle types for composite unit information
27pub type MetersPerSecond = f64;
28pub type Meters3PerKgPerSecond2 = f64;
29pub type Meters2KgPerSecond2Kelvin = f64;
30pub type JouleSeconds = f64;
31pub type JoulePerMeter3Kelvin4 = f64;
32pub type WattsPerMeters2Kelvin4 = f64;
33pub type JoulePerKelvin = f64;
34pub type Mpc3 = f64;
35pub type HInvMpc = f64;
36
37/// Represents continuous physical quantities that _cannot_ be negative.
38#[derive(Clone, Copy, Debug, PartialOrd, PartialEq)]
39pub struct PositiveFloat(pub f64);
40
41impl PositiveFloat {
42    pub fn new(x: f64) -> Result<Self, anyhow::Error> {
43        if x < 0. {
44            return Err(anyhow!("expected positive number"));
45        }
46        Ok(Self(x))
47    }
48
49    pub fn zero() -> Self {
50        Self(0.)
51    }
52
53    pub fn one() -> Self {
54        Self(1.)
55    }
56
57    // Passthrough methods for convenience
58    pub fn floor(&self) -> f64 {
59        self.0.floor()
60    }
61
62    pub fn powf(&self, exp: f64) -> f64 {
63        self.0.powf(exp)
64    }
65}
66
67impl std::ops::Sub for PositiveFloat {
68    type Output = PositiveFloat;
69
70    fn sub(self, rhs: Self) -> Self::Output {
71        PositiveFloat(self.0 - rhs.0)
72    }
73}
74
75impl std::ops::Add for PositiveFloat {
76    type Output = PositiveFloat;
77
78    fn add(self, rhs: Self) -> Self::Output {
79        PositiveFloat(self.0 + rhs.0)
80    }
81}