From e6ad6c0ff873c80b6ab26b24e27c035b5811cb2d Mon Sep 17 00:00:00 2001 From: Nikos Karastathis <n.karastathis@kit.edu> Date: Mon, 25 Jan 2021 16:16:41 +0100 Subject: [PATCH] added and tested Exponential Refractive Index class in media --- .../media/ExponentialRefractiveIndex.inl | 31 +++++++ corsika/media/ExponentialRefractiveIndex.hpp | 60 ++++++++++++++ tests/media/testRefractiveIndex.cpp | 80 +++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 corsika/detail/media/ExponentialRefractiveIndex.inl create mode 100644 corsika/media/ExponentialRefractiveIndex.hpp diff --git a/corsika/detail/media/ExponentialRefractiveIndex.inl b/corsika/detail/media/ExponentialRefractiveIndex.inl new file mode 100644 index 000000000..664b47b39 --- /dev/null +++ b/corsika/detail/media/ExponentialRefractiveIndex.inl @@ -0,0 +1,31 @@ +///* +// * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu +// * +// * 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. +// */ +// +//#pragma once +// +//#include <bits/stdc++.h> +//#include <corsika/media/IRefractiveIndexModel.hpp> +// +//namespace corsika { +// +// template <typename T> +// template <typename... Args> +// ExponentialRefractiveIndex<T>::ExponentialRefractiveIndex(double const n0, +// InverseLengthType const lambda, Args&&... args) +// : T(std::forward<Args>(args)...) +// , n_0(n0) +// , lambda_(lambda) {} +// +// template <typename T> +// double ExponentialRefractiveIndex<T>::getRefractiveIndex(Point const& point) const { +// //TODO: THIS METHOD CURRENTLY ONLY USES THE Z-COORDINATE. +// //NEED TO THINK IT FOR FUTURE WORK ON ARBITRARY GEOMETRIES. +// return n_0 * exp((-lambda_) * point.getCoordinates().getZ()); +// } +// +//} // namespace corsika diff --git a/corsika/media/ExponentialRefractiveIndex.hpp b/corsika/media/ExponentialRefractiveIndex.hpp new file mode 100644 index 000000000..3ac778926 --- /dev/null +++ b/corsika/media/ExponentialRefractiveIndex.hpp @@ -0,0 +1,60 @@ +/* + * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu + * + * 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. + */ + +#pragma once + +#include <bits/stdc++.h> +#include <corsika/media/IRefractiveIndexModel.hpp> + +namespace corsika { + + /** + * An exponential refractive index. + * + * This class returns the value of an exponential refractive index + * for all evaluated locations. + * + */ + template <typename T> + class ExponentialRefractiveIndex : public T { + + double n_0; ///< n0 constant. + InverseLengthType lambda_; ///< lambda parameter. + + public: + /** + * Construct an ExponentialRefractiveIndex. + * + * This is initialized with two parameters n_0 and lambda + * and returns the value of the exponential refractive index + * at a given point location. + * + * @param field The refractive index to return to a given point. + */ + template <typename... Args> + ExponentialRefractiveIndex(double const n0, + InverseLengthType const lambda, Args&&... args) + : T(std::forward<Args>(args)...) + , n_0(n0) + , lambda_(lambda) {} + /** + * Evaluate the refractive index at a given location. + * + * @param point The location to evaluate at. + * @returns The refractive index at this point. + */ + double getRefractiveIndex(Point const& point) const final override + { + //TODO: THIS METHOD CURRENTLY ONLY USES THE Z-COORDINATE. + //NEED TO THINK IT FOR FUTURE WORK ON ARBITRARY GEOMETRIES. + return n_0 * exp((-lambda_) * point.getCoordinates().getZ()); + } + + }; // END: class ExponentialRefractiveIndex + +} // namespace corsika \ No newline at end of file diff --git a/tests/media/testRefractiveIndex.cpp b/tests/media/testRefractiveIndex.cpp index fb1e71fec..1888f6a08 100644 --- a/tests/media/testRefractiveIndex.cpp +++ b/tests/media/testRefractiveIndex.cpp @@ -16,6 +16,7 @@ #include <corsika/media/InhomogeneousMedium.hpp> #include <corsika/media/NuclearComposition.hpp> #include <corsika/media/UniformRefractiveIndex.hpp> +#include <corsika/media/ExponentialRefractiveIndex.hpp> #include <SetupTestTrajectory.hpp> @@ -89,3 +90,82 @@ TEST_CASE("UniformRefractiveIndex w/ Homogeneous") { CHECK((medium.getIntegratedGrammage(track, 3_m) / (density * 3_m)) == Approx(1)); CHECK((medium.getArclengthFromGrammage(track, density * 5_m) / 5_m) == Approx(1)); } + + +TEST_CASE("ExponentialRefractiveIndex w/ Homogeneous medium") { + + logging::set_level(logging::level::info); + corsika_logger->set_pattern("[%n:%^%-8l%$] custom pattern: %v"); + + // get a CS and a point + CoordinateSystemPtr const& gCS = get_root_CoordinateSystem(); + + Point const gOrigin(gCS, {0_m, 0_m, 0_m}); + + // setup our interface types + using IModelInterface = IRefractiveIndexModel<IMediumModel>; + using AtmModel = ExponentialRefractiveIndex<HomogeneousMedium<IModelInterface>>; + + // the constant density + const auto density{19.2_g / cube(1_cm)}; + + // the composition we use for the homogenous medium + NuclearComposition const protonComposition(std::vector<Code>{Code::Proton}, + std::vector<float>{1.f}); + + // a new refractive index + const double n0{2}; + const InverseLengthType lambda{56 / 1_m}; + + // create the atmospheric model and check refractive index + AtmModel medium(n0, lambda, density, protonComposition); + CHECK(n0 == medium.getRefractiveIndex(Point(gCS, 10_m, 14_m, 0_m))); + + // another refractive index + const double n0_{1}; + const InverseLengthType lambda_{1 / 1_km}; + + // create the atmospheric model and check refractive index + AtmModel medium_(n0_, lambda_, density, protonComposition); + CHECK(medium_.getRefractiveIndex(Point(gCS, 12_m, 56_m, 1_km)) == Approx(0.3678794)); + + // another refractive index + const double n0__{4}; + const InverseLengthType lambda__{2 / 1_m}; + + // create the atmospheric model and check refractive index + AtmModel medium__(n0__, lambda__, density, protonComposition); + CHECK(medium__.getRefractiveIndex(Point(gCS, 0_m, 0_m, 35_km)) == Approx(0)); + + // define our axis vector + Vector const axis(gCS, QuantityVector<dimensionless_d>(0, 0, 1)); + + // check the density and nuclear composition + REQUIRE(density == medium.getMassDensity(Point(gCS, 0_m, 0_m, 0_m))); + medium.getNuclearComposition(); + REQUIRE(density == medium_.getMassDensity(Point(gCS, 0_m, 0_m, 0_m))); + medium_.getNuclearComposition(); + REQUIRE(density == medium__.getMassDensity(Point(gCS, 0_m, 0_m, 0_m))); + medium__.getNuclearComposition(); + + // create a line of length 1 m + Line const line(gOrigin, Vector<SpeedType::dimension_type>( + gCS, {1_m / second, 0_m / second, 0_m / second})); + + // the end time of our line + auto const tEnd = 1_s; + + // and the associated trajectory + setup::Trajectory const track = + setup::testing::make_track<setup::Trajectory>(line, tEnd); +// // and the associated trajectory +// Trajectory<Line> const trajectory(line, tEnd); + + // and check the integrated grammage + REQUIRE((medium.getIntegratedGrammage(track, 3_m) / (density * 3_m)) == Approx(1)); + REQUIRE((medium.getArclengthFromGrammage(track, density * 5_m) / 5_m) == Approx(1)); + REQUIRE((medium_.getIntegratedGrammage(track, 3_m) / (density * 3_m)) == Approx(1)); + REQUIRE((medium_.getArclengthFromGrammage(track, density * 5_m) / 5_m) == Approx(1)); + REQUIRE((medium__.getIntegratedGrammage(track, 3_m) / (density * 3_m)) == Approx(1)); + REQUIRE((medium__.getArclengthFromGrammage(track, density * 5_m) / 5_m) == Approx(1)); +} -- GitLab