CORSIKA  @c8_version@
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>;
96  phys::units::quantity<phys::units::dimensions<3, -1, 0>, double>;
97  using InverseGrammageType =
98  phys::units::quantity<phys::units::dimensions<2, -1, 0>, double>;
99  using MagneticFluxType =
101  using ElectricFieldType =
102  phys::units::quantity<phys::units::dimensions<1, 1, -3, -1>, double>;
103  using VectorPotentialType =
104  phys::units::quantity<phys::units::dimensions<1, 1, -2, -1>, double>;
105 
106  template <typename DimFrom, typename DimTo>
107  auto constexpr conversion_factor_HEP_to_SI() {
108  static_assert(DimFrom::dim1 == 0 && DimFrom::dim2 == 0 && DimFrom::dim3 == 0 &&
109  DimFrom::dim4 == 0 && DimFrom::dim5 == 0 && DimFrom::dim6 == 0 &&
110  DimFrom::dim7 == 0,
111  "must be a pure HEP type");
112 
113  static_assert(
114  DimTo::dim4 == 0 && DimTo::dim5 == 0 && DimTo::dim6 == 0 && DimTo::dim7 == 0,
115  "conversion possible only into L, M, T dimensions");
116 
117  int constexpr e = DimFrom::dim8; // HEP dim.
118 
119  int constexpr l = DimTo::dim1; // SI length dim.
120  int constexpr m = DimTo::dim2; // SI mass dim.
121  int constexpr t = DimTo::dim3; // SI time dim.
122 
123  int constexpr p = m;
124  int constexpr q = -m - t;
125  static_assert(q == l + e - 2 * m, "HEP/SI dimension mismatch!");
126 
127  return static_pow<-e>(constants::hBarC) * static_pow<p>(constants::hBar) *
128  static_pow<q>(constants::c);
129  }
130 
131  template <typename DimFrom>
132  auto constexpr conversion_factor_SI_to_HEP() {
133  static_assert(DimFrom::dim4 == 0 && DimFrom::dim5 == 0 && DimFrom::dim6 == 0 &&
134  DimFrom::dim7 == 0 && DimFrom::dim8 == 0,
135  "must be pure L, M, T type");
136 
137  int constexpr l = DimFrom::dim1; // SI length dim.
138  int constexpr m = DimFrom::dim2; // SI mass dim.
139  int constexpr t = DimFrom::dim3; // SI time dim.
140 
141  int constexpr p = -m;
142  int constexpr q = m + t;
143  int constexpr e = m - t - l;
144 
145  return static_pow<e>(constants::hBarC) * static_pow<p>(constants::hBar) *
146  static_pow<q>(constants::c);
147  }
148 
149  template <typename DimTo, typename DimFrom>
150  auto constexpr convert_HEP_to_SI(quantity<DimFrom> q) {
151  return conversion_factor_HEP_to_SI<DimFrom, DimTo>() * q;
152  }
153 
154  template <typename DimFrom>
155  auto constexpr convert_SI_to_HEP(quantity<DimFrom> q) {
156  return conversion_factor_SI_to_HEP<DimFrom>() * q;
157  }
158 
159 } // end namespace corsika::units::si
160 
166 namespace phys {
167  namespace units {
168  namespace literals {
169 
175  QUANTITY_DEFINE_SCALING_LITERALS(eV, hepenergy_d, 1)
176 
177  QUANTITY_DEFINE_SCALING_LITERALS(b, corsika::units::si::sigma_d,
178  magnitude(corsika::constants::barn))
179 
180  } // namespace literals
181  } // namespace units
182 } // namespace phys
183 
184 // import into main \namespace corsika here:
185 namespace corsika {
186  using namespace units;
187  using namespace units::si;
188  using namespace phys::units;
189  using namespace phys::units::literals;
190  using namespace phys::units::io;
191  using phys::units::io::operator<<;
192 } // 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
`, since they are used everywhere as integral part of the framework.
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