IAP GITLAB

Skip to content
Snippets Groups Projects
Cascade.h 6.29 KiB
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_
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
#include <corsika/environment/Environment.h>
ralfulrich's avatar
ralfulrich committed
#include <corsika/process/ProcessReturn.h>
ralfulrich's avatar
ralfulrich committed
#include <corsika/random/RNGManager.h>
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
#include <corsika/random/UniformRealDistribution.h>
#include <corsika/setup/SetupTrajectory.h>
#include <corsika/units/PhysicalUnits.h>
namespace corsika::cascade {

  template <typename Tracking, typename ProcessList, typename Stack>
  class Cascade {
    using Particle = typename Stack::ParticleType;
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
    Cascade(corsika::environment::Environment const& env, Tracking& tr, ProcessList& pl,
            Stack& stack)
        : fEnvironment(env)
        , fTracking(tr)
        , fProcessSequence(pl)
Ralf Ulrich's avatar
Ralf Ulrich committed
        , fStack(stack) {}
      fTracking.Init();
      fProcessSequence.Init();
      fStack.Init();
    }

    void Run() {
      while (!fStack.IsEmpty()) {
        while (!fStack.IsEmpty()) {
ralfulrich's avatar
ralfulrich committed
          Particle pNext = *fStack.GetNextParticle();
        }
        // do cascade equations, which can put new particles on Stack,
        // thus, the double loop
ralfulrich's avatar
ralfulrich committed
        // DoCascadeEquations();
    void Step(Particle& particle) {
ralfulrich's avatar
ralfulrich committed
      using namespace corsika::units::si;
      // determine geometric tracking
      corsika::setup::Trajectory step = fTracking.GetTrack(particle);

      // determine combined total interaction length (inverse)
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
      InverseGrammageType const total_inv_lambda =
          fProcessSequence.GetTotalInverseInteractionLength(particle, step);
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
      // sample random exponential step length in grammage
      std::exponential_distribution expDist(total_inv_lambda * (1_g / (1_m * 1_m)));
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
      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;

Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
      // convert next_step from grammage to length
      auto const* currentNode =
          fEnvironment.GetUniverse()->GetContainingNode(particle.GetPosition());

      if (currentNode == &*fEnvironment.GetUniverse()) {
        throw std::runtime_error("particle entered void universe");
      }

Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
      LengthType const distance_interact =
          currentNode->GetModelProperties().ArclengthFromGrammage(step, next_interact);
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed

      // 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
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
      InverseTimeType const total_inv_lifetime =
          fProcessSequence.GetTotalInverseLifetime(particle);
      // sample random exponential decay time
      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]
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
      LengthType const distance_decay = next_decay * particle.GetMomentum().norm() /
                                        particle.GetEnergy() *
ralfulrich's avatar
ralfulrich committed
                                        corsika::units::constants::c;

      // take minimum of geometry, interaction, decay for next step
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
      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:
Ralf Ulrich's avatar
Ralf Ulrich committed
      // std::visit(corsika::setup::ParticleUpdate<Particle>{particle}, step);
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
      particle.SetPosition(step.PositionFromArclength(min_distance));
      // .... also update time, momentum, direction, ...

      // apply all continuous processes on particle + track
ralfulrich's avatar
ralfulrich committed
      corsika::process::EProcessReturn status =
          fProcessSequence.DoContinuous(particle, step, fStack);
ralfulrich's avatar
ralfulrich committed
      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 ? "
ralfulrich's avatar
ralfulrich committed
                << ((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
ralfulrich's avatar
ralfulrich committed

        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);
ralfulrich's avatar
ralfulrich committed

ralfulrich's avatar
ralfulrich committed
    corsika::environment::Environment const& fEnvironment;
    Tracking& fTracking;
    ProcessList& fProcessSequence;
    corsika::random::RNG& fRNG =
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
        corsika::random::RNGManager::GetInstance().GetRandomStream("cascade");
} // namespace corsika::cascade