diff --git a/Documentation/Examples/staticsequence_example.cc b/Documentation/Examples/staticsequence_example.cc index 1038e06370c5b1af4d7a2572169139a7d0c96ae5..306c3567ed210daed7787a4f3a7fbdd896aa9e55 100644 --- a/Documentation/Examples/staticsequence_example.cc +++ b/Documentation/Examples/staticsequence_example.cc @@ -25,43 +25,43 @@ using namespace std; const int nData = 10; -class Process1 : public BaseProcess { +class Process1 : public ContinuousProcess<Process1> { public: Process1() {} - template <typename D, typename T, typename S> - EProcessReturn DoContinuous(D& d, T&, S&) const { + template <typename D, typename T> + EProcessReturn DoContinuous(D& d, T&) const { for (int i = 0; i < nData; ++i) d.p[i] += 1; return EProcessReturn::eOk; } }; -class Process2 : public BaseProcess { +class Process2 : public ContinuousProcess<Process2> { public: Process2() {} - template <typename D, typename T, typename S> - inline EProcessReturn DoContinuous(D& d, T&, S&) const { + template <typename D, typename T> + inline EProcessReturn DoContinuous(D& d, T&) const { for (int i = 0; i < nData; ++i) d.p[i] -= 0.1 * i; return EProcessReturn::eOk; } }; -class Process3 : public BaseProcess { +class Process3 : public ContinuousProcess<Process3> { public: Process3() {} - template <typename D, typename T, typename S> - inline EProcessReturn DoContinuous(D&, T&, S&) const { + template <typename D, typename T> + inline EProcessReturn DoContinuous(D&, T&) const { return EProcessReturn::eOk; } }; -class Process4 : public BaseProcess { +class Process4 : public ContinuousProcess<Process4> { public: Process4(const double v) : fV(v) {} - template <typename D, typename T, typename S> - inline EProcessReturn DoContinuous(D& d, T&, S&) const { + template <typename D, typename T> + inline EProcessReturn DoContinuous(D& d, T&) const { for (int i = 0; i < nData; ++i) d.p[i] *= fV; return EProcessReturn::eOk; } diff --git a/Framework/ProcessSequence/BaseProcess.h b/Framework/ProcessSequence/BaseProcess.h index f559a77c3b4f3a0dcc5facae289b0393f4f85a2e..e397d70b26358aaaba514f6ef3941844f1788187 100644 --- a/Framework/ProcessSequence/BaseProcess.h +++ b/Framework/ProcessSequence/BaseProcess.h @@ -23,6 +23,13 @@ namespace corsika::process { */ struct BaseProcess { + static constexpr bool is_boundary_crossing = false; + static constexpr bool is_continuous = false; + static constexpr bool is_decay = false; + static constexpr bool is_interaction = false; + static constexpr bool is_secondaries = false; + static constexpr bool is_stack = false; + void Init() {} // override this in derived }; diff --git a/Framework/ProcessSequence/BoundaryCrossingProcess.h b/Framework/ProcessSequence/BoundaryCrossingProcess.h index 5b7f6ec62f7192112334d86005280a763ad0e929..48618c695390bbcca939b3de25446533bcf1e40c 100644 --- a/Framework/ProcessSequence/BoundaryCrossingProcess.h +++ b/Framework/ProcessSequence/BoundaryCrossingProcess.h @@ -20,6 +20,7 @@ namespace corsika::process { template <typename TDerived> struct BoundaryCrossingProcess : BaseProcess { + static constexpr bool is_boundary_crossing = true; /** * This method is called when a particle crosses the boundary between the nodes diff --git a/Framework/ProcessSequence/CMakeLists.txt b/Framework/ProcessSequence/CMakeLists.txt index a6c2a1701fccba3090b5376a2856090a97a3ae7e..8d2774a944dd6209f9f5ee3328a25776ef6dd192 100644 --- a/Framework/ProcessSequence/CMakeLists.txt +++ b/Framework/ProcessSequence/CMakeLists.txt @@ -17,6 +17,7 @@ set ( StackProcess.h DecayProcess.h ProcessSequence.h + ConditionalProcessSequence.h ProcessReturn.h ) @@ -47,9 +48,17 @@ target_link_libraries ( CORSIKA_ADD_TEST (testProcessSequence) target_link_libraries ( testProcessSequence - ProcessSwitch CORSIKAsetup CORSIKAgeometry CORSIKAprocesssequence CORSIKAtesting ) + + CORSIKA_ADD_TEST (testConditionalProcessSequence) + target_link_libraries ( + testConditionalProcessSequence + CORSIKAsetup + CORSIKAgeometry + CORSIKAprocesssequence + CORSIKAtesting + ) diff --git a/Framework/ProcessSequence/ConditionalProcessSequence.h b/Framework/ProcessSequence/ConditionalProcessSequence.h index 9766ac1c2a60d12b6cfc3057b899aac26890f9bc..1c81b4561bce1e48f486db532a3d82ba7ffe35c5 100644 --- a/Framework/ProcessSequence/ConditionalProcessSequence.h +++ b/Framework/ProcessSequence/ConditionalProcessSequence.h @@ -14,16 +14,26 @@ #include <corsika/process/ProcessReturn.h> #include <corsika/process/ProcessSequence.h> #include <corsika/units/PhysicalUnits.h> +#include <boost/mp11.hpp> +#include <type_traits> namespace corsika::process { - template <class TPredicate, class... Ts, class... Us> + template <class TPredicate, class TSeq, class USeq> class ConditionalProcessSequence { using predicate_t = TPredicate; - using true_seq_t = ProcessSequence<Ts...>; - using false_seq_t = ProcessSequence<Us...>; + using true_seq_t = TSeq; + using false_seq_t = USeq; public: + static constexpr bool is_boundary_crossing = + TSeq::is_boundary_crossing || USeq::is_boundary_crossing; + static constexpr bool is_continuous = TSeq::is_continuous || USeq::is_continuous; + static constexpr bool is_decay = TSeq::is_decay || USeq::is_decay; + static constexpr bool is_interaction = TSeq::is_interaction || USeq::is_interaction; + static constexpr bool is_secondaries = TSeq::is_secondaries || USeq::is_secondaries; + static constexpr bool is_stack = TSeq::is_stack || USeq::is_stack; + template <class TPredicate_, class TTrueSeq, class TFalseSeq> ConditionalProcessSequence(TPredicate_&& pred, TTrueSeq&& true_seq, TFalseSeq&& false_seq) @@ -116,8 +126,8 @@ namespace corsika::process { EProcessReturn SelectDecay(TParticle& vP, TSecondaries& vS, corsika::units::si::InverseTimeType decay_select, corsika::units::si::InverseTimeType& decay_inv_count) { - return pred_(vP) ? true_seq_.SelectDecay(vP, vS, lambda_select, lambda_inv_count) - : false_seq_.SelectDecay(vP, vS, lambda_select, lambda_inv_count); + return pred_(vP) ? true_seq_.SelectDecay(vP, vS, decay_select, decay_inv_count) + : false_seq_.SelectDecay(vP, vS, decay_select, decay_inv_count); } // TODO: this should be removed along with all Init() functions of the processes @@ -132,6 +142,37 @@ namespace corsika::process { false_seq_t false_seq_; }; + // deduction guides + template <class P, class T, class U> + ConditionalProcessSequence(P&&, T&&, U &&) + ->ConditionalProcessSequence< + P, boost::mp11::mp_rename<std::decay_t<T>, ProcessSequence>, + boost::mp11::mp_rename<std::decay_t<U>, ProcessSequence>>; + + // template <class T, class U> + // ConditionalProcessSequence(corsika::units::si::HEPEnergyType, T&&, U &&) + // ->ConditionalProcessSequence< + // ByThreshold, boost::mp11::mp_rename<std::decay_t<T>, ProcessSequence>, + // boost::mp11::mp_rename<std::decay_t<U>, ProcessSequence>>; + + struct EnergyThreshold { + EnergyThreshold(corsika::units::si::HEPEnergyType x) + : value{x} {} + + template <class T> + bool operator()(const T& t) const { + return t.GetEnergy() > value; + } + + corsika::units::si::HEPEnergyType value; + }; + + template <class... Ts, class... Us> + ConditionalProcessSequence(corsika::units::si::HEPEnergyType, + const ProcessSequence<Ts...>&, const ProcessSequence<Us...>&) + ->ConditionalProcessSequence<EnergyThreshold, ProcessSequence<Ts...>, + ProcessSequence<Us...>>; + } // namespace corsika::process #endif \ No newline at end of file diff --git a/Framework/ProcessSequence/ContinuousProcess.h b/Framework/ProcessSequence/ContinuousProcess.h index d1f9a8b542e4079f06d7896c76ce5a18f3af43e7..c81c510ee6719607c5485c69efe4acf364d490dd 100644 --- a/Framework/ProcessSequence/ContinuousProcess.h +++ b/Framework/ProcessSequence/ContinuousProcess.h @@ -28,6 +28,7 @@ namespace corsika::process { template <typename TDerived> struct ContinuousProcess : BaseProcess { + static constexpr bool is_continuous = true; // enforce TDerived to implement this template <typename Particle, typename Track> diff --git a/Framework/ProcessSequence/DecayProcess.h b/Framework/ProcessSequence/DecayProcess.h index 0cc3aa754e460d3b4750a3b744599a99fb4bc54c..b98dc8a5d4dc4bef055a8384cf689d6d238d5455 100644 --- a/Framework/ProcessSequence/DecayProcess.h +++ b/Framework/ProcessSequence/DecayProcess.h @@ -29,6 +29,7 @@ namespace corsika::process { template <typename TDerived> struct DecayProcess : BaseProcess { + static constexpr bool is_decay = true; // enforce TDerived to implement this template <typename TParticle> diff --git a/Framework/ProcessSequence/InteractionProcess.h b/Framework/ProcessSequence/InteractionProcess.h index c3398a9a8ce73af30d66a6d382a729fb5313ded1..49907064987bcd8324aa12b87bfaa330a941101a 100644 --- a/Framework/ProcessSequence/InteractionProcess.h +++ b/Framework/ProcessSequence/InteractionProcess.h @@ -29,6 +29,7 @@ namespace corsika::process { template <typename TDerived> struct InteractionProcess : BaseProcess { + static constexpr bool is_interaction = true; // enforce TDerived to implement this template <typename TParticle> diff --git a/Framework/ProcessSequence/ProcessSequence.h b/Framework/ProcessSequence/ProcessSequence.h index 24f44d43a05f39bdc4c9535a5230eefe011c2b01..69a610d25690f0b82d9c1543a2840464b01a0bc4 100644 --- a/Framework/ProcessSequence/ProcessSequence.h +++ b/Framework/ProcessSequence/ProcessSequence.h @@ -44,54 +44,72 @@ namespace corsika::process { // marker to track whether some T is a process template <class T> - constexpr bool is_process_v = std::is_base_of_v<BaseProcess, T>; + constexpr bool is_process_v = + T::is_boundary_crossing || T::is_continuous || T::is_decay || T::is_interaction || + T::is_secondaries || T::is_stack; - // forward declare ProcessSequence for is_process_sequence - template <class... Ts> - class ProcessSequence; + template <class T> + struct has_boundary_crossing_trait { + static constexpr bool value = T::is_boundary_crossing; + }; - // forward declare ConditionalProcessSequence for is_process_sequence - template <class... Ts> - class ConditionalProcessSequence; + template <class T> + struct has_continuous_trait { + static constexpr bool value = T::is_continuous; + }; template <class T> - struct is_process_sequence : std::false_type {}; + struct has_decay_trait { + static constexpr bool value = T::is_decay; + }; - template <class... Ts> - struct is_process_sequence<ProcessSequence<Ts...>> : std::true_type {}; + template <class T> + struct has_interaction_trait { + static constexpr bool value = T::is_interaction; + }; - template <class... Ts> - struct is_process_sequence<ConditionalProcessSequence<Ts...>> : std::true_type {}; + template <class T> + struct has_secondaries_trait { + static constexpr bool value = T::is_secondaries; + }; template <class T> - constexpr bool is_process_sequence_v = is_process_sequence<T>::value; + struct has_stack_trait { + static constexpr bool value = T::is_stack; + }; template <class... Ts> class ProcessSequence : public std::tuple<Ts...> { using storage_t = std::tuple<Ts...>; public: + static constexpr bool is_boundary_crossing = + (... || has_boundary_crossing_trait<std::decay_t<Ts>>::value); + static constexpr bool is_continuous = + (... || has_continuous_trait<std::decay_t<Ts>>::value); + static constexpr bool is_decay = (... || has_decay_trait<std::decay_t<Ts>>::value); + static constexpr bool is_interaction = + (... || has_interaction_trait<std::decay_t<Ts>>::value); + static constexpr bool is_secondaries = + (... || has_secondaries_trait<std::decay_t<Ts>>::value); + static constexpr bool is_stack = (... || has_stack_trait<std::decay_t<Ts>>::value); + template <class... Us> ProcessSequence(Us&&... us) : storage_t(std::forward<Us>(us)...) { - static_assert((... && (is_process_v<std::decay_t<Us>> || - is_process_sequence_v<std::decay_t<Us>>)), - "all arguments must be processes or other process sequences"); + static_assert((... && is_process_v<std::decay_t<Us>>), + "all arguments must be processes"); } // example for a trait-based call: // void Hello() const { detail::CallHello<T1,T2>::Call(A, B); } - template <template <class> class Base, class Functor> + template <template <class> class Trait, class Functor> void for_each(Functor&& functor) { boost::mp11::tuple_for_each(static_cast<storage_t&>(*this), [&](auto&& x) { - using T = std::decay_t<decltype(x)>; // if x is the right kind of Process, run the functor on the Process - if constexpr (std::is_base_of_v<Base<T>, T>) + if constexpr (Trait<std::decay_t<decltype(x)>>::value) std::forward<Functor>(functor)(std::forward<decltype(x)>(x)); - // if x is a nested process sequence, run the nested for_each loop - if constexpr (is_process_sequence_v<T>) - x.template for_each<Base>(std::forward<Functor>(functor)); }); } @@ -99,7 +117,7 @@ namespace corsika::process { EProcessReturn DoBoundaryCrossing(Particle& p, VTNType const& from, VTNType const& to) { EProcessReturn ret = EProcessReturn::eOk; - for_each<BoundaryCrossingProcess>( + for_each<has_boundary_crossing_trait>( [&](auto&& proc) { ret |= proc.DoBoundaryCrossing(p, from, to); }); return ret; } @@ -107,14 +125,16 @@ namespace corsika::process { template <typename TParticle, typename TTrack> EProcessReturn DoContinuous(TParticle& vP, TTrack& vT) { EProcessReturn ret = EProcessReturn::eOk; - for_each<ContinuousProcess>([&](auto&& proc) { ret |= proc.DoContinuous(vP, vT); }); + for_each<has_continuous_trait>( + [&](auto&& proc) { ret |= proc.DoContinuous(vP, vT); }); return ret; } template <typename TSecondaries> EProcessReturn DoSecondaries(TSecondaries& vS) { EProcessReturn ret = EProcessReturn::eOk; - for_each<SecondariesProcess>([&](auto&& proc) { ret |= proc.DoSecondaries(vS); }); + for_each<has_secondaries_trait>( + [&](auto&& proc) { ret |= proc.DoSecondaries(vS); }); return ret; } @@ -128,7 +148,7 @@ namespace corsika::process { */ bool CheckStep() { bool ret = false; - for_each<StackProcess>([&](auto&& proc) { ret |= proc.CheckStep(); }); + for_each<has_stack_trait>([&](auto&& proc) { ret |= proc.CheckStep(); }); return ret; } @@ -138,7 +158,7 @@ namespace corsika::process { template <typename TStack> EProcessReturn DoStack(TStack& vS) { EProcessReturn ret = EProcessReturn::eOk; - for_each<StackProcess>([&](auto&& proc) { + for_each<has_stack_trait>([&](auto&& proc) { if (proc.CheckStep()) ret |= proc.DoStack(vS); }); return ret; @@ -150,7 +170,7 @@ namespace corsika::process { // infinite if no other process in the sequence implements it LengthType max_length = std::numeric_limits<double>::infinity() * meter; - for_each<ContinuousProcess>([&](auto&& proc) { + for_each<has_continuous_trait>([&](auto&& proc) { const auto len = proc.MaxStepLength(vP, vTrack); if (len < max_length) max_length = len; }); @@ -173,7 +193,7 @@ namespace corsika::process { using namespace corsika::units::si; InverseGrammageType tot = 0 * meter * meter / gram; - for_each<InteractionProcess>( + for_each<has_interaction_trait>( [&](auto&& proc) { tot += proc.GetInverseInteractionLength(vP); }); return tot; } @@ -192,7 +212,7 @@ namespace corsika::process { corsika::units::si::InverseTimeType GetInverseLifetime(TParticle& p) { using namespace corsika::units::si; InverseTimeType tot = 0 / second; - for_each<DecayProcess>([&](auto&& proc) { tot += proc.GetInverseLifetime(p); }); + for_each<has_decay_trait>([&](auto&& proc) { tot += proc.GetInverseLifetime(p); }); return tot; } @@ -203,7 +223,7 @@ namespace corsika::process { corsika::units::si::InverseGrammageType lambda_select, corsika::units::si::InverseGrammageType& lambda_inv_count) { EProcessReturn ret = EProcessReturn::eOk; - for_each<InteractionProcess>([&](auto&& proc) { + for_each<has_interaction_trait>([&](auto&& proc) { // check if we should execute THIS process and then EXIT if (ret == EProcessReturn::eOk) { // if this is not a ContinuousProcess --> evaluate probability @@ -223,7 +243,7 @@ namespace corsika::process { corsika::units::si::InverseTimeType decay_select, corsika::units::si::InverseTimeType& decay_inv_count) { EProcessReturn ret = EProcessReturn::eOk; - for_each<DecayProcess>([&](auto&& proc) { + for_each<has_decay_trait>([&](auto&& proc) { // check if we should execute THIS process and then skip all others if (ret == EProcessReturn::eOk) { // if this is not a ContinuousProcess --> evaluate probability @@ -244,13 +264,11 @@ namespace corsika::process { } }; - // deduction guide: lvalue references are stored as references - template <class... Ts> - ProcessSequence(Ts&... ts)->ProcessSequence<Ts&...>; - - // deduction guide: rvalue references are stored as values + // deduction guide: store lvalue references as references, rvalue references as values template <class... Ts> - ProcessSequence(Ts&&... ts)->ProcessSequence<Ts...>; + ProcessSequence(Ts&&... ts) + ->ProcessSequence< + boost::mp11::mp_if<std::is_rvalue_reference<Ts>, std::decay_t<Ts>, Ts>...>; } // namespace corsika::process diff --git a/Framework/ProcessSequence/SecondariesProcess.h b/Framework/ProcessSequence/SecondariesProcess.h index 5b90e2917d5d2364b3df15d758bebb981fb6af1b..df2a11cf5e27e654ee834ed963377beec60ad640 100644 --- a/Framework/ProcessSequence/SecondariesProcess.h +++ b/Framework/ProcessSequence/SecondariesProcess.h @@ -29,6 +29,7 @@ namespace corsika::process { template <typename TDerived> struct SecondariesProcess : BaseProcess { + static constexpr bool is_secondaries = true; // enforce TDerived to implement this template <typename TSecondaries> diff --git a/Framework/ProcessSequence/StackProcess.h b/Framework/ProcessSequence/StackProcess.h index 5a4e1943c200b4a5744fa43c5dd2475392dbf842..a3f3558dfaa8c462edd3293df86b33f312a6ede8 100644 --- a/Framework/ProcessSequence/StackProcess.h +++ b/Framework/ProcessSequence/StackProcess.h @@ -29,6 +29,7 @@ namespace corsika::process { template <typename TDerived> struct StackProcess : BaseProcess { + static constexpr bool is_stack = true; StackProcess() = delete; StackProcess(const unsigned int nStep) diff --git a/Framework/ProcessSequence/testConditionalProcessSequence.cc b/Framework/ProcessSequence/testConditionalProcessSequence.cc new file mode 100644 index 0000000000000000000000000000000000000000..8961360f1841d962d54ce13dd2d2094939576fbd --- /dev/null +++ b/Framework/ProcessSequence/testConditionalProcessSequence.cc @@ -0,0 +1,129 @@ +/* + * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu + * + * See file AUTHORS for a list of contributors. + * + * This software is distributed under the terms of the GNU General Public + * Licence version 3 (GPL Version 3). See file LICENSE for a full version of + * the license. + */ + +#include <catch2/catch.hpp> + +#include <corsika/process/ConditionalProcessSequence.h> +#include <corsika/process/ProcessSequence.h> +#include <corsika/units/PhysicalUnits.h> +#include <tuple> +#include <vector> + +using namespace corsika; +using namespace corsika::units::si; +using namespace corsika::process; +using namespace std; + +auto constexpr kgMSq = 1_kg / (1_m * 1_m); + +template <int N> +struct DummyProcess : InteractionProcess<DummyProcess<N>> { + void Init() {} + + template <typename TParticle> + corsika::units::si::GrammageType GetInteractionLength(TParticle const&) const { + return N * kgMSq; + } + + template <typename TSecondaries> + corsika::process::EProcessReturn DoInteraction(TSecondaries& vSec) { + // to figure out which process was selected in the end, we produce N + // secondaries for DummyProcess<N> + + for (int i = 0; i < N; ++i) { + vSec.AddSecondary(std::tuple<HEPEnergyType>{vSec.GetEnergy() / N}); + } + + return EProcessReturn::eOk; + } +}; + +template <class T> +struct DummySecondaries : std::vector<T> { + void AddSecondary(T&& t) { std::vector<T>::push_back(t); } +}; + +struct DummyParticle { + DummyParticle(corsika::units::si::HEPEnergyType e) + : energy(e) {} + + corsika::units::si::HEPEnergyType GetEnergy() const { return energy; } + + corsika::units::si::HEPEnergyType energy; +}; + +TEST_CASE("ConditionalProcessSequence") { + DummyProcess<1> true_A; + DummyProcess<2> true_B; + DummyProcess<3> false_P; + DummyProcess<4> additional; + + ConditionalProcessSequence<EnergyThreshold, + ProcessSequence<DummyProcess<1>&, DummyProcess<2>&>, + ProcessSequence<DummyProcess<3>&>> + cseq(1_TeV, ProcessSequence(true_A, true_B), false_P); + ProcessSequence seq(cseq, additional); + + SECTION("low energy") { + auto p = DummyParticle{0.5_TeV}; + + SECTION("interaction length") { + REQUIRE(cseq.GetTotalInteractionLength(p) / kgMSq == Approx(2. / 3)); + REQUIRE(seq.GetTotalInteractionLength(p) / kgMSq == Approx(4. / 7)); + } + + // SECTION("SelectInteraction") { + // DummySecondaries<DummyParticle> secondaries; + // + // InverseGrammageType invLambda = r * 7. / 4 / kgMSq; + // InverseGrammageType accumulator = 0 / kgMSq; + // seq.SelectInteraction(p, secondaries, invLambda, accumulator); + // + // REQUIRE(secondaries.size(), 7); + // + // const auto mean = std::accumulate(secondaries.begin(), secondaries.end(), 0.) / + // secondaries.size(); + // REQUIRE(mean == Approx(12. / 7.).margin(0.01)); + // } + } + + SECTION("high energy") { + auto p = DummyParticle{3_TeV}; + + SECTION("interaction length") { + REQUIRE(cseq.GetTotalInteractionLength(p) / kgMSq == Approx(3)); + REQUIRE(seq.GetTotalInteractionLength(p) / kgMSq == Approx(12. / 7.)); + } + + // SECTION("SelectInteraction") { + // std::vector<int> numberOfSecondaries; + // + // for (int i = 0; i < 1000; ++i) { + // typename SimpleStack::DummyParticle theParticle = + // stack.GetNextParticle(); // as in corsika::Cascade + // StackTestView view(theParticle); + // auto projectile = view.GetProjectile(); + // + // double r = i / 1000.; + // InverseGrammageType invLambda = r * 7. / 12. / kgMSq; + // + // InverseGrammageType accumulator = 0 / kgMSq; + // completeSeq.SelectInteraction(p, projectile, invLambda, accumulator); + // + // numberOfSecondaries.push_back(view.GetSize()); + // } + // + // auto const mean = + // std::accumulate(numberOfSecondaries.cbegin(), numberOfSecondaries.cend(), 0.) + // / numberOfSecondaries.size(); + // REQUIRE(mean == Approx(24. / 7.).margin(0.01)); + // } + } +} diff --git a/Framework/ProcessSequence/testProcessSequence.cc b/Framework/ProcessSequence/testProcessSequence.cc index 0b8c95e4a6ce6ba1cbb7411ca8350c28d01ff0f5..ec0baa2dccb7fe467488e645fc676ed2e60bd81e 100644 --- a/Framework/ProcessSequence/testProcessSequence.cc +++ b/Framework/ProcessSequence/testProcessSequence.cc @@ -15,7 +15,6 @@ #include <iostream> #include <corsika/process/ProcessSequence.h> -#include <corsika/process/switch_process/SwitchProcess.h> using namespace corsika; using namespace corsika::units::si; @@ -132,6 +131,9 @@ class Process4 : public BaseProcess { int fV = 0; public: + static constexpr bool is_continuous = true; + static constexpr bool is_interaction = true; + Process4(const int v) : fV(v) {} void Init() { diff --git a/Processes/NullModel/NullModel.cc b/Processes/NullModel/NullModel.cc index 2e2861dc9375d3340dd4da1c56459b654fc463dd..10c678cb620c1981c1f57fcb7dcbf55d282de6dc 100644 --- a/Processes/NullModel/NullModel.cc +++ b/Processes/NullModel/NullModel.cc @@ -20,16 +20,4 @@ namespace corsika::process::null_model { NullModel::NullModel(units::si::LengthType maxStepLength) : fMaxStepLength(maxStepLength) {} - template <> - process::EProcessReturn NullModel::DoContinuous(setup::Stack::ParticleType&, - setup::Trajectory&) const { - return process::EProcessReturn::eOk; - } - - template <> - units::si::LengthType NullModel::MaxStepLength(setup::Stack::ParticleType&, - setup::Trajectory&) const { - return fMaxStepLength; - } - } // namespace corsika::process::null_model diff --git a/Processes/NullModel/NullModel.h b/Processes/NullModel/NullModel.h index a46e47ecd8121602cf31dd7137ccc991d5b43594..55cbba7f887d56934e6289cb691317af962ecf39 100644 --- a/Processes/NullModel/NullModel.h +++ b/Processes/NullModel/NullModel.h @@ -20,16 +20,22 @@ namespace corsika::process::null_model { corsika::units::si::LengthType const fMaxStepLength; public: + static constexpr bool is_continuous = true; + NullModel(corsika::units::si::LengthType maxStepLength = corsika::units::si::meter * std::numeric_limits<double>::infinity()); void Init(); template <typename Particle, typename Track> - process::EProcessReturn DoContinuous(Particle&, Track&) const; + process::EProcessReturn DoContinuous(Particle&, Track&) const { + return process::EProcessReturn::eOk; + } template <typename Particle, typename Track> - corsika::units::si::LengthType MaxStepLength(Particle&, Track&) const; + corsika::units::si::LengthType MaxStepLength(Particle&, Track&) const { + return fMaxStepLength; + } }; } // namespace corsika::process::null_model