8 #include "DataStructures/ComplexDataVector.hpp"
9 #include "DataStructures/ComplexModalVector.hpp"
11 #include "DataStructures/DataBox/Tag.hpp"
12 #include "DataStructures/Tags.hpp"
14 #include "Evolution/Systems/Cce/IntegrandInputSteps.hpp"
15 #include "Evolution/Systems/Cce/Tags.hpp"
19 #include "NumericalAlgorithms/Spectral/SwshCollocation.hpp"
20 #include "NumericalAlgorithms/Spectral/SwshDerivatives.hpp"
21 #include "NumericalAlgorithms/Spectral/SwshFiltering.hpp"
24 #include "Utilities/VectorAlgebra.hpp"
27 namespace TestHelpers {
31 template <
typename Tag>
38 template <
typename Tag>
40 using type =
typename Tag::type;
45 void volume_one_minus_y(
47 size_t l_max) noexcept;
53 size_t exponent) noexcept;
58 template <
typename... Tags>
60 template <
typename FromDataBox,
typename ToDataBox>
62 const FromDataBox& from_data_box) noexcept {
66 const typename Tags::type&... from_value) noexcept {
67 const auto assign = [](
auto to,
const auto& from) noexcept {
73 db::get<Tags>(from_data_box)...);
79 void generate_volume_data_from_separated_values(
84 size_t number_of_radial_grid_points) noexcept;
93 template <
typename Tag>
96 template <
typename Tag>
103 template <
typename AngularTagList,
typename RadialCoefficientTagList>
105 const gsl::not_null<Variables<AngularTagList>*> angular_collocation,
120 for (
size_t radial_power = 1;
121 radial_power < radial_coefficients->number_of_grid_points();
123 dy_radial_values[radial_power - 1] =
124 -
static_cast<double>(radial_power) * radial_values[radial_power];
126 dy_radial_values[radial_coefficients->number_of_grid_points() - 1] = 0.0;
130 template <
typename Tag,
typename DerivKind>
132 template <
typename AngularTagList,
typename RadialCoefficientTagList>
134 const gsl::not_null<Variables<AngularTagList>*> angular_collocation,
141 *angular_collocation)) =
142 Spectral::Swsh::angular_derivative<DerivKind>(
149 *radial_coefficients)) =
154 template <
typename LhsTag,
typename RhsTag>
156 template <
typename AngularTagList,
typename RadialCoefficientTagList>
158 const gsl::not_null<Variables<AngularTagList>*> angular_collocation,
163 const size_t ) noexcept {
165 *angular_collocation)) =
171 *radial_coefficients));
176 multiplied_radial_values = 0.0;
177 for (
size_t lhs_radial_power = 0;
178 lhs_radial_power < radial_coefficients->number_of_grid_points();
179 ++lhs_radial_power) {
180 for (
size_t rhs_radial_power = 0;
182 radial_coefficients->number_of_grid_points() - lhs_radial_power;
183 ++rhs_radial_power) {
184 multiplied_radial_values[lhs_radial_power + rhs_radial_power] +=
185 lhs_radial_values[lhs_radial_power] *
186 rhs_radial_values[rhs_radial_power];
194 template <
typename AngularTagList,
typename RadialCoefficientTagList>
196 const gsl::not_null<Variables<AngularTagList>*> angular_collocation,
201 const size_t ) noexcept {
207 *radial_coefficients)));
213 template <
typename AngularTagList,
typename RadialCoefficientTagList>
215 const gsl::not_null<Variables<AngularTagList>*> angular_collocation,
220 const size_t ) noexcept {
226 *radial_coefficients)));
232 template <
typename AngularTagList,
typename RadialCoefficientTagList>
234 const gsl::not_null<Variables<AngularTagList>*> angular_collocation,
239 const size_t ) noexcept {
245 *radial_coefficients)));
261 template <
typename InputTagList,
typename TargetTagList,
262 typename PreSwshDerivativesTagList,
typename SwshDerivativesTagList,
263 typename AngularCollocationTagList,
264 typename PreSwshDerivativesRadialModeTagList,
typename Generator>
265 void generate_separable_expected(
267 pre_swsh_derivatives,
268 const gsl::not_null<Variables<SwshDerivativesTagList>*> swsh_derivatives,
270 angular_collocations,
271 const gsl::not_null<Variables<PreSwshDerivativesRadialModeTagList>*>
275 const size_t number_of_radial_points) noexcept {
280 Spectral::Quadrature::GaussLobatto>(
281 number_of_radial_points));
287 (1.0 - y) / (2.0 * create_vector_of_n_copies(boundary_r.data(),
288 number_of_radial_points));
291 tmpl::for_each<InputTagList>([
292 &angular_collocations, &radial_modes, &pre_swsh_derivatives, &dist,
293 &generator, &l_max, &number_of_radial_points, &one_divided_by_r
294 ](
auto tag_v) noexcept {
295 using tag =
typename decltype(tag_v)::type;
296 using radial_polynomial_tag = RadialPolyCoefficientsFor<tag>;
297 using angular_collocation_tag = AngularCollocationsFor<tag>;
299 get(get<angular_collocation_tag>(*angular_collocations)).data() =
300 make_with_random_values<ComplexDataVector>(
303 Spectral::Swsh::filter_swsh_boundary_quantity(
305 &
get(get<angular_collocation_tag>(*angular_collocations))),
308 auto& radial_polynomial =
get(get<radial_polynomial_tag>(*radial_modes));
313 for (
size_t i = 0; i < radial_polynomial.size(); ++i) {
314 radial_polynomial[i] *= exp(
315 -10.0 *
square(
static_cast<double>(i) /
316 static_cast<double>(radial_polynomial.size() - 1)));
320 radial_polynomial[i] = 0.0;
324 generate_volume_data_from_separated_values(
327 get(get<angular_collocation_tag>(*angular_collocations)).
data(),
328 radial_polynomial, l_max, number_of_radial_points);
333 const auto calculate_separable_for_pre_swsh_derivative = [
334 &angular_collocations, &radial_modes, &pre_swsh_derivatives, &l_max,
335 &number_of_radial_points, &one_divided_by_r, &boundary_r
336 ](
auto pre_swsh_derivative_tag_v) noexcept {
337 using pre_swsh_derivative_tag =
338 typename decltype(pre_swsh_derivative_tag_v)::type;
339 CalculateSeparatedTag<pre_swsh_derivative_tag>{}(
340 angular_collocations, radial_modes, one_divided_by_r, boundary_r.data(),
342 generate_volume_data_from_separated_values(
344 &
get(get<pre_swsh_derivative_tag>(*pre_swsh_derivatives)).
data()),
346 get(
get<AngularCollocationsFor<pre_swsh_derivative_tag>>(
347 *angular_collocations))
349 get(
get<RadialPolyCoefficientsFor<pre_swsh_derivative_tag>>(
351 l_max, number_of_radial_points);
354 const auto calculate_separable_for_swsh_derivative = [
355 &angular_collocations, &radial_modes, &swsh_derivatives, &l_max,
356 &number_of_radial_points, &one_divided_by_r, &boundary_r
357 ](
auto swsh_derivative_tag_v) noexcept {
358 using swsh_derivative_tag =
typename decltype(swsh_derivative_tag_v)::type;
359 CalculateSeparatedTag<swsh_derivative_tag>{}(angular_collocations,
360 radial_modes, one_divided_by_r,
361 boundary_r.data(), l_max);
362 generate_volume_data_from_separated_values(
365 get(
get<AngularCollocationsFor<swsh_derivative_tag>>(
366 *angular_collocations))
368 get(
get<RadialPolyCoefficientsFor<swsh_derivative_tag>>(*radial_modes)),
369 l_max, number_of_radial_points);
372 tmpl::for_each<TargetTagList>([
373 &calculate_separable_for_pre_swsh_derivative, &
374 calculate_separable_for_swsh_derivative
375 ](
auto target_tag_v) noexcept {
376 using target_tag =
typename decltype(target_tag_v)::type;
377 tmpl::for_each<
typename detail::TagsToComputeForImpl<
378 target_tag>::pre_swsh_derivative_tags>(
379 calculate_separable_for_pre_swsh_derivative);
380 tmpl::for_each<
typename detail::TagsToComputeForImpl<
381 target_tag>::swsh_derivative_tags>(
382 calculate_separable_for_swsh_derivative);
383 tmpl::for_each<
typename detail::TagsToComputeForImpl<
384 target_tag>::second_swsh_derivative_tags>(
385 calculate_separable_for_swsh_derivative);