Line | Branch | Exec | Source |
---|---|---|---|
1 | // This file is part of Bembel, the higher order C++ boundary element library. | ||
2 | // | ||
3 | // Copyright (C) 2022 see <http://www.bembel.eu> | ||
4 | // | ||
5 | // It was written as part of a cooperation of J. Doelz, H. Harbrecht, S. Kurz, | ||
6 | // M. Multerer, S. Schoeps, and F. Wolf at Technische Universitaet Darmstadt, | ||
7 | // Universitaet Basel, and Universita della Svizzera italiana, Lugano. This | ||
8 | // source code is subject to the GNU General Public License version 3 and | ||
9 | // provided WITHOUT ANY WARRANTY, see <http://www.bembel.eu> for further | ||
10 | // information. | ||
11 | |||
12 | #ifndef BEMBEL_SRC_CLUSTERTREE_ELEMENTTREENODE_HPP_ | ||
13 | #define BEMBEL_SRC_CLUSTERTREE_ELEMENTTREENODE_HPP_ | ||
14 | |||
15 | namespace Bembel { | ||
16 | |||
17 | /** | ||
18 | * \ingroup ClusterTree | ||
19 | * \brief The ElementTreeNode corresponds to an element in the element tree. | ||
20 | */ | ||
21 | class ElementTreeNode { | ||
22 | public: | ||
23 | /** | ||
24 | * \brief iterator struct for element tree nodes. They may be used to iterator | ||
25 | * over the elements in a cluster. To do so, however, the cluster must be set | ||
26 | * up by ElementTree beforehand. | ||
27 | */ | ||
28 | struct const_iterator { | ||
29 | using iterator_category = std::forward_iterator_tag; | ||
30 | using difference_type = std::ptrdiff_t; | ||
31 | using value_type = ElementTreeNode; | ||
32 | using pointer = value_type *; | ||
33 | using reference = value_type &; | ||
34 | |||
35 | /** | ||
36 | * \brief Constructs a new iterator. | ||
37 | */ | ||
38 | 3657743 | explicit const_iterator(pointer ptr) : m_ptr(ptr) {} | |
39 | |||
40 | /** | ||
41 | * \brief Accesses the pointed-to element. | ||
42 | */ | ||
43 | 1073779 | reference operator*() const { return *m_ptr; } | |
44 | /** | ||
45 | * \brief Accesses the pointed-to element. | ||
46 | */ | ||
47 | 2065179 | const pointer operator->() const { return m_ptr; } | |
48 | |||
49 | /** | ||
50 | * \brief Prefix increment. | ||
51 | */ | ||
52 | 84403836 | const_iterator &operator++() { | |
53 | 84403836 | m_ptr = m_ptr->next_; | |
54 | 84403836 | return *this; | |
55 | } | ||
56 | |||
57 | /** | ||
58 | * \brief Postfix increment. | ||
59 | */ | ||
60 | const_iterator operator++(int) { | ||
61 | const_iterator tmp = *this; | ||
62 | ++(*this); | ||
63 | return tmp; | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * \brief Compares the underlying iterators. | ||
68 | */ | ||
69 | friend bool operator==(const const_iterator &a, const const_iterator &b) { | ||
70 | return a.m_ptr == b.m_ptr; | ||
71 | } | ||
72 | /** | ||
73 | * \brief Compares the underlying iterators. | ||
74 | */ | ||
75 | 85936188 | friend bool operator!=(const const_iterator &a, const const_iterator &b) { | |
76 | 85936188 | return a.m_ptr != b.m_ptr; | |
77 | } | ||
78 | |||
79 | private: | ||
80 | pointer m_ptr; | ||
81 | }; | ||
82 | ////////////////////////////////////////////////////////////////////////////// | ||
83 | /// constructors | ||
84 | ////////////////////////////////////////////////////////////////////////////// | ||
85 | /** | ||
86 | * \brief Default constructor. | ||
87 | */ | ||
88 | 24637 | ElementTreeNode() noexcept | |
89 | 49274 | : prev_(nullptr), | |
90 | 24637 | next_(nullptr), | |
91 | 24637 | id_(-1), | |
92 | 24637 | level_(-1), | |
93 | 24637 | patch_(-1), | |
94 | 24637 | radius_(std::numeric_limits<double>::infinity()) { | |
95 | 24637 | midpoint_ << 0., 0., 0.; | |
96 | 24637 | llc_ << 0., 0.; | |
97 | 24637 | } | |
98 | /** | ||
99 | * \brief Move constructor. | ||
100 | */ | ||
101 | ✗ | ElementTreeNode(ElementTreeNode &&other) noexcept { | |
102 | ✗ | midpoint_.swap(other.midpoint_); | |
103 | ✗ | llc_.swap(other.llc_); | |
104 | ✗ | vertices_ = std::move(other.vertices_); | |
105 | ✗ | radius_ = other.radius_; | |
106 | ✗ | id_ = other.id_; | |
107 | ✗ | patch_ = other.patch_; | |
108 | ✗ | sons_ = std::move(other.sons_); | |
109 | ✗ | adjcents_ = std::move(other.adjcents_); | |
110 | ✗ | } | |
111 | |||
112 | /** | ||
113 | * \brief Copy constructor (deleted). | ||
114 | * | ||
115 | * \param other The ElementTreeNode instance to copy from. | ||
116 | */ | ||
117 | ElementTreeNode(const ElementTreeNode &other) = delete; | ||
118 | /** | ||
119 | * \brief Copy assignment operator (deleted). | ||
120 | * | ||
121 | * \param other The ElementTreeNode instance to copy from. | ||
122 | * \return Reference to this ElementTreeNode instance. | ||
123 | */ | ||
124 | ElementTreeNode &operator=(const ElementTreeNode &other) = delete; | ||
125 | /** | ||
126 | * \brief Move assignment operator (deleted). | ||
127 | * | ||
128 | * \param other The ElementTreeNode instance to move from. | ||
129 | * \return Reference to this ElementTreeNode instance. | ||
130 | */ | ||
131 | ElementTreeNode &operator=(ElementTreeNode &&other) = delete; | ||
132 | ////////////////////////////////////////////////////////////////////////////// | ||
133 | /// methods | ||
134 | ////////////////////////////////////////////////////////////////////////////// | ||
135 | /** | ||
136 | * \brief Prints the member variables of the element. | ||
137 | */ | ||
138 | void print() const { | ||
139 | std::cout << "{" << std::endl; | ||
140 | std::cout << "midpoint: " << midpoint_.transpose() << std::endl; | ||
141 | std::cout << "llc: " << llc_.transpose() << std::endl; | ||
142 | std::cout << "p s n: " << prev_ << " " << this << " " << next_ | ||
143 | << std::endl; | ||
144 | std::cout << "neighbours: "; | ||
145 | for (auto i = 0; i < adjcents_.size(); ++i) | ||
146 | std::cout << adjcents_[i] << " "; | ||
147 | std::cout << std::endl; | ||
148 | std::cout << "vertices: "; | ||
149 | for (auto i = 0; i < vertices_.size(); ++i) | ||
150 | std::cout << vertices_[i] << " "; | ||
151 | std::cout << std::endl; | ||
152 | std::cout << "radius: " << radius_ << std::endl; | ||
153 | std::cout << "id: " << id_ << std::endl; | ||
154 | std::cout << "level: " << level_ << std::endl; | ||
155 | std::cout << "patch: " << patch_ << std::endl; | ||
156 | std::cout << "}" << std::endl; | ||
157 | return; | ||
158 | } | ||
159 | ////////////////////////////////////////////////////////////////////////////// | ||
160 | /** | ||
161 | * \brief Maps a point in the reference domain of a patch to the reference | ||
162 | * element of this element. | ||
163 | * | ||
164 | * This function asserts that the correct element is chosen. So the return | ||
165 | * value must be with in [0,1]^2. | ||
166 | * | ||
167 | * \param in Point in reference domain of the patch. | ||
168 | * \return Point in reference domain of the element. | ||
169 | */ | ||
170 | 3840 | Eigen::Vector2d mapToReferenceElement(const Eigen::Vector2d &in) const { | |
171 |
3/6✓ Branch 2 taken 3840 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3840 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3840 times.
✗ Branch 9 not taken.
|
3840 | Eigen::Vector2d out = (in - llc_) / get_h(); |
172 |
4/8✓ Branch 1 taken 3840 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3840 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3840 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3840 times.
✗ Branch 11 not taken.
|
3840 | assert(out(0) >= 0. && out(0) <= 1. && out(1) >= 0. && out(1) <= 1.); |
173 | 3840 | return out; | |
174 | } | ||
175 | ////////////////////////////////////////////////////////////////////////////// | ||
176 | /** | ||
177 | * \brief Get the midpoint of this element with respect to the patch. | ||
178 | * | ||
179 | * \return Midpoint with respect to the patch containing the element. | ||
180 | */ | ||
181 | Eigen::Vector2d referenceMidpoint() const { | ||
182 | return llc_ + Eigen::Vector2d(0.5, 0.5) * get_h(); | ||
183 | } | ||
184 | ////////////////////////////////////////////////////////////////////////////// | ||
185 | /// getter | ||
186 | ////////////////////////////////////////////////////////////////////////////// | ||
187 | /** | ||
188 | * \brief Get with of the reference element with respect to the reference | ||
189 | * domain of the patch. | ||
190 | * | ||
191 | * \return Width of the reference element. | ||
192 | */ | ||
193 | 101058784 | double get_h() const { return double(1) / double(1 << level_); } | |
194 | ////////////////////////////////////////////////////////////////////////////// | ||
195 | /** | ||
196 | * \brief Get the level of refinement of the element. | ||
197 | * | ||
198 | * \return Level of refinement. | ||
199 | */ | ||
200 | 300096 | int get_level() const { return level_; } | |
201 | ////////////////////////////////////////////////////////////////////////////// | ||
202 | /** | ||
203 | * \brief Returns a const reference to the first son if any or itself. | ||
204 | * | ||
205 | * \return Const reference to the first son or this element itself. | ||
206 | */ | ||
207 | 2974824 | const ElementTreeNode &front() const { | |
208 | 2974824 | const ElementTreeNode *ptr = this; | |
209 |
2/2✓ Branch 3 taken 6524496 times.
✓ Branch 4 taken 2974824 times.
|
9499320 | while (ptr->sons_.size()) ptr = std::addressof(ptr->sons_.front()); |
210 | 2974824 | return *ptr; | |
211 | } | ||
212 | ////////////////////////////////////////////////////////////////////////////// | ||
213 | /** | ||
214 | * \brief Returns a const reference to the last son if any or itself. | ||
215 | * | ||
216 | * \return Const reference to the last son or this element itself. | ||
217 | */ | ||
218 | 608616 | const ElementTreeNode &back() const { | |
219 | 608616 | const ElementTreeNode *ptr = this; | |
220 |
2/2✓ Branch 3 taken 608976 times.
✓ Branch 4 taken 608616 times.
|
1217592 | while (ptr->sons_.size()) ptr = std::addressof(ptr->sons_.back()); |
221 | 608616 | return *ptr; | |
222 | } | ||
223 | ////////////////////////////////////////////////////////////////////////////// | ||
224 | /** | ||
225 | * \brief Returns an iterator pointing to the element in the sequence before | ||
226 | * this ElementTreeNodes. | ||
227 | * | ||
228 | * \return Returns a ElementTreeNode::const_iterator object. | ||
229 | */ | ||
230 | |||
231 | 2974824 | const_iterator cbegin() const { | |
232 | 2974824 | const ElementTreeNode &el = this->front(); | |
233 | 2974824 | return const_iterator(const_cast<ElementTreeNode *>(std::addressof(el))); | |
234 | } | ||
235 | ////////////////////////////////////////////////////////////////////////////// | ||
236 | /** | ||
237 | * \brief Returns an iterator pointing to the element in the sequence after | ||
238 | * this ElementTreeNode. | ||
239 | * | ||
240 | * \return Returns a ElementTreeNode::const_iterator object. | ||
241 | */ | ||
242 | 608616 | const_iterator cend() const { | |
243 | 608616 | const ElementTreeNode &el = this->back(); | |
244 | 608616 | return const_iterator(const_cast<ElementTreeNode *>(el.next_)); | |
245 | } | ||
246 | ////////////////////////////////////////////////////////////////////////////// | ||
247 | /** | ||
248 | * \brief Returns an iterator pointing to the element in the sequence before | ||
249 | * this ElementTreeNodes. | ||
250 | * | ||
251 | * \return Returns a ElementTreeNode::const_iterator object. | ||
252 | */ | ||
253 | 2974824 | const_iterator begin() const { return cbegin(); } | |
254 | ////////////////////////////////////////////////////////////////////////////// | ||
255 | /** | ||
256 | * \brief Returns an iterator pointing to the element in the sequence after | ||
257 | * this ElementTreeNode. | ||
258 | * | ||
259 | * \return Returns a ElementTreeNode::const_iterator object. | ||
260 | */ | ||
261 | 608616 | const_iterator end() const { | |
262 | 608616 | return cend(); | |
263 | } | ||
264 | ////////////////////////////////////////////////////////////////////////////// | ||
265 | /// member variables | ||
266 | ////////////////////////////////////////////////////////////////////////////// | ||
267 | std::vector<ElementTreeNode> sons_; /// children | ||
268 | std::vector<ElementTreeNode *> adjcents_; /// neighbouring elements indices | ||
269 | std::vector<int> vertices_; /// indices of the vertices | ||
270 | Eigen::Vector3d midpoint_; /// midpoint of the element | ||
271 | Eigen::Vector2d llc_; /// lower left corner on [0,1]^2 | ||
272 | ElementTreeNode *prev_; | ||
273 | ElementTreeNode *next_; | ||
274 | double radius_; /// radius of the element | ||
275 | int id_; /// element id with respect to the level | ||
276 | int level_; /// level of the element | ||
277 | int patch_; /// patch of the element | ||
278 | }; | ||
279 | } // namespace Bembel | ||
280 | #endif // BEMBEL_SRC_CLUSTERTREE_ELEMENTTREENODE_HPP_ | ||
281 |