From e46991e98e23042245a7b1fa3705c741f88fff58 Mon Sep 17 00:00:00 2001 From: Maximilian Reininghaus <maximilian.reininghaus@kit.edu> Date: Wed, 12 Sep 2018 19:30:02 +0200 Subject: [PATCH] Trajectory interface --- Framework/Geometry/BaseTrajectory.h | 23 ++++++++++++ Framework/Geometry/CMakeLists.txt | 3 ++ Framework/Geometry/Helix.h | 39 +++++++++++--------- Framework/Geometry/LineTrajectory.h | 25 ++++++------- Framework/Geometry/QuantityVector.h | 2 ++ Framework/Geometry/Sphere.h | 1 + Framework/Geometry/Trajectory.h | 31 ++++++++++++++++ Framework/Geometry/testGeometry.cc | 55 ++++++++++++++++++++--------- 8 files changed, 134 insertions(+), 45 deletions(-) create mode 100644 Framework/Geometry/BaseTrajectory.h create mode 100644 Framework/Geometry/Trajectory.h diff --git a/Framework/Geometry/BaseTrajectory.h b/Framework/Geometry/BaseTrajectory.h new file mode 100644 index 000000000..ec5e4062c --- /dev/null +++ b/Framework/Geometry/BaseTrajectory.h @@ -0,0 +1,23 @@ +#ifndef _include_BASETRAJECTORY_H +#define _include_BASETRAJECTORY_H + +#include <corsika/geometry/Point.h> +#include <corsika/geometry/Vector.h> +#include <corsika/units/PhysicalUnits.h> +#include <string> + +namespace corsika::geometry { + + /*! + * Base class for trajectories. + */ + class BaseTrajectory { + + public: + //!< t for \f$ t = 0 \f$, the starting Point shall be returned. + virtual Point GetPosition(corsika::units::TimeType t) const = 0; + }; + +} // namespace corsika::geometry + +#endif diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index c55295c89..a4fc43cb3 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -13,6 +13,9 @@ set ( Helix.h BaseVector.h QuantityVector.h + BaseTrajectory.h + LineTrajectory.h + Trajectory.h ) set ( diff --git a/Framework/Geometry/Helix.h b/Framework/Geometry/Helix.h index c392356d4..29bb49438 100644 --- a/Framework/Geometry/Helix.h +++ b/Framework/Geometry/Helix.h @@ -1,33 +1,38 @@ #ifndef _include_HELIX_H_ #define _include_HELIX_H_ +#include <corsika/geometry/BaseTrajectory.h> #include <corsika/geometry/Point.h> #include <corsika/geometry/Vector.h> #include <corsika/units/PhysicalUnits.h> #include <cmath> namespace corsika::geometry { - - using corsika::units::frequency_d; - using corsika::units::FrequencyType; - using corsika::units::quantity; - using corsika::units::SpeedType; - using corsika::units::TimeType; - - class Helix // TODO: inherit from to-be-implemented "Trajectory" - { - using SpeedVec = Vector<SpeedType::dimension_type>; + /*! + * A Helix is defined by the cyclotron frequency \f$ \omega_c \f$, the initial + * Point r0 and + * the velocity vectors \f$ \vec{v}_{\parallel} \f$ and \f$ \vec{v}_{\perp} \f$ + * denoting the projections of the initial velocity \f$ \vec{v}_0 \f$ parallel + * and perpendicular to the axis \f$ \vec{B} \f$, respectively, i.e. + * \f{align*}{ + \vec{v}_{\parallel} &= \frac{\vec{v}_0 \cdot \vec{B}}{\vec{B}^2} \vec{B} \\ + \vec{v}_{\perp} &= \vec{v}_0 - \vec{v}_{\parallel} + \f} + */ + + class Helix : public BaseTrajectory { + using VelocityVec = Vector<corsika::units::SpeedType::dimension_type>; Point const r0; - FrequencyType const omegaC; - SpeedVec const vPar; - SpeedVec vPerp, uPerp; + corsika::units::FrequencyType const omegaC; + VelocityVec const vPar; + VelocityVec const vPerp, uPerp; - LengthType const radius; + corsika::units::LengthType const radius; public: - Helix(Point const& pR0, quantity<frequency_d> pOmegaC, SpeedVec const& pvPar, - SpeedVec const& pvPerp) + Helix(Point const& pR0, corsika::units::FrequencyType pOmegaC, + VelocityVec const& pvPar, VelocityVec const& pvPerp) : r0(pR0) , omegaC(pOmegaC) , vPar(pvPar) @@ -35,7 +40,7 @@ namespace corsika::geometry { , uPerp(vPerp.cross(vPar.normalized())) , radius(pvPar.norm() / abs(pOmegaC)) {} - auto GetPosition(TimeType t) const { + Point GetPosition(corsika::units::TimeType t) const { return r0 + vPar * t + (vPerp * (cos(omegaC * t) - 1) + uPerp * sin(omegaC * t)) / omegaC; } diff --git a/Framework/Geometry/LineTrajectory.h b/Framework/Geometry/LineTrajectory.h index 4d56a598f..556da4642 100644 --- a/Framework/Geometry/LineTrajectory.h +++ b/Framework/Geometry/LineTrajectory.h @@ -1,26 +1,27 @@ #ifndef _include_LINETRAJECTORY_H #define _include_LINETRAJECTORY_H -#include <Units/PhysicalUnits.h> -#include <corsika/Point.h> -#include <corsika/Vector.h> +#include <corsika/geometry/BaseTrajectory.h> +#include <corsika/geometry/Point.h> +#include <corsika/geometry/Vector.h> +#include <corsika/units/PhysicalUnits.h> -namesapce corsika { +namespace corsika::geometry { - class LineTrajectory // TODO: inherit from Trajectory - { - using SpeedVec = Vector<Speed::dimension_type>; + class LineTrajectory : public BaseTrajectory { + using VelocityVec = Vector<corsika::units::SpeedType::dimension_type>; Point const r0; - SpeedVec const v0; + VelocityVec const v0; - LineTrajectory(Point const& pR0, SpeedVec const& pV0) - : r0(r0) + public: + LineTrajectory(Point const& pR0, VelocityVec const& pV0) + : r0(pR0) , v0(pV0) {} - auto GetPosition(Time t) const { return r0 + v0 * t; } + Point GetPosition(corsika::units::TimeType t) const override { return r0 + v0 * t; } }; -} // end namesapce +} // namespace corsika::geometry #endif diff --git a/Framework/Geometry/QuantityVector.h b/Framework/Geometry/QuantityVector.h index c5af419ee..671a68560 100644 --- a/Framework/Geometry/QuantityVector.h +++ b/Framework/Geometry/QuantityVector.h @@ -101,6 +101,8 @@ namespace corsika { auto& operator-() const { return QuantityVector<dim>(-eVector); } auto normalized() const { return (*this) * (1 / norm()); } + + auto operator==(QuantityVector<dim> const& p) const { return eVector == p.eVector; } }; } // end namespace corsika diff --git a/Framework/Geometry/Sphere.h b/Framework/Geometry/Sphere.h index 552dfde6f..28b4e7dc6 100644 --- a/Framework/Geometry/Sphere.h +++ b/Framework/Geometry/Sphere.h @@ -15,6 +15,7 @@ namespace corsika::geometry { : center(pCenter) , radius(pRadius) {} + //! returns true if the Point p is within the sphere auto isInside(Point const& p) const { return radius * radius > (center - p).squaredNorm(); } diff --git a/Framework/Geometry/Trajectory.h b/Framework/Geometry/Trajectory.h new file mode 100644 index 000000000..8a640cacd --- /dev/null +++ b/Framework/Geometry/Trajectory.h @@ -0,0 +1,31 @@ +#ifndef _include_TRAJECTORY_H +#define _include_TRAJECTORY_H + +#include <corsika/geometry/BaseTrajectory.h> +#include <corsika/units/PhysicalUnits.h> + +namespace corsika::geometry { + + class Trajectory { + corsika::units::TimeType const fTStart, fTEnd; + BaseTrajectory const& fTrajectory; + + public: + Trajectory(corsika::units::TimeType pTStart, corsika::units::TimeType pTEnd, + BaseTrajectory const& pTrajectory) + : fTStart(pTStart) + , fTEnd(pTEnd) + , fTrajectory(pTrajectory) {} + + Point GetPosition(corsika::units::TimeType t) const { + return fTrajectory.GetPosition(t + fTStart); + } + + Point GetPosition(double u) const { + return GetPosition(fTEnd * u + fTStart * (1 - u)); + } + }; + +} // namespace corsika::geometry + +#endif diff --git a/Framework/Geometry/testGeometry.cc b/Framework/Geometry/testGeometry.cc index af824df1c..d453b8f7b 100644 --- a/Framework/Geometry/testGeometry.cc +++ b/Framework/Geometry/testGeometry.cc @@ -2,14 +2,17 @@ // cpp file #include <catch2/catch.hpp> -#include <Geometry/CoordinateSystem.h> -#include <Geometry/Point.h> -#include <Geometry/Sphere.h> +#include <corsika/geometry/CoordinateSystem.h> +#include <corsika/geometry/Helix.h> +#include <corsika/geometry/LineTrajectory.h> +#include <corsika/geometry/Point.h> +#include <corsika/geometry/Sphere.h> +#include <corsika/geometry/Trajectory.h> #include <corsika/units/PhysicalUnits.h> #include <cmath> -using namespace phys::units; -using namespace phys::units::literals; +using namespace corsika::geometry; +using namespace corsika::units; TEST_CASE("transformations between CoordinateSystems") { CoordinateSystem rootCS; @@ -17,10 +20,11 @@ TEST_CASE("transformations between CoordinateSystems") { REQUIRE(CoordinateSystem::GetTransformation(rootCS, rootCS) .isApprox(EigenTransform::Identity())); - QuantityVector<length_d> const coordinates{0_m, 0_m, 0_m}; + corsika::QuantityVector<length_d> const coordinates{0_m, 0_m, 0_m}; Point p1(rootCS, coordinates); - QuantityVector<magnetic_flux_density_d> components{1. * tesla, 0. * tesla, 0. * tesla}; + corsika::QuantityVector<magnetic_flux_density_d> components{1. * tesla, 0. * tesla, + 0. * tesla}; Vector<magnetic_flux_density_d> v1(rootCS, components); REQUIRE((p1.GetCoordinates() - coordinates).norm().magnitude() == Approx(0)); @@ -32,7 +36,7 @@ TEST_CASE("transformations between CoordinateSystems") { } SECTION("translations") { - QuantityVector<length_d> const translationVector{0_m, 4_m, 0_m}; + corsika::QuantityVector<length_d> const translationVector{0_m, 4_m, 0_m}; CoordinateSystem translatedCS = rootCS.translate(translationVector); @@ -52,13 +56,13 @@ TEST_CASE("transformations between CoordinateSystems") { } SECTION("multiple translations") { - QuantityVector<length_d> const tv1{0_m, 5_m, 0_m}; + corsika::QuantityVector<length_d> const tv1{0_m, 5_m, 0_m}; CoordinateSystem cs2 = rootCS.translate(tv1); - QuantityVector<length_d> const tv2{3_m, 0_m, 0_m}; + corsika::QuantityVector<length_d> const tv2{3_m, 0_m, 0_m}; CoordinateSystem cs3 = rootCS.translate(tv2); - QuantityVector<length_d> const tv3{0_m, 0_m, 2_m}; + corsika::QuantityVector<length_d> const tv3{0_m, 0_m, 2_m}; CoordinateSystem cs4 = cs3.translate(tv3); REQUIRE(cs4.GetReference()->GetReference() == &rootCS); @@ -70,7 +74,7 @@ TEST_CASE("transformations between CoordinateSystems") { } SECTION("rotations") { - QuantityVector<length_d> const axis{0_m, 0_m, 1_km}; + corsika::QuantityVector<length_d> const axis{0_m, 0_m, 1_km}; double const angle = 90. / 180. * M_PI; CoordinateSystem rotatedCS = rootCS.rotate(axis, angle); @@ -85,9 +89,9 @@ TEST_CASE("transformations between CoordinateSystems") { } SECTION("multiple rotations") { - QuantityVector<length_d> const zAxis{0_m, 0_m, 1_km}; - QuantityVector<length_d> const yAxis{0_m, 7_nm, 0_m}; - QuantityVector<length_d> const xAxis{2_m, 0_nm, 0_m}; + corsika::QuantityVector<length_d> const zAxis{0_m, 0_m, 1_km}; + corsika::QuantityVector<length_d> const yAxis{0_m, 7_nm, 0_m}; + corsika::QuantityVector<length_d> const xAxis{2_m, 0_nm, 0_m}; double const angle = 90. / 180. * M_PI; @@ -110,7 +114,26 @@ TEST_CASE("Sphere") { SECTION("isInside") { REQUIRE_FALSE(sphere.isInside(Point(rootCS, {100_m, 0_m, 0_m}))); - REQUIRE(sphere.isInside(Point(rootCS, {2_m, 3_m, 4_m}))); } } + +TEST_CASE("Trajectories") { + CoordinateSystem rootCS; + Point r0(rootCS, {0_m, 0_m, 0_m}); + + SECTION("Line") { + Vector<SpeedType::dimension_type> v0(rootCS, + {1_m / second, 0_m / second, 0_m / second}); + + LineTrajectory lineTrajectory(r0, v0); + REQUIRE((lineTrajectory.GetPosition(2_s).GetCoordinates() - + corsika::QuantityVector<length_d>(2_m, 0_m, 0_m)) + .norm() + .magnitude() == Approx(0)); + + BaseTrajectory* base = &lineTrajectory; + REQUIRE(lineTrajectory.GetPosition(2_s).GetCoordinates() == + base->GetPosition(2_s).GetCoordinates()); + } +} -- GitLab