IAP GITLAB

Skip to content
Snippets Groups Projects
cascade_example.cpp 5.75 KiB
Newer Older
ralfulrich's avatar
ralfulrich committed
/*
 * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
ralfulrich's avatar
ralfulrich committed
 *
 * 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.
 */

ralfulrich's avatar
ralfulrich committed
#include <corsika/framework/core/Cascade.hpp>
#include <corsika/framework/process/ProcessSequence.hpp>
#include <corsika/framework/core/PhysicalUnits.hpp>
#include <corsika/framework/random/RNGManager.hpp>
#include <corsika/framework/geometry/Sphere.hpp>
#include <corsika/framework/utility/CorsikaFenv.hpp>
ralfulrich's avatar
ralfulrich committed
#include <corsika/framework/core/Logging.hpp>
ralfulrich's avatar
ralfulrich committed

#include <corsika/output/OutputManager.hpp>
ralfulrich's avatar
ralfulrich committed

#include <corsika/media/Environment.hpp>
#include <corsika/media/HomogeneousMedium.hpp>
#include <corsika/media/NuclearComposition.hpp>
#include <corsika/media/ShowerAxis.hpp>
#include <corsika/media/MediumPropertyModel.hpp>
#include <corsika/media/UniformMagneticField.hpp>

#include <corsika/setup/SetupEnvironment.hpp>
#include <corsika/setup/SetupStack.hpp>
#include <corsika/setup/SetupTrajectory.hpp>

#include <corsika/modules/BetheBlochPDG.hpp>
#include <corsika/modules/StackInspector.hpp>
#include <corsika/modules/Sibyll.hpp>
#include <corsika/modules/ParticleCut.hpp>
#include <corsika/modules/TrackWriter.hpp>
ralfulrich's avatar
ralfulrich committed

ralfulrich's avatar
ralfulrich committed
/*
  NOTE, WARNING, ATTENTION
ralfulrich's avatar
ralfulrich committed
  The .../Random.hpp implement the hooks of external modules to the C8 random
ralfulrich's avatar
ralfulrich committed
  number generator. It has to occur excatly ONCE per linked
  executable. If you include the header below multiple times and
  link this togehter, it will fail.
 */
#include <corsika/modules/sibyll/Random.hpp>
#include <corsika/modules/urqmd/Random.hpp>
ralfulrich's avatar
ralfulrich committed

#include <iostream>
#include <limits>

using namespace corsika;
using namespace std;

