libMesh
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. More...
 
 TreeNode (const TreeNode< N > &)=delete
 Class contains unique_ptrs and cannot be default copied. More...
 
 ~TreeNode ()=default
 Destructor. More...
 
bool is_root () const
 
bool active () const
 
bool insert (const Node *nd)
 Tries to insert Node nd into the TreeNode. More...
 
bool insert (const Elem *nd)
 Inserts Elem el into the TreeNode. More...
 
void refine ()
 Refine the tree node into N children if it contains more than tol nodes. More...
 
void set_bounding_box (const std::pair< Point, Point > &bbox)
 Sets the bounding box;. More...
 
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. More...
 
void print_elements (std::ostream &out_stream=libMesh::out) const
 Prints the contents of the elements set if we are active. More...
 
void transform_nodes_to_elements (std::vector< std::vector< const Elem *>> &nodes_to_elem)
 Transforms node numbers to element pointers. More...
 
void transform_nodes_to_elements (std::unordered_map< dof_id_type, std::vector< const Elem *>> &nodes_to_elem)
 Transforms node numbers to element pointers. More...
 
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
 Fills candidate_elements with any elements containing the specified point p, optionally restricted to a set of allowed subdomains, optionally using a non-default relative tolerance for searches. More...
 

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. More...
 
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. More...
 
BoundingBox create_bounding_box (unsigned int c) const
 Constructs the bounding box for child c. More...
 

Private Attributes

const MeshBasemesh
 Reference to the mesh. More...
 
const TreeNode< N > * parent
 Pointer to this node's parent. More...
 
std::vector< std::unique_ptr< TreeNode< N > > > children
 Pointers to our children. More...
 
BoundingBox bounding_box
 The Cartesian bounding box for the node. More...
 
std::vector< const Elem * > elements
 Pointers to the elements in this tree node. More...
 
std::vector< const Node * > nodes
 The node numbers contained in this portion of the tree. More...
 
const unsigned int tgt_bin_size
 The maximum number of things we should store before refining ourself. More...
 
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. More...
 
bool contains_ifems
 Does this node contain any infinite elements. More...
 

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.

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.

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 }
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
const TreeNode< N > * parent
Pointer to this node&#39;s parent.
Definition: tree_node.h:212
std::vector< const Node * > nodes
The node numbers contained in this portion of the tree.
Definition: tree_node.h:233
bool active() const
Definition: tree_node.h:88
std::vector< const Elem * > elements
Pointers to the elements in this tree node.
Definition: tree_node.h:228
std::vector< std::unique_ptr< TreeNode< N > > > children
Pointers to our children.
Definition: tree_node.h:218
const unsigned int tgt_bin_size
The maximum number of things we should store before refining ourself.
Definition: tree_node.h:239
libmesh_assert(ctx)
const MeshBase & mesh
Reference to the mesh.
Definition: tree_node.h:207
bool contains_ifems
Does this node contain any infinite elements.
Definition: tree_node.h:253

◆ 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.

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

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

88 { return children.empty(); }
std::vector< std::unique_ptr< TreeNode< N > > > children
Pointers to our children.
Definition: tree_node.h:218

◆ 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.

References libMesh::libmesh_assert().

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
libmesh_assert(ctx)

◆ 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.

References libMesh::TensorTools::norm(), and libMesh::Real.

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) -> decltype(std::abs(a))
Definition: tensor_tools.h:74
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE 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.

References libMesh::Real.

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 }
BoundingBox bounding_box
The Cartesian bounding box for the node.
Definition: tree_node.h:223
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE 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.

References libMesh::TOLERANCE.

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 }
static constexpr Real TOLERANCE
bool bounds_point(const Point &p, Real relative_tol=0) const
Definition: tree_node.C:265
bool active() const
Definition: tree_node.h:88
std::vector< const Elem * > elements
Pointers to the elements in this tree node.
Definition: tree_node.h:228
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
bool contains_ifems
Does this node contain any infinite elements.
Definition: tree_node.h:253

◆ 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.

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

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 }
bool bounds_point(const Point &p, Real relative_tol=0) const
Definition: tree_node.C:265
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
libmesh_assert(ctx)
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:111

◆ 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

Fills candidate_elements with 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.

References libMesh::TOLERANCE.

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 }
static constexpr Real TOLERANCE
bool bounds_point(const Point &p, Real relative_tol=0) const
Definition: tree_node.C:265
bool active() const
Definition: tree_node.h:88
std::vector< const Elem * > elements
Pointers to the elements in this tree node.
Definition: tree_node.h:228
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
bool contains_ifems
Does this node contain any infinite elements.
Definition: tree_node.h:253

◆ 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.

References libMesh::libmesh_assert().

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 }
bool bounds_point(const Point &p, Real relative_tol=0) const
Definition: tree_node.C:265
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
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
Fills candidate_elements with any elements containing the specified point p, optionally restricted to...
Definition: tree_node.C:611
libmesh_assert(ctx)

