Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <array> 7 : #include <cstddef> 8 : #include <optional> 9 : 10 : #include "DataStructures/Tensor/TypeAliases.hpp" 11 : #include "Domain/Structure/OrientationMap.hpp" 12 : #include "Utilities/TypeTraits/RemoveReferenceWrapper.hpp" 13 : 14 : /// \cond 15 : namespace PUP { 16 : class er; 17 : } // namespace PUP 18 : /// \endcond 19 : 20 : namespace domain { 21 : namespace CoordinateMaps { 22 : 23 : /*! 24 : * \ingroup CoordinateMapsGroup 25 : * \brief A CoordinateMap that swaps/negates the coordinate 26 : * axes. 27 : * 28 : * Providing an OrientationMap to the constructor allows for 29 : * the resulting map to have different orientations. 30 : */ 31 : template <size_t VolumeDim> 32 1 : class DiscreteRotation { 33 : public: 34 0 : static constexpr size_t dim = VolumeDim; 35 : 36 0 : explicit DiscreteRotation( 37 : OrientationMap<VolumeDim> orientation = OrientationMap<VolumeDim>{}); 38 0 : ~DiscreteRotation() = default; 39 0 : DiscreteRotation(const DiscreteRotation&) = default; 40 0 : DiscreteRotation(DiscreteRotation&&) = default; // NOLINT 41 0 : DiscreteRotation& operator=(const DiscreteRotation&) = default; 42 0 : DiscreteRotation& operator=(DiscreteRotation&&) = default; 43 : 44 : template <typename T> 45 0 : std::array<tt::remove_cvref_wrap_t<T>, VolumeDim> operator()( 46 : const std::array<T, VolumeDim>& source_coords) const; 47 : 48 : /// The inverse function is only callable with doubles because the inverse 49 : /// might fail if called for a point out of range, and it is unclear 50 : /// what should happen if the inverse were to succeed for some points in a 51 : /// DataVector but fail for other points. 52 1 : std::optional<std::array<double, VolumeDim>> inverse( 53 : const std::array<double, VolumeDim>& target_coords) const; 54 : 55 : template <typename T> 56 0 : tnsr::Ij<tt::remove_cvref_wrap_t<T>, VolumeDim, Frame::NoFrame> jacobian( 57 : const std::array<T, VolumeDim>& source_coords) const; 58 : 59 : template <typename T> 60 0 : tnsr::Ij<tt::remove_cvref_wrap_t<T>, VolumeDim, Frame::NoFrame> inv_jacobian( 61 : const std::array<T, VolumeDim>& source_coords) const; 62 : 63 : // NOLINTNEXTLINE(google-runtime-references) 64 0 : void pup(PUP::er& p); 65 : 66 0 : bool is_identity() const { return is_identity_; } 67 : 68 : private: 69 0 : friend bool operator==(const DiscreteRotation& lhs, 70 : const DiscreteRotation& rhs) { 71 : return lhs.orientation_ == rhs.orientation_ and 72 : lhs.is_identity_ == rhs.is_identity_; 73 : } 74 : 75 0 : OrientationMap<VolumeDim> orientation_{}; 76 0 : bool is_identity_ = false; 77 : }; 78 : 79 : template <size_t VolumeDim> 80 0 : inline bool operator!=(const CoordinateMaps::DiscreteRotation<VolumeDim>& lhs, 81 : const CoordinateMaps::DiscreteRotation<VolumeDim>& rhs) { 82 : return not(lhs == rhs); 83 : } 84 : 85 : } // namespace CoordinateMaps 86 : } // namespace domain