Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <iosfwd>
8 : #include <type_traits>
9 : #include <unordered_set>
10 :
11 : #include "Domain/Structure/OrientationMap.hpp"
12 :
13 : /// \cond
14 : namespace PUP {
15 : class er;
16 : } // namespace PUP
17 : template <size_t VolumeDim>
18 : class ElementId;
19 : /// \endcond
20 :
21 : /// \ingroup ComputationalDomainGroup
22 : /// Information about the neighbors of a host Element or Block in a particular
23 : /// direction.
24 : ///
25 : /// \tparam VolumeDim the volume dimension.
26 : /// \tparam IdType the type of the Id of the neighbor (either ElementId or
27 : /// size_t for a Block)
28 : template <size_t VolumeDim, typename IdType = ElementId<VolumeDim>>
29 1 : class Neighbors {
30 : static_assert(std::is_same_v<IdType, size_t> or
31 : std::is_same_v<IdType, ElementId<VolumeDim>>);
32 :
33 : public:
34 : /// Construct with the ids, the orientation of the neighbors relative to the
35 : /// host, and whether the neighbors are conforming.
36 : ///
37 : /// \param ids the ids of the neighbors.
38 : /// \param orientations An OrientationMap (which takes objects in the logical
39 : /// coordinate frame of the host and maps them to the logical coordinate frame
40 : /// of the neighbor) for each neighboring Block (Elements within a Block share
41 : /// the same orientation). The key of the unordered map is the Block ID.
42 : /// \param are_conforming whether or not the block logical coordinates of the
43 : /// neighbors conform to those of the host (see
44 : /// domain::neighbor_is_conforming)
45 1 : Neighbors(std::unordered_set<IdType> ids,
46 : std::unordered_map<size_t, OrientationMap<VolumeDim>> orientations,
47 : bool are_conforming);
48 :
49 : /// Construct with the ids and orientation of the neighbors relative to the
50 : /// host, assuming the neighbors are conforming.
51 : ///
52 : /// \param ids the ids of the neighbors.
53 : /// \param orientation This OrientationMap takes objects in the logical
54 : /// coordinate frame of the host and maps them to the logical coordinate frame
55 : /// of the neighbor.
56 1 : Neighbors(std::unordered_set<IdType> ids,
57 : OrientationMap<VolumeDim> orientation);
58 :
59 : /// Construct with the id and orientation of a single neighbor relative to the
60 : /// host, assuming the neighbor is conforming.
61 : ///
62 : /// \param id the id of the neighbors.
63 : /// \param orientation This OrientationMap takes objects in the logical
64 : /// coordinate frame of the host Element and maps them to the logical
65 : /// coordinate frame of the neighbor Element.
66 1 : Neighbors(IdType id, OrientationMap<VolumeDim> orientation);
67 :
68 : /// Default constructor for Charm++ serialization.
69 1 : Neighbors() = default;
70 0 : ~Neighbors() = default;
71 0 : Neighbors(const Neighbors& neighbor) = default;
72 0 : Neighbors(Neighbors&&) = default;
73 0 : Neighbors& operator=(const Neighbors& rhs) = default;
74 0 : Neighbors& operator=(Neighbors&&) = default;
75 :
76 0 : const std::unordered_set<IdType>& ids() const { return ids_; }
77 :
78 : /// The orientations of the neighbors for each neighboring Block.
79 : ///
80 : /// \note All Elements within a Block share the same orientation.
81 1 : const std::unordered_map<size_t, OrientationMap<VolumeDim>>& orientations()
82 : const {
83 : return orientations_;
84 : }
85 :
86 : /// Whether or not the block logical coordinates of the neighbors conform to
87 : /// those of the host (see domain::neighbor_is_conforming)
88 1 : bool are_conforming() const { return are_conforming_; }
89 :
90 : /// The orientation of a particular neighbor.
91 1 : const OrientationMap<VolumeDim>& orientation(const IdType& id) const;
92 :
93 : /// Reset the ids of the neighbors.
94 : ///
95 : /// \note This should only be called to reset Element Neighbors after
96 : /// h-refinement
97 1 : void set_ids_to(std::unordered_set<IdType> new_ids);
98 :
99 : /// Add ids of neighbors.
100 : ///
101 : /// \note Adding an existing neighbor is allowed.
102 : /// \note The additional ids must be from Blocks with the existing
103 : /// orientations.
104 1 : void add_ids(std::unordered_set<IdType> additional_ids);
105 :
106 : /// Serialization for Charm++
107 : // NOLINTNEXTLINE(google-runtime-references)
108 1 : void pup(PUP::er& p);
109 :
110 : /// The number of neighbors
111 1 : size_t size() const { return ids_.size(); }
112 :
113 0 : typename std::unordered_set<IdType>::iterator begin() { return ids_.begin(); }
114 :
115 0 : typename std::unordered_set<IdType>::iterator end() { return ids_.end(); }
116 :
117 0 : typename std::unordered_set<IdType>::const_iterator begin() const {
118 : return ids_.begin();
119 : }
120 :
121 0 : typename std::unordered_set<IdType>::const_iterator end() const {
122 : return ids_.end();
123 : }
124 :
125 0 : typename std::unordered_set<IdType>::const_iterator cbegin() const {
126 : return ids_.begin();
127 : }
128 :
129 0 : typename std::unordered_set<IdType>::const_iterator cend() const {
130 : return ids_.end();
131 : }
132 :
133 : private:
134 0 : std::unordered_set<IdType> ids_{};
135 0 : std::unordered_map<size_t, OrientationMap<VolumeDim>> orientations_{};
136 0 : bool are_conforming_{true};
137 : };
138 :
139 : /// Output operator for Neighbors.
140 : template <size_t VolumeDim, typename IdType>
141 1 : std::ostream& operator<<(std::ostream& os,
142 : const Neighbors<VolumeDim, IdType>& neighbors);
143 :
144 : template <size_t VolumeDim, typename IdType>
145 0 : bool operator==(const Neighbors<VolumeDim, IdType>& lhs,
146 : const Neighbors<VolumeDim, IdType>& rhs);
147 :
148 : template <size_t VolumeDim, typename IdType>
149 0 : bool operator!=(const Neighbors<VolumeDim, IdType>& lhs,
150 : const Neighbors<VolumeDim, IdType>& rhs);
|