CORSIKA8  0.0.0
The framework to simulate particle cascades for astroparticle physics
PhysicalUnits.hpp
Go to the documentation of this file.
1 /*
2  * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
3  *
4  * This software is distributed under the terms of the GNU General Public
5  * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
6  * the license.
7  */
8 
9 #pragma once
10 
11 // the templated static-unit package we use:
14 
16 
24 /*
25  It is essentially a bug of the phys_units package to define the
26  operator<< not in the same namespace as the types it is working
27  on. This breaks ADL (argument-dependent lookup). Here we "fix" this:
28  */
29 namespace phys::units {
30  using phys::units::io::operator<<;
31 } // namespace phys::units
32 
40 namespace corsika::units {
41  template <int N, typename T>
42  auto constexpr static_pow([[maybe_unused]] T x) {
43  if constexpr (N == 0) {
44  return 1;
45  } else if constexpr (N > 0) {
46  return x * static_pow<N - 1, T>(x);
47  } else {
48  return 1 / static_pow<-N, T>(x);
49  }
50  }
51 } // namespace corsika::units
52 
60 namespace corsika::units::si {
61 
62  using namespace phys::units;
63  using namespace phys::units::literals;
64  using namespace phys::units::io;
65 
66  using phys::units::io::operator<<;
67 
72 
75 
82  using ElectricChargeType =
91  using InverseLengthType =
92  phys::units::quantity<phys::units::dimensions<-1, 0, 0>, double>;
93  using InverseTimeType =
94  phys::units::quantity<phys::units::dimensions<0, 0, -1>, double>;
95  using InverseGrammageType =
96  phys::units::quantity<phys::units::dimensions<2, -1, 0>, double>;
97  using MagneticFluxType =
99 
100  template <typename DimFrom, typename DimTo>
101  auto constexpr conversion_factor_HEP_to_SI() {
102  static_assert(DimFrom::dim1 == 0 && DimFrom::dim2 == 0 && DimFrom::dim3 == 0 &&
103  DimFrom::dim4 == 0 && DimFrom::dim5 == 0 && DimFrom::dim6 == 0 &&
104  DimFrom::dim7 == 0,
105  "must be a pure HEP type");
106 
107  static_assert(
108  DimTo::dim4 == 0 && DimTo::dim5 == 0 && DimTo::dim6 == 0 && DimTo::dim7 == 0,
109  "conversion possible only into L, M, T dimensions");
110 
111  int constexpr e = DimFrom::dim8; // HEP dim.
112 
113  int constexpr l = DimTo::dim1; // SI length dim.
114  int constexpr m = DimTo::dim2; // SI mass dim.
115  int constexpr t = DimTo::dim3; // SI time dim.
116 
117  int constexpr p = m;
118  int constexpr q = -m - t;
119  static_assert(q == l + e - 2 * m, "HEP/SI dimension mismatch!");
120 
121  return static_pow<-e>(constants::hBarC) * static_pow<p>(constants::hBar) *
122  static_pow<q>(constants::c);
123  }
124 
125  template <typename DimFrom>
126  auto constexpr conversion_factor_SI_to_HEP() {
127  static_assert(DimFrom::dim4 == 0 && DimFrom::dim5 == 0 && DimFrom::dim6 == 0 &&
128  DimFrom::dim7 == 0 && DimFrom::dim8 == 0,
129  "must be pure L, M, T type");
130 
131  int constexpr l = DimFrom::dim1; // SI length dim.
132  int constexpr m = DimFrom::dim2; // SI mass dim.
133  int constexpr t = DimFrom::dim3; // SI time dim.
134 
135  int constexpr p = -m;
136  int constexpr q = m + t;
137  int constexpr e = m - t - l;
138 
139  return static_pow<e>(constants::hBarC) * static_pow<p>(constants::hBar) *
140  static_pow<q>(constants::c);
141  }
142 
143  template <typename DimTo, typename DimFrom>
144  auto constexpr convert_HEP_to_SI(quantity<DimFrom> q) {
145  return conversion_factor_HEP_to_SI<DimFrom, DimTo>() * q;
146  }
147 
148  template <typename DimFrom>
149  auto constexpr convert_SI_to_HEP(quantity<DimFrom> q) {
150  return conversion_factor_SI_to_HEP<DimFrom>() * q;
151  }
152 
153 } // end namespace corsika::units::si
154 
160 namespace phys {
161  namespace units {
162  namespace literals {
163 
169  QUANTITY_DEFINE_SCALING_LITERALS(eV, hepenergy_d, 1)
170 
171  QUANTITY_DEFINE_SCALING_LITERALS(b, corsika::units::si::sigma_d,
172  magnitude(corsika::constants::barn))
173 
174  } // namespace literals
175  } // namespace units
176 } // namespace phys
177 
178 // import into main \namespace corsika here:
179 namespace corsika {
180  using namespace units;
181  using namespace units::si;
182  using namespace phys::units;
183  using namespace phys::units::literals;
184  using namespace phys::units::io;
185  using phys::units::io::operator<<;
186 } // namespace corsika
We could drag dimensions around individually, but it&#39;s much more convenient to package them...
Definition: quantity.hpp:62
namespace units.
IO for compile-time quantity library.
namespace phys.
Zero-overhead dimensional analysis and unit/quantity manipulation and conversion. ...
namespace io.
Extension of the phys::units package.
class "quantity" is the heart of the library.
Definition: quantity.hpp:54
The cascade namespace assembles all objects needed to simulate full particles cascades.
Constants are defined with static units, based on the package (namespace) phys::units, imported in PhysicsUnits.hpp.
SI units as used mainly in CORSIKA8 as basedline.
constexpr X magnitude(quantity< DX, X > const &q)
quantity&#39;s magnitude.
Definition: quantity.hpp:749