From 2d1030b2beb1d7b917dc621a9d6cfefbef2792ce Mon Sep 17 00:00:00 2001 From: Maximilian Reininghaus <maximilian.reininghaus@kit.edu> Date: Thu, 16 May 2019 19:40:52 -0300 Subject: [PATCH] simplified traits in ProcessSequence --- Framework/ProcessSequence/ProcessSequence.h | 91 ++++++++++----------- Processes/SwitchProcess/SwitchProcess.h | 31 +++++-- 2 files changed, 66 insertions(+), 56 deletions(-) diff --git a/Framework/ProcessSequence/ProcessSequence.h b/Framework/ProcessSequence/ProcessSequence.h index 3e1e4e9a0..713076bc6 100644 --- a/Framework/ProcessSequence/ProcessSequence.h +++ b/Framework/ProcessSequence/ProcessSequence.h @@ -47,9 +47,19 @@ namespace corsika::process { // this is a marker to track which BaseProcess is also a ProcessSequence template <typename T> - struct is_process_sequence { - static const bool value = false; - }; + struct is_process_sequence : std::false_type {}; + + 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 @@ -57,11 +67,14 @@ namespace corsika::process { rvalue as well as lvalue Processes in the ProcessSequence. */ 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 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: T1 A; // this is a reference, if possible T2 B; // this is a reference, if possible @@ -78,13 +91,13 @@ namespace corsika::process { VTNType const& to) { EProcessReturn ret = EProcessReturn::eOk; - if constexpr (std::is_base_of<BoundaryCrossingProcess<T1type>, T1type>::value || - is_process_sequence<T1>::value) { + if constexpr (std::is_base_of_v<BoundaryCrossingProcess<T1type>, T1type> || + t1ProcSeq) { ret |= A.DoBoundaryCrossing(p, from, to); } - if constexpr (std::is_base_of<BoundaryCrossingProcess<T2type>, T2type>::value || - is_process_sequence<T2>::value) { + if constexpr (std::is_base_of_v<BoundaryCrossingProcess<T2type>, T2type> || + t2ProcSeq) { ret |= B.DoBoundaryCrossing(p, from, to); } @@ -94,12 +107,10 @@ namespace corsika::process { template <typename TParticle, typename TTrack> EProcessReturn DoContinuous(TParticle& vP, TTrack& vT) { EProcessReturn ret = EProcessReturn::eOk; - if constexpr (std::is_base_of<ContinuousProcess<T1type>, T1type>::value || - is_process_sequence<T1>::value) { + if constexpr (std::is_base_of_v<ContinuousProcess<T1type>, T1type> || t1ProcSeq) { ret |= A.DoContinuous(vP, vT); } - if constexpr (std::is_base_of<ContinuousProcess<T2type>, T2type>::value || - is_process_sequence<T2>::value) { + if constexpr (std::is_base_of_v<ContinuousProcess<T2type>, T2type> || t2ProcSeq) { ret |= B.DoContinuous(vP, vT); } return ret; @@ -108,12 +119,10 @@ namespace corsika::process { template <typename TSecondaries> EProcessReturn DoSecondaries(TSecondaries& vS) { EProcessReturn ret = EProcessReturn::eOk; - if constexpr (std::is_base_of<SecondariesProcess<T1type>, T1type>::value || - is_process_sequence<T1>::value) { + if constexpr (std::is_base_of_v<SecondariesProcess<T1type>, T1type> || t1ProcSeq) { ret |= A.DoSecondaries(vS); } - if constexpr (std::is_base_of<SecondariesProcess<T2type>, T2type>::value || - is_process_sequence<T2>::value) { + if constexpr (std::is_base_of_v<SecondariesProcess<T2type>, T2type> || t2ProcSeq) { ret |= B.DoSecondaries(vS); } return ret; @@ -121,12 +130,10 @@ namespace corsika::process { bool CheckStep() { bool ret = false; - if constexpr (std::is_base_of<StackProcess<T1type>, T1type>::value || - is_process_sequence<T1>::value) { + if constexpr (std::is_base_of_v<StackProcess<T1type>, T1type> || t1ProcSeq) { ret |= A.CheckStep(); } - if constexpr (std::is_base_of<StackProcess<T2type>, T2type>::value || - is_process_sequence<T2>::value) { + if constexpr (std::is_base_of_v<StackProcess<T2type>, T2type> || t2ProcSeq) { ret |= B.CheckStep(); } return ret; @@ -135,12 +142,10 @@ namespace corsika::process { template <typename TStack> EProcessReturn DoStack(TStack& vS) { EProcessReturn ret = EProcessReturn::eOk; - if constexpr (std::is_base_of<StackProcess<T1type>, T1type>::value || - is_process_sequence<T1>::value) { + if constexpr (std::is_base_of_v<StackProcess<T1type>, T1type> || t1ProcSeq) { if (A.CheckStep()) { ret |= A.DoStack(vS); } } - if constexpr (std::is_base_of<StackProcess<T2type>, T2type>::value || - is_process_sequence<T2>::value) { + if constexpr (std::is_base_of_v<StackProcess<T2type>, T2type> || t2ProcSeq) { if (B.CheckStep()) { ret |= B.DoStack(vS); } } return ret; @@ -152,13 +157,11 @@ namespace corsika::process { max_length = // if no other process in the sequence implements it std::numeric_limits<double>::infinity() * corsika::units::si::meter; - if constexpr (std::is_base_of<ContinuousProcess<T1type>, T1type>::value || - is_process_sequence<T1>::value) { + if constexpr (std::is_base_of_v<ContinuousProcess<T1type>, T1type> || t1ProcSeq) { corsika::units::si::LengthType const len = A.MaxStepLength(vP, vTrack); max_length = std::min(max_length, len); } - if constexpr (std::is_base_of<ContinuousProcess<T2type>, T2type>::value || - is_process_sequence<T2>::value) { + if constexpr (std::is_base_of_v<ContinuousProcess<T2type>, T2type> || t2ProcSeq) { corsika::units::si::LengthType const len = B.MaxStepLength(vP, vTrack); max_length = std::min(max_length, len); } @@ -182,12 +185,10 @@ namespace corsika::process { InverseGrammageType tot = 0 * meter * meter / gram; - if constexpr (std::is_base_of_v<InteractionProcess<T1type>, T1type> || - is_process_sequence_v<T1>) { + if constexpr (std::is_base_of_v<InteractionProcess<T1type>, T1type> || t1ProcSeq) { tot += A.GetInverseInteractionLength(vP); } - if constexpr (std::is_base_of_v<InteractionProcess<T2type>, T2type> || - is_process_sequence_v<T2>) { + if constexpr (std::is_base_of_v<InteractionProcess<T2type>, T2type> || t2ProcSeq) { tot += B.GetInverseInteractionLength(vP); } return tot; @@ -199,13 +200,13 @@ namespace corsika::process { [[maybe_unused]] corsika::units::si::InverseGrammageType lambda_select, 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 const EProcessReturn ret = A.SelectInteraction(vP, vS, lambda_select, lambda_inv_count); // if A did succeed, stop routine 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 lambda_inv_count += A.GetInverseInteractionLength(vP); // check if we should execute THIS process and then EXIT @@ -215,13 +216,13 @@ namespace corsika::process { } } // end branch A - if constexpr (is_process_sequence<T2>::value) { + if constexpr (t2ProcSeq) { // if A is a process sequence --> check inside const EProcessReturn ret = B.SelectInteraction(vP, vS, lambda_select, lambda_inv_count); // if A did succeed, stop routine 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 lambda_inv_count += B.GetInverseInteractionLength(vP); // check if we should execute THIS process and then EXIT @@ -249,12 +250,10 @@ namespace corsika::process { corsika::units::si::InverseTimeType tot = 0 / second; - if constexpr (std::is_base_of<DecayProcess<T1type>, T1type>::value || - is_process_sequence<T1>::value) { + if constexpr (std::is_base_of_v<DecayProcess<T1type>, T1type> || t1ProcSeq) { tot += A.GetInverseLifetime(p); } - if constexpr (std::is_base_of<DecayProcess<T2type>, T2type>::value || - is_process_sequence<T2>::value) { + if constexpr (std::is_base_of_v<DecayProcess<T2type>, T2type> || t2ProcSeq) { tot += B.GetInverseLifetime(p); } return tot; @@ -266,12 +265,12 @@ namespace corsika::process { TParticle& vP, TSecondaries& vS, [[maybe_unused]] corsika::units::si::InverseTimeType decay_select, 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 const EProcessReturn ret = A.SelectDecay(vP, vS, decay_select, decay_inv_count); // if A did succeed, stop routine 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 decay_inv_count += A.GetInverseLifetime(vP); // check if we should execute THIS process and then EXIT @@ -282,12 +281,12 @@ namespace corsika::process { } } // end branch A - if constexpr (is_process_sequence<T2>::value) { + if constexpr (t2ProcSeq) { // if A is a process sequence --> check inside const EProcessReturn ret = B.SelectDecay(vP, vS, decay_select, decay_inv_count); // if A did succeed, stop routine 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 decay_inv_count += B.GetInverseLifetime(vP); // check if we should execute THIS process and then EXIT @@ -320,9 +319,7 @@ namespace corsika::process { /// marker to identify objectas ProcessSequence template <typename A, typename B> - struct is_process_sequence<corsika::process::ProcessSequence<A, B> > { - static const bool value = true; - }; + struct is_process_sequence<corsika::process::ProcessSequence<A, B>> : std::true_type {}; } // namespace corsika::process diff --git a/Processes/SwitchProcess/SwitchProcess.h b/Processes/SwitchProcess/SwitchProcess.h index 85d614109..31e59599b 100644 --- a/Processes/SwitchProcess/SwitchProcess.h +++ b/Processes/SwitchProcess/SwitchProcess.h @@ -17,8 +17,7 @@ namespace corsika::process::switch_process { */ template <class TLowEProcess, class THighEProcess> - class SwitchProcess - : public InteractionProcess<SwitchProcess<TLowEProcess, THighEProcess>> { + class SwitchProcess : public BaseProcess<SwitchProcess<TLowEProcess, THighEProcess>> { TLowEProcess& fLowEProcess; THighEProcess& fHighEProcess; units::si::HEPEnergyType const fThresholdEnergy; @@ -35,6 +34,11 @@ namespace corsika::process::switch_process { fHighEProcess.Init(); } + template <typename TParticle> + corsika::units::si::InverseGrammageType GetInverseInteractionLength(TParticle& p) { + return 1 / GetInteractionLength(p); + } + template <typename TParticle> units::si::GrammageType GetInteractionLength(TParticle& vParticle) { if (vParticle.GetEnergy() < fThresholdEnergy) { @@ -60,26 +64,35 @@ namespace corsika::process::switch_process { TParticle& vP, TSecondaries& vS, [[maybe_unused]] corsika::units::si::InverseGrammageType lambda_select, corsika::units::si::InverseGrammageType& lambda_inv_count) { - if (vP.GetEnergy() < fThresholdEnergy) { if constexpr (is_process_sequence_v<TLowEProcess>) { return fLowEProcess.SelectInteraction(vP, vS, lambda_select, lambda_inv_count); } 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 { if constexpr (is_process_sequence_v<THighEProcess>) { return fHighEProcess.SelectInteraction(vP, vS, lambda_select, lambda_inv_count); } 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 -template <typename A, typename B> -struct corsika::process::is_process_sequence< - corsika::process::switch_process::SwitchProcess<A, B>> : std::true_type {}; - #endif -- GitLab