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);