CORSIKA8  0.0.0
The framework to simulate particle cascades for astroparticle physics
SwitchProcessSequence.hpp
Go to the documentation of this file.
1 /*
2  * (c) Copyright 2018 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 
17 #include <corsika/framework/process/BoundaryCrossingProcess.hpp>
18 #include <corsika/framework/process/ContinuousProcess.hpp>
19 #include <corsika/framework/process/ContinuousProcessIndex.hpp>
20 #include <corsika/framework/process/DecayProcess.hpp>
21 #include <corsika/framework/process/InteractionProcess.hpp>
23 #include <corsika/framework/process/SecondariesProcess.hpp>
24 #include <corsika/framework/process/StackProcess.hpp>
26 
27 #include <cmath>
28 #include <limits>
29 #include <type_traits>
30 
31 namespace corsika {
32 
73  template <typename TCondition, typename TSequence, typename USequence,
74  int IndexFirstProcess = 0,
75  int IndexOfProcess1 = count_processes<TSequence, IndexFirstProcess>::count,
76  int IndexOfProcess2 = count_processes<USequence, IndexOfProcess1>::count>
78  : public BaseProcess<SwitchProcessSequence<TCondition, TSequence, USequence>> {
79 
80  using process1_type = typename std::decay_t<TSequence>;
81  using process2_type = typename std::decay_t<USequence>;
82 
83  // make sure only BaseProcess types TSequence/2 are passed
84  static_assert(is_process_v<process1_type>,
85  "can only use process derived from BaseProcess in "
86  "SwitchProcessSequence, for Process 1");
87  static_assert(is_process_v<process2_type>,
88  "can only use process derived from BaseProcess in "
89  "SwitchProcessSequence, for Process 2");
90 
91  // make sure none of TSequence/2 is a StackProcess
92  static_assert(!std::is_base_of_v<StackProcess<process1_type>, process1_type>,
93  "cannot use StackProcess in SwitchProcessSequence, for Process 1");
94  static_assert(!std::is_base_of_v<StackProcess<process2_type>, process2_type>,
95  "cannot use StackProcess in SwitchProcessSequence, for Process 2");
96 
97  // if TSequence/2 are already ProcessSequences, make sure they do not contain
98  // any StackProcess
99  static_assert(!contains_stack_process_v<process1_type>,
100  "cannot use StackProcess in SwitchProcessSequence, remove from "
101  "ProcessSequence 1");
102  static_assert(!contains_stack_process_v<process2_type>,
103  "cannot use StackProcess in SwitchProcessSequence, remove from "
104  "ProcessSequence 2");
105 
106  public:
107  // resource management
108  SwitchProcessSequence() = delete; // only initialized objects
111  SwitchProcessSequence& operator=(SwitchProcessSequence const&) = default;
112  ~SwitchProcessSequence() = default;
113 
114  static bool const is_process_sequence = true;
115  static bool const is_switch_process_sequence = true;
116 
128  SwitchProcessSequence(TCondition sel, TSequence in_A, USequence in_B)
129  : select_(sel)
130  , A_(in_A)
131  , B_(in_B) {}
132 
133  template <typename TParticle>
134  ProcessReturn doBoundaryCrossing(TParticle& particle,
135  typename TParticle::node_type const& from,
136  typename TParticle::node_type const& to);
137 
138  template <typename TParticle, typename TTrack>
139  ProcessReturn doContinuous(TParticle& particle, TTrack& vT,
140  ContinuousProcessIndex const limitId);
141 
142  template <typename TSecondaries>
143  void doSecondaries(TSecondaries& vS);
144 
145  template <typename TParticle, typename TTrack>
146  ContinuousProcessStepLength getMaxStepLength(TParticle& particle, TTrack& vTrack);
147 
148  template <typename TParticle>
149  GrammageType getInteractionLength(TParticle&& particle) {
150  return 1. / getInverseInteractionLength(particle);
151  }
152 
153  template <typename TParticle>
154  InverseGrammageType getInverseInteractionLength(TParticle&& particle);
155 
156  template <typename TSecondaryView>
157  ProcessReturn selectInteraction(
158  TSecondaryView& view, [[maybe_unused]] InverseGrammageType lambda_inv_select,
159  [[maybe_unused]] InverseGrammageType lambda_inv_sum =
161 
162  template <typename TParticle>
163  TimeType getLifetime(TParticle&& particle) {
164  return 1. / getInverseLifetime(particle);
165  }
166 
167  template <typename TParticle>
168  InverseTimeType getInverseLifetime(TParticle&& particle);
169 
170  // select decay process
171  template <typename TSecondaryView>
172  ProcessReturn selectDecay(
173  TSecondaryView& view, [[maybe_unused]] InverseTimeType decay_inv_select,
174  [[maybe_unused]] InverseTimeType decay_inv_sum = InverseTimeType::zero());
175 
179  static unsigned int constexpr getNumberOfProcesses() { return numberOfProcesses_; }
180 
181 #ifdef CORSIKA_UNIT_TESTING
182  TCondition getCondition() const { return select_; }
183  TSequence getSequence() const { return A_; }
184  USequence getAltSequence() const { return B_; }
185 #endif
186 
187  private:
188  TCondition select_;
189 
191  TSequence A_;
192  USequence B_;
193 
194  static unsigned int constexpr numberOfProcesses_ = IndexOfProcess2; // static counter
195  };
196 
207  template <typename TCondition, typename TSequence, typename USequence,
208  typename = std::enable_if_t<is_process_v<typename std::decay_t<TSequence>> &&
209  is_process_v<typename std::decay_t<USequence>>>>
211  TCondition&& selector, TSequence&& vA, USequence&& vB) {
213  }
214 
216 
217 } // namespace corsika
218 
219 #include <corsika/detail/framework/process/SwitchProcessSequence.inl>
Import and extend the phys::units package.
static unsigned int constexpr getNumberOfProcesses()
static counter to uniquely index (count) all ContinuousProcess in switch sequence.
Class to switch between two process branches.
Each process in C8 must derive from BaseProcess.
Definition: BaseProcess.hpp:33
SwitchProcessSequence(TCondition sel, TSequence in_A, USequence in_B)
Only valid user constructor will create fully initialized object.
To index individual processes (continuous processes) inside a ProcessSequence.
class "quantity" is the heart of the library.
Definition: quantity.hpp:54
The cascade namespace assembles all objects needed to simulate full particles cascades.
static constexpr quantity zero()
We need a "zero" of each type – for comparisons, to initialize running totals, etc.
Definition: quantity.hpp:359
SwitchProcessSequence< TCondition, TSequence, USequence > make_select(TCondition &&selector, TSequence &&vA, USequence &&vB)
the functin make_select(select, proc1, proc1) assembles many BaseProcesses, and ProcessSequences into...
ProcessReturn
since in a process sequence many status updates can accumulate for a single particle, this enum should define only bit-flags that can be accumulated easily with "|="
Process to act on the entire particle stack.
To store step length in LengthType and unique index in ProcessSequence of shortest step ContinuousPro...