ElementId.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines class ElementId.
6 
7 #pragma once
8 
9 #include <array>
10 #include <cstddef>
11 #include <functional>
12 #include <iosfwd>
13 #include <limits>
14 
15 #include "Domain/ElementIndex.hpp" // IWYU pragma: keep
16 #include "Domain/SegmentId.hpp"
17 #include "Domain/Side.hpp"
18 #include "Utilities/MakeArray.hpp"
19 
20 /// \cond
21 namespace Parallel {
22 template <class>
23 class ArrayIndex;
24 } // namespace Parallel
25 /// \endcond
26 namespace PUP {
27 class er;
28 } // namespace PUP
29 
30 /// \ingroup ComputationalDomainGroup
31 /// An ElementId uniquely labels an Element.
32 /// It is constructed from the BlockId of the Block to which the Element belongs
33 /// and the VolumeDim SegmentIds that label the segments of the Block that the
34 /// Element covers.
35 template <size_t VolumeDim>
36 class ElementId {
37  public:
38  /// Default constructor needed for Charm++ serialization.
39  constexpr ElementId() = default;
40 
41  /// Create the ElementId of the root Element of a Block.
42  explicit ElementId(size_t block_id) noexcept;
43 
44  /// Convert an ElementIndex to an ElementId
45  // clang-tidy: mark explicit: we want to allow conversion
46  ElementId(const ElementIndex<VolumeDim>& index) noexcept; // NOLINT
47 
48  /// Conversion operator needed to index `proxy`s using `ElementId`
49  // clang-tidy: mark explicit, we want implicit conversion
50  operator Parallel::ArrayIndex<ElementIndex<VolumeDim>>() const // NOLINT
51  noexcept;
52 
53  /// Create an arbitrary ElementId.
54  ElementId(size_t block_id,
55  std::array<SegmentId, VolumeDim> segment_ids) noexcept;
56 
57  ElementId<VolumeDim> id_of_child(size_t dim, Side side) const noexcept;
58 
59  ElementId<VolumeDim> id_of_parent(size_t dim) const noexcept;
60 
61  constexpr size_t block_id() const noexcept { return block_id_; }
62 
63  const std::array<SegmentId, VolumeDim>& segment_ids() const noexcept {
64  return segment_ids_;
65  }
66 
67  /// Serialization for Charm++
68  void pup(PUP::er& p) noexcept; // NOLINT
69 
70  /// Returns an ElementId meant for identifying data on external boundaries,
71  /// which should never correspond to the Id of an actual element.
72  static ElementId<VolumeDim> external_boundary_id() noexcept;
73 
74  private:
75  size_t block_id_ = std::numeric_limits<size_t>::max();
77  make_array<VolumeDim>(SegmentId());
78 };
79 
80 /// Output operator for ElementId.
81 template <size_t VolumeDim>
83  const ElementId<VolumeDim>& id) noexcept;
84 
85 /// Equivalence operator for ElementId.
86 template <size_t VolumeDim>
87 bool operator==(const ElementId<VolumeDim>& lhs,
88  const ElementId<VolumeDim>& rhs) noexcept;
89 
90 /// Inequivalence operator for ElementId.
91 template <size_t VolumeDim>
92 bool operator!=(const ElementId<VolumeDim>& lhs,
93  const ElementId<VolumeDim>& rhs) noexcept;
94 
95 // ######################################################################
96 // INLINE DEFINITIONS
97 // ######################################################################
98 
99 template <size_t VolumeDim>
100 size_t hash_value(const ElementId<VolumeDim>& c) noexcept;
101 
102 // clang-tidy: do not modify namespace std
103 namespace std { // NOLINT
104 template <size_t VolumeDim>
105 struct hash<ElementId<VolumeDim>> {
106  size_t operator()(const ElementId<VolumeDim>& c) const noexcept;
107 };
108 } // namespace std
109 
110 template <size_t VolumeDim>
111 inline bool operator==(const ElementId<VolumeDim>& lhs,
112  const ElementId<VolumeDim>& rhs) noexcept {
113  return lhs.block_id() == rhs.block_id() and
114  lhs.segment_ids() == rhs.segment_ids();
115 }
116 
117 template <size_t VolumeDim>
118 inline bool operator!=(const ElementId<VolumeDim>& lhs,
119  const ElementId<VolumeDim>& rhs) noexcept {
120  return not(lhs == rhs);
121 }
Definition: Strahlkorper.hpp:14
A SegmentId labels a segment of the interval [-1,1] and is used to identify the bounds of an Element ...
Definition: SegmentId.hpp:50
Defines function make_array.
An ElementId uniquely labels an Element. It is constructed from the BlockId of the Block to which the...
Definition: ElementId.hpp:36
Contains functions that forward to Charm++ parallel functions.
Definition: Abort.hpp:13
bool operator!=(const ElementId< VolumeDim > &lhs, const ElementId< VolumeDim > &rhs) noexcept
Inequivalence operator for ElementId.
Definition: ElementId.hpp:118
Side
A label for the side of a manifold.
Definition: Side.hpp:17
T max(T... args)
Defines class ElementIndex.
A class for indexing a Charm array by Element.
Definition: ElementIndex.hpp:53
bool operator==(const ElementId< VolumeDim > &lhs, const ElementId< VolumeDim > &rhs) noexcept
Equivalence operator for ElementId.
Definition: ElementId.hpp:111
std::ostream & operator<<(std::ostream &os, const ElementId< VolumeDim > &id) noexcept
Output operator for ElementId.
Definition: ElementId.cpp:82
Defines class SegmentId.
The array index used for indexing Chare Arrays, mostly an implementation detail.
Definition: ArrayIndex.hpp:20
Defines enum class Side.