SendNextTimeToCce.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <tuple>
7 #include <vector>
8 
10 #include "DataStructures/IdPair.hpp"
12 #include "Domain/Structure/BlockId.hpp"
13 #include "ErrorHandling/Error.hpp"
14 #include "Evolution/Systems/Cce/Actions/BoundaryComputeAndSendToEvolution.hpp"
15 #include "Evolution/Systems/Cce/Components/CharacteristicEvolution.hpp"
16 #include "Evolution/Systems/Cce/OptionTags.hpp"
17 #include "Evolution/Systems/Cce/Tags.hpp"
18 #include "NumericalAlgorithms/Interpolation/PointInfoTag.hpp"
19 #include "Parallel/GlobalCache.hpp"
20 #include "Parallel/Invoke.hpp"
21 #include "Parallel/Printf.hpp"
22 #include "Time/Tags.hpp"
23 #include "Time/TimeStepId.hpp"
24 
25 namespace Cce::Actions {
26 
27 /// \cond
28 struct ReceiveNextElementTime;
29 /// \endcond
30 
31 /*!
32  * \ingroup ActionsGroup
33  * \brief If the element contains the first point in the interpolation
34  * collection, sends the next (full) `TimeStepId` to the
35  * `Metavariables::cce_boundary_component` to inform the boundary
36  * local-time-stepping interpolation/extrapolation.
37  *
38  * \details After checking the domain against the set of points for the
39  * interpolator, this sends the next step time if the current step is also a
40  * full step.
41  *
42  * Uses:
43  * - DataBox:
44  * - `Tags::TimeStepId`
45  * - `Tags::Next<Tags::TimeStepId>`
46  * - `Tags::TimeStepper<TimeStepper>`
47  *
48  * \ref DataBoxGroup changes:
49  * - Adds: nothing
50  * - Removes: nothing
51  * - Modifies: nothing
52  */
53 template <typename InterpolationTargetTag>
55  using const_global_cache_tags = tmpl::list<::Tags::TimeStepper<TimeStepper>>;
56  template <typename DbTags, typename Metavariables, typename... InboxTags,
57  typename ArrayIndex, typename ActionList,
58  typename ParallelComponent>
59  static std::tuple<db::DataBox<DbTags>&&> apply(
61  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
63  const ArrayIndex& array_index, const ActionList /*meta*/,
64  const ParallelComponent* const /*meta*/) noexcept {
65  const auto& block_logical_coords =
66  get<intrp::Vars::PointInfoTag<InterpolationTargetTag,
67  Metavariables::volume_dim>>(
68  db::get<intrp::Tags::InterpPointInfo<Metavariables>>(box));
70  {array_index}};
71  std::vector<boost::optional<IdPair<
72  domain::BlockId, tnsr::I<double, 3_st, typename ::Frame::Logical>>>>
73  first_valid_block_logical_coords;
74  for (const auto& coordinate : block_logical_coords) {
75  if (static_cast<bool>(coordinate)) {
76  first_valid_block_logical_coords.push_back(coordinate);
77  break;
78  }
79  }
80  if (first_valid_block_logical_coords.empty() ) {
82  "Warning: No valid block logical coordinates found, please ensure "
83  "that at least one point for the interpolation is within the domain "
84  "to use `SendNextTimeToCce`. No 'next' time is sent, but execution "
85  "will continue.\n");
86  }
87  const auto element_coord_holders = element_logical_coordinates(
88  element_ids, first_valid_block_logical_coords);
89 
90  if (UNLIKELY(db::get<::Tags::TimeStepId>(box).substep() == 0 and
91  element_coord_holders.count(element_ids[0]) != 0)) {
92  // find the next step time via the timestepper
93  auto next_step_id = db::get<::Tags::Next<::Tags::TimeStepId>>(box);
94  while (next_step_id.substep() != 0) {
95  next_step_id =
96  db::get<::Tags::TimeStepper<TimeStepper>>(box).next_time_id(
97  next_step_id, db::get<::Tags::TimeStep>(box));
98  }
99  auto& receiver_proxy = Parallel::get_parallel_component<
100  typename Metavariables::cce_boundary_component>(cache);
101  Parallel::simple_action<Actions::ReceiveNextElementTime>(
102  receiver_proxy, db::get<::Tags::TimeStepId>(box),
103  std::move(next_step_id));
104  }
105  return std::forward_as_tuple(std::move(box));
106  }
107 };
108 
109 /*!
110  * \ingroup ActionsGroup
111  * \brief Stash the `next_time` in the
112  * `Cce::InterfaceManagers::GhInterfaceManager` to inform the local
113  * time-stepping logic for boundary interpolation/extrapolation.
114  *
115  * \details If that information completes a set necessary for generating a
116  * requested step's data, then this also dispatches the data to
117  * `Cce::Actions::SendToEvolution` boundary computation.
118  *
119  * \ref DataBoxGroup changes:
120  * - Adds: nothing
121  * - Removes: nothing
122  * - Modifies:
123  * - `Tags::GhInterfaceManager`
124  */
126  template <typename ParallelComponent, typename... DbTags, typename ArrayIndex,
127  typename Metavariables>
128  static void apply(db::DataBox<tmpl::list<DbTags...>>& box,
130  const ArrayIndex& /*array_index*/, const TimeStepId& time,
131  const TimeStepId& next_time) noexcept {
132  if constexpr (tmpl::list_contains_v<tmpl::list<DbTags...>,
134  db::mutate<Tags::GhInterfaceManager>(
135  make_not_null(&box),
136  [&cache, &time,
137  &next_time](const gsl::not_null<
139  interface_manager) noexcept {
140  (*interface_manager)->insert_next_gh_time(time, next_time);
141  // if this information permits the evaluation of the next time, then
142  // immediately do the evaluation
143  const auto gh_data =
144  (*interface_manager)->retrieve_and_remove_first_ready_gh_data();
145  if (static_cast<bool>(gh_data)) {
151  get<0>(*gh_data), get<1>(*gh_data));
152  }
153  });
154  } else {
155  ERROR(
156  "Tags::GhInterfaceManager must be present in the DataBox to execute "
157  "simple action `ReceiveNextElementTime`.");
158  }
159  }
160 };
161 } // namespace Cce::Actions
UNLIKELY
#define UNLIKELY(x)
Definition: Gsl.hpp:73
get
constexpr Tag::type & get(Variables< TagList > &v) noexcept
Return Tag::type pointing into the contiguous array.
Definition: Variables.hpp:639
Parallel::GlobalCache
Definition: ElementReceiveInterpPoints.hpp:16
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:223
vector
Error.hpp
Parallel::printf
void printf(const std::string &format, Args &&... args)
Print an atomic message to stdout with C printf usage.
Definition: Printf.hpp:103
tuple
intrp::Vars::PointInfoTag
Definition: PointInfoTag.hpp:18
IdPair
A data structure that contains an ID and data associated with that ID.
Definition: IdPair.hpp:16
ERROR
#define ERROR(m)
prints an error message to the standard error stream and aborts the program.
Definition: Error.hpp:36
Printf.hpp
DataBox.hpp
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
Cce::Actions
The set of actions for use in the CCE evolution system.
Definition: BoundaryComputeAndSendToEvolution.hpp:29
TimeStepId
Definition: TimeStepId.hpp:25
TimeStepId.hpp
Cce::Actions::ReceiveNextElementTime
Stash the next_time in the Cce::InterfaceManagers::GhInterfaceManager to inform the local time-steppi...
Definition: SendNextTimeToCce.hpp:125
Cce::Tags::GhInterfaceManager
Definition: OptionTags.hpp:408
Cce::CharacteristicEvolution
The component for handling the CCE evolution and waveform output.
Definition: CharacteristicEvolution.hpp:91
Tensor.hpp
domain::BlockId
Index a block of the computational domain.
Definition: BlockId.hpp:21
Cce::Actions::SendToEvolution
Computes Bondi boundary data from GH evolution variables and sends the result to the EvolutionCompone...
Definition: BoundaryComputeAndSendToEvolution.hpp:60
Cce::GhWorldtubeBoundary
Component that supplies CCE worldtube boundary data sourced from a running GH system.
Definition: WorldtubeBoundary.hpp:106
Parallel::simple_action
void simple_action(Proxy &&proxy) noexcept
Invoke a simple action on proxy
Definition: Invoke.hpp:82
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::unique_ptr
db::DataBox
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
Cce::Actions::SendNextTimeToCce
If the element contains the first point in the interpolation collection, sends the next (full) TimeSt...
Definition: SendNextTimeToCce.hpp:54
element_logical_coordinates
auto element_logical_coordinates(const std::vector< ElementId< Dim >> &element_ids, const std::vector< boost::optional< IdPair< domain::BlockId, tnsr::I< double, Dim, typename Frame::Logical >>>> &block_coord_holders) noexcept -> std::unordered_map< ElementId< Dim >, ElementLogicalCoordHolder< Dim >>
gsl::not_null
Require a pointer to not be a nullptr
Definition: Gsl.hpp:183