libMesh
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | List of all members
libMesh::TreeNode< N > Class Template Reference

This class defines a node on a tree. More...

#include <tree_node.h>

Public Member Functions

 TreeNode (const MeshBase &m, unsigned int tbs, const TreeNode< N > *p=nullptr)
 Constructor.
 
 TreeNode (const TreeNode< N > &)=delete
 Class contains unique_ptrs and cannot be default copied.
 
 ~TreeNode ()=default
 Destructor.
 
bool is_root () const
 
bool active () const
 
bool insert (const Node *nd)
 Tries to insert Node nd into the TreeNode.
 
bool insert (const Elem *nd)
 Inserts Elem el into the TreeNode.
 
void refine ()
 Refine the tree node into N children if it contains more than tol nodes.
 
void set_bounding_box (const std::pair< Point, Point > &bbox)
 Sets the bounding box;.
 
bool bounds_node (const Node *nd, Real relative_tol=0) const
 
bool bounds_point (const Point &p, Real relative_tol=0) const
 
unsigned int level () const
 
void print_nodes (std::ostream &out_stream=libMesh::out) const
 Prints the contents of the node_numbers vector if we are active.
 
void print_elements (std::ostream &out_stream=libMesh::out) const
 Prints the contents of the elements set if we are active.
 
void transform_nodes_to_elements (std::vector< std::vector< const Elem * > > &nodes_to_elem)
 Transforms node numbers to element pointers.
 
void transform_nodes_to_elements (std::unordered_map< dof_id_type, std::vector< const Elem * > > &nodes_to_elem)
 Transforms node numbers to element pointers.
 
unsigned int n_active_bins () const
 
const Elemfind_element (const Point &p, const std::set< subdomain_id_type > *allowed_subdomains=nullptr, Real relative_tol=TOLERANCE) const
 
void find_elements (const Point &p, std::set< const Elem * > &candidate_elements, const std::set< subdomain_id_type > *allowed_subdomains=nullptr, Real relative_tol=TOLERANCE) const
 Adds to candidate_elements any elements containing the specified point p, optionally restricted to a set of allowed subdomains, optionally using a non-default relative tolerance for searches.
 

Private Member Functions

const Elemfind_element_in_children (const Point &p, const std::set< subdomain_id_type > *allowed_subdomains, Real relative_tol) const
 Look for point p in our children, optionally restricted to a set of allowed subdomains.
 
void find_elements_in_children (const Point &p, std::set< const Elem * > &candidate_elements, const std::set< subdomain_id_type > *allowed_subdomains, Real relative_tol) const
 Look for points in our children, optionally restricted to a set of allowed subdomains.
 
BoundingBox create_bounding_box (unsigned int c) const
 Constructs the bounding box for child c.
 

Private Attributes

const MeshBasemesh
 Reference to the mesh.
 
const TreeNode< N > * parent
 Pointer to this node's parent.
 
std::vector< std::unique_ptr< TreeNode< N > > > children
 Pointers to our children.
 
BoundingBox bounding_box
 The Cartesian bounding box for the node.
 
std::vector< const Elem * > elements
 Pointers to the elements in this tree node.
 
std::vector< const Node * > nodes
 The node numbers contained in this portion of the tree.
 
const unsigned int tgt_bin_size
 The maximum number of things we should store before refining ourself.
 
unsigned int target_bin_size_increase_level
 This specifies the refinement level beyond which we will scale up the target bin size in child TreeNodes.
 
bool contains_ifems
 Does this node contain any infinite elements.
 

Detailed Description

template<unsigned int N>
class libMesh::TreeNode< N >

This class defines a node on a tree.

