12#ifndef BEMBEL_SRC_CLUSTERTREE_ELEMENTTREE_HPP_
13#define BEMBEL_SRC_CLUSTERTREE_ELEMENTTREE_HPP_
107 geometry_ =
g.get_geometry_ptr();
109 number_of_patches_ = geometry_->size();
113 std::vector<ElementTreeNode *>
patches;
115 number_of_points_ = 0;
116 number_of_elements_ = number_of_patches_;
119 for (
auto i = 0;
i < number_of_patches_; ++
i) {
120 root.
sons_[
i].adjcents_ = std::vector<ElementTreeNode *>(4,
nullptr);
132 if (
i == number_of_patches_ - 1) {
140 for (
auto j = 0;
j < 4; ++
j) {
141 v = (*geometry_)[
i].eval(Constants::corners[0][
j],
142 Constants::corners[1][
j]);
143 unsigned int index = 0;
144 for (; index <
uniquePts.size(); ++index)
170 if (
el.sons_.size()) {
171 for (
auto i = 0;
i <
el.sons_.size(); ++
i)
207 Eigen::MatrixXd
pts(3, number_of_points_);
208 if (
idct !=
nullptr) {
209 idct->resize(number_of_points_);
214 pts.col(
it->vertices_[0]) =
215 (*geometry_)[
it->patch_].eval(
it->llc_(0),
it->llc_(1));
216 pts.col(
it->vertices_[1]) =
217 (*geometry_)[
it->patch_].eval(
it->llc_(0) +
h,
it->llc_(1));
218 pts.col(
it->vertices_[2]) =
219 (*geometry_)[
it->patch_].eval(
it->llc_(0) +
h,
it->llc_(1) +
h);
220 pts.col(
it->vertices_[3]) =
221 (*geometry_)[
it->patch_].eval(
it->llc_(0),
it->llc_(1) +
h);
222 if (
idct !=
nullptr) {
223 ++((*idct)(
it->vertices_[0]));
224 ++((*idct)(
it->vertices_[1]));
225 ++((*idct)(
it->vertices_[2]));
226 ++((*idct)(
it->vertices_[3]));
241 unsigned int elID = 0;
242 Eigen::MatrixXi
retval(4, number_of_elements_);
357 for (
auto i = 0;
i < root_.
sons_.size(); ++
i)
369 const Eigen::MatrixXd &
P) {
373 if (!
el.sons_.size()) {
375 util::computeEnclosingBall(&
mp1, &
r1,
P.col(
el.vertices_[0]), 0,
376 P.col(
el.vertices_[2]), 0);
377 util::computeEnclosingBall(&
mp2, &
r2,
P.col(
el.vertices_[1]), 0,
378 P.col(
el.vertices_[3]), 0);
379 util::computeEnclosingBall(&(
el.midpoint_), &(
el.radius_),
mp1,
r1,
mp2,
383 for (
auto i = 0;
i < 4; ++
i)
386 util::computeEnclosingBall(&
mp1, &
r1,
el.sons_[0].midpoint_,
387 el.sons_[0].radius_,
el.sons_[2].midpoint_,
388 el.sons_[2].radius_);
389 util::computeEnclosingBall(&
mp2, &
r2,
el.sons_[1].midpoint_,
390 el.sons_[1].radius_,
el.sons_[3].midpoint_,
391 el.sons_[3].radius_);
392 util::computeEnclosingBall(&(
el.midpoint_), &(
el.radius_),
mp1,
r1,
mp2,
404 std::cout <<
"element[" <<
i++ <<
"] = ";
418 Eigen::MatrixXd
retval(3, number_of_elements_);
433 Eigen::VectorXd
retval(number_of_elements_);
448 Eigen::VectorXi
retval(number_of_elements_);
468 Eigen::VectorXi
retval(number_of_elements_);
472 for (
auto j = 0;
j < 4; ++
j)
473 if (
it->adjcents_[
j] ==
nullptr) {
476 }
else if (
it->adjcents_[
j]->patch_ !=
it->patch_) {
493 Eigen::VectorXi
retval(number_of_elements_);
511 std::vector<std::array<int, 4>>
retval;
513 for (
auto j = 0;
j < 4; ++
j) {
515 if (
it->adjcents_[
j] !=
nullptr) {
545 std::vector<int>
out(number_of_elements_);
547 const double h =
it->get_h();
548 const Eigen::Vector2d
ref_mid =
549 it->llc_ + Eigen::Vector2d(.5 *
h, .5 *
h);
562 return number_of_patches_ *
563 (((1 <<
el.level_) * (1 <<
el.level_) - 1) / 3) +
573 template <
typename T>
575 bool operator()(
const T &
v1,
const T &
v2)
const {
576 return ((
v1 -
v2).
norm() < Constants::pt_comp_tolerance);
584 void updateTopology(
const std::vector<ElementTreeNode *> &
elements) {
585 std::map<std::array<int, 2>, ElementTreeNode *>
edges;
586 std::array<int, 2>
e1,
e2;
589 for (
auto j = 0;
j < 4; ++
j) {
600 for (
auto k = 0;
k < 4; ++
k) {
601 const int v3 =
it->second->vertices_[
k];
602 const int v4 =
it->second->vertices_[(
k + 1) % 4];
624 void refineLeaf(ElementTreeNode &
cur_el) {
626 if (
cur_el.sons_.size())
return;
627 std::vector<int>
ptIds(5);
629 std::vector<ElementTreeNode *>
elements;
631 for (
auto i = 0;
i < 4; ++
i) {
633 if (
cur_el.adjcents_[
i] !=
nullptr) {
634 for (
auto j = 0;
j < 4; ++
j)
635 if (
cur_el.adjcents_[
i]->adjcents_[
j] == std::addressof(
cur_el)) {
644 for (
auto i = 0;
i < 4; ++
i) {
646 if (
cur_el.adjcents_[
i] !=
nullptr) {
660 ptIds[
i] = number_of_points_;
665 ptIds[
i] = number_of_points_;
670 ptIds[4] = number_of_points_;
674 number_of_elements_ += 3;
676 max_level_ <
cur_el.level_ + 1 ?
cur_el.level_ + 1 : max_level_;
679 for (
auto i = 0;
i < 4; ++
i) {
684 if (
cur_el.prev_ !=
nullptr)
687 if (std::addressof(
cur_el) == pfirst_)
688 pfirst_ = std::addressof(
cur_el.sons_[
i]);
695 if (
cur_el.next_ !=
nullptr)
698 if (std::addressof(
cur_el) == plast_)
699 plast_ = std::addressof(
cur_el.sons_[
i]);
707 cur_el.sons_[
i].adjcents_ = std::vector<ElementTreeNode *>(4,
nullptr);
716 cur_el.sons_[0].vertices_.push_back(
cur_el.vertices_[0]);
722 cur_el.sons_[1].vertices_.push_back(
cur_el.vertices_[1]);
728 cur_el.sons_[2].vertices_.push_back(
cur_el.vertices_[2]);
734 cur_el.sons_[3].vertices_.push_back(
cur_el.vertices_[3]);
743 std::shared_ptr<PatchVector> geometry_;
744 ElementTreeNode root_;
745 ElementTreeNode *pfirst_;
746 ElementTreeNode *plast_;
747 int number_of_patches_;
749 int number_of_points_;
750 int number_of_elements_;
This class organizes an element structure on a Geometry object and handles refinement.
ElementTreeNode::const_iterator cpbegin() const
Returns an iterator to the beginning of the sequence represented by the leafs as ElementTreeNodes of ...
Eigen::MatrixXd computeElementEnclosings()
Computes enclosing balls surrounding all elements.
ElementTreeNode & root()
Return reference to the root ElementTreeNode.
void refineUniformly()
Refine all patches uniformly.
ElementTree(const Geometry &g, unsigned int max_level=0)
Explicit constructor for the ElementTree class.
ElementTreeNode::const_iterator cpend() const
Returns an iterator one past the end of the sequence represented by the leafs as ElementTreeNodes of ...
ElementTreeNode::const_iterator pbegin() const
iterators
ElementTreeNode::const_iterator cluster_begin(const ElementTreeNode &cl) const
Returns a cluster iterator to the beginning of the sequence represented by the the given ElementTreeN...
ElementTree(const ElementTree &)=delete
Deleted copy constructor for the ElementTree class.
ElementTree & operator=(const ElementTree &)=delete
Deleted copy assignment operator for the ElementTree class.
int get_number_of_points() const
getter
const ElementTreeNode & root() const
Return const reference to the root ElementTreeNode.
Eigen::VectorXi generatePatchBoundaryLabels() const
Generate list of labels if elements are on the patch boundary or at the boundary of the geometry.
ElementTreeNode::const_iterator pend() const
Returns an iterator one past the end of the sequence represented by the leafs as ElementTreeNodes of ...
Eigen::MatrixXd generateRadiusList() const
Return a matrix with all radii of the element enclosing.
Eigen::VectorXi identifyPatch(unsigned int pn) const
Generate list of labels if elements contained within a given patch.
void refinePatch(int patch)
Refine a given patch.
const PatchVector & get_geometry() const
Return const reference to the Geometry.
ElementTree & operator=(ElementTree &&)=delete
Deleted move assignment operator for the ElementTree class.
std::vector< int > computeReorderingVector() const
The ordering of elements in the element tree does not correspond to the element order underlying the ...
std::vector< std::array< int, 4 > > patchTopologyInfo() const
Resolves neighborhood relations of the patches.
void printPanels() const
Prints all Elements of the Tree.
void init_ElementTree(const Geometry &g, unsigned int max_level)
init
void computeElementEnclosings_recursion(ElementTreeNode &el, const Eigen::MatrixXd &P)
Computes enclosing balls of one element and all its sons.
int get_number_of_elements() const
Return number of elements in the ElementTree.
Eigen::MatrixXd generatePointList(Eigen::VectorXi *idct=nullptr) const
Return the coordinates of all points of the elements.
Eigen::MatrixXd generateMidpointList() const
other Stuff
ElementTree(ElementTree &&)=delete
Deleted move constructor for the ElementTree class.
Eigen::VectorXi generateElementLabels() const
Return a vector with computed global indices of the elements.
Eigen::MatrixXi generateElementList() const
Return list of elements containing the indices of the vertices.
ElementTreeNode::const_iterator cluster_end(const ElementTreeNode &cl) const
Returns a cluster iterator one past the end of the sequence represented by the the given ElementTreeN...
ElementTree()
constructors
void refineUniformly_recursion(ElementTreeNode &el)
Refine the given element or it's sons.
int get_max_level() const
Return maximum level of refinement.
The ElementTreeNode corresponds to an element in the element tree.
std::vector< ElementTreeNode > sons_
member variables
this class wraps a GeometryVector and provides some basic functionality, like reading Geometry files
std::vector< Bembel::Patch > PatchVector
typedef for PatchVector
Routines for the evalutation of pointwise errors.
constexpr int getFunctionSpaceOutputDimension()
iterator struct for element tree nodes. They may be used to iterator over the elements in a cluster....