IAP GITLAB

Skip to content
Snippets Groups Projects
Commit 2d1030b2 authored by Maximilian Reininghaus's avatar Maximilian Reininghaus :vulcan:
Browse files

simplified traits in ProcessSequence

parent 9dece868
No related branches found
No related tags found
No related merge requests found
...@@ -47,9 +47,19 @@ namespace corsika::process { ...@@ -47,9 +47,19 @@ namespace corsika::process {
// this is a marker to track which BaseProcess is also a ProcessSequence // this is a marker to track which BaseProcess is also a ProcessSequence
template <typename T> template <typename T>
struct is_process_sequence { struct is_process_sequence : std::false_type {};
static const bool value = false;
}; template <typename T>
bool constexpr is_process_sequence_v = is_process_sequence<T>::value;
namespace switch_process {
template <typename A, typename B>
class SwitchProcess; // fwd-decl.
}
template <typename A, typename B>
struct corsika::process::is_process_sequence<switch_process::SwitchProcess<A, B>>
: std::true_type {};
/** /**
T1 and T2 are both references if possible (lvalue), otherwise T1 and T2 are both references if possible (lvalue), otherwise
...@@ -57,11 +67,14 @@ namespace corsika::process { ...@@ -57,11 +67,14 @@ namespace corsika::process {
rvalue as well as lvalue Processes in the ProcessSequence. rvalue as well as lvalue Processes in the ProcessSequence.
*/ */
template <typename T1, typename T2> template <typename T1, typename T2>
class ProcessSequence : public BaseProcess<ProcessSequence<T1, T2> > { class ProcessSequence : public BaseProcess<ProcessSequence<T1, T2>> {
using T1type = typename std::decay<T1>::type; using T1type = typename std::decay<T1>::type;
using T2type = typename std::decay<T2>::type; using T2type = typename std::decay<T2>::type;
static bool constexpr t1ProcSeq = is_process_sequence_v<T1type>;
static bool constexpr t2ProcSeq = is_process_sequence_v<T2type>;
public: public:
T1 A; // this is a reference, if possible T1 A; // this is a reference, if possible
T2 B; // this is a reference, if possible T2 B; // this is a reference, if possible
...@@ -78,13 +91,13 @@ namespace corsika::process { ...@@ -78,13 +91,13 @@ namespace corsika::process {
VTNType const& to) { VTNType const& to) {
EProcessReturn ret = EProcessReturn::eOk; EProcessReturn ret = EProcessReturn::eOk;
if constexpr (std::is_base_of<BoundaryCrossingProcess<T1type>, T1type>::value || if constexpr (std::is_base_of_v<BoundaryCrossingProcess<T1type>, T1type> ||
is_process_sequence<T1>::value) { t1ProcSeq) {
ret |= A.DoBoundaryCrossing(p, from, to); ret |= A.DoBoundaryCrossing(p, from, to);
} }
if constexpr (std::is_base_of<BoundaryCrossingProcess<T2type>, T2type>::value || if constexpr (std::is_base_of_v<BoundaryCrossingProcess<T2type>, T2type> ||
is_process_sequence<T2>::value) { t2ProcSeq) {
ret |= B.DoBoundaryCrossing(p, from, to); ret |= B.DoBoundaryCrossing(p, from, to);
} }
...@@ -94,12 +107,10 @@ namespace corsika::process { ...@@ -94,12 +107,10 @@ namespace corsika::process {
template <typename TParticle, typename TTrack> template <typename TParticle, typename TTrack>
EProcessReturn DoContinuous(TParticle& vP, TTrack& vT) { EProcessReturn DoContinuous(TParticle& vP, TTrack& vT) {
EProcessReturn ret = EProcessReturn::eOk; EProcessReturn ret = EProcessReturn::eOk;
if constexpr (std::is_base_of<ContinuousProcess<T1type>, T1type>::value || if constexpr (std::is_base_of_v<ContinuousProcess<T1type>, T1type> || t1ProcSeq) {
is_process_sequence<T1>::value) {
ret |= A.DoContinuous(vP, vT); ret |= A.DoContinuous(vP, vT);
} }
if constexpr (std::is_base_of<ContinuousProcess<T2type>, T2type>::value || if constexpr (std::is_base_of_v<ContinuousProcess<T2type>, T2type> || t2ProcSeq) {
is_process_sequence<T2>::value) {
ret |= B.DoContinuous(vP, vT); ret |= B.DoContinuous(vP, vT);
} }
return ret; return ret;
...@@ -108,12 +119,10 @@ namespace corsika::process { ...@@ -108,12 +119,10 @@ namespace corsika::process {
template <typename TSecondaries> template <typename TSecondaries>
EProcessReturn DoSecondaries(TSecondaries& vS) { EProcessReturn DoSecondaries(TSecondaries& vS) {
EProcessReturn ret = EProcessReturn::eOk; EProcessReturn ret = EProcessReturn::eOk;
if constexpr (std::is_base_of<SecondariesProcess<T1type>, T1type>::value || if constexpr (std::is_base_of_v<SecondariesProcess<T1type>, T1type> || t1ProcSeq) {
is_process_sequence<T1>::value) {
ret |= A.DoSecondaries(vS); ret |= A.DoSecondaries(vS);
} }
if constexpr (std::is_base_of<SecondariesProcess<T2type>, T2type>::value || if constexpr (std::is_base_of_v<SecondariesProcess<T2type>, T2type> || t2ProcSeq) {
is_process_sequence<T2>::value) {
ret |= B.DoSecondaries(vS); ret |= B.DoSecondaries(vS);
} }
return ret; return ret;
...@@ -121,12 +130,10 @@ namespace corsika::process { ...@@ -121,12 +130,10 @@ namespace corsika::process {
bool CheckStep() { bool CheckStep() {
bool ret = false; bool ret = false;
if constexpr (std::is_base_of<StackProcess<T1type>, T1type>::value || if constexpr (std::is_base_of_v<StackProcess<T1type>, T1type> || t1ProcSeq) {
is_process_sequence<T1>::value) {
ret |= A.CheckStep(); ret |= A.CheckStep();
} }
if constexpr (std::is_base_of<StackProcess<T2type>, T2type>::value || if constexpr (std::is_base_of_v<StackProcess<T2type>, T2type> || t2ProcSeq) {
is_process_sequence<T2>::value) {
ret |= B.CheckStep(); ret |= B.CheckStep();
} }
return ret; return ret;
...@@ -135,12 +142,10 @@ namespace corsika::process { ...@@ -135,12 +142,10 @@ namespace corsika::process {
template <typename TStack> template <typename TStack>
EProcessReturn DoStack(TStack& vS) { EProcessReturn DoStack(TStack& vS) {
EProcessReturn ret = EProcessReturn::eOk; EProcessReturn ret = EProcessReturn::eOk;
if constexpr (std::is_base_of<StackProcess<T1type>, T1type>::value || if constexpr (std::is_base_of_v<StackProcess<T1type>, T1type> || t1ProcSeq) {
is_process_sequence<T1>::value) {
if (A.CheckStep()) { ret |= A.DoStack(vS); } if (A.CheckStep()) { ret |= A.DoStack(vS); }
} }
if constexpr (std::is_base_of<StackProcess<T2type>, T2type>::value || if constexpr (std::is_base_of_v<StackProcess<T2type>, T2type> || t2ProcSeq) {
is_process_sequence<T2>::value) {
if (B.CheckStep()) { ret |= B.DoStack(vS); } if (B.CheckStep()) { ret |= B.DoStack(vS); }
} }
return ret; return ret;
...@@ -152,13 +157,11 @@ namespace corsika::process { ...@@ -152,13 +157,11 @@ namespace corsika::process {
max_length = // if no other process in the sequence implements it max_length = // if no other process in the sequence implements it
std::numeric_limits<double>::infinity() * corsika::units::si::meter; std::numeric_limits<double>::infinity() * corsika::units::si::meter;
if constexpr (std::is_base_of<ContinuousProcess<T1type>, T1type>::value || if constexpr (std::is_base_of_v<ContinuousProcess<T1type>, T1type> || t1ProcSeq) {
is_process_sequence<T1>::value) {
corsika::units::si::LengthType const len = A.MaxStepLength(vP, vTrack); corsika::units::si::LengthType const len = A.MaxStepLength(vP, vTrack);
max_length = std::min(max_length, len); max_length = std::min(max_length, len);
} }
if constexpr (std::is_base_of<ContinuousProcess<T2type>, T2type>::value || if constexpr (std::is_base_of_v<ContinuousProcess<T2type>, T2type> || t2ProcSeq) {
is_process_sequence<T2>::value) {
corsika::units::si::LengthType const len = B.MaxStepLength(vP, vTrack); corsika::units::si::LengthType const len = B.MaxStepLength(vP, vTrack);
max_length = std::min(max_length, len); max_length = std::min(max_length, len);
} }
...@@ -182,12 +185,10 @@ namespace corsika::process { ...@@ -182,12 +185,10 @@ namespace corsika::process {
InverseGrammageType tot = 0 * meter * meter / gram; InverseGrammageType tot = 0 * meter * meter / gram;
if constexpr (std::is_base_of_v<InteractionProcess<T1type>, T1type> || if constexpr (std::is_base_of_v<InteractionProcess<T1type>, T1type> || t1ProcSeq) {
is_process_sequence_v<T1>) {
tot += A.GetInverseInteractionLength(vP); tot += A.GetInverseInteractionLength(vP);
} }
if constexpr (std::is_base_of_v<InteractionProcess<T2type>, T2type> || if constexpr (std::is_base_of_v<InteractionProcess<T2type>, T2type> || t2ProcSeq) {
is_process_sequence_v<T2>) {
tot += B.GetInverseInteractionLength(vP); tot += B.GetInverseInteractionLength(vP);
} }
return tot; return tot;
...@@ -199,13 +200,13 @@ namespace corsika::process { ...@@ -199,13 +200,13 @@ namespace corsika::process {
[[maybe_unused]] corsika::units::si::InverseGrammageType lambda_select, [[maybe_unused]] corsika::units::si::InverseGrammageType lambda_select,
corsika::units::si::InverseGrammageType& lambda_inv_count) { corsika::units::si::InverseGrammageType& lambda_inv_count) {
if constexpr (is_process_sequence<T1type>::value) { if constexpr (t1ProcSeq) {
// if A is a process sequence --> check inside // if A is a process sequence --> check inside
const EProcessReturn ret = const EProcessReturn ret =
A.SelectInteraction(vP, vS, lambda_select, lambda_inv_count); A.SelectInteraction(vP, vS, lambda_select, lambda_inv_count);
// if A did succeed, stop routine // if A did succeed, stop routine
if (ret != EProcessReturn::eOk) { return ret; } if (ret != EProcessReturn::eOk) { return ret; }
} else if constexpr (std::is_base_of<InteractionProcess<T1type>, T1type>::value) { } else if constexpr (std::is_base_of_v<InteractionProcess<T1type>, T1type>) {
// if this is not a ContinuousProcess --> evaluate probability // if this is not a ContinuousProcess --> evaluate probability
lambda_inv_count += A.GetInverseInteractionLength(vP); lambda_inv_count += A.GetInverseInteractionLength(vP);
// check if we should execute THIS process and then EXIT // check if we should execute THIS process and then EXIT
...@@ -215,13 +216,13 @@ namespace corsika::process { ...@@ -215,13 +216,13 @@ namespace corsika::process {
} }
} // end branch A } // end branch A
if constexpr (is_process_sequence<T2>::value) { if constexpr (t2ProcSeq) {
// if A is a process sequence --> check inside // if A is a process sequence --> check inside
const EProcessReturn ret = const EProcessReturn ret =
B.SelectInteraction(vP, vS, lambda_select, lambda_inv_count); B.SelectInteraction(vP, vS, lambda_select, lambda_inv_count);
// if A did succeed, stop routine // if A did succeed, stop routine
if (ret != EProcessReturn::eOk) { return ret; } if (ret != EProcessReturn::eOk) { return ret; }
} else if constexpr (std::is_base_of<InteractionProcess<T2type>, T2type>::value) { } else if constexpr (std::is_base_of_v<InteractionProcess<T2type>, T2type>) {
// if this is not a ContinuousProcess --> evaluate probability // if this is not a ContinuousProcess --> evaluate probability
lambda_inv_count += B.GetInverseInteractionLength(vP); lambda_inv_count += B.GetInverseInteractionLength(vP);
// check if we should execute THIS process and then EXIT // check if we should execute THIS process and then EXIT
...@@ -249,12 +250,10 @@ namespace corsika::process { ...@@ -249,12 +250,10 @@ namespace corsika::process {
corsika::units::si::InverseTimeType tot = 0 / second; corsika::units::si::InverseTimeType tot = 0 / second;
if constexpr (std::is_base_of<DecayProcess<T1type>, T1type>::value || if constexpr (std::is_base_of_v<DecayProcess<T1type>, T1type> || t1ProcSeq) {
is_process_sequence<T1>::value) {
tot += A.GetInverseLifetime(p); tot += A.GetInverseLifetime(p);
} }
if constexpr (std::is_base_of<DecayProcess<T2type>, T2type>::value || if constexpr (std::is_base_of_v<DecayProcess<T2type>, T2type> || t2ProcSeq) {
is_process_sequence<T2>::value) {
tot += B.GetInverseLifetime(p); tot += B.GetInverseLifetime(p);
} }
return tot; return tot;
...@@ -266,12 +265,12 @@ namespace corsika::process { ...@@ -266,12 +265,12 @@ namespace corsika::process {
TParticle& vP, TSecondaries& vS, TParticle& vP, TSecondaries& vS,
[[maybe_unused]] corsika::units::si::InverseTimeType decay_select, [[maybe_unused]] corsika::units::si::InverseTimeType decay_select,
corsika::units::si::InverseTimeType& decay_inv_count) { corsika::units::si::InverseTimeType& decay_inv_count) {
if constexpr (is_process_sequence<T1>::value) { if constexpr (t1ProcSeq) {
// if A is a process sequence --> check inside // if A is a process sequence --> check inside
const EProcessReturn ret = A.SelectDecay(vP, vS, decay_select, decay_inv_count); const EProcessReturn ret = A.SelectDecay(vP, vS, decay_select, decay_inv_count);
// if A did succeed, stop routine // if A did succeed, stop routine
if (ret != EProcessReturn::eOk) { return ret; } if (ret != EProcessReturn::eOk) { return ret; }
} else if constexpr (std::is_base_of<DecayProcess<T1type>, T1type>::value) { } else if constexpr (std::is_base_of_v<DecayProcess<T1type>, T1type>) {
// if this is not a ContinuousProcess --> evaluate probability // if this is not a ContinuousProcess --> evaluate probability
decay_inv_count += A.GetInverseLifetime(vP); decay_inv_count += A.GetInverseLifetime(vP);
// check if we should execute THIS process and then EXIT // check if we should execute THIS process and then EXIT
...@@ -282,12 +281,12 @@ namespace corsika::process { ...@@ -282,12 +281,12 @@ namespace corsika::process {
} }
} // end branch A } // end branch A
if constexpr (is_process_sequence<T2>::value) { if constexpr (t2ProcSeq) {
// if A is a process sequence --> check inside // if A is a process sequence --> check inside
const EProcessReturn ret = B.SelectDecay(vP, vS, decay_select, decay_inv_count); const EProcessReturn ret = B.SelectDecay(vP, vS, decay_select, decay_inv_count);
// if A did succeed, stop routine // if A did succeed, stop routine
if (ret != EProcessReturn::eOk) { return ret; } if (ret != EProcessReturn::eOk) { return ret; }
} else if constexpr (std::is_base_of<DecayProcess<T2type>, T2type>::value) { } else if constexpr (std::is_base_of_v<DecayProcess<T2type>, T2type>) {
// if this is not a ContinuousProcess --> evaluate probability // if this is not a ContinuousProcess --> evaluate probability
decay_inv_count += B.GetInverseLifetime(vP); decay_inv_count += B.GetInverseLifetime(vP);
// check if we should execute THIS process and then EXIT // check if we should execute THIS process and then EXIT
...@@ -320,9 +319,7 @@ namespace corsika::process { ...@@ -320,9 +319,7 @@ namespace corsika::process {
/// marker to identify objectas ProcessSequence /// marker to identify objectas ProcessSequence
template <typename A, typename B> template <typename A, typename B>
struct is_process_sequence<corsika::process::ProcessSequence<A, B> > { struct is_process_sequence<corsika::process::ProcessSequence<A, B>> : std::true_type {};
static const bool value = true;
};
} // namespace corsika::process } // namespace corsika::process
......
...@@ -17,8 +17,7 @@ namespace corsika::process::switch_process { ...@@ -17,8 +17,7 @@ namespace corsika::process::switch_process {
*/ */
template <class TLowEProcess, class THighEProcess> template <class TLowEProcess, class THighEProcess>
class SwitchProcess class SwitchProcess : public BaseProcess<SwitchProcess<TLowEProcess, THighEProcess>> {
: public InteractionProcess<SwitchProcess<TLowEProcess, THighEProcess>> {
TLowEProcess& fLowEProcess; TLowEProcess& fLowEProcess;
THighEProcess& fHighEProcess; THighEProcess& fHighEProcess;
units::si::HEPEnergyType const fThresholdEnergy; units::si::HEPEnergyType const fThresholdEnergy;
...@@ -35,6 +34,11 @@ namespace corsika::process::switch_process { ...@@ -35,6 +34,11 @@ namespace corsika::process::switch_process {
fHighEProcess.Init(); fHighEProcess.Init();
} }
template <typename TParticle>
corsika::units::si::InverseGrammageType GetInverseInteractionLength(TParticle& p) {
return 1 / GetInteractionLength(p);
}
template <typename TParticle> template <typename TParticle>
units::si::GrammageType GetInteractionLength(TParticle& vParticle) { units::si::GrammageType GetInteractionLength(TParticle& vParticle) {
if (vParticle.GetEnergy() < fThresholdEnergy) { if (vParticle.GetEnergy() < fThresholdEnergy) {
...@@ -60,26 +64,35 @@ namespace corsika::process::switch_process { ...@@ -60,26 +64,35 @@ namespace corsika::process::switch_process {
TParticle& vP, TSecondaries& vS, TParticle& vP, TSecondaries& vS,
[[maybe_unused]] corsika::units::si::InverseGrammageType lambda_select, [[maybe_unused]] corsika::units::si::InverseGrammageType lambda_select,
corsika::units::si::InverseGrammageType& lambda_inv_count) { corsika::units::si::InverseGrammageType& lambda_inv_count) {
if (vP.GetEnergy() < fThresholdEnergy) { if (vP.GetEnergy() < fThresholdEnergy) {
if constexpr (is_process_sequence_v<TLowEProcess>) { if constexpr (is_process_sequence_v<TLowEProcess>) {
return fLowEProcess.SelectInteraction(vP, vS, lambda_select, lambda_inv_count); return fLowEProcess.SelectInteraction(vP, vS, lambda_select, lambda_inv_count);
} else { } else {
return fLowEProcess.DoInteraction(vS); lambda_inv_count += fLowEProcess.GetInverseInteractionLength(vP);
// check if we should execute THIS process and then EXIT
if (lambda_select < lambda_inv_count) {
fLowEProcess.DoInteraction(vS);
return EProcessReturn::eInteracted;
} else {
return EProcessReturn::eOk;
}
} }
} else { } else {
if constexpr (is_process_sequence_v<THighEProcess>) { if constexpr (is_process_sequence_v<THighEProcess>) {
return fHighEProcess.SelectInteraction(vP, vS, lambda_select, lambda_inv_count); return fHighEProcess.SelectInteraction(vP, vS, lambda_select, lambda_inv_count);
} else { } else {
return fHighEProcess.DoInteraction(vS); lambda_inv_count += fHighEProcess.GetInverseInteractionLength(vP);
// check if we should execute THIS process and then EXIT
if (lambda_select < lambda_inv_count) {
fHighEProcess.DoInteraction(vS);
return EProcessReturn::eInteracted;
} else {
return EProcessReturn::eOk;
}
} }
} }
} }
}; };
} // namespace corsika::process::switch_process } // namespace corsika::process::switch_process
template <typename A, typename B>
struct corsika::process::is_process_sequence<
corsika::process::switch_process::SwitchProcess<A, B>> : std::true_type {};
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment