InterpolateToTarget.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 
10 #include "Domain/Tags.hpp"
11 #include "NumericalAlgorithms/Interpolation/Actions/InterpolationTargetVarsFromElement.hpp"
12 #include "NumericalAlgorithms/Interpolation/InterpolationTarget.hpp"
13 #include "NumericalAlgorithms/Interpolation/IrregularInterpolant.hpp"
14 #include "NumericalAlgorithms/Interpolation/PointInfoTag.hpp"
16 #include "Parallel/Invoke.hpp"
17 #include "Utilities/TMPL.hpp"
18 
19 /// \cond
20 namespace tuples {
21 template <typename... Tags>
22 class TaggedTuple;
23 } // namespace tuples
24 /// \endcond
25 
26 namespace intrp {
27 namespace Actions {
28 
29 /// \ingroup ActionsGroup
30 /// \brief Interpolates and sends points to an InterpolationTarget.
31 ///
32 /// This is invoked on DgElementArray.
33 ///
34 /// Uses:
35 /// - DataBox:
36 /// - `intrp::Tags::InterpPointInfo<Metavariables>`
37 /// - `Tags::Mesh<Metavariables::volume_dim>`
38 /// - Variables tagged by
39 /// InterpolationTargetTag::vars_to_interpolate_to_target
40 ///
41 /// DataBox changes:
42 /// - Adds: nothing
43 /// - Removes: nothing
44 /// - Modifies: nothing
45 template <typename InterpolationTargetTag>
47  template <typename DbTags, typename Metavariables, typename... InboxTags,
48  typename ArrayIndex, typename ActionList,
49  typename ParallelComponent>
50  static std::tuple<db::DataBox<DbTags>&&> apply(
52  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
54  const ArrayIndex& array_index, const ActionList /*meta*/,
55  const ParallelComponent* const /*meta*/) noexcept {
56  static constexpr size_t dim = Metavariables::volume_dim;
57 
58  // Get element logical coordinates.
59  const auto& block_logical_coords =
60  get<Vars::PointInfoTag<InterpolationTargetTag, dim>>(
61  db::get<Tags::InterpPointInfo<Metavariables>>(box));
62  const std::vector<ElementId<dim>> element_ids{{array_index}};
63  const auto element_coord_holders =
64  element_logical_coordinates(element_ids, block_logical_coords);
65 
66  // There is exactly one element_id in the list of element_ids.
67  if (element_coord_holders.count(element_ids[0]) == 0) {
68  // There are no points in this element, so we don't need
69  // to do anything.
70  return std::forward_as_tuple(std::move(box));
71  }
72 
73  // There are points in this element, so interpolate to them and
74  // send the interpolated data to the target. This is done
75  // in several steps:
76  const auto& element_coord_holder = element_coord_holders.at(element_ids[0]);
77 
78  using compute_items_in_new_box = tmpl::list_difference<
79  typename InterpolationTargetTag::compute_items_on_source, DbTags>;
80 
81  // 1. Create a new DataBox that contains
82  // InterpolationTargetTag::compute_items_on_source
83  auto new_box =
84  db::create_from<db::RemoveTags<>, db::AddSimpleTags<>,
86  std::move(box));
87 
88  // 2. Set up local variables to hold vars_to_interpolate and fill it
89  const auto& mesh = db::get<domain::Tags::Mesh<dim>>(new_box);
90  Variables<typename InterpolationTargetTag::vars_to_interpolate_to_target>
91  local_vars(mesh.number_of_grid_points());
92 
93  tmpl::for_each<
94  typename InterpolationTargetTag::vars_to_interpolate_to_target>(
95  [&new_box, &local_vars ](auto tag_v) noexcept {
96  using tag = typename decltype(tag_v)::type;
97  get<tag>(local_vars) = db::get<tag>(new_box);
98  });
99 
100  // 3. Set up interpolator
101  intrp::Irregular<dim> interpolator(
102  mesh, element_coord_holder.element_logical_coords);
103 
104  // 4. Interpolate and send interpolated data to target
105  auto& receiver_proxy = Parallel::get_parallel_component<
109  receiver_proxy,
110  std::vector<Variables<
111  typename InterpolationTargetTag::vars_to_interpolate_to_target>>(
112  {interpolator.interpolate(local_vars)}),
113  std::vector<std::vector<size_t>>({element_coord_holder.offsets}),
114  db::get<typename Metavariables::temporal_id>(new_box));
115 
116  // 5. Put back original DataBox.
117  box = db::create_from<db::RemoveTags<compute_items_in_new_box>,
118  db::AddSimpleTags<>>(std::move(new_box));
119 
120  return std::forward_as_tuple(std::move(box));
121  }
122 };
123 } // namespace Actions
124 } // namespace intrp
Parallel::ConstGlobalCache
Definition: ElementReceiveInterpPoints.hpp:16
DataBoxTag.hpp
intrp::Irregular
Definition: IrregularInterpolant.hpp:30
intrp::Actions::InterpolateToTarget
Interpolates and sends points to an InterpolationTarget.
Definition: InterpolateToTarget.hpp:46
Tags.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
std::tuple
intrp::Actions::InterpolationTargetVarsFromElement
Receives interpolated variables from an Element on a subset of the target points.
Definition: InterpolationTargetVarsFromElement.hpp:61
DataBox.hpp
cstddef
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
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
db::DataBox
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
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