Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-19 07:33:43

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include <numbers>
0012 
0013 namespace Acts {
0014 
0015 /// @namespace Acts::UnitConstants
0016 /// @brief Constants and helper literals for physical units.
0017 /// All physical quantities have both a numerical value and a unit. For the
0018 /// computations we always choose a particular unit for a given physical
0019 /// quantity so we only need to consider the numerical values as such. The
0020 /// chosen base unit for a particular physical dimension, e.g. length, time, or
0021 /// energy, within this code base is called the native unit. The base units
0022 /// should be chosen such that they are internally consistent, require the least
0023 /// amount of explicit conversion factors (ideally none at all), and have
0024 /// typical numerical values close to unity to reduce numerical issues.
0025 ///
0026 /// Here, the following native units are used:
0027 ///
0028 /// - Length is expressed in mm.
0029 /// - Time is expressed in [speed-of-light * time] == mm. A consequence
0030 ///   of this choice is that the speed-of-light expressed in native units
0031 ///   is 1.
0032 /// - Angles are expressed in radian.
0033 /// - Energy, mass, and momentum are all expressed in GeV (consistent with
0034 ///   speed-of-light == 1).
0035 /// - Electric charge is expressed in e, i.e. units of the elementary charge.
0036 /// - The magnetic field is expressed in GeV/(e*mm). The magnetic field
0037 ///   connects momentum to length, e.g. in SI units the radius of a charged
0038 ///   particle trajectory in a constant magnetic field is given by
0039 ///
0040 ///   @f$
0041 ///      \text{radius} = - \frac{\text{momentum} }{ \text{charge} } / \text{field}
0042 ///   @f$
0043 ///
0044 /// With the chosen magnetic field unit the expression above stays the
0045 /// same and no additional conversion factors are necessary.
0046 ///
0047 /// Depending on the context a physical quantity might not be given in the
0048 /// native units. In this case we need to convert to the native unit first
0049 /// before the value can be used. The necessary conversion factors are defined
0050 /// in  @ref Acts::UnitConstants. Multiplying a value with the unit constant
0051 /// produces the equivalent value in the native unit, e.g.
0052 ///
0053 /// @snippet{trimleft} examples/units.cpp Using Unit Constants
0054 ///
0055 /// To further simplify the usage, physical quantities can also be expressed
0056 /// via [C++ user
0057 /// literals](https://en.cppreference.com/cpp/language/user_literal)
0058 /// defined
0059 /// in @ref Acts::UnitLiterals. This allows us to express quantities in a
0060 /// concise way:
0061 ///
0062 /// @snippet{trimleft} examples/units.cpp Using Unit Literals
0063 ///
0064 /// @warning Since using user-defined literals requires a namespace import of
0065 ///          @ref Acts::UnitLiterals it should not be used in headers since it
0066 ///          would (accidentally) modify the namespace wherever the header is
0067 ///          included.
0068 ///
0069 /// To ensure consistent computations and results the following guidelines
0070 /// **must** be followed when handling physical quantities with units:
0071 ///
0072 /// @snippet{trimleft} examples/units.cpp Unit Best Practices
0073 ///
0074 /// Here's a comprehensive example showing various ways to work with units:
0075 ///
0076 /// @snippet{trimleft} examples/units.cpp Comprehensive Units Example
0077 ///
0078 /// Converting output values from native units:
0079 ///
0080 /// @snippet{trimleft} examples/units.cpp Converting Output Values
0081 ///
0082 /// @note A helper script is available in
0083 ///   `Core/scripts/print_units_physical_constants.py` to validate some of the
0084 ///   numerical values.
0085 
0086 namespace UnitConstants {
0087 // Length, native unit mm
0088 /// Millimeter - native unit for length
0089 constexpr double mm = 1.0;
0090 /// Femtometer - 1e-15 meter
0091 constexpr double fm = 1e-12 * mm;
0092 /// Picometer - 1e-12 meter
0093 constexpr double pm = 1e-9 * mm;
0094 /// Nanometer - 1e-9 meter
0095 constexpr double nm = 1e-6 * mm;
0096 /// Micrometer - 1e-6 meter
0097 constexpr double um = 1e-3 * mm;
0098 /// Centimeter - 1e-2 meter
0099 constexpr double cm = 1e1 * mm;
0100 /// Meter
0101 constexpr double m = 1e3 * mm;
0102 /// Kilometer - 1e3 meter
0103 constexpr double km = 1e6 * mm;
0104 // Shortcuts for commonly used area and volume units. This intentionally
0105 // contains not all possible combinations to avoid cluttering the namespace.
0106 // Missing area or volume units can always be defined on the fly using the
0107 // existing length units e.g. 1fm³ -> 1fm * 1fm * 1fm
0108 // Area, native unit mm²
0109 /// Square millimeter - native unit for area
0110 constexpr double mm2 = mm * mm;
0111 /// Square centimeter
0112 constexpr double cm2 = cm * cm;
0113 /// Square meter
0114 constexpr double m2 = m * m;
0115 // Volume, native unit mm³
0116 /// Cubic millimeter - native unit for volume
0117 constexpr double mm3 = mm * mm * mm;
0118 /// Cubic centimeter
0119 constexpr double cm3 = cm * cm * cm;
0120 /// Cubic meter
0121 constexpr double m3 = m * m * m;
0122 // Time, native unit mm = [speed-of-light * time] = mm/s * s
0123 /// @note Depends on speed of light in SI units
0124 constexpr double s = 299792458000.0;  // = 299792458.0 * (m / 1.0) * 1.0;
0125 /// Femtosecond - 1e-15 second
0126 constexpr double fs = 1e-15 * s;
0127 /// Picosecond - 1e-12 second
0128 constexpr double ps = 1e-12 * s;
0129 /// Nanosecond - 1e-9 second
0130 constexpr double ns = 1e-9 * s;
0131 /// Microsecond - 1e-6 second
0132 constexpr double us = 1e-6 * s;
0133 /// Millisecond - 1e-3 second
0134 constexpr double ms = 1e-3 * s;
0135 /// Minute - 60 seconds
0136 constexpr double min = 60.0 * s;
0137 /// Hour - 3600 seconds
0138 constexpr double h = 3600.0 * s;
0139 // Angles, native unit radian
0140 /// Milliradian - 1e-3 radian
0141 constexpr double mrad = 1e-3;
0142 /// Radian - native unit for angle
0143 constexpr double rad = 1.0;
0144 /// Degree - pi/180 radians
0145 constexpr double degree = std::numbers::pi / 180. / rad;
0146 // Energy/mass/momentum, native unit GeV
0147 /// Gigaelectronvolt - native unit for energy/mass/momentum
0148 constexpr double GeV = 1.0;
0149 /// Electronvolt - 1e-9 GeV
0150 constexpr double eV = 1e-9 * GeV;
0151 /// Kiloelectronvolt - 1e-6 GeV
0152 constexpr double keV = 1e-6 * GeV;
0153 /// Megaelectronvolt - 1e-3 GeV
0154 constexpr double MeV = 1e-3 * GeV;
0155 /// Teraelectronvolt - 1e3 GeV
0156 constexpr double TeV = 1e3 * GeV;
0157 /// Joule in GeV
0158 constexpr double J = 6241509074.460763 * GeV;
0159 /// atomic mass unit u
0160 constexpr double u = 0.93149410242;
0161 /// Gram in GeV/c²
0162 /// @note 1eV/c² == 1.782662e-36kg
0163 ///      1GeV/c² == 1.782662e-27kg
0164 ///   ->     1kg == (1/1.782662e-27)GeV/c²
0165 ///   ->      1g == (1/(1e3*1.782662e-27))GeV/c²
0166 constexpr double g = 1.0 / 1.782662e-24;
0167 /// Kilogram in GeV/c²
0168 constexpr double kg = 1.0 / 1.782662e-27;
0169 /// Charge, native unit e (elementary charge)
0170 constexpr double e = 1.0;
0171 /// Magnetic field, native unit (eV*s)/(e*m²)
0172 /// @note Depends on speed of light in SI units
0173 constexpr double T = 0.000299792458;  // = eV * s / (e * m2);
0174 /// Gauss - 1e-4 Tesla
0175 constexpr double Gauss = 1e-4 * T;
0176 /// Kilogauss - 1e-1 Tesla
0177 constexpr double kGauss = 1e-1 * T;
0178 /// Amount of substance, native unit mol
0179 constexpr double mol = 1.0;
0180 }  // namespace UnitConstants
0181 
0182 /// @brief Namespace for user-defined literals for physical units. See @ref
0183 ///        UnitConstants for details.
0184 namespace UnitLiterals {
0185 // define user literal functions for the given unit constant
0186 #define ACTS_DEFINE_UNIT_LITERAL(name)                       \
0187   constexpr double operator""_##name(long double x) {        \
0188     return ::Acts::UnitConstants::name * x;                  \
0189   }                                                          \
0190   constexpr double operator""_##name(unsigned long long x) { \
0191     return ::Acts::UnitConstants::name * x;                  \
0192   }
0193 ACTS_DEFINE_UNIT_LITERAL(fm)
0194 ACTS_DEFINE_UNIT_LITERAL(pm)
0195 ACTS_DEFINE_UNIT_LITERAL(nm)
0196 ACTS_DEFINE_UNIT_LITERAL(um)
0197 ACTS_DEFINE_UNIT_LITERAL(mm)
0198 ACTS_DEFINE_UNIT_LITERAL(cm)
0199 ACTS_DEFINE_UNIT_LITERAL(m)
0200 ACTS_DEFINE_UNIT_LITERAL(km)
0201 ACTS_DEFINE_UNIT_LITERAL(mm2)
0202 ACTS_DEFINE_UNIT_LITERAL(cm2)
0203 ACTS_DEFINE_UNIT_LITERAL(m2)
0204 ACTS_DEFINE_UNIT_LITERAL(mm3)
0205 ACTS_DEFINE_UNIT_LITERAL(cm3)
0206 ACTS_DEFINE_UNIT_LITERAL(m3)
0207 ACTS_DEFINE_UNIT_LITERAL(fs)
0208 ACTS_DEFINE_UNIT_LITERAL(ps)
0209 ACTS_DEFINE_UNIT_LITERAL(ns)
0210 ACTS_DEFINE_UNIT_LITERAL(us)
0211 ACTS_DEFINE_UNIT_LITERAL(ms)
0212 ACTS_DEFINE_UNIT_LITERAL(s)
0213 ACTS_DEFINE_UNIT_LITERAL(min)
0214 ACTS_DEFINE_UNIT_LITERAL(h)
0215 ACTS_DEFINE_UNIT_LITERAL(mrad)
0216 ACTS_DEFINE_UNIT_LITERAL(rad)
0217 ACTS_DEFINE_UNIT_LITERAL(degree)
0218 ACTS_DEFINE_UNIT_LITERAL(eV)
0219 ACTS_DEFINE_UNIT_LITERAL(keV)
0220 ACTS_DEFINE_UNIT_LITERAL(MeV)
0221 ACTS_DEFINE_UNIT_LITERAL(GeV)
0222 ACTS_DEFINE_UNIT_LITERAL(TeV)
0223 ACTS_DEFINE_UNIT_LITERAL(J)
0224 ACTS_DEFINE_UNIT_LITERAL(u)
0225 ACTS_DEFINE_UNIT_LITERAL(g)
0226 ACTS_DEFINE_UNIT_LITERAL(kg)
0227 ACTS_DEFINE_UNIT_LITERAL(e)
0228 ACTS_DEFINE_UNIT_LITERAL(T)
0229 ACTS_DEFINE_UNIT_LITERAL(Gauss)
0230 ACTS_DEFINE_UNIT_LITERAL(kGauss)
0231 ACTS_DEFINE_UNIT_LITERAL(mol)
0232 // not needed anymore. undef to prevent littering the namespace
0233 #undef ACTS_DEFINE_UNIT_LITERAL
0234 }  // namespace UnitLiterals
0235 
0236 /// Physical constants in native units.
0237 ///
0238 /// Unit constants are intentionally not listed.
0239 namespace PhysicalConstants {
0240 // Speed of light
0241 /// Speed of light in vacuum - native unit (dimensionless)
0242 constexpr double c = 1.0;
0243 /// Reduced Planck constant h/2*pi.
0244 ///
0245 /// Computed from CODATA 2018 constants to double precision.
0246 constexpr double hbar =
0247     6.582119569509066e-25 * UnitConstants::GeV * UnitConstants::s;
0248 }  // namespace PhysicalConstants
0249 
0250 }  // namespace Acts