diff --git a/Environment/CMakeLists.txt b/Environment/CMakeLists.txt index b04a58bdce307668b346ab1957b8e8b6325216a1..ef1d24035859fc6668d902ae89ee7aebc994a95b 100644 --- a/Environment/CMakeLists.txt +++ b/Environment/CMakeLists.txt @@ -6,7 +6,7 @@ set ( HomogeneousMedium.h InhomogeneousMedium.h HomogeneousMedium.h - LinearIntegrator.h + LinearApproximationIntegrator.h DensityFunction.h Environment.h ) diff --git a/Environment/DensityFunction.h b/Environment/DensityFunction.h index 943410afc2a40226de94f9efac61c00af86ab225..32ee30adedfcbe9fccf1ebea2f09c8b9877f6015 100644 --- a/Environment/DensityFunction.h +++ b/Environment/DensityFunction.h @@ -11,7 +11,7 @@ #ifndef _include_environment_DensityFunction_h_ #define _include_environment_DensityFunction_h_ -#include <corsika/environment/LinearIntegrator.h> +#include <corsika/environment/LinearApproximationIntegrator.h> #include <corsika/geometry/Line.h> #include <corsika/geometry/Point.h> #include <corsika/geometry/Trajectory.h> @@ -19,10 +19,10 @@ namespace corsika::environment { template <class TDerivableRho, - template <typename> class TApproximator = LinearApproximator> + template <typename> class TIntegrator = LinearApproximationIntegrator> class DensityFunction - : public TApproximator<DensityFunction<TDerivableRho, TApproximator>> { - friend class TApproximator<DensityFunction<TDerivableRho, TApproximator>>; + : public TIntegrator<DensityFunction<TDerivableRho, TIntegrator>> { + friend class TIntegrator<DensityFunction<TDerivableRho, TIntegrator>>; TDerivableRho fRho; //!< functor for density diff --git a/Environment/InhomogeneousMedium.h b/Environment/InhomogeneousMedium.h index c506fb176d2d10370330c7b4d4d16eb45b304f95..feb6497cfcd82a28b8eafa183c068d106e187520 100644 --- a/Environment/InhomogeneousMedium.h +++ b/Environment/InhomogeneousMedium.h @@ -20,8 +20,8 @@ #include <corsika/units/PhysicalUnits.h> /** - * An inhomogeneous medium. The mass density distribution TDensityFunction must be a - * \f$C^1\f$-function. + * A general inhomogeneous medium. The mass density distribution TDensityFunction must be + * a \f$C^2\f$-function. */ namespace corsika::environment { @@ -46,7 +46,7 @@ namespace corsika::environment { corsika::units::si::GrammageType IntegratedGrammage( corsika::geometry::Trajectory<corsika::geometry::Line> const& pLine, corsika::units::si::LengthType pTo) const override { - return fDensityFunction.IntegratedGrammage(pLine, pTo); + return fDensityFunction.IntegrateGrammage(pLine, pTo); } corsika::units::si::LengthType ArclengthFromGrammage( diff --git a/Environment/LinearIntegrator.h b/Environment/LinearApproximationIntegrator.h similarity index 85% rename from Environment/LinearIntegrator.h rename to Environment/LinearApproximationIntegrator.h index 00f5904655cd1cd4cfe6fe66add749178716ea66..910d2397189e7aa9b1456e00df94f72cfd49ff4f 100644 --- a/Environment/LinearIntegrator.h +++ b/Environment/LinearApproximationIntegrator.h @@ -8,8 +8,8 @@ * the license. */ -#ifndef _include_environment_LinearIntegrator_h_ -#define _include_environment_LinearIntegrator_h_ +#ifndef _include_environment_LinearApproximationIntegrator_h_ +#define _include_environment_LinearApproximationIntegrator_h_ #include <limits> @@ -19,7 +19,7 @@ namespace corsika::environment { template <class TDerived> - class LinearApproximator { + class LinearApproximationIntegrator { auto const& GetImplementation() const { return *static_cast<TDerived const*>(this); } public: @@ -43,9 +43,9 @@ namespace corsika::environment { } auto MaximumLength(corsika::geometry::Trajectory<corsika::geometry::Line> const& line, - double relError) const { + [[maybe_unused]] double relError) const { using namespace corsika::units::si; - auto const c1 = GetImplementation().fRho.SecondDerivative( + [[maybe_unused]] auto const c1 = GetImplementation().fRho.SecondDerivative( line.GetPosition(0), line.NormalizedDirection()); // todo: provide a real, working implementation diff --git a/Environment/testEnvironment.cc b/Environment/testEnvironment.cc index 7f39ca1043bcb6df61800d7b0b041df95844335f..5bb18bfe09e48d4865f5aafcd8ad4aa01f4afeb8 100644 --- a/Environment/testEnvironment.cc +++ b/Environment/testEnvironment.cc @@ -16,6 +16,7 @@ #include <corsika/environment/HomogeneousMedium.h> #include <corsika/environment/IMediumModel.h> #include <corsika/environment/InhomogeneousMedium.h> +#include <corsika/environment/LinearApproximationIntegrator.h> #include <corsika/environment/NuclearComposition.h> #include <corsika/environment/VolumeTreeNode.h> #include <corsika/geometry/Line.h> @@ -27,12 +28,12 @@ using namespace corsika::geometry; using namespace corsika::environment; +using namespace corsika::particles; using namespace corsika::units::si; TEST_CASE("HomogeneousMedium") { - NuclearComposition const protonComposition( - std::vector<corsika::particles::Code>{corsika::particles::Code::Proton}, - std::vector<float>{1.f}); + NuclearComposition const protonComposition(std::vector<Code>{Code::Proton}, + std::vector<float>{1.f}); HomogeneousMedium<IMediumModel> const medium(19.2_g / cube(1_cm), protonComposition); } @@ -52,10 +53,15 @@ struct Exponential { auto FirstDerivative(Point const& p, Vector<dimensionless_d> const& v) const { return Derivative<1>(p, v); } + + auto SecondDerivative(Point const& p, Vector<dimensionless_d> const& v) const { + return Derivative<2>(p, v); + } }; -TEST_CASE("DensityFunction") { - CoordinateSystem& cs = RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); +TEST_CASE("InhomogeneousMedium") { + CoordinateSystem const& cs = + RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); Point const origin(cs, {0_m, 0_m, 0_m}); @@ -68,19 +74,34 @@ TEST_CASE("DensityFunction") { Trajectory<Line> const trajectory(line, tEnd); Exponential const e; - REQUIRE(e.Derivative<1>(origin, direction) / (1_kg / 1_m / 1_m / 1_m / 1_m) == - Approx(1)); + DensityFunction<decltype(e), LinearApproximationIntegrator> const rho(e); - DensityFunction const rho(e); - REQUIRE(rho.EvaluateAt(origin) == e(origin)); + SECTION("DensityFunction") { + REQUIRE(e.Derivative<1>(origin, direction) / (1_kg / 1_m / 1_m / 1_m / 1_m) == + Approx(1)); + REQUIRE(rho.EvaluateAt(origin) == e(origin)); + } auto const exactGrammage = [](auto l) { return 1_m * rho0 * (exp(l / 1_m) - 1); }; auto const exactLength = [](auto X) { return 1_m * log(1 + X / (rho0 * 1_m)); }; auto constexpr l = 15_cm; - CHECK(rho.IntegrateGrammage(trajectory, l) / exactGrammage(l) == - Approx(1).epsilon(1e-2)); - CHECK(rho.ArclengthFromGrammage(trajectory, exactGrammage(l)) / - exactLength(exactGrammage(l)) == - Approx(1).epsilon(1e-2)); + + NuclearComposition const composition{{Code::Proton}, {1.f}}; + InhomogeneousMedium<IMediumModel, decltype(rho)> const inhMedium(composition, rho); + + SECTION("Integration") { + REQUIRE(rho.IntegrateGrammage(trajectory, l) / exactGrammage(l) == + Approx(1).epsilon(1e-2)); + REQUIRE(rho.ArclengthFromGrammage(trajectory, exactGrammage(l)) / + exactLength(exactGrammage(l)) == + Approx(1).epsilon(1e-2)); + REQUIRE(rho.MaximumLength(trajectory, 1e-2) > + l); // todo: write reasonable test when implementation is working + + REQUIRE(rho.IntegrateGrammage(trajectory, l) == + inhMedium.IntegratedGrammage(trajectory, l)); + REQUIRE(rho.ArclengthFromGrammage(trajectory, 20_g / (1_cm * 1_cm)) == + inhMedium.ArclengthFromGrammage(trajectory, 20_g / (1_cm * 1_cm))); + } }