CORSIKA  @c8_version@
The framework to simulate particle cascades for astroparticle physics
ProposalProcessBase.hpp
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 #include <PROPOSAL/PROPOSAL.h>
12 
14 #include <corsika/framework/random/RNGManager.hpp>
15 
16 #include <array>
17 
18 namespace corsika::proposal {
19 
24  static constexpr std::array<Code, 7> tracked{
25  Code::Photon, Code::Electron, Code::Positron, Code::MuMinus,
26  Code::MuPlus, Code::TauPlus, Code::TauMinus,
27  };
28 
33  static constexpr double v_cut = 0.01;
34 
40  static std::map<Code, PROPOSAL::ParticleDef> particle = {
41  {Code::Photon, PROPOSAL::GammaDef()}, {Code::Electron, PROPOSAL::EMinusDef()},
42  {Code::Positron, PROPOSAL::EPlusDef()}, {Code::MuMinus, PROPOSAL::MuMinusDef()},
43  {Code::MuPlus, PROPOSAL::MuPlusDef()}, {Code::TauMinus, PROPOSAL::TauMinusDef()},
44  {Code::TauPlus, PROPOSAL::TauPlusDef()}};
45 
49 
50  // Cross sections for muons and taus
51  template <typename T>
52  auto cross_builder = [](PROPOSAL::Medium& medium,
54  emCut) {
55  auto particle_def = T();
57  CORSIKA_LOG_DEBUG("PROPOSAL: Generate general cross sections for particle type {} ",
58  particle_def.name);
59  auto interpolate = true;
60 
61  auto p_cut =
62  std::make_shared<const PROPOSAL::EnergyCutSettings>(emCut / 1_MeV, v_cut, false);
63 
64  // do not use v_cut for ionization due to numerical problems
65  auto p_cut_no_vcut =
66  std::make_shared<const PROPOSAL::EnergyCutSettings>(emCut / 1_MeV, 1, false);
67 
68  auto cross_vec = std::vector<std::shared_ptr<PROPOSAL::CrossSectionBase>>();
69  cross_vec.push_back(PROPOSAL::make_crosssection(
70  PROPOSAL::crosssection::BremsKelnerKokoulinPetrukhin{false}, particle_def, medium,
71  p_cut, interpolate));
72  cross_vec.push_back(PROPOSAL::make_crosssection(
73  PROPOSAL::crosssection::EpairKelnerKokoulinPetrukhin{false}, particle_def, medium,
74  p_cut, interpolate));
75  cross_vec.push_back(PROPOSAL::make_crosssection(
76  PROPOSAL::crosssection::IonizBetheBlochRossi{*p_cut_no_vcut}, particle_def,
77  medium, p_cut_no_vcut, interpolate));
78  cross_vec.push_back(PROPOSAL::make_crosssection(
79  PROPOSAL::crosssection::PhotoAbramowiczLevinLevyMaor97{
80  std::make_unique<PROPOSAL::crosssection::ShadowButkevichMikheyev>()},
81  particle_def, medium, p_cut, interpolate));
82 
83  return cross_vec;
84  };
85 
86  // cross sections for photons
87  template <>
88  auto cross_builder<PROPOSAL::GammaDef> =
89  [](PROPOSAL::Medium& medium,
91  auto particle_def = PROPOSAL::GammaDef();
92  CORSIKA_LOG_DEBUG(
93  "PROPOSAL: Generate photon cross sections for particle type {} ",
94  particle_def.name);
95 
96  auto interpolate = true;
97  auto cross_vec = std::vector<std::shared_ptr<PROPOSAL::CrossSectionBase>>();
98  auto photopair =
99  PROPOSAL::make_crosssection(PROPOSAL::crosssection::PhotoPairKochMotz{false},
100  particle_def, medium, nullptr, interpolate);
101  cross_vec.push_back(std::move(photopair));
102  auto compton =
103  PROPOSAL::make_crosssection(PROPOSAL::crosssection::ComptonKleinNishina{},
104  particle_def, medium, nullptr, interpolate);
105  cross_vec.push_back(std::move(compton));
106  auto photoproduction = PROPOSAL::make_crosssection(
107  PROPOSAL::crosssection::PhotoproductionHeckC7Shadowing{}, particle_def,
108  medium, nullptr, interpolate);
109  cross_vec.push_back(std::move(photoproduction));
110  auto photoeffect =
111  PROPOSAL::make_crosssection(PROPOSAL::crosssection::PhotoeffectSauter{},
112  particle_def, medium, nullptr, interpolate);
113  cross_vec.push_back(std::move(photoeffect));
114  return cross_vec;
115  };
116 
117  // cross sections for electrons
118  template <>
119  auto cross_builder<PROPOSAL::EMinusDef> =
120  [](PROPOSAL::Medium& medium,
122  emCut) {
123  auto particle_def = PROPOSAL::EMinusDef();
125  CORSIKA_LOG_DEBUG(
126  "PROPOSAL: Generate electron cross sections for particle type {} ",
127  particle_def.name);
128  auto interpolate = true;
129 
130  auto p_cut = std::make_shared<const PROPOSAL::EnergyCutSettings>(emCut / 1_MeV,
131  v_cut, false);
132 
133  // do not use v_cut for ionization due to numerical problems
134  auto p_cut_no_vcut =
135  std::make_shared<const PROPOSAL::EnergyCutSettings>(emCut / 1_MeV, 1, false);
136 
137  auto cross_vec = std::vector<std::shared_ptr<PROPOSAL::CrossSectionBase>>();
138  cross_vec.push_back(PROPOSAL::make_crosssection(
139  PROPOSAL::crosssection::BremsElectronScreening{false}, particle_def, medium,
140  p_cut, interpolate));
141  cross_vec.push_back(PROPOSAL::make_crosssection(
142  PROPOSAL::crosssection::EpairForElectronPositron{false}, particle_def, medium,
143  p_cut, interpolate));
144  cross_vec.push_back(PROPOSAL::make_crosssection(
145  PROPOSAL::crosssection::IonizBergerSeltzerMoller{*p_cut_no_vcut},
146  particle_def, medium, p_cut_no_vcut, interpolate));
147  cross_vec.push_back(PROPOSAL::make_crosssection(
148  PROPOSAL::crosssection::PhotoAbramowiczLevinLevyMaor97{
149  std::make_unique<PROPOSAL::crosssection::ShadowButkevichMikheyev>()},
150  particle_def, medium, p_cut, interpolate));
151 
152  return cross_vec;
153  };
154 
155  // cross sections for positrons
156  template <>
157  auto cross_builder<PROPOSAL::EPlusDef> =
158  [](PROPOSAL::Medium& medium,
160  emCut) {
161  auto particle_def = PROPOSAL::EPlusDef();
163  CORSIKA_LOG_DEBUG(
164  "PROPOSAL: Generate positron cross sections for particle type {} ",
165  particle_def.name);
166  auto interpolate = true;
167 
168  auto p_cut = std::make_shared<const PROPOSAL::EnergyCutSettings>(emCut / 1_MeV,
169  v_cut, false);
170 
171  // do not use v_cut for ionization due to numerical problems
172  auto p_cut_no_vcut =
173  std::make_shared<const PROPOSAL::EnergyCutSettings>(emCut / 1_MeV, 1, false);
174 
175  auto cross_vec = std::vector<std::shared_ptr<PROPOSAL::CrossSectionBase>>();
176  cross_vec.push_back(PROPOSAL::make_crosssection(
177  PROPOSAL::crosssection::BremsElectronScreening{false}, particle_def, medium,
178  p_cut, interpolate));
179  cross_vec.push_back(PROPOSAL::make_crosssection(
180  PROPOSAL::crosssection::EpairForElectronPositron{false}, particle_def, medium,
181  p_cut, interpolate));
182  cross_vec.push_back(PROPOSAL::make_crosssection(
183  PROPOSAL::crosssection::IonizBergerSeltzerBhabha{*p_cut_no_vcut},
184  particle_def, medium, p_cut_no_vcut, interpolate));
185  cross_vec.push_back(PROPOSAL::make_crosssection(
186  PROPOSAL::crosssection::PhotoAbramowiczLevinLevyMaor97{
187  std::make_unique<PROPOSAL::crosssection::ShadowButkevichMikheyev>()},
188  particle_def, medium, p_cut, interpolate));
189  cross_vec.push_back(
190  PROPOSAL::make_crosssection(PROPOSAL::crosssection::AnnihilationHeitler{},
191  particle_def, medium, nullptr, interpolate));
192 
193  return cross_vec;
194  };
195 
200  static std::map<Code, std::function<PROPOSAL::crosssection_list_t(
201  PROPOSAL::Medium&, corsika::units::si::HEPEnergyType)>>
202  cross = {{Code::Photon, cross_builder<PROPOSAL::GammaDef>},
203  {Code::Electron, cross_builder<PROPOSAL::EMinusDef>},
204  {Code::Positron, cross_builder<PROPOSAL::EPlusDef>},
205  {Code::MuMinus, cross_builder<PROPOSAL::MuMinusDef>},
206  {Code::MuPlus, cross_builder<PROPOSAL::MuPlusDef>},
207  {Code::TauMinus, cross_builder<PROPOSAL::TauMinusDef>},
208  {Code::TauPlus, cross_builder<PROPOSAL::TauPlusDef>}};
209 
215  protected:
216  default_prng_type& RNG_ = RNGManager<>::getInstance().getRandomStream("proposal");
217 
218  std::unordered_map<std::size_t, PROPOSAL::Medium>
220 
226  template <typename TEnvironment>
227  ProposalProcessBase(TEnvironment const& _env);
228 
232  bool canInteract(Code pcode) const;
233 
234  using calc_key_t = std::pair<std::size_t, Code>;
235 
240  struct hash {
241  size_t operator()(const calc_key_t& p) const noexcept;
242  };
243 
247  virtual void buildCalculator(Code, NuclearComposition const&) = 0;
248 
254  template <typename Particle, typename Calculators>
255  auto getCalculator(Particle& vP, Calculators& calc) {
256  const auto& comp = vP.getNode()->getModelProperties().getNuclearComposition();
257  auto calc_it = calc.find(std::make_pair(comp.getHash(), vP.getPID()));
258  if (calc_it != calc.end()) return calc_it;
259  buildCalculator(vP.getPID(), comp);
260  return getCalculator(vP, calc);
261  }
262  };
263 } // namespace corsika::proposal
264 
265 #include <corsika/detail/modules/proposal/ProposalProcessBase.inl>
PROPOSAL base process which handels mapping of particle codes to stored interpolation tables...
auto getCalculator(Particle &vP, Calculators &calc)
Searches the particle dependet calculator dependent of actuall medium composition and particle type...
bool canInteract(Code pcode) const
Checks if a particle can be processed by proposal.
virtual void buildCalculator(Code, NuclearComposition const &)=0
Builds the calculator to the corresponding class.
std::unordered_map< std::size_t, PROPOSAL::Medium > media
maps nuclear composition from univers to media to produce crosssections, which requires further ioniz...
Hash to store interpolation tables related to a pair of particle and nuclear composition.
Describes the composition of matter Allowes and handles the creation of custom matter compositions...
Interface to particle properties.
ProposalProcessBase(TEnvironment const &_env)
Store cut and nuclear composition of the whole universe in media which are required for creating cros...
prng_type & getRandomStream(string_type const &streamName)