From aa57373744a70ace0ea37b035b4fdc629b42a359 Mon Sep 17 00:00:00 2001 From: Maximilian Reininghaus <maximilian.reininghaus@kit.edu> Date: Mon, 21 Jan 2019 11:53:43 +0100 Subject: [PATCH] changed implementation to PYTHIA-like --- Framework/Units/PhysicalConstants.h | 3 + .../HadronicElasticModel.h | 70 +++++++++---------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/Framework/Units/PhysicalConstants.h b/Framework/Units/PhysicalConstants.h index ae47bd34d..38c59992f 100644 --- a/Framework/Units/PhysicalConstants.h +++ b/Framework/Units/PhysicalConstants.h @@ -53,9 +53,12 @@ namespace corsika::units::constants { constexpr quantity<speed_d> c{Rep(299792458L) * meter / second}; constexpr auto cSquared = c * c; + // hbar * c constexpr quantity<dimensions<1, 0, 0, 0, 0, 0, 0, 1>> hBarC{ Rep(1.973'269'78e-7L) * electronvolt * meter}; // from RPP 2018 + auto constexpr invGeVsq = 1e-18 / (electronvolt * electronvolt); + // unified atomic mass unit constexpr quantity<mass_d> u{Rep(1.6605402e-27L) * kilogram}; diff --git a/Processes/HadronicElasticModel/HadronicElasticModel.h b/Processes/HadronicElasticModel/HadronicElasticModel.h index 243d9727e..0e7dc954d 100644 --- a/Processes/HadronicElasticModel/HadronicElasticModel.h +++ b/Processes/HadronicElasticModel/HadronicElasticModel.h @@ -36,8 +36,10 @@ namespace corsika::process::HadronicElasticModel { : public corsika::process::InteractionProcess<HadronicElasticInteraction> { private: corsika::units::si::CrossSectionType const fX, fY; - static double constexpr fEpsilon = 0.0808; - static double constexpr fEta = 0.4525; + + static double constexpr gfEpsilon = 0.0808; + static double constexpr gfEta = 0.4525; + // Froissart-Martin is not violated up for sqrt s < 10^32 eV with these values [DL]. using SquaredHEPEnergyType = decltype(corsika::units::si::HEPEnergyType() * corsika::units::si::HEPEnergyType()); @@ -47,33 +49,32 @@ namespace corsika::process::HadronicElasticModel { "HadronicElasticModel"); corsika::environment::Environment const& fEnvironment; - auto B(corsika::units::si::HEPEnergyType sqrtS) const { - using namespace corsika::units::si; - auto constexpr a = - 2.5 / (1_GeV * 1_GeV); // read off by eye from Gaisser, Engel, Resconi, fig. 4.9 - auto constexpr b = 10 / (1_GeV * 1_GeV); - return a * std::log10(sqrtS / 10_GeV) + b; + auto B(decltype(units::si::detail::static_pow<2>(units::si::electronvolt)) s) const { + using namespace corsika::units::constants; + auto constexpr b_p = 2.3; + return (2 * b_p + 2 * b_p + 4 * pow(s * invGeVsq, gfEpsilon) - 4.2) * invGeVsq; } corsika::units::si::CrossSectionType CrossSection(SquaredHEPEnergyType s) const { using namespace corsika::units::si; - // according to Gaisser, Engel, Resconi, eq. (4.41) - // assuming every target behaves like a proton - CrossSectionType const sigmaTot = fX * pow(s * (1 / (1_GeV * 1_GeV)), fEpsilon) + - fY * pow(s * (1 / (1_GeV * 1_GeV)), -fEta); + using namespace corsika::units::constants; + // assuming every target behaves like a proton, fX and fY are universal + CrossSectionType const sigmaTot = + fX * pow(s * invGeVsq, gfEpsilon) + fY * pow(s * invGeVsq, -gfEta); - // we ignore rho because rho^2 is just ~2 % + // according to Schuler & Sjöstrand, PRD 49, 2257 (1994) + // (we ignore rho because rho^2 is just ~2 %) auto const sigmaElastic = - sigmaTot * sigmaTot / - (16 * M_PI * ConvertHEPToSI<CrossSectionType::dimension_type>(B(sqrt(s)))); + units::si::detail::static_pow<2>(sigmaTot) / + (16 * M_PI * ConvertHEPToSI<CrossSectionType::dimension_type>(B(s))); return sigmaElastic; } public: HadronicElasticInteraction(corsika::environment::Environment const&, - units::si::CrossSectionType x = 2.17e-5 * units::si::barn, - units::si::CrossSectionType y = 5.608e-5 * - units::si::barn); + // x & y values taken from Pythia8 for pp collisions + units::si::CrossSectionType x = 0.217 * units::si::barn, + units::si::CrossSectionType y = 0.5608 * units::si::barn); void Init(); template <typename Particle, typename Track> @@ -126,6 +127,7 @@ namespace corsika::process::HadronicElasticModel { } using namespace units::si; + using namespace units::constants; const auto* currentNode = fEnvironment.GetUniverse()->GetContainingNode(p.GetPosition()); @@ -166,8 +168,8 @@ namespace corsika::process::HadronicElasticModel { auto const sqrtS = eProjectileCoM + eTargetCoM; auto const s = units::si::detail::static_pow<2>(sqrtS); - - auto const B = this->B(sqrtS); + + auto const B = this->B(s); std::cout << B << std::endl; corsika::random::ExponentialDistribution tDist(1 / B); @@ -176,41 +178,35 @@ namespace corsika::process::HadronicElasticModel { auto const maxT = 4 * pProjectileCoMSqNorm; do { - // |t| cannot become arbitrarily large, max. given by GEN eq. (4.16), so we just - // throw again until we have an acceptable value note that the formula holds in - // any frame despite of what is stated there + // |t| cannot become arbitrarily large, max. given by GER eq. (4.16), so we just + // throw again until we have an acceptable value. Note that the formula holds in + // any frame despite of what is stated in the book. absT = tDist(fRNG); } while (absT >= maxT); return absT; }(); - auto constexpr GeVsq = 1_GeV * 1_GeV; - std::cout << "s = " << s / GeVsq << " GeV²; absT = " << absT / GeVsq - << " GeV² (max./GeV² = " << 4 * projectileMomentumSquaredNorm / GeVsq + std::cout << "HadronicElasticInteraction: s = " << s * invGeVsq + << " GeV²; absT = " << absT * invGeVsq + << " GeV² (max./GeV² = " << 4 * invGeVsq * projectileMomentumSquaredNorm << ')' << std::endl; auto const theta = - 2 * asin(sqrt(absT / (4 * pProjectileCoMSqNorm))); // would work for in any frame + 2 * + asin(sqrt(absT / (4 * pProjectileCoMSqNorm))); // would work for in any frame auto const phi = phiDist(fRNG); geometry::QuantityVector<units::si::hepmomentum_d> const scatteredMomentum{ pProjectileCoMNorm * sin(theta) * cos(phi), pProjectileCoMNorm * sin(theta) * sin(phi), pProjectileCoMNorm * cos(theta)}; - + auto const [eProjectileScatteredLab, pProjectileScatteredLab] = boost.fromCoM(eProjectileCoM, scatteredMomentum); - - std::cout << "xxx: " << pProjectileScatteredLab.squaredNorm() / p.GetMomentum().squaredNorm() << std::endl; p.SetMomentum(pProjectileScatteredLab); - - // alternatives: 1. do not touch energy - // 2. take back-boosted energy - // 3. recalculate energy from momentum - - //~ p.SetEnergy(sqrt(pProjectileScatteredLab.squaredNorm() + - //~ units::si::detail::static_pow<2>(corsika::particles::GetMass(p.GetPID())))); + p.SetEnergy(eProjectileScatteredLab); // alternatively recalculate energy from + // momentum and mass return process::EProcessReturn::eOk; } -- GitLab