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