InterpolateWithoutInterpComponent.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <pup.h>
8 
10 #include "Domain/ElementId.hpp"
11 #include "NumericalAlgorithms/Interpolation/Actions/InterpolationTargetVarsFromElement.hpp"
12 #include "NumericalAlgorithms/Interpolation/IrregularInterpolant.hpp"
13 #include "NumericalAlgorithms/Interpolation/PointInfoTag.hpp"
14 #include "Options/Options.hpp"
17 #include "Parallel/Invoke.hpp"
18 #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
19 #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
20 #include "Time/TimeStepId.hpp"
21 #include "Utilities/TMPL.hpp"
22 
23 /// \cond
24 namespace Tags {
25 struct TimeStepId;
26 } // namespace Tags
27 namespace domain {
28 namespace Tags {
29 template <size_t VolumeDim>
30 struct Mesh;
31 } // namespace Tags
32 } // namespace domain
33 namespace Tags {
34 template <typename TagsList>
35 struct Variables;
36 } // namespace Tags
37 template <size_t Dim>
38 class Mesh;
39 template <size_t VolumeDim>
40 class ElementId;
41 namespace intrp {
42 template <typename Metavariables, typename Tag>
43 struct InterpolationTarget;
44 namespace Registrars {
45 template <size_t VolumeDim, typename InterpolationTargetTag,
46  typename Metavariables, typename Tensors>
47 struct InterpolateWithoutInterpComponent;
48 } // namespace Registrars
49 namespace Events {
50 template <size_t VolumeDim, typename InterpolationTargetTag,
51  typename Metavariables, typename Tensors,
52  typename EventRegistrars =
53  tmpl::list<Registrars::InterpolateWithoutInterpComponent<
54  VolumeDim, InterpolationTargetTag, Metavariables, Tensors>>>
55 class InterpolateWithoutInterpComponent;
56 } // namespace Events
57 } // namespace intrp
58 /// \endcond
59 
60 namespace intrp {
61 
62 /// \cond
63 namespace Registrars {
64 template <size_t VolumeDim, typename InterpolationTargetTag,
65  typename Metavariables, typename Tensors>
66 struct InterpolateWithoutInterpComponent {
67  template <typename RegistrarList>
68  using f = Events::InterpolateWithoutInterpComponent<
69  VolumeDim, InterpolationTargetTag, Metavariables, Tensors, RegistrarList>;
70 };
71 } // namespace Registrars
72 /// \endcond
73 
74 namespace Events {
75 /// Does an interpolation onto an InterpolationTargetTag by calling Actions on
76 /// the InterpolationTarget component.
77 template <size_t VolumeDim, typename InterpolationTargetTag,
78  typename Metavariables, typename... Tensors, typename EventRegistrars>
79 class InterpolateWithoutInterpComponent<VolumeDim, InterpolationTargetTag,
80  Metavariables, tmpl::list<Tensors...>,
81  EventRegistrars>
82  : public Event<EventRegistrars> {
83  /// \cond
84  explicit InterpolateWithoutInterpComponent(
85  CkMigrateMessage* /*unused*/) noexcept {}
86  using PUP::able::register_constructor;
87  WRAPPED_PUPable_decl_template(InterpolateWithoutInterpComponent); // NOLINT
88  /// \endcond
89 
90  using options = tmpl::list<>;
91  static constexpr OptionString help =
92  "Does interpolation using the given InterpolationTargetTag, "
93  "without an Interpolator ParallelComponent.";
94 
95  static std::string name() noexcept {
96  return option_name<InterpolationTargetTag>();
97  }
98 
99  InterpolateWithoutInterpComponent() = default;
100 
101  using argument_tags =
102  tmpl::list<::Tags::TimeStepId, Tags::InterpPointInfo<Metavariables>,
103  domain::Tags::Mesh<VolumeDim>, Tensors...>;
104 
105  template <typename ParallelComponent>
106  void operator()(
107  const TimeStepId& time_id,
109  const Mesh<VolumeDim>& mesh,
110  const db::const_item_type<Tensors>&... tensors,
112  const ElementId<VolumeDim>& array_index,
113  const ParallelComponent* const /*meta*/) const noexcept {
114  // Get element logical coordinates of the target points.
115  const auto& block_logical_coords =
116  get<Vars::PointInfoTag<InterpolationTargetTag, VolumeDim>>(point_infos);
117  const std::vector<ElementId<VolumeDim>> element_ids{{array_index}};
118  const auto element_coord_holders =
119  element_logical_coordinates(element_ids, block_logical_coords);
120 
121  // There is exactly one element_id in the list of element_ids.
122  if (element_coord_holders.count(element_ids[0]) == 0) {
123  // There are no target points in this element, so we don't need
124  // to do anything.
125  return;
126  }
127 
128  // There are points in this element, so interpolate to them and
129  // send the interpolated data to the target. This is done
130  // in several steps:
131  const auto& element_coord_holder = element_coord_holders.at(element_ids[0]);
132 
133  // 1. Get the list of variables
134  Variables<typename InterpolationTargetTag::vars_to_interpolate_to_target>
135  interp_vars(mesh.number_of_grid_points());
136 
137  // Clang-tidy wants extra braces for `if constexpr`
138  if constexpr (std::is_same_v<tmpl::list<>, typename InterpolationTargetTag::
139  compute_items_on_source>) {
140  // 1.a Copy the tensors directly into the variables; no need to
141  // make a DataBox because we have no ComputeItems.
142  [[maybe_unused]] const auto copy_to_variables = [&interp_vars](
143  const auto tensor_tag_v, const auto& tensor) noexcept {
144  using tensor_tag = tmpl::type_from<decltype(tensor_tag_v)>;
145  get<tensor_tag>(interp_vars) = tensor;
146  return 0;
147  };
148  expand_pack(copy_to_variables(tmpl::type_<Tensors>{}, tensors)...);
149  } else {
150  // 1.b Make a DataBox and insert ComputeItems
151  const auto box = db::create<
152  db::AddSimpleTags<Tensors...>,
154  typename InterpolationTargetTag::compute_items_on_source>>(
155  tensors...);
156  // Copy vars_to_interpolate_to_target from databox to vars
157  tmpl::for_each<
158  typename InterpolationTargetTag::vars_to_interpolate_to_target>(
159  [&box, &interp_vars ](auto tag_v) noexcept {
160  using tag = typename decltype(tag_v)::type;
161  get<tag>(interp_vars) = db::get<tag>(box);
162  });
163  }
164 
165  // 2. Set up interpolator
166  intrp::Irregular<VolumeDim> interpolator(
167  mesh, element_coord_holder.element_logical_coords);
168 
169  // 3. Interpolate and send interpolated data to target
170  auto& receiver_proxy = Parallel::get_parallel_component<
174  receiver_proxy,
175  std::vector<Variables<
176  typename InterpolationTargetTag::vars_to_interpolate_to_target>>(
177  {interpolator.interpolate(interp_vars)}),
178  std::vector<std::vector<size_t>>({element_coord_holder.offsets}),
179  time_id);
180  }
181 };
182 
183 /// \cond
184 template <size_t VolumeDim, typename InterpolationTargetTag,
185  typename Metavariables, typename... Tensors, typename EventRegistrars>
186 PUP::able::PUP_ID InterpolateWithoutInterpComponent<
187  VolumeDim, InterpolationTargetTag, Metavariables, tmpl::list<Tensors...>,
188  EventRegistrars>::my_PUP_ID = 0; // NOLINT
189 /// \endcond
190 
191 } // namespace Events
192 } // namespace intrp
Parallel::ConstGlobalCache
Definition: ElementReceiveInterpPoints.hpp:16
expand_pack
constexpr void expand_pack(Ts &&...) noexcept
Allows zero-cost unordered expansion of a parameter.
Definition: TMPL.hpp:546
intrp::Tags::InterpPointInfo
The following tag is for the case in which interpolation bypasses the Interpolator ParallelComponent....
Definition: PointInfoTag.hpp:44
std::string
DataBoxTag.hpp
CharmPupable.hpp
intrp::Irregular
Definition: IrregularInterpolant.hpp:30
Options.hpp
std::vector
db::AddComputeTags
tmpl::flatten< tmpl::list< Tags... > > AddComputeTags
List of Compute Item Tags to add to the DataBox.
Definition: DataBox.hpp:1171
domain::Tags::Mesh
The computational grid of the Element in the DataBox.
Definition: Tags.hpp:106
intrp::Irregular::interpolate
void interpolate(gsl::not_null< Variables< TagsList > * > result, const Variables< TagsList > &vars) const noexcept
Performs the interpolation on a Variables with grid points corresponding to the Mesh<Dim> specified i...
ElementId
An ElementId uniquely labels an Element.
Definition: ElementId.hpp:49
ElementId.hpp
db::create
constexpr auto create(Args &&... args)
Create a new DataBox.
Definition: DataBox.hpp:1196
intrp::Actions::InterpolationTargetVarsFromElement
Receives interpolated variables from an Element on a subset of the target points.
Definition: InterpolationTargetVarsFromElement.hpp:61
WRAPPED_PUPable_decl_template
#define WRAPPED_PUPable_decl_template(className)
Mark derived classes as serializable.
Definition: CharmPupable.hpp:22
Event
Definition: Event.hpp:30
cstddef
db::item_type
typename DataBox_detail::item_type_impl< TagList, Tag >::type item_type
Get the type that can be written to the Tag. If it is a base tag then a TagList must be passed as a s...
Definition: DataBoxTag.hpp:246
Mesh::number_of_grid_points
size_t number_of_grid_points() const noexcept
The total number of grid points in all dimensions.
Definition: Mesh.hpp:130
TimeStepId
Definition: TimeStepId.hpp:25
std::decay_t
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:50
TimeStepId.hpp
db::AddSimpleTags
tmpl::flatten< tmpl::list< Tags... > > AddSimpleTags
List of Tags to add to the DataBox.
Definition: DataBox.hpp:1150
Parallel::get_parallel_component
auto get_parallel_component(ConstGlobalCache< Metavariables > &cache) noexcept -> Parallel::proxy_from_parallel_component< ConstGlobalCache_detail::get_component_if_mocked< typename Metavariables::component_list, ParallelComponentTag >> &
Access the Charm++ proxy associated with a ParallelComponent.
Definition: ConstGlobalCache.hpp:223
Parallel::simple_action
void simple_action(Proxy &&proxy) noexcept
Invoke a simple action on proxy
Definition: Invoke.hpp:111
OptionString
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:30
TMPL.hpp
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 >>
ConstGlobalCache.hpp
intrp::InterpolationTarget
ParallelComponent representing a set of points to be interpolated to and a function to call upon inte...
Definition: InterpolationTarget.hpp:111