From 7bbfe4c71087aab08fa692202e97880a624459a7 Mon Sep 17 00:00:00 2001 From: Maximilian Reininghaus <maximilian.reininghaus@kit.edu> Date: Wed, 30 Jan 2019 20:16:14 +0100 Subject: [PATCH] inhomogeneous medium + test (still WIP) --- Environment/CMakeLists.txt | 4 ++ Environment/HomogeneousMedium.h | 2 +- Environment/InhomogeneousMedium.h | 60 ++++++++++++++++++++++++++ Environment/testEnvironment.cc | 71 ++++++++++++++++++------------- 4 files changed, 107 insertions(+), 30 deletions(-) create mode 100644 Environment/InhomogeneousMedium.h diff --git a/Environment/CMakeLists.txt b/Environment/CMakeLists.txt index a476b89e..b04a58bd 100644 --- a/Environment/CMakeLists.txt +++ b/Environment/CMakeLists.txt @@ -4,6 +4,10 @@ set ( IMediumModel.h NuclearComposition.h HomogeneousMedium.h + InhomogeneousMedium.h + HomogeneousMedium.h + LinearIntegrator.h + DensityFunction.h Environment.h ) diff --git a/Environment/HomogeneousMedium.h b/Environment/HomogeneousMedium.h index d058f67c..02f7aabc 100644 --- a/Environment/HomogeneousMedium.h +++ b/Environment/HomogeneousMedium.h @@ -36,7 +36,7 @@ namespace corsika::environment { HomogeneousMedium(corsika::units::si::MassDensityType pDensity, NuclearComposition pNuclComp) : fDensity(pDensity) - , fNuclComp(pNuclComp){}; + , fNuclComp(pNuclComp) {} corsika::units::si::MassDensityType GetMassDensity( corsika::geometry::Point const&) const override { diff --git a/Environment/InhomogeneousMedium.h b/Environment/InhomogeneousMedium.h new file mode 100644 index 00000000..c506fb17 --- /dev/null +++ b/Environment/InhomogeneousMedium.h @@ -0,0 +1,60 @@ +/** + * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu + * + * See file AUTHORS for a list of contributors. + * + * 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. + */ + +#ifndef _include_environment_InhomogeneousMedium_h_ +#define _include_environment_InhomogeneousMedium_h_ + +#include <corsika/environment/NuclearComposition.h> +#include <corsika/geometry/Line.h> +#include <corsika/geometry/Point.h> +#include <corsika/geometry/Trajectory.h> +#include <corsika/particles/ParticleProperties.h> +#include <corsika/random/RNGManager.h> +#include <corsika/units/PhysicalUnits.h> + +/** + * An inhomogeneous medium. The mass density distribution TDensityFunction must be a + * \f$C^1\f$-function. + */ + +namespace corsika::environment { + + template <class T, class TDensityFunction> + class InhomogeneousMedium : public T { + NuclearComposition const fNuclComp; + TDensityFunction const fDensityFunction; + + public: + template <typename... Args> + InhomogeneousMedium(NuclearComposition pNuclComp, Args&&... rhoArgs) + : fNuclComp(pNuclComp) + , fDensityFunction(rhoArgs...) {} + + corsika::units::si::MassDensityType GetMassDensity( + corsika::geometry::Point const& p) const override { + return fDensityFunction.EvaluateAt(p); + } + NuclearComposition const& GetNuclearComposition() const override { return fNuclComp; } + + 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); + } + + corsika::units::si::LengthType ArclengthFromGrammage( + corsika::geometry::Trajectory<corsika::geometry::Line> const& pLine, + corsika::units::si::GrammageType pGrammage) const override { + return fDensityFunction.ArclengthFromGrammage(pLine, pGrammage); + } + }; + +} // namespace corsika::environment +#endif diff --git a/Environment/testEnvironment.cc b/Environment/testEnvironment.cc index 0695d02e..01edec05 100644 --- a/Environment/testEnvironment.cc +++ b/Environment/testEnvironment.cc @@ -11,14 +11,18 @@ #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one // cpp file +#include <corsika/environment/DensityFunction.h> #include <corsika/environment/HomogeneousMedium.h> #include <corsika/environment/IMediumModel.h> +#include <corsika/environment/InhomogeneousMedium.h> #include <corsika/environment/NuclearComposition.h> #include <corsika/environment/VolumeTreeNode.h> +#include <corsika/geometry/Line.h> +#include <corsika/geometry/RootCoordinateSystem.h> +#include <corsika/geometry/Vector.h> #include <corsika/particles/ParticleProperties.h> +#include <corsika/units/PhysicalUnits.h> #include <catch2/catch.hpp> -#include <random> -#include <vector> using namespace corsika::geometry; using namespace corsika::environment; @@ -31,32 +35,41 @@ TEST_CASE("HomogeneousMedium") { HomogeneousMedium<IMediumModel> const medium(19.2_g / cube(1_cm), protonComposition); } -TEST_CASE("NuclearComposition") { - NuclearComposition const composition( - std::vector<corsika::particles::Code>{corsika::particles::Code::Proton, - corsika::particles::Code::Neutron}, - std::vector<float>{2.f / 3.f, 1.f / 3.f}); - SECTION("SampleTarget") { - std::vector<CrossSectionType> crossSections{50_mbarn, 100_mbarn}; - - std::mt19937 rng; - - int proton{0}, neutron{0}; - - for (int i = 0; i < 1'000'000; ++i) { - corsika::particles::Code p = composition.SampleTarget(crossSections, rng); - switch (p) { - case corsika::particles::Code::Proton: - proton++; - break; - case corsika::particles::Code::Neutron: - neutron++; - break; - default: - throw std::runtime_error(""); - } - } - - REQUIRE(static_cast<double>(proton) / neutron == Approx(1).epsilon(1e-2)); +auto constexpr rho0 = 1_kg / 1_m / 1_m / 1_m; + +struct Exponential { + auto operator()(corsika::geometry::Point const& p) const { + return exp(p.GetCoordinates()[0] / 1_m) * rho0; + } + + 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); } +}; + +TEST_CASE("DensityFunction") { + CoordinateSystem& cs = RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); + + Point const origin(cs, {0_m, 0_m, 0_m}); + + Vector direction(cs, QuantityVector<dimensionless_d>(1, 0, 0)); + + Line line(origin, Vector<SpeedType::dimension_type>( + cs, {200_m / second, 0_m / second, 0_m / second})); + + auto const tEnd = 5_s; + 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 const rho(e); + REQUIRE(rho.EvaluateAt(origin) == e(origin)); + + auto const exactGrammage = [](auto x) { return rho0 * exp(x / 1_m); }; + REQUIRE(rho.IntegrateGrammage(trajectory, 5_cm) / exactGrammage(5_cm) == + Approx(1).epsilon(1e-2)); } -- GitLab