InsertInterpolationScriData.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <tuple>
7 
9 #include "Evolution/Systems/Cce/OptionTags.hpp"
10 #include "Evolution/Systems/Cce/Tags.hpp"
11 #include "Parallel/GlobalCache.hpp"
12 #include "Time/Tags.hpp"
13 
14 namespace Cce {
15 namespace Actions {
16 
17 namespace detail {
18 template <typename Tag>
19 struct get_interpolator_argument_tag {
20  using type = Tag;
21 };
22 
23 template <typename Tag>
24 struct get_interpolator_argument_tag<Tags::Du<Tag>> {
25  using type = Tag;
26 };
27 
28 template <typename Tag>
29 struct InsertIntoInterpolationManagerImpl {
30  using return_tags =
31  tmpl::list<Tags::InterpolationManager<ComplexDataVector, Tag>>;
32  using argument_tags =
33  tmpl::list<typename get_interpolator_argument_tag<Tag>::type,
34  Tags::InertialRetardedTime>;
35  static void apply(
36  const gsl::not_null<ScriPlusInterpolationManager<ComplexDataVector, Tag>*>
37  interpolation_manager,
38  const typename Tag::type& scri_data,
39  const Scalar<DataVector>& inertial_retarded_time) noexcept {
40  interpolation_manager->insert_data(get(inertial_retarded_time),
41  get(scri_data).data());
42  }
43 };
44 
45 template <typename LhsTag, typename RhsTag>
46 struct InsertIntoInterpolationManagerImpl<::Tags::Multiplies<LhsTag, RhsTag>> {
47  using return_tags = tmpl::list<Tags::InterpolationManager<
49  using argument_tags =
50  tmpl::list<typename get_interpolator_argument_tag<LhsTag>::type, RhsTag,
51  Tags::InertialRetardedTime>;
52  static void apply(const gsl::not_null<ScriPlusInterpolationManager<
54  interpolation_manager,
55  const typename LhsTag::type& lhs_data,
56  const typename RhsTag::type& rhs_data,
57  const Scalar<DataVector>& inertial_retarded_time) noexcept {
58  interpolation_manager->insert_data(get(inertial_retarded_time),
59  get(lhs_data).data(),
60  get(rhs_data).data());
61  }
62 };
63 
64 template <typename Tag, typename ParallelComponent, typename Metavariables>
65 void output_impl(const size_t observation_l_max, const size_t l_max,
66  const TimeStepId& time_id, const typename Tag::type& tag_data,
68  std::vector<double> data_to_write(2 * square(observation_l_max + 1) + 1);
69  std::vector<std::string> file_legend;
70  file_legend.reserve(2 * square(observation_l_max + 1) + 1);
71  file_legend.emplace_back("time");
72  for (int l = 0; l <= static_cast<int>(observation_l_max); ++l) {
73  for (int m = -l; m <= l; ++m) {
74  file_legend.push_back(MakeString{} << "Real Y_" << l << "," << m);
75  file_legend.push_back(MakeString{} << "Imag Y_" << l << "," << m);
76  }
77  }
78  auto& my_proxy = Parallel::get_parallel_component<ParallelComponent>(cache);
79  auto observer_proxy = Parallel::get_parallel_component<
81  cache)[static_cast<size_t>(Parallel::my_node(*my_proxy.ckLocal()))];
82  // swsh transform
83  const ComplexModalVector goldberg_modes =
85  Spectral::Swsh::swsh_transform(l_max, 1, get(tag_data)), l_max)
86  .data();
87 
88  data_to_write[0] = time_id.substep_time().value();
89  for (size_t i = 0; i < square(observation_l_max + 1); ++i) {
90  data_to_write[2 * i + 1] = real(goldberg_modes[i]);
91  data_to_write[2 * i + 2] = imag(goldberg_modes[i]);
92  }
93  Parallel::threaded_action<observers::ThreadedActions::WriteSimpleData>(
94  observer_proxy, file_legend, data_to_write,
95  "/" + db::tag_name<Tag>() + "_Noninertial");
96 }
97 } // namespace detail
98 
99 /*!
100  * \ingroup ActionsGroup
101  * \brief Places the data from the current hypersurface necessary to compute
102  * `Tag` in the `ScriPlusInterpolationManager` associated with the `Tag`.
103  *
104  * \details Adds both the appropriate scri+ value(s) and a number of target
105  * inertial times to interpolate of quantity equal to the
106  * `InitializationTags::ScriOutputDensity` determined from options, equally
107  * spaced between the current time and the next time in the algorithm.
108  *
109  * Uses:
110  * - `::Tags::TimeStepId`
111  * - `::Tags::Next<::Tags::TimeStepId>`
112  * - `Cce::InitializationTags::ScriOutputDensity`
113  * - if `Tag` is `::Tags::Multiplies<Lhs, Rhs>`:
114  * - `Lhs` and `Rhs`
115  * - if `Tag` has `Cce::Tags::Du<Argument>`:
116  * - `Argument`
117  * - otherwise uses `Tag`
118  *
119  * \ref DataBoxGroup changes:
120  * - Modifies:
121  * - `Tags::InterpolationManager<ComplexDataVector, Tag>`
122  * - Adds: nothing
123  * - Removes: nothing
124  */
125 template <typename Tag, typename BoundaryComponent>
127  using const_global_cache_tags = tmpl::flatten<
130  tt::is_a_v<AnalyticWorldtubeBoundary, BoundaryComponent>,
131  tmpl::list<Tags::OutputNoninertialNews>, tmpl::list<>>>>;
132  template <typename DbTags, typename... InboxTags, typename Metavariables,
133  typename ArrayIndex, typename ActionList,
134  typename ParallelComponent>
135  static auto apply(db::DataBox<DbTags>& box,
136  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
138  const ArrayIndex& /*array_index*/,
139  const ActionList /*meta*/,
140  const ParallelComponent* const /*meta*/) noexcept {
141  if constexpr(tt::is_a_v<AnalyticWorldtubeBoundary, BoundaryComponent>) {
142  if (db::get<Tags::OutputNoninertialNews>(box) and
143  db::get<::Tags::TimeStepId>(box).substep() == 0 and
144  std::is_same_v<Tag, Tags::News>) {
145  detail::output_impl<Tags::News, ParallelComponent>(
146  db::get<Tags::ObservationLMax>(box), db::get<Tags::LMax>(box),
147  db::get<::Tags::TimeStepId>(box), db::get<Tags::News>(box), cache);
148  db::get<Tags::AnalyticBoundaryDataManager>(box)
149  .template write_news<ParallelComponent>(
150  cache, db::get<::Tags::TimeStepId>(box).substep_time().value());
151  }
152  }
153  if (db::get<::Tags::TimeStepId>(box).substep() == 0) {
154  // insert the data points into the interpolator.
155  db::mutate_apply<detail::InsertIntoInterpolationManagerImpl<Tag>>(
156  make_not_null(&box));
157 
158  const auto& time_span_deque =
159  db::get<Tags::InterpolationManager<ComplexDataVector, Tag>>(box)
160  .get_u_bondi_ranges();
161 
162  const double this_time = time_span_deque.back().first;
163  double time_delta_estimate = db::get<::Tags::TimeStep>(box).value();
164  if(time_span_deque.size() > 1) {
165  time_delta_estimate =
166  this_time - time_span_deque[time_span_deque.size() - 2].first;
167  }
168 
169  // insert the target times into the interpolator.
170  db::mutate<Tags::InterpolationManager<ComplexDataVector, Tag>>(
171  make_not_null(&box),
172  [&this_time, &time_delta_estimate](
173  const gsl::not_null<
175  interpolation_manager,
176  const size_t number_of_interpolated_times) noexcept {
177  for (size_t i = 0; i < number_of_interpolated_times; ++i) {
178  interpolation_manager->insert_target_time(
179  this_time +
180  time_delta_estimate * static_cast<double>(i) /
181  static_cast<double>(number_of_interpolated_times));
182  }
183  },
184  db::get<InitializationTags::ScriOutputDensity>(box));
185  }
186  return std::forward_as_tuple(std::move(box));
187  }
188 };
189 } // namespace Actions
190 } // namespace Cce
std::apply
T apply(T... args)
Cce::InitializationTags::ScriOutputDensity
Definition: OptionTags.hpp:233
get
constexpr Tag::type & get(Variables< TagList > &v) noexcept
Return Tag::type pointing into the contiguous array.
Definition: Variables.hpp:660
Parallel::GlobalCache
Definition: ElementReceiveInterpPoints.hpp:15
GlobalCache.hpp
Parallel::get_parallel_component
auto get_parallel_component(GlobalCache< Metavariables > &cache) noexcept -> Parallel::proxy_from_parallel_component< GlobalCache_detail::get_component_if_mocked< typename Metavariables::component_list, ParallelComponentTag >> &
Access the Charm++ proxy associated with a ParallelComponent.
Definition: GlobalCache.hpp:535
std::vector< double >
square
constexpr decltype(auto) square(const T &x)
Compute the square of x
Definition: ConstantExpressions.hpp:55
tuple
observers::ObserverWriter
The nodegroup parallel component that is responsible for writing data to disk.
Definition: ObserverComponent.hpp:51
Parallel::my_node
int my_node(const DistribObject &distributed_object) noexcept
Index of my node.
Definition: Info.hpp:51
DataBox.hpp
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
Spectral::Swsh::libsharp_to_goldberg_modes
void libsharp_to_goldberg_modes(gsl::not_null< SpinWeighted< ComplexModalVector, Spin > * > goldberg_modes, const SpinWeighted< ComplexModalVector, Spin > &libsharp_modes, size_t l_max) noexcept
Compute the set of Goldberg Spin-weighted spherical harmonic modes (in the convention of ) from a lib...
TimeStepId
Definition: TimeStepId.hpp:25
ComplexModalVector
A class for storing complex spectral coefficients on a spectral grid.
Definition: ComplexModalVector.hpp:40
Spectral::Swsh::swsh_transform
void swsh_transform(const size_t l_max, const size_t number_of_radial_points, const gsl::not_null< SpinWeighted< ComplexModalVector, Spin > * > first_coefficient, const ModalThenNodalTypes &... coefficients_then_collocations) noexcept
Perform a forward libsharp spin-weighted spherical harmonic transform on any number of supplied SpinW...
Definition: SwshTransform.hpp:171
ActionTesting::cache
Parallel::GlobalCache< Metavariables > & cache(MockRuntimeSystem< Metavariables > &runner, const ArrayIndex &array_index) noexcept
Returns the GlobalCache of Component with index array_index.
Definition: MockRuntimeSystemFreeFunctions.hpp:382
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: CharacteristicExtractFwd.hpp:6
Cce::Actions::InsertInterpolationScriData
Places the data from the current hypersurface necessary to compute Tag in the ScriPlusInterpolationMa...
Definition: InsertInterpolationScriData.hpp:126
Cce::ScriPlusInterpolationManager
Stores necessary data and interpolates on to new time points at scri+.
Definition: ScriPlusInterpolationManager.hpp:48
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
std::conditional_t
ComplexDataVector
Stores a collection of complex function values.
Definition: ComplexDataVector.hpp:53
std::data
T data(T... args)
Tags::Multiplies
A prefix tag representing the product of two other tags. Note that if non-spin-weighted types are nee...
Definition: Tags.hpp:82
MakeString
Make a string by streaming into object.
Definition: MakeString.hpp:18
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecThirdOrderPiecewisePolynomial.hpp:13