A tree node contains a pointer to its parent (nullptr if the node is the root) and pointers to its children (nullptr if the node is active.

Author
Daniel Dreyer
Date
2003

Base class for different Tree types.

Definition at line 54 of file tree_node.h.

Constructor & Destructor Documentation

◆ TreeNode() [1/2]

template<unsigned int N>
libMesh::TreeNode< N >::TreeNode ( const MeshBase m,
unsigned int  tbs,
const TreeNode< N > *  p = nullptr 
)
inline

Constructor.

Takes a pointer to this node's parent. The pointer should only be nullptr for the top-level (root) node.

Definition at line 264 of file tree_node.h.

266 :
267 mesh (m),
268 parent (p),
269 tgt_bin_size (tbs),
271 contains_ifems (false)
272{
273 // libmesh_assert our children are empty, thus we are active.
274 libmesh_assert (children.empty());
275 libmesh_assert (this->active());
276
277 // Reserve space for the nodes & elements
278 nodes.reserve (tgt_bin_size);
279 elements.reserve (tgt_bin_size);
280}
bool active() const
Definition tree_node.h:88
std::vector< std::unique_ptr< TreeNode< N > > > children
Pointers to our children.
Definition tree_node.h:218
const MeshBase & mesh
Reference to the mesh.
Definition tree_node.h:207
std::vector< const Node * > nodes
The node numbers contained in this portion of the tree.
Definition tree_node.h:233
const TreeNode< N > * parent
Pointer to this node's parent.
Definition tree_node.h:212
std::vector< const Elem * > elements
Pointers to the elements in this tree node.
Definition tree_node.h:228
bool contains_ifems
Does this node contain any infinite elements.
Definition tree_node.h:253
const unsigned int tgt_bin_size
The maximum number of things we should store before refining ourself.
Definition tree_node.h:239
unsigned int target_bin_size_increase_level
This specifies the refinement level beyond which we will scale up the target bin size in child TreeNo...
Definition tree_node.h:248
libmesh_assert(ctx)

References libMesh::TreeNode< N >::active(), libMesh::TreeNode< N >::children, libMesh::TreeNode< N >::elements, libMesh::libmesh_assert(), libMesh::TreeNode< N >::nodes, and libMesh::TreeNode< N >::tgt_bin_size.

◆ TreeNode() [2/2]

template<unsigned int N>
libMesh::TreeNode< N >::TreeNode ( const TreeNode< N > &  )
delete

Class contains unique_ptrs and cannot be default copied.

◆ ~TreeNode()

template<unsigned int N>
libMesh::TreeNode< N >::~TreeNode ( )
default

Destructor.

Deletes all children, if any. Thus to delete a tree it is sufficient to explicitly delete the root node.

Member Function Documentation

◆ active()

template<unsigned int N>
bool libMesh::TreeNode< N >::active ( ) const
inline
Returns
true if this node is active (i.e. has no children), false otherwise.

Definition at line 88 of file tree_node.h.

88{ return children.empty(); }

References libMesh::TreeNode< N >::children.

Referenced by libMesh::TreeNode< N >::TreeNode().

◆ bounds_node()

template<unsigned int N>
bool libMesh::TreeNode< N >::bounds_node ( const Node nd,
Real  relative_tol = 0 
) const
Returns
true if this TreeNode (or its children) contain node n (within relative tolerance), false otherwise.

Definition at line 255 of file tree_node.C.

257{
258 libmesh_assert(nd);
259 return bounds_point(*nd, relative_tol);
260}
bool bounds_point(const Point &p, Real relative_tol=0) const
Definition tree_node.C:265

References libMesh::libmesh_assert().

◆ bounds_point()

template<unsigned int N>
bool libMesh::TreeNode< N >::bounds_point ( const Point p,
Real  relative_tol = 0 
) const
Returns
true if this TreeNode (or its children) contain point p (within relative tolerance), false otherwise.

Definition at line 265 of file tree_node.C.

267{
268 const Point & min = bounding_box.first;
269 const Point & max = bounding_box.second;
270
271 const Real tol = (max - min).norm() * relative_tol;
272
273 if ((p(0) >= min(0) - tol)
274 && (p(0) <= max(0) + tol)
275#if LIBMESH_DIM > 1
276 && (p(1) >= min(1) - tol)
277 && (p(1) <= max(1) + tol)
278#endif
279#if LIBMESH_DIM > 2
280 && (p(2) >= min(2) - tol)
281 && (p(2) <= max(2) + tol)
282#endif
283 )
284 return true;
285
286 return false;
287}
BoundingBox bounding_box
The Cartesian bounding box for the node.
Definition tree_node.h:223
auto norm(const T &a)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

References libMesh::Real.

◆ create_bounding_box()

template<unsigned int N>
BoundingBox libMesh::TreeNode< N >::create_bounding_box ( unsigned int  c) const
private

Constructs the bounding box for child c.

Definition at line 293 of file tree_node.C.

294{
295 switch (N)
296 {
297 // How to refine an OctTree Node
298 case 8:
299 {
300 const Real xmin = bounding_box.first(0);
301 const Real ymin = bounding_box.first(1);
302 const Real zmin = bounding_box.first(2);
303
304 const Real xmax = bounding_box.second(0);
305 const Real ymax = bounding_box.second(1);
306 const Real zmax = bounding_box.second(2);
307
308 const Real xc = .5*(xmin + xmax);
309 const Real yc = .5*(ymin + ymax);
310 const Real zc = .5*(zmin + zmax);
311
312 switch (c)
313 {
314 case 0:
315 return BoundingBox (Point(xmin, ymin, zmin),
316 Point(xc, yc, zc));
317 case 1:
318 return BoundingBox (Point(xc, ymin, zmin),
319 Point(xmax, yc, zc));
320 case 2:
321 return BoundingBox (Point(xmin, yc, zmin),
322 Point(xc, ymax, zc));
323 case 3:
324 return BoundingBox (Point(xc, yc, zmin),
325 Point(xmax, ymax, zc));
326 case 4:
327 return BoundingBox (Point(xmin, ymin, zc),
328 Point(xc, yc, zmax));
329 case 5:
330 return BoundingBox (Point(xc, ymin, zc),
331 Point(xmax, yc, zmax));
332 case 6:
333 return BoundingBox (Point(xmin, yc, zc),
334 Point(xc, ymax, zmax));
335 case 7:
336 return BoundingBox (Point(xc, yc, zc),
337 Point(xmax, ymax, zmax));
338 default:
339 libmesh_error_msg("c >= N! : " << c);
340 }
341
342 break;
343 } // case 8
344
345 // How to refine an QuadTree Node
346 case 4:
347 {
348 const Real xmin = bounding_box.first(0);
349 const Real ymin = bounding_box.first(1);
350
351 const Real xmax = bounding_box.second(0);
352 const Real ymax = bounding_box.second(1);
353
354 const Real xc = .5*(xmin + xmax);
355 const Real yc = .5*(ymin + ymax);
356
357 switch (c)
358 {
359 case 0:
360 return BoundingBox (Point(xmin, ymin),
361 Point(xc, yc));
362 case 1:
363 return BoundingBox (Point(xc, ymin),
364 Point(xmax, yc));
365 case 2:
366 return BoundingBox (Point(xmin, yc),
367 Point(xc, ymax));
368 case 3:
369 return BoundingBox (Point(xc, yc),
370 Point(xmax, ymax));
371 default:
372 libmesh_error_msg("c >= N!");
373 }
374
375 break;
376 } // case 4
377
378 // How to refine a BinaryTree Node
379 case 2:
380 {
381 const Real xmin = bounding_box.first(0);
382
383 const Real xmax = bounding_box.second(0);
384
385 const Real xc = .5*(xmin + xmax);
386
387 switch (c)
388 {
389 case 0:
390 return BoundingBox (Point(xmin),
391 Point(xc));
392 case 1:
393 return BoundingBox (Point(xc),
394 Point(xmax));
395 default:
396 libmesh_error_msg("c >= N!");
397 }
398
399 break;
400 } // case 2
401
402 default:
403 libmesh_error_msg("Only implemented for Octrees, QuadTrees, and Binary Trees!");
404 }
405}

References libMesh::Real.

◆ find_element()

template<unsigned int N>
const Elem * libMesh::TreeNode< N >::find_element ( const Point p,
const std::set< subdomain_id_type > *  allowed_subdomains = nullptr,
Real  relative_tol = TOLERANCE 
) const
Returns
An element containing point p, optionally restricted to a set of allowed subdomains.

Definition at line 577 of file tree_node.C.

580{
581 if (this->active())
582 {
583 // Only check our children if the point is in our bounding box
584 // or if the node contains infinite elements
585 if (this->bounds_point(p, relative_tol) || this->contains_ifems)
586 // Search the active elements in the active TreeNode.
587 for (const auto & elem : elements)
588 if (!allowed_subdomains || allowed_subdomains->count(elem->subdomain_id()))
589 if (elem->active())
590 {
591 bool found = relative_tol > TOLERANCE
592 ? elem->close_to_point(p, relative_tol)
593 : elem->contains_point(p);
594
595 if (found)
596 return elem;
597 }
598
599 // The point was not found in any element
600 return nullptr;
601 }
602 else
603 return this->find_element_in_children(p,allowed_subdomains,
604 relative_tol);
605}
const Elem * find_element_in_children(const Point &p, const std::set< subdomain_id_type > *allowed_subdomains, Real relative_tol) const
Look for point p in our children, optionally restricted to a set of allowed subdomains.
Definition tree_node.C:642
static constexpr Real TOLERANCE

References libMesh::Elem::close_to_point(), and libMesh::TOLERANCE.

◆ find_element_in_children()

template<unsigned int N>
const Elem * libMesh::TreeNode< N >::find_element_in_children ( const Point p,
const std::set< subdomain_id_type > *  allowed_subdomains,
Real  relative_tol 
) const
private

Look for point p in our children, optionally restricted to a set of allowed subdomains.

Definition at line 642 of file tree_node.C.

645{
646 libmesh_assert (!this->active());
647
648 // value-initialization sets all array members to false
649 auto searched_child = std::array<bool, N>();
650
651 // First only look in the children whose bounding box
652 // contain the point p.
653 for (auto c : index_range(children))
654 if (children[c]->bounds_point(p, relative_tol))
655 {
656 const Elem * e =
657 children[c]->find_element(p,allowed_subdomains,
658 relative_tol);
659
660 if (e != nullptr)
661 return e;
662
663 // If we get here then a child that bounds the
664 // point does not have any elements that contain
665 // the point. So, we will search all our children.
666 // However, we have already searched child c so there
667 // is no use searching her again.
668 searched_child[c] = true;
669 }
670
671
672 // If we get here then our child whose bounding box
673 // was searched and did not find any elements containing
674 // the point p. So, let's look at the other children
675 // but exclude the one we have already searched.
676 for (auto c : index_range(children))
677 if (!searched_child[c])
678 {
679 const Elem * e =
680 children[c]->find_element(p,allowed_subdomains,
681 relative_tol);
682
683 if (e != nullptr)
684 return e;
685 }
686
687 // If we get here we have searched all our children.
688 // Since this process was started at the root node then
689 // we have searched all the elements in the tree without
690 // success. So, we should return nullptr since at this point
691 // _no_ elements in the tree claim to contain point p.
692 return nullptr;
693}
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition int_range.h:153

References libMesh::index_range(), and libMesh::libmesh_assert().

◆ find_elements()

template<unsigned int N>
void libMesh::TreeNode< N >::find_elements ( const Point p,
std::set< const Elem * > &  candidate_elements,
const std::set< subdomain_id_type > *  allowed_subdomains = nullptr,
Real  relative_tol = TOLERANCE 
) const

Adds to candidate_elements any elements containing the specified point p, optionally restricted to a set of allowed subdomains, optionally using a non-default relative tolerance for searches.

Definition at line 611 of file tree_node.C.

615{
616 if (this->active())
617 {
618 // Only check our children if the point is in our bounding box
619 // or if the node contains infinite elements
620 if (this->bounds_point(p, relative_tol) || this->contains_ifems)
621 // Search the active elements in the active TreeNode.
622 for (const auto & elem : elements)
623 if (!allowed_subdomains || allowed_subdomains->count(elem->subdomain_id()))
624 if (elem->active())
625 {
626 bool found = relative_tol > TOLERANCE
627 ? elem->close_to_point(p, relative_tol)
628 : elem->contains_point(p);
629
630 if (found)
631 candidate_elements.insert(elem);
632 }
633 }
634 else
635 this->find_elements_in_children(p, candidate_elements,
636 allowed_subdomains, relative_tol);
637}
void find_elements_in_children(const Point &p, std::set< const Elem * > &candidate_elements, const std::set< subdomain_id_type > *allowed_subdomains, Real relative_tol) const
Look for points in our children, optionally restricted to a set of allowed subdomains.
Definition tree_node.C:698

References libMesh::TOLERANCE.

◆ find_elements_in_children()

template<unsigned int N>
void libMesh::TreeNode< N >::find_elements_in_children ( const Point p,
std::set< const Elem * > &  candidate_elements,
const std::set< subdomain_id_type > *  allowed_subdomains,
Real  relative_tol 
) const
private

Look for points in our children, optionally restricted to a set of allowed subdomains.

Definition at line 698 of file tree_node.C.

702{
703 libmesh_assert (!this->active());
704
705 // First only look in the children whose bounding box
706 // contain the point p.
707 for (std::size_t c=0; c<children.size(); c++)
708 if (children[c]->bounds_point(p, relative_tol))
709 children[c]->find_elements(p, candidate_elements,
710 allowed_subdomains, relative_tol);
711}

References libMesh::libmesh_assert().

◆ insert() [1/2]

template<unsigned int N>
bool libMesh::TreeNode< N >::insert ( const Elem nd)

Inserts Elem el into the TreeNode.

Returns
true iff el is inserted into the TreeNode or one of its children.

Definition at line 71 of file tree_node.C.

72{
73 libmesh_assert(elem);
74
75 // We first want to find the corners of the cuboid surrounding the cell.
76 const BoundingBox bbox = elem->loose_bounding_box();
77
78 // If we are using a QuadTree, it's either because LIBMESH_DIM==2 or
79 // we have a planar xy mesh. Either way, the bounding box
80 // comparison in this case needs to do something slightly different
81 // for the z-coordinate.
82 bool bboxes_intersect = false;
83
84 if (N == 8) // OctTree
85 bboxes_intersect = this->bounding_box.intersects(bbox);
86 else if (N == 4) // QuadTree
87 {
88 // Perform a specialized BoundingBox intersection check that
89 // ignores z-coords. Copied from geom/bounding_box.C Check for
90 // "real" intersection in the x and y directions, then check
91 // that the z-coordinate is "close".
92
93 // Helper macro
94#define IS_BETWEEN(min, check, max) \
95 ((min) <= (check) && (check) <= (max))
96
97 // Make local variables first to make things more clear in a moment
98 const Real & elem_min_x = bbox.first(0);
99 const Real & elem_max_x = bbox.second(0);
100 const Real & tree_min_x = this->bounding_box.first(0);
101 const Real & tree_max_x = this->bounding_box.second(0);
102
103 const Real & elem_min_y = bbox.first(1);
104 const Real & elem_max_y = bbox.second(1);
105 const Real & tree_min_y = this->bounding_box.first(1);
106 const Real & tree_max_y = this->bounding_box.second(1);
107
108 bool x_int =
109 IS_BETWEEN(elem_min_x, tree_min_x, elem_max_x) ||
110 IS_BETWEEN(elem_min_x, tree_max_x, elem_max_x) ||
111 IS_BETWEEN(tree_min_x, elem_min_x, tree_max_x) ||
112 IS_BETWEEN(tree_min_x, elem_max_x, tree_max_x);
113
114 bool y_int =
115 IS_BETWEEN(elem_min_y, tree_min_y, elem_max_y) ||
116 IS_BETWEEN(elem_min_y, tree_max_y, elem_max_y) ||
117 IS_BETWEEN(tree_min_y, elem_min_y, tree_max_y) ||
118 IS_BETWEEN(tree_min_y, elem_max_y, tree_max_y);
119
120 // When LIBMESH_DIM==3, check that the z-coordinates of the elem
121 // bbox and the tree bbox are "close" since the QuadTree is
122 // meant to work in the case when the mesh is planar_xy but not
123 // necessarily lying in the z=0 plane.
124 bool z_match = true;
125 if (LIBMESH_DIM == 3)
126 {
127 const Real & elem_min_z = bbox.first(2);
128 const Real & elem_max_z = bbox.second(2);
129 const Real & tree_min_z = this->bounding_box.first(2);
130 const Real & tree_max_z = this->bounding_box.second(2);
131
132 z_match =
133 (std::abs(elem_min_z - elem_max_z) < TOLERANCE) &&
134 (std::abs(tree_min_z - tree_max_z) < TOLERANCE) &&
135 (std::abs(elem_min_z - tree_max_z) < TOLERANCE);
136 }
137
138 bboxes_intersect = z_match && x_int && y_int;
139 }
140 else // binary tree
141 {
142 // TODO: implement 1D bounding box intersection check
143 libmesh_not_implemented();
144 }
145
146 // Next, find out whether this cuboid has got non-empty intersection
147 // with the bounding box of the current tree node.
148 //
149 // If not, we should not care about this element.
150 if (!bboxes_intersect)
151 return false;
152
153 // Only add the element if we are active
154 if (this->active())
155 {
156 elements.push_back (elem);
157
158#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
159
160 // flag indicating this node contains
161 // infinite elements
162 if (elem->infinite())
163 this->contains_ifems = true;
164
165#endif
166
167 unsigned int element_count = cast_int<unsigned int>(elements.size());
169 {
170 const std::set<unsigned char> & elem_dimensions = mesh.elem_dimensions();
171 if (elem_dimensions.size() > 1)
172 {
173 element_count = 0;
174 unsigned char highest_dim_elem = *elem_dimensions.rbegin();
175 for (const Elem * other_elem : elements)
176 if (other_elem->dim() == highest_dim_elem)
177 element_count++;
178 }
179 }
180
181 // Refine ourself if we reach the target bin size for a TreeNode.
182 if (element_count == tgt_bin_size)
183 this->refine();
184
185 return true;
186 }
187
188 // If we are not active simply pass the element along to
189 // our children
190 libmesh_assert_equal_to (children.size(), N);
191
192 bool was_inserted = false;
193 for (unsigned int c=0; c<N; c++)
194 if (children[c]->insert (elem))
195 was_inserted = true;
196 return was_inserted;
197}
unsigned int dim
bool intersects(const BoundingBox &) const
const std::set< unsigned char > & elem_dimensions() const
Definition mesh_base.h:430
bool get_count_lower_dim_elems_in_point_locator() const
Get the current value of _count_lower_dim_elems_in_point_locator.
Definition mesh_base.C:1880
void refine()
Refine the tree node into N children if it contains more than tol nodes.
Definition tree_node.C:202
bool insert(const Node *nd)
Tries to insert Node nd into the TreeNode.
Definition tree_node.C:36

References libMesh::MeshBase::elem_dimensions(), libMesh::MeshBase::get_count_lower_dim_elems_in_point_locator(), libMesh::Elem::infinite(), libMesh::BoundingBox::intersects(), libMesh::libmesh_assert(), libMesh::Elem::loose_bounding_box(), mesh, libMesh::Real, and libMesh::TOLERANCE.

◆ insert() [2/2]

template<unsigned int N>
bool libMesh::TreeNode< N >::insert ( const Node nd)

Tries to insert Node nd into the TreeNode.

Returns
true iff nd is inserted into the TreeNode or one of its children.

Definition at line 36 of file tree_node.C.

37{
39 libmesh_assert_less (nd->id(), mesh.n_nodes());
40
41 // Return if we don't bound the node
42 if (!this->bounds_node(nd))
43 return false;
44
45 // Add the node to ourself if we are active
46 if (this->active())
47 {
48 nodes.push_back (nd);
49
50 // Refine ourself if we reach the target bin size for a TreeNode.
51 if (nodes.size() == tgt_bin_size)
52 this->refine();
53
54 return true;
55 }
56
57 // If we are not active simply pass the node along to
58 // our children
59 libmesh_assert_equal_to (children.size(), N);
60
61 bool was_inserted = false;
62 for (unsigned int c=0; c<N; c++)
63 if (children[c]->insert (nd))
64 was_inserted = true;
65 return was_inserted;
66}
virtual dof_id_type n_nodes() const =0
bool bounds_node(const Node *nd, Real relative_tol=0) const
Definition tree_node.C:255

References libMesh::DofObject::id(), libMesh::libmesh_assert(), mesh, and libMesh::MeshBase::n_nodes().

◆ is_root()

template<unsigned int N>
bool libMesh::TreeNode< N >::is_root ( ) const
inline
Returns
true if this node is the root node, false otherwise.

Definition at line 82 of file tree_node.h.

82{ return (parent == nullptr); }

References libMesh::TreeNode< N >::parent.

◆ level()

template<unsigned int N>
unsigned int libMesh::TreeNode< N >::level ( ) const
inline
Returns
The level of the node.

Definition at line 286 of file tree_node.h.

287{
288 if (parent != nullptr)
289 return parent->level()+1;
290
291 // if we have no parent, we are a level-0 box
292 return 0;
293}

◆ n_active_bins()

template<unsigned int N>
unsigned int libMesh::TreeNode< N >::n_active_bins ( ) const
Returns
The number of active bins below (including) this element.

Definition at line 557 of file tree_node.C.

558{
559 if (this->active())
560 return 1;
561
562 else
563 {
564 unsigned int sum=0;
565
566 for (const auto & child : children)
567 sum += child->n_active_bins();
568
569 return sum;
570 }
571}
unsigned int n_active_bins() const
Definition tree_node.C:557

◆ print_elements()

template<unsigned int N>
void libMesh::TreeNode< N >::print_elements ( std::ostream &  out_stream = libMesh::out) const

Prints the contents of the elements set if we are active.

Definition at line 429 of file tree_node.C.

430{
431 if (this->active())
432 {
433 out_stream << "TreeNode Level: " << this->level() << std::endl;
434
435 for (const auto & elem : elements)
436 out_stream << " " << elem;
437
438 out_stream << std::endl << std::endl;
439 }
440 else
441 for (const auto & child : children)
442 child->print_elements();
443}
void print_elements(std::ostream &out_stream=libMesh::out) const
Prints the contents of the elements set if we are active.
Definition tree_node.C:429
unsigned int level() const
Definition tree_node.h:286

◆ print_nodes()

template<unsigned int N>
void libMesh::TreeNode< N >::print_nodes ( std::ostream &  out_stream = libMesh::out) const

Prints the contents of the node_numbers vector if we are active.

Definition at line 410 of file tree_node.C.

411{
412 if (this->active())
413 {
414 out_stream << "TreeNode Level: " << this->level() << std::endl;
415
416 for (const Node * node : nodes)
417 out_stream << " " << node->id();
418
419 out_stream << std::endl << std::endl;
420 }
421 else
422 for (const auto & child : children)
423 child->print_nodes();
424}
void print_nodes(std::ostream &out_stream=libMesh::out) const
Prints the contents of the node_numbers vector if we are active.
Definition tree_node.C:410

◆ refine()

template<unsigned int N>
void libMesh::TreeNode< N >::refine ( )

Refine the tree node into N children if it contains more than tol nodes.

Definition at line 202 of file tree_node.C.

203{
204 // Huh? better be active...
205 libmesh_assert (this->active());
206 libmesh_assert (children.empty());
207
208 // A TreeNode<N> has by definition N children
209 children.resize(N);
210
211 // Scale up the target bin size in child TreeNodes if we have reached
212 // the maximum number of refinement levels.
213 unsigned int new_target_bin_size = tgt_bin_size;
215 {
216 new_target_bin_size *= 2;
217 }
218
219 for (unsigned int c=0; c<N; c++)
220 {
221 // Create the child and set its bounding box.
222 children[c] = std::make_unique<TreeNode<N>>(mesh, new_target_bin_size, this);
223 children[c]->set_bounding_box(this->create_bounding_box(c));
224
225 // Pass off our nodes to our children
226 for (const Node * node : nodes)
227 children[c]->insert(node);
228
229 // Pass off our elements to our children
230 for (const Elem * elem : elements)
231 children[c]->insert(elem);
232 }
233
234 // We don't need to store nodes or elements any more, they have been
235 // added to the children. Use the "swap trick" to actually reduce
236 // the capacity of these vectors.
237 std::vector<const Node *>().swap(nodes);
238 std::vector<const Elem *>().swap(elements);
239
240 libmesh_assert_equal_to (nodes.capacity(), 0);
241 libmesh_assert_equal_to (elements.capacity(), 0);
242}
BoundingBox create_bounding_box(unsigned int c) const
Constructs the bounding box for child c.
Definition tree_node.C:293

References libMesh::libmesh_assert(), and mesh.

◆ set_bounding_box()

template<unsigned int N>
void libMesh::TreeNode< N >::set_bounding_box ( const std::pair< Point, Point > &  bbox)

Sets the bounding box;.

Definition at line 247 of file tree_node.C.

248{
249 bounding_box = bbox;
250}

◆ transform_nodes_to_elements() [1/2]

template<unsigned int N>
void libMesh::TreeNode< N >::transform_nodes_to_elements ( std::unordered_map< dof_id_type, std::vector< const Elem * > > &  nodes_to_elem)

Transforms node numbers to element pointers.

Definition at line 503 of file tree_node.C.

504{
505 if (this->active())
506 {
507 elements.clear();
508
509 // Temporarily use a set. Since multiple nodes
510 // will likely map to the same element we use a
511 // set to eliminate the duplication.
512 std::set<const Elem *> elements_set;
513
514 for (const Node * node : nodes)
515 {
516 // the actual global node number we are replacing
517 // with the connected elements
518 const dof_id_type node_number = node->id();
519
520 libmesh_assert_less (node_number, mesh.n_nodes());
521
522 auto & my_elems = nodes_to_elem[node_number];
523 elements_set.insert(my_elems.begin(), my_elems.end());
524 }
525
526 // Done with the nodes.
527 std::vector<const Node *>().swap(nodes);
528
529 // Now the set is built. We can copy this to the
530 // vector. Note that the resulting vector will
531 // already be sorted, and will require less memory
532 // than the set.
533 elements.reserve(elements_set.size());
534
535 for (const auto & elem : elements_set)
536 {
537 elements.push_back(elem);
538
539#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
540
541 // flag indicating this node contains
542 // infinite elements
543 if (elem->infinite())
544 this->contains_ifems = true;
545
546#endif
547 }
548 }
549 else
550 for (auto & child : children)
551 child->transform_nodes_to_elements (nodes_to_elem);
552}
void transform_nodes_to_elements(std::vector< std::vector< const Elem * > > &nodes_to_elem)
Transforms node numbers to element pointers.
Definition tree_node.C:448
uint8_t dof_id_type
Definition id_types.h:67

References mesh, and libMesh::MeshBase::n_nodes().

◆ transform_nodes_to_elements() [2/2]

template<unsigned int N>
void libMesh::TreeNode< N >::transform_nodes_to_elements ( std::vector< std::vector< const Elem * > > &  nodes_to_elem)

Transforms node numbers to element pointers.

Definition at line 448 of file tree_node.C.

449{
450 if (this->active())
451 {
452 elements.clear();
453
454 // Temporarily use a set. Since multiple nodes
455 // will likely map to the same element we use a
456 // set to eliminate the duplication.
457 std::set<const Elem *> elements_set;
458
459 for (const Node * node : nodes)
460 {
461 // the actual global node number we are replacing
462 // with the connected elements
463 const dof_id_type node_number = node->id();
464
465 libmesh_assert_less (node_number, mesh.n_nodes());
466 libmesh_assert_less (node_number, nodes_to_elem.size());
467
468 for (const Elem * elem : nodes_to_elem[node_number])
469 elements_set.insert(elem);
470 }
471
472 // Done with the nodes.
473 std::vector<const Node *>().swap(nodes);
474
475 // Now the set is built. We can copy this to the
476 // vector. Note that the resulting vector will
477 // already be sorted, and will require less memory
478 // than the set.
479 elements.reserve(elements_set.size());
480
481 for (const auto & elem : elements_set)
482 {
483 elements.push_back(elem);
484
485#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
486
487 // flag indicating this node contains
488 // infinite elements
489 if (elem->infinite())
490 this->contains_ifems = true;
491
492#endif
493 }
494 }
495 else
496 for (auto & child : children)
497 child->transform_nodes_to_elements (nodes_to_elem);
498}

References mesh, and libMesh::MeshBase::n_nodes().

Member Data Documentation

◆ bounding_box

template<unsigned int N>
BoundingBox libMesh::TreeNode< N >::bounding_box
private

The Cartesian bounding box for the node.

Definition at line 223 of file tree_node.h.

◆ children

template<unsigned int N>
std::vector<std::unique_ptr<TreeNode<N> > > libMesh::TreeNode< N >::children
private

Pointers to our children.

This vector is empty if the node is active.

Definition at line 218 of file tree_node.h.

Referenced by libMesh::TreeNode< N >::active(), and libMesh::TreeNode< N >::TreeNode().

◆ contains_ifems

template<unsigned int N>
bool libMesh::TreeNode< N >::contains_ifems
private

Does this node contain any infinite elements.

Definition at line 253 of file tree_node.h.

◆ elements

template<unsigned int N>
std::vector<const Elem *> libMesh::TreeNode< N >::elements
private

Pointers to the elements in this tree node.

Definition at line 228 of file tree_node.h.

Referenced by libMesh::TreeNode< N >::TreeNode().

◆ mesh

template<unsigned int N>
const MeshBase& libMesh::TreeNode< N >::mesh
private

Reference to the mesh.

Definition at line 207 of file tree_node.h.

◆ nodes

template<unsigned int N>
std::vector<const Node *> libMesh::TreeNode< N >::nodes
private

The node numbers contained in this portion of the tree.

Definition at line 233 of file tree_node.h.

Referenced by libMesh::TreeNode< N >::TreeNode().

◆ parent

template<unsigned int N>
const TreeNode<N>* libMesh::TreeNode< N >::parent
private

Pointer to this node's parent.

Definition at line 212 of file tree_node.h.

Referenced by libMesh::TreeNode< N >::is_root().

◆ target_bin_size_increase_level

template<unsigned int N>
unsigned int libMesh::TreeNode< N >::target_bin_size_increase_level
private

This specifies the refinement level beyond which we will scale up the target bin size in child TreeNodes.

We set the default to be 10, which should be large enough such that in most cases the target bin size does not need to be increased.

Definition at line 248 of file tree_node.h.

◆ tgt_bin_size

template<unsigned int N>
const unsigned int libMesh::TreeNode< N >::tgt_bin_size
private

The maximum number of things we should store before refining ourself.

Definition at line 239 of file tree_node.h.

Referenced by libMesh::TreeNode< N >::TreeNode().


The documentation for this class was generated from the following files: