diff --git a/Documentation/Examples/CMakeLists.txt b/Documentation/Examples/CMakeLists.txt index f9c631669868f15f8d2d1ea55dcf18ed970a96e1..c677f3ab9a3dccd82235fee8d4690be4de697d17 100644 --- a/Documentation/Examples/CMakeLists.txt +++ b/Documentation/Examples/CMakeLists.txt @@ -22,30 +22,27 @@ target_link_libraries (stack_example SuperStupidStack CORSIKAunits CORSIKAlogging) CORSIKA_ADD_TEST (stack_example) -if (Pythia8_FOUND) - add_executable (cascade_example cascade_example.cc) - target_compile_options(cascade_example PRIVATE -g) # do not skip asserts - target_link_libraries (cascade_example SuperStupidStack CORSIKAunits - CORSIKAlogging - CORSIKArandom - ProcessSibyll - ProcessPythia - CORSIKAcascade - ProcessParticleCut - ProcessEnergyLoss - ProcessStackInspector - ProcessTrackWriter - ProcessTrackingLine - CORSIKAprocesses - CORSIKAcascade - CORSIKAparticles - CORSIKAgeometry - CORSIKAenvironment - CORSIKAprocesssequence - ) - install (TARGETS cascade_example DESTINATION share/examples) - CORSIKA_ADD_TEST (cascade_example) -endif() +add_executable (cascade_example cascade_example.cc) +target_compile_options(cascade_example PRIVATE -g) # do not skip asserts +target_link_libraries (cascade_example SuperStupidStack CORSIKAunits + CORSIKAlogging + CORSIKArandom + ProcessSibyll + CORSIKAcascade + ProcessEnergyLoss + ProcessStackInspector + ProcessParticleCut + ProcessTrackWriter + ProcessTrackingLine + CORSIKAprocesses + CORSIKAcascade + CORSIKAparticles + CORSIKAgeometry + CORSIKAenvironment + CORSIKAprocesssequence + ) +install (TARGETS cascade_example DESTINATION share/examples) +CORSIKA_ADD_TEST (cascade_example) add_executable (boundary_example boundary_example.cc) target_compile_options(boundary_example PRIVATE -g) # do not skip asserts @@ -62,7 +59,6 @@ target_link_libraries (boundary_example SuperStupidStack CORSIKAunits CORSIKAlog CORSIKAenvironment CORSIKAprocesssequence ) - install (TARGETS boundary_example DESTINATION share/examples) CORSIKA_ADD_TEST (boundary_example) @@ -80,6 +76,7 @@ if (Pythia8_FOUND) ProcessTrackingLine ProcessParticleCut ProcessHadronicElasticModel + ProcessStackInspector CORSIKAprocesses CORSIKAcascade CORSIKAparticles @@ -92,30 +89,28 @@ if (Pythia8_FOUND) CORSIKA_ADD_TEST (cascade_proton_example) endif() -if (Pythia8_FOUND) - add_executable (vertical_EAS vertical_EAS.cc) - target_compile_options(vertical_EAS PRIVATE -g) # do not skip asserts - target_link_libraries (vertical_EAS SuperStupidStack CORSIKAunits - CORSIKAlogging - CORSIKArandom - ProcessSibyll - ProcessPythia - CORSIKAcascade - ProcessEnergyLoss - ProcessTrackWriter - ProcessTrackingLine - ProcessParticleCut - ProcessHadronicElasticModel - CORSIKAprocesses - CORSIKAcascade - CORSIKAparticles - CORSIKAgeometry - CORSIKAenvironment - CORSIKAprocesssequence - ) - install (TARGETS vertical_EAS DESTINATION share/examples) - # CORSIKA_ADD_TEST (vertical_EAS) not yet... -endif() +add_executable (vertical_EAS vertical_EAS.cc) +target_compile_options(vertical_EAS PRIVATE -g) # do not skip asserts +target_link_libraries (vertical_EAS SuperStupidStack CORSIKAunits + CORSIKAlogging + CORSIKArandom + ProcessSibyll + CORSIKAcascade + ProcessEnergyLoss + ProcessTrackWriter + ProcessTrackingLine + ProcessHadronicElasticModel + ProcessParticleCut + ProcessStackInspector + CORSIKAprocesses + CORSIKAcascade + CORSIKAparticles + CORSIKAgeometry + CORSIKAenvironment + CORSIKAprocesssequence + ) +install (TARGETS vertical_EAS DESTINATION share/examples) +# CORSIKA_ADD_TEST (vertical_EAS) not yet... add_executable (staticsequence_example staticsequence_example.cc) target_compile_options(staticsequence_example PRIVATE -g) # do not skip asserts diff --git a/Documentation/Examples/cascade_example.cc b/Documentation/Examples/cascade_example.cc index 400bb07d8166075b038cd8b59ded4ae759769808..7690d664811f4192d224044ab39ebea7b92d6136 100644 --- a/Documentation/Examples/cascade_example.cc +++ b/Documentation/Examples/cascade_example.cc @@ -29,8 +29,6 @@ #include <corsika/process/sibyll/Interaction.h> #include <corsika/process/sibyll/NuclearInteraction.h> -#include <corsika/process/pythia/Decay.h> - #include <corsika/process/track_writer/TrackWriter.h> #include <corsika/process/particle_cut/ParticleCut.h> @@ -105,7 +103,6 @@ int main() { particles::Code::KMinus, particles::Code::K0Long, particles::Code::K0Short}; random::RNGManager::GetInstance().RegisterRandomStream("s_rndm"); - random::RNGManager::GetInstance().RegisterRandomStream("pythia"); process::sibyll::Interaction sibyll; process::sibyll::NuclearInteraction sibyllNuc(sibyll, env); process::sibyll::Decay decay(trackedHadrons); diff --git a/Documentation/Examples/vertical_EAS.cc b/Documentation/Examples/vertical_EAS.cc index f96544ffbc5c8034f3e06b711590e2885f90af4c..872ea2d943bb808edeb295b767cc931dc3e49032 100644 --- a/Documentation/Examples/vertical_EAS.cc +++ b/Documentation/Examples/vertical_EAS.cc @@ -28,10 +28,7 @@ #include <corsika/process/sibyll/Interaction.h> #include <corsika/process/sibyll/NuclearInteraction.h> -#include <corsika/process/pythia/Decay.h> - #include <corsika/process/particle_cut/ParticleCut.h> - #include <corsika/process/track_writer/TrackWriter.h> #include <corsika/units/PhysicalUnits.h> @@ -59,7 +56,6 @@ using namespace corsika::environment; using namespace std; using namespace corsika::units::si; - // // The example main program for a particle cascade // @@ -102,8 +98,6 @@ int main() { process::sibyll::Interaction sibyll; process::sibyll::NuclearInteraction sibyllNuc(sibyll, env); process::sibyll::Decay decay(trackedHadrons); - // random::RNGManager::GetInstance().RegisterRandomStream("pythia"); - // process::pythia::Decay decay(trackedHadrons); process::particle_cut::ParticleCut cut(20_GeV); // random::RNGManager::GetInstance().RegisterRandomStream("HadronicElasticModel"); // process::HadronicElasticModel::HadronicElasticInteraction diff --git a/Framework/Cascade/Cascade.h b/Framework/Cascade/Cascade.h index 75f29e4ed51bc70d7d31d4917ef4c186baee4bef..f9ec0beb0e40df08a16595bee6be8dc0048cff94 100644 --- a/Framework/Cascade/Cascade.h +++ b/Framework/Cascade/Cascade.h @@ -153,7 +153,7 @@ namespace corsika::cascade { // determine combined total interaction length (inverse) InverseGrammageType const total_inv_lambda = - fProcessSequence.GetTotalInverseInteractionLength(vParticle, step); + fProcessSequence.GetTotalInverseInteractionLength(vParticle); // sample random exponential step length in grammage corsika::random::ExponentialDistribution expDist(1 / total_inv_lambda); @@ -242,13 +242,14 @@ namespace corsika::cascade { if (min_distance == distance_interact) { std::cout << "collide" << std::endl; - InverseGrammageType const actual_inv_length = - fProcessSequence.GetTotalInverseInteractionLength(vParticle, step); + InverseGrammageType const current_inv_length = + fProcessSequence.GetTotalInverseInteractionLength(vParticle); - random::UniformRealDistribution<InverseGrammageType> uniDist(actual_inv_length); + random::UniformRealDistribution<InverseGrammageType> uniDist( + current_inv_length); const auto sample_process = uniDist(fRNG); InverseGrammageType inv_lambda_count = 0. * meter * meter / gram; - fProcessSequence.SelectInteraction(vParticle, projectile, step, sample_process, + fProcessSequence.SelectInteraction(vParticle, projectile, sample_process, inv_lambda_count); } else if (min_distance == distance_decay) { std::cout << "decay" << std::endl; diff --git a/Framework/Cascade/testCascade.cc b/Framework/Cascade/testCascade.cc index 89fd65ef42150149a9c0ffbd7183fed865ba659d..f29d1af9fba4c01c6452fc2dc026df7ff99f2c42 100644 --- a/Framework/Cascade/testCascade.cc +++ b/Framework/Cascade/testCascade.cc @@ -69,8 +69,8 @@ public: ProcessSplit(GrammageType const X0) : fX0(X0) {} - template <typename Particle, typename Track> - corsika::units::si::GrammageType GetInteractionLength(Particle&, Track&) const { + template <typename Particle> + corsika::units::si::GrammageType GetInteractionLength(Particle const&) const { return fX0; } diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index c12c79b01d9663c8caf08a8068ec0dc13b529e3c..510d8e3922f2c7c9a1bbd0578bea34f74641e500 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -10,6 +10,7 @@ set ( Point.h Line.h Sphere.h + Plane.h Volume.h CoordinateSystem.h RootCoordinateSystem.h diff --git a/Framework/Geometry/Plane.h b/Framework/Geometry/Plane.h new file mode 100644 index 0000000000000000000000000000000000000000..2c3f103f52bb9278ffcca63766512ceda13d32c2 --- /dev/null +++ b/Framework/Geometry/Plane.h @@ -0,0 +1,41 @@ + +/* + * (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. + */ + +#ifndef _include_Framework_Geometry_Plane_h_ +#define _include_Framework_Geometry_Plane_h_ + +#include <corsika/geometry/Point.h> +#include <corsika/geometry/Vector.h> +#include <corsika/units/PhysicalUnits.h> + +namespace corsika::geometry { + class Plane { + + using DimLessVec = Vector<corsika::units::si::dimensionless_d>; + + Point const fCenter; + DimLessVec const fNormal; + + public: + Plane(Point const& vCenter, DimLessVec const& vNormal) + : fCenter(vCenter) + , fNormal(vNormal) {} + bool IsAbove(Point const& vP) const { + return fNormal.dot(vP - fCenter) > corsika::units::si::LengthType::zero(); + } + + Point const& GetCenter() const { return fCenter; } + DimLessVec const& GetNormal() const { return fNormal; } + }; + +} // namespace corsika::geometry + +#endif diff --git a/Framework/ProcessSequence/ContinuousProcess.h b/Framework/ProcessSequence/ContinuousProcess.h index 58d378aa3eb5bdad5f8029555ea8825afa450007..27f6c8fae4cb52e037f7ac128dd5fde161dd5566 100644 --- a/Framework/ProcessSequence/ContinuousProcess.h +++ b/Framework/ProcessSequence/ContinuousProcess.h @@ -34,11 +34,11 @@ namespace corsika::process { // here starts the interface part // -> enforce derived to implement DoContinuous... template <typename Particle, typename Track> - EProcessReturn DoContinuous(Particle&, Track&) const; + EProcessReturn DoContinuous(Particle&, Track const&) const; // -> enforce derived to implement MaxStepLength... template <typename Particle, typename Track> - corsika::units::si::LengthType MaxStepLength(Particle& p, Track& track) const; + units::si::LengthType MaxStepLength(Particle const& p, Track const& track) const; }; // overwrite the default trait class, to mark BaseProcess<T> as useful process diff --git a/Framework/ProcessSequence/InteractionProcess.h b/Framework/ProcessSequence/InteractionProcess.h index 27ad9c222d5ce644d6b344a469edaf8e717fcf87..a9b4b9fca306e865a85ac94ae6a9878ce7f0057d 100644 --- a/Framework/ProcessSequence/InteractionProcess.h +++ b/Framework/ProcessSequence/InteractionProcess.h @@ -38,13 +38,12 @@ namespace corsika::process { template <typename Particle> EProcessReturn DoInteraction(Particle&); - template <typename Particle, typename Track> - corsika::units::si::GrammageType GetInteractionLength(Particle& p, Track& t); + template <typename TParticle> + corsika::units::si::GrammageType GetInteractionLength(TParticle& p); - template <typename Particle, typename Track> - corsika::units::si::InverseGrammageType GetInverseInteractionLength(Particle& p, - Track& t) { - return 1. / GetRef().GetInteractionLength(p, t); + template <typename TParticle> + corsika::units::si::InverseGrammageType GetInverseInteractionLength(TParticle& p) { + return 1. / GetRef().GetInteractionLength(p); } }; diff --git a/Framework/ProcessSequence/ProcessSequence.h b/Framework/ProcessSequence/ProcessSequence.h index 3bd759c04a97e55360c87473cc4457159bd967fa..55eb43ba795c35d04654a5256232221fa4c900b5 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 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,64 +157,58 @@ 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); } return max_length; } - template <typename TParticle, typename TTrack> - corsika::units::si::GrammageType GetTotalInteractionLength(TParticle& vP, - TTrack& vT) { - return 1. / GetInverseInteractionLength(vP, vT); + template <typename TParticle> + corsika::units::si::GrammageType GetTotalInteractionLength(TParticle& vP) { + return 1. / GetInverseInteractionLength(vP); } - template <typename TParticle, typename TTrack> + template <typename TParticle> corsika::units::si::InverseGrammageType GetTotalInverseInteractionLength( - TParticle& vP, TTrack& vT) { - return GetInverseInteractionLength(vP, vT); + TParticle& vP) { + return GetInverseInteractionLength(vP); } - template <typename TParticle, typename TTrack> - corsika::units::si::InverseGrammageType GetInverseInteractionLength(TParticle& vP, - TTrack& vT) { + template <typename TParticle> + corsika::units::si::InverseGrammageType GetInverseInteractionLength(TParticle& vP) { using namespace corsika::units::si; InverseGrammageType tot = 0 * meter * meter / gram; - if constexpr (std::is_base_of<InteractionProcess<T1type>, T1type>::value || - is_process_sequence<T1>::value) { - tot += A.GetInverseInteractionLength(vP, vT); + if constexpr (std::is_base_of_v<InteractionProcess<T1type>, T1type> || t1ProcSeq) { + tot += A.GetInverseInteractionLength(vP); } - if constexpr (std::is_base_of<InteractionProcess<T2type>, T2type>::value || - is_process_sequence<T2>::value) { - tot += B.GetInverseInteractionLength(vP, vT); + if constexpr (std::is_base_of_v<InteractionProcess<T2type>, T2type> || t2ProcSeq) { + tot += B.GetInverseInteractionLength(vP); } return tot; } - template <typename TParticle, typename TSecondaries, typename TTrack> + template <typename TParticle, typename TSecondaries> EProcessReturn SelectInteraction( - TParticle& vP, TSecondaries& vS, TTrack& vT, + TParticle& vP, TSecondaries& vS, [[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, vT, lambda_select, lambda_inv_count); + 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, vT); + lambda_inv_count += A.GetInverseInteractionLength(vP); // check if we should execute THIS process and then EXIT if (lambda_select < lambda_inv_count) { A.DoInteraction(vS); @@ -217,15 +216,15 @@ 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, vT, lambda_select, lambda_inv_count); + 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, vT); + lambda_inv_count += B.GetInverseInteractionLength(vP); // check if we should execute THIS process and then EXIT if (lambda_select < lambda_inv_count) { B.DoInteraction(vS); @@ -251,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; @@ -268,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 @@ -284,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 @@ -322,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/Framework/ProcessSequence/testProcessSequence.cc b/Framework/ProcessSequence/testProcessSequence.cc index aa78ee89c4c012eb2df3d322b6b1ddf6fa44ba1e..e8bfe7c1c835762e64ccb3afed48962775dc24ae 100644 --- a/Framework/ProcessSequence/testProcessSequence.cc +++ b/Framework/ProcessSequence/testProcessSequence.cc @@ -100,8 +100,8 @@ public: cout << "Process2::DoInteraction" << endl; return EProcessReturn::eOk; } - template <typename Particle, typename Track> - GrammageType GetInteractionLength(Particle&, Track&) const { + template <typename Particle> + GrammageType GetInteractionLength(Particle&) const { cout << "Process2::GetInteractionLength" << endl; return 3_g / (1_cm * 1_cm); } @@ -123,8 +123,8 @@ public: cout << "Process3::DoInteraction" << endl; return EProcessReturn::eOk; } - template <typename Particle, typename Track> - GrammageType GetInteractionLength(Particle&, Track&) const { + template <typename Particle> + GrammageType GetInteractionLength(Particle&) const { cout << "Process3::GetInteractionLength" << endl; return 1_g / (1_cm * 1_cm); } @@ -220,12 +220,11 @@ TEST_CASE("Process Sequence", "[Process Sequence]") { Process3 m3(2); DummyData particle; - DummyTrajectory track; auto sequence2 = cp1 << m2 << m3; - GrammageType const tot = sequence2.GetTotalInteractionLength(particle, track); + GrammageType const tot = sequence2.GetTotalInteractionLength(particle); InverseGrammageType const tot_inv = - sequence2.GetTotalInverseInteractionLength(particle, track); + sequence2.GetTotalInverseInteractionLength(particle); cout << "lambda_tot=" << tot << "; lambda_tot_inv=" << tot_inv << endl; } diff --git a/Framework/StackInterface/SecondaryView.h b/Framework/StackInterface/SecondaryView.h index 1bbbe02ccaad07fcc533d5782c753427c0dddbf1..fae9d463f9c6808b69d346092fe6277a7c5fec7a 100644 --- a/Framework/StackInterface/SecondaryView.h +++ b/Framework/StackInterface/SecondaryView.h @@ -43,14 +43,18 @@ namespace corsika::stack { All operations possible on a Stack object are also possible on a SecondaryView object. This means you can add, delete, copy, swap, iterate, etc. - */ - /* INTERNAL NOTE FOR DEVELOPERS The secondary particle indices are - stored in a std::vector fIndices, the index of the primary projectle - particle is explicitly stored in fProjectileIndex. StackIterator - indices are refering to those numbers, where - StackIterator::GetIndex()==0 refers to the fProjectileIndex and - StackIterator::GetIndex()>0 to fIndices[i+1], see function GetIndexFromIterator. + *Further information about implementation (for developers):* All + data is stored in the original stack privided at construction + time. The secondary particle (view) indices are stored in an + extra std::vector of SecondaryView class 'fIndices' referring to + the original stack slot indices. The index of the primary + projectle particle is also explicitly stored in + 'fProjectileIndex'. StackIterator indices + 'i = StackIterator::GetIndex()' are referring to those numbers, + where 'i==0' refers to the 'fProjectileIndex', and + 'StackIterator::GetIndex()>0' to 'fIndices[i-1]', see function + GetIndexFromIterator. */ template <typename StackDataType, template <typename> typename ParticleInterface> @@ -125,8 +129,11 @@ namespace corsika::stack { template <typename... Args> auto AddSecondary(StackIterator& proj, const Args... v) { + // make space on stack InnerStackType::GetStackData().IncrementSize(); + // get current number of secondaries on stack const unsigned int idSec = GetSize(); + // determine index on (inner) stack where new particle will be located const unsigned int index = InnerStackType::GetStackData().GetSize() - 1; fIndices.push_back(index); // NOTE: "+1" is since "0" is special marker here for PROJECTILE, see @@ -161,14 +168,26 @@ namespace corsika::stack { /// @} /** - * need overwrite Stack::Delete, since we want to call SecondaryView::DeleteLast + * need overwrite Stack::Delete, since we want to call + * SecondaryView::DeleteLast + * + * The particle is deleted on the underlying (internal) stack. The + * local references in SecondaryView in fIndices must be fixed, + * too. The approach is to a) check if the particle 'p' is at the + * very end of the internal stack, b) if not: move it there by + * copying the last particle to the current particle location, c) + * remove the last particle. + * */ void Delete(StackIterator p) { if (IsEmpty()) { /* error */ throw std::runtime_error("Stack, cannot delete entry since size is zero"); } - if (p.GetIndex() < GetSize() - 1) - InnerStackType::GetStackData().Copy(GetSize() - 1, p.GetIndex()); + const int innerSize = InnerStackType::GetSize(); + const int innerIndex = GetIndexFromIterator(p.GetIndex()); + if (innerIndex < innerSize - 1) + InnerStackType::GetStackData().Copy(innerSize - 1, + GetIndexFromIterator(p.GetIndex())); DeleteLast(); } diff --git a/Framework/StackInterface/testCombinedStack.cc b/Framework/StackInterface/testCombinedStack.cc index 8fe244b667bf736cc418368ee2e06116ef845608..aceccd1b472a99c57168eef4d78851b3641c092c 100644 --- a/Framework/StackInterface/testCombinedStack.cc +++ b/Framework/StackInterface/testCombinedStack.cc @@ -333,7 +333,8 @@ using StackTest2 = CombinedStack<typename StackTest::StackImpl, TestStackData3, CombinedTestInterfaceType2>; #if defined(__clang__) -using StackTestView = SecondaryView<typename StackTest2::StackImpl, CombinedTestInterfaceType2>; +using StackTestView = + SecondaryView<typename StackTest2::StackImpl, CombinedTestInterfaceType2>; #elif defined(__GNUC__) || defined(__GNUG__) using StackTestView = corsika::stack::MakeView<StackTest2>::type; #endif diff --git a/Framework/StackInterface/testSecondaryView.cc b/Framework/StackInterface/testSecondaryView.cc index 2d2064b64e2e09c96ec5f77ebbf25d50f5d60e9e..95c196d5ecef139339b21bb41623f8a52e846d76 100644 --- a/Framework/StackInterface/testSecondaryView.cc +++ b/Framework/StackInterface/testSecondaryView.cc @@ -134,4 +134,67 @@ TEST_CASE("SecondaryStack", "[stack]") { REQUIRE(view.GetSize() == 1); } + + SECTION("deletion") { + StackTest stack; + stack.AddParticle(std::tuple{-99.}); + stack.AddParticle(std::tuple{0.}); + + { + auto particle = stack.GetNextParticle(); + StackTestView view(particle); + + auto proj = view.GetProjectile(); + proj.AddSecondary(std::tuple{-2.}); + proj.AddSecondary(std::tuple{-1.}); + proj.AddSecondary(std::tuple{1.}); + proj.AddSecondary(std::tuple{2.}); + + CHECK(stack.GetSize() == 6); // -99, 0, -2, -1, 1, 2 + CHECK(view.GetSize() == 4); // -2, -1, 1, 2 + + // now delete all negative entries, i.e. -1 and -2 + auto p = view.begin(); + while (p != view.end()) { + auto data = p.GetData(); + if (data < 0) { + p.Delete(); + } else { + ++p; + } + } + CHECK(stack.GetSize() == 4); // -99, 0, 2, 1 (order changes during deletion) + CHECK(view.GetSize() == 2); // 2, 1 + } + + // repeat + + { + auto particle = stack.GetNextParticle(); + StackTestView view(particle); + + // put -2,...,+2 on stack + auto proj = view.GetProjectile(); + proj.AddSecondary(std::tuple{-2.}); + proj.AddSecondary(std::tuple{-1.}); + proj.AddSecondary(std::tuple{1.}); + proj.AddSecondary(std::tuple{2.}); + // stack should contain -99, 0, 2, 1, [-2, -1, 1, 2] + + auto p = view.begin(); + while (p != view.end()) { + auto data = p.GetData(); + if (data < 0) { + p.Delete(); + } else { + ++p; + } + } + + // stack should contain -99, 0, 2, 1, [2, 1] + // view should contain 1, 2 + + CHECK(stack.GetSize() == 6); + } + } } diff --git a/Framework/Units/PhysicalConstants.h b/Framework/Units/PhysicalConstants.h index 75dfc51cedd83bd266f07f971aef48ca717b7d81..23494f036ed2f692de71984c8fc1b81a6d919112 100644 --- a/Framework/Units/PhysicalConstants.h +++ b/Framework/Units/PhysicalConstants.h @@ -51,6 +51,9 @@ namespace corsika::units::constants { auto constexpr nucleonMass = 0.5 * (0.93827 + 0.93957) * 1e9 * electronvolt; + // molar gas constant + auto constexpr R = Rep(8.314'459'8) * joule / (mole * kelvin); + // etc. } // namespace corsika::units::constants diff --git a/Framework/Utilities/sgn.h b/Framework/Utilities/sgn.h index 71d5bec5bbb59fe8c71ef35d0c3f9da1a40b27b7..43d9a9fad728785ec851424b2113f5e7dac60af1 100644 --- a/Framework/Utilities/sgn.h +++ b/Framework/Utilities/sgn.h @@ -3,12 +3,12 @@ namespace corsika::utl { -//! sign function without branches -template <typename T> -static int sgn(T val) { - return (T(0) < val) - (val < T(0)); -} + //! sign function without branches + template <typename T> + static int sgn(T val) { + return (T(0) < val) - (val < T(0)); + } -} +} // namespace corsika::utl #endif diff --git a/Processes/CMakeLists.txt b/Processes/CMakeLists.txt index c9f218bf0066f3b7d16f883464090beca71e8000..b54f76d8fd3d16d37de019ffb202015ab15bd663 100644 --- a/Processes/CMakeLists.txt +++ b/Processes/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory (TrackingLine) add_subdirectory (HadronicElasticModel) add_subdirectory (EnergyLoss) add_subdirectory (UrQMD) +add_subdirectory (SwitchProcess) add_subdirectory (ParticleCut) #add_custom_target(CORSIKAprocesses) diff --git a/Processes/EnergyLoss/EnergyLoss.cc b/Processes/EnergyLoss/EnergyLoss.cc index 990d6172501dc67f0df4958cf651d587003f1923..aaa6dfd6146deb0f34cfbdd79f7e78d76aafa4be 100644 --- a/Processes/EnergyLoss/EnergyLoss.cc +++ b/Processes/EnergyLoss/EnergyLoss.cc @@ -24,9 +24,8 @@ using namespace std; using namespace corsika; using namespace corsika::units::si; -using namespace corsika::setup; -using Particle = Stack::ParticleType; -using Track = Trajectory; +using SetupParticle = corsika::setup::Stack::ParticleType; +using SetupTrack = corsika::setup::Trajectory; namespace corsika::process::energy_loss { @@ -53,7 +52,7 @@ namespace corsika::process::energy_loss { * For shell correction, see Sec 6 of https://www.nap.edu/read/20066/chapter/8#115 * */ - HEPEnergyType EnergyLoss::BetheBloch(Particle& p, GrammageType const dX) { + HEPEnergyType EnergyLoss::BetheBloch(SetupParticle const& p, GrammageType const dX) { // all these are material constants and have to come through Environment // right now: values for nitrogen_D @@ -70,20 +69,20 @@ namespace corsika::process::energy_loss { // end of material constants // this is the Bethe-Bloch coefficiet 4pi N_A r_e^2 m_e c^2 - auto const K = 0.307075_MeV / 1_mol * square(1_cm); + auto constexpr K = 0.307075_MeV / 1_mol * square(1_cm); HEPEnergyType const E = p.GetEnergy(); HEPMassType const m = p.GetMass(); double const gamma = E / m; - double const Z = p.GetChargeNumber(); - double const Z2 = pow(Z, 2); - HEPMassType const me = particles::Electron::GetMass(); + int const Z = p.GetChargeNumber(); + int const Z2 = Z * Z; + HEPMassType constexpr me = particles::Electron::GetMass(); auto const m2 = m * m; - auto const me2 = me * me; - double const gamma2 = pow(gamma, 2); + auto constexpr me2 = me * me; + double const gamma2 = gamma * gamma; double const beta2 = (gamma2 - 1) / gamma2; // 1-1/gamma2 (1-1/gamma)*(1+1/gamma); // (gamma_2-1)/gamma_2 = (1-1/gamma2); - double const c2 = 1; // HEP convention here c=c2=1 + double constexpr c2 = 1; // HEP convention here c=c2=1 cout << "BetheBloch beta2=" << beta2 << " gamma2=" << gamma2 << endl; [[maybe_unused]] double const eta2 = beta2 / (1 - beta2); HEPMassType const Wmax = @@ -148,7 +147,8 @@ namespace corsika::process::energy_loss { (0.5 * log(aux) - beta2 - Cadj / Z - delta / 2 + barkas + bloch) * dX; } - process::EProcessReturn EnergyLoss::DoContinuous(Particle& p, Track& t) { + process::EProcessReturn EnergyLoss::DoContinuous(SetupParticle& p, + SetupTrack const& t) { if (p.GetChargeNumber() == 0) return process::EProcessReturn::eOk; GrammageType const dX = p.GetNode()->GetModelProperties().IntegratedGrammage(t, t.GetLength()); @@ -170,12 +170,25 @@ namespace corsika::process::energy_loss { p.SetEnergy(Enew); MomentumUpdate(p, Enew); fEnergyLossTot += dE; - GetXbin(p, dE); + GetXbin(p, t, dE); return status; } - units::si::LengthType EnergyLoss::MaxStepLength(Particle&, Track&) { - return units::si::meter * std::numeric_limits<double>::infinity(); + units::si::LengthType EnergyLoss::MaxStepLength(SetupParticle const& vParticle, + SetupTrack const& vTrack) const { + if (vParticle.GetChargeNumber() == 0) { + return units::si::meter * std::numeric_limits<double>::infinity(); + } + + auto constexpr dX = 1_g / square(1_cm); + auto const dE = -BetheBloch(vParticle, dX); // dE > 0 + //~ auto const Ekin = vParticle.GetEnergy() - vParticle.GetMass(); + auto const maxLoss = 0.01 * vParticle.GetEnergy(); + auto const maxGrammage = maxLoss / dE * dX; + + return vParticle.GetNode()->GetModelProperties().ArclengthFromGrammage(vTrack, + maxGrammage) * + 1.0001; // to make sure particle gets absorbed when DoContinuous() is called } void EnergyLoss::MomentumUpdate(corsika::setup::Stack::ParticleType& vP, @@ -187,17 +200,17 @@ namespace corsika::process::energy_loss { #include <corsika/geometry/CoordinateSystem.h> - int EnergyLoss::GetXbin(corsika::setup::Stack::ParticleType& vP, + int EnergyLoss::GetXbin(SetupParticle const& vP, SetupTrack const& vTrack, const HEPEnergyType dE) { using namespace corsika::geometry; CoordinateSystem const& rootCS = RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); - Point pos1(rootCS, 0_m, 0_m, 0_m); - Point pos2(rootCS, 0_m, 0_m, vP.GetPosition().GetCoordinates()[2]); - Vector delta = (pos2 - pos1) / 1_s; - Trajectory t(Line(pos1, delta), 1_s); + Point const pos1(rootCS, 0_m, 0_m, 0_m); + Point const pos2(rootCS, 0_m, 0_m, vTrack.GetPosition(0).GetCoordinates()[2]); + auto const delta = (pos2 - pos1) / 1_s; + Trajectory const t(Line(pos1, delta), 1_s); GrammageType const grammage = vP.GetNode()->GetModelProperties().IntegratedGrammage(t, t.GetLength()); diff --git a/Processes/EnergyLoss/EnergyLoss.h b/Processes/EnergyLoss/EnergyLoss.h index deaff4faf0837f6cac44ce2da975637393035d49..d0726d9d44220f27c356f5128a43a0092cecc558 100644 --- a/Processes/EnergyLoss/EnergyLoss.h +++ b/Processes/EnergyLoss/EnergyLoss.h @@ -25,34 +25,31 @@ namespace corsika::process::energy_loss { class EnergyLoss : public corsika::process::ContinuousProcess<EnergyLoss> { using MeVgcm2 = decltype(1e6 * units::si::electronvolt / units::si::gram * - corsika::units::si::square(1e-2 * units::si::meter)); + units::si::square(1e-2 * units::si::meter)); - void MomentumUpdate(corsika::setup::Stack::ParticleType&, - corsika::units::si::HEPEnergyType Enew); + void MomentumUpdate(setup::Stack::ParticleType&, units::si::HEPEnergyType Enew); public: EnergyLoss(); void Init() {} + process::EProcessReturn DoContinuous(setup::Stack::ParticleType&, + setup::Trajectory const&); + units::si::LengthType MaxStepLength(setup::Stack::ParticleType const&, + setup::Trajectory const&) const; - corsika::process::EProcessReturn DoContinuous(corsika::setup::Stack::ParticleType&, - corsika::setup::Trajectory&); - corsika::units::si::LengthType MaxStepLength(corsika::setup::Stack::ParticleType&, - corsika::setup::Trajectory&); - - corsika::units::si::HEPEnergyType GetTotal() const { return fEnergyLossTot; } + units::si::HEPEnergyType GetTotal() const { return fEnergyLossTot; } void PrintProfile() const; private: - corsika::units::si::HEPEnergyType BetheBloch( - corsika::setup::Stack::ParticleType& p, - const corsika::units::si::GrammageType dX); + static units::si::HEPEnergyType BetheBloch(setup::Stack::ParticleType const& p, + const units::si::GrammageType dX); - int GetXbin(corsika::setup::Stack::ParticleType& p, - const corsika::units::si::HEPEnergyType dE); + int GetXbin(setup::Stack::ParticleType const&, setup::Trajectory const&, + units::si::HEPEnergyType); - corsika::units::si::HEPEnergyType fEnergyLossTot; - corsika::units::si::GrammageType fdX; // profile binning - std::map<int, double> fProfile; // longitudinal profile + units::si::HEPEnergyType fEnergyLossTot; + units::si::GrammageType fdX; // profile binning + std::map<int, double> fProfile; // longitudinal profile }; } // namespace corsika::process::energy_loss diff --git a/Processes/HadronicElasticModel/HadronicElasticModel.cc b/Processes/HadronicElasticModel/HadronicElasticModel.cc index 33f162e41531bf4008f91b21bb98e8afc13a7abb..9e05c521320787b1f8a42ca3c154cfa708285769 100644 --- a/Processes/HadronicElasticModel/HadronicElasticModel.cc +++ b/Processes/HadronicElasticModel/HadronicElasticModel.cc @@ -18,14 +18,12 @@ #include <corsika/utl/COMBoost.h> #include <corsika/setup/SetupStack.h> -#include <corsika/setup/SetupTrajectory.h> #include <iomanip> #include <iostream> using namespace corsika::setup; -using Particle = corsika::setup::Stack::ParticleType; -using Track = corsika::setup::Trajectory; +using SetupParticle = corsika::setup::Stack::ParticleType; namespace corsika::process::HadronicElasticModel { @@ -38,7 +36,7 @@ namespace corsika::process::HadronicElasticModel { template <> units::si::GrammageType HadronicElasticInteraction::GetInteractionLength( - Particle const& p, Track&) { + SetupParticle const& p) { using namespace units::si; if (p.GetPID() == particles::Code::Proton) { auto const* currentNode = p.GetNode(); @@ -79,7 +77,7 @@ namespace corsika::process::HadronicElasticModel { } template <> - process::EProcessReturn HadronicElasticInteraction::DoInteraction(Particle& p) { + process::EProcessReturn HadronicElasticInteraction::DoInteraction(SetupParticle& p) { if (p.GetPID() != particles::Code::Proton) { return process::EProcessReturn::eOk; } using namespace units::si; diff --git a/Processes/HadronicElasticModel/HadronicElasticModel.h b/Processes/HadronicElasticModel/HadronicElasticModel.h index 4180c04c514d00089fd044ab39027b9128a853ff..b3fd15fd2cdc6feac967182cff342b60f30e954d 100644 --- a/Processes/HadronicElasticModel/HadronicElasticModel.h +++ b/Processes/HadronicElasticModel/HadronicElasticModel.h @@ -56,8 +56,8 @@ namespace corsika::process::HadronicElasticModel { units::si::CrossSectionType y = 0.05608 * units::si::barn); void Init(); - template <typename Particle, typename Track> - corsika::units::si::GrammageType GetInteractionLength(Particle const& p, Track&); + template <typename Particle> + corsika::units::si::GrammageType GetInteractionLength(Particle const& p); template <typename Particle> corsika::process::EProcessReturn DoInteraction(Particle&); diff --git a/Processes/Pythia/Decay.cc b/Processes/Pythia/Decay.cc index 222c68c8dd57d7fd57c453b62f53777e85ad062a..20d2aaa5044e484b2727e5cdc03f011fe36be83b 100644 --- a/Processes/Pythia/Decay.cc +++ b/Processes/Pythia/Decay.cc @@ -147,10 +147,6 @@ namespace corsika::process::pythia { // set particle stable Decay::SetStable(vP.GetPID()); - - // remove original particle from corsika stack - vP.Delete(); - // if (fCount>10) throw std::runtime_error("stop here"); } } // namespace corsika::process::pythia diff --git a/Processes/Pythia/Interaction.cc b/Processes/Pythia/Interaction.cc index ae8104350086f5cfda94b174305d0f0366faa2ce..2a0cce386edc6dfc5a14f0f6fb84fd94aa5a85a7 100644 --- a/Processes/Pythia/Interaction.cc +++ b/Processes/Pythia/Interaction.cc @@ -15,7 +15,6 @@ #include <corsika/environment/NuclearComposition.h> #include <corsika/geometry/FourVector.h> #include <corsika/setup/SetupStack.h> -#include <corsika/setup/SetupTrajectory.h> #include <corsika/utl/COMBoost.h> #include <tuple> @@ -28,7 +27,6 @@ using namespace corsika; using namespace corsika::setup; using Projectile = corsika::setup::StackView::ParticleType; using Particle = corsika::setup::Stack::ParticleType; -using Track = Trajectory; namespace corsika::process::pythia { @@ -168,7 +166,7 @@ namespace corsika::process::pythia { } template <> - units::si::GrammageType Interaction::GetInteractionLength(Particle& p, Track&) { + units::si::GrammageType Interaction::GetInteractionLength(Particle& p) { using namespace units; using namespace units::si; @@ -411,8 +409,6 @@ namespace corsika::process::pythia { << "Elab_final=" << Elab_final / 1_GeV << ", Plab_final=" << (Plab_final / 1_GeV).GetComponents() << endl; } - // delete current particle - vP.Delete(); } return process::EProcessReturn::eOk; } diff --git a/Processes/Pythia/Interaction.h b/Processes/Pythia/Interaction.h index ac27825acf0561d0d9e7e8e8b66961bdfc674e2f..3594358e0b39f528991183b4c414e8edaa3b5828 100644 --- a/Processes/Pythia/Interaction.h +++ b/Processes/Pythia/Interaction.h @@ -51,16 +51,16 @@ namespace corsika::process::pythia { const corsika::particles::Code TargetId, const corsika::units::si::HEPEnergyType CoMenergy); - template <typename TParticle, typename TTrack> - corsika::units::si::GrammageType GetInteractionLength(TParticle&, TTrack&); + template <typename TParticle> + corsika::units::si::GrammageType GetInteractionLength(TParticle&); /** In this function PYTHIA is called to produce one event. The event is copied (and boosted) into the shower lab frame. */ - template <typename TProjctile> - corsika::process::EProcessReturn DoInteraction(TProjctile&); + template <typename TProjectile> + corsika::process::EProcessReturn DoInteraction(TProjectile&); private: corsika::random::RNG& fRNG = diff --git a/Processes/Pythia/Random.cc b/Processes/Pythia/Random.cc index 8fcbcf4ee7274ba36252f7969306073f3cffddd5..0d08403ca1d890a062e2632124079c6a3cb220f6 100644 --- a/Processes/Pythia/Random.cc +++ b/Processes/Pythia/Random.cc @@ -12,9 +12,6 @@ namespace corsika::process::pythia { - double Random::flat() { - std::uniform_real_distribution<double> dist; - return dist(fRNG); - } + double Random::flat() { return fDist(fRNG); } } // namespace corsika::process::pythia diff --git a/Processes/Pythia/Random.h b/Processes/Pythia/Random.h index 276fc532ca53ac84b708e8ad12cb16fbaed01c9a..cd35fc4eeafcbdf4ec507cf54ab966271a8183f0 100644 --- a/Processes/Pythia/Random.h +++ b/Processes/Pythia/Random.h @@ -23,6 +23,7 @@ namespace corsika::process { double flat(); private: + std::uniform_real_distribution<double> fDist; corsika::random::RNG& fRNG = corsika::random::RNGManager::GetInstance().GetRandomStream("pythia"); }; diff --git a/Processes/Pythia/testPythia.cc b/Processes/Pythia/testPythia.cc index 3fb2df13ecd1c24e674997a3c3aa468164f21d06..f6f09b84c17f80f8b579d1a11eba843e6ddbc964 100644 --- a/Processes/Pythia/testPythia.cc +++ b/Processes/Pythia/testPythia.cc @@ -118,14 +118,6 @@ TEST_CASE("pythia process") { auto const* nodePtr = theMedium.get(); // save the medium for later use before moving it universe.AddChild(std::move(theMedium)); - geometry::Point const origin(cs, {0_m, 0_m, 0_m}); - geometry::Vector<units::si::SpeedType::dimension_type> v(cs, 0_m / second, 0_m / second, - 1_m / second); - geometry::Line line(origin, v); - geometry::Trajectory<geometry::Line> track(line, 10_s); - - random::RNGManager::GetInstance().RegisterRandomStream("s_rndm"); - SECTION("pythia decay") { setup::Stack stack; @@ -173,7 +165,6 @@ TEST_CASE("pythia process") { process::pythia::Interaction model; model.Init(); [[maybe_unused]] const process::EProcessReturn ret = model.DoInteraction(projectile); - [[maybe_unused]] const GrammageType length = - model.GetInteractionLength(particle, track); + [[maybe_unused]] const GrammageType length = model.GetInteractionLength(particle); } } diff --git a/Processes/Sibyll/Interaction.cc b/Processes/Sibyll/Interaction.cc index d674f9a3a775970bf60de08c0cf33b55fc73a17d..c089ec083c9c7d9ec1d91136cb0c7796dc958c57 100644 --- a/Processes/Sibyll/Interaction.cc +++ b/Processes/Sibyll/Interaction.cc @@ -118,8 +118,8 @@ namespace corsika::process::sibyll { } template <> - units::si::GrammageType Interaction::GetInteractionLength(SetupParticle& vP, - Track&) const { + units::si::GrammageType Interaction::GetInteractionLength( + SetupParticle const& vP) const { using namespace units; using namespace units::si; @@ -366,8 +366,6 @@ namespace corsika::process::sibyll { << ", Plab_final=" << (Plab_final / 1_GeV).GetComponents() << endl; } } - // delete current particle - vP.Delete(); return process::EProcessReturn::eOk; } diff --git a/Processes/Sibyll/Interaction.h b/Processes/Sibyll/Interaction.h index e7d7a0902116c2fceb9240cf9266d04a2ea2fd72..643bd0d51bd4f387aafa3870f2dddfb0ed1fe9d5 100644 --- a/Processes/Sibyll/Interaction.h +++ b/Processes/Sibyll/Interaction.h @@ -52,8 +52,8 @@ namespace corsika::process::sibyll { GetCrossSection(const corsika::particles::Code, const corsika::particles::Code, const corsika::units::si::HEPEnergyType) const; - template <typename TParticle, typename TTrack> - corsika::units::si::GrammageType GetInteractionLength(TParticle&, TTrack&) const; + template <typename TParticle> + corsika::units::si::GrammageType GetInteractionLength(TParticle const&) const; /** In this function SIBYLL is called to produce one event. The diff --git a/Processes/Sibyll/NuclearInteraction.cc b/Processes/Sibyll/NuclearInteraction.cc index 31abd9da350e1c80c24868eb2313e860b51bd821..907e95b271bb44cfb4d2982f0f1f40f88cbb0eca 100644 --- a/Processes/Sibyll/NuclearInteraction.cc +++ b/Processes/Sibyll/NuclearInteraction.cc @@ -217,7 +217,7 @@ namespace corsika::process::sibyll { template <> template <> units::si::GrammageType NuclearInteraction<SetupEnvironment>::GetInteractionLength( - Particle& vP, Track&) { + Particle& vP) { using namespace units; using namespace units::si; diff --git a/Processes/Sibyll/NuclearInteraction.h b/Processes/Sibyll/NuclearInteraction.h index 6bee9ba7a7964e74112c2bf60e5cbd4b1c23c2fa..261f931321ed98119ab02f4e3cace952308fdbb7 100644 --- a/Processes/Sibyll/NuclearInteraction.h +++ b/Processes/Sibyll/NuclearInteraction.h @@ -53,11 +53,11 @@ namespace corsika::process::sibyll { std::tuple<corsika::units::si::CrossSectionType, corsika::units::si::CrossSectionType> GetCrossSection(Particle& p, const corsika::particles::Code TargetId); - template <typename Particle, typename Track> - corsika::units::si::GrammageType GetInteractionLength(Particle&, Track&); + template <typename Particle> + corsika::units::si::GrammageType GetInteractionLength(Particle&); - template <typename Projectle> - corsika::process::EProcessReturn DoInteraction(Projectle&); + template <typename Projectile> + corsika::process::EProcessReturn DoInteraction(Projectile&); private: TEnvironment const& fEnvironment; diff --git a/Processes/Sibyll/testSibyll.cc b/Processes/Sibyll/testSibyll.cc index d5f5d9bc8e39ac775de3fb9d541a18b596941bad..0c42c90abb86a758c45f5ad4a79ebe87d3f1d3fa 100644 --- a/Processes/Sibyll/testSibyll.cc +++ b/Processes/Sibyll/testSibyll.cc @@ -98,12 +98,6 @@ TEST_CASE("SibyllInterface", "[processes]") { const geometry::CoordinateSystem& cs = env.GetCoordinateSystem(); - geometry::Point const origin(cs, {0_m, 0_m, 0_m}); - geometry::Vector<units::si::SpeedType::dimension_type> v(cs, 0_m / second, 0_m / second, - 1_m / second); - geometry::Line line(origin, v); - geometry::Trajectory<geometry::Line> track(line, 10_s); - random::RNGManager::GetInstance().RegisterRandomStream("s_rndm"); SECTION("InteractionInterface") { @@ -126,8 +120,7 @@ TEST_CASE("SibyllInterface", "[processes]") { model.Init(); [[maybe_unused]] const process::EProcessReturn ret = model.DoInteraction(projectile); - [[maybe_unused]] const GrammageType length = - model.GetInteractionLength(particle, track); + [[maybe_unused]] const GrammageType length = model.GetInteractionLength(particle); } SECTION("NuclearInteractionInterface") { @@ -153,8 +146,7 @@ TEST_CASE("SibyllInterface", "[processes]") { model.Init(); [[maybe_unused]] const process::EProcessReturn ret = model.DoInteraction(projectile); - [[maybe_unused]] const GrammageType length = - model.GetInteractionLength(particle, track); + [[maybe_unused]] const GrammageType length = model.GetInteractionLength(particle); } SECTION("DecayInterface") { diff --git a/Processes/StackInspector/StackInspector.cc b/Processes/StackInspector/StackInspector.cc index 814763d5cbfcbc0bd4201db70f220dc4e8ea123f..e56503378ed5abfc15578c474ed0afd4d54d6412 100644 --- a/Processes/StackInspector/StackInspector.cc +++ b/Processes/StackInspector/StackInspector.cc @@ -37,7 +37,7 @@ template <typename TStack> StackInspector<TStack>::~StackInspector() {} template <typename TStack> -process::EProcessReturn StackInspector<TStack>::DoStack(TStack& vS) { +process::EProcessReturn StackInspector<TStack>::DoStack(TStack const& vS) { if (!fReport) return process::EProcessReturn::eOk; [[maybe_unused]] int i = 0; HEPEnergyType Etot = 0_GeV; diff --git a/Processes/StackInspector/StackInspector.h b/Processes/StackInspector/StackInspector.h index 57a929dd2362b302d43d05175878a257c5c8a832..62f36eeebae774f74d26953697707e698c75da6e 100644 --- a/Processes/StackInspector/StackInspector.h +++ b/Processes/StackInspector/StackInspector.h @@ -30,7 +30,7 @@ namespace corsika::process { ~StackInspector(); void Init(); - EProcessReturn DoStack(TStack&); + EProcessReturn DoStack(TStack const&); private: bool fReport; diff --git a/Processes/SwitchProcess/CMakeLists.txt b/Processes/SwitchProcess/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..feac9f360ced5356d90ecd87cc7d4ca51939e0f6 --- /dev/null +++ b/Processes/SwitchProcess/CMakeLists.txt @@ -0,0 +1,50 @@ +set ( + MODEL_HEADERS + SwitchProcess.h + ) + +set ( + MODEL_NAMESPACE + corsika/process/switch_process + ) + +add_library (ProcessSwitch INTERFACE) +CORSIKA_COPY_HEADERS_TO_NAMESPACE (ProcessSwitch ${MODEL_NAMESPACE} ${MODEL_HEADERS}) + +set_target_properties ( + ProcessStackInspector + PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION 1 +# PUBLIC_HEADER "${MODEL_HEADERS}" + ) + +# target dependencies on other libraries (also the header onlys) +target_link_libraries ( + ProcessSwitch + INTERFACE + CORSIKAunits + CORSIKAprocesssequence + ) + +target_include_directories ( + ProcessSwitch + INTERFACE + $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include> + $<INSTALL_INTERFACE:include/include> + ) + +install (FILES ${MODEL_HEADERS} DESTINATION include/${MODEL_NAMESPACE}) + +# -------------------- +# code unit testing +add_executable (testSwitchProcess testSwitchProcess.cc) + +target_link_libraries ( + testSwitchProcess + ProcessSwitch + CORSIKAstackinterface + CORSIKAthirdparty # for catch2 +) + +CORSIKA_ADD_TEST(testSwitchProcess) diff --git a/Processes/SwitchProcess/SwitchProcess.h b/Processes/SwitchProcess/SwitchProcess.h new file mode 100644 index 0000000000000000000000000000000000000000..31e59599bc6dceb68edf4ad030d284eb37c69bce --- /dev/null +++ b/Processes/SwitchProcess/SwitchProcess.h @@ -0,0 +1,98 @@ +#ifndef _corsika_SwitchProcess_h +#define _corsika_SwitchProcess_h + +#include <corsika/process/InteractionProcess.h> +#include <corsika/process/ProcessSequence.h> +#include <corsika/setup/SetupStack.h> +#include <corsika/units/PhysicalUnits.h> + +namespace corsika::process::switch_process { + + /** + * This process provides an energy-based switch between two interaction processes P1 and + * P1. For energies below the threshold, P1 is invoked, otherwise P2. Both can be either + * single interaction processes or multiple ones combined in a ProcessSequence. A + * SwitchProcess itself will always be regarded as a ProcessSequence rather than an + * InteractionProcess when assembled into a greater ProcessSequence. + */ + + template <class TLowEProcess, class THighEProcess> + class SwitchProcess : public BaseProcess<SwitchProcess<TLowEProcess, THighEProcess>> { + TLowEProcess& fLowEProcess; + THighEProcess& fHighEProcess; + units::si::HEPEnergyType const fThresholdEnergy; + + public: + SwitchProcess(TLowEProcess& vLowEProcess, THighEProcess& vHighEProcess, + units::si::HEPEnergyType vThresholdEnergy) + : fLowEProcess(vLowEProcess) + , fHighEProcess(vHighEProcess) + , fThresholdEnergy(vThresholdEnergy) {} + + void Init() { + fLowEProcess.Init(); + 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) { + if constexpr (is_process_sequence_v<TLowEProcess>) { + return fLowEProcess.GetTotalInteractionLength(vParticle); + } else { + return fLowEProcess.GetInteractionLength(vParticle); + } + } else { + if constexpr (is_process_sequence_v<THighEProcess>) { + return fHighEProcess.GetTotalInteractionLength(vParticle); + } else { + return fHighEProcess.GetInteractionLength(vParticle); + } + } + } + + // required to conform to ProcessSequence interface. We cannot just + // implement DoInteraction() because we want to call SelectInteraction + // in case a member process is a ProcessSequence. + template <typename TParticle, typename TSecondaries> + EProcessReturn SelectInteraction( + 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 { + 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 { + 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 + +#endif diff --git a/Processes/SwitchProcess/testSwitchProcess.cc b/Processes/SwitchProcess/testSwitchProcess.cc new file mode 100644 index 0000000000000000000000000000000000000000..4e902e8857367bfbb4d1ab7643941cdcce27c04c --- /dev/null +++ b/Processes/SwitchProcess/testSwitchProcess.cc @@ -0,0 +1,256 @@ +#include <corsika/process/switch_process/SwitchProcess.h> +#include <corsika/stack/SecondaryView.h> +#include <corsika/stack/Stack.h> +#include <corsika/units/PhysicalUnits.h> + +#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one + // cpp file +#include <catch2/catch.hpp> + +#include <algorithm> +#include <random> + +using namespace corsika; +using namespace corsika::process; +using namespace corsika::units::si; + +class TestStackData { + +public: + // these functions are needed for the Stack interface + void Init() {} + void Clear() { fData.clear(); } + unsigned int GetSize() const { return fData.size(); } + unsigned int GetCapacity() const { return fData.size(); } + void Copy(int i1, int i2) { fData[i2] = fData[i1]; } + void Swap(int i1, int i2) { std::swap(fData[i1], fData[i2]); } + + // custom data access function + void SetData(unsigned int i, HEPEnergyType v) { fData[i] = v; } + HEPEnergyType GetData(const unsigned int i) const { return fData[i]; } + + // these functions are also needed by the Stack interface + void IncrementSize() { fData.resize(fData.size() + 1); } + void DecrementSize() { + if (fData.size() > 0) { fData.pop_back(); } + } + + // custom private data section +private: + std::vector<HEPEnergyType> fData; +}; + +/** + * From static_cast of a StackIterator over entries in the + * TestStackData class you get and object of type + * TestParticleInterface defined here + * + * It provides Get/Set methods to read and write data to the "Data" + * storage of TestStackData obtained via + * "StackIteratorInterface::GetStackData()", given the index of the + * iterator "StackIteratorInterface::GetIndex()" + * + */ +template <typename StackIteratorInterface> +class TestParticleInterface + : public corsika::stack::ParticleBase<StackIteratorInterface> { + +public: + using corsika::stack::ParticleBase<StackIteratorInterface>::GetStackData; + using corsika::stack::ParticleBase<StackIteratorInterface>::GetIndex; + + /* + The SetParticleData methods are called for creating new entries + on the stack. You can specifiy various parametric versions to + perform this task: + */ + + // default version for particle-creation from input data + void SetParticleData(const std::tuple<HEPEnergyType> v) { SetEnergy(std::get<0>(v)); } + void SetParticleData(TestParticleInterface<StackIteratorInterface>& /*parent*/, + std::tuple<HEPEnergyType> v) { + SetEnergy(std::get<0>(v)); + } + + // here are the fundamental methods for access to TestStackData data + void SetEnergy(HEPEnergyType v) { GetStackData().SetData(GetIndex(), v); } + HEPEnergyType GetEnergy() const { return GetStackData().GetData(GetIndex()); } +}; + +using SimpleStack = corsika::stack::Stack<TestStackData, TestParticleInterface>; + +// see issue 161 +#if defined(__clang__) +using StackTestView = corsika::stack::SecondaryView<TestStackData, TestParticleInterface>; +#elif defined(__GNUC__) || defined(__GNUG__) +using StackTestView = corsika::stack::MakeView<SimpleStack>::type; +#endif + +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; + } +}; + +using DummyLowEnergyProcess = DummyProcess<1>; +using DummyHighEnergyProcess = DummyProcess<2>; +using DummyAdditionalProcess = DummyProcess<3>; + +TEST_CASE("SwitchProcess from InteractionProcess") { + DummyLowEnergyProcess low; + DummyHighEnergyProcess high; + DummyAdditionalProcess proc; + + switch_process::SwitchProcess switchProcess(low, high, 1_TeV); + auto seq = switchProcess << proc; + + SimpleStack stack; + + SECTION("low energy") { + stack.AddParticle(std::tuple<HEPEnergyType>{0.5_TeV}); + auto p = stack.GetNextParticle(); + + // low energy process returns 1 kg/m² + SECTION("interaction length") { + REQUIRE(switchProcess.GetInteractionLength(p) / kgMSq == Approx(1)); + REQUIRE(seq.GetTotalInteractionLength(p) / kgMSq == Approx(3. / 4)); + } + + // low energy process creates 1 secondary + //~ SECTION("SelectInteraction") { + //~ typename SimpleStack::ParticleType theParticle = + //~ stack.GetNextParticle(); // as in corsika::Cascade + //~ StackTestView view(theParticle); + //~ auto projectile = view.GetProjectile(); + + //~ InverseGrammageType invLambda = 0 / kgMSq; + //~ switchProcess.SelectInteraction(p, projectile, 0.01 / kgMSq, invLambda); + + //~ REQUIRE(view.GetSize() == 1); + //~ } + } + + SECTION("high energy") { + stack.AddParticle(std::tuple<HEPEnergyType>{4_TeV}); + auto p = stack.GetNextParticle(); + + // high energy process returns 2 kg/m² + SECTION("interaction length") { + REQUIRE(switchProcess.GetInteractionLength(p) / kgMSq == Approx(2)); + REQUIRE(seq.GetTotalInteractionLength(p) / kgMSq == Approx(6. / 5)); + } + + // high energy process creates 2 secondaries + SECTION("SelectInteraction") { + typename SimpleStack::ParticleType theParticle = + stack.GetNextParticle(); // as in corsika::Cascade + StackTestView view(theParticle); + auto projectile = view.GetProjectile(); + + InverseGrammageType invLambda = 0 / kgMSq; + switchProcess.SelectInteraction(p, projectile, 0.01 / kgMSq, invLambda); + + REQUIRE(view.GetSize() == 2); + } + } +} + +TEST_CASE("SwitchProcess from ProcessSequence") { + DummyProcess<1> innerA; + DummyProcess<2> innerB; + DummyProcess<3> outer; + DummyProcess<4> additional; + + auto seq = innerA << innerB; + + switch_process::SwitchProcess switchProcess(seq, outer, 1_TeV); + auto completeSeq = switchProcess << additional; + + SimpleStack stack; + + SECTION("low energy") { + stack.AddParticle(std::tuple<HEPEnergyType>{0.5_TeV}); + auto p = stack.GetNextParticle(); + + SECTION("interaction length") { + REQUIRE(switchProcess.GetInteractionLength(p) / kgMSq == Approx(2. / 3)); + REQUIRE(completeSeq.GetTotalInteractionLength(p) / kgMSq == Approx(4. / 7)); + } + + SECTION("SelectInteraction") { + std::vector<int> numberOfSecondaries; + + for (int i = 0; i < 1000; ++i) { + typename SimpleStack::ParticleType theParticle = + stack.GetNextParticle(); // as in corsika::Cascade + StackTestView view(theParticle); + auto projectile = view.GetProjectile(); + + double r = i / 1000.; + InverseGrammageType invLambda = r * 7./4 / 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(12./7.).margin(0.01)); + } + } + + SECTION("high energy") { + stack.AddParticle(std::tuple<HEPEnergyType>{3.0_TeV}); + auto p = stack.GetNextParticle(); + + SECTION("interaction length") { + REQUIRE(switchProcess.GetInteractionLength(p) / kgMSq == Approx(3)); + REQUIRE(completeSeq.GetTotalInteractionLength(p) / kgMSq == Approx(12. / 7.)); + } + + SECTION("SelectInteraction") { + std::vector<int> numberOfSecondaries; + + for (int i = 0; i < 1000; ++i) { + typename SimpleStack::ParticleType 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/Processes/TrackWriter/TrackWriter.cc b/Processes/TrackWriter/TrackWriter.cc index e422bce8af8f054819cd03c174eaf594e85d6c76..d3247e87c8ad0e66620afcad2b2dc18d3e1c6049 100644 --- a/Processes/TrackWriter/TrackWriter.cc +++ b/Processes/TrackWriter/TrackWriter.cc @@ -37,9 +37,9 @@ namespace corsika::process::track_writer { using namespace units::si; auto const start = vT.GetPosition(0).GetCoordinates(); auto const delta = vT.GetPosition(1).GetCoordinates() - start; - auto const& name = particles::GetName(vP.GetPID()); + auto const pdg = static_cast<int>(particles::GetPDG(vP.GetPID())); - fFile << name << " " << vP.GetEnergy() / 1_eV << ' ' << start[0] / 1_m << ' ' + fFile << pdg << ' ' << vP.GetEnergy() / 1_eV << ' ' << start[0] / 1_m << ' ' << start[1] / 1_m << ' ' << start[2] / 1_m << " " << delta[0] / 1_m << ' ' << delta[1] / 1_m << ' ' << delta[2] / 1_m << '\n'; diff --git a/Processes/TrackingLine/TrackingLine.cc b/Processes/TrackingLine/TrackingLine.cc index 319030f91d5347d47af58cddbdea607684a16677..149556bf245b9fb418fb3db03f267e64b688fb5f 100644 --- a/Processes/TrackingLine/TrackingLine.cc +++ b/Processes/TrackingLine/TrackingLine.cc @@ -16,31 +16,27 @@ #include <corsika/geometry/Vector.h> #include <corsika/process/tracking_line/TrackingLine.h> -#include <algorithm> -#include <iostream> +#include <limits> #include <stdexcept> #include <utility> -using namespace corsika; +using namespace corsika::geometry; +using namespace corsika::units::si; namespace corsika::process::tracking_line { - std::optional<std::pair<corsika::units::si::TimeType, corsika::units::si::TimeType>> - TimeOfIntersection(corsika::geometry::Line const& line, - geometry::Sphere const& sphere) { + std::optional<std::pair<TimeType, TimeType>> TimeOfIntersection(Line const& line, + Sphere const& sphere) { auto const delta = line.GetR0() - sphere.GetCenter(); auto const v = line.GetV0(); - auto const vSqNorm = v.squaredNorm(); + auto const vSqNorm = + v.squaredNorm(); // todo: get rid of this by having V0 normalized always auto const R = sphere.GetRadius(); auto const vDotDelta = v.dot(delta); auto const discriminant = vDotDelta * vDotDelta - vSqNorm * (delta.squaredNorm() - R * R); - //~ std::cout << "discriminant: " << discriminant << std::endl; - //~ std::cout << "alpha: " << alpha << std::endl; - //~ std::cout << "beta: " << beta << std::endl; - if (discriminant.magnitude() > 0) { auto const sqDisc = sqrt(discriminant); auto const invDenom = 1 / vSqNorm; @@ -50,4 +46,17 @@ namespace corsika::process::tracking_line { return {}; } } + + TimeType TimeOfIntersection(Line const& vLine, Plane const& vPlane) { + auto const delta = vPlane.GetCenter() - vLine.GetR0(); + auto const v = vLine.GetV0(); + auto const n = vPlane.GetNormal(); + auto const c = n.dot(v); + + if (c.magnitude() == 0) { + return std::numeric_limits<TimeType::value_type>::infinity() * 1_s; + } else { + return n.dot(delta) / c; + } + } } // namespace corsika::process::tracking_line diff --git a/Processes/TrackingLine/TrackingLine.h b/Processes/TrackingLine/TrackingLine.h index a801a2ee2baa206424211151c6a7fb9a616d0b70..df02264fe6f4c5640fe40c799255e87ce26a958e 100644 --- a/Processes/TrackingLine/TrackingLine.h +++ b/Processes/TrackingLine/TrackingLine.h @@ -13,6 +13,7 @@ #define _include_corsika_processes_TrackingLine_h_ #include <corsika/geometry/Line.h> +#include <corsika/geometry/Plane.h> #include <corsika/geometry/Sphere.h> #include <corsika/geometry/Trajectory.h> #include <corsika/geometry/Vector.h> @@ -33,8 +34,10 @@ namespace corsika::process { namespace tracking_line { std::optional<std::pair<corsika::units::si::TimeType, corsika::units::si::TimeType>> - TimeOfIntersection(corsika::geometry::Line const& line, - geometry::Sphere const& sphere); + TimeOfIntersection(geometry::Line const&, geometry::Sphere const&); + + corsika::units::si::TimeType TimeOfIntersection(geometry::Line const&, + geometry::Plane const&); class TrackingLine { diff --git a/Processes/UrQMD/UrQMD.cc b/Processes/UrQMD/UrQMD.cc index df4456bfb965f398720e33aafd286ed56bbdb307..98f7a7385727d30836e7590bfb6bd54f8de4f542 100644 --- a/Processes/UrQMD/UrQMD.cc +++ b/Processes/UrQMD/UrQMD.cc @@ -2,9 +2,6 @@ #include <corsika/geometry/Vector.h> #include <corsika/particles/ParticleProperties.h> #include <corsika/process/urqmd/UrQMD.h> -#include <corsika/random/RNGManager.h> -#include <corsika/setup/SetupStack.h> -#include <corsika/setup/SetupTrajectory.h> #include <corsika/units/PhysicalUnits.h> #include <algorithm> @@ -20,7 +17,6 @@ UrQMD::UrQMD() { iniurqmd_(); } using SetupStack = corsika::setup::Stack; using SetupParticle = corsika::setup::Stack::StackIterator; using SetupProjectile = corsika::setup::StackView::StackIterator; -using SetupTrack = corsika::setup::Trajectory; template <typename TParticle> // need template here, as this is called both with // SetupParticle as well as SetupProjectile @@ -82,7 +78,7 @@ bool UrQMD::CanInteract(particles::Code vCode) const { vCode) != std::cend(validProjectileCodes); } -GrammageType UrQMD::GetInteractionLength(SetupParticle& vParticle, SetupTrack&) const { +GrammageType UrQMD::GetInteractionLength(SetupParticle& vParticle) const { if (!CanInteract(vParticle.GetPID())) { // we could do the canInteract check in GetCrossSection, too but if // we do it here we have the advantage of avoiding the loop diff --git a/Processes/UrQMD/UrQMD.h b/Processes/UrQMD/UrQMD.h index 0b34e2e147a94c58a933d0cf508a428be5c7b917..a77e6e843b38055bc96c470c79f2902fcfa58ce5 100644 --- a/Processes/UrQMD/UrQMD.h +++ b/Processes/UrQMD/UrQMD.h @@ -5,7 +5,6 @@ #include <corsika/process/InteractionProcess.h> #include <corsika/random/RNGManager.h> #include <corsika/setup/SetupStack.h> -#include <corsika/setup/SetupTrajectory.h> #include <corsika/units/PhysicalUnits.h> #include <array> @@ -15,8 +14,9 @@ namespace corsika::process::UrQMD { class UrQMD : public corsika::process::InteractionProcess<UrQMD> { public: UrQMD(); + void Init() {} corsika::units::si::GrammageType GetInteractionLength( - corsika::setup::Stack::StackIterator&, corsika::setup::Trajectory&) const; + corsika::setup::Stack::StackIterator&) const; template <typename TParticle> corsika::units::si::CrossSectionType GetCrossSection(TParticle const&, diff --git a/README.md b/README.md index 67dd505f0d4dafc3f5ee73e055df7e4754429c99..d5cf8f7c2764daf2fe25f5c861502318a7ea4026 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ CORSIKA 8 is tested regularly at least on gcc7.3.0 and clang-6.0.0. Additional software prerequisites: eigen3, boost, cmake, g++, git. On a bare Ubuntu 18.04, just add: ``` -sudo apt-get install libeigen3-dev libboost-dev cmake g++ git +sudo apt install libeigen3-dev cmake g++ git ``` Follow these steps to download and install CORSIKA 8 milestone2