ProductMaps.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <boost/optional.hpp>
8 #include <cstddef>
9 #include <functional>
10 #include <limits>
11 #include <string>
12 #include <unordered_map>
13 #include <utility>
14 
16 #include "Domain/CoordinateMaps/TimeDependentHelpers.hpp"
17 #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
20 #include "Utilities/TMPL.hpp"
21 #include "Utilities/TypeTraits/RemoveReferenceWrapper.hpp"
22 
23 /// \cond
24 namespace PUP {
25 class er;
26 } // namespace PUP
27 /// \endcond
28 
29 namespace domain {
30 namespace CoordinateMaps {
31 namespace TimeDependent {
32 /// \ingroup CoordMapsTimeDependentGroup
33 /// \brief Product of two codimension=0 CoordinateMaps, where one or both must
34 /// be time-dependent.
35 ///
36 /// \tparam Map1 the map for the first coordinate(s)
37 /// \tparam Map2 the map for the second coordinate(s)
38 template <typename Map1, typename Map2>
40  public:
41  static constexpr size_t dim = Map1::dim + Map2::dim;
42  using map_list = tmpl::list<Map1, Map2>;
43  static_assert(dim == 2 or dim == 3,
44  "Only 2D and 3D maps are supported by ProductOf2Maps");
45  static_assert(
46  domain::is_map_time_dependent_v<Map1> or
47  domain::is_map_time_dependent_v<Map2>,
48  "Either Map1 or Map2 must be time-dependent for time-dependent product "
49  "maps. A time-independent product map exists in domain::CoordinateMaps.");
50 
51  // Needed for Charm++ serialization
52  ProductOf2Maps() = default;
53 
54  ProductOf2Maps(Map1 map1, Map2 map2) noexcept;
55 
56  template <typename T>
58  const std::array<T, dim>& source_coords, double time,
59  const std::unordered_map<
62  functions_of_time) const noexcept;
63 
64  boost::optional<std::array<double, dim>> inverse(
65  const std::array<double, dim>& target_coords, double time,
66  const std::unordered_map<
69  functions_of_time) const noexcept;
70 
71  template <typename T>
72  std::array<tt::remove_cvref_wrap_t<T>, dim> frame_velocity(
73  const std::array<T, dim>& source_coords, double time,
74  const std::unordered_map<
77  functions_of_time) const noexcept;
78 
79  template <typename T>
80  tnsr::Ij<tt::remove_cvref_wrap_t<T>, dim, Frame::NoFrame> inv_jacobian(
81  const std::array<T, dim>& source_coords, double time,
82  const std::unordered_map<
85  functions_of_time) const noexcept;
86 
87  template <typename T>
88  tnsr::Ij<tt::remove_cvref_wrap_t<T>, dim, Frame::NoFrame> jacobian(
89  const std::array<T, dim>& source_coords, double time,
90  const std::unordered_map<
93  functions_of_time) const noexcept;
94 
95  // clang-tidy: google-runtime-references
96  void pup(PUP::er& p); // NOLINT
97 
98  bool is_identity() const noexcept {
99  return map1_.is_identity() and map2_.is_identity();
100  }
101 
102  private:
103  friend bool operator==(const ProductOf2Maps& lhs,
104  const ProductOf2Maps& rhs) noexcept {
105  return lhs.map1_ == rhs.map1_ and lhs.map2_ == rhs.map2_;
106  }
107 
108  Map1 map1_;
109  Map2 map2_;
110 };
111 
112 template <typename Map1, typename Map2>
113 bool operator!=(const ProductOf2Maps<Map1, Map2>& lhs,
114  const ProductOf2Maps<Map1, Map2>& rhs) noexcept;
115 
116 /// \ingroup CoordinateMapsGroup
117 /// \brief Product of three one-dimensional CoordinateMaps.
118 template <typename Map1, typename Map2, typename Map3>
120  public:
121  static constexpr size_t dim = Map1::dim + Map2::dim + Map3::dim;
122  using map_list = tmpl::list<Map1, Map2, Map3>;
123  static_assert(dim == 3, "Only 3D maps are implemented for ProductOf3Maps");
124  static_assert(
125  domain::is_map_time_dependent_v<Map1> or
126  domain::is_map_time_dependent_v<Map2> or
127  domain::is_map_time_dependent_v<Map3>,
128  "Either Map1, Map2, or Map3 must be time-dependent for time-dependent "
129  "product maps. A time-independent product map exists in "
130  "domain::CoordinateMaps.");
131 
132  // Needed for Charm++ serialization
133  ProductOf3Maps() = default;
134 
135  ProductOf3Maps(Map1 map1, Map2 map2, Map3 map3) noexcept;
136 
137  template <typename T>
138  std::array<tt::remove_cvref_wrap_t<T>, dim> operator()(
139  const std::array<T, dim>& source_coords, double time,
140  const std::unordered_map<
141  std::string,
143  functions_of_time) const noexcept;
144 
145  boost::optional<std::array<double, dim>> inverse(
146  const std::array<double, dim>& target_coords, double time,
147  const std::unordered_map<
148  std::string,
150  functions_of_time) const noexcept;
151 
152  template <typename T>
153  std::array<tt::remove_cvref_wrap_t<T>, dim> frame_velocity(
154  const std::array<T, dim>& source_coords, double time,
155  const std::unordered_map<
156  std::string,
158  functions_of_time) const noexcept;
159 
160  template <typename T>
161  tnsr::Ij<tt::remove_cvref_wrap_t<T>, dim, Frame::NoFrame> inv_jacobian(
162  const std::array<T, dim>& source_coords, double time,
163  const std::unordered_map<
164  std::string,
166  functions_of_time) const noexcept;
167 
168  template <typename T>
169  tnsr::Ij<tt::remove_cvref_wrap_t<T>, dim, Frame::NoFrame> jacobian(
170  const std::array<T, dim>& source_coords, double time,
171  const std::unordered_map<
172  std::string,
174  functions_of_time) const noexcept;
175 
176  // clang-tidy: google-runtime-references
177  void pup(PUP::er& p) noexcept; // NOLINT
178 
179  bool is_identity() const noexcept {
180  return map1_.is_identity() and map2_.is_identity() and map3_.is_identity();
181  }
182 
183  private:
184  friend bool operator==(const ProductOf3Maps& lhs,
185  const ProductOf3Maps& rhs) noexcept {
186  return lhs.map1_ == rhs.map1_ and lhs.map2_ == rhs.map2_ and
187  lhs.map3_ == rhs.map3_;
188  }
189 
190  Map1 map1_;
191  Map2 map2_;
192  Map3 map3_;
193 };
194 
195 template <typename Map1, typename Map2, typename Map3>
196 bool operator!=(const ProductOf3Maps<Map1, Map2, Map3>& lhs,
197  const ProductOf3Maps<Map1, Map2, Map3>& rhs) noexcept;
198 } // namespace TimeDependent
199 } // namespace CoordinateMaps
200 } // namespace domain
std::string
utility
functional
domain::CoordinateMaps::TimeDependent::ProductOf2Maps
Product of two codimension=0 CoordinateMaps, where one or both must be time-dependent.
Definition: ProductMaps.hpp:39
Frame::NoFrame
Represents an index that is not in a known frame, e.g. some internal intermediate frame that is irrel...
Definition: IndexType.hpp:48
cstddef
MakeWithValue.hpp
array
DereferenceWrapper.hpp
limits
domain::CoordinateMaps::TimeDependent::ProductOf3Maps
Product of three one-dimensional CoordinateMaps.
Definition: ProductMaps.hpp:119
Tensor.hpp
std::unique_ptr
unordered_map
TMPL.hpp
string