IAP GITLAB

Skip to content
Snippets Groups Projects
VerySimpleModel.cc 3.54 KiB
Newer Older
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
/*
 * (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/process/very_simple_model/VerySimpleModel.h>
#include <corsika/setup/SetupStack.h>
#include <corsika/setup/SetupTrajectory.h>

#include <tuple>

using namespace corsika;
using namespace corsika::units::si;
using namespace corsika::process::very_simple_model;

using SetupParticle = corsika::setup::Stack::StackIterator;
using SetupProjectile = corsika::setup::StackView::StackIterator;

  void VerySimpleModel::Init() {}

  VerySimpleModel::VerySimpleModel() {}

  template <>
  process::EProcessReturn VerySimpleModel::DoInteraction(SetupProjectile& vP) {
    const auto projectileID = vP.GetPID();

    auto const posOrig = vP.GetPosition();
    auto const tOrig = vP.GetTime();
    auto const eProjectileLab = vP.GetEnergy();
    auto const pProjectileLab = vP.GetMomentum();

    const auto* currentNode = vP.GetNode();
    const auto& mediumComposition =
        currentNode->GetModelProperties().GetNuclearComposition();

    // get cross sections for target materials
    auto const& compVec = mediumComposition.GetComponents();
    std::vector<units::si::CrossSectionType> cross_section_of_components(compVec.size());

    for (size_t i = 0; i < compVec.size(); ++i) {
      cross_section_of_components[i] = GetCrossSection(projectileID, compVec[i]);
    }

    const auto corsikaTargetId =
        mediumComposition.SampleTarget(cross_section_of_components, fRNG);

    // add secondaries to corsika stack
    auto const sec1Code = particles::Code::MuPlus;
    auto const sec1E = eProjectileLab;
    auto const sec1P = pProjectileLab;

    auto secondary1 = vP.AddSecondary(
        std::tuple<particles::Code, units::si::HEPEnergyType, stack::MomentumVector,
              geometry::Point, units::si::TimeType>(sec1Code, sec1E, sec1P, posOrig,
                                                    tOrig));

    auto const sec2Code = particles::Code::MuMinus;
    auto const sec2E = eProjectileLab;
    auto const sec2P = pProjectileLab;
    
    auto secondary2 = vP.AddSecondary(
        std::tuple<particles::Code, units::si::HEPEnergyType, stack::MomentumVector,
              geometry::Point, units::si::TimeType>(sec2Code, sec2E, sec2E, posOrig,
                                                    tOrig));

    return process::EProcessReturn::eOk;
  }

  template <>
  corsika::units::si::CrossSectionType GetCrossSection(SetupParticle const& vProjectile,
                                                       particles::Code vTargetCode) {
    if (vProjectile.GetPID() == particles::MuPlus) {
      return 20_mb;
    } else if (vProjectile.GetPID() == particles::MuMinus) {
      return 10_mb;
    } else {
      return 0_mb;
    }
  }

  template <>
  corsika::units::si::GrammageType GetInteractionLength(Projectile const& vP) {
    auto const* currentNode = vP.GetNode();
    const auto& mediumComposition =
        currentNode->GetModelProperties().GetNuclearComposition();

    si::CrossSectionType weightedProdCrossSection = mediumComposition.WeightedSum(
        [=](particles::Code targetID) -> si::CrossSectionType {
          return this->GetCrossSection(corsikaBeamId, targetID);
        });

    GrammageType const int_length = mediumComposition.GetAverageMassNumber() *
                                    units::constants::u / weightedProdCrossSection;

    return int_length;
  }