File indexing completed on 2025-09-13 08:53:38
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <utility>
0011
0012 #include "corecel/Config.hh"
0013
0014 #include "corecel/math/Constant.hh"
0015 #include "corecel/math/UnitUtils.hh"
0016
0017 #include "Constants.hh"
0018 #include "Types.hh"
0019 #include "Units.hh"
0020
0021 namespace celeritas
0022 {
0023 namespace units
0024 {
0025
0026
0027
0028
0029
0030
0031 struct CLight
0032 {
0033 static CELER_CONSTEXPR_FUNCTION Constant value()
0034 {
0035 return constants::c_light;
0036 }
0037 static char const* label() { return "c"; }
0038 };
0039
0040
0041 struct EElectron
0042 {
0043 static CELER_CONSTEXPR_FUNCTION Constant value()
0044 {
0045 return constants::e_electron;
0046 }
0047 static char const* label() { return "e"; }
0048 };
0049
0050
0051
0052
0053
0054
0055
0056
0057 struct ElectronVolt
0058 {
0059 static CELER_CONSTEXPR_FUNCTION Constant value()
0060 {
0061 #if CELERITAS_UNITS == CELERITAS_UNITS_CLHEP
0062 return units::megaelectronvolt / Constant(1e6);
0063 #else
0064 return constants::e_electron * units::volt;
0065 #endif
0066 }
0067 static char const* label() { return "eV"; }
0068 };
0069
0070
0071 struct Mev
0072 {
0073 static CELER_CONSTEXPR_FUNCTION Constant value()
0074 {
0075 #if CELERITAS_UNITS == CELERITAS_UNITS_CLHEP
0076 return units::megaelectronvolt;
0077 #else
0078 return Constant(1e6) * constants::e_electron * units::volt;
0079 #endif
0080 }
0081 static char const* label() { return "MeV"; }
0082 };
0083
0084
0085 struct MevPerCsq : UnitDivide<Mev, UnitProduct<CLight, CLight>>
0086 {
0087 static char const* label() { return "MeV/c^2"; }
0088 };
0089
0090
0091 struct MevPerC : UnitDivide<Mev, CLight>
0092 {
0093 static char const* label() { return "MeV/c"; }
0094 };
0095
0096
0097 struct Amu
0098 {
0099 static CELER_CONSTEXPR_FUNCTION Constant value()
0100 {
0101 return constants::atomic_mass;
0102 }
0103 static char const* label() { return "amu"; }
0104 };
0105
0106
0107 struct Barn
0108 {
0109 static CELER_CONSTEXPR_FUNCTION Constant value() { return units::barn; }
0110 static char const* label() { return "b"; }
0111 };
0112
0113
0114 struct Millibarn
0115 {
0116 static CELER_CONSTEXPR_FUNCTION Constant value()
0117 {
0118 return Constant(1e-3) * units::barn;
0119 }
0120 static char const* label() { return "mb"; }
0121 };
0122
0123
0124 struct Mol
0125 {
0126 static CELER_CONSTEXPR_FUNCTION Constant value()
0127 {
0128 return constants::na_avogadro;
0129 }
0130 static char const* label() { return "mol"; }
0131 };
0132
0133
0134
0135
0136
0137
0138
0139 struct Centimeter
0140 {
0141 static CELER_CONSTEXPR_FUNCTION Constant value()
0142 {
0143 return units::centimeter;
0144 }
0145 static char const* label() { return "cm"; }
0146 };
0147
0148 struct Gram
0149 {
0150 static CELER_CONSTEXPR_FUNCTION Constant value() { return units::gram; }
0151 static char const* label() { return "g"; }
0152 };
0153
0154 struct Gauss
0155 {
0156 static CELER_CONSTEXPR_FUNCTION Constant value() { return units::gauss; }
0157 static char const* label() { return "G"; }
0158 };
0159
0160
0161 struct InvCentimeterCubed
0162 {
0163 static CELER_CONSTEXPR_FUNCTION Constant value()
0164 {
0165 return 1 / (units::centimeter * units::centimeter * units::centimeter);
0166 }
0167 static char const* label() { return "1/cm^3"; }
0168 };
0169
0170
0171 struct MolPerCentimeterCubed : UnitProduct<Mol, InvCentimeterCubed>
0172 {
0173 static char const* label() { return "mol/cm^3"; }
0174 };
0175
0176
0177 struct GramPerCentimeterCubed : UnitProduct<Gram, InvCentimeterCubed>
0178 {
0179 static char const* label() { return "g/cm^3"; }
0180 };
0181
0182
0183
0184
0185
0186
0187 struct Meter
0188 {
0189 static CELER_CONSTEXPR_FUNCTION Constant value() { return units::meter; }
0190 static char const* label() { return "m"; }
0191 };
0192
0193 struct Kilogram
0194 {
0195 static CELER_CONSTEXPR_FUNCTION Constant value()
0196 {
0197 return units::kilogram;
0198 }
0199 static char const* label() { return "kg"; }
0200 };
0201
0202 struct Second
0203 {
0204 static CELER_CONSTEXPR_FUNCTION Constant value() { return units::second; }
0205 static char const* label() { return "s"; }
0206 };
0207
0208 struct Tesla
0209 {
0210 static CELER_CONSTEXPR_FUNCTION Constant value() { return units::tesla; }
0211 static char const* label() { return "T"; }
0212 };
0213
0214
0215
0216
0217
0218
0219
0220 struct Millimeter
0221 {
0222 static CELER_CONSTEXPR_FUNCTION Constant value()
0223 {
0224 return units::millimeter;
0225 }
0226 static char const* label() { return "mm"; }
0227 };
0228
0229 struct Nanosecond
0230 {
0231 static CELER_CONSTEXPR_FUNCTION Constant value()
0232 {
0233 return units::nanosecond;
0234 }
0235 static char const* label() { return "ns"; }
0236 };
0237
0238
0239 struct ClhepUnitMass
0240 {
0241 static CELER_CONSTEXPR_FUNCTION Constant value()
0242 {
0243 if constexpr (CELERITAS_UNITS == CELERITAS_UNITS_CLHEP)
0244 {
0245
0246
0247 return Constant(1);
0248 }
0249 else
0250 {
0251 return constants::e_electron / coulomb * kilogram * Constant(1e-6);
0252 }
0253 }
0254 static char const* label() { return "mass_clhep"; }
0255 };
0256
0257
0258 struct ClhepUnitBField
0259 {
0260 static CELER_CONSTEXPR_FUNCTION Constant value()
0261 {
0262 return Constant{1e3} * tesla;
0263 }
0264 static char const* label() { return "field_clhep"; }
0265 };
0266
0267
0268
0269
0270
0271
0272
0273
0274 struct Native
0275 {
0276 static CELER_CONSTEXPR_FUNCTION Constant value() { return Constant{1}; }
0277 };
0278
0279
0280 struct LogMev
0281 {
0282
0283 static CELER_CONSTEXPR_FUNCTION Constant value() { return Constant{0}; }
0284 };
0285
0286
0287
0288
0289
0290 template<UnitSystem>
0291 struct UnitSystemTraits;
0292
0293
0294
0295
0296 template<>
0297 struct UnitSystemTraits<UnitSystem::cgs>
0298 {
0299 using Length = Centimeter;
0300 using Mass = Gram;
0301 using Time = Second;
0302 using BField = Gauss;
0303
0304 static char const* label() { return "cgs"; }
0305 };
0306
0307
0308 template<>
0309 struct UnitSystemTraits<UnitSystem::si>
0310 {
0311 using Length = Meter;
0312 using Mass = Kilogram;
0313 using Time = Second;
0314 using BField = Tesla;
0315
0316 static char const* label() { return "si"; }
0317 };
0318
0319
0320 template<>
0321 struct UnitSystemTraits<UnitSystem::clhep>
0322 {
0323 using Length = Millimeter;
0324 using Mass = ClhepUnitMass;
0325 using Time = Nanosecond;
0326 using BField = ClhepUnitBField;
0327
0328 static char const* label() { return "clhep"; }
0329 };
0330
0331
0332
0333
0334 using CgsTraits = UnitSystemTraits<UnitSystem::cgs>;
0335 using SiTraits = UnitSystemTraits<UnitSystem::si>;
0336 using ClhepTraits = UnitSystemTraits<UnitSystem::clhep>;
0337 using NativeTraits = UnitSystemTraits<UnitSystem::native>;
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348 template<class F>
0349 constexpr decltype(auto) visit_unit_system(F&& func, UnitSystem sys)
0350 {
0351 #define CELER_US_VISIT_CASE(TYPE) \
0352 case UnitSystem::TYPE: \
0353 return std::forward<F>(func)(UnitSystemTraits<UnitSystem::TYPE>{});
0354
0355 switch (sys)
0356 {
0357 CELER_US_VISIT_CASE(cgs);
0358 CELER_US_VISIT_CASE(si);
0359 CELER_US_VISIT_CASE(clhep);
0360 default:
0361 CELER_ASSERT_UNREACHABLE();
0362 }
0363
0364 #undef CELER_US_VISIT_CASE
0365 }
0366
0367
0368
0369 }
0370 }