diff --git a/CMakeLists.txt b/CMakeLists.txt index ab861c930704041afbcc93d608b051fb87132e3a..2437c992d9ebf740b82b6607e829f3c7a8838fbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project (corsika VERSION 8.0.0 DESCRIPTION "CORSIKA C++ PROJECT " LANGUAGES CXX) set (CMAKE_INSTALL_MESSAGE LAZY) # --std=c++14 -set (CMAKE_CXX_STANDARD 14) +set (CMAKE_CXX_STANDARD 17) enable_testing () #add_custom_target (corsika_pre_build) diff --git a/Framework/Geometry/QuantityVector.h b/Framework/Geometry/QuantityVector.h index 36cf0d567f520f8ba93f51cbbf73df9b92ca59a3..02546962072c849bcac75fa2c7a0b57ab65b1aab 100644 --- a/Framework/Geometry/QuantityVector.h +++ b/Framework/Geometry/QuantityVector.h @@ -58,10 +58,16 @@ public: template <typename ScalarDim> auto operator*(phys::units::quantity<ScalarDim, double> const p) const { - return QuantityVector<typename phys::units::detail::Product<ScalarDim, dim, double, double>::dimension_type>(eVector * p.magnitude()); - // TODO: this function does not work if the result is dimensionless, as - // dimensionless quantities are "cast" back to plain old double in PhysUnits. - // Either change PhysUnits, or cover this case with a template specialization? + using ResQuantity = phys::units::detail::Product<ScalarDim, dim, double, double>; + + if constexpr (std::is_same<ResQuantity, double>::value) // result dimensionless, not a "Quantity" anymore + { + return QuantityVector<phys::units::dimensionless_d>(eVector * p.magnitude()); + } + else + { + return QuantityVector<typename ResQuantity::dimension_type>(eVector * p.magnitude()); + } } auto operator*(double const p) const diff --git a/Framework/Geometry/Vector.h b/Framework/Geometry/Vector.h index 47b91f7ccc6ce6b3075a151f9b7085abf70e1b59..5670aaaf1dea08e869a4b137cf7798c3aeb48fd3 100644 --- a/Framework/Geometry/Vector.h +++ b/Framework/Geometry/Vector.h @@ -55,18 +55,18 @@ public: } template <typename dim2> - auto parallelProjectionOnto(BaseVector<dim2> const& pVec, CoordinateSystem const& pCS) const + auto parallelProjectionOnto(Vector<dim2> const& pVec, CoordinateSystem const& pCS) const { auto const ourCompVec = getComponents(pCS); - auto const otherCompVec = pVec.getComponents(pVec); + auto const otherCompVec = pVec.getComponents(pCS); auto const& a = ourCompVec.eVector; auto const& b = otherCompVec.eVector; - return Vector<dim>(pCS, (a * b) / b.squaredNorm() * b); + return Vector<dim>(pCS, QuantityVector<dim>(b * ((a.dot(b)) / b.squaredNorm()))); } template <typename dim2> - auto parallelProjectionOnto(BaseVector<dim2> const& pVec) + auto parallelProjectionOnto(Vector<dim2> const& pVec) const { return parallelProjectionOnto<dim2>(pVec, *BaseVector<dim>::cs); } @@ -92,8 +92,16 @@ public: template <typename ScalarDim> auto operator*(phys::units::quantity<ScalarDim, double> const p) const { - using res_dim = typename decltype(BaseVector<dim>::qVector * p)::dimension; - return Vector<res_dim>(*BaseVector<dim>::cs, BaseVector<dim>::qVector * p); + using ResQuantity = decltype(BaseVector<dim>::qVector * p); + if constexpr (std::is_same<ResQuantity, double>::value) // result dimensionless, not a "Quantity" anymore + { + return Vector<phys::units::dimensionless_d>(*BaseVector<dim>::cs, BaseVector<dim>::qVector * p); + } + else + { + using res_dim = typename decltype(BaseVector<dim>::qVector * p)::dimension; + return Vector<res_dim>(*BaseVector<dim>::cs, BaseVector<dim>::qVector * p); + } } auto operator*(double const p) const diff --git a/ThirdParty/phys/units/quantity.hpp b/ThirdParty/phys/units/quantity.hpp index d64e56bcac6d973494e10b9aeda62828251ac886..29ab27f65e487a088a71e0ac068b539dbf608f80 100644 --- a/ThirdParty/phys/units/quantity.hpp +++ b/ThirdParty/phys/units/quantity.hpp @@ -340,7 +340,7 @@ private: enum { has_dimension = ! Dims::is_all_zero }; - static_assert( has_dimension, "quantity dimensions must not all be zero" ); + // static_assert( has_dimension, "quantity dimensions must not all be zero" ); private: // friends: