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.
*/
#ifndef _include_corsika_cascade_Cascade_h_
#define _include_corsika_cascade_Cascade_h_
#include <corsika/setup/SetupTrajectory.h>
#include <corsika/units/PhysicalUnits.h>
#include <cmath>
#include <iostream>
template <typename Tracking, typename ProcessList, typename Stack>
using Particle = typename Stack::ParticleType;
ralfulrich
committed
Cascade() = delete;
Cascade(corsika::environment::Environment const& env, Tracking& tr, ProcessList& pl,
Stack& stack)
: fEnvironment(env)
, fTracking(tr)
}
void Run() {
while (!fStack.IsEmpty()) {
while (!fStack.IsEmpty()) {
ralfulrich
committed
Step(pNext);
}
// do cascade equations, which can put new particles on Stack,
// thus, the double loop
corsika::setup::Trajectory step = fTracking.GetTrack(particle);
// determine combined total interaction length (inverse)
fProcessSequence.GetTotalInverseInteractionLength(particle, step);
std::exponential_distribution expDist(total_inv_lambda * (1_g / (1_m * 1_m)));
GrammageType const next_interact = (1_g / (1_m * 1_m)) * expDist(fRNG);
std::cout << "total_inv_lambda=" << total_inv_lambda
<< ", next_interact=" << next_interact << std::endl;
auto const* currentNode =
fEnvironment.GetUniverse()->GetContainingNode(particle.GetPosition());
if (currentNode == &*fEnvironment.GetUniverse()) {
throw std::runtime_error("particle entered void universe");
}
currentNode->GetModelProperties().ArclengthFromGrammage(step, next_interact);
// determine the maximum geometric step length
LengthType const distance_max = fProcessSequence.MaxStepLength(particle, step);
std::cout << "distance_max=" << distance_max << std::endl;
// determine combined total inverse decay time
InverseTimeType const total_inv_lifetime =
fProcessSequence.GetTotalInverseLifetime(particle);
std::exponential_distribution expDistDecay(total_inv_lifetime * 1_s);
TimeType const next_decay = 1_s * expDistDecay(fRNG);
std::cout << "total_inv_lifetime=" << total_inv_lifetime
<< ", next_decay=" << next_decay << std::endl;
// convert next_decay from time to length [m]
LengthType const distance_decay = next_decay * particle.GetMomentum().norm() /
particle.GetEnergy() *
// take minimum of geometry, interaction, decay for next step
auto const min_distance =
std::min({distance_interact, distance_decay, distance_max});
std::cout << " move particle by : " << min_distance << std::endl;
// here the particle is actually moved along the trajectory to new position:
// std::visit(corsika::setup::ParticleUpdate<Particle>{particle}, step);
particle.SetPosition(step.PositionFromArclength(min_distance));
// .... also update time, momentum, direction, ...
step.LimitEndTo(min_distance);
// apply all continuous processes on particle + track
fProcessSequence.DoContinuous(particle, step, fStack);
if (status == corsika::process::EProcessReturn::eParticleAbsorbed) {
std::cout << "Cascade: delete absorbed particle " << particle.GetPID() << " "
<< particle.GetEnergy() / 1_GeV << "GeV" << std::endl;
particle.Delete();
return;
std::cout << "sth. happening before geometric limit ? "
<< ((min_distance < distance_max) ? "yes" : "no") << std::endl;
if (min_distance < distance_max) { // interaction to happen within geometric limit
// check whether decay or interaction limits this step
if (min_distance == distance_interact) {
std::cout << "collide" << std::endl;
InverseGrammageType const actual_inv_length =
fProcessSequence.GetTotalInverseInteractionLength(particle, step);
corsika::random::UniformRealDistribution<InverseGrammageType> uniDist(
actual_inv_length);
const auto sample_process = uniDist(fRNG);
InverseGrammageType inv_lambda_count = 0. * meter * meter / gram;
fProcessSequence.SelectInteraction(particle, fStack, sample_process,
inv_lambda_count);
} else {
std::cout << "decay" << std::endl;
InverseTimeType const actual_decay_time =
fProcessSequence.GetTotalInverseLifetime(particle);
corsika::random::UniformRealDistribution<InverseTimeType> uniDist(
actual_decay_time);
const auto sample_process = uniDist(fRNG);
InverseTimeType inv_decay_count = 0 / second;
fProcessSequence.SelectDecay(particle, fStack, sample_process, inv_decay_count);
corsika::environment::Environment const& fEnvironment;
ralfulrich
committed
Stack& fStack;
corsika::random::RNG& fRNG =
corsika::random::RNGManager::GetInstance().GetRandomStream("cascade");
} // namespace corsika::cascade