◆ insert() [1/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.

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

37 {
38  libmesh_assert(nd);
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 }
void refine()
Refine the tree node into N children if it contains more than tol nodes.
Definition: tree_node.C:202
std::vector< const Node * > nodes
The node numbers contained in this portion of the tree.
Definition: tree_node.h:233
bool bounds_node(const Node *nd, Real relative_tol=0) const
Definition: tree_node.C:255
bool active() const
Definition: tree_node.h:88
bool insert(const Node *nd)
Tries to insert Node nd into the TreeNode.
Definition: tree_node.C:36
std::vector< std::unique_ptr< TreeNode< N > > > children
Pointers to our children.
Definition: tree_node.h:218
const unsigned int tgt_bin_size
The maximum number of things we should store before refining ourself.
Definition: tree_node.h:239
libmesh_assert(ctx)
const MeshBase & mesh
Reference to the mesh.
Definition: tree_node.h:207
virtual dof_id_type n_nodes() const =0

◆ insert() [2/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.

References std::abs(), 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.

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 }
void refine()
Refine the tree node into N children if it contains more than tol nodes.
Definition: tree_node.C:202
static constexpr Real TOLERANCE
bool intersects(const BoundingBox &) const
Definition: bounding_box.h:165
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:1612
bool active() const
Definition: tree_node.h:88
std::vector< const Elem * > elements
Pointers to the elements in this tree node.
Definition: tree_node.h:228
bool insert(const Node *nd)
Tries to insert Node nd into the TreeNode.
Definition: tree_node.C:36
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
Definition: type_vector.h:57
std::vector< std::unique_ptr< TreeNode< N > > > children
Pointers to our children.
Definition: tree_node.h:218
const unsigned int tgt_bin_size
The maximum number of things we should store before refining ourself.
Definition: tree_node.h:239
BoundingBox bounding_box
The Cartesian bounding box for the node.
Definition: tree_node.h:223
libmesh_assert(ctx)
const std::set< unsigned char > & elem_dimensions() const
Definition: mesh_base.h:276
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const MeshBase & mesh
Reference to the mesh.
Definition: tree_node.h:207
bool contains_ifems
Does this node contain any infinite elements.
Definition: tree_node.h:253

◆ 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.

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

82 { return (parent == nullptr); }
const TreeNode< N > * parent
Pointer to this node&#39;s parent.
Definition: tree_node.h:212

◆ 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 }
const TreeNode< N > * parent
Pointer to this node&#39;s parent.
Definition: tree_node.h:212

◆ 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 }
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

◆ 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 }
bool active() const
Definition: tree_node.h:88
std::vector< const Elem * > elements
Pointers to the elements in this tree node.
Definition: tree_node.h:228
std::vector< std::unique_ptr< TreeNode< N > > > children
Pointers to our children.
Definition: tree_node.h:218
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 }
std::vector< const Node * > nodes
The node numbers contained in this portion of the tree.
Definition: tree_node.h:233
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
unsigned int level() const
Definition: tree_node.h:286

◆ 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.

References libMesh::MeshTools::create_bounding_box(), libMesh::libmesh_assert(), and mesh.

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 }
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
BoundingBox create_bounding_box(unsigned int c) const
Constructs the bounding box for child c.
Definition: tree_node.C:293
std::vector< const Node * > nodes
The node numbers contained in this portion of the tree.
Definition: tree_node.h:233
bool active() const
Definition: tree_node.h:88
std::vector< const Elem * > elements
Pointers to the elements in this tree node.
Definition: tree_node.h:228
std::vector< std::unique_ptr< TreeNode< N > > > children
Pointers to our children.
Definition: tree_node.h:218
const unsigned int tgt_bin_size
The maximum number of things we should store before refining ourself.
Definition: tree_node.h:239
libmesh_assert(ctx)
const MeshBase & mesh
Reference to the mesh.
Definition: tree_node.h:207
unsigned int level() const
Definition: tree_node.h:286

◆ 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 }
BoundingBox bounding_box
The Cartesian bounding box for the node.
Definition: tree_node.h:223

◆ transform_nodes_to_elements() [1/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.

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

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 }
std::vector< const Node * > nodes
The node numbers contained in this portion of the tree.
Definition: tree_node.h:233
bool active() const
Definition: tree_node.h:88
std::vector< const Elem * > elements
Pointers to the elements in this tree node.
Definition: tree_node.h:228
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
virtual dof_id_type n_nodes() const =0
bool contains_ifems
Does this node contain any infinite elements.
Definition: tree_node.h:253
uint8_t dof_id_type
Definition: id_types.h:67

◆ transform_nodes_to_elements() [2/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.

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

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 }
std::vector< const Node * > nodes
The node numbers contained in this portion of the tree.
Definition: tree_node.h:233
bool active() const
Definition: tree_node.h:88
std::vector< const Elem * > elements
Pointers to the elements in this tree node.
Definition: tree_node.h:228
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
virtual dof_id_type n_nodes() const =0
bool contains_ifems
Does this node contain any infinite elements.
Definition: tree_node.h:253
uint8_t dof_id_type
Definition: id_types.h:67

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: