PrecomputeCceDependencies.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"
9 #include "DataStructures/SpinWeighted.hpp"
10 #include "Evolution/Systems/Cce/IntegrandInputSteps.hpp"
11 #include "Evolution/Systems/Cce/Tags.hpp"
13 #include "NumericalAlgorithms/Spectral/SwshCollocation.hpp"
14 #include "NumericalAlgorithms/Spectral/SwshTags.hpp"
15 #include "Utilities/Gsl.hpp"
16 #include "Utilities/TMPL.hpp"
17 #include "Utilities/VectorAlgebra.hpp"
18 
19 namespace Cce {
20 
21 namespace detail {
22 // A convenience function for computing the spin-weighted derivatives of \f$R\f$
23 // divided by \f$R\f$, which appears often in Jacobians to transform between
24 // Bondi coordinates and the numerical coordinates used in CCE.
25 template <typename DerivKind>
26 void angular_derivative_of_r_divided_by_r_impl(
29  Spectral::Swsh::Tags::derivative_spin_weight<DerivKind>>*>
30  d_r_divided_by_r,
31  const SpinWeighted<ComplexDataVector, 0>& boundary_r, size_t l_max,
32  size_t number_of_radial_points) noexcept;
33 
34 } // namespace detail
35 
36 /*!
37  * \brief A set of procedures for computing the set of inputs to the CCE
38  * integrand computations that can be computed before any of the intermediate
39  * integrands are evaluated.
40  *
41  * \details The template specializations of this template are
42  * compatible with acting as a the mutator in a \ref DataBoxGroup
43  * `db::mutate_apply` operation. For flexibility in defining the \ref
44  * DataBoxGroup structure, the tags for `Tensor`s used in these functions are
45  * also organized into type lists:
46  * - type alias `integration_independent_tags`: with a subset of
47  * `Cce::pre_computation_tags`, used for both input and output.
48  * - type alias `boundary_values`: with a subset of
49  * `Cce::pre_computation_boundary_tags`, used only for input.
50  * - type alias `pre_swsh_derivatives` containing hypersurface quantities. For
51  * this struct, it will only ever contain `Cce::Tags::BondiJ`, and is used as
52  * input.
53  *
54  * The `BoundaryPrefix` tag allows easy switching between the
55  * regularity-preserving version and standard CCE
56  *
57  */
58 template <template <typename> class BoundaryPrefix, typename Tag>
60 
61 /// Computes \f$1 - y\f$ for the CCE system.
62 template <template <typename> class BoundaryPrefix>
63 struct PrecomputeCceDependencies<BoundaryPrefix, Tags::OneMinusY> {
64  using boundary_tags = tmpl::list<>;
65  using pre_swsh_derivative_tags = tmpl::list<>;
66  using integration_independent_tags = tmpl::list<>;
67 
68  using return_tags = tmpl::list<Tags::OneMinusY>;
69  using argument_tags = tmpl::list<Spectral::Swsh::Tags::LMax,
71 
72  static void apply(
74  one_minus_y,
75  const size_t l_max, const size_t number_of_radial_points) noexcept {
76  const size_t number_of_angular_points =
78  const DataVector one_minus_y_collocation =
79  1.0 - Spectral::collocation_points<Spectral::Basis::Legendre,
80  Spectral::Quadrature::GaussLobatto>(
81  number_of_radial_points);
82  // iterate through the angular 'chunks' and set them to their 1-y value
83  for (size_t i = 0; i < number_of_radial_points; ++i) {
84  ComplexDataVector angular_view{
85  get(*one_minus_y).data().data() + number_of_angular_points * i,
86  number_of_angular_points};
87  angular_view = one_minus_y_collocation[i];
88  }
89  }
90 };
91 
92 /// Computes a volume version of Bondi radius of the worldtube \f$R\f$ from its
93 /// boundary value (by repeating it over the radial dimension)
94 template <template <typename> class BoundaryPrefix>
95 struct PrecomputeCceDependencies<BoundaryPrefix, Tags::BondiR> {
96  using boundary_tags = tmpl::list<BoundaryPrefix<Tags::BondiR>>;
97  using pre_swsh_derivative_tags = tmpl::list<>;
98  using integration_independent_tags = tmpl::list<>;
99 
100  using return_tags = tmpl::list<Tags::BondiR>;
101  using argument_tags =
102  tmpl::append<boundary_tags,
103  tmpl::list<Spectral::Swsh::Tags::NumberOfRadialPoints>>;
104 
105  static void apply(
107  const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
108  const size_t number_of_radial_points) noexcept {
109  fill_with_n_copies(make_not_null(&get(*r).data()), get(boundary_r).data(),
110  number_of_radial_points);
111  }
112 };
113 
114 /// Computes \f$\partial_u R / R\f$ from its boundary value (by repeating it
115 /// over the radial dimension).
116 template <template <typename> class BoundaryPrefix>
117 struct PrecomputeCceDependencies<BoundaryPrefix, Tags::DuRDividedByR> {
118  using boundary_tags = tmpl::list<BoundaryPrefix<Tags::DuRDividedByR>>;
119  using pre_swsh_derivative_tags = tmpl::list<>;
120  using integration_independent_tags = tmpl::list<>;
121 
122  using return_tags = tmpl::list<Tags::DuRDividedByR>;
123  using argument_tags =
124  tmpl::append<boundary_tags,
125  tmpl::list<Spectral::Swsh::Tags::NumberOfRadialPoints>>;
126 
127  static void apply(
129  du_r_divided_by_r,
131  boundary_du_r_divided_by_r,
132  const size_t number_of_radial_points) noexcept {
133  fill_with_n_copies(make_not_null(&get(*du_r_divided_by_r).data()),
134  get(boundary_du_r_divided_by_r).data(),
135  number_of_radial_points);
136  }
137 };
138 
139 /// Computes \f$\eth R / R\f$ by differentiating and repeating the boundary
140 /// value of \f$R\f$.
141 template <template <typename> class BoundaryPrefix>
142 struct PrecomputeCceDependencies<BoundaryPrefix, Tags::EthRDividedByR> {
143  using boundary_tags = tmpl::list<BoundaryPrefix<Tags::BondiR>>;
144  using pre_swsh_derivative_tags = tmpl::list<>;
145  using integration_independent_tags = tmpl::list<>;
146 
147  using return_tags = tmpl::list<Tags::EthRDividedByR>;
148  using argument_tags =
149  tmpl::append<boundary_tags,
150  tmpl::list<Spectral::Swsh::Tags::LMax,
152 
153  static void apply(
155  eth_r_divided_by_r,
156  const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
157  const size_t l_max, const size_t number_of_radial_points) noexcept {
158  detail::angular_derivative_of_r_divided_by_r_impl<
159  Spectral::Swsh::Tags::Eth>(make_not_null(&get(*eth_r_divided_by_r)),
160  get(boundary_r), l_max,
161  number_of_radial_points);
162  }
163 };
164 
165 /// Computes \f$\eth \eth R / R\f$ by differentiating and repeating the boundary
166 /// value of \f$R\f$.
167 template <template <typename> class BoundaryPrefix>
168 struct PrecomputeCceDependencies<BoundaryPrefix, Tags::EthEthRDividedByR> {
169  using boundary_tags = tmpl::list<BoundaryPrefix<Tags::BondiR>>;
170  using pre_swsh_derivative_tags = tmpl::list<>;
171  using integration_independent_tags = tmpl::list<>;
172 
173  using return_tags = tmpl::list<Tags::EthEthRDividedByR>;
174  using argument_tags =
175  tmpl::append<boundary_tags,
176  tmpl::list<Spectral::Swsh::Tags::LMax,
178 
179  static void apply(
181  eth_eth_r_divided_by_r,
182  const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
183  const size_t l_max, const size_t number_of_radial_points) noexcept {
184  detail::angular_derivative_of_r_divided_by_r_impl<
186  make_not_null(&get(*eth_eth_r_divided_by_r)), get(boundary_r), l_max,
187  number_of_radial_points);
188  }
189 };
190 
191 /// Computes \f$\eth \bar{\eth} R / R\f$ by differentiating and repeating the
192 /// boundary value of \f$R\f$.
193 template <template <typename> class BoundaryPrefix>
194 struct PrecomputeCceDependencies<BoundaryPrefix, Tags::EthEthbarRDividedByR> {
195  using boundary_tags = tmpl::list<BoundaryPrefix<Tags::BondiR>>;
196  using pre_swsh_derivative_tags = tmpl::list<>;
197  using integration_independent_tags = tmpl::list<>;
198 
199  using return_tags = tmpl::list<Tags::EthEthbarRDividedByR>;
200  using argument_tags =
201  tmpl::append<boundary_tags,
202  tmpl::list<Spectral::Swsh::Tags::LMax,
204 
205  static void apply(
207  eth_ethbar_r_divided_by_r,
208  const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
209  const size_t l_max, const size_t number_of_radial_points) noexcept {
210  detail::angular_derivative_of_r_divided_by_r_impl<
212  make_not_null(&get(*eth_ethbar_r_divided_by_r)), get(boundary_r), l_max,
213  number_of_radial_points);
214  }
215 };
216 
217 /// Computes \f$K = \sqrt{1 + J \bar{J}}\f$.
218 template <template <typename> class BoundaryPrefix>
219 struct PrecomputeCceDependencies<BoundaryPrefix, Tags::BondiK> {
220  using boundary_tags = tmpl::list<>;
221  using pre_swsh_derivative_tags = tmpl::list<Tags::BondiJ>;
222  using integration_independent_tags = tmpl::list<>;
223 
224  using return_tags = tmpl::list<Tags::BondiK>;
225  using argument_tags = tmpl::append<tmpl::list<Spectral::Swsh::Tags::LMax>,
226  pre_swsh_derivative_tags>;
227 
228  static void apply(
230  const size_t /*l_max*/,
231  const Scalar<SpinWeighted<ComplexDataVector, 2>>& j) noexcept {
232  get(*k).data() = sqrt(1.0 + get(j).data() * conj(get(j)).data());
233  }
234 };
235 
236 /*!
237  * \brief Convenience routine for computing all of the CCE inputs to integrand
238  * computation that do not depend on intermediate integrand results. It should
239  * be executed before moving through the hierarchy of integrands.
240  *
241  * \details Provided a \ref DataBoxGroup with the appropriate tags (including
242  * `Cce::pre_computation_boundary_tags`, `Cce::pre_computation_tags`,
243  * `Cce::Tags::BondiJ` and `Spectral::Swsh::Tags::LMax`), this function will
244  * apply all of the necessary mutations to update the
245  * `Cce::pre_computation_tags` to their correct values for the current values
246  * for the remaining (input) tags.
247  *
248  * The `BoundaryPrefix` template template parameter is to be passed a prefix
249  * tag associated with the boundary value prefix used in the computation (e.g.
250  * `Cce::Tags::BoundaryValue`), and allows easy switching between the
251  * regularity-preserving version and standard CCE.
252  */
253 template <template <typename> class BoundaryPrefix, typename DataBoxType>
255  const gsl::not_null<DataBoxType*> box) noexcept {
256  tmpl::for_each<pre_computation_tags>([&box](auto x) {
257  using integration_independent_tag = typename decltype(x)::type;
258  using mutation =
260  db::mutate_apply<mutation>(box);
261  });
262 }
263 } // namespace Cce
A set of procedures for computing the set of inputs to the CCE integrand computations that can be com...
Definition: PrecomputeCceDependencies.hpp:59
Contains functionality for Cauchy Characteristic Extraction.
Definition: BoundaryData.cpp:21
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
const DataVector & collocation_points(const size_t num_points) noexcept
Collocation points.
Definition: Spectral.cpp:247
void mutate_all_precompute_cce_dependencies(const gsl::not_null< DataBoxType *> box) noexcept
Convenience routine for computing all of the CCE inputs to integrand computation that do not depend o...
Definition: PrecomputeCceDependencies.hpp:254
Definition: Determinant.hpp:11
Tag for the number of radial grid points in the three-dimensional representation of radially concentr...
Definition: SwshTags.hpp:195
void fill_with_n_copies(const gsl::not_null< VectorType *> result, const VectorType &to_copy, const size_t times_to_copy) noexcept
Creates or fills a vector with data from to_repeat copied times_to_repeat times in sequence...
Definition: VectorAlgebra.hpp:54
Make a spin-weighted type T with spin-weight Spin. Mathematical operators are restricted to addition...
Definition: SpinWeighted.hpp:25
Stores a collection of complex function values.
Definition: ComplexDataVector.hpp:47
Definition: DataBoxTag.hpp:29
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
Tag for the maximum spin-weighted spherical harmonic l; sets angular resolution.
Definition: SwshTags.hpp:187
Stores a collection of function values.
Definition: DataVector.hpp:42
Wraps the template metaprogramming library used (brigand)
Defines functions and classes from the GSL.
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:36
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
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:44
Tensor< T, Symmetry<>, index_list<> > Scalar
Scalar type.
Definition: TypeAliases.hpp:21
Require a pointer to not be a nullptr
Definition: Gsl.hpp:182