Skip to main content

Crate pantometry_units

Crate pantometry_units 

Source
Expand description

Dimensional analysis: physical quantities that refuse to be added wrongly.

use pantometry_units::{Area, Energy, Length, Mass, Power, SpecificHeat, Temperature, Time};

// A unit-bearing constructor is the only place a factor of a thousand may appear.
let side = Length::mm(10.0);
let area: Area = side * side;                       // the dimension follows the product
assert!((area.to_si() - 1e-4).abs() < 1e-18);

// Absorbed power over a time is an energy, and the type says so without being told.
let absorbed = Power::mw(96.0);
let heat: Energy = absorbed * Time::s(1.0);

// Divide it by a heat capacity and a temperature comes out.
let capacity = Mass::g(2.0) * SpecificHeat::j_per_kg_k(858.0);
let rise: Temperature = heat / capacity;
assert!((rise.to_si() - 0.05594).abs() < 1e-4);

And the mistake the whole crate exists to prevent does not compile:

use pantometry_units::{Length, Time};
let nonsense = Length::mm(3.0) + Time::s(1.0);

One domain can get away with a convention. pantometry-core began as optics and said “millimetres, nanometres and seconds, everywhere” in a doc comment, and that held because every number in the crate was a length, a wavelength or a fraction. It stops holding the moment a second domain arrives: a kelvin, a newton and a watt are all f64, they all add, and the compiler and the tests both stay green while the physics goes wrong.

So dimension lives in the type. Qty carries the seven SI base exponents as const generic parameters, which makes Length + Time a compile error and Force * Length an Energy — and costs nothing at runtime, since a Qty is an f64 and every operation on it is the f64 operation.

§Storage is always SI base units

A Qty holds metres, kilograms, seconds, amperes, kelvin, moles, candela — never millimetres, never nanometres. Those are entry and exit forms:

use pantometry_units::{Length, Time, Velocity};

let d = Length::mm(120.0);
let t = Time::ms(4.0);
let v: Velocity = d / t;
assert!((v.to_si() - 30.0).abs() < 1e-12);   // 30 m/s
assert!((d.in_nm() - 1.2e8).abs() < 1.0);

That way there is exactly one representation to reason about, and the unit-bearing constructors are the only place a factor of 1000 can hide.

§What this cannot do

Angles are dimensionless, so Frequency and an angular velocity are the same type — SI says radians are m/m, and no dimensional system can separate them. Same for torque and energy. Where that distinction matters, it has to be carried by a newtype in the domain crate, not here.

Only declared products compose. Length * Length is an Area because that pair is written down below. Deriving arbitrary products would need arithmetic on const generic parameters, which is unstable, so the alternative to a declared list is a dependency on uom. The list is cheap to extend, and anything undeclared can always go through Qty::from_si.

Re-exports§

pub use vector::AccelerationVec;
pub use vector::ForceVec;
pub use vector::LengthVec;
pub use vector::MomentumVec;
pub use vector::QVec3;
pub use vector::VelocityVec;

Modules§

vector
Vector quantities: three components sharing one dimension.

Structs§

Qty
A quantity, with the seven SI base dimensions in its type.

Constants§

BOLTZMANN
Boltzmann constant, J·K⁻¹ (exact by definition).
C
Speed of light in vacuum, m·s⁻¹ (exact by definition).
G0
Standard gravity, m·s⁻².
PLANCK
Planck constant, J·s (exact by definition).
STEFAN_BOLTZMANN
Stefan-Boltzmann constant, W·m⁻²·K⁻⁴ — radiative exchange lives on this.

Functions§

photon_energy
Energy of one photon at a vacuum wavelength: E = hc/λ.

Type Aliases§

Acceleration
Metres per second squared.
Amount
Moles.
AngularMomentum
kg·m²·s⁻¹ — the rotational counterpart of momentum, and conserved for the same reason.
Area
Square metres.
Charge
Coulombs.
Concentration
kg·m⁻³ as a concentration of one species dissolved in another.
Conductance
W·K⁻¹ — how fast heat crosses a joint, UA.
Conductivity
S/m — the reciprocal of Resistivity, and what a finite-volume solve actually wants, because conductances in parallel add where resistances do not.
Current
Amperes.
CurrentDensity
A/m² — current per unit area. What actually flows, and the thing I is an integral of.
Damping
N·s·m⁻¹ — a dashpot’s c. Force proportional to velocity, and the only place a mechanical simulation loses energy on purpose.
Density
kg·m⁻³. Note that a glass catalogue quotes g/cm³, a factor of a thousand away — see Density::g_per_cm3.
Diffusivity
m²·s⁻¹ — thermal diffusivity α = k/(ρ c_p), and also mass diffusivity.
Dimensionless
A pure ratio: reflectance, duty cycle, refractive index, Strehl.
DynamicViscosity
Pa·s — dynamic viscosity, the μ of Darcy’s law and of Stokes drag.
ElectricField
V/m — the gradient of a potential.
Energy
Joules.
Force
Newtons.
Frequency
Cycles per second. Dimensionally identical to an angular velocity, since a radian is m/m — the type system cannot and should not pretend otherwise.
HeatCapacity
J·K⁻¹ — mass times specific heat. How much heat a thing can hide before it shows up as a temperature.
Irradiance
Power per unit area, W·m⁻². What a detector face actually receives.
LatentHeat
J·kg⁻¹ — the heat a phase change costs at no change in temperature.
Length
Metres.
LuminousIntensity
Candelas.
Mass
Kilograms.
MassFlow
kg·s⁻¹ — a mass flow rate. What a brew scale reads the derivative of.
MomentOfInertia
kg·m² — how hard a body is to spin up about an axis.
Momentum
kg·m·s⁻¹ — mass times velocity, and the thing a closed system conserves exactly rather than nearly.
Power
Watts.
Pressure
Pascals. Also the unit of an energy density and of a stress, which are the same dimension and not a coincidence.
Resistance
Ohms — volts per ampere.
Resistivity
Ω·m — resistance times length. The property of a material, where Resistance is the property of a particular piece of one.
SpecificHeat
J·kg⁻¹·K⁻¹ — the c_p that says how much heat a gram of glass can hide.
Stiffness
N·m⁻¹ — a spring’s k, and the penalty stiffness a contact is modelled with.
Temperature
Absolute temperature. Kelvin only — see Temperature::celsius.
ThermalConductivity
W·m⁻¹·K⁻¹ — the k of Fourier’s law.
ThermalExpansion
K⁻¹ — the coefficient that turns absorbed light into a focus shift.
Time
Seconds.
Velocity
Metres per second.
Voltage
Volts.
Volume
Cubic metres.