From 63528c40e3f1341e564e63b3c41e7512c71fc46b Mon Sep 17 00:00:00 2001 From: Felix Riehn <felix@matilda> Date: Tue, 11 May 2021 19:08:30 +0100 Subject: [PATCH] corsika/detail/modules/epos/Interaction.inl --- corsika/modules/epos/Interaction.hpp | 29 ++++-- corsika/modules/epos/Random.hpp | 8 +- modules/epos/epos.cpp | 14 ++- modules/epos/epos.hpp | 135 ++++++++++++++++++++++++++- tests/modules/testEpos.cpp | 37 +++++++- 5 files changed, 207 insertions(+), 16 deletions(-) diff --git a/corsika/modules/epos/Interaction.hpp b/corsika/modules/epos/Interaction.hpp index 7c5e179dd..9505e6145 100644 --- a/corsika/modules/epos/Interaction.hpp +++ b/corsika/modules/epos/Interaction.hpp @@ -17,29 +17,46 @@ namespace corsika::epos { class Interaction : public InteractionProcess<Interaction> { - + std::string data_path_; + unsigned int count_ = 0; + public: - Interaction(); + Interaction(const std::string& dataPath = ""); ~Interaction(); - //! returns production and elastic cross section for hadrons in sibyll. Inputs are: + //! returns production and elastic cross section for hadrons in epos. Inputs are: //! CorsikaId of beam particle, CorsikaId of target particle and center-of-mass //! energy. Allowed targets are: nuclei or single nucleons (p,n,hydrogen). - CrossSectionType getCrossSection(Code const, Code const, HEPEnergyType const) const; + std::tuple<CrossSectionType, CrossSectionType> getCrossSection( + Code const, Code const, HEPEnergyType const) const; template <typename TParticle> GrammageType getInteractionLength(TParticle const&) const; /** - In this function SIBYLL is called to produce one event. The + In this function EPOSLHC is called to produce one event. The event is copied (and boosted) into the shower lab frame. */ template <typename TSecondaries> void doInteraction(TSecondaries&); + bool isValidCoMEnergy(HEPEnergyType const ecm) const { + return (minEnergyCoM_ <= ecm) && (ecm <= maxEnergyCoM_); + } + //! eposlhc only accepts nuclei with 4<=A<=18 as targets, or protons aka Hydrogen or + //! neutrons (p,n == nucleon) + bool isValidTarget(Code const TargetId) const { + return false; + } + + void initialize_eposlhc_c7(); + private: default_prng_type& RNG_ = RNGManager::getInstance().getRandomStream("epos"); - unsigned int count_; + HEPEnergyType const minEnergyCoM_ = -10. * 1e9 * electronvolt; + HEPEnergyType const maxEnergyCoM_ = -1.e6 * 1e9 * electronvolt; + int const maxTargetMassNumber_ = -1; + int const minNuclearTargetA_ = -10; }; } // namespace corsika::epos diff --git a/corsika/modules/epos/Random.hpp b/corsika/modules/epos/Random.hpp index 1e7e7bc7c..c3fec35ab 100644 --- a/corsika/modules/epos/Random.hpp +++ b/corsika/modules/epos/Random.hpp @@ -14,17 +14,17 @@ /** * \file epos/Random.hpp * - * This file is an integral part of the sibyll interface. It must be - * linked to the executable linked to sibyll exactly once + * This file is an integral part of the epos interface. It must be + * linked to the executable linked to epos exactly once * */ namespace epos { - double rndm_interface() { + float rndm_interface() { static corsika::default_prng_type& rng = corsika::RNGManager::getInstance().getRandomStream("epos"); - std::uniform_real_distribution<double> dist; + std::uniform_real_distribution<float> dist; return dist(rng); } diff --git a/modules/epos/epos.cpp b/modules/epos/epos.cpp index 757fba685..1836776c7 100644 --- a/modules/epos/epos.cpp +++ b/modules/epos/epos.cpp @@ -1,4 +1,5 @@ #include <epos.hpp> +#include <iostream> namespace epos { @@ -8,7 +9,18 @@ namespace epos { // this is needed as linker object, but it is not needed to do anything void ranfcv_(double&) {} - double rangen_() { return ::epos::rndm_interface(); } + float rangen_() { return ::epos::rndm_interface(); } + datadir::datadir(const std::string& dir) { + if (dir.length() > 500) { + std::cerr << "Epos error, will cut datadir \"" << dir + << "\" to 500 characters: " << std::endl; + } + int i = 0; + for (i = 0; i < std::min(500, int(dir.length())); ++i) data[i] = dir[i]; + data[i + 0] = ' '; + data[i + 1] = '\0'; + length = dir.length(); + } } diff --git a/modules/epos/epos.hpp b/modules/epos/epos.hpp index 47c2939d2..d7799369a 100644 --- a/modules/epos/epos.hpp +++ b/modules/epos/epos.hpp @@ -9,6 +9,7 @@ #pragma once #include <array> +#include <string> /** * \file epos.hpp @@ -24,13 +25,15 @@ namespace epos { * * CORSIKA8, for example, has to provide an implementation of this. **/ - extern double rndm_interface(); + extern float rndm_interface(); extern "C" { void aaset_(int&); void atitle_(); - double LHCparameters_(); + void ainit_(); + void aepos_(int&); + double lhcparameters_(); void hdecin_(bool&); void hnbspd_(int&); void hnbpajini_(); @@ -59,8 +62,7 @@ namespace epos { void ranfini_(double&, int&, int&); void ranfcv_(double&); // void ranfgt(int&); - double rangen_(); - + float rangen_(); // common blocks as // defined in epos.inc @@ -95,6 +97,12 @@ namespace epos { int model; } appli_; + extern struct { + int iapplxs; + int modelxs; + } xsappli_; + + extern struct { int nevent; int nfull; @@ -102,6 +110,21 @@ namespace epos { int ninicon; } events_; + extern struct { + int neventxs; + int iframexs; + } xsevent_; + + // common/metr1/iospec,iocova,iopair,iozero,ioflac,iomom + extern struct { + int iospec; + int iocova; + int iopair; + int iozero; + int ioflac; + int iomom; + } metr1_; + extern struct { int ifrade; int iframe; @@ -272,5 +295,109 @@ namespace epos { // bimevt, kolevt, koievt, pmxevt, egyevt, npjevt , ntgevt, npnevt, nppevt, ntnevt, // ntpevt, jpnevt, jppevt, jtnevt, jtpevt , xbjevt, qsqevt, nglevt, zppevt, zptevt, // minfra, maxfra, kohevt + + // common/cseed/seedi,seedj,seedj2,seedc,iseqini,iseqsim + extern struct { + double seedi; + double seedj; + double seedj2; + double seedc; + int iseqini; + int iseqsim; + } cseed_; + + // integer istore,istmax,irescl,ntrymx,nclean,iopdg,ioidch + // common/othe1/istore,istmax,gaumx,irescl,ntrymx,nclean,iopdg,ioidch + extern struct { + int istore; + int istmax; + int gaumx; + int irescl; + int ntrymx; + int nclean; + int iopdg; + int ioidch; + } othe1_; + + // character*500 fnch,fnhi,fndt,fnii,fnid,fnie,fnrj,fnmt + // * ,fngrv,fncp,fnnx,fncs,fndr,fnhpf + // common/fname/ fnch, fnhi, fndt, fnii, fnid, fnie, fnrj, fnmt + // * ,fngrv,fncp,fnnx,fncs,fndr,fnhpf + extern struct { + char fnch[500]; + char fnhi[500]; + char fndt[500]; + char fnii[500]; + char fnid[500]; + char fnie[500]; + char fnrj[500]; + char fnmt[500]; + char fngrv[500]; + char fncp[500]; + char fnnx[500]; + char fncs[500]; + char fndr[500]; + char fnhpf[500]; + + } fname_; + + // integer nfnch,nfnhi,nfndt,nfnii,nfnid,nfnie,nfnrj,nfnmt + // *,nfngrv,nfncp,nfnnx,nfncs,nfndr,nfnhpf + // common/nfname/nfnch,nfnhi,nfndt,nfnii,nfnid,nfnie,nfnrj,nfnmt + // *,nfngrv,nfncp,nfnnx,nfncs,nfndr,nfnhpf + extern struct { + int nfnch; + int nfnhi; + int nfndt; + int nfnii; + int nfnid; + int nfnie; + int nfnrj; + int nfnmt; + int nfngrv; + int nfncp; + int nfnnx; + int nfncs; + int nfndr; + int nfnhpf; + } nfname_; + + // integer iprmpt,ish,ishsub,irandm,irewch,iecho,modsho,idensi + // common/prnt1/iprmpt,ish,ishsub,irandm,irewch,iecho,modsho,idensi + extern struct { + int iprmpt; + int ish; + int ishsub; + int irandm; + int irewch; + int iecho; + int modsho; + int idensi; + } prnt1_; + unsigned int constexpr mmry = 1; + unsigned int constexpr mxptl = 200000 / mmry; + // real pptl,tivptl,xorptl + // integer nptl,iorptl,idptl,istptl,ifrptl,jorptl,ibptl,ityptl + // common/cptl/nptl,pptl(5,mxptl),iorptl(mxptl),idptl(mxptl) + extern struct { + int nptl; + float pptl[mxptl][5]; + int iorptl[mxptl]; + int idptl[mxptl]; + } cptl_; + + /** + Small helper class to provide a data-directory name in the format eposlhc expects + */ + class datadir { + private: + datadir operator=(const std::string& dir); + datadir operator=(const datadir&); + + public: + datadir(const std::string& dir); + char data[500]; + int length; + }; } } // namespace epos diff --git a/tests/modules/testEpos.cpp b/tests/modules/testEpos.cpp index f0b01ce36..e00ca7dbd 100644 --- a/tests/modules/testEpos.cpp +++ b/tests/modules/testEpos.cpp @@ -81,7 +81,38 @@ TEST_CASE("EposInterface", "[processes]") { auto const& cs = *csPtr; [[maybe_unused]] auto const& env_dummy = env; - // RNGManager::getInstance().registerRandomStream("epos"); + RNGManager::getInstance().registerRandomStream("epos"); + + SECTION("InteractionInterface - random number"){ + auto const rndm = ::epos::rangen_(); + CHECK(rndm>0); + CHECK(rndm<1); + } + + SECTION("InteractionInterface - valid targets") { + + Interaction model; + // eposlhc accepts protons or nuclei with 4<=A<=18 as targets + CHECK_FALSE(model.isValidTarget(Code::Electron)); + CHECK(model.isValidTarget(Code::Hydrogen)); + CHECK_FALSE(model.isValidTarget(Code::Deuterium)); + CHECK(model.isValidTarget(Code::Helium)); + CHECK_FALSE(model.isValidTarget(Code::Helium3)); + CHECK_FALSE(model.isValidTarget(Code::Iron)); + CHECK(model.isValidTarget(Code::Oxygen)); + + // hydrogen target == proton target == neutron target + auto const [xs_prod_pp, xs_ela_pp] = + model.getCrossSection(Code::Proton, Code::Proton, 100_GeV); + auto const [xs_prod_pn, xs_ela_pn] = + model.getCrossSection(Code::Proton, Code::Neutron, 100_GeV); + auto const [xs_prod_pHydrogen, xs_ela_pHydrogen] = + model.getCrossSection(Code::Proton, Code::Hydrogen, 100_GeV); + CHECK(xs_prod_pp == xs_prod_pHydrogen); + CHECK(xs_prod_pp == xs_prod_pn); + CHECK(xs_ela_pp == xs_ela_pHydrogen); + CHECK(xs_ela_pn == xs_ela_pHydrogen); + } SECTION("InteractionInterface - low energy") { @@ -96,6 +127,10 @@ TEST_CASE("EposInterface", "[processes]") { Interaction model; model.doInteraction(view); + + [[maybe_unused]] const GrammageType length = model.getInteractionLength(particle); + CHECK(length / 1_g * 1_cm * 1_cm == Approx(88.7).margin(0.1)); + } } -- GitLab