BoundaryComputeAndSendToEvolution.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <string>
7 #include <tuple>
8 
10 #include "DataStructures/VariablesTag.hpp"
11 #include "Evolution/Systems/Cce/Actions/ReceiveWorldtubeData.hpp"
12 #include "Evolution/Systems/Cce/Components/WorldtubeBoundary.hpp"
13 #include "Evolution/Systems/Cce/InterfaceManagers/GhInterfaceManager.hpp"
14 #include "Evolution/Systems/Cce/OptionTags.hpp"
15 #include "Evolution/Systems/Cce/ReceiveTags.hpp"
16 #include "Evolution/Systems/Cce/Tags.hpp"
17 #include "Evolution/Systems/Cce/WorldtubeDataManager.hpp"
18 #include "IO/Observer/Actions/GetLockPointer.hpp"
19 #include "IO/Observer/ObserverComponent.hpp"
20 #include "Parallel/GlobalCache.hpp"
21 #include "Parallel/Invoke.hpp"
22 #include "Parallel/Printf.hpp"
23 #include "Time/Tags.hpp"
24 #include "Time/TimeStepId.hpp"
26 #include "Utilities/Gsl.hpp"
27 #include "Utilities/TMPL.hpp"
28 #include "Utilities/TypeTraits.hpp"
29 
30 namespace Cce {
31 namespace Actions {
32 
33 /*!
34  * \ingroup ActionsGroup
35  * \brief Obtains the CCE boundary data at the specified `time`, and reports it
36  * to the `EvolutionComponent` via `Actions::ReceiveWorldtubeData`.
37  *
38  * \details See the template partial specializations of this class for details
39  * on the different strategies for each component type.
40  */
41 template <typename BoundaryComponent, typename EvolutionComponent>
43 
44 /*!
45  * \ingroup ActionsGroup
46  * \brief Computes Bondi boundary data from GH evolution variables and sends the
47  * result to the `EvolutionComponent` (template argument).
48  *
49  * \details After the computation, this action will call
50  * `Cce::Actions::ReceiveWorldtubeData` on the `EvolutionComponent` with each of
51  * the types from `typename Metavariables::cce_boundary_communication_tags` sent
52  * as arguments
53  *
54  * \ref DataBoxGroup changes:
55  * - Adds: nothing
56  * - Removes: nothing
57  * - Modifies:
58  * - `Tags::Variables<typename
59  * Metavariables::cce_boundary_communication_tags>` (every tensor)
60  */
61 template <typename BoundaryComponent, typename EvolutionComponent>
63 
64 /*!
65  * \ingroup ActionsGroup
66  * \brief Obtains the CCE boundary data at the specified `time`, and reports it
67  * to the `EvolutionComponent` via `Actions::ReceiveWorldtubeData`.
68  *
69  * \details This uses the `WorldtubeDataManager` to perform all of the work of
70  * managing the file buffer, interpolating to the desired time point, and
71  * compute the Bondi quantities on the boundary. Once readied, it sends each
72  * tensor from the the full `Variables<typename
73  * Metavariables::cce_boundary_communication_tags>` back to the
74  * `EvolutionComponent`
75  *
76  * Uses:
77  * - DataBox:
78  * - `Tags::H5WorldtubeBoundaryDataManager`
79  *
80  * \ref DataBoxGroup changes:
81  * - Adds: nothing
82  * - Removes: nothing
83  * - Modifies:
84  * - `Tags::Variables<typename
85  * Metavariables::cce_boundary_communication_tags>` (every tensor)
86  */
87 template <typename Metavariables, typename EvolutionComponent>
89  EvolutionComponent> {
90  template <typename ParallelComponent, typename... DbTags, typename ArrayIndex,
91  Requires<tmpl2::flat_any_v<std::is_same_v<
93  typename Metavariables::cce_boundary_communication_tags>,
94  DbTags>...>> = nullptr>
95  static void apply(db::DataBox<tmpl::list<DbTags...>>& box,
97  const ArrayIndex& /*array_index*/,
98  const TimeStepId& time) noexcept {
99  auto hdf5_lock = Parallel::get_parallel_component<
101  .ckLocalBranch()
102  ->template local_synchronous_action<
105  bool successfully_populated = false;
108  typename Metavariables::cce_boundary_communication_tags>>(
109  make_not_null(&box),
110  [&successfully_populated, &time, &hdf5_lock](
112  worldtube_data_manager,
113  const gsl::not_null<Variables<
114  typename Metavariables::cce_boundary_communication_tags>*>
115  boundary_variables) noexcept {
116  successfully_populated =
117  (*worldtube_data_manager)
118  ->populate_hypersurface_boundary_data(
119  boundary_variables, time.substep_time().value(),
120  hdf5_lock);
121  });
122  if (not successfully_populated) {
123  ERROR("Insufficient boundary data to proceed, exiting early at time " +
124  std::to_string(time.substep_time().value()));
125  }
127  typename Metavariables::cce_boundary_communication_tags>>(
128  Parallel::get_parallel_component<EvolutionComponent>(cache), time,
130  typename Metavariables::cce_boundary_communication_tags>>(box),
131  true);
132  }
133 };
134 
135 /*!
136  * \ingroup ActionsGroup
137  * \brief Calculates the analytic boundary data at the specified `time`, and
138  * sends the resulting Bondi-Sachs boundary data to the `EvolutionComponent`
139  *
140  * \details This uses the `Cce::AnalyticBoundaryDataManager` to
141  * perform all of the work of calculating the analytic boundary solution, which
142  * in turn uses derived classes of `Cce::Solutions::WorldtubeData` to calculate
143  * the metric data before it is transformed to Bondi-Sachs variables.
144  *
145  * \ref DataBoxGroup changes:
146  * - Adds: nothing
147  * - Removes: nothing
148  * - Modifies:
149  * - `Tags::AnalyticWordltubeBoundaryDataManager`
150  */
151 template <typename Metavariables, typename EvolutionComponent>
153  AnalyticWorldtubeBoundary<Metavariables>, EvolutionComponent> {
154  template <typename ParallelComponent, typename DbTagList, typename ArrayIndex>
155  static void apply(db::DataBox<DbTagList>& box,
157  const ArrayIndex& /*array_index*/,
158  const TimeStepId& time) noexcept {
159  if constexpr (tmpl::list_contains_v<
160  DbTagList,
161  ::Tags::Variables<typename Metavariables::
162  cce_boundary_communication_tags>>) {
163  bool successfully_populated = false;
166  typename Metavariables::cce_boundary_communication_tags>>(
167  make_not_null(&box),
168  [&successfully_populated, &time](
170  worldtube_data_manager,
171  const gsl::not_null<Variables<
172  typename Metavariables::cce_boundary_communication_tags>*>
173  boundary_variables) noexcept {
174  successfully_populated =
175  (*worldtube_data_manager)
176  .populate_hypersurface_boundary_data(
177  boundary_variables, time.substep_time().value());
178  });
179 
180  if (not successfully_populated) {
181  ERROR("Insufficient boundary data to proceed, exiting early at time "
182  << time.substep_time().value());
183  }
185  typename Metavariables::cce_boundary_communication_tags>>(
186  Parallel::get_parallel_component<EvolutionComponent>(cache), time,
188  typename Metavariables::cce_boundary_communication_tags>>(box),
189  true);
190  } else {
191  ERROR(
192  "Did not find required tag `::Tags::Variables<typename "
193  "Metavariables::cce_boundary_communication_tags>` in the DataBox");
194  }
195  }
196 };
197 
198 /*!
199  * \ingroup ActionsGroup
200  * \brief Submits a request for CCE boundary data at the specified `time` to the
201  * `Cce::InterfaceManagers::GhInterfaceManager`, and sends the data to the
202  * `EvolutionComponent` (template argument) if it is ready.
203  *
204  * \details This uses the `Cce::InterfaceManagers::GhInterfaceManager` to
205  * perform all of the work of managing the buffer of data sent from the GH
206  * system and interpolating if necessary and supported. This dispatches then to
207  * `Cce::Actions::SendToEvolution<GhWorldtubeBoundary<Metavariables>,
208  * EvolutionComponent>` if the boundary data is ready, otherwise
209  * simply submits the request and waits for data to become available via
210  * `Cce::Actions::ReceiveGhWorldtubeData`, which will call
211  * `Cce::Actions::SendToEvolution<GhWorldtubeBoundary<Metavariables>,
212  * EvolutionComponent>` as soon as the data becomes available.
213  *
214  * \ref DataBoxGroup changes:
215  * - Adds: nothing
216  * - Removes: nothing
217  * - Modifies:
218  * - `Tags::GhInterfaceManager`
219  */
220 template <typename Metavariables, typename EvolutionComponent>
222  EvolutionComponent> {
223  template <typename ParallelComponent, typename... DbTags, typename ArrayIndex,
224  Requires<tmpl2::flat_any_v<std::is_same_v<
226  typename Metavariables::cce_boundary_communication_tags>,
227  DbTags>...>> = nullptr>
228  static void apply(db::DataBox<tmpl::list<DbTags...>>& box,
230  const ArrayIndex& /*array_index*/,
231  const TimeStepId& time) noexcept {
232  db::mutate<Tags::GhInterfaceManager>(
233  make_not_null(&box),
234  [&time, &cache](const gsl::not_null<
236  interface_manager) noexcept {
237  (*interface_manager)->request_gh_data(time);
238  const auto gh_data =
239  (*interface_manager)->retrieve_and_remove_first_ready_gh_data();
240  if (static_cast<bool>(gh_data)) {
242  GhWorldtubeBoundary<Metavariables>, EvolutionComponent>>(
245  get<0>(*gh_data), get<1>(*gh_data));
246  }
247  });
248  }
249 };
250 
251 /// \cond
252 template <typename Metavariables, typename EvolutionComponent>
253 struct SendToEvolution<GhWorldtubeBoundary<Metavariables>, EvolutionComponent> {
254  template <typename ParallelComponent, typename... DbTags, typename ArrayIndex,
255  Requires<tmpl2::flat_any_v<std::is_same_v<
257  typename Metavariables::cce_boundary_communication_tags>,
258  DbTags>...>> = nullptr>
259  static void apply(db::DataBox<tmpl::list<DbTags...>>& box,
261  const ArrayIndex& /*array_index*/, const TimeStepId& time,
262  const InterfaceManagers::GhInterfaceManager::gh_variables&
263  gh_variables) noexcept {
265  typename Metavariables::cce_boundary_communication_tags>>(
266  make_not_null(&box),
267  [&gh_variables](
268  const gsl::not_null<Variables<
269  typename Metavariables::cce_boundary_communication_tags>*>
270  boundary_variables,
271  const double extraction_radius, const double l_max) noexcept {
273  boundary_variables,
275  gh_variables),
277  gh_variables),
279  gh_variables),
280  extraction_radius, l_max);
281  },
282  db::get<InitializationTags::ExtractionRadius>(box),
283  db::get<Tags::LMax>(box));
285  typename Metavariables::cce_boundary_communication_tags>>(
286  Parallel::get_parallel_component<EvolutionComponent>(cache), time,
288  typename Metavariables::cce_boundary_communication_tags>>(box),
289  true);
290  }
291 };
292 /// \endcond
293 
294 } // namespace Actions
295 } // namespace Cce
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
Error.hpp
tmpl2::flat_any_v
constexpr bool flat_any_v
A non-short-circuiting logical OR between bools 'B"".
Definition: TMPL.hpp:532
Tags::Variables
Definition: VariablesTag.hpp:21
tuple
db::get
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:786
Cce::H5WorldtubeBoundary
Component that supplies CCE worldtube boundary data.
Definition: CharacteristicExtractFwd.hpp:8
db::mutate
decltype(auto) mutate(const gsl::not_null< DataBox< TagList > * > box, Invokable &&invokable, Args &&... args) noexcept
Allows changing the state of one or more non-computed elements in the DataBox.
Definition: DataBox.hpp:636
ERROR
#define ERROR(m)
prints an error message to the standard error stream and aborts the program.
Definition: Error.hpp:37
observers::ObserverWriter
The nodegroup parallel component that is responsible for writing data to disk.
Definition: ObserverComponent.hpp:51
Cce::ReceiveTags::BoundaryData
A receive tag for the data sent to the CCE evolution component from the CCE boundary component.
Definition: ReceiveTags.hpp:16
Printf.hpp
DataBox.hpp
Parallel::local_synchronous_action
decltype(auto) local_synchronous_action(Proxy &&proxy, Args &&... args) noexcept
Invoke a local synchronous action on proxy
Definition: Invoke.hpp:79
GeneralizedHarmonic::Tags::Pi
Conjugate momentum to the spacetime metric.
Definition: Tags.hpp:29
gr::Tags::SpacetimeMetric
Definition: Tags.hpp:17
observers::Tags::H5FileLock
Node lock used when needing to read/write to H5 files on disk.
Definition: Tags.hpp:139
Cce::Tags::AnalyticBoundaryDataManager
A tag that constructs a AnalyticBoundaryDataManager from options.
Definition: OptionTags.hpp:529
TimeStepId
Definition: TimeStepId.hpp:25
Parallel::receive_data
void receive_data(Proxy &&proxy, typename ReceiveTag::temporal_id temporal_id, ReceiveDataType &&receive_data, const bool enable_if_disabled=false) noexcept
Send the data args... to the algorithm running on proxy, and tag the message with the identifier temp...
Definition: Invoke.hpp:32
TimeStepId.hpp
GeneralizedHarmonic::Tags::Phi
Auxiliary variable which is analytically the spatial derivative of the spacetime metric.
Definition: Tags.hpp:40
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:380
Cce
The set of utilities for performing Cauchy characteristic evolution and Cauchy characteristic matchin...
Definition: CharacteristicExtractFwd.hpp:6
Gsl.hpp
Cce::Tags::H5WorldtubeBoundaryDataManager
A tag that constructs a MetricWorldtubeDataManager from options.
Definition: OptionTags.hpp:246
Cce::create_bondi_boundary_data
void create_bondi_boundary_data(const gsl::not_null< Variables< BoundaryTagList > * > bondi_boundary_data, const tnsr::iaa< DataVector, 3 > &phi, const tnsr::aa< DataVector, 3 > &pi, const tnsr::aa< DataVector, 3 > &spacetime_metric, const double extraction_radius, const size_t l_max) noexcept
Process the worldtube data from generalized harmonic quantities to desired Bondi quantities,...
Definition: BoundaryData.hpp:792
Cce::Actions::SendToEvolution
Computes Bondi boundary data from GH evolution variables and sends the result to the EvolutionCompone...
Definition: BoundaryComputeAndSendToEvolution.hpp:62
observers::Actions::GetLockPointer
Local synchronous action for retrieving a pointer to the NodeLock with tag LockTag on the component.
Definition: GetLockPointer.hpp:25
Cce::GhWorldtubeBoundary
Component that supplies CCE worldtube boundary data sourced from a running GH system.
Definition: WorldtubeBoundary.hpp:166
Parallel::simple_action
void simple_action(Proxy &&proxy) noexcept
Invoke a simple action on proxy
Definition: Invoke.hpp:62
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
Requires
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t
Definition: Requires.hpp:67
std::unique_ptr
Cce::AnalyticWorldtubeBoundary
Component that supplies CCE worldtube boundary data sourced from an analytic solution.
Definition: CharacteristicExtractFwd.hpp:11
TMPL.hpp
Cce::Actions::BoundaryComputeAndSendToEvolution
Obtains the CCE boundary data at the specified time, and reports it to the EvolutionComponent via Act...
Definition: BoundaryComputeAndSendToEvolution.hpp:42
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecThirdOrderPiecewisePolynomial.hpp:13
string