Newer
Older
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#include <corsika/cascade/testCascade.h>
#include <corsika/cascade/Cascade.h>
#include <corsika/process/ProcessSequence.h>
#include <corsika/process/stack_inspector/StackInspector.h>
#include <corsika/process/tracking_line/TrackingLine.h>
ralfulrich
committed
#include <corsika/particles/ParticleProperties.h>
#include <corsika/environment/HomogeneousMedium.h>
#include <corsika/environment/NuclearComposition.h>
ralfulrich
committed
using namespace corsika;
using namespace corsika::process;
using namespace corsika::units;
#include <limits>
auto MakeDummyEnv() {
TestEnvironmentType env; // dummy environment
auto theMedium = TestEnvironmentType::CreateNode<Sphere>(
100_km * std::numeric_limits<double>::infinity());
using MyHomogeneousModel = environment::HomogeneousMedium<environment::IMediumModel>;
1_g / (1_cm * 1_cm * 1_cm),
environment::NuclearComposition(
std::vector<particles::Code>{particles::Code::Proton}, std::vector<float>{1.}));
universe.AddChild(std::move(theMedium));
return env;
}
class ProcessSplit : public process::InteractionProcess<ProcessSplit> {
GrammageType fX0;
ProcessSplit(GrammageType const X0)
: fX0(X0) {}
template <typename Particle>
corsika::units::si::GrammageType GetInteractionLength(Particle const&) const {
return fX0;
template <typename TProjectile>
corsika::process::EProcessReturn DoInteraction(TProjectile& vP) {
fCalls++;
const HEPEnergyType E = vP.GetEnergy();
vP.AddSecondary(
std::tuple<particles::Code, units::si::HEPEnergyType,
corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{
vP.GetPID(), E / 2, vP.GetMomentum(), vP.GetPosition(), vP.GetTime()});
vP.AddSecondary(
std::tuple<particles::Code, units::si::HEPEnergyType,
corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{
vP.GetPID(), E / 2, vP.GetMomentum(), vP.GetPosition(), vP.GetTime()});
return EProcessReturn::eInteracted;
}
void Init() { fCalls = 0; }
int GetCalls() const { return fCalls; }
};
class ProcessCut : public process::SecondariesProcess<ProcessCut> {
int fCount = 0;
int fCalls = 0;
HEPEnergyType fEcrit;
ProcessCut(HEPEnergyType e)
template <typename TStack>
EProcessReturn DoSecondaries(TStack& vS) {
auto p = vS.begin();
while (p != vS.end()) {
HEPEnergyType E = p.GetEnergy();
if (E < fEcrit) {
p.Delete();
fCount++;
} else {
++p; // next particle
}
cout << "ProcessCut::DoSecondaries size=" << vS.GetSize() << " count=" << fCount
<< endl;
return EProcessReturn::eOk;
fCount = 0;
};
TEST_CASE("Cascade", "[Cascade]") {
random::RNGManager& rmng = random::RNGManager::GetInstance();
auto const& rootCS = env.GetCoordinateSystem();
tracking_line::TrackingLine tracking;
stack_inspector::StackInspector<TestCascadeStack> stackInspect(1, true, E0);
const GrammageType X0 = 20_g / square(1_cm);
ProcessSplit split(X0);
ProcessCut cut(Ecrit);
auto sequence = nullModel << stackInspect << split << cut;
std::tuple<particles::Code, units::si::HEPEnergyType,
corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{
particles::Code::Electron, E0,
corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, -1_GeV}),
Point(rootCS, {0_m, 0_m, 10_km}), 0_ns});
cascade::Cascade<tracking_line::TrackingLine, decltype(sequence), TestCascadeStack,
TestCascadeStackView>
EAS(env, tracking, sequence, stack);
SECTION("full cascade") {
EAS.Run();
CHECK(cut.GetCount() == 2048);
CHECK(cut.GetCalls() == 2047);
CHECK(split.GetCalls() == 2047);
}
SECTION("forced interaction") {
EAS.SetNodes();
EAS.forceInteraction();
CHECK(stack.GetSize() == 2);
CHECK(split.GetCalls() == 1);
}