1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
4 #pragma once
6 #include <cstddef>
7 #include <unordered_map>
8 #include <vector>
12 /// \cond
13 namespace domain {
14 class BlockId;
15 } // namespace domain
16 class DataVector;
17 template <size_t VolumeDim>
18 class ElementId;
19 template <typename IdType, typename DataType>
20 class IdPair;
21 /// \endcond
23 /// \ingroup ComputationalDomainGroup
24 ///
25 /// Holds element logical coordinates of an arbitrary set of points on
26 /// a single `Element`. The arbitrary set of points is assumed to be
27 /// a subset of a larger set of points spanning multiple `Element`s,
28 /// and this class holds `offsets` that index into that larger set of
29 /// points.
30 ///
31 /// \details `offsets.size()` is the same as the size of the `DataVector`
32 /// inside `element_logical_coords`.
33 ///
34 /// This is used during the process of interpolating volume quantities
35 /// on the `Elements` (e.g. the spatial metric) onto an arbitrary set
36 /// of points (e.g. the points on an apparent horizon or a
37 /// wave-extraction surface) expressed in some frame. Here is an
38 /// outline of how this interpolation proceeds, and where
39 /// `element_logical_coordinates` and `block_logical_coordinates` fit
40 /// into the picture:
41 ///
42 /// Assume some component (e.g. HorizonA) has a `Tensor<DataVector>`
43 /// of target coordinate points in some coordinate frame. The goal is
44 /// to determine the `Element` and logical coordinates of each point,
45 /// have each `Element` interpolate volume data onto the points
46 /// contained inside that `Element`, and send the interpolated data
47 /// back to the component. The first step of this process is to
48 /// determine the block_id and block_logical_coordinates of each
49 /// point; this is done by the component (e.g. HorizonA), which calls
50 /// the function `block_logical_coordinates` on its full set of target
51 /// points. The result of `block_logical_coordinates` is then
52 /// communicated to the members of a NodeGroup component
53 /// (e.g. HorizonManager). Each node of the NodeGroup then calls
54 /// `element_logical_coordinates`, which returns a map of `ElementId`
55 /// to `ElementLogicalCoordHolder` for all the `Element`s on that node
56 /// that contain one or more of the target points. The NodeGroup
57 /// (which already has received the volume data from the `Elements` on
58 /// that node), interpolates the volume data to the element logical
59 /// coordinates for all of these `ElementId`s. The `offsets` in the
60 /// `ElementLogicalCoordHolder` are the indices into the `DataVectors`
61 /// of the original target coordinates and will be used to assemble
62 /// the interpolated data into `Tensor<DataVector>`s that have the
63 /// same ordering as the original target coordinates. The NodeGroups
64 /// perform a reduction to get the data back to the original
65 /// component.
66 template <size_t Dim>
68  tnsr::I<DataVector, Dim, Frame::Logical> element_logical_coords;
69  std::vector<size_t> offsets;
70 };
72 /// \ingroup ComputationalDomainGroup
73 ///
74 /// Given a set of points in block logical coordinates and their
75 /// `BlockIds`, as returned from the function
76 /// `block_logical_coordinates`, determines which `Element`s in a list
77 /// of `ElementId`s contains each point, and determines the element
78 /// logical coordinates of each point.
79 ///
80 /// \details Returns a std::unordered_map from `ElementId`s to
81 /// `ElementLogicalCoordHolder`s.
82 /// It is expected that only a subset of the points will be found
83 /// in the given `Element`s.
84 /// If a point is on a shared boundary of two or more `Element`s, it
85 /// will be returned only once, and will be considered to belong to
86 /// the first `Element` in the list of `ElementId`s.
87 template <size_t Dim>
89  const std::vector<ElementId<Dim>>& element_ids,
90  const std::vector<
91  IdPair<domain::BlockId, tnsr::I<double, Dim, typename Frame::Logical>>>&
92  block_coord_holders) noexcept
A data structure that contains an ID and data associated with that ID.
Definition: IdPair.hpp:16
Index a block of the computational domain.
Definition: BlockId.hpp:21
Definition: BlockId.hpp:16
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 ...
An ElementId uniquely labels an Element. It is constructed from the BlockId of the Block to which the...
Definition: ElementId.hpp:36
Defines a list of useful type aliases for tensors.
Holds element logical coordinates of an arbitrary set of points on a single Element. The arbitrary set of points is assumed to be a subset of a larger set of points spanning multiple Elements, and this class holds offsets that index into that larger set of points.
Definition: ElementLogicalCoordinates.hpp:67
Stores a collection of function values.
Definition: DataVector.hpp:46