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"
16 #include "Parallel/GlobalCache.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 intrp
45 /// \endcond
46 
47 namespace intrp {
48 namespace Events {
49 /// \cond
50 template <size_t VolumeDim, typename InterpolationTargetTag,
51  typename Metavariables, typename Tensors>
52 class InterpolateWithoutInterpComponent;
53 /// \endcond
54 
55 /// Does an interpolation onto an InterpolationTargetTag by calling Actions on
56 /// the InterpolationTarget component.
57 template <size_t VolumeDim, typename InterpolationTargetTag,
58  typename Metavariables, typename... Tensors>
59 class InterpolateWithoutInterpComponent<VolumeDim, InterpolationTargetTag,
60  Metavariables, tmpl::list<Tensors...>>
61  : public Event {
62  /// \cond
63  explicit InterpolateWithoutInterpComponent(
64  CkMigrateMessage* /*unused*/) noexcept {}
65  using PUP::able::register_constructor;
66  WRAPPED_PUPable_decl_template(InterpolateWithoutInterpComponent); // NOLINT
67  /// \endcond
68 
69  using options = tmpl::list<>;
70  static constexpr Options::String help =
71  "Does interpolation using the given InterpolationTargetTag, "
72  "without an Interpolator ParallelComponent.";
73 
74  static std::string name() noexcept {
75  return Options::name<InterpolationTargetTag>();
76  }
77 
78  InterpolateWithoutInterpComponent() = default;
79 
80  using argument_tags =
81  tmpl::list<::Tags::TimeStepId, Tags::InterpPointInfo<Metavariables>,
82  domain::Tags::Mesh<VolumeDim>, Tensors...>;
83 
84  template <typename ParallelComponent>
85  void operator()(
86  const TimeStepId& time_id,
87  const typename Tags::InterpPointInfo<Metavariables>::type& point_infos,
88  const Mesh<VolumeDim>& mesh, const typename Tensors::type&... tensors,
90  const ElementId<VolumeDim>& array_index,
91  const ParallelComponent* const /*meta*/) const noexcept {
92  // Get element logical coordinates of the target points.
93  const auto& block_logical_coords =
94  get<Vars::PointInfoTag<InterpolationTargetTag, VolumeDim>>(point_infos);
95  const std::vector<ElementId<VolumeDim>> element_ids{{array_index}};
96  const auto element_coord_holders =
97  element_logical_coordinates(element_ids, block_logical_coords);
98 
99  // There is exactly one element_id in the list of element_ids.
100  if (element_coord_holders.count(element_ids[0]) == 0) {
101  // There are no target points in this element, so we don't need
102  // to do anything.
103  return;
104  }
105 
106  // There are points in this element, so interpolate to them and
107  // send the interpolated data to the target. This is done
108  // in several steps:
109  const auto& element_coord_holder = element_coord_holders.at(element_ids[0]);
110 
111  // 1. Get the list of variables
112  Variables<typename InterpolationTargetTag::vars_to_interpolate_to_target>
113  interp_vars(mesh.number_of_grid_points());
114 
115  // Clang-tidy wants extra braces for `if constexpr`
116  if constexpr (std::is_same_v<tmpl::list<>, typename InterpolationTargetTag::
117  compute_items_on_source>) {
118  // 1.a Copy the tensors directly into the variables; no need to
119  // make a DataBox because we have no ComputeItems.
120  [[maybe_unused]] const auto copy_to_variables = [&interp_vars](
121  const auto tensor_tag_v, const auto& tensor) noexcept {
122  using tensor_tag = tmpl::type_from<decltype(tensor_tag_v)>;
123  get<tensor_tag>(interp_vars) = tensor;
124  return 0;
125  };
126  expand_pack(copy_to_variables(tmpl::type_<Tensors>{}, tensors)...);
127  } else {
128  // 1.b Make a DataBox and insert ComputeItems
129  const auto box = db::create<
130  db::AddSimpleTags<Tensors...>,
132  typename InterpolationTargetTag::compute_items_on_source>>(
133  tensors...);
134  // Copy vars_to_interpolate_to_target from databox to vars
135  tmpl::for_each<
136  typename InterpolationTargetTag::vars_to_interpolate_to_target>(
137  [&box, &interp_vars ](auto tag_v) noexcept {
138  using tag = typename decltype(tag_v)::type;
139  get<tag>(interp_vars) = db::get<tag>(box);
140  });
141  }
142 
143  // 2. Set up interpolator
144  intrp::Irregular<VolumeDim> interpolator(
145  mesh, element_coord_holder.element_logical_coords);
146 
147  // 3. Interpolate and send interpolated data to target
148  auto& receiver_proxy = Parallel::get_parallel_component<
152  receiver_proxy,
153  std::vector<Variables<
154  typename InterpolationTargetTag::vars_to_interpolate_to_target>>(
155  {interpolator.interpolate(interp_vars)}),
156  std::vector<std::vector<size_t>>({element_coord_holder.offsets}),
157  time_id);
158  }
159 
160  bool needs_evolved_variables() const noexcept override { return true; }
161 };
162 
163 /// \cond
164 template <size_t VolumeDim, typename InterpolationTargetTag,
165  typename Metavariables, typename... Tensors>
166 PUP::able::PUP_ID InterpolateWithoutInterpComponent<
167  VolumeDim, InterpolationTargetTag, Metavariables,
168  tmpl::list<Tensors...>>::my_PUP_ID = 0; // NOLINT
169 /// \endcond
170 
171 } // namespace Events
172 } // namespace intrp
expand_pack
constexpr void expand_pack(Ts &&...) noexcept
Allows zero-cost unordered expansion of a parameter.
Definition: TMPL.hpp:585
std::string
CharmPupable.hpp
intrp::Irregular
Definition: IrregularInterpolant.hpp:30
Parallel::GlobalCache
Definition: ElementReceiveInterpPoints.hpp:15
GlobalCache.hpp
Options.hpp
intrp
Contains classes and functions for interpolation.
Definition: ElementInitInterpPoints.hpp:23
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
std::vector
db::AddComputeTags
tmpl::flatten< tmpl::list< Tags... > > AddComputeTags
List of Compute Item Tags to add to the DataBox.
Definition: DataBox.hpp:863
domain::Tags::Mesh
The computational grid of the Element in the DataBox.
Definition: Tags.hpp:107
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:51
ElementId.hpp
db::create
constexpr auto create(Args &&... args)
Create a new DataBox.
Definition: DataBox.hpp:907
intrp::Actions::InterpolationTargetVarsFromElement
Receives interpolated variables from an Element on a subset of the target points.
Definition: InterpolationTargetVarsFromElement.hpp:60
WRAPPED_PUPable_decl_template
#define WRAPPED_PUPable_decl_template(className)
Mark derived classes as serializable.
Definition: CharmPupable.hpp:22
Event
Definition: Event.hpp:19
DataBox.hpp
cstddef
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 >>
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:49
TimeStepId.hpp
db::AddSimpleTags
tmpl::flatten< tmpl::list< Tags... > > AddSimpleTags
List of Tags to add to the DataBox.
Definition: DataBox.hpp:856
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
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
Parallel::simple_action
void simple_action(Proxy &&proxy) noexcept
Invoke a simple action on proxy
Definition: Invoke.hpp:62
TMPL.hpp
intrp::InterpolationTarget
ParallelComponent representing a set of points to be interpolated to and a function to call upon inte...
Definition: InterpolationTarget.hpp:347