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
|