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 
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, const typename Tensors::type&... tensors,
111  const ElementId<VolumeDim>& array_index,
112  const ParallelComponent* const /*meta*/) const noexcept {
113  // Get element logical coordinates of the target points.
114  const auto& block_logical_coords =
115  get<Vars::PointInfoTag<InterpolationTargetTag, VolumeDim>>(point_infos);
116  const std::vector<ElementId<VolumeDim>> element_ids{{array_index}};
117  const auto element_coord_holders =
118  element_logical_coordinates(element_ids, block_logical_coords);
119 
120  // There is exactly one element_id in the list of element_ids.
121  if (element_coord_holders.count(element_ids[0]) == 0) {
122  // There are no target points in this element, so we don't need
123  // to do anything.
124  return;
125  }
126 
127  // There are points in this element, so interpolate to them and
128  // send the interpolated data to the target. This is done
129  // in several steps:
130  const auto& element_coord_holder = element_coord_holders.at(element_ids[0]);
131 
132  // 1. Get the list of variables
133  Variables<typename InterpolationTargetTag::vars_to_interpolate_to_target>
134  interp_vars(mesh.number_of_grid_points());
135 
136  // Clang-tidy wants extra braces for `if constexpr`
137  if constexpr (std::is_same_v<tmpl::list<>, typename InterpolationTargetTag::
138  compute_items_on_source>) {
139  // 1.a Copy the tensors directly into the variables; no need to
140  // make a DataBox because we have no ComputeItems.
141  [[maybe_unused]] const auto copy_to_variables = [&interp_vars](
142  const auto tensor_tag_v, const auto& tensor) noexcept {
143  using tensor_tag = tmpl::type_from<decltype(tensor_tag_v)>;
144  get<tensor_tag>(interp_vars) = tensor;
145  return 0;
146  };
147  expand_pack(copy_to_variables(tmpl::type_<Tensors>{}, tensors)...);
148  } else {
149  // 1.b Make a DataBox and insert ComputeItems
150  const auto box = db::create<
151  db::AddSimpleTags<Tensors...>,
153  typename InterpolationTargetTag::compute_items_on_source>>(
154  tensors...);
155  // Copy vars_to_interpolate_to_target from databox to vars
156  tmpl::for_each<
157  typename InterpolationTargetTag::vars_to_interpolate_to_target>(
158  [&box, &interp_vars ](auto tag_v) noexcept {
159  using tag = typename decltype(tag_v)::type;
160  get<tag>(interp_vars) = db::get<tag>(box);
161  });
162  }
163 
164  // 2. Set up interpolator
165  intrp::Irregular<VolumeDim> interpolator(
166  mesh, element_coord_holder.element_logical_coords);
167 
168  // 3. Interpolate and send interpolated data to target
169  auto& receiver_proxy = Parallel::get_parallel_component<
173  receiver_proxy,
174  std::vector<Variables<
175  typename InterpolationTargetTag::vars_to_interpolate_to_target>>(
176  {interpolator.interpolate(interp_vars)}),
177  std::vector<std::vector<size_t>>({element_coord_holder.offsets}),
178  time_id);
179  }
180 };
181 
182 /// \cond
183 template <size_t VolumeDim, typename InterpolationTargetTag,
184  typename Metavariables, typename... Tensors, typename EventRegistrars>
185 PUP::able::PUP_ID InterpolateWithoutInterpComponent<
186  VolumeDim, InterpolationTargetTag, Metavariables, tmpl::list<Tensors...>,
187  EventRegistrars>::my_PUP_ID = 0; // NOLINT
188 /// \endcond
189 
190 } // namespace Events
191 } // 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:547
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
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