Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cmath>
7 :
8 : #include "DataStructures/Matrix.hpp"
9 : #include "DataStructures/Tags.hpp"
10 : #include "Evolution/Systems/Cce/Equations.hpp"
11 : #include "Evolution/Systems/Cce/Tags.hpp"
12 : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshTags.hpp"
13 : #include "Utilities/TMPL.hpp"
14 :
15 : namespace Cce {
16 :
17 : /*!
18 : * The set of Bondi quantities computed by hypersurface step, in the required
19 : * order of computation
20 : */
21 1 : using bondi_hypersurface_step_tags =
22 : tmpl::list<Tags::BondiBeta, Tags::BondiQ, Tags::BondiU, Tags::BondiW,
23 : Tags::BondiH>;
24 :
25 : /*!
26 : * Metafunction that is a `tmpl::list` of the temporary tags taken by the
27 : * `ComputeBondiIntegrand` computational struct.
28 : */
29 : template <typename Tag>
30 1 : using integrand_temporary_tags =
31 : typename ComputeBondiIntegrand<Tag>::temporary_tags;
32 :
33 : namespace detail {
34 : // structs containing typelists for organizing the set of tags needed at each
35 : // step of the CCE hypersurface evaluation steps. These are not directly the
36 : // tags that are inputs in the `Equations.hpp`, as those would contain
37 : // redundancy, and not necessarily obtain the derivatives during the most ideal
38 : // steps. So, the ordering in these structs has been slightly 'designed' in ways
39 : // that are not trivial to automate with tmpl list manipulation
40 : template <typename Tag>
41 : struct TagsToComputeForImpl;
42 :
43 : template <>
44 : struct TagsToComputeForImpl<Tags::BondiBeta> {
45 : using pre_swsh_derivative_tags =
46 : tmpl::list<Tags::Dy<Tags::BondiJ>, Tags::Dy<Tags::Dy<Tags::BondiJ>>>;
47 : using second_swsh_derivative_tags = tmpl::list<>;
48 : using swsh_derivative_tags = tmpl::list<>;
49 : };
50 :
51 : // Note: Due to the order in which Jacobians for the conversion between
52 : // numerical and Bondi spin-weighted derivatives are evaluated, all of the
53 : // higher (second) spin-weighted derivatives must be computed AFTER the
54 : // eth(dy(bondi)) values (which act as inputs to the second derivative
55 : // conversions to fixed Bondi radius), so must appear later in the
56 : // `swsh_derivative_tags` typelists.
57 : template <>
58 : struct TagsToComputeForImpl<Tags::BondiQ> {
59 : using pre_swsh_derivative_tags =
60 : tmpl::list<Tags::Dy<Tags::BondiBeta>, Tags::Dy<Tags::Dy<Tags::BondiBeta>>,
61 : ::Tags::Multiplies<Tags::BondiJ, Tags::BondiJbar>,
62 : ::Tags::Multiplies<Tags::BondiJbar, Tags::Dy<Tags::BondiJ>>>;
63 : using swsh_derivative_tags = tmpl::list<
64 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
65 : Spectral::Swsh::Tags::Eth>,
66 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiBeta>,
67 : Spectral::Swsh::Tags::Eth>,
68 : Spectral::Swsh::Tags::Derivative<
69 : ::Tags::Multiplies<Tags::BondiJ, Tags::BondiJbar>,
70 : Spectral::Swsh::Tags::Eth>,
71 : Spectral::Swsh::Tags::Derivative<
72 : ::Tags::Multiplies<Tags::BondiJbar, Tags::Dy<Tags::BondiJ>>,
73 : Spectral::Swsh::Tags::Eth>,
74 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiJ>,
75 : Spectral::Swsh::Tags::Ethbar>,
76 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
77 : Spectral::Swsh::Tags::Ethbar>>;
78 : using second_swsh_derivative_tags = tmpl::list<>;
79 : };
80 :
81 : template <>
82 : struct TagsToComputeForImpl<Tags::BondiU> {
83 : using pre_swsh_derivative_tags =
84 : tmpl::list<Tags::Exp2Beta, Tags::Dy<Tags::BondiQ>,
85 : Tags::Dy<Tags::Dy<Tags::BondiQ>>>;
86 : using second_swsh_derivative_tags = tmpl::list<>;
87 : using swsh_derivative_tags = tmpl::list<>;
88 : };
89 :
90 : template <>
91 : struct TagsToComputeForImpl<Tags::BondiW> {
92 : using pre_swsh_derivative_tags =
93 : tmpl::list<Tags::Dy<Tags::BondiU>, Tags::Dy<Tags::Dy<Tags::BondiU>>,
94 : Tags::Dy<::Tags::Multiplies<Tags::BondiJ, Tags::BondiJbar>>,
95 : Tags::Dy<Spectral::Swsh::Tags::Derivative<
96 : Tags::BondiJ, Spectral::Swsh::Tags::Ethbar>>>;
97 : using swsh_derivative_tags = tmpl::list<
98 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiBeta>,
99 : Spectral::Swsh::Tags::Ethbar>,
100 : Spectral::Swsh::Tags::Derivative<
101 : Tags::Dy<::Tags::Multiplies<Tags::BondiJ, Tags::BondiJbar>>,
102 : Spectral::Swsh::Tags::Ethbar>,
103 : Spectral::Swsh::Tags::Derivative<
104 : Tags::Dy<::Tags::Multiplies<Tags::BondiJ, Tags::BondiJbar>>,
105 : Spectral::Swsh::Tags::Eth>,
106 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiU>,
107 : Spectral::Swsh::Tags::Ethbar>,
108 : Spectral::Swsh::Tags::Derivative<Tags::BondiU,
109 : Spectral::Swsh::Tags::Ethbar>>;
110 : // Currently, the `eth_ethbar_j` term is the single instance of a swsh
111 : // derivative needing nested `Spectral::Swsh::Tags::Derivatives` steps to
112 : // compute. The reason is that if we do not compute the derivative in two
113 : // steps, there are intermediate terms in the Jacobian which depend on eth_j,
114 : // which is a spin-weight 3 quantity and therefore cannot be computed with
115 : // libsharp (the SWSH library being used). If `eth_ethbar_j` becomes not
116 : // needed, the remaining `second_swsh_derivative_tags` can be merged to the
117 : // end of `swsh_derivative_tags` and the corresponding computational steps
118 : // from `SwshDerivatives.hpp` removed.
119 : using second_swsh_derivative_tags =
120 : tmpl::list<Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
121 : Spectral::Swsh::Tags::EthEth>,
122 : Spectral::Swsh::Tags::Derivative<
123 : Tags::BondiBeta, Spectral::Swsh::Tags::EthEthbar>,
124 : Spectral::Swsh::Tags::Derivative<
125 : ::Tags::Multiplies<Tags::BondiJ, Tags::BondiJbar>,
126 : Spectral::Swsh::Tags::EthEthbar>,
127 : Spectral::Swsh::Tags::Derivative<
128 : Tags::BondiJ, Spectral::Swsh::Tags::EthbarEthbar>,
129 : Spectral::Swsh::Tags::Derivative<
130 : Spectral::Swsh::Tags::Derivative<
131 : Tags::BondiJ, Spectral::Swsh::Tags::Ethbar>,
132 : Spectral::Swsh::Tags::Eth>>;
133 : };
134 :
135 : template <>
136 : struct TagsToComputeForImpl<Tags::BondiH> {
137 : using pre_swsh_derivative_tags =
138 : tmpl::list<::Tags::Multiplies<Tags::BondiJbar, Tags::BondiU>,
139 : ::Tags::Multiplies<Tags::BondiUbar, Tags::Dy<Tags::BondiJ>>,
140 : Tags::JbarQMinus2EthBeta, Tags::Dy<Tags::BondiW>>;
141 : using swsh_derivative_tags = tmpl::list<
142 : Spectral::Swsh::Tags::Derivative<Tags::BondiQ, Spectral::Swsh::Tags::Eth>,
143 : Spectral::Swsh::Tags::Derivative<Tags::BondiU, Spectral::Swsh::Tags::Eth>,
144 : Spectral::Swsh::Tags::Derivative<
145 : ::Tags::Multiplies<Tags::BondiUbar, Tags::Dy<Tags::BondiJ>>,
146 : Spectral::Swsh::Tags::Eth>,
147 : Spectral::Swsh::Tags::Derivative<
148 : ::Tags::Multiplies<Tags::BondiJbar, Tags::Dy<Tags::BondiJ>>,
149 : Spectral::Swsh::Tags::Ethbar>,
150 : Spectral::Swsh::Tags::Derivative<Tags::JbarQMinus2EthBeta,
151 : Spectral::Swsh::Tags::Ethbar>,
152 : Spectral::Swsh::Tags::Derivative<
153 : ::Tags::Multiplies<Tags::BondiJbar, Tags::BondiU>,
154 : Spectral::Swsh::Tags::Ethbar>,
155 : Spectral::Swsh::Tags::Derivative<Tags::BondiQ,
156 : Spectral::Swsh::Tags::Ethbar>>;
157 : using second_swsh_derivative_tags = tmpl::list<>;
158 : };
159 :
160 : template <>
161 : struct TagsToComputeForImpl<Tags::KleinGordonSource<Tags::BondiBeta>> {
162 : using pre_swsh_derivative_tags = tmpl::list<Tags::Dy<Tags::KleinGordonPsi>>;
163 : using swsh_derivative_tags = tmpl::list<>;
164 : using second_swsh_derivative_tags = tmpl::list<>;
165 : };
166 :
167 : template <>
168 : struct TagsToComputeForImpl<Tags::KleinGordonSource<Tags::BondiQ>> {
169 : using pre_swsh_derivative_tags = tmpl::list<>;
170 : using swsh_derivative_tags =
171 : tmpl::list<Spectral::Swsh::Tags::Derivative<Tags::KleinGordonPsi,
172 : Spectral::Swsh::Tags::Eth>>;
173 : using second_swsh_derivative_tags = tmpl::list<>;
174 : };
175 :
176 : template <>
177 : struct TagsToComputeForImpl<Tags::KleinGordonPi> {
178 : using pre_swsh_derivative_tags =
179 : tmpl::list<Tags::Dy<Tags::Dy<Tags::KleinGordonPsi>>>;
180 : using second_swsh_derivative_tags =
181 : tmpl::list<Spectral::Swsh::Tags::Derivative<Tags::KleinGordonPsi,
182 : Spectral::Swsh::Tags::EthEth>,
183 : Spectral::Swsh::Tags::Derivative<
184 : Tags::KleinGordonPsi, Spectral::Swsh::Tags::EthEthbar>>;
185 : using swsh_derivative_tags = tmpl::list<
186 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::KleinGordonPsi>,
187 : Spectral::Swsh::Tags::Eth>,
188 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::KleinGordonPsi>,
189 : Spectral::Swsh::Tags::Ethbar>,
190 : Spectral::Swsh::Tags::Derivative<Tags::KleinGordonPsi,
191 : Spectral::Swsh::Tags::Eth>,
192 : Spectral::Swsh::Tags::Derivative<Tags::KleinGordonPsi,
193 : Spectral::Swsh::Tags::Ethbar>>;
194 : };
195 : } // namespace detail
196 :
197 : /*!
198 : * \brief A typelist for the set of `BoundaryValue` tags needed as an input to
199 : * any of the template specializations of `PrecomputeCceDependencies`.
200 : *
201 : * \details This is provided for easy and maintainable
202 : * construction of a `Variables` or \ref DataBoxGroup with all of the quantities
203 : * necessary for a CCE computation or portion thereof.
204 : * A container of these tags should have size
205 : * `Spectral::Swsh::number_of_swsh_collocation_points(l_max)`.
206 : */
207 : template <template <typename> class BoundaryPrefix>
208 1 : using pre_computation_boundary_tags =
209 : tmpl::list<BoundaryPrefix<Tags::BondiR>,
210 : BoundaryPrefix<Tags::DuRDividedByR>>;
211 :
212 : /*!
213 : * \brief A typelist for the set of tags computed by the set of
214 : * template specializations of `PrecomputeCceDepedencies`.
215 : *
216 : * \details This is provided for easy and maintainable construction of a
217 : * `Variables` or \ref DataBoxGroup with all of the quantities needed for a CCE
218 : * computation or component. The data structures represented by these tags
219 : * should each have size `number_of_radial_points *
220 : * Spectral::Swsh::number_of_swsh_collocation_points(l_max)`. All of these tags
221 : * may be computed at once if using a \ref DataBoxGroup using the template
222 : * `mutate_all_precompute_cce_dependencies` or individually using
223 : * the template specializations `PrecomputeCceDependencies`.
224 : *
225 : * \note the tag `Tags::DuRDividedByR` is omitted from this list because in the
226 : * case where a gauge transformation must be applied, the time derivative
227 : * quantities must wait until later in the computation.
228 : */
229 1 : using pre_computation_tags =
230 : tmpl::list<Tags::EthRDividedByR, Tags::EthEthRDividedByR,
231 : Tags::EthEthbarRDividedByR, Tags::BondiK, Tags::OneMinusY,
232 : Tags::BondiR>;
233 :
234 : /// @{
235 : /*!
236 : * \brief A typelist for the set of tags computed by the set of
237 : * template specializations of `ComputePreSwshDerivatives`.
238 : *
239 : * \details This is provided for easy and maintainable construction of a
240 : * `Variables` or \ref DataBoxGroup with all of the quantities needed for a CCE
241 : * computation or component. The data structures represented by these tags
242 : * should each have size `number_of_radial_points *
243 : * Spectral::Swsh::number_of_swsh_collocation_points(l_max)`. All of these tags
244 : * (for a given integrated Bondi quantity) may be computed at once if using a
245 : * \ref DataBoxGroup using the template
246 : * `mutate_all_pre_swsh_derivatives_for_tag` or individually using the template
247 : * specializations of `ComputePreSwshDerivatives`. The full set of integrated
248 : * Bondi quantities is available from the typelist
249 : * `bondi_hypersurface_step_tags`.
250 : */
251 : template <typename Tag>
252 1 : struct pre_swsh_derivative_tags_to_compute_for {
253 0 : using type =
254 : typename detail::TagsToComputeForImpl<Tag>::pre_swsh_derivative_tags;
255 : };
256 :
257 : template <typename Tag>
258 0 : using pre_swsh_derivative_tags_to_compute_for_t =
259 : typename pre_swsh_derivative_tags_to_compute_for<Tag>::type;
260 : /// @}
261 :
262 : /// @{
263 : /*!
264 : * \brief A typelist for the set of tags computed by single spin-weighted
265 : * differentiation using utilities from the `Swsh` namespace.
266 : */
267 : template <typename Tag>
268 1 : struct single_swsh_derivative_tags_to_compute_for {
269 0 : using type = typename detail::TagsToComputeForImpl<Tag>::swsh_derivative_tags;
270 : };
271 :
272 : template <typename Tag>
273 0 : using single_swsh_derivative_tags_to_compute_for_t =
274 : typename single_swsh_derivative_tags_to_compute_for<Tag>::type;
275 : /// @}
276 :
277 : /// @{
278 : /*!
279 : * \brief A typelist for the set of tags computed by multiple spin-weighted
280 : * differentiation using utilities from the `Swsh` namespace.
281 : */
282 : template <typename Tag>
283 1 : struct second_swsh_derivative_tags_to_compute_for {
284 0 : using type =
285 : typename detail::TagsToComputeForImpl<Tag>::second_swsh_derivative_tags;
286 : };
287 :
288 : template <typename Tag>
289 0 : using second_swsh_derivative_tags_to_compute_for_t =
290 : typename second_swsh_derivative_tags_to_compute_for<Tag>::type;
291 : /// @}
292 :
293 : /// Typelist of steps for `SwshDerivatives` mutations called on volume
294 : /// quantities needed for scri+ computations
295 1 : using all_swsh_derivative_tags_for_scri = tmpl::list<
296 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiU>,
297 : Spectral::Swsh::Tags::Eth>,
298 : Spectral::Swsh::Tags::Derivative<
299 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
300 : Spectral::Swsh::Tags::EthEthbar>,
301 : Spectral::Swsh::Tags::Ethbar>,
302 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::Du<Tags::BondiJ>>,
303 : Spectral::Swsh::Tags::Ethbar>,
304 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::Dy<Tags::BondiU>>,
305 : Spectral::Swsh::Tags::Ethbar>,
306 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiQ>,
307 : Spectral::Swsh::Tags::Ethbar>,
308 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::Dy<Tags::BondiBeta>>,
309 : Spectral::Swsh::Tags::Eth>>;
310 :
311 : /// Typelist of steps for `PreSwshDerivatives` mutations called on boundary
312 : /// (angular grid only) quantities needed for scri+ computations
313 1 : using all_boundary_pre_swsh_derivative_tags_for_scri =
314 : tmpl::list<Tags::ComplexInertialRetardedTime>;
315 :
316 : /// Typelist of steps for `SwshDerivatives` mutations called on boundary
317 : /// (angular grid only) quantities needed for scri+ computations
318 1 : using all_boundary_swsh_derivative_tags_for_scri =
319 : tmpl::list<Spectral::Swsh::Tags::Derivative<
320 : Tags::ComplexInertialRetardedTime, Spectral::Swsh::Tags::EthEth>>;
321 :
322 : /*!
323 : * \brief A typelist for the set of tags computed by spin-weighted
324 : * differentiation using utilities from the `Swsh` namespace.
325 : *
326 : * \details This is provided for easy and maintainable construction of a
327 : * `Variables` or \ref DataBoxGroup with all of the quantities needed for a CCE
328 : * computation or component. The data structures represented by these tags
329 : * should each have size `number_of_radial_points *
330 : * Spectral::Swsh::number_of_swsh_collocation_points(l_max)`. All of these tags
331 : * (for a given integrated Bondi quantity) may be computed at once if using a
332 : * \ref DataBoxGroup using the template `mutate_all_swsh_derivatives_for_tag`.
333 : * Individual tag computation is not provided in a convenient interface, as
334 : * there is significant savings in aggregating spin-weighted differentiation
335 : * steps. The full set of integrated Bondi quantities is available from the
336 : * typelist `bondi_hypersurface_step_tags`.
337 : */
338 1 : using all_swsh_derivative_tags =
339 : tmpl::remove_duplicates<tmpl::flatten<tmpl::list<
340 : tmpl::transform<
341 : bondi_hypersurface_step_tags,
342 : tmpl::bind<tmpl::list,
343 : single_swsh_derivative_tags_to_compute_for<tmpl::_1>,
344 : second_swsh_derivative_tags_to_compute_for<tmpl::_1>>>,
345 : all_swsh_derivative_tags_for_scri>>>;
346 :
347 : /*!
348 : * \brief A typelist for the full set of coefficient buffers needed to process
349 : * all of the tags in `all_swsh_derivative_tags` using batch processing provided
350 : * in `mutate_all_swsh_derivatives_for_tag`.
351 : *
352 : * \details This is provided for easy and maintainable construction of a
353 : * `Variables` or \ref DataBoxGroup with all of the quantities needed for a CCE
354 : * computation or component. The data structures represented by these tags
355 : * should each have size `number_of_radial_points *
356 : * Spectral::Swsh::size_of_libsharp_coefficient_vector(l_max)`. Providing
357 : * buffers associated with these tags is necessary for the use of the aggregated
358 : * computation `mutate_all_swsh_derivatives_for_tag`.
359 : */
360 1 : using all_transform_buffer_tags =
361 : tmpl::remove_duplicates<tmpl::flatten<tmpl::transform<
362 : all_swsh_derivative_tags,
363 : tmpl::bind<Spectral::Swsh::coefficient_buffer_tags_for_derivative_tag,
364 : tmpl::_1>>>>;
365 :
366 : namespace detail {
367 : template <typename Tag>
368 : struct additional_pre_swsh_derivative_tags_for {
369 : using type = tmpl::conditional_t<std::is_same_v<Tag, Tags::BondiH>,
370 : tmpl::list<Tags::Dy<Tag>>,
371 : tmpl::list<Tag, Tags::Dy<Tag>>>;
372 : };
373 : } // namespace detail
374 :
375 : /// Typelist of steps for `PreSwshDerivatives` mutations needed for scri+
376 : /// computations
377 1 : using all_pre_swsh_derivative_tags_for_scri =
378 : tmpl::list<Tags::Du<Tags::BondiJ>, Tags::Dy<Tags::Du<Tags::BondiJ>>,
379 : Tags::Dy<Tags::Dy<Tags::Du<Tags::BondiJ>>>,
380 : Tags::Dy<Tags::Dy<Tags::BondiW>>,
381 : Tags::Dy<Tags::Dy<Tags::BondiQ>>,
382 : Tags::Dy<Tags::Dy<Tags::BondiU>>,
383 : Tags::Dy<Tags::Dy<Tags::Dy<Tags::BondiJ>>>,
384 : Tags::Dy<Tags::Dy<Tags::Dy<Tags::BondiU>>>,
385 : Tags::Dy<Tags::Dy<Tags::Dy<Tags::BondiBeta>>>,
386 : Tags::Dy<Spectral::Swsh::Tags::Derivative<
387 : Tags::BondiBeta, Spectral::Swsh::Tags::EthEthbar>>>;
388 :
389 : /*!
390 : * \brief A typelist for the full set of tags needed as direct or indirect
391 : * input to any `ComputeBondiIntegrand` that are computed any specialization of
392 : * `ComputePreSwshDerivatives`.
393 : *
394 : * \details This is provided for easy and maintainable construction of a
395 : * `Variables` or \ref DataBoxGroup with all of the quantities needed for a CCE
396 : * computation or component. The data structures represented by these tags
397 : * should each have size `number_of_radial_points *
398 : * Spectral::Swsh::number_of_swsh_collocation_points(l_max)`.
399 : */
400 1 : using all_pre_swsh_derivative_tags =
401 : tmpl::remove_duplicates<tmpl::flatten<tmpl::list<
402 : tmpl::transform<
403 : bondi_hypersurface_step_tags,
404 : tmpl::bind<
405 : tmpl::list, pre_swsh_derivative_tags_to_compute_for<tmpl::_1>,
406 : detail::additional_pre_swsh_derivative_tags_for<tmpl::_1>>>,
407 : all_pre_swsh_derivative_tags_for_scri>>>;
408 :
409 :
410 : } // namespace Cce
|