PreSwshDerivatives.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 
8 #include "DataStructures/ComplexDataVector.hpp"
10 #include "DataStructures/SpinWeighted.hpp"
13 #include "Domain/Mesh.hpp"
14 #include "Evolution/Systems/Cce/IntegrandInputSteps.hpp"
15 #include "Evolution/Systems/Cce/LinearOperators.hpp"
16 #include "Evolution/Systems/Cce/Tags.hpp"
18 #include "NumericalAlgorithms/Spectral/SwshCollocation.hpp"
19 #include "NumericalAlgorithms/Spectral/SwshDerivatives.hpp"
20 #include "NumericalAlgorithms/Spectral/SwshTags.hpp"
21 #include "Utilities/Gsl.hpp"
22 #include "Utilities/TMPL.hpp"
23 
24 namespace Cce {
25 
26 /*!
27  * \brief A set of procedures for computing the set of inputs to the CCE
28  * integrand computations that are to be performed prior to the spin-weighted
29  * spherical harmonic differentiation (and for the first step in the series of
30  * integrations, after the `PrecomputeCceDependencies`)
31  *
32  * \details For the storage model in which a set of `Variables` are stored in a
33  * `DataBox`, there are type aliases provided in each of the specializations:
34  * - output/input : `pre_swsh_derivatives` type alias. A \ref DataBoxGroup with
35  * tags `all_pre_swsh_derivative_tags` is compatible with all specializations.
36  * - input : `swsh_derivative_tags` type alias. A \ref DataBoxGroup with tags
37  * `all_swsh_derivative_tags` is compatible with all specializations.
38  * - input : `integrand_tags` type alias. A \ref DataBoxGroup with tags
39  * `Tags::BondiU` and `Tags::BondiBeta` is compatible with all specializations.
40  */
41 template <typename Tag>
43 
44 /*!
45  * \brief Compute \f$\bar{J}\f$.
46  *
47  * \note Computing \f$\bar{J}\f$ should be unnecessary in most execution
48  * procedures, as all quantities should be derived from \f$J\f$ and its
49  * derivatives followed by explicit conjugation operations, which are expected
50  * to be sufficiently cheap to avoid the storage cost of recording the
51  * conjugates. The exception is caching for certain spin-weighted derivatives of
52  * products
53  */
54 template <>
55 struct PreSwshDerivatives<Tags::BondiJbar> {
56  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiJ>;
57  using swsh_derivative_tags = tmpl::list<>;
58  using integrand_tags = tmpl::list<>;
59 
60  using return_tags = tmpl::list<Tags::BondiJbar>;
61  using argument_tags = pre_swsh_derivative_tags;
62  static void apply(
64  const Scalar<SpinWeighted<ComplexDataVector, 2>>& j) noexcept {
65  get(*jbar) = conj(get(j));
66  }
67 };
68 
69 /*!
70  * \brief Compute \f$\bar{U}\f$.
71  *
72  * \note Computing \f$\bar{U}\f$ should be unnecessary in most execution
73  * procedures, as all quantities should be derived from \f$U\f$ and its
74  * derivatives followed by explicit conjugation operations, which are expected
75  * to be sufficiently cheap to avoid the storage cost of recording the
76  * conjugates.
77  */
78 template <>
79 struct PreSwshDerivatives<Tags::BondiUbar> {
80  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiU>;
81  using swsh_derivative_tags = tmpl::list<>;
82  using integrand_tags = tmpl::list<>;
83 
84  using return_tags = tmpl::list<Tags::BondiUbar>;
85  using argument_tags = pre_swsh_derivative_tags;
86  static void apply(
88  const Scalar<SpinWeighted<ComplexDataVector, 1>>& u) noexcept {
89  get(*ubar) = conj(get(u));
90  }
91 };
92 
93 /*!
94  * Compute \f$\bar{Q}\f$.
95  *
96  * \note Computing \f$\bar{Q}\f$ should be unnecessary in most execution
97  * procedures, as all quantities should be derived from \f$Q\f$ and its
98  * derivatives followed by explicit conjugation operations, which are expected
99  * to be sufficiently cheap to avoid the storage cost of recording the
100  * conjugates
101  */
102 template <>
103 struct PreSwshDerivatives<Tags::BondiQbar> {
104  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiQ>;
105  using swsh_derivative_tags = tmpl::list<>;
106  using integrand_tags = tmpl::list<>;
107 
108  using return_tags = tmpl::list<Tags::BondiQbar>;
109  using argument_tags = pre_swsh_derivative_tags;
110  static void apply(
112  const Scalar<SpinWeighted<ComplexDataVector, 1>>& q) noexcept {
113  get(*qbar) = conj(get(q));
114  }
115 };
116 
117 /// Compute the product of `Lhs` and `Rhs`.
118 template <typename Lhs, typename Rhs>
120  using pre_swsh_derivative_tags = tmpl::list<Lhs, Rhs>;
121  using swsh_derivative_tags = tmpl::list<>;
122  using integrand_tags = tmpl::list<>;
123 
124  using return_tags = tmpl::list<::Tags::Multiplies<Lhs, Rhs>>;
125  using argument_tags = pre_swsh_derivative_tags;
126  static void apply(
129  result,
132  rhs) noexcept {
133  get(*result) = get(lhs) * get(rhs);
134  }
135 };
136 
137 /*!
138  * \brief Compute the product of \f$\bar{J}\f$ and the quantity represented by
139  * `Rhs`.
140  *
141  * \details In this function, \f$\bar{J}\f$ is obtained via conjugation of
142  * `Tags::BondiJ` inline, rather than accessing `Tags::BondiJbar` in storage.
143  */
144 template <typename Rhs>
145 struct PreSwshDerivatives<::Tags::Multiplies<Tags::BondiJbar, Rhs>> {
146  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiJ, Rhs>;
147  using swsh_derivative_tags = tmpl::list<>;
148  using integrand_tags = tmpl::list<>;
149 
150  using return_tags = tmpl::list<::Tags::Multiplies<Tags::BondiJbar, Rhs>>;
151  using argument_tags = pre_swsh_derivative_tags;
152  static void apply(
156  result,
159  rhs) noexcept {
160  get(*result) = conj(get(j)) * get(rhs);
161  }
162 };
163 
164 /*!
165  * \brief Compute the product of \f$\bar{J}\f$ and the quantity represented by
166  * `Rhs`.
167  *
168  * \details In this function, \f$\bar{J}\f$ is obtained via conjugation of
169  * `Tags::BondiJ` inline, rather than accessing `Tags::BondiJbar` in storage.
170  */
171 template <typename Lhs>
172 struct PreSwshDerivatives<::Tags::Multiplies<Lhs, Tags::BondiJbar>> {
173  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiJ, Lhs>;
174  using swsh_derivative_tags = tmpl::list<>;
175  using integrand_tags = tmpl::list<>;
176 
177  using return_tags = tmpl::list<::Tags::Multiplies<Lhs, Tags::BondiJbar>>;
178  using argument_tags = pre_swsh_derivative_tags;
179  static void apply(
183  result,
186  lhs) noexcept {
187  get(*result) = get(lhs) * conj(get(j));
188  }
189 };
190 
191 /*!
192  * \brief Compute the product of \f$\bar{U}\f$ and the quantity represented by
193  * `Rhs`.
194  *
195  * \details In this function, \f$\bar{U}\f$ is obtained via conjugation of
196  * `Tags::BondiU` inline, rather than accessing `Tags::BondiUbar` in storage.
197  */
198 template <typename Rhs>
199 struct PreSwshDerivatives<::Tags::Multiplies<Tags::BondiUbar, Rhs>> {
200  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiU, Rhs>;
201  using swsh_derivative_tags = tmpl::list<>;
202  using integrand_tags = tmpl::list<>;
203 
204  using return_tags = tmpl::list<::Tags::Multiplies<Tags::BondiUbar, Rhs>>;
205  using argument_tags = pre_swsh_derivative_tags;
206  static void apply(
210  result,
213  rhs) noexcept {
214  get(*result) = conj(get(u)) * get(rhs);
215  }
216 };
217 
218 /*!
219  * \brief Compute \f$\bar{J} * (Q - 2 \eth \beta)\f$.
220  *
221  * \note the conjugates for this are accessed by their non-conjugate
222  * counterparts (`Tags::BondiJ` and `Tags::BondiQ`) then conjugated inline
223  */
224 template <>
225 struct PreSwshDerivatives<Tags::JbarQMinus2EthBeta> {
226  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiJ, Tags::BondiQ>;
227  using swsh_derivative_tags =
230  using integrand_tags = tmpl::list<>;
231 
232  using return_tags = tmpl::list<Tags::JbarQMinus2EthBeta>;
233  using argument_tags =
234  tmpl::append<pre_swsh_derivative_tags, swsh_derivative_tags>;
235  static void apply(
237  jbar_q_minus_2_eth_beta,
240  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_beta) noexcept {
241  get(*jbar_q_minus_2_eth_beta) =
242  conj(get(j)) * (get(q) - 2.0 * get(eth_beta));
243  }
244 };
245 
246 /// Compute \f$\exp(2 \beta)\f$
247 template <>
248 struct PreSwshDerivatives<Tags::Exp2Beta> {
249  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiBeta>;
250  using swsh_derivative_tags = tmpl::list<>;
251  using integrand_tags = tmpl::list<>;
252 
253  using return_tags = tmpl::list<Tags::Exp2Beta>;
254  using argument_tags = tmpl::append<tmpl::list<pre_swsh_derivative_tags>>;
255  static void apply(
257  exp_2_beta,
258  const Scalar<SpinWeighted<ComplexDataVector, 0>>& beta) noexcept {
259  get(*exp_2_beta).data() = exp(2.0 * get(beta).data());
260  }
261 };
262 
263 /// Compute the derivative of the quantity represented by `Tag` with respect to
264 /// the numerical radial coordinate \f$y\f$.
265 template <typename Tag>
266 struct PreSwshDerivatives<Tags::Dy<Tag>> {
267  using pre_swsh_derivative_tags = tmpl::list<Tag>;
268  using swsh_derivative_tags = tmpl::list<>;
269  using integrand_tags = tmpl::list<>;
270 
271  using return_tags = tmpl::list<Tags::Dy<Tag>>;
272  using argument_tags = tmpl::append<pre_swsh_derivative_tags,
273  tmpl::list<Spectral::Swsh::Tags::LMax>>;
274 
275  static void apply(
276  const gsl::not_null<
278  dy_val,
280  const size_t l_max) noexcept {
281  logical_partial_directional_derivative_of_complex(
282  make_not_null(&get(*dy_val).data()), get(val).data(),
283  Mesh<3>{
286  get(val).size() /
288  Spectral::Basis::Legendre,
289  Spectral::Quadrature::GaussLobatto},
290  // 2 for differentiating in y; coordinate ordering is:
291  // {\phi, \theta, y}.
292  2);
293  }
294 };
295 
296 /*!
297  * \brief Computes the first derivative with respect to \f$y\f$ of
298  * `Tags::BondiBeta`.
299  *
300  * \details In a CCE evolution, the values of the first derivatives of
301  * `Tags::BondiBeta` can just be copied from its integrand.
302  */
303 template <>
304 struct PreSwshDerivatives<Tags::Dy<Tags::BondiBeta>> {
305  using pre_swsh_derivative_tags = tmpl::list<>;
306  using swsh_derivative_tags = tmpl::list<>;
307  using integrand_tags = tmpl::list<Tags::Integrand<Tags::BondiBeta>>;
308 
309  using return_tags = tmpl::list<Tags::Dy<Tags::BondiBeta>>;
310  using argument_tags = integrand_tags;
311  static void apply(
314  integrand_beta) noexcept {
315  *dy_beta = integrand_beta;
316  }
317 };
318 
319 /*!
320  * \brief Computes the first derivative with respect to \f$y\f$ of
321  * `Tags::BondiU`.
322  *
323  * \details In a CCE evolution, the values of the first derivatives of
324  * `Tags::BondiU` can just be copied from its integrand.
325  */
326 template <>
327 struct PreSwshDerivatives<Tags::Dy<Tags::BondiU>> {
328  using pre_swsh_derivative_tags = tmpl::list<>;
329  using swsh_derivative_tags = tmpl::list<>;
330  using integrand_tags = tmpl::list<Tags::Integrand<Tags::BondiU>>;
331 
332  using return_tags = tmpl::list<Tags::Dy<Tags::BondiU>>;
333  using argument_tags = integrand_tags;
334  static void apply(
336  const Scalar<SpinWeighted<ComplexDataVector, 1>>& integrand_u) noexcept {
337  *dy_u = integrand_u;
338  }
339 };
340 
341 /*!
342  * \brief Compute the derivative with respect to the numerical radial coordinate
343  * \f$y\f$ of a quantity which is a spin-weighted spherical harmonic
344  * derivative.
345  *
346  * \details This is separate from the generic case of a derivative with
347  * respect to \f$y\f$ because the included type aliases arrange the input tags
348  * in different categories.
349  */
350 template <typename Tag, typename DerivKind>
352  Tags::Dy<Spectral::Swsh::Tags::Derivative<Tag, DerivKind>>> {
353  using pre_swsh_derivative_tags = tmpl::list<>;
354  using swsh_derivative_tags =
355  tmpl::list<Spectral::Swsh::Tags::Derivative<Tag, DerivKind>>;
356  using integrand_tags = tmpl::list<>;
357 
358  using return_tags =
359  tmpl::list<Tags::Dy<Spectral::Swsh::Tags::Derivative<Tag, DerivKind>>>;
360  using argument_tags = tmpl::append<swsh_derivative_tags,
361  tmpl::list<Spectral::Swsh::Tags::LMax>>;
362 
363  static constexpr int spin =
365  static void apply(
367  dy_val,
369  const size_t l_max) noexcept {
370  logical_partial_directional_derivative_of_complex(
371  make_not_null(&get(*dy_val).data()), get(val).data(),
372  Mesh<3>{
375  get(val).size() /
377  Spectral::Basis::Legendre,
378  Spectral::Quadrature::GaussLobatto},
379  // 2 for differentiating in y; coordinate ordering is:
380  // {\phi, \theta, y}.
381  2);
382  }
383 };
384 
385 /*!
386  * \brief Evaluates the set of inputs to the CCE integrand for
387  * `BondiValueTag` that do not involve spin-weighted angular differentiation.
388  *
389  * \details This function is to be called on the `DataBox` holding the relevant
390  * CCE data on each hypersurface integration step, prior to evaluating the
391  * spin-weighted derivatives needed for the same CCE integrand. Provided a
392  * `DataBox` with the appropriate tags (including
393  * `all_pre_swsh_derivative_tags`, `all_swsh_derivative_tags` and
394  * `Spectral::Swsh::Tags::LMax`), this function will apply all of the necessary
395  * mutations to update `all_pre_swsh_derivatives_for_tag<BondiValueTag>` to
396  * their correct values for the current values for the remaining (input) tags.
397  */
398 template <typename BondiValueTag, typename DataBoxType>
400  const gsl::not_null<DataBoxType*> box) noexcept {
401  tmpl::for_each<
402  pre_swsh_derivative_tags_to_compute_for_t<BondiValueTag>>([&box](
403  auto pre_swsh_derivative_tag_v) noexcept {
404  using pre_swsh_derivative_tag =
405  typename decltype(pre_swsh_derivative_tag_v)::type;
407  db::mutate_apply<mutation>(box);
408  });
409 }
410 } // namespace Cce
A prefix tag representing the product of two other tags. Note that if non-spin-weighted types are nee...
Definition: Tags.hpp:85
Contains functionality for Cauchy Characteristic Extraction.
Definition: BoundaryData.cpp:21
Bondi parameter .
Definition: Tags.hpp:20
constexpr size_t number_of_swsh_collocation_points(const size_t l_max) noexcept
Convenience function for determining the number of spin-weighted spherical harmonic collocation value...
Definition: SwshCollocation.hpp:25
A set of procedures for computing the set of inputs to the CCE integrand computations that are to be ...
Definition: PreSwshDerivatives.hpp:42
Holds the number of grid points, basis, and quadrature in each direction of the computational grid...
Definition: Mesh.hpp:49
Prefix tag representing the spin-weighted derivative of a spin-weighted scalar.
Definition: SwshTags.hpp:139
constexpr size_t number_of_swsh_phi_collocation_points(const size_t l_max) noexcept
Returns the number of spin-weighted spherical harmonic collocation values in for a libsharp-compatib...
Definition: SwshCollocation.hpp:51
Make a spin-weighted type T with spin-weight Spin. Mathematical operators are restricted to addition...
Definition: SpinWeighted.hpp:25
Defines classes and functions used for manipulating DataBox&#39;s.
constexpr size_t number_of_swsh_theta_collocation_points(const size_t l_max) noexcept
Returns the number of spin-weighted spherical harmonic collocation values in for a libsharp-compatib...
Definition: SwshCollocation.hpp:38
Stores a collection of complex function values.
Definition: ComplexDataVector.hpp:47
Definition: DataBoxTag.hpp:29
Defines the class template Mesh.
Defines classes for Tensor.
Defines a list of useful type aliases for tensors.
constexpr auto apply(F &&f, const DataBox< BoxTags > &box, Args &&... args) noexcept
Apply the invokable f with argument Tags TagsList from DataBox box
Definition: DataBox.hpp:1628
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:29
Wraps the template metaprogramming library used (brigand)
Defines functions and classes from the GSL.
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion, but it may be necessary to perform the conversion explicitly when type deduction is desired.
Definition: Gsl.hpp:879
void mutate_all_pre_swsh_derivatives_for_tag(const gsl::not_null< DataBoxType *> box) noexcept
Evaluates the set of inputs to the CCE integrand for BondiValueTag that do not involve spin-weighted ...
Definition: PreSwshDerivatives.hpp:399
Tensor< T, Symmetry<>, index_list<> > Scalar
Scalar type.
Definition: TypeAliases.hpp:21
Require a pointer to not be a nullptr
Definition: Gsl.hpp:182