TryToInterpolate.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
9 #include "Domain/ElementLogicalCoordinates.hpp"
10 #include "Domain/Tags.hpp"
11 #include "NumericalAlgorithms/Interpolation/IrregularInterpolant.hpp"
12 #include "NumericalAlgorithms/Interpolation/Tags.hpp"
14 #include "Parallel/Invoke.hpp"
15 #include "Utilities/Gsl.hpp"
16 #include "Utilities/TMPL.hpp"
18 
19 /// \cond
20 namespace intrp {
21 template <typename Metavariables, typename InterpolationTargetTag>
22 struct InterpolationTarget;
23 namespace Actions {
24 template <typename InterpolationTargetTag>
25 struct InterpolationTargetReceiveVars;
26 } // namespace Actions
27 } // namespace intrp
28 /// \endcond
29 
30 namespace intrp {
31 
32 namespace interpolator_detail {
33 
34 // Interpolates data onto a set of points desired by an InterpolationTarget.
35 template <typename InterpolationTargetTag, typename Metavariables,
36  typename DbTags>
37 void interpolate_data(
39  const typename Metavariables::temporal_id::type& temporal_id) noexcept {
40  db::mutate_apply<tmpl::list<Tags::InterpolatedVarsHolders<Metavariables>>,
41  tmpl::list<Tags::VolumeVarsInfo<Metavariables>>>(
42  [&temporal_id](
43  const gsl::not_null<
45  holders,
47  volume_vars_info) noexcept {
48  auto& interp_info =
49  get<Vars::HolderTag<InterpolationTargetTag, Metavariables>>(
50  *holders)
51  .infos.at(temporal_id);
52 
53  for (const auto& volume_info_outer : volume_vars_info) {
54  // Are we at the right time?
55  if (volume_info_outer.first != temporal_id) {
56  continue;
57  }
58 
59  // Get list of ElementIds that have the correct temporal_id and that
60  // have not yet been interpolated.
63  element_ids;
64 
65  for (const auto& volume_info_inner : volume_info_outer.second) {
66  // Have we interpolated this element before?
67  if (interp_info.interpolation_is_done_for_these_elements.find(
68  volume_info_inner.first) ==
69  interp_info.interpolation_is_done_for_these_elements.end()) {
70  interp_info.interpolation_is_done_for_these_elements.emplace(
71  volume_info_inner.first);
72  element_ids.push_back(volume_info_inner.first);
73  }
74  }
75 
76  // Get element logical coordinates.
77  const auto element_coord_holders = element_logical_coordinates(
78  element_ids, interp_info.block_coord_holders);
79 
80  // Construct local vars and interpolate.
81  for (const auto& element_coord_pair : element_coord_holders) {
82  const auto& element_id = element_coord_pair.first;
83  const auto& element_coord_holder = element_coord_pair.second;
84  const auto& volume_info = volume_info_outer.second.at(element_id);
85 
86  // Construct local_vars which is some set of variables
87  // derived from volume_info.vars plus an arbitrary set
88  // of compute items in
89  // InterpolationTargetTag::compute_items_on_source.
90 
91  auto new_box = db::create<
93  typename Metavariables::interpolator_source_vars>>,
95  typename InterpolationTargetTag::compute_items_on_source>>(
96  volume_info.vars);
97 
98  Variables<
99  typename InterpolationTargetTag::vars_to_interpolate_to_target>
100  local_vars(volume_info.mesh.number_of_grid_points());
101 
102  tmpl::for_each<
103  typename InterpolationTargetTag::vars_to_interpolate_to_target>(
104  [&new_box, &local_vars](auto x) noexcept {
105  using tag = typename decltype(x)::type;
106  get<tag>(local_vars) = db::get<tag>(new_box);
107  });
108 
109  // Now interpolate.
111  interpolator(volume_info.mesh,
112  element_coord_holder.element_logical_coords);
113  interp_info.vars.emplace_back(interpolator.interpolate(local_vars));
114  interp_info.global_offsets.emplace_back(
115  element_coord_holder.offsets);
116  }
117  }
118  },
119  box);
120 }
121 } // namespace interpolator_detail
122 
123 /// Check if we have enough information to interpolate. If so, do the
124 /// interpolation and send data to the InterpolationTarget.
125 template <typename InterpolationTargetTag, typename Metavariables,
126  typename DbTags>
127 void try_to_interpolate(
130  const typename Metavariables::temporal_id::type& temporal_id) noexcept {
131  const auto& holders =
132  db::get<Tags::InterpolatedVarsHolders<Metavariables>>(*box);
133  const auto& vars_infos =
134  get<Vars::HolderTag<InterpolationTargetTag, Metavariables>>(holders)
135  .infos;
136 
137  // If we don't yet have any points for this InterpolationTarget at
138  // this temporal_id, we should exit (we can't interpolate anyway).
139  if (vars_infos.count(temporal_id) == 0) {
140  return;
141  }
142 
143  interpolator_detail::interpolate_data<InterpolationTargetTag, Metavariables>(
144  box, temporal_id);
145 
146  // Send interpolated data only if interpolation has been done on all
147  // of the local elements.
148  const auto& num_elements = db::get<Tags::NumberOfElements>(*box);
149  if (vars_infos.at(temporal_id)
150  .interpolation_is_done_for_these_elements.size() == num_elements) {
151  // Send data to InterpolationTarget, but only if the list of points is
152  // non-empty.
153  if (not vars_infos.at(temporal_id).global_offsets.empty()) {
154  const auto& info = vars_infos.at(temporal_id);
155  auto& receiver_proxy = Parallel::get_parallel_component<
156  InterpolationTarget<Metavariables, InterpolationTargetTag>>(*cache);
158  Actions::InterpolationTargetReceiveVars<InterpolationTargetTag>>(
159  receiver_proxy, info.vars, info.global_offsets);
160  }
161 
162  // Clear interpolated data, since we don't need it anymore.
163  db::mutate<Tags::InterpolatedVarsHolders<Metavariables>>(
164  box, [&temporal_id](const gsl::not_null<db::item_type<
165  Tags::InterpolatedVarsHolders<Metavariables>>*>
166  holders_l) noexcept {
167  get<Vars::HolderTag<InterpolationTargetTag, Metavariables>>(
168  *holders_l)
169  .infos.erase(temporal_id);
170  });
171  }
172 }
173 
174 } // namespace intrp
Definition: Variables.hpp:46
Defines class tuples::TaggedTuple.
auto element_logical_coordinates(const std::vector< ElementId< Dim >> &element_ids, const std::vector< IdPair< domain::BlockId, tnsr::I< double, Dim, typename Frame::Logical >>> &block_coord_holders) noexcept -> std::unordered_map< ElementId< Dim >, ElementLogicalCoordHolder< Dim >>
Given a set of points in block logical coordinates and their BlockIds, as returned from the function ...
Definition: AddTemporalIdsToInterpolationTarget.hpp:17
An ElementId uniquely labels an Element. It is constructed from the BlockId of the Block to which the...
Definition: ElementId.hpp:36
constexpr auto create(Args &&... args)
Create a new DataBox.
Definition: DataBox.hpp:1259
Interpolates a Variables onto an arbitrary set of points.
Definition: IrregularInterpolant.hpp:30
Defines classes and functions used for manipulating DataBox&#39;s.
tmpl::flatten< tmpl::list< Tags... > > AddSimpleTags
List of Tags to add to the DataBox.
Definition: DataBox.hpp:1227
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
Defines class Variables.
A Charm++ chare that caches constant data once per Charm++ node.
Definition: ConstGlobalCache.hpp:76
Wraps the template metaprogramming library used (brigand)
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:163
typename DataBox_detail::item_type_impl< TagList, Tag >::type item_type
Get the type that is returned by the Tag. If it is a base tag then a TagList must be passed as a seco...
Definition: DataBoxTag.hpp:410
Defines functions and classes from the GSL.
Defines tags related to domain quantities.
void simple_action(Proxy &&proxy) noexcept
Invoke a simple action on proxy
Definition: Invoke.hpp:112
Identifies a step in the linear solver algorithm.
Definition: IterationId.hpp:25
Definition: SolvePoissonProblem.hpp:38
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
Defines class template ConstGlobalCache.
Definition: ComputeTimeDerivative.hpp:28
Require a pointer to not be a nullptr
Definition: ConservativeFromPrimitive.hpp:12
tmpl::flatten< tmpl::list< Tags... > > AddComputeTags
List of Compute Item Tags to add to the DataBox.
Definition: DataBox.hpp:1234