ScriObserveInterpolated.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <string>
8 #include <tuple>
9 #include <utility>
10 #include <vector>
11 
12 #include "DataStructures/ComplexDataVector.hpp"
14 #include "DataStructures/SpinWeighted.hpp"
15 #include "Evolution/Systems/Cce/OptionTags.hpp"
16 #include "Evolution/Systems/Cce/ScriPlusInterpolationManager.hpp"
17 #include "Evolution/Systems/Cce/Tags.hpp"
18 #include "IO/Observer/WriteSimpleData.hpp"
19 #include "NumericalAlgorithms/Spectral/SwshCoefficients.hpp"
20 #include "NumericalAlgorithms/Spectral/SwshTransform.hpp"
22 #include "Parallel/Invoke.hpp"
23 #include "Time/Tags.hpp"
24 #include "Utilities/Gsl.hpp"
25 #include "Utilities/MakeString.hpp"
26 #include "Utilities/TMPL.hpp"
27 
28 namespace Cce {
29 namespace detail {
30 // Provide a nicer name for the output h5 files for some of the uglier
31 // combinations we need
32 template <typename Tag>
33 struct ScriOutput {
34  static std::string name() noexcept { return db::tag_name<Tag>(); }
35 };
36 template <typename Tag>
37 struct ScriOutput<Tags::ScriPlus<Tag>> {
38  static std::string name() noexcept {
39  return pretty_type::short_name<Tag>();
40  }
41 };
42 template <>
43 struct ScriOutput<::Tags::Multiplies<
44  Tags::Du<Tags::TimeIntegral<Tags::ScriPlus<Tags::Psi4>>>,
45  Tags::ScriPlusFactor<Tags::Psi4>>> {
46  static std::string name() noexcept { return "Psi4"; }
47 };
48 } // namespace detail
49 
50 namespace Actions {
51 
52 /*!
53  * \ingroup ActionsGroup
54  * \brief Checks the interpolation managers and if they are ready, performs the
55  * interpolation and sends the data to file via
56  * `observers::ThreadedActions::WriteSimpleData`.
57  *
58  * \details This uses the `ScriPlusInterpolationManager` to perform the
59  * interpolations of all requested scri quantities (determined by
60  * `scri_values_to_observe` in the metavariables), and write them to disk using
61  * `observers::threadedActions::WriteSimpleData`.
62  *
63  * \ref DataBoxGroup changes:
64  * - Adds: nothing
65  * - Removes: nothing
66  * - Modifies: `InterpolagionManager<ComplexDataVector, Tag>` for each `Tag` in
67  * `Metavariables::scri_values_to_observe`
68  */
69 template <typename ObserverWriterComponent>
71  using const_global_cache_tags = tmpl::list<Tags::ObservationLMax>;
72  template <typename DbTags, typename... InboxTags, typename Metavariables,
73  typename ArrayIndex, typename ActionList,
74  typename ParallelComponent>
77  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
79  const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
80  const ParallelComponent* const /*meta*/) noexcept {
81  const size_t observation_l_max = db::get<Tags::ObservationLMax>(box);
82  const size_t l_max = db::get<Tags::LMax>(box);
83  std::vector<double> data_to_write(2 * square(observation_l_max + 1) + 1);
84  std::vector<std::string> file_legend;
85  file_legend.reserve(2 * square(observation_l_max + 1) + 1);
86  file_legend.emplace_back("time");
87  for (int i = 0; i <= static_cast<int>(observation_l_max); ++i) {
88  for(int j = -i; j <= i; ++j) {
89  file_legend.push_back(MakeString{} << "Real Y_" << i << "," << j);
90  file_legend.push_back(MakeString{} << "Imag Y_" << i << "," << j);
91  }
92  }
93  auto observer_proxy =
94  Parallel::get_parallel_component<ObserverWriterComponent>(
95  cache)[static_cast<size_t>(Parallel::my_node())];
96  while (
99  tmpl::front<typename Metavariables::scri_values_to_observe>>>(box)
100  .first_time_is_ready_to_interpolate()) {
101  tmpl::for_each<typename Metavariables::scri_values_to_observe>([
102  &box, &data_to_write, &observer_proxy, &file_legend, &observation_l_max,
103  &l_max
104  ](auto tag_v) noexcept {
105  using tag = typename decltype(tag_v)::type;
107  db::mutate<Tags::InterpolationManager<ComplexDataVector, tag>>(
108  make_not_null(&box),
109  [&interpolation](
110  const gsl::not_null<
112  interpolation_manager) {
113  interpolation =
114  interpolation_manager->interpolate_and_pop_first_time();
115  });
116  // swsh transform
117  const auto to_transform =
119  interpolation.second};
120  const ComplexModalVector goldberg_modes =
121  Spectral::Swsh::libsharp_to_goldberg_modes(
122  Spectral::Swsh::swsh_transform(l_max, 1, to_transform), l_max)
123  .data();
124 
125  data_to_write[0] = interpolation.first;
126  for(size_t i = 0; i < square(observation_l_max + 1); ++i) {
127  data_to_write[2 * i + 1] = real(goldberg_modes[i]);
128  data_to_write[2 * i + 2] = imag(goldberg_modes[i]);
129  }
130  Parallel::threaded_action<observers::ThreadedActions::WriteSimpleData>(
131  observer_proxy, file_legend, data_to_write,
132  "/" + ::Cce::detail::ScriOutput<tag>::name());
133  });
134  }
135  return std::forward_as_tuple(std::move(box));
136  }
137 };
138 } // namespace Actions
139 } // namespace Cce
A prefix tag representing the product of two other tags. Note that if non-spin-weighted types are nee...
Definition: Tags.hpp:86
The set of utilities for performing Cauchy characteristic evolution and Cauchy characteristic matchin...
Definition: BoundaryComputeAndSendToEvolution.hpp:28
Stores necessary data and interpolates on to new time points at scri+.
Definition: ScriPlusInterpolationManager.hpp:45
Checks the interpolation managers and if they are ready, performs the interpolation and sends the dat...
Definition: ScriObserveInterpolated.hpp:70
int my_node()
Index of my node.
Definition: Info.hpp:34
SpinWeighted< ComplexModalVector, Spin > swsh_transform(const size_t l_max, const size_t number_of_radial_points, const SpinWeighted< ComplexDataVector, Spin > &collocation) noexcept
Perform a forward libsharp spin-weighted spherical harmonic transform on a single supplied SpinWeight...
Definition: SwshTransform.cpp:107
Definition: Determinant.hpp:11
Make a string by streaming into object.
Definition: MakeString.hpp:16
Make a spin-weighted type T with spin-weight Spin. Mathematical operators are restricted to addition...
Definition: SpinWeighted.hpp:24
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
Defines classes and functions used for manipulating DataBox&#39;s.
Stores a collection of complex function values.
Definition: ComplexDataVector.hpp:47
A class for storing complex spectral coefficients on a spectral grid.
Definition: ComplexModalVector.hpp:39
Definition: InterpolationTargetWedgeSectionTorus.hpp:25
Definition: DataBoxTag.hpp:27
A Charm++ chare that caches constant data once per Charm++ node.
Definition: ConstGlobalCache.hpp:136
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:1444
Definition: Tags.hpp:401
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:1134
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
Definition: Test_ActionTesting.cpp:365
Defines class template ConstGlobalCache.
decltype(auto) constexpr square(const T &x)
Compute the square of x
Definition: ConstantExpressions.hpp:54
Definition: ComputeTimeDerivative.hpp:29
Require a pointer to not be a nullptr
Definition: Gsl.hpp:182