diff --git a/Documentation/Examples/cascade_example.cc b/Documentation/Examples/cascade_example.cc index 615c2e1bdd71b2bfc12da6cad825f4157540de78..18c03158ab46f9909d06860f04cb2a173a88ae00 100644 --- a/Documentation/Examples/cascade_example.cc +++ b/Documentation/Examples/cascade_example.cc @@ -216,9 +216,9 @@ public: HEPEnergyType GetEmEnergy() const { return fEmEnergy; } }; +template <bool deleteParticle> struct MyBoundaryCrossingProcess - : public BoundaryCrossingProcess<MyBoundaryCrossingProcess> { - //~ environment::BaseNodeType const& fA, fB; + : public BoundaryCrossingProcess<MyBoundaryCrossingProcess<deleteParticle>> { MyBoundaryCrossingProcess(std::string const& filename) { fFile.open(filename); } @@ -226,12 +226,7 @@ struct MyBoundaryCrossingProcess EProcessReturn DoBoundaryCrossing(Particle& p, typename Particle::BaseNodeType const& from, typename Particle::BaseNodeType const& to) { - std::cout << "boundary crossing! from: " << from.GetModelProperties().GetName() - << "; to: " << to.GetModelProperties().GetName() << std::endl; - - //~ if ((&fA == &from && &fB == &to) || (&fA == &to && &fB == &from)) { - p.Delete(); - //~ } + std::cout << "boundary crossing! from: " << &from << "; to: " << &to << std::endl; auto const& name = particles::GetName(p.GetPID()); auto const start = p.GetPosition().GetCoordinates(); @@ -239,25 +234,15 @@ struct MyBoundaryCrossingProcess fFile << name << " " << start[0] / 1_m << ' ' << start[1] / 1_m << ' ' << start[2] / 1_m << '\n'; + if constexpr (deleteParticle) { p.Delete(); } + return EProcessReturn::eOk; } - std::ofstream fFile; - void Init() {} -}; -template <class T> -class TheNameModel : public T { - std::string const fName; - -public: - template <typename... Args> - TheNameModel(std::string const& name, Args&&... args) - : T(std::forward<Args>(args)...) - , fName(name) {} - - std::string const& GetName() const override { return fName; } +private: + std::ofstream fFile; }; // @@ -273,41 +258,29 @@ int main() { EnvType env; auto& universe = *(env.GetUniverse()); - auto outerMedium = - EnvType::CreateNode<Sphere>(Point{env.GetCoordinateSystem(), 0_m, 0_m, 0_m}, - 1_km * std::numeric_limits<double>::infinity()); + const CoordinateSystem& rootCS = env.GetCoordinateSystem(); + + auto outerMedium = EnvType::CreateNode<Sphere>( + Point{rootCS, 0_m, 0_m, 0_m}, 1_km * std::numeric_limits<double>::infinity()); // fraction of oxygen const float fox = 0.20946; - outerMedium->SetModelProperties< - TheNameModel<environment::HomogeneousMedium<setup::IEnvironmentModel>>>( - "outer", 1_kg / (1_m * 1_m * 1_m), - environment::NuclearComposition( - std::vector<particles::Code>{particles::Code::Nitrogen, - particles::Code::Oxygen}, - std::vector<float>{(float)1. - fox, fox})); - - auto innerMedium = EnvType::CreateNode<Sphere>( - Point{env.GetCoordinateSystem(), 0_m, 0_m, -500_m}, 5000_m); - - innerMedium->SetModelProperties< - TheNameModel<environment::HomogeneousMedium<setup::IEnvironmentModel>>>( - "inner", 1_kg / (1_m * 1_m * 1_m), - environment::NuclearComposition( - std::vector<particles::Code>{particles::Code::Nitrogen, - particles::Code::Oxygen}, - std::vector<float>{(float)1. - fox, fox})); + auto const props = + outerMedium + ->SetModelProperties<environment::HomogeneousMedium<setup::IEnvironmentModel>>( + 1_kg / (1_m * 1_m * 1_m), + environment::NuclearComposition( + std::vector<particles::Code>{particles::Code::Nitrogen, + particles::Code::Oxygen}, + std::vector<float>{1.f - fox, fox})); + + auto innerMedium = EnvType::CreateNode<Sphere>(Point{rootCS, 0_m, 0_m, 0_m}, 5000_m); + + innerMedium->SetModelProperties(props); outerMedium->AddChild(std::move(innerMedium)); universe.AddChild(std::move(outerMedium)); - universe.SetModelProperties< - TheNameModel<environment::HomogeneousMedium<setup::IEnvironmentModel>>>( - "Universe", 0_kg / (1_m * 1_m * 1_m), - environment::NuclearComposition( - std::vector<particles::Code>{particles::Code::Proton}, std::vector<float>{1.})); - - const CoordinateSystem& rootCS = env.GetCoordinateSystem(); // setup processes, decays and interactions tracking_line::TrackingLine tracking; @@ -319,17 +292,11 @@ int main() { process::sibyll::Decay decay; ProcessCut cut(20_GeV); - random::RNGManager::GetInstance().RegisterRandomStream("HadronicElasticModel"); - process::HadronicElasticModel::HadronicElasticInteraction hadronicElastic; - process::TrackWriter::TrackWriter trackWriter("tracks.dat"); - MyBoundaryCrossingProcess boundaryCrossing("crossings.dat"); + MyBoundaryCrossingProcess<false> boundaryCrossing("crossings.dat"); // assemble all processes into an ordered process list - // auto sequence = p0 << sibyll << decay << hadronicElastic << cut << trackWriter; - auto sequence = - /*p0 <<*/ sibyll << sibyllNuc << decay << cut /* << hadronicElastic */ - << boundaryCrossing << trackWriter; + auto sequence = sibyll << sibyllNuc << decay << cut << boundaryCrossing << trackWriter; // setup particle stack, and add primary particle setup::Stack stack; @@ -339,30 +306,29 @@ int main() { const int nuclZ = int(nuclA / 2.15 + 0.7); const HEPMassType mass = particles::Proton::GetMass() * nuclZ + (nuclA - nuclZ) * particles::Neutron::GetMass(); - const HEPEnergyType E0 = nuclA * 10_TeV; - double phi = 0; - for (double theta = 0; theta < 180; theta += 20) { - auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { - return sqrt(Elab * Elab - m * m); - }; - HEPMomentumType P0 = elab2plab(E0, mass); - auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) { - return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi), - -ptot * cos(theta)); - }; - auto const [px, py, pz] = - momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0); - auto plab = corsika::stack::MomentumVector(rootCS, {px, py, pz}); - cout << "input particle: " << beamCode << endl; - cout << "input angles: theta=" << theta << " phi=" << phi << endl; - cout << "input momentum: " << plab.GetComponents() / 1_GeV << endl; - Point pos(rootCS, 0_m, 0_m, 0_m); - for (int l = 0; l < 1; ++l) { - stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::stack::MomentumVector, geometry::Point, - units::si::TimeType>{beamCode, E0, plab, pos, 0_ns}); - } - } + const HEPEnergyType E0 = nuclA * 100_TeV; + double const phi = 0; + double const theta = 0; + auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { + return sqrt(Elab * Elab - m * m); + }; + HEPMomentumType P0 = elab2plab(E0, mass); + auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) { + return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi), + -ptot * cos(theta)); + }; + auto const [px, py, pz] = + momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0); + auto plab = corsika::stack::MomentumVector(rootCS, {px, py, pz}); + cout << "input particle: " << beamCode << endl; + cout << "input angles: theta=" << theta << " phi=" << phi << endl; + cout << "input momentum: " << plab.GetComponents() / 1_GeV << endl; + Point pos(rootCS, 0_m, 0_m, 0_m); + + stack.AddParticle( + std::tuple<particles::Code, units::si::HEPEnergyType, + corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{ + beamCode, E0, plab, pos, 0_ns}); // define air shower object, run simulation cascade::Cascade EAS(env, tracking, sequence, stack); diff --git a/Framework/Cascade/Cascade.h b/Framework/Cascade/Cascade.h index a8185a0f10639e2615b64a06a8eea4f3eb6982ab..2d5088ed343530c945f9f16fbd124440088063e3 100644 --- a/Framework/Cascade/Cascade.h +++ b/Framework/Cascade/Cascade.h @@ -20,6 +20,7 @@ #include <corsika/setup/SetupTrajectory.h> #include <corsika/units/PhysicalUnits.h> +#include <cassert> #include <cmath> #include <iostream> #include <type_traits> @@ -91,9 +92,6 @@ namespace corsika::cascade { auto const* numericalNode = fEnvironment.GetUniverse()->GetContainingNode(p.GetPosition()); p.SetNode(numericalNode); - - std::cout << "initial node " << p.GetNode()->GetModelProperties().GetName() - << std::endl; }); } @@ -229,19 +227,15 @@ namespace corsika::cascade { } else { // step-length limitation within volume std::cout << "step-length limitation" << std::endl; } - auto const* numericalNodeAfterStep = - fEnvironment.GetUniverse()->GetContainingNode(particle.GetPosition()); - std::cout << "nodes: " << currentLogicalNode->GetModelProperties().GetName() - << " " << numericalNodeAfterStep->GetModelProperties().GetName() - << std::endl; + auto const assertion = [&] { + auto const* numericalNodeAfterStep = + fEnvironment.GetUniverse()->GetContainingNode(particle.GetPosition()); + return numericalNodeAfterStep == currentLogicalNode; + }; - if (numericalNodeAfterStep != currentLogicalNode) { - std::cout << "position " << particle.GetPosition().GetCoordinates() - << std::endl; - throw std::runtime_error("numerical and logical nodes don't match"); - } - } else { // boundary crossing + assert(assertion()); // numerical and logical nodes don't match + } else { // boundary crossing std::cout << "boundary crossing! next node = " << nextVol << std::endl; particle.SetNode(nextVol); fProcessSequence.DoBoundaryCrossing(particle, *currentLogicalNode, *nextVol); @@ -255,7 +249,7 @@ namespace corsika::cascade { Stack& fStack; corsika::random::RNG& fRNG = corsika::random::RNGManager::GetInstance().GetRandomStream("cascade"); - }; + }; // namespace corsika::cascade } // namespace corsika::cascade diff --git a/Processes/Sibyll/testSibyll.cc b/Processes/Sibyll/testSibyll.cc index 318bb5c2369129ff44e780d3b6fb5c4c2446f7f5..8f9bf45120562a7e31a12683e26e8f3a56931450 100644 --- a/Processes/Sibyll/testSibyll.cc +++ b/Processes/Sibyll/testSibyll.cc @@ -99,6 +99,7 @@ TEST_CASE("SibyllInterface", "[processes]") { environment::NuclearComposition( std::vector<particles::Code>{particles::Code::Oxygen}, std::vector<float>{1.})); + auto const* nodePtr = theMedium.get(); universe.AddChild(std::move(theMedium)); const geometry::CoordinateSystem& cs = env.GetCoordinateSystem(); @@ -123,6 +124,7 @@ TEST_CASE("SibyllInterface", "[processes]") { std::tuple<particles::Code, units::si::HEPEnergyType, corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{ particles::Code::Proton, E0, plab, pos, 0_ns}); + particle.SetNode(nodePtr); Interaction model; @@ -147,6 +149,7 @@ TEST_CASE("SibyllInterface", "[processes]") { corsika::stack::MomentumVector, geometry::Point, units::si::TimeType, unsigned short, unsigned short>{ particles::Code::Nucleus, E0, plab, pos, 0_ns, 4, 2}); + particle.SetNode(nodePtr); Interaction hmodel; NuclearInteraction model(hmodel); diff --git a/Processes/TrackingLine/TrackingLine.h b/Processes/TrackingLine/TrackingLine.h index 4db45da2f7f5730e2123fa0bddd2a64b52bfe98c..e847a3fd7ebef23583c632cc5b71af474c883428 100644 --- a/Processes/TrackingLine/TrackingLine.h +++ b/Processes/TrackingLine/TrackingLine.h @@ -43,7 +43,7 @@ namespace corsika::process { template <typename Particle> // was Stack previously, and argument was // Stack::StackIterator - auto GetTrack(Particle const& p) { + auto GetTrack(Particle const& p) { using namespace corsika::units::si; using namespace corsika::geometry; geometry::Vector<SpeedType::dimension_type> const velocity = @@ -52,8 +52,10 @@ namespace corsika::process { auto const currentPosition = p.GetPosition(); std::cout << "TrackingLine pid: " << p.GetPID() << " , E = " << p.GetEnergy() / 1_GeV << " GeV" << std::endl; - std::cout << "TrackingLine pos: " << currentPosition.GetCoordinates() << " [" - << p.GetNode()->GetModelProperties().GetName() << "]\n"; + std::cout << "TrackingLine pos: " + << currentPosition.GetCoordinates() + // << " [" << p.GetNode()->GetModelProperties().GetName() << "]" + << std::endl; std::cout << "TrackingLine E: " << p.GetEnergy() / 1_GeV << " GeV" << std::endl; std::cout << "TrackingLine p: " << p.GetMomentum().GetComponents() / 1_GeV << " GeV " << std::endl; @@ -84,8 +86,10 @@ namespace corsika::process { if (auto opt = TimeOfIntersection(line, sphere); opt.has_value()) { auto const [t1, t2] = *opt; - std::cout << "intersection times: " << t1 / 1_s << "; " << t2 / 1_s << " " - << vtn.GetModelProperties().GetName() << std::endl; + std::cout << "intersection times: " << t1 / 1_s << "; " + << t2 / 1_s + // << " " << vtn.GetModelProperties().GetName() + << std::endl; if (t1.magnitude() > 0) intersections.emplace_back(t1, &vtn); else if (t2.magnitude() > 0) @@ -119,10 +123,10 @@ namespace corsika::process { min = minIter->first; } - std::cout << " t-intersect: " << min << " " - << minIter->second->GetModelProperties().GetName() << std::endl; - //~ std::cout << "point of intersection: " << - //line.GetPosition(min).GetCoordinates() << std::endl; + std::cout << " t-intersect: " + << min + // << " " << minIter->second->GetModelProperties().GetName() + << std::endl; return std::make_tuple(geometry::Trajectory<geometry::Line>(line, min), velocity.norm() * min, minIter->second); diff --git a/Setup/SetupEnvironment.h b/Setup/SetupEnvironment.h index f55cda3507ec882e10301e3bce95e3e5d1719914..83397da951f2d7594fea3e2c5a3dfa1d2b88da19 100644 --- a/Setup/SetupEnvironment.h +++ b/Setup/SetupEnvironment.h @@ -12,13 +12,13 @@ #ifndef _include_corsika_setup_environment_h_ #define _include_corsika_setup_environment_h_ +#include <corsika/environment/Environment.h> #include <corsika/environment/IMediumModel.h> #include <corsika/environment/NameModel.h> -#include <corsika/environment/Environment.h> namespace corsika::setup { - using IEnvironmentModel = environment::NameModel<environment::IMediumModel>; + using IEnvironmentModel = environment::IMediumModel; using SetupEnvironment = environment::Environment<IEnvironmentModel>; -} +} // namespace corsika::setup #endif