Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <boost/preprocessor/punctuation/comma_if.hpp>
7 : #include <boost/preprocessor/repetition/repeat.hpp>
8 : #include <boost/preprocessor/tuple/elem.hpp>
9 : #include <boost/preprocessor/tuple/enum.hpp>
10 : #include <boost/preprocessor/tuple/size.hpp>
11 : #include <memory>
12 : #include <optional>
13 : #include <pup.h>
14 : #include <string>
15 : #include <tuple>
16 : #include <unordered_map>
17 : #include <utility>
18 :
19 : #include "DataStructures/Tensor/Tensor.hpp"
20 : #include "Domain/CoordinateMaps/CoordinateMap.hpp"
21 : #include "Domain/CoordinateMaps/CoordinateMap.tpp"
22 : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
23 : #include "Utilities/GenerateInstantiations.hpp"
24 :
25 0 : #define INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS(data) \
26 : BOOST_PP_TUPLE_ENUM(BOOST_PP_TUPLE_ELEM(0, data))
27 0 : #define INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data) \
28 : BOOST_PP_TUPLE_ELEM(BOOST_PP_TUPLE_SIZE(BOOST_PP_TUPLE_ELEM(0, data)), 0, \
29 : BOOST_PP_TUPLE_ELEM(0, data))::dim
30 0 : #define INSTANTIATE_COORD_MAP_DETAILINSERT_SIZE(z, n, _) BOOST_PP_COMMA_IF(n) n
31 :
32 0 : #define INSTANTIATE_COORD_MAP_DETAIL_GET_FILLED_INDEX_SEQUENCE(data) \
33 : BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(BOOST_PP_TUPLE_ELEM(0, data)), \
34 : INSTANTIATE_COORD_MAP_DETAILINSERT_SIZE, _)
35 :
36 0 : #define INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data) \
37 : BOOST_PP_TUPLE_ELEM(1, data)
38 :
39 0 : #define INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data) \
40 : BOOST_PP_TUPLE_ELEM(2, data)
41 :
42 0 : #define INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data) BOOST_PP_TUPLE_ELEM(3, data)
43 :
44 : /*!
45 : * \ingroup ComputationalDomainGroup
46 : * \brief Generate instantiations of member functions of the `CoordinateMap`
47 : * class template.
48 : *
49 : * Called as follows:
50 : *
51 : * \code
52 : * using Affine2d =
53 : * domain::CoordinateMaps::ProductOf2Maps<domain::CoordinateMaps::Affine,
54 : * domain::CoordinateMaps::Affine>;
55 : * using Affine3d =
56 : * domain::CoordinateMaps::ProductOf3Maps<domain::CoordinateMaps::Affine,
57 : * domain::CoordinateMaps::Affine,
58 : * domain::CoordinateMaps::Affine>;
59 : *
60 : * GENERATE_INSTANTIATIONS(INSTANTIATE_MAPS_SIMPLE_FUNCTIONS,
61 : * ((Affine2d), (Affine3d)), (Frame::BlockLogical),
62 : * (Frame::Grid, Frame::Inertial))
63 : * \endcode
64 : *
65 : * The first tuple passed to `GENERATE_INSTANTIATIONS` has a bunch of tuples in
66 : * it that is the list of maps being composed. The reason for defining the type
67 : * aliases `Affine2d` and `Affine3d` is that otherwise the number of maps being
68 : * composed is calculated incorrectly. The second tuple contains the source
69 : * frames for the map. The third tuple passed to `GENERATE_INSTANTIATIONS`
70 : * contains the target frames to instantiate for, typically `Frame::Grid` and
71 : * `Frame::Inertial`.
72 : *
73 : * Instantiates:
74 : * - `get_to_grid_frame_impl`
75 : * - `inverse_impl`
76 : * - `class CoordinateMap`
77 : */
78 1 : #define INSTANTIATE_MAPS_SIMPLE_FUNCTIONS(_, data) \
79 : template std::unique_ptr<domain::CoordinateMapBase< \
80 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), Frame::Grid, \
81 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data)>> \
82 : domain::CoordinateMap< \
83 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), \
84 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data), \
85 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS(data)>:: \
86 : get_to_grid_frame_impl( \
87 : std::integer_sequence< \
88 : unsigned long, \
89 : INSTANTIATE_COORD_MAP_DETAIL_GET_FILLED_INDEX_SEQUENCE( \
90 : data)>) const; \
91 : template std::optional< \
92 : tnsr::I<double, INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
93 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data)>> \
94 : domain::CoordinateMap<INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), \
95 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data), \
96 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS(data)>:: \
97 : inverse_impl( \
98 : tnsr::I<double, INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
99 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data)>&&, \
100 : double, \
101 : const std::unordered_map< \
102 : std::string, \
103 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&, \
104 : std::index_sequence< \
105 : INSTANTIATE_COORD_MAP_DETAIL_GET_FILLED_INDEX_SEQUENCE( \
106 : data)> /*meta*/) const; \
107 : template class domain::CoordinateMap< \
108 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), \
109 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data), \
110 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS(data)>;
111 :
112 : /*!
113 : * \ingroup ComputationalDomainGroup
114 : * \brief Generate instantiations of member functions of the `CoordinateMap`
115 : * class template.
116 : *
117 : * Called as follows:
118 : *
119 : * \code
120 : * using Affine2d =
121 : * domain::CoordinateMaps::ProductOf2Maps<domain::CoordinateMaps::Affine,
122 : * domain::CoordinateMaps::Affine>;
123 : * using Affine3d =
124 : * domain::CoordinateMaps::ProductOf3Maps<domain::CoordinateMaps::Affine,
125 : * domain::CoordinateMaps::Affine,
126 : * domain::CoordinateMaps::Affine>;
127 : *
128 : * GENERATE_INSTANTIATIONS(INSTANTIATE_MAPS_DATA_TYPE_FUNCTIONS,
129 : * ((Affine2d), (Affine3d)), (Frame::BlockLogical),
130 : * (Frame::Grid, Frame::Inertial),
131 : * (double, DataVector))
132 : * \endcode
133 : *
134 : * The first tuple passed to `GENERATE_INSTANTIATIONS` has a bunch of tuples in
135 : * it that is the list of maps being composed. The reason for defining the type
136 : * aliases `Affine2d` and `Affine3d` is that otherwise the number of maps being
137 : * composed is calculated incorrectly. The second tuple contains the source
138 : * frames for the map. The third tuple passed to `GENERATE_INSTANTIATIONS`
139 : * contains the target frames to instantiate for, typically `Frame::Grid` and
140 : * `Frame::Inertial`. The last tuple is the data types for which to instantiate
141 : * the functions, usually `double` and `DataVector`.
142 : *
143 : * Instantiates:
144 : * - `call_impl`
145 : * - `inv_jacobian_impl`
146 : * - `jacobian_impl`
147 : * - `coords_frame_velocity_jacobians_impl`
148 : */
149 1 : #define INSTANTIATE_MAPS_DATA_TYPE_FUNCTIONS(_, data) \
150 : template tnsr::I<INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data), \
151 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
152 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data)> \
153 : domain::CoordinateMap<INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), \
154 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data), \
155 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS(data)>:: \
156 : call_impl( \
157 : tnsr::I<INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data), \
158 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
159 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data)>&&, \
160 : double, \
161 : const std::unordered_map< \
162 : std::string, \
163 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&, \
164 : std::integer_sequence< \
165 : unsigned long, \
166 : INSTANTIATE_COORD_MAP_DETAIL_GET_FILLED_INDEX_SEQUENCE(data)>) \
167 : const; \
168 : template InverseJacobian< \
169 : INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data), \
170 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
171 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), \
172 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data)> \
173 : domain::CoordinateMap<INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), \
174 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data), \
175 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS(data)>:: \
176 : inv_jacobian_impl( \
177 : tnsr::I<INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data), \
178 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
179 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data)>&&, \
180 : double, \
181 : const std::unordered_map< \
182 : std::string, \
183 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&) \
184 : const; \
185 : template Jacobian<INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data), \
186 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
187 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), \
188 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data)> \
189 : domain::CoordinateMap<INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), \
190 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data), \
191 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS(data)>:: \
192 : jacobian_impl( \
193 : tnsr::I<INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data), \
194 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
195 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data)>&&, \
196 : double, \
197 : const std::unordered_map< \
198 : std::string, \
199 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&) \
200 : const; \
201 : template std::tuple< \
202 : tnsr::I<INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data), \
203 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
204 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data)>, \
205 : InverseJacobian<INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data), \
206 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
207 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), \
208 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data)>, \
209 : Jacobian<INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data), \
210 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
211 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), \
212 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data)>, \
213 : tnsr::I<INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data), \
214 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
215 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data)>> \
216 : domain::CoordinateMap<INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data), \
217 : INSTANTIATE_COORD_MAP_DETAIL_GET_TARGET_FRAME(data), \
218 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS(data)>:: \
219 : coords_frame_velocity_jacobians_impl( \
220 : tnsr::I<INSTANTIATE_COORD_MAP_DETAIL_DTYPE(data), \
221 : INSTANTIATE_COORD_MAP_DETAIL_GET_MAPS_DIM(data), \
222 : INSTANTIATE_COORD_MAP_DETAIL_GET_SOURCE_FRAME(data)>, \
223 : double, \
224 : const std::unordered_map< \
225 : std::string, \
226 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&) \
227 : const;
228 :
229 : /*!
230 : * \ingroup ComputationalDomainGroup
231 : * \brief Generate instantiations of member functions of the `CoordinateMap`
232 : * class template.
233 : *
234 : * Called as follows:
235 : *
236 : * \code
237 : * using Affine2d =
238 : * domain::CoordinateMaps::ProductOf2Maps<domain::CoordinateMaps::Affine,
239 : * domain::CoordinateMaps::Affine>;
240 : * using Affine3d =
241 : * domain::CoordinateMaps::ProductOf3Maps<domain::CoordinateMaps::Affine,
242 : * domain::CoordinateMaps::Affine,
243 : * domain::CoordinateMaps::Affine>;
244 : *
245 : * INSTANTIATE_MAPS_FUNCTIONS(((Affine2d), (Affine3d)), (Frame::BlockLogical),
246 : * (Frame::Grid, Frame::Inertial),
247 : * (double, DataVector))
248 : * \endcode
249 : *
250 : * The first tuple passed to `GENERATE_INSTANTIATIONS` has a bunch of tuples in
251 : * it that is the list of maps being composed. The reason for defining the type
252 : * aliases `Affine2d` and `Affine3d` is that otherwise the number of maps being
253 : * composed is calculated incorrectly. The second tuple contains the source
254 : * frames for the map. The third tuple passed to `GENERATE_INSTANTIATIONS`
255 : * contains the frames to instantiate for, typically `Frame::Grid` and
256 : * `Frame::Inertial`.
257 : *
258 : * Instantiates:
259 : * - `get_to_grid_frame_impl`
260 : * - `inverse_impl`
261 : * - `class CoordinateMap`
262 : * - `call_impl`
263 : * - `inv_jacobian_impl`
264 : * - `jacobian_impl`
265 : * - `coords_frame_velocity_jacobians_impl`
266 : */
267 : #define INSTANTIATE_MAPS_FUNCTIONS(MAPS_TUPLE, SOURCE_FRAME, \
268 1 : TARGET_FRAMES_TUPLE, TYPES_TUPLE) \
269 : GENERATE_INSTANTIATIONS(INSTANTIATE_MAPS_SIMPLE_FUNCTIONS, MAPS_TUPLE, \
270 : SOURCE_FRAME, TARGET_FRAMES_TUPLE) \
271 : GENERATE_INSTANTIATIONS(INSTANTIATE_MAPS_DATA_TYPE_FUNCTIONS, MAPS_TUPLE, \
272 : SOURCE_FRAME, TARGET_FRAMES_TUPLE, TYPES_TUPLE)
|