Line data Source code
1 1 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : /// \file
5 : /// Defines the class templates ProductOf2Maps and ProductOf3Maps.
6 :
7 : #pragma once
8 :
9 : #include <array>
10 : #include <cstddef>
11 : #include <functional>
12 : #include <optional>
13 : #include <utility>
14 :
15 : #include "DataStructures/Tensor/Tensor.hpp"
16 : #include "Utilities/DereferenceWrapper.hpp"
17 : #include "Utilities/MakeWithValue.hpp"
18 : #include "Utilities/TMPL.hpp"
19 : #include "Utilities/TypeTraits/RemoveReferenceWrapper.hpp"
20 :
21 : /// \cond
22 : namespace PUP {
23 : class er;
24 : } // namespace PUP
25 : /// \endcond
26 :
27 : namespace domain {
28 : namespace CoordinateMaps {
29 : /// \ingroup CoordinateMapsGroup
30 : /// \brief Product of two codimension=0 CoordinateMaps.
31 : ///
32 : /// \tparam Map1 the map for the first coordinate(s)
33 : /// \tparam Map2 the map for the second coordinate(s)
34 : template <typename Map1, typename Map2>
35 1 : class ProductOf2Maps {
36 : public:
37 0 : static constexpr size_t dim = Map1::dim + Map2::dim;
38 0 : using map_list = tmpl::list<Map1, Map2>;
39 : static_assert(dim == 2 or dim == 3,
40 : "Only 2D and 3D maps are supported by ProductOf2Maps");
41 :
42 : // Needed for Charm++ serialization
43 0 : ProductOf2Maps() = default;
44 :
45 0 : ProductOf2Maps(Map1 map1, Map2 map2);
46 :
47 : template <typename T>
48 0 : std::array<tt::remove_cvref_wrap_t<T>, dim> operator()(
49 : const std::array<T, dim>& source_coords) const;
50 :
51 : /// The inverse function is only callable with doubles because the inverse
52 : /// might fail if called for a point out of range, and it is unclear
53 : /// what should happen if the inverse were to succeed for some points in a
54 : /// DataVector but fail for other points.
55 1 : std::optional<std::array<double, dim>> inverse(
56 : const std::array<double, dim>& target_coords) const;
57 :
58 : template <typename T>
59 0 : tnsr::Ij<tt::remove_cvref_wrap_t<T>, dim, Frame::NoFrame> inv_jacobian(
60 : const std::array<T, dim>& source_coords) const;
61 :
62 : template <typename T>
63 0 : tnsr::Ij<tt::remove_cvref_wrap_t<T>, dim, Frame::NoFrame> jacobian(
64 : const std::array<T, dim>& source_coords) const;
65 :
66 : // NOLINTNEXTLINE(google-runtime-references)
67 0 : void pup(PUP::er& p);
68 :
69 0 : bool is_identity() const { return is_identity_; }
70 :
71 : private:
72 0 : friend bool operator==(const ProductOf2Maps& lhs, const ProductOf2Maps& rhs) {
73 : return lhs.map1_ == rhs.map1_ and lhs.map2_ == rhs.map2_ and
74 : lhs.is_identity_ == rhs.is_identity_;
75 : }
76 :
77 0 : Map1 map1_;
78 0 : Map2 map2_;
79 0 : bool is_identity_ = false;
80 : };
81 :
82 : template <typename Map1, typename Map2>
83 0 : bool operator!=(const ProductOf2Maps<Map1, Map2>& lhs,
84 : const ProductOf2Maps<Map1, Map2>& rhs);
85 :
86 : /// \ingroup CoordinateMapsGroup
87 : /// \brief Product of three one-dimensional CoordinateMaps.
88 : template <typename Map1, typename Map2, typename Map3>
89 1 : class ProductOf3Maps {
90 : public:
91 0 : static constexpr size_t dim = Map1::dim + Map2::dim + Map3::dim;
92 0 : using map_list = tmpl::list<Map1, Map2, Map3>;
93 : static_assert(dim == 3, "Only 3D maps are implemented for ProductOf3Maps");
94 :
95 : // Needed for Charm++ serialization
96 0 : ProductOf3Maps() = default;
97 :
98 0 : ProductOf3Maps(Map1 map1, Map2 map2, Map3 map3);
99 :
100 : template <typename T>
101 0 : std::array<tt::remove_cvref_wrap_t<T>, dim> operator()(
102 : const std::array<T, dim>& source_coords) const;
103 :
104 0 : std::optional<std::array<double, dim>> inverse(
105 : const std::array<double, dim>& target_coords) const;
106 :
107 : template <typename T>
108 0 : tnsr::Ij<tt::remove_cvref_wrap_t<T>, dim, Frame::NoFrame> inv_jacobian(
109 : const std::array<T, dim>& source_coords) const;
110 :
111 : template <typename T>
112 0 : tnsr::Ij<tt::remove_cvref_wrap_t<T>, dim, Frame::NoFrame> jacobian(
113 : const std::array<T, dim>& source_coords) const;
114 :
115 : // NOLINTNEXTLINE(google-runtime-references)
116 0 : void pup(PUP::er& p);
117 :
118 0 : bool is_identity() const { return is_identity_; }
119 :
120 : private:
121 0 : friend bool operator==(const ProductOf3Maps& lhs, const ProductOf3Maps& rhs) {
122 : return lhs.map1_ == rhs.map1_ and lhs.map2_ == rhs.map2_ and
123 : lhs.map3_ == rhs.map3_ and lhs.is_identity_ == rhs.is_identity_;
124 : }
125 :
126 0 : Map1 map1_;
127 0 : Map2 map2_;
128 0 : Map3 map3_;
129 0 : bool is_identity_ = false;
130 : };
131 :
132 : template <typename Map1, typename Map2, typename Map3>
133 0 : bool operator!=(const ProductOf3Maps<Map1, Map2, Map3>& lhs,
134 : const ProductOf3Maps<Map1, Map2, Map3>& rhs);
135 : } // namespace CoordinateMaps
136 : } // namespace domain
|