lindhard/constants.rs
1//! Physical constants, SI units.
2//!
3//! Source for every value: CODATA 2022 recommended values, P. J. Mohr,
4//! D. B. Newell, B. N. Taylor, E. Tiesinga, "CODATA recommended values of the
5//! fundamental physical constants: 2022", Rev. Mod. Phys. 97, 025002 (2025),
6//! doi:10.1103/RevModPhys.97.025002. Values marked "exact" are fixed by the
7//! 2019 SI redefinition; the rest carry their standard uncertainty in the doc
8//! comment.
9//!
10//! Verified digit by digit on 2026-10-06 (#15) against NIST's listing of the
11//! 2022 CODATA adjustment, <https://physics.nist.gov/cuu/Constants/Table/allascii.txt>
12//! (rows "elementary charge", "Planck constant", "speed of light in vacuum",
13//! "Boltzmann constant", "Avogadro constant", "vacuum electric permittivity",
14//! "fine-structure constant", "electron mass", "proton mass", "atomic mass
15//! constant", "Bohr radius", "Hartree energy", "electron mass energy
16//! equivalent"). Every stored value equals the listed one. [`HBAR`] and
17//! [`COULOMB_E2`] are not stored values but expressions of the stored ones;
18//! the tests check them, and four stored values, against other rows of the
19//! same listing.
20
21/// Elementary charge `e`, C. CODATA 2022: 1.602 176 634e-19 (exact).
22pub const ELEMENTARY_CHARGE: f64 = 1.602_176_634e-19;
23
24/// Planck constant `h`, J s. CODATA 2022: 6.626 070 15e-34 (exact).
25pub const PLANCK: f64 = 6.626_070_15e-34;
26
27/// Reduced Planck constant `h / 2π`, J s. Derived from the exact [`PLANCK`];
28/// CODATA 2022 lists 1.054 571 817...e-34 (exact).
29pub const HBAR: f64 = PLANCK / std::f64::consts::TAU;
30
31/// Speed of light in vacuum `c`, m/s. CODATA 2022: 299 792 458 (exact).
32pub const SPEED_OF_LIGHT: f64 = 299_792_458.0;
33
34/// Boltzmann constant `k_B`, J/K. CODATA 2022: 1.380 649e-23 (exact).
35pub const BOLTZMANN: f64 = 1.380_649e-23;
36
37/// Avogadro constant `N_A`, 1/mol. CODATA 2022: 6.022 140 76e23 (exact).
38pub const AVOGADRO: f64 = 6.022_140_76e23;
39
40/// Vacuum electric permittivity `ε₀`, F/m. CODATA 2022: 8.854 187 8188(14)e-12.
41pub const VACUUM_PERMITTIVITY: f64 = 8.854_187_818_8e-12;
42
43/// Fine-structure constant `α`, dimensionless. CODATA 2022: 7.297 352 5643(11)e-3.
44pub const FINE_STRUCTURE: f64 = 7.297_352_564_3e-3;
45
46/// Electron mass `m_e`, kg. CODATA 2022: 9.109 383 7139(28)e-31.
47pub const ELECTRON_MASS: f64 = 9.109_383_713_9e-31;
48
49/// Proton mass `m_p`, kg. CODATA 2022: 1.672 621 925 95(52)e-27.
50pub const PROTON_MASS: f64 = 1.672_621_925_95e-27;
51
52/// Atomic mass constant `m_u` (unified atomic mass unit), kg.
53/// CODATA 2022: 1.660 539 068 92(52)e-27.
54pub const ATOMIC_MASS_UNIT: f64 = 1.660_539_068_92e-27;
55
56/// Bohr radius `a₀`, m. CODATA 2022: 5.291 772 105 44(82)e-11.
57pub const BOHR_RADIUS: f64 = 5.291_772_105_44e-11;
58
59/// Hartree energy `E_h`, J. CODATA 2022: 4.359 744 722 2060(48)e-18.
60pub const HARTREE_ENERGY: f64 = 4.359_744_722_206e-18;
61
62/// Electron rest energy `m_e c²`, J. CODATA 2022: 8.187 105 7880(26)e-14
63/// (equivalently 0.510 998 950 69(16) MeV).
64pub const ELECTRON_REST_ENERGY: f64 = 8.187_105_788_0e-14;
65
66/// Coulomb constant `e² / (4π ε₀)`, J m. Derived from [`ELEMENTARY_CHARGE`]
67/// (C) and [`VACUUM_PERMITTIVITY`] (F/m = C²/(J m)), so the unit is J m
68/// (about 2.307e-28 J m, i.e. 14.3996 eV Å). CODATA lists no row for this
69/// combination; its relative uncertainty is that of ε₀, 1.6e-10. This is the
70/// combination the screened-Coulomb interatomic potentials in the ion engine
71/// are written with.
72pub const COULOMB_E2: f64 =
73 ELEMENTARY_CHARGE * ELEMENTARY_CHARGE / (4.0 * std::f64::consts::PI * VACUUM_PERMITTIVITY);
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn coulomb_constant_in_ev_angstrom() {
81 // e^2/(4 pi eps0) = 14.3996 eV Angstrom (derived value, 4-digit check).
82 let v = COULOMB_E2 / ELEMENTARY_CHARGE / 1.0e-10;
83 assert!((v - 14.3996).abs() < 1e-3, "{v}");
84 }
85
86 #[test]
87 fn hartree_is_alpha_squared_electron_rest_energy() {
88 // E_h = alpha^2 m_e c^2 (identity, holds to CODATA rounding).
89 let rel =
90 (HARTREE_ENERGY / (FINE_STRUCTURE * FINE_STRUCTURE * ELECTRON_REST_ENERGY) - 1.0).abs();
91 assert!(rel < 1e-9, "{rel}");
92 }
93
94 /// Rows of the NIST listing of the 2022 CODATA adjustment
95 /// (<https://physics.nist.gov/cuu/Constants/Table/allascii.txt>, read
96 /// 2026-10-06) that are not stored here, recomputed from the stored values.
97 /// Where both sides are printed to 11 or more significant digits the
98 /// tolerance only covers the rounding of those digits (a few 1e-12), so a
99 /// wrong digit in a stored input fails; the identities (`a0`, `alpha`,
100 /// `m_e c^2`) hold to the CODATA rounding of their inputs, 1e-9.
101 #[test]
102 fn derived_values_match_codata_2022_listing() {
103 let rel = |a: f64, b: f64| (a / b - 1.0).abs();
104 // "reduced Planck constant": 1.054 571 817... e-34 J s (exact, truncated).
105 assert!(rel(HBAR, 1.054_571_817e-34) < 1e-9);
106 // "reduced Planck constant in eV s": 6.582 119 569... e-16 (exact, truncated).
107 assert!(rel(HBAR / ELEMENTARY_CHARGE, 6.582_119_569e-16) < 1e-9);
108 // "electron mass energy equivalent in MeV": 0.510 998 950 69(16).
109 let mec2_mev = ELECTRON_REST_ENERGY / ELEMENTARY_CHARGE / 1.0e6;
110 assert!(rel(mec2_mev, 0.510_998_950_69) < 3e-11, "{mec2_mev}");
111 // "electron mass energy equivalent" = m_e c^2: 8.187 105 7880(26) e-14 J.
112 let mec2 = ELECTRON_MASS * SPEED_OF_LIGHT * SPEED_OF_LIGHT;
113 assert!(rel(mec2, ELECTRON_REST_ENERGY) < 1e-9, "{mec2}");
114 // "Hartree energy in eV": 27.211 386 245 981(30).
115 let eh_ev = HARTREE_ENERGY / ELEMENTARY_CHARGE;
116 assert!(rel(eh_ev, 27.211_386_245_981) < 1e-12, "{eh_ev}");
117 // "molar mass constant" M_u = N_A m_u: 1.000 000 001 05(31) e-3 kg/mol.
118 let mu = AVOGADRO * ATOMIC_MASS_UNIT;
119 assert!(rel(mu, 1.000_000_001_05e-3) < 2e-11, "{mu}");
120 // Bohr radius a0 = hbar / (alpha m_e c), to CODATA rounding.
121 let a0 = HBAR / (FINE_STRUCTURE * ELECTRON_MASS * SPEED_OF_LIGHT);
122 assert!(rel(a0, BOHR_RADIUS) < 1e-9, "{a0}");
123 // alpha = e^2 / (4 pi eps0 hbar c), i.e. COULOMB_E2 = alpha hbar c.
124 assert!(rel(COULOMB_E2, FINE_STRUCTURE * HBAR * SPEED_OF_LIGHT) < 1e-9);
125 }
126}