![]() |
|
|||
File indexing completed on 2025-10-19 07:57:04
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 /// @verbatim embed:rst:leading-slashes 0016 /// All physical quantities have both a numerical value and a unit. For the 0017 /// computations we always choose a particular unit for a given physical 0018 /// quantity so we only need to consider the numerical values as such. The 0019 /// chosen base unit for a particular physical dimension, e.g. length, time, or 0020 /// energy, within this code base is called the native unit. The base units 0021 /// should be chosen such that they are internally consistent, require the least 0022 /// amount of explicit conversion factors (ideally none at all), and have 0023 /// typical numerical values close to unity to reduce numerical issues. 0024 /// 0025 /// Here, the following native units are used: 0026 /// 0027 /// - Length is expressed in mm. 0028 /// - Time is expressed in [speed-of-light * time] == mm. A consequence 0029 /// of this choice is that the speed-of-light expressed in native units 0030 /// is 1. 0031 /// - Angles are expressed in radian. 0032 /// - Energy, mass, and momentum are all expressed in GeV (consistent with 0033 /// speed-of-light == 1). 0034 /// - Electric charge is expressed in e, i.e. units of the elementary charge. 0035 /// - The magnetic field is expressed in GeV/(e*mm). The magnetic field 0036 /// connects momentum to length, e.g. in SI units the radius of a charged 0037 /// particle trajectory in a constant magnetic field is given by 0038 /// 0039 /// .. math:: 0040 /// 0041 /// radius = - (momentum / charge) / field 0042 /// 0043 /// With the chosen magnetic field unit the expression above stays the 0044 /// same and no additional conversion factors are necessary. 0045 /// - Amount of substance is expressed in mol. 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 ``Acts::UnitConstants``. Multiplying a value with the unit constant 0051 /// produces the equivalent value in the native unit, e.g. 0052 /// 0053 /// .. code-block:: cpp 0054 /// 0055 /// double length = 1 * Acts::UnitConstants::m; // length == 1000.0 0056 /// double momentum = 100 * Acts::UnitConstants::MeV; // momentum == 0.1 0057 /// 0058 /// The conversion of a value in native units into the equivalent value in a 0059 /// specific other unit is computed by dividing with the relevant unit, e.g. 0060 /// 0061 /// .. code-block:: cpp 0062 /// 0063 /// double length = 10.0; // native units mm 0064 /// double lengthInM = length / Acts::UnitConstants::m; // == 0.01; 0065 /// 0066 /// To further simplify the usage, physical quantities can also be expressed via 0067 /// `C++ user literals 0068 /// <https://en.cppreference.com/w/cpp/language/user_literal>`_ defined in 0069 /// ``Acts::UnitLiterals``. This allows us to express quantities in a concise 0070 /// way: 0071 /// 0072 /// .. code-block:: cpp 0073 /// 0074 /// using namespace Acts::UnitLiterals; 0075 /// 0076 /// double length = 1_m; // == 1000.0 0077 /// double momentum = 1.25_TeV; // == 1250.0 0078 /// double lengthInUm = length / 1_um; // == 1000000.0 0079 /// double momentumInMeV = momentum / 1_MeV; // == 1250000.0 0080 /// 0081 /// .. warning:: 0082 /// Since using user-defined literals requires a namespace import of 0083 /// ``Acts::UnitLiterals`` it should not be used in headers since it would 0084 /// (accidentally) modify the namespace wherever the header is included. 0085 /// 0086 /// To ensure consistent computations and results the following guidelines 0087 /// **must** be followed when handling physical quantities with units: 0088 /// 0089 /// - All unqualified numerical values, i.e. without a unit, are assumed to 0090 /// be expressed in the relevant native unit, e.g. mm for lengths or GeV 0091 /// for energy/momentum. 0092 /// - If a variable stores a physical quantity in a specific unit that is 0093 /// not the native unit, clearly mark this in the variable, i.e. 0094 /// 0095 /// .. code-block:: cpp 0096 /// 0097 /// double momentum = 100.0; // momentum is stored as native unit GeV 0098 /// double momentumInMeV = 10.0; // would be 0.01 in native units 0099 /// 0100 /// - All input values must be given as ``numerical_value * unit_constant`` or 0101 /// equivalently using the unit literals as ``value_unit``. The resulting 0102 /// unqualified numerical value will be automatically converted to the 0103 /// native unit. 0104 /// - To output an unqualified numerical value in the native units as a 0105 /// numerical value in a specific unit divide by the unit constants as 0106 /// ``numerical_value / unit_constant`` or using the unit literals as 0107 /// ``value / 1_unit``. 0108 /// 0109 /// Examples: 0110 /// 0111 /// .. code-block:: cpp 0112 /// 0113 /// #include <Acts/include/Definitions/Units.hpp> 0114 /// using namespace Acts::UnitLiterals; 0115 /// 0116 /// // define input values w/ units (via unit constants) 0117 /// double width = 12 * Acts::UnitConstants::mm; 0118 /// double mmuon = 105.7 * Acts::UnitConstants::MeV; 0119 /// // define input values w/ units (via unit user literals) 0120 /// double length = 23_cm; 0121 /// double time = 1214.2_ns; 0122 /// double angle = 123_degree; 0123 /// double momentum = 2.5_TeV; 0124 /// double mass = 511_keV; 0125 /// double velocity = 345_m / 1_s; 0126 /// double bfield = 3.9_T; 0127 /// 0128 /// // convert output values (via unit constants) 0129 /// double t_in_ns = trackPars.time() / Acts::UnitConstants::ns; 0130 /// // convert output values (via unit user literals) 0131 /// double x_in_mm = trackPars.position()[ePos0] / 1_mm; 0132 /// double p_in_TeV = trackPars.absoluteMomentum() / 1_TeV; 0133 /// 0134 /// @endverbatim 0135 0136 /// @note A helper script is available in 0137 /// `Core/scripts/print_units_physical_constants.py` to validate some of the 0138 /// numerical values. 0139 0140 namespace UnitConstants { 0141 // Length, native unit mm 0142 /// Millimeter - native unit for length 0143 constexpr double mm = 1.0; 0144 /// Femtometer - 1e-15 meter 0145 constexpr double fm = 1e-12 * mm; 0146 /// Picometer - 1e-12 meter 0147 constexpr double pm = 1e-9 * mm; 0148 /// Nanometer - 1e-9 meter 0149 constexpr double nm = 1e-6 * mm; 0150 /// Micrometer - 1e-6 meter 0151 constexpr double um = 1e-3 * mm; 0152 /// Centimeter - 1e-2 meter 0153 constexpr double cm = 1e1 * mm; 0154 /// Meter 0155 constexpr double m = 1e3 * mm; 0156 /// Kilometer - 1e3 meter 0157 constexpr double km = 1e6 * mm; 0158 // Shortcuts for commonly used area and volume units. This intentionally 0159 // contains not all possible combinations to avoid cluttering the namespace. 0160 // Missing area or volume units can always be defined on the fly using the 0161 // existing length units e.g. 1fm³ -> 1fm * 1fm * 1fm 0162 // Area, native unit mm² 0163 /// Square millimeter - native unit for area 0164 constexpr double mm2 = mm * mm; 0165 /// Square centimeter 0166 constexpr double cm2 = cm * cm; 0167 /// Square meter 0168 constexpr double m2 = m * m; 0169 // Volume, native unit mm³ 0170 /// Cubic millimeter - native unit for volume 0171 constexpr double mm3 = mm * mm * mm; 0172 /// Cubic centimeter 0173 constexpr double cm3 = cm * cm * cm; 0174 /// Cubic meter 0175 constexpr double m3 = m * m * m; 0176 // Time, native unit mm = [speed-of-light * time] = mm/s * s 0177 /// @note Depends on speed of light in SI units 0178 constexpr double s = 299792458000.0; // = 299792458.0 * (m / 1.0) * 1.0; 0179 /// Femtosecond - 1e-15 second 0180 constexpr double fs = 1e-15 * s; 0181 /// Picosecond - 1e-12 second 0182 constexpr double ps = 1e-12 * s; 0183 /// Nanosecond - 1e-9 second 0184 constexpr double ns = 1e-9 * s; 0185 /// Microsecond - 1e-6 second 0186 constexpr double us = 1e-6 * s; 0187 /// Millisecond - 1e-3 second 0188 constexpr double ms = 1e-3 * s; 0189 /// Minute - 60 seconds 0190 constexpr double min = 60.0 * s; 0191 /// Hour - 3600 seconds 0192 constexpr double h = 3600.0 * s; 0193 // Angles, native unit radian 0194 /// Milliradian - 1e-3 radian 0195 constexpr double mrad = 1e-3; 0196 /// Radian - native unit for angle 0197 constexpr double rad = 1.0; 0198 /// Degree - pi/180 radians 0199 constexpr double degree = std::numbers::pi / 180. / rad; 0200 // Energy/mass/momentum, native unit GeV 0201 /// Gigaelectronvolt - native unit for energy/mass/momentum 0202 constexpr double GeV = 1.0; 0203 /// Electronvolt - 1e-9 GeV 0204 constexpr double eV = 1e-9 * GeV; 0205 /// Kiloelectronvolt - 1e-6 GeV 0206 constexpr double keV = 1e-6 * GeV; 0207 /// Megaelectronvolt - 1e-3 GeV 0208 constexpr double MeV = 1e-3 * GeV; 0209 /// Teraelectronvolt - 1e3 GeV 0210 constexpr double TeV = 1e3 * GeV; 0211 /// Joule in GeV 0212 constexpr double J = 6241509074.460763 * GeV; 0213 /// atomic mass unit u 0214 constexpr double u = 0.93149410242; 0215 /// Gram in GeV/c² 0216 /// @note 1eV/c² == 1.782662e-36kg 0217 /// 1GeV/c² == 1.782662e-27kg 0218 /// -> 1kg == (1/1.782662e-27)GeV/c² 0219 /// -> 1g == (1/(1e3*1.782662e-27))GeV/c² 0220 constexpr double g = 1.0 / 1.782662e-24; 0221 /// Kilogram in GeV/c² 0222 constexpr double kg = 1.0 / 1.782662e-27; 0223 /// Charge, native unit e (elementary charge) 0224 constexpr double e = 1.0; 0225 /// Magnetic field, native unit (eV*s)/(e*m²) 0226 /// @note Depends on speed of light in SI units 0227 constexpr double T = 0.000299792458; // = eV * s / (e * m2); 0228 /// Gauss - 1e-4 Tesla 0229 constexpr double Gauss = 1e-4 * T; 0230 /// Kilogauss - 1e-1 Tesla 0231 constexpr double kGauss = 1e-1 * T; 0232 /// Amount of substance, native unit mol 0233 constexpr double mol = 1.0; 0234 } // namespace UnitConstants 0235 0236 namespace UnitLiterals { 0237 // define user literal functions for the given unit constant 0238 #define ACTS_DEFINE_UNIT_LITERAL(name) \ 0239 constexpr double operator""_##name(long double x) { \ 0240 return ::Acts::UnitConstants::name * x; \ 0241 } \ 0242 constexpr double operator""_##name(unsigned long long x) { \ 0243 return ::Acts::UnitConstants::name * x; \ 0244 } 0245 ACTS_DEFINE_UNIT_LITERAL(fm) 0246 ACTS_DEFINE_UNIT_LITERAL(pm) 0247 ACTS_DEFINE_UNIT_LITERAL(nm) 0248 ACTS_DEFINE_UNIT_LITERAL(um) 0249 ACTS_DEFINE_UNIT_LITERAL(mm) 0250 ACTS_DEFINE_UNIT_LITERAL(cm) 0251 ACTS_DEFINE_UNIT_LITERAL(m) 0252 ACTS_DEFINE_UNIT_LITERAL(km) 0253 ACTS_DEFINE_UNIT_LITERAL(mm2) 0254 ACTS_DEFINE_UNIT_LITERAL(cm2) 0255 ACTS_DEFINE_UNIT_LITERAL(m2) 0256 ACTS_DEFINE_UNIT_LITERAL(mm3) 0257 ACTS_DEFINE_UNIT_LITERAL(cm3) 0258 ACTS_DEFINE_UNIT_LITERAL(m3) 0259 ACTS_DEFINE_UNIT_LITERAL(fs) 0260 ACTS_DEFINE_UNIT_LITERAL(ps) 0261 ACTS_DEFINE_UNIT_LITERAL(ns) 0262 ACTS_DEFINE_UNIT_LITERAL(us) 0263 ACTS_DEFINE_UNIT_LITERAL(ms) 0264 ACTS_DEFINE_UNIT_LITERAL(s) 0265 ACTS_DEFINE_UNIT_LITERAL(min) 0266 ACTS_DEFINE_UNIT_LITERAL(h) 0267 ACTS_DEFINE_UNIT_LITERAL(mrad) 0268 ACTS_DEFINE_UNIT_LITERAL(rad) 0269 ACTS_DEFINE_UNIT_LITERAL(degree) 0270 ACTS_DEFINE_UNIT_LITERAL(eV) 0271 ACTS_DEFINE_UNIT_LITERAL(keV) 0272 ACTS_DEFINE_UNIT_LITERAL(MeV) 0273 ACTS_DEFINE_UNIT_LITERAL(GeV) 0274 ACTS_DEFINE_UNIT_LITERAL(TeV) 0275 ACTS_DEFINE_UNIT_LITERAL(J) 0276 ACTS_DEFINE_UNIT_LITERAL(u) 0277 ACTS_DEFINE_UNIT_LITERAL(g) 0278 ACTS_DEFINE_UNIT_LITERAL(kg) 0279 ACTS_DEFINE_UNIT_LITERAL(e) 0280 ACTS_DEFINE_UNIT_LITERAL(T) 0281 ACTS_DEFINE_UNIT_LITERAL(Gauss) 0282 ACTS_DEFINE_UNIT_LITERAL(kGauss) 0283 ACTS_DEFINE_UNIT_LITERAL(mol) 0284 // not needed anymore. undef to prevent littering the namespace 0285 #undef ACTS_DEFINE_UNIT_LITERAL 0286 } // namespace UnitLiterals 0287 0288 /// Physical constants in native units. 0289 /// 0290 /// Unit constants are intentionally not listed. 0291 namespace PhysicalConstants { 0292 // Speed of light 0293 /// Speed of light in vacuum - native unit (dimensionless) 0294 constexpr double c = 1.0; 0295 /// Reduced Planck constant h/2*pi. 0296 /// 0297 /// Computed from CODATA 2018 constants to double precision. 0298 constexpr double hbar = 0299 6.582119569509066e-25 * UnitConstants::GeV * UnitConstants::s; 0300 } // namespace PhysicalConstants 0301 0302 } // namespace Acts
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |