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 0 : static constexpr bool supports_hessian{Map1::supports_hessian and
72 : Map2::supports_hessian};
73 :
74 : private:
75 0 : friend bool operator==(const ProductOf2Maps& lhs, const ProductOf2Maps& rhs) {
76 : return lhs.map1_ == rhs.map1_ and lhs.map2_ == rhs.map2_ and
77 : lhs.is_identity_ == rhs.is_identity_;
78 : }
79 :
80 0 : Map1 map1_;
81 0 : Map2 map2_;
82 0 : bool is_identity_ = false;
83 : };
84 :
85 : template <typename Map1, typename Map2>
86 0 : bool operator!=(const ProductOf2Maps<Map1, Map2>& lhs,
87 : const ProductOf2Maps<Map1, Map2>& rhs);
88 :
89 : /// \ingroup CoordinateMapsGroup
90 : /// \brief Product of three one-dimensional CoordinateMaps.
91 : template <typename Map1, typename Map2, typename Map3>
92 1 : class ProductOf3Maps {
93 : public:
94 0 : static constexpr size_t dim = Map1::dim + Map2::dim + Map3::dim;
95 0 : using map_list = tmpl::list<Map1, Map2, Map3>;
96 : static_assert(dim == 3, "Only 3D maps are implemented for ProductOf3Maps");
97 :
98 : // Needed for Charm++ serialization
99 0 : ProductOf3Maps() = default;
100 :
101 0 : ProductOf3Maps(Map1 map1, Map2 map2, Map3 map3);
102 :
103 : template <typename T>
104 0 : std::array<tt::remove_cvref_wrap_t<T>, dim> operator()(
105 : const std::array<T, dim>& source_coords) const;
106 :
107 0 : std::optional<std::array<double, dim>> inverse(
108 : const std::array<double, dim>& target_coords) const;
109 :
110 : template <typename T>
111 0 : tnsr::Ij<tt::remove_cvref_wrap_t<T>, dim, Frame::NoFrame> inv_jacobian(
112 : const std::array<T, dim>& source_coords) const;
113 :
114 : template <typename T>
115 0 : tnsr::Ij<tt::remove_cvref_wrap_t<T>, dim, Frame::NoFrame> jacobian(
116 : const std::array<T, dim>& source_coords) const;
117 :
118 : // NOLINTNEXTLINE(google-runtime-references)
119 0 : void pup(PUP::er& p);
120 :
121 0 : bool is_identity() const { return is_identity_; }
122 :
123 0 : static constexpr bool supports_hessian{Map1::supports_hessian and
124 : Map2::supports_hessian and
125 : Map3::supports_hessian};
126 :
127 : private:
128 0 : friend bool operator==(const ProductOf3Maps& lhs, const ProductOf3Maps& rhs) {
129 : return lhs.map1_ == rhs.map1_ and lhs.map2_ == rhs.map2_ and
130 : lhs.map3_ == rhs.map3_ and lhs.is_identity_ == rhs.is_identity_;
131 : }
132 :
133 0 : Map1 map1_;
134 0 : Map2 map2_;
135 0 : Map3 map3_;
136 0 : bool is_identity_ = false;
137 : };
138 :
139 : template <typename Map1, typename Map2, typename Map3>
140 0 : bool operator!=(const ProductOf3Maps<Map1, Map2, Map3>& lhs,
141 : const ProductOf3Maps<Map1, Map2, Map3>& rhs);
142 : } // namespace CoordinateMaps
143 : } // namespace domain
|