| 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 | 3657759 | explicit const_iterator(pointer ptr) : m_ptr(ptr) {} | |
| 39 | |||
| 40 | /** | ||
| 41 | * \brief Accesses the pointed-to element. | ||
| 42 | */ | ||
| 43 | 1073815 | reference operator*() const { return *m_ptr; } | |
| 44 | /** | ||
| 45 | * \brief Accesses the pointed-to element. | ||
| 46 | */ | ||
| 47 | 2065343 | const pointer operator->() const { return m_ptr; } | |
| 48 | |||
| 49 | /** | ||
| 50 | * \brief Prefix increment. | ||
| 51 | */ | ||
| 52 | 84403852 | const_iterator &operator++() { | |
| 53 | 84403852 | m_ptr = m_ptr->next_; | |
| 54 | 84403852 | 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 | 85936204 | friend bool operator!=(const const_iterator &a, const const_iterator &b) { | |
| 76 | 85936204 | 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 | 24641 | ElementTreeNode() noexcept | |
| 89 | 49282 | : prev_(nullptr), | |
| 90 | 24641 | next_(nullptr), | |
| 91 | 24641 | id_(-1), | |
| 92 | 24641 | level_(-1), | |
| 93 | 24641 | patch_(-1), | |
| 94 | 24641 | radius_(std::numeric_limits<double>::infinity()) { | |
| 95 | 24641 | midpoint_ << 0., 0., 0.; | |
| 96 | 24641 | llc_ << 0., 0.; | |
| 97 | 24641 | } | |
| 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 | 101058864 | 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 |