diff --git a/Documentation/Examples/vertical_EAS.cc b/Documentation/Examples/vertical_EAS.cc index a19c8bd89b0d7cf32884ed5589d08e11b299e720..e7944b8e63ef5b87ccb83101163c033f9e3c693e 100644 --- a/Documentation/Examples/vertical_EAS.cc +++ b/Documentation/Examples/vertical_EAS.cc @@ -135,8 +135,8 @@ int main(int argc, char** argv) { auto const observationHeight = 0_km + builder.getEarthRadius(); auto const injectionHeight = 112.75_km + builder.getEarthRadius(); auto const t = -observationHeight * cos(thetaRad) + - sqrt(-si::detail::static_pow<2>(sin(thetaRad) * observationHeight) + - si::detail::static_pow<2>(injectionHeight)); + sqrt(-units::static_pow<2>(sin(thetaRad) * observationHeight) + + units::static_pow<2>(injectionHeight)); Point const showerCore{rootCS, 0_m, 0_m, observationHeight}; Point const injectionPos = showerCore + diff --git a/Environment/testEnvironment.cc b/Environment/testEnvironment.cc index 55f316e1b5bfeb73a85aed6c2833447158d03754..b135396567b812dad56e1b6dd515736b1cd1e8f6 100644 --- a/Environment/testEnvironment.cc +++ b/Environment/testEnvironment.cc @@ -51,7 +51,7 @@ TEST_CASE("FlatExponential") { Vector const axis(gCS, QuantityVector<dimensionless_d>(0, 0, 1)); LengthType const lambda = 3_m; - auto const rho0 = 1_g / units::si::detail::static_pow<3>(1_cm); + auto const rho0 = 1_g / units::static_pow<3>(1_cm); FlatExponential<IMediumModel> const medium(gOrigin, axis, rho0, lambda, protonComposition); auto const tEnd = 5_s; @@ -106,7 +106,7 @@ TEST_CASE("SlidingPlanarExponential") { std::vector<float>{1.f}); LengthType const lambda = 3_m; - auto const rho0 = 1_g / units::si::detail::static_pow<3>(1_cm); + auto const rho0 = 1_g / units::static_pow<3>(1_cm); auto const tEnd = 5_s; SlidingPlanarExponential<IMediumModel> const medium(gOrigin, rho0, lambda, @@ -146,7 +146,7 @@ struct Exponential { template <int N> auto Derivative(Point const& p, Vector<dimensionless_d> const& v) const { return v.GetComponents()[0] * (*this)(p) / - corsika::units::si::detail::static_pow<N>(1_m); + corsika::units::static_pow<N>(1_m); } auto FirstDerivative(Point const& p, Vector<dimensionless_d> const& v) const { diff --git a/Framework/Units/PhysicalUnits.h b/Framework/Units/PhysicalUnits.h index 06ca5374fbfb5a8e334c1634b0c697f75819d4cd..9e9f26bde19df00c75d3f99593b471c5c705acb8 100644 --- a/Framework/Units/PhysicalUnits.h +++ b/Framework/Units/PhysicalUnits.h @@ -30,6 +30,19 @@ namespace phys::units { * */ +namespace corsika::units { + template <int N, typename T> + auto constexpr static_pow([[maybe_unused]] T x) { + if constexpr (N == 0) { + return 1; + } else if constexpr (N > 0) { + return x * static_pow<N - 1, T>(x); + } else { + return 1 / static_pow<-N, T>(x); + } + } +} + namespace corsika::units::si { using namespace phys::units; using namespace phys::units::literals; @@ -67,19 +80,6 @@ namespace corsika::units::si { using InverseGrammageType = phys::units::quantity<phys::units::dimensions<2, -1, 0>, double>; - namespace detail { - template <int N, typename T> - auto constexpr static_pow([[maybe_unused]] T x) { - if constexpr (N == 0) { - return 1; - } else if constexpr (N > 0) { - return x * static_pow<N - 1, T>(x); - } else { - return 1 / static_pow<-N, T>(x); - } - } - } // namespace detail - template <typename DimFrom, typename DimTo> auto constexpr ConversionFactorHEPToSI() { static_assert(DimFrom::dim1 == 0 && DimFrom::dim2 == 0 && DimFrom::dim3 == 0 && diff --git a/Framework/Units/testUnits.cc b/Framework/Units/testUnits.cc index 9f033d243f66c41deb044a912d08dbc3d2d5d003..bae1ce1d7123d82c9878bc4a4bbd319f33ce9912 100644 --- a/Framework/Units/testUnits.cc +++ b/Framework/Units/testUnits.cc @@ -114,7 +114,7 @@ TEST_CASE("PhysicalUnits", "[Units]") { } SECTION("static_pow") { - using namespace corsika::units::si::detail; + using namespace corsika::units; double x = 235.7913; REQUIRE(1 == static_pow<0, double>(x)); REQUIRE(x == static_pow<1, double>(x)); diff --git a/Processes/CONEXSourceCut/testCONEXSourceCut.cc b/Processes/CONEXSourceCut/testCONEXSourceCut.cc index 18df797fe78d62d216df5c5e91de0b1dc0b4c400..031ea746f6651d41865d06e9cd37dc577f64b9a9 100644 --- a/Processes/CONEXSourceCut/testCONEXSourceCut.cc +++ b/Processes/CONEXSourceCut/testCONEXSourceCut.cc @@ -57,8 +57,8 @@ TEST_CASE("CONEXSourceCut") { auto const injectionHeight = 112.75_km + conex::earthRadius; auto const t = -observationHeight * cos(thetaRad) + - sqrt(-units::si::detail::static_pow<2>(sin(thetaRad) * observationHeight) + - units::si::detail::static_pow<2>(injectionHeight)); + sqrt(-units::static_pow<2>(sin(thetaRad) * observationHeight) + + units::static_pow<2>(injectionHeight)); Point const showerCore{rootCS, 0_m, 0_m, observationHeight}; Point const injectionPos = showerCore + diff --git a/Processes/HadronicElasticModel/HadronicElasticModel.cc b/Processes/HadronicElasticModel/HadronicElasticModel.cc index c8f3eed3dd74a39d1de39e40be9112c5dab5f54e..dbece1ac127c2f3f3d0970971ce7fde6aba7aee5 100644 --- a/Processes/HadronicElasticModel/HadronicElasticModel.cc +++ b/Processes/HadronicElasticModel/HadronicElasticModel.cc @@ -50,7 +50,7 @@ units::si::GrammageType HadronicElasticInteraction::GetInteractionLength( for (size_t i = 0; i < fractions.size(); ++i) { auto const targetMass = particles::GetMass(components[i]); - auto const s = detail::static_pow<2>(projectileEnergy + targetMass) - + auto const s = units::static_pow<2>(projectileEnergy + targetMass) - projectileMomentumSquaredNorm; avgCrossSection += CrossSection(s) * fractions[i]; } @@ -92,7 +92,7 @@ process::EProcessReturn HadronicElasticInteraction::DoInteraction(SetupView& vie for (size_t i = 0; i < components.size(); ++i) { auto const targetMass = particles::GetMass(components[i]); - auto const s = units::si::detail::static_pow<2>(projectileEnergy + targetMass) - + auto const s = units::static_pow<2>(projectileEnergy + targetMass) - projectileMomentumSquaredNorm; cross_section_of_components[i] = CrossSection(s); } @@ -119,7 +119,7 @@ process::EProcessReturn HadronicElasticInteraction::DoInteraction(SetupView& vie auto const eTargetCoM = targetCoM.GetTimeLikeComponent(); auto const sqrtS = eProjectileCoM + eTargetCoM; - auto const s = units::si::detail::static_pow<2>(sqrtS); + auto const s = units::static_pow<2>(sqrtS); auto const B = this->B(s); std::cout << B << std::endl; @@ -158,7 +158,7 @@ process::EProcessReturn HadronicElasticInteraction::DoInteraction(SetupView& vie p.SetMomentum(projectileScatteredLab.GetSpaceLikeComponents()); p.SetEnergy( sqrt(projectileScatteredLab.GetSpaceLikeComponents().squaredNorm() + - units::si::detail::static_pow<2>(particles::GetMass( + units::static_pow<2>(particles::GetMass( p.GetPID())))); // Don't use energy from boost. It can be smaller than // the momentum due to limited numerical accuracy. @@ -185,7 +185,7 @@ units::si::CrossSectionType HadronicElasticInteraction::CrossSection( // according to Schuler & Sjöstrand, PRD 49, 2257 (1994) // (we ignore rho because rho^2 is just ~2 %) auto const sigmaElastic = - units::si::detail::static_pow<2>(sigmaTotal) / + units::static_pow<2>(sigmaTotal) / (16 * M_PI * ConvertHEPToSI<CrossSectionType::dimension_type>(B(s))); std::cout << "HEM sigmaTot = " << sigmaTotal / 1_mb << " mb" << std::endl; diff --git a/Processes/InteractionCounter/testInteractionCounter.cc b/Processes/InteractionCounter/testInteractionCounter.cc index c63579e8819920a298dd39ddc90ffa8973f31454..08b67182b1f881a48ce291bc37ca1c36359a08e5 100644 --- a/Processes/InteractionCounter/testInteractionCounter.cc +++ b/Processes/InteractionCounter/testInteractionCounter.cc @@ -60,7 +60,7 @@ auto setupStack(int vA, int vZ, HEPEnergyType vMomentum, TNodeType* vNodePtr, corsika::stack::MomentumVector const pLab(cs, {vMomentum, 0_GeV, 0_GeV}); HEPEnergyType const E0 = - sqrt(units::si::detail::static_pow<2>(mN * vA) + pLab.squaredNorm()); + sqrt(units::static_pow<2>(mN * vA) + pLab.squaredNorm()); auto particle = stack->AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType, corsika::stack::MomentumVector, geometry::Point, @@ -82,7 +82,7 @@ auto setupStack(particles::Code vProjectileType, HEPEnergyType vMomentum, corsika::stack::MomentumVector const pLab(cs, {vMomentum, 0_GeV, 0_GeV}); HEPEnergyType const E0 = - sqrt(units::si::detail::static_pow<2>(particles::GetMass(vProjectileType)) + + sqrt(units::static_pow<2>(particles::GetMass(vProjectileType)) + pLab.squaredNorm()); auto particle = stack->AddParticle( std::tuple<particles::Code, units::si::HEPEnergyType, diff --git a/Processes/Sibyll/testSibyll.cc b/Processes/Sibyll/testSibyll.cc index 84e04ba21079451cd2e8e2641eaaa641e508ded2..d8e9e14fc4573aa64bc99b3f47e4dfdf5e9f0c76 100644 --- a/Processes/Sibyll/testSibyll.cc +++ b/Processes/Sibyll/testSibyll.cc @@ -87,9 +87,7 @@ using namespace corsika::units; template <typename TStackView> auto sumMomentum(TStackView const& view, geometry::CoordinateSystem const& vCS) { geometry::Vector<hepenergy_d> sum{vCS, 0_eV, 0_eV, 0_eV}; - for (auto const& p : view) { sum += p.GetMomentum(); } - return sum; } diff --git a/Processes/UrQMD/UrQMD.cc b/Processes/UrQMD/UrQMD.cc index cec9beb3ee2608a4d0a0314ba857e8ff47cd926b..0a795e1ee1c5809707edeb68505a671413b53303 100644 --- a/Processes/UrQMD/UrQMD.cc +++ b/Processes/UrQMD/UrQMD.cc @@ -126,8 +126,8 @@ CrossSectionType UrQMD::GetCrossSection(particles::Code projectileCode, !IsNucleus(targetCode)) { // both particles are "special" auto const mProj = particles::GetMass(projectileCode); auto const mTar = particles::GetMass(targetCode); - double sqrtS = sqrt(units::si::detail::static_pow<2>(mProj) + - units::si::detail::static_pow<2>(mTar) + 2 * labEnergy * mTar) * + double sqrtS = sqrt(units::static_pow<2>(mProj) + + units::static_pow<2>(mTar) + 2 * labEnergy * mTar) * (1 / 1_GeV); // we must set some UrQMD globals first... @@ -179,7 +179,7 @@ CrossSectionType UrQMD::GetCrossSection(particles::Code projectileCode, int const At = IsNucleus(targetCode) ? particles::GetNucleusA(targetCode) : 1; double const maxImpact = nucrad_(Ap) + nucrad_(At) + 2 * options_.CTParam[30 - 1]; - return 10_mb * M_PI * units::si::detail::static_pow<2>(maxImpact); + return 10_mb * M_PI * units::static_pow<2>(maxImpact); // is a constant cross-section really reasonable? } } diff --git a/Processes/UrQMD/testUrQMD.cc b/Processes/UrQMD/testUrQMD.cc index 71cdd8068864a3c4eda760696374f9b61e193634..5cb6be54ff7b6a0842a1729a2fa7fad2b8ae4a4f 100644 --- a/Processes/UrQMD/testUrQMD.cc +++ b/Processes/UrQMD/testUrQMD.cc @@ -86,7 +86,7 @@ auto setupStack(int vA, int vZ, HEPEnergyType vMomentum, TNodeType* vNodePtr, corsika::stack::MomentumVector const pLab(cs, {vMomentum, 0_GeV, 0_GeV}); HEPEnergyType const E0 = - sqrt(units::si::detail::static_pow<2>(mN * vA) + pLab.squaredNorm()); + sqrt(units::static_pow<2>(mN * vA) + pLab.squaredNorm()); auto particle = stack->AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType, corsika::stack::MomentumVector, geometry::Point, @@ -107,7 +107,7 @@ auto setupStack(particles::Code vProjectileType, HEPEnergyType vMomentum, corsika::stack::MomentumVector const pLab(cs, {vMomentum, 0_GeV, 0_GeV}); HEPEnergyType const E0 = - sqrt(units::si::detail::static_pow<2>(particles::GetMass(vProjectileType)) + + sqrt(units::static_pow<2>(particles::GetMass(vProjectileType)) + pLab.squaredNorm()); auto particle = stack->AddParticle( std::tuple<particles::Code, units::si::HEPEnergyType, diff --git a/Stack/History/testHistoryView.cc b/Stack/History/testHistoryView.cc index bba09b71c1dc9f08073f76dd215973132cc8c1fe..9079c815b3b625ce21b799c767e7a8b315b50ec8 100644 --- a/Stack/History/testHistoryView.cc +++ b/Stack/History/testHistoryView.cc @@ -75,29 +75,30 @@ TEST_CASE("HistoryStackExtension", "[stack]") { corsika::history::EventPtr evt = p0.GetEvent(); CHECK(evt == nullptr); - // add secondaries, 1st generation - history::HistorySecondaryView<TestStackView> hview0(p0); - - auto const ev0 = p0.GetEvent(); - CHECK(ev0 == nullptr); - // CHECK(ev0->projectile(s.begin()) == p0); - - // add 5 secondaries - for (int i = 0; i < 5; ++i) { - auto sec = hview0.AddSecondary( + SECTION("interface test, view") { + + // add secondaries, 1st generation + history::HistorySecondaryView<TestStackView> hview0(p0); + + auto const ev0 = p0.GetEvent(); + CHECK(ev0 == nullptr); + + // add 5 secondaries + for (int i = 0; i < 5; ++i) { + auto sec = hview0.AddSecondary( std::tuple<particles::Code, units::si::HEPEnergyType, corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{ particles::Code::Electron, 1.5_GeV, corsika::stack::MomentumVector(dummyCS, {1_GeV, 1_GeV, 1_GeV}), Point(dummyCS, {1 * meter, 1 * meter, 1 * meter}), 100_s}); - CHECK(sec.GetParentEventIndex() == i); - CHECK(sec.GetEvent() != nullptr); - CHECK(sec.GetEvent()->parentEvent() == nullptr); - } + CHECK(sec.GetParentEventIndex() == i); + CHECK(sec.GetEvent() != nullptr); + CHECK(sec.GetEvent()->parentEvent() == nullptr); + } - // read 1st genertion particle particle - auto p1 = stack.GetNextParticle(); + // read 1st genertion particle particle + auto p1 = stack.GetNextParticle(); history::HistorySecondaryView<TestStackView> hview1(p1); @@ -176,4 +177,58 @@ TEST_CASE("HistoryStackExtension", "[stack]") { CHECK(test_proj1.GetEvent()->parentEvent()->parentEvent() == nullptr); } */ + } + + SECTION("also test projectile access") { + + // add secondaries, 1st generation + history::HistorySecondaryView<TestStackView> hview0(p0); + auto proj0 = hview0.GetProjectile(); + auto const ev0 = p0.GetEvent(); + CHECK(ev0 == nullptr); + + // add 5 secondaries + for (int i = 0; i < 5; ++i) { + auto sec = proj0.AddSecondary( + std::tuple<particles::Code, units::si::HEPEnergyType, + corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{ + particles::Code::Electron, 1.5_GeV, + corsika::stack::MomentumVector(dummyCS, {1_GeV, 1_GeV, 1_GeV}), + Point(dummyCS, {1 * meter, 1 * meter, 1 * meter}), 100_s}); + + CHECK(sec.GetParentEventIndex() == i); + CHECK(sec.GetEvent() != nullptr); + CHECK(sec.GetEvent()->parentEvent() == nullptr); + } + CHECK(stack.getEntries()==6); + + + // read 1st genertion particle particle + auto p1 = stack.GetNextParticle(); + + history::HistorySecondaryView<TestStackView> hview1(p1); + auto proj1 = hview1.GetProjectile(); + auto const ev1 = p1.GetEvent(); + + // add second generation of secondaries + // add 10 secondaries + for (int i = 0; i < 10; ++i) { + auto sec = proj1.AddSecondary( + std::tuple<particles::Code, units::si::HEPEnergyType, + corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{ + particles::Code::Electron, 1.5_GeV, + corsika::stack::MomentumVector(dummyCS, {1_GeV, 1_GeV, 1_GeV}), + Point(dummyCS, {1 * meter, 1 * meter, 1 * meter}), 100_s}); + + CHECK(sec.GetParentEventIndex() == i); + CHECK(sec.GetEvent()->parentEvent() == ev1); + CHECK(sec.GetEvent()->parentEvent()->secondaries().size() == 10); + CHECK(sec.GetEvent()->parentEvent()->parentEvent() == ev0); + + CHECK((stack.begin() + sec.GetEvent()->projectileIndex()).GetEvent() == + sec.GetEvent()->parentEvent()); + } + CHECK(stack.getEntries()==16); + + } }