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