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 "Evolution/Systems/Cce/IntegrandInputSteps.hpp"
14 #include "Evolution/Systems/Cce/LinearOperators.hpp"
15 #include "Evolution/Systems/Cce/OptionTags.hpp"
16 #include "Evolution/Systems/Cce/Tags.hpp"
19 #include "NumericalAlgorithms/Spectral/SwshCollocation.hpp"
20 #include "NumericalAlgorithms/Spectral/SwshDerivatives.hpp"
21 #include "NumericalAlgorithms/Spectral/SwshTags.hpp"
22 #include "Utilities/Gsl.hpp"
23 #include "Utilities/TMPL.hpp"
24 
25 namespace Cce {
26 
27 /*!
28  * \brief A set of procedures for computing the set of inputs to the CCE
29  * integrand computations that are to be performed prior to the spin-weighted
30  * spherical harmonic differentiation (and for the first step in the series of
31  * integrations, after the `PrecomputeCceDependencies`)
32  *
33  * \details For the storage model in which a set of `Variables` are stored in a
34  * `DataBox`, there are type aliases provided in each of the specializations:
35  * - output/input : `pre_swsh_derivatives` type alias. A \ref DataBoxGroup with
36  * tags `all_pre_swsh_derivative_tags` is compatible with all specializations.
37  * - input : `swsh_derivative_tags` type alias. A \ref DataBoxGroup with tags
38  * `all_swsh_derivative_tags` is compatible with all specializations.
39  * - input : `integrand_tags` type alias. A \ref DataBoxGroup with tags
40  * `Tags::BondiU` and `Tags::BondiBeta` is compatible with all specializations.
41  */
42 template <typename Tag>
44 
45 /*!
46  * \brief Compute \f$\bar{J}\f$.
47  *
48  * \note Computing \f$\bar{J}\f$ should be unnecessary in most execution
49  * procedures, as all quantities should be derived from \f$J\f$ and its
50  * derivatives followed by explicit conjugation operations, which are expected
51  * to be sufficiently cheap to avoid the storage cost of recording the
52  * conjugates. The exception is caching for certain spin-weighted derivatives of
53  * products
54  */
55 template <>
56 struct PreSwshDerivatives<Tags::BondiJbar> {
57  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiJ>;
58  using swsh_derivative_tags = tmpl::list<>;
59  using integrand_tags = tmpl::list<>;
60 
61  using return_tags = tmpl::list<Tags::BondiJbar>;
62  using argument_tags = pre_swsh_derivative_tags;
63  static void apply(
65  const Scalar<SpinWeighted<ComplexDataVector, 2>>& j) noexcept {
66  get(*jbar) = conj(get(j));
67  }
68 };
69 
70 /*!
71  * \brief Compute \f$\bar{U}\f$.
72  *
73  * \note Computing \f$\bar{U}\f$ should be unnecessary in most execution
74  * procedures, as all quantities should be derived from \f$U\f$ and its
75  * derivatives followed by explicit conjugation operations, which are expected
76  * to be sufficiently cheap to avoid the storage cost of recording the
77  * conjugates.
78  */
79 template <>
80 struct PreSwshDerivatives<Tags::BondiUbar> {
81  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiU>;
82  using swsh_derivative_tags = tmpl::list<>;
83  using integrand_tags = tmpl::list<>;
84 
85  using return_tags = tmpl::list<Tags::BondiUbar>;
86  using argument_tags = pre_swsh_derivative_tags;
87  static void apply(
89  const Scalar<SpinWeighted<ComplexDataVector, 1>>& u) noexcept {
90  get(*ubar) = conj(get(u));
91  }
92 };
93 
94 /*!
95  * Compute \f$\bar{Q}\f$.
96  *
97  * \note Computing \f$\bar{Q}\f$ should be unnecessary in most execution
98  * procedures, as all quantities should be derived from \f$Q\f$ and its
99  * derivatives followed by explicit conjugation operations, which are expected
100  * to be sufficiently cheap to avoid the storage cost of recording the
101  * conjugates
102  */
103 template <>
104 struct PreSwshDerivatives<Tags::BondiQbar> {
105  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiQ>;
106  using swsh_derivative_tags = tmpl::list<>;
107  using integrand_tags = tmpl::list<>;
108 
109  using return_tags = tmpl::list<Tags::BondiQbar>;
110  using argument_tags = pre_swsh_derivative_tags;
111  static void apply(
113  const Scalar<SpinWeighted<ComplexDataVector, 1>>& q) noexcept {
114  get(*qbar) = conj(get(q));
115  }
116 };
117 
118 /// Compute the product of `Lhs` and `Rhs`.
119 template <typename Lhs, typename Rhs>
121  using pre_swsh_derivative_tags = tmpl::list<Lhs, Rhs>;
122  using swsh_derivative_tags = tmpl::list<>;
123  using integrand_tags = tmpl::list<>;
124 
125  using return_tags = tmpl::list<::Tags::Multiplies<Lhs, Rhs>>;
126  using argument_tags = pre_swsh_derivative_tags;
127  static void apply(
130  result,
133  rhs) noexcept {
134  get(*result) = get(lhs) * get(rhs);
135  }
136 };
137 
138 /*!
139  * \brief Compute the product of \f$\bar{J}\f$ and the quantity represented by
140  * `Rhs`.
141  *
142  * \details In this function, \f$\bar{J}\f$ is obtained via conjugation of
143  * `Tags::BondiJ` inline, rather than accessing `Tags::BondiJbar` in storage.
144  */
145 template <typename Rhs>
146 struct PreSwshDerivatives<::Tags::Multiplies<Tags::BondiJbar, Rhs>> {
147  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiJ, Rhs>;
148  using swsh_derivative_tags = tmpl::list<>;
149  using integrand_tags = tmpl::list<>;
150 
151  using return_tags = tmpl::list<::Tags::Multiplies<Tags::BondiJbar, Rhs>>;
152  using argument_tags = pre_swsh_derivative_tags;
153  static void apply(
157  result,
160  rhs) noexcept {
161  get(*result) = conj(get(j)) * get(rhs);
162  }
163 };
164 
165 /*!
166  * \brief Compute the product of \f$\bar{J}\f$ and the quantity represented by
167  * `Rhs`.
168  *
169  * \details In this function, \f$\bar{J}\f$ is obtained via conjugation of
170  * `Tags::BondiJ` inline, rather than accessing `Tags::BondiJbar` in storage.
171  */
172 template <typename Lhs>
173 struct PreSwshDerivatives<::Tags::Multiplies<Lhs, Tags::BondiJbar>> {
174  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiJ, Lhs>;
175  using swsh_derivative_tags = tmpl::list<>;
176  using integrand_tags = tmpl::list<>;
177 
178  using return_tags = tmpl::list<::Tags::Multiplies<Lhs, Tags::BondiJbar>>;
179  using argument_tags = pre_swsh_derivative_tags;
180  static void apply(
184  result,
187  lhs) noexcept {
188  get(*result) = get(lhs) * conj(get(j));
189  }
190 };
191 
192 /*!
193  * \brief Compute the product of \f$\bar{U}\f$ and the quantity represented by
194  * `Rhs`.
195  *
196  * \details In this function, \f$\bar{U}\f$ is obtained via conjugation of
197  * `Tags::BondiU` inline, rather than accessing `Tags::BondiUbar` in storage.
198  */
199 template <typename Rhs>
200 struct PreSwshDerivatives<::Tags::Multiplies<Tags::BondiUbar, Rhs>> {
201  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiU, Rhs>;
202  using swsh_derivative_tags = tmpl::list<>;
203  using integrand_tags = tmpl::list<>;
204 
205  using return_tags = tmpl::list<::Tags::Multiplies<Tags::BondiUbar, Rhs>>;
206  using argument_tags = pre_swsh_derivative_tags;
207  static void apply(
211  result,
214  rhs) noexcept {
215  get(*result) = conj(get(u)) * get(rhs);
216  }
217 };
218 
219 /*!
220  * \brief Compute \f$\bar{J} * (Q - 2 \eth \beta)\f$.
221  *
222  * \note the conjugates for this are accessed by their non-conjugate
223  * counterparts (`Tags::BondiJ` and `Tags::BondiQ`) then conjugated inline
224  */
225 template <>
226 struct PreSwshDerivatives<Tags::JbarQMinus2EthBeta> {
227  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiJ, Tags::BondiQ>;
228  using swsh_derivative_tags =
231  using integrand_tags = tmpl::list<>;
232 
233  using return_tags = tmpl::list<Tags::JbarQMinus2EthBeta>;
234  using argument_tags =
235  tmpl::append<pre_swsh_derivative_tags, swsh_derivative_tags>;
236  static void apply(
238  jbar_q_minus_2_eth_beta,
241  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_beta) noexcept {
242  get(*jbar_q_minus_2_eth_beta) =
243  conj(get(j)) * (get(q) - 2.0 * get(eth_beta));
244  }
245 };
246 
247 /// Compute \f$\exp(2 \beta)\f$
248 template <>
249 struct PreSwshDerivatives<Tags::Exp2Beta> {
250  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiBeta>;
251  using swsh_derivative_tags = tmpl::list<>;
252  using integrand_tags = tmpl::list<>;
253 
254  using return_tags = tmpl::list<Tags::Exp2Beta>;
255  using argument_tags = pre_swsh_derivative_tags;
256  static void apply(
258  exp_2_beta,
259  const Scalar<SpinWeighted<ComplexDataVector, 0>>& beta) noexcept {
260  get(*exp_2_beta).data() = exp(2.0 * get(beta).data());
261  }
262 };
263 
264 /// Copies the values of the inertial retarded time into a spin-weighted
265 /// container so that spin-weighted derivatives can be taken
266 template <>
267 struct PreSwshDerivatives<Tags::ComplexInertialRetardedTime> {
268  using pre_swsh_derivative_tags = tmpl::list<>;
269  using swsh_derivative_tags = tmpl::list<>;
270  using integrand_tags = tmpl::list<>;
271 
272  using return_tags = tmpl::list<Tags::ComplexInertialRetardedTime>;
273  using argument_tags = tmpl::list<Tags::InertialRetardedTime>;
274  static void apply(
276  complex_inertial_retarded_time,
277  const Scalar<DataVector>& inertial_retarded_time) noexcept {
278  get(*complex_inertial_retarded_time).data() =
279  std::complex<double>(1.0, 0.0) * get(inertial_retarded_time);
280  }
281 };
282 
283 /// Compute the derivative of the quantity represented by `Tag` with respect to
284 /// the numerical radial coordinate \f$y\f$.
285 template <typename Tag>
286 struct PreSwshDerivatives<Tags::Dy<Tag>> {
287  using pre_swsh_derivative_tags = tmpl::list<Tag>;
288  using swsh_derivative_tags = tmpl::list<>;
289  using integrand_tags = tmpl::list<>;
290 
291  using return_tags = tmpl::list<Tags::Dy<Tag>>;
292  using argument_tags =
293  tmpl::append<pre_swsh_derivative_tags, tmpl::list<Tags::LMax>>;
294 
295  static void apply(
296  const gsl::not_null<
298  dy_val,
300  const size_t l_max) noexcept {
301  logical_partial_directional_derivative_of_complex(
302  make_not_null(&get(*dy_val).data()), get(val).data(),
303  Mesh<3>{
306  get(val).size() /
308  Spectral::Basis::Legendre,
309  Spectral::Quadrature::GaussLobatto},
310  // 2 for differentiating in y; coordinate ordering is:
311  // {\phi, \theta, y}.
312  2);
313  }
314 };
315 
316 /*!
317  * \brief Computes the first derivative with respect to \f$y\f$ of
318  * `Tags::BondiBeta`.
319  *
320  * \details In a CCE evolution, the values of the first derivatives of
321  * `Tags::BondiBeta` can just be copied from its integrand.
322  */
323 template <>
324 struct PreSwshDerivatives<Tags::Dy<Tags::BondiBeta>> {
325  using pre_swsh_derivative_tags = tmpl::list<>;
326  using swsh_derivative_tags = tmpl::list<>;
327  using integrand_tags = tmpl::list<Tags::Integrand<Tags::BondiBeta>>;
328 
329  using return_tags = tmpl::list<Tags::Dy<Tags::BondiBeta>>;
330  using argument_tags = integrand_tags;
331  static void apply(
334  integrand_beta) noexcept {
335  *dy_beta = integrand_beta;
336  }
337 };
338 
339 /*!
340  * \brief Computes the first derivative with respect to \f$y\f$ of
341  * `Tags::BondiU`.
342  *
343  * \details In a CCE evolution, the values of the first derivatives of
344  * `Tags::BondiU` can just be copied from its integrand.
345  */
346 template <>
347 struct PreSwshDerivatives<Tags::Dy<Tags::BondiU>> {
348  using pre_swsh_derivative_tags = tmpl::list<>;
349  using swsh_derivative_tags = tmpl::list<>;
350  using integrand_tags = tmpl::list<Tags::Integrand<Tags::BondiU>>;
351 
352  using return_tags = tmpl::list<Tags::Dy<Tags::BondiU>>;
353  using argument_tags = integrand_tags;
354  static void apply(
356  const Scalar<SpinWeighted<ComplexDataVector, 1>>& integrand_u) noexcept {
357  *dy_u = integrand_u;
358  }
359 };
360 
361 /// \brief Compute \f$\partial_u J\f$ from \f$H\f$ and the Jacobian factors.
362 template <>
363 struct PreSwshDerivatives<Tags::Du<Tags::BondiJ>> {
364  using pre_swsh_derivative_tags = tmpl::list<Tags::Dy<Tags::BondiJ>>;
365  using swsh_derivative_tags = tmpl::list<>;
366  using integrand_tags = tmpl::list<Tags::BondiH>;
367  using integration_independent_tags =
368  tmpl::list<Tags::DuRDividedByR, Tags::OneMinusY>;
369 
370  using return_tags = tmpl::list<Tags::Du<Tags::BondiJ>>;
371  using argument_tags = tmpl::append<pre_swsh_derivative_tags, integrand_tags,
372  integration_independent_tags>;
373  static void apply(
375  const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_bondi_j,
377  const Scalar<SpinWeighted<ComplexDataVector, 0>>& du_r_divided_by_r,
378  const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y) noexcept {
379  get(*du_j) = get(bondi_h) -
380  get(du_r_divided_by_r) * get(one_minus_y) * get(dy_bondi_j);
381  }
382 };
383 
384 /*!
385  * \brief Compute the derivative with respect to the numerical radial coordinate
386  * \f$y\f$ of a quantity which is a spin-weighted spherical harmonic
387  * derivative.
388  *
389  * \details This is separate from the generic case of a derivative with
390  * respect to \f$y\f$ because the included type aliases arrange the input tags
391  * in different categories.
392  */
393 template <typename Tag, typename DerivKind>
395  Tags::Dy<Spectral::Swsh::Tags::Derivative<Tag, DerivKind>>> {
396  using pre_swsh_derivative_tags = tmpl::list<>;
397  using swsh_derivative_tags =
398  tmpl::list<Spectral::Swsh::Tags::Derivative<Tag, DerivKind>>;
399  using integrand_tags = tmpl::list<>;
400 
401  using return_tags =
402  tmpl::list<Tags::Dy<Spectral::Swsh::Tags::Derivative<Tag, DerivKind>>>;
403  using argument_tags =
404  tmpl::append<swsh_derivative_tags, tmpl::list<Tags::LMax>>;
405 
406  static constexpr int spin =
408  static void apply(
410  dy_val,
412  const size_t l_max) noexcept {
413  logical_partial_directional_derivative_of_complex(
414  make_not_null(&get(*dy_val).data()), get(val).data(),
415  Mesh<3>{
418  get(val).size() /
420  Spectral::Basis::Legendre,
421  Spectral::Quadrature::GaussLobatto},
422  // 2 for differentiating in y; coordinate ordering is:
423  // {\phi, \theta, y}.
424  2);
425  }
426 };
427 
428 /*!
429  * \brief Evaluates the set of inputs to the CCE integrand for
430  * `BondiValueTag` that do not involve spin-weighted angular differentiation.
431  *
432  * \details This function is to be called on the `DataBox` holding the relevant
433  * CCE data on each hypersurface integration step, prior to evaluating the
434  * spin-weighted derivatives needed for the same CCE integrand. Provided a
435  * `DataBox` with the appropriate tags (including
436  * `all_pre_swsh_derivative_tags`, `all_swsh_derivative_tags` and
437  * `Tags::LMax`), this function will apply all of the necessary
438  * mutations to update `all_pre_swsh_derivatives_for_tag<BondiValueTag>` to
439  * their correct values for the current values for the remaining (input) tags.
440  */
441 template <typename BondiValueTag, typename DataBoxType>
443  const gsl::not_null<DataBoxType*> box) noexcept {
444  tmpl::for_each<
445  pre_swsh_derivative_tags_to_compute_for_t<BondiValueTag>>([&box](
446  auto pre_swsh_derivative_tag_v) noexcept {
447  using pre_swsh_derivative_tag =
448  typename decltype(pre_swsh_derivative_tag_v)::type;
450  db::mutate_apply<mutation>(box);
451  });
452 }
453 } // namespace Cce
Spectral::Swsh::number_of_swsh_phi_collocation_points
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
get
constexpr Tag::type & get(Variables< TagList > &v) noexcept
Return Tag::type pointing into the contiguous array.
Definition: Variables.hpp:689
Spectral::Swsh::Tags::Eth
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:30
Cce::Tags::BondiBeta
Bondi parameter .
Definition: Tags.hpp:30
Cce::PreSwshDerivatives
A set of procedures for computing the set of inputs to the CCE integrand computations that are to be ...
Definition: PreSwshDerivatives.hpp:43
Spectral::Swsh::Tags::Derivative
Prefix tag representing the spin-weighted derivative of a spin-weighted scalar.
Definition: SwshTags.hpp:152
Spectral.hpp
SpinWeighted
Make a spin-weighted type T with spin-weight Spin. Mathematical operators are restricted to addition,...
Definition: SpinWeighted.hpp:24
Cce::mutate_all_pre_swsh_derivatives_for_tag
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:442
db::apply
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:1443
DataBox.hpp
cstddef
Spectral::Swsh::number_of_swsh_theta_collocation_points
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
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:50
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
Cce
The set of utilities for performing Cauchy characteristic evolution and Cauchy characteristic matchin...
Definition: BoundaryComputeAndSendToEvolution.hpp:28
Gsl.hpp
TypeAliases.hpp
Tensor.hpp
std::complex< double >
make_not_null
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,...
Definition: Gsl.hpp:880
Mesh.hpp
ComplexDataVector
Stores a collection of complex function values.
Definition: ComplexDataVector.hpp:47
TMPL.hpp
Tags::Multiplies
A prefix tag representing the product of two other tags. Note that if non-spin-weighted types are nee...
Definition: Tags.hpp:86
gsl::not_null
Require a pointer to not be a nullptr
Definition: Gsl.hpp:183
Spectral::Swsh::number_of_swsh_collocation_points
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