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 "Evolution/Systems/Cce/Actions/BoundaryComputeAndSendToEvolution.hpp"
14 #include "Evolution/Systems/Cce/Components/CharacteristicEvolution.hpp"
15 #include "Evolution/Systems/Cce/OptionTags.hpp"
16 #include "Evolution/Systems/Cce/Tags.hpp"
17 #include "NumericalAlgorithms/Interpolation/PointInfoTag.hpp"
18 #include "Parallel/GlobalCache.hpp"
19 #include "Parallel/Invoke.hpp"
20 #include "Parallel/Printf.hpp"
21 #include "Time/Tags.hpp"
22 #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  template <typename DbTags, typename Metavariables, typename... InboxTags,
56  typename ArrayIndex, typename ActionList,
57  typename ParallelComponent>
58  static std::tuple<db::DataBox<DbTags>&&> apply(
59  db::DataBox<DbTags>& box,
60  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
62  const ArrayIndex& array_index, const ActionList /*meta*/,
63  const ParallelComponent* const /*meta*/) noexcept {
64  const auto& block_logical_coords =
65  get<intrp::Vars::PointInfoTag<InterpolationTargetTag,
66  Metavariables::volume_dim>>(
67  db::get<intrp::Tags::InterpPointInfo<Metavariables>>(box));
69  {array_index}};
71  domain::BlockId, tnsr::I<double, 3_st, typename ::Frame::Logical>>>>
72  first_valid_block_logical_coords;
73  for (const auto& coordinate : block_logical_coords) {
74  if (coordinate.has_value()) {
75  first_valid_block_logical_coords.push_back(coordinate);
76  break;
77  }
78  }
79  if (first_valid_block_logical_coords.empty() ) {
81  "Warning: No valid block logical coordinates found, please ensure "
82  "that at least one point for the interpolation is within the domain "
83  "to use `SendNextTimeToCce`. No 'next' time is sent, but execution "
84  "will continue.\n");
85  }
86  const auto element_coord_holders = element_logical_coordinates(
87  element_ids, first_valid_block_logical_coords);
88 
89  if (UNLIKELY(db::get<::Tags::TimeStepId>(box).substep() == 0 and
90  element_coord_holders.count(element_ids[0]) != 0)) {
91  // find the next step time via the timestepper
92  auto next_step_id = db::get<::Tags::Next<::Tags::TimeStepId>>(box);
93  while (next_step_id.substep() != 0) {
94  next_step_id =
95  db::get<::Tags::TimeStepper<TimeStepper>>(box).next_time_id(
96  next_step_id, db::get<::Tags::TimeStep>(box));
97  }
98  auto& receiver_proxy = Parallel::get_parallel_component<
99  typename Metavariables::cce_boundary_component>(cache);
100  Parallel::simple_action<Actions::ReceiveNextElementTime>(
101  receiver_proxy, db::get<::Tags::TimeStepId>(box),
102  std::move(next_step_id));
103  }
104  return std::forward_as_tuple(std::move(box));
105  }
106 };
107 
108 /*!
109  * \ingroup ActionsGroup
110  * \brief Stash the `next_time` in the
111  * `Cce::InterfaceManagers::GhInterfaceManager` to inform the local
112  * time-stepping logic for boundary interpolation/extrapolation.
113  *
114  * \details If that information completes a set necessary for generating a
115  * requested step's data, then this also dispatches the data to
116  * `Cce::Actions::SendToEvolution` boundary computation.
117  *
118  * \ref DataBoxGroup changes:
119  * - Adds: nothing
120  * - Removes: nothing
121  * - Modifies:
122  * - `Tags::GhInterfaceManager`
123  */
125  template <typename ParallelComponent, typename... DbTags, typename ArrayIndex,
126  typename Metavariables>
127  static void apply(db::DataBox<tmpl::list<DbTags...>>& box,
129  const ArrayIndex& /*array_index*/, const TimeStepId& time,
130  const TimeStepId& next_time) noexcept {
131  if constexpr (tmpl::list_contains_v<tmpl::list<DbTags...>,
133  db::mutate<Tags::GhInterfaceManager>(
134  make_not_null(&box),
135  [&cache, &time,
136  &next_time](const gsl::not_null<
138  interface_manager) noexcept {
139  (*interface_manager)->insert_next_gh_time(time, next_time);
140  // if this information permits the evaluation of the next time, then
141  // immediately do the evaluation
142  const auto gh_data =
143  (*interface_manager)->retrieve_and_remove_first_ready_gh_data();
144  if (static_cast<bool>(gh_data)) {
150  get<0>(*gh_data), get<1>(*gh_data));
151  }
152  });
153  } else {
154  ERROR(
155  "Tags::GhInterfaceManager must be present in the DataBox to execute "
156  "simple action `ReceiveNextElementTime`.");
157  }
158  }
159 };
160 } // namespace Cce::Actions
UNLIKELY
#define UNLIKELY(x)
Definition: Gsl.hpp:73
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
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
db::get
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:791
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:37
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:31
TimeStepId
Definition: TimeStepId.hpp:25
element_logical_coordinates
auto element_logical_coordinates(const std::vector< ElementId< Dim >> &element_ids, const std::vector< std::optional< IdPair< domain::BlockId, tnsr::I< double, Dim, typename Frame::Logical >>>> &block_coord_holders) noexcept -> std::unordered_map< ElementId< Dim >, ElementLogicalCoordHolder< Dim >>
TimeStepId.hpp
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
Cce::Actions::ReceiveNextElementTime
Stash the next_time in the Cce::InterfaceManagers::GhInterfaceManager to inform the local time-steppi...
Definition: SendNextTimeToCce.hpp:124
Cce::Tags::GhInterfaceManager
Definition: OptionTags.hpp:483
Cce::CharacteristicEvolution
The component for handling the CCE evolution and waveform output.
Definition: CharacteristicEvolution.hpp:98
Tensor.hpp
domain::BlockId
Index a block of the computational domain.
Definition: BlockId.hpp:21
std::optional
Cce::Actions::SendToEvolution
Computes Bondi boundary data from GH evolution variables and sends the result to the EvolutionCompone...
Definition: BoundaryComputeAndSendToEvolution.hpp:62
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
std::unique_ptr
Cce::Actions::SendNextTimeToCce
If the element contains the first point in the interpolation collection, sends the next (full) TimeSt...
Definition: SendNextTimeToCce.hpp:54
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecPiecewisePolynomial.hpp:13