diff --git a/Framework/ProcessSequence/BoundaryCrossingProcess.h b/Framework/ProcessSequence/BoundaryCrossingProcess.h index dca9243a57665efe6aa462da902c5b21eea5f81d..feee4d0db95a74891c80fd84e52ef8c95687fc25 100644 --- a/Framework/ProcessSequence/BoundaryCrossingProcess.h +++ b/Framework/ProcessSequence/BoundaryCrossingProcess.h @@ -18,6 +18,8 @@ namespace corsika::process { private: protected: public: + using _TDerived = TDerived; + /** * This method is called when a particle crosses the boundary between the nodes * \p from and \p to. diff --git a/Framework/ProcessSequence/ContinuousProcess.h b/Framework/ProcessSequence/ContinuousProcess.h index 7a03d4d4a4504e95467c510131641e1693af761a..546f368b2f2d677de5faf61fe3660e48956cca21 100644 --- a/Framework/ProcessSequence/ContinuousProcess.h +++ b/Framework/ProcessSequence/ContinuousProcess.h @@ -24,10 +24,11 @@ namespace corsika::process { */ template <typename TDerived> - class ContinuousProcess : public BaseProcess<TDerived>{ + class ContinuousProcess : public BaseProcess<TDerived> { private: protected: - public: + public: + using TDerived = derived; // here starts the interface part // -> enforce TDerived to implement DoContinuous... diff --git a/Framework/ProcessSequence/DecayProcess.h b/Framework/ProcessSequence/DecayProcess.h index d3f66f6d69ec60e1d738889f5d1214a8d737d0d9..55d1ce7f5c25d7d64dd3870d977ecb265eb38adc 100644 --- a/Framework/ProcessSequence/DecayProcess.h +++ b/Framework/ProcessSequence/DecayProcess.h @@ -26,8 +26,8 @@ namespace corsika::process { template <typename TDerived> class DecayProcess : BaseProcess<TDerived> { - public: - + public: + using _TDerived = TDerived; using BaseProcess<TDerived>::GetRef; /// here starts the interface-definition part diff --git a/Processes/DevTools/Analytics/CMakeLists.txt b/Processes/DevTools/Analytics/CMakeLists.txt index 54acad48446f98f9bb31b0e80e4d75704193bee4..4221754280c4917dff85b5c4c325d2a8fbbd2f88 100644 --- a/Processes/DevTools/Analytics/CMakeLists.txt +++ b/Processes/DevTools/Analytics/CMakeLists.txt @@ -50,6 +50,7 @@ CORSIKA_ADD_TEST (testExecTime testExecTime.cc) target_link_libraries ( testExecTime ProcessDevTools CORSIKAsetup + DevTools_Dummy CORSIKAthirdparty # for catch2 ) diff --git a/Processes/DevTools/Analytics/ExecTime.h b/Processes/DevTools/Analytics/ExecTime.h index 81da08022cc89e5e5a9c78b5108c2599f9f5c4b4..033e7cc823cf47b0680149a1d42d408b3be83776 100644 --- a/Processes/DevTools/Analytics/ExecTime.h +++ b/Processes/DevTools/Analytics/ExecTime.h @@ -21,92 +21,118 @@ namespace corsika::process { namespace devtools { - template <class T> - class ExecTime : public T { - private: - void start(); - void stop(); + template <typename T, bool> + class ExecTime_BoundaryCrossing {}; - protected: + template <typename T> + class ExecTime_BoundaryCrossing<T, true> : protected T { public: - - float mean(); - float min(); - float max(); - float var(); - - /// Interface implementation - - // Boundary Crossing template < typename Particle, typename VTNType, typename std::enable_if_t< - std::is_base_of<BoundaryCrossingProcess<typename T::TDerived>, T>::type, int> = 0 > + std::is_base_of<BoundaryCrossingProcess<typename T::_TDerived>, T>::value, + int> = 0> EProcessReturn DoBoundaryCrossing(Particle& p, VTNType const& from, VTNType const& to) { return T::DoBoundaryCrossing(p, from, to); } + }; - // Continous - template <typename Particle, typename Track, - typename std::enable_if_t< - std::is_base_of<ContinuousProcess<typename T::TDerived>, T>::type, int> = 0> + template <typename T, bool> + class ExecTime_Continuous {}; + + template <typename T> + class ExecTime_Continuous<T, true> : protected T { + public: + template <typename Particle, typename Track> EProcessReturn DoContinuous(Particle& p, Track const& t) const { return T::DoContinous(p, t); } - template <typename Particle, typename Track, - typename std::enable_if_t< - std::is_base_of<ContinuousProcess<typename T::TDerived>, T>::type, int> = 0> + template <typename Particle, typename Track> units::si::LengthType MaxStepLength(Particle const& p, Track const& track) const { return T::MaxStepLength(p, track); } + }; + + template <typename T, bool> + class ExecTime_Decay {}; - // Decay - template <typename Particle, - typename std::enable_if_t< - std::is_base_of<DecayProcess<typename T::TDerived>, T>::type, int> = 0> + template <typename T> + class ExecTime_Decay<T, true> : protected T { + public: + template <typename Particle> EProcessReturn DoDecay(Particle& p) { return T::DoDecay(p); } - template <typename Particle, - typename std::enable_if_t< - std::is_base_of<DecayProcess<typename T::TDerived>, T>::type, int> = 0> + template <typename Particle> corsika::units::si::TimeType GetLifetime(Particle& p) { return T::GetLifetime(p); } + }; - // Interaction - template <typename Particle, - typename std::enable_if_t< - std::is_base_of<InteractionProcess<typename T::TDerived>, T>::type, int> = 0> + template <typename T, bool> + class ExecTime_Interaction {}; + + template <typename T> + class ExecTime_Interaction<T, true> : protected T { + public: + template <typename Particle> EProcessReturn DoInteraction(Particle& p) { return T::DoInteraction(p); } - template <typename TParticle, - typename std::enable_if_t< - std::is_base_of<InteractionProcess<typename T::TDerived>, T>::type, int> = 0> - corsika::units::si::GrammageType GetInteractionLength(TParticle& p) { + template <typename Particle> + corsika::units::si::GrammageType GetInteractionLength(Particle& p) { return T::GetInteractionLength(p); } + }; - // Secondaries - template <typename TSecondaries, - typename std::enable_if_t< - std::is_base_of<SecondariesProcess<typename T::TDerived>, T>::type, int> = 0> - inline EProcessReturn DoSecondaries(TSecondaries& sec) { + template <typename T, bool> + class ExecTime_Secondaries {}; + + template <typename T> + class ExecTime_Secondaries<T, true> : protected T { + public: + template <typename Secondaries> + inline EProcessReturn DoSecondaries(Secondaries& sec) { return T::DoSecondaries(sec); } + }; - // Stack - template <typename TStack, - typename std::enable_if_t< - std::is_base_of<StackProcess<typename T::TDerived>, T>::type, int> = 0> - inline EProcessReturn DoStack(TStack& stack) { - return T::stack(stack); - } + template <typename T> + class ExecTime + : public ExecTime_BoundaryCrossing< + T, + std::is_base_of<BoundaryCrossingProcess<typename T::_TDerived>, T>::value>, + public ExecTime_Continuous< + T, std::is_base_of<ContinuousProcess<typename T::_TDerived>, T>::value>, + public ExecTime_Decay<T, + std::is_base_of<DecayProcess<typename T::_TDerived>, T>::value>, + public ExecTime_Interaction< + T, std::is_base_of<InteractionProcess<typename T::_TDerived>, T>::value>, + public ExecTime_Secondaries< + T, std::is_base_of<SecondariesProcess<typename T::_TDerived>, T>::value> { + private: + void start(); + void stop(); + + protected: + public: + float mean(); + float min(); + float max(); + float var(); + + /* + // Stack + template < + typename TStack, + typename std::enable_if_t< + std::is_base_of<StackProcess<typename T::_TDerived>, T>::type, + int> = 0> inline EProcessReturn DoStack(TStack& stack) { return T::stack(stack); + }*/ }; } // namespace devtools } // namespace corsika::process \ No newline at end of file diff --git a/Processes/DevTools/Analytics/testExecTime.cc b/Processes/DevTools/Analytics/testExecTime.cc index 559ad8694fb0034460e98161562f535d7f50d330..853ccd2d277807f12ca20cf36acf22ee0ebdee27 100644 --- a/Processes/DevTools/Analytics/testExecTime.cc +++ b/Processes/DevTools/Analytics/testExecTime.cc @@ -12,12 +12,25 @@ #include <corsika/process/devtools/ExecTime.h> +#include <corsika/process/devtools/DummyBoundaryCrossingProcess.h> +#include <corsika/process/devtools/DummyContinuousProcess.h> +#include <corsika/process/devtools/DummyDecayProcess.h> +#include <corsika/process/devtools/DummyInteractionProcess.h> +#include <corsika/process/devtools/DummySecondariesProcess.h> +using namespace corsika::process; using namespace corsika::process::devtools; TEST_CASE("ContinuousProcess interface", "[proccesses][DevTools ExecTime]") { - - + ExecTime<DummyBoundaryCrossingProcess<100>> execTime; + int tmp = 0; + SECTION("BoundaryCrossing") { + auto start = std::chrono::steady_clock::now(); + REQUIRE(execTime.DoBoundaryCrossing(tmp, 0, 0) == EProcessReturn::eOk); + auto end = std::chrono::steady_clock::now(); + REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == + Approx(100).margin(1)); + } } diff --git a/Processes/DevTools/Dummy/DummyBoundaryCrossingProcess.h b/Processes/DevTools/Dummy/DummyBoundaryCrossingProcess.h index b39e25bc6416b2f3d870e2a3f0e6e4671eedf790..bafff176762745e01876ed8221d15d0f93fc0a4e 100644 --- a/Processes/DevTools/Dummy/DummyBoundaryCrossingProcess.h +++ b/Processes/DevTools/Dummy/DummyBoundaryCrossingProcess.h @@ -8,22 +8,23 @@ #pragma once +#include <corsika/process/BoundaryCrossingProcess.h> + #include <chrono> #include <thread> -#include <corsika/process/BoundaryCrossingProcess.h> - namespace corsika::process { namespace devtools { template <int ISleep> - class DummyBoundaryCrossingProcess : BoundaryCrossingProcess<DummyBoundaryCrossingProcess<ISleep>> { + class DummyBoundaryCrossingProcess + : public BoundaryCrossingProcess<DummyBoundaryCrossingProcess<ISleep>> { private: public: template <typename Particle, typename VTNType> EProcessReturn DoBoundaryCrossing(Particle&, VTNType const& from, VTNType const& to) { - std::this_thread::sleep_for( std::chrono::milliseconds(ISleep) ); + std::this_thread::sleep_for(std::chrono::milliseconds(ISleep)); return EProcessReturn::eOk; } }; diff --git a/Processes/DevTools/Dummy/DummyContinuousProcess.h b/Processes/DevTools/Dummy/DummyContinuousProcess.h index 9fa9ae645f13a1ba8ec7229a4b0920ea36a3ee17..32844732d63ed7bedb18466aab18940af019c4a9 100644 --- a/Processes/DevTools/Dummy/DummyContinuousProcess.h +++ b/Processes/DevTools/Dummy/DummyContinuousProcess.h @@ -8,29 +8,27 @@ #pragma once +#include <corsika/process/ContinuousProcess.h> + #include <chrono> #include <thread> -#include <corsika/process/ContinuousProcess.h> - namespace corsika::process { namespace devtools { template <int ISleep> - class DummyContinuousProcess : ContinuousProcess<DummyContinuousProcess<ISleep>> { + class DummyContinuousProcess : public ContinuousProcess<DummyContinuousProcess<ISleep>> { private: public: template <typename Particle, typename Track> EProcessReturn DoContinuous(Particle&, Track const&) const { - std::this_thread::sleep_for( - std::chrono::milliseconds(ISleep)); + std::this_thread::sleep_for(std::chrono::milliseconds(ISleep)); return process::EProcessReturn::eOk; } template <typename Particle, typename Track> units::si::LengthType MaxStepLength(Particle const& p, Track const& track) const { - std::this_thread::sleep_for( - std::chrono::milliseconds(ISleep)); + std::this_thread::sleep_for(std::chrono::milliseconds(ISleep)); return units::si::meter * std::numeric_limits<double>::infinity(); } diff --git a/Processes/DevTools/Dummy/DummyDecayProcess.h b/Processes/DevTools/Dummy/DummyDecayProcess.h index 3f18da6e1dfcaa9482e56db46798a47d6baa51a0..f30c42eec1cf8451b950c12a7c708fed6d14b356 100644 --- a/Processes/DevTools/Dummy/DummyDecayProcess.h +++ b/Processes/DevTools/Dummy/DummyDecayProcess.h @@ -8,13 +8,12 @@ #pragma once -#include <chrono> -#include <thread> - #include <corsika/process/DecayProcess.h> - #include <corsika/units/PhysicalUnits.h> +#include <chrono> +#include <thread> + namespace corsika::process { namespace devtools { @@ -24,17 +23,15 @@ namespace corsika::process { public: template <typename Particle> EProcessReturn DoDecay(Particle&) { - std::this_thread::sleep_for( - std::chrono::milliseconds(ISleep)); + std::this_thread::sleep_for(std::chrono::milliseconds(ISleep)); return process::EProcessReturn::eOk; } template <typename Particle> corsika::units::si::TimeType GetLifetime(Particle& p) { using namespace corsika::units::si; - - std::this_thread::sleep_for( - std::chrono::milliseconds(ISleep)); + + std::this_thread::sleep_for(std::chrono::milliseconds(ISleep)); return std::numeric_limits<double>::infinity() * 1_s; } }; diff --git a/Processes/DevTools/Dummy/DummyInteractionProcess.h b/Processes/DevTools/Dummy/DummyInteractionProcess.h index 6b2e64d0e19d3db48735eabfac2e525c3d7ad41a..cfa6968859cb6f17819ab65defcf8f5cd048fd8f 100644 --- a/Processes/DevTools/Dummy/DummyInteractionProcess.h +++ b/Processes/DevTools/Dummy/DummyInteractionProcess.h @@ -8,23 +8,21 @@ #pragma once +#include <corsika/process/InteractionProcess.h> + #include <chrono> #include <thread> -#include <corsika/process/InteractionProcess.h> - namespace corsika::process { namespace devtools { template <int ISleep> - class DummyInteractionProcess : InteractionProcess< DummyInteractionProcess<ISleep> > { + class DummyInteractionProcess : InteractionProcess<DummyInteractionProcess<ISleep> > { private: public: template <typename Particle> - EProcessReturn DoInteraction(Particle&) - { - std::this_thread::sleep_for( - std::chrono::milliseconds(ISleep)); + EProcessReturn DoInteraction(Particle&) { + std::this_thread::sleep_for(std::chrono::milliseconds(ISleep)); return process::EProcessReturn::eOk; } @@ -32,8 +30,7 @@ namespace corsika::process { corsika::units::si::GrammageType GetInteractionLength(TParticle& p) { using namespace corsika::units::si; - std::this_thread::sleep_for( - std::chrono::milliseconds(ISleep)); + std::this_thread::sleep_for(std::chrono::milliseconds(ISleep)); return std::numeric_limits<double>::infinity() * (1_g / 1_cm / 1_cm); } }; diff --git a/Processes/DevTools/Dummy/DummySecondariesProcess.h b/Processes/DevTools/Dummy/DummySecondariesProcess.h index 55e05fbf9ead402cf4a37639b75662ef1a1c0b7e..f06db70b5236a4b67055bce3d8a3d434dca5d279 100644 --- a/Processes/DevTools/Dummy/DummySecondariesProcess.h +++ b/Processes/DevTools/Dummy/DummySecondariesProcess.h @@ -8,11 +8,11 @@ #pragma once +#include <corsika/process/SecondariesProcess.h> + #include <chrono> #include <thread> -#include <corsika/process/SecondariesProcess.h> - namespace corsika::process { namespace devtools { @@ -21,10 +21,8 @@ namespace corsika::process { private: public: template <typename TSecondaries> - inline EProcessReturn DoSecondaries(TSecondaries&) - { - std::this_thread::sleep_for( - std::chrono::milliseconds(ISleep)); + inline EProcessReturn DoSecondaries(TSecondaries&) { + std::this_thread::sleep_for(std::chrono::milliseconds(ISleep)); return process::EProcessReturn::eOk; } }; diff --git a/Processes/DevTools/Dummy/TestDummy.cc b/Processes/DevTools/Dummy/TestDummy.cc index 41b58f425a37c43800c5c3855b69e069393001b9..a2226c3dd4133adc9e6325d0db34ad8717d99159 100644 --- a/Processes/DevTools/Dummy/TestDummy.cc +++ b/Processes/DevTools/Dummy/TestDummy.cc @@ -22,6 +22,8 @@ using namespace corsika; using namespace corsika::process; using namespace corsika::process::devtools; +using namespace corsika::units::si; + TEST_CASE("Dummy Processes") { DummyBoundaryCrossingProcess<1000> dbc; DummyContinuousProcess<1000> dc; @@ -51,4 +53,41 @@ TEST_CASE("Dummy Processes") { REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == Approx(1000).margin(1)); } + + SECTION("Decay") { + auto start = std::chrono::steady_clock::now(); + REQUIRE(dd.DoDecay(tmp) == EProcessReturn::eOk); + auto end = std::chrono::steady_clock::now(); + REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == + Approx(1000).margin(1)); + + start = std::chrono::steady_clock::now(); + REQUIRE(dd.GetLifetime(tmp) == units::si::second * std::numeric_limits<double>::infinity()); + end = std::chrono::steady_clock::now(); + REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == + Approx(1000).margin(1)); + } + + SECTION("Interaction") { + auto start = std::chrono::steady_clock::now(); + REQUIRE(di.DoInteraction(tmp) == EProcessReturn::eOk); + auto end = std::chrono::steady_clock::now(); + REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == + Approx(1000).margin(1)); + + start = std::chrono::steady_clock::now(); + REQUIRE(di.GetInteractionLength(tmp) == (units::si::gram / 1_cm / 1_cm) * std::numeric_limits<double>::infinity()); + end = std::chrono::steady_clock::now(); + REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == + Approx(1000).margin(1)); + } + + SECTION("Secondaries") { + auto start = std::chrono::steady_clock::now(); + REQUIRE(dse.DoSecondaries(tmp) == EProcessReturn::eOk); + auto end = std::chrono::steady_clock::now(); + REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == + Approx(1000).margin(1)); + + } }