//
// The example main program for a particle cascade
//
int main() {

ralfulrich's avatar
ralfulrich committed
  logging::set_level(logging::level::info);

  std::cout << "cascade_example" << std::endl;

ralfulrich's avatar
ralfulrich committed
  const LengthType height_atmosphere = 112.8_km;

  feenableexcept(FE_INVALID);
  // initialize random number sequence(s)
ralfulrich's avatar
ralfulrich committed
  RNGManager::getInstance().registerRandomStream("cascade");
ralfulrich's avatar
ralfulrich committed

  // setup environment, geometry
  setup::Environment env;
ralfulrich's avatar
ralfulrich committed
  auto& universe = *(env.getUniverse());
ralfulrich's avatar
ralfulrich committed

ralfulrich's avatar
ralfulrich committed
  CoordinateSystemPtr const& rootCS = env.getCoordinateSystem();
ralfulrich's avatar
ralfulrich committed

  auto world =
      setup::Environment::createNode<Sphere>(Point{rootCS, 0_m, 0_m, 0_m}, 150_km);
ralfulrich's avatar
ralfulrich committed

ralfulrich's avatar
ralfulrich committed
  using MyHomogeneousModel = MediumPropertyModel<
      UniformMagneticField<HomogeneousMedium<setup::EnvironmentInterface>>>;
ralfulrich's avatar
ralfulrich committed
  // fraction of oxygen
ralfulrich's avatar
ralfulrich committed
  float const fox = 0.20946;
  auto const props = world->setModelProperties<MyHomogeneousModel>(
      Medium::AirDry1Atm, MagneticFieldVector(rootCS, 0_T, 0_T, 0_T),
      1_kg / (1_m * 1_m * 1_m),
ralfulrich's avatar
ralfulrich committed
      NuclearComposition(std::vector<Code>{Code::Nitrogen, Code::Oxygen},
                         std::vector<float>{1.f - fox, fox}));
ralfulrich's avatar
ralfulrich committed

  auto innerMedium =
ralfulrich's avatar
ralfulrich committed
      setup::Environment::createNode<Sphere>(Point{rootCS, 0_m, 0_m, 0_m}, 5000_m);
ralfulrich's avatar
ralfulrich committed

ralfulrich's avatar
ralfulrich committed
  innerMedium->setModelProperties(props);
  world->addChild(std::move(innerMedium));
  universe.addChild(std::move(world));
ralfulrich's avatar
ralfulrich committed

  // setup particle stack, and add primary particle
  setup::Stack stack;
ralfulrich's avatar
ralfulrich committed
  stack.clear();
ralfulrich's avatar
ralfulrich committed
  const Code beamCode = Code::Nucleus;
  const int nuclA = 4;
  const int nuclZ = int(nuclA / 2.15 + 0.7);
ralfulrich's avatar
ralfulrich committed
  const HEPMassType mass = get_nucleus_mass(nuclA, nuclZ);
ralfulrich's avatar
ralfulrich committed
  const HEPEnergyType E0 = nuclA * 1_TeV;
  double theta = 0.;
  double phi = 0.;

  Point const injectionPos(
      rootCS, 0_m, 0_m,
      height_atmosphere); // this is the CORSIKA 7 start of atmosphere/universe

ralfulrich's avatar
ralfulrich committed
  OutputManager output("cascade_outputs");

  ShowerAxis const showerAxis{injectionPos, Vector{rootCS, 0_m, 0_m, -100_km}, env};
ralfulrich's avatar
ralfulrich committed
  {
    auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
      return sqrt((Elab - m) * (Elab + 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);
ralfulrich's avatar
ralfulrich committed
    auto plab = MomentumVector(rootCS, {px, py, pz});
ralfulrich's avatar
ralfulrich committed
    cout << "input particle: " << beamCode << endl;
    cout << "input angles: theta=" << theta << " phi=" << phi << endl;
ralfulrich's avatar
ralfulrich committed
    cout << "input momentum: " << plab.getComponents() / 1_GeV << endl;
    stack.addParticle(
        std::make_tuple(beamCode, E0, plab, injectionPos, 0_ns, nuclA, nuclZ));
ralfulrich's avatar
ralfulrich committed
  }

  // setup processes, decays and interactions
  setup::Tracking tracking;
ralfulrich's avatar
ralfulrich committed
  StackInspector<setup::Stack> stackInspect(1, true, E0);
ralfulrich's avatar
ralfulrich committed
  RNGManager::getInstance().registerRandomStream("sibyll");
  RNGManager::getInstance().registerRandomStream("pythia");
  corsika::sibyll::Interaction sibyll;
  corsika::sibyll::NuclearInteraction sibyllNuc(sibyll, env);
  corsika::sibyll::Decay decay;
ralfulrich's avatar
ralfulrich committed
  // cascade with only HE model ==> HE cut
ralfulrich's avatar
ralfulrich committed
  ParticleCut cut(80_GeV, true, true);
  TrackWriter trackWriter;
ralfulrich's avatar
ralfulrich committed
  output.add("tracks", trackWriter); // register TrackWriter
ralfulrich's avatar
ralfulrich committed

  BetheBlochPDG eLoss{showerAxis};
ralfulrich's avatar
ralfulrich committed

  // assemble all processes into an ordered process list
  auto sequence =
ralfulrich's avatar
ralfulrich committed
      make_sequence(stackInspect, sibyll, sibyllNuc, decay, eLoss, cut, trackWriter);
ralfulrich's avatar
ralfulrich committed

  // define air shower object, run simulation
  Cascade EAS(env, tracking, sequence, output, stack);
ralfulrich's avatar
ralfulrich committed
  EAS.run();
ralfulrich's avatar
ralfulrich committed
  eLoss.printProfile(); // print longitudinal profile
ralfulrich's avatar
ralfulrich committed
  cut.showResults();
ralfulrich's avatar
ralfulrich committed
  const HEPEnergyType Efinal =
ralfulrich's avatar
ralfulrich committed
      cut.getCutEnergy() + cut.getInvEnergy() + cut.getEmEnergy();
ralfulrich's avatar
ralfulrich committed
  cout << "total cut energy (GeV): " << Efinal / 1_GeV << endl
       << "relative difference (%): " << (Efinal / E0 - 1) * 100 << endl;
ralfulrich's avatar
ralfulrich committed
  cout << "total dEdX energy (GeV): " << eLoss.getTotal() / 1_GeV << endl
       << "relative difference (%): " << eLoss.getTotal() / E0 * 100 << endl;
  cut.reset();
ralfulrich's avatar
ralfulrich committed

  output.endOfLibrary();
ralfulrich's avatar
ralfulrich committed
}