libMesh::TreeNode< N > Class Template Reference

Base class for different Tree types. More...

#include <tree_node.h>

Public Member Functions

 TreeNode (const MeshBase &m, unsigned int tbs, const TreeNode< N > *p=nullptr)
 
 ~TreeNode ()
 
bool is_root () const
 
bool active () const
 
bool insert (const Node *nd)
 
bool insert (const Elem *nd)
 
void refine ()
 
void set_bounding_box (const std::pair< Point, Point > &bbox)
 
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=libMesh::out) const
 
void print_elements (std::ostream &out=libMesh::out) const
 
void transform_nodes_to_elements (std::vector< std::vector< const Elem *>> &nodes_to_elem)
 
void transform_nodes_to_elements (std::unordered_map< dof_id_type, std::vector< const Elem *>> &nodes_to_elem)
 
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
 

Private Member Functions

const Elemfind_element_in_children (const Point &p, const std::set< subdomain_id_type > *allowed_subdomains, Real relative_tol) const
 
BoundingBox create_bounding_box (unsigned int c) const
 

Private Attributes

const MeshBasemesh
 
const TreeNode< N > * parent
 
std::vector< TreeNode< N > *> children
 
BoundingBox bounding_box
 
std::vector< const Elem * > elements
 
std::vector< const Node * > nodes
 
const unsigned int tgt_bin_size
 
unsigned int target_bin_size_increase_level
 
bool contains_ifems
 

Detailed Description

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

Base class for different Tree types.

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

Definition at line 53 of file tree_node.h.

Constructor & Destructor Documentation

◆ TreeNode()

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 239 of file tree_node.h.

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

241  :
242  mesh (m),
243  parent (p),
244  tgt_bin_size (tbs),
246  contains_ifems (false)
247 {
248  // libmesh_assert our children are empty, thus we are active.
249  libmesh_assert (children.empty());
250  libmesh_assert (this->active());
251 
252  // Reserve space for the nodes & elements
253  nodes.reserve (tgt_bin_size);
254  elements.reserve (tgt_bin_size);
255 }
unsigned int target_bin_size_increase_level
Definition: tree_node.h:223
const TreeNode< N > * parent
Definition: tree_node.h:187
std::vector< const Node * > nodes
Definition: tree_node.h:208
bool active() const
Definition: tree_node.h:82
std::vector< const Elem * > elements
Definition: tree_node.h:203
const unsigned int tgt_bin_size
Definition: tree_node.h:214
const MeshBase & mesh
Definition: tree_node.h:182
std::vector< TreeNode< N > *> children
Definition: tree_node.h:193

◆ ~TreeNode()

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

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

Definition at line 261 of file tree_node.h.

262 {
263  // When we are destructed we must delete all of our
264  // children. They will this delete their children,
265  // All the way down the line...
266  for (std::size_t c=0; c<children.size(); c++)
267  delete children[c];
268 }
std::vector< TreeNode< N > *> children
Definition: tree_node.h:193

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 82 of file tree_node.h.

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

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

82 { return children.empty(); }
std::vector< TreeNode< N > *> children
Definition: tree_node.h:193

◆ 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 191 of file tree_node.C.

193 {
194  libmesh_assert(nd);
195  return bounds_point(*nd, relative_tol);
196 }
bool bounds_point(const Point &p, Real relative_tol=0) const
Definition: tree_node.C:201

◆ 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 201 of file tree_node.C.

References libMesh::MeshTools::bounding_box(), std::max(), std::min(), and libMesh::Real.

203 {
204  const Point & min = bounding_box.first;
205  const Point & max = bounding_box.second;
206 
207  const Real tol = (max - min).norm() * relative_tol;
208 
209  if ((p(0) >= min(0) - tol)
210  && (p(0) <= max(0) + tol)
211 #if LIBMESH_DIM > 1
212  && (p(1) >= min(1) - tol)
213  && (p(1) <= max(1) + tol)
214 #endif
215 #if LIBMESH_DIM > 2
216  && (p(2) >= min(2) - tol)
217  && (p(2) <= max(2) + tol)
218 #endif
219  )
220  return true;
221 
222  return false;
223 }
long double max(long double a, double b)
BoundingBox bounding_box
Definition: tree_node.h:198
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
long double min(long double a, double b)

◆ 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 229 of file tree_node.C.

References libMesh::MeshTools::bounding_box(), and libMesh::Real.

230 {
231  switch (N)
232  {
233  // How to refine an OctTree Node
234  case 8:
235  {
236  const Real xmin = bounding_box.first(0);
237  const Real ymin = bounding_box.first(1);
238  const Real zmin = bounding_box.first(2);
239 
240  const Real xmax = bounding_box.second(0);
241  const Real ymax = bounding_box.second(1);
242  const Real zmax = bounding_box.second(2);
243 
244  const Real xc = .5*(xmin + xmax);
245  const Real yc = .5*(ymin + ymax);
246  const Real zc = .5*(zmin + zmax);
247 
248  switch (c)
249  {
250  case 0:
251  return BoundingBox (Point(xmin, ymin, zmin),
252  Point(xc, yc, zc));
253  case 1:
254  return BoundingBox (Point(xc, ymin, zmin),
255  Point(xmax, yc, zc));
256  case 2:
257  return BoundingBox (Point(xmin, yc, zmin),
258  Point(xc, ymax, zc));
259  case 3:
260  return BoundingBox (Point(xc, yc, zmin),
261  Point(xmax, ymax, zc));
262  case 4:
263  return BoundingBox (Point(xmin, ymin, zc),
264  Point(xc, yc, zmax));
265  case 5:
266  return BoundingBox (Point(xc, ymin, zc),
267  Point(xmax, yc, zmax));
268  case 6:
269  return BoundingBox (Point(xmin, yc, zc),
270  Point(xc, ymax, zmax));
271  case 7:
272  return BoundingBox (Point(xc, yc, zc),
273  Point(xmax, ymax, zmax));
274  default:
275  libmesh_error_msg("c >= N! : " << c);
276  }
277 
278  break;
279  } // case 8
280 
281  // How to refine an QuadTree Node
282  case 4:
283  {
284  const Real xmin = bounding_box.first(0);
285  const Real ymin = bounding_box.first(1);
286 
287  const Real xmax = bounding_box.second(0);
288  const Real ymax = bounding_box.second(1);
289 
290  const Real xc = .5*(xmin + xmax);
291  const Real yc = .5*(ymin + ymax);
292 
293  switch (c)
294  {
295  case 0:
296  return BoundingBox (Point(xmin, ymin),
297  Point(xc, yc));
298  case 1:
299  return BoundingBox (Point(xc, ymin),
300  Point(xmax, yc));
301  case 2:
302  return BoundingBox (Point(xmin, yc),
303  Point(xc, ymax));
304  case 3:
305  return BoundingBox (Point(xc, yc),
306  Point(xmax, ymax));
307  default:
308  libmesh_error_msg("c >= N!");
309  }
310 
311  break;
312  } // case 4
313 
314  // How to refine a BinaryTree Node
315  case 2:
316  {
317  const Real xmin = bounding_box.first(0);
318 
319  const Real xmax = bounding_box.second(0);
320 
321  const Real xc = .5*(xmin + xmax);
322 
323  switch (c)
324  {
325  case 0:
326  return BoundingBox (Point(xmin),
327  Point(xc));
328  case 1:
329  return BoundingBox (Point(xc),
330  Point(xmax));
331  default:
332  libmesh_error_msg("c >= N!");
333  }
334 
335  break;
336  } // case 2
337 
338  default:
339  libmesh_error_msg("Only implemented for Octrees, QuadTrees, and Binary Trees!");
340  }
341 }
BoundingBox bounding_box
Definition: tree_node.h:198
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 523 of file tree_node.C.

526 {
527  if (this->active())
528  {
529  // Only check our children if the point is in our bounding box
530  // or if the node contains infinite elements
531  if (this->bounds_point(p, relative_tol) || this->contains_ifems)
532  // Search the active elements in the active TreeNode.
533  for (const auto & elem : elements)
534  if (!allowed_subdomains || allowed_subdomains->count(elem->subdomain_id()))
535  if (elem->active() && elem->contains_point(p, relative_tol))
536  return elem;
537 
538  // The point was not found in any element
539  return nullptr;
540  }
541  else
542  return this->find_element_in_children(p,allowed_subdomains,
543  relative_tol);
544 }
bool bounds_point(const Point &p, Real relative_tol=0) const
Definition: tree_node.C:201
bool active() const
Definition: tree_node.h:82
std::vector< const Elem * > elements
Definition: tree_node.h:203
const Elem * find_element_in_children(const Point &p, const std::set< subdomain_id_type > *allowed_subdomains, Real relative_tol) const
Definition: tree_node.C:550

◆ 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 550 of file tree_node.C.

553 {
554  libmesh_assert (!this->active());
555 
556  // value-initialization sets all array members to false
557  auto searched_child = std::array<bool, N>();
558 
559  // First only look in the children whose bounding box
560  // contain the point p.
561  for (std::size_t c=0; c<children.size(); c++)
562  if (children[c]->bounds_point(p, relative_tol))
563  {
564  const Elem * e =
565  children[c]->find_element(p,allowed_subdomains,
566  relative_tol);
567 
568  if (e != nullptr)
569  return e;
570 
571  // If we get here then a child that bounds the
572  // point does not have any elements that contain
573  // the point. So, we will search all our children.
574  // However, we have already searched child c so there
575  // is no use searching her again.
576  searched_child[c] = true;
577  }
578 
579 
580  // If we get here then our child whose bounding box
581  // was searched and did not find any elements containing
582  // the point p. So, let's look at the other children
583  // but exclude the one we have already searched.
584  for (std::size_t c=0; c<children.size(); c++)
585  if (!searched_child[c])
586  {
587  const Elem * e =
588  children[c]->find_element(p,allowed_subdomains,
589  relative_tol);
590 
591  if (e != nullptr)
592  return e;
593  }
594 
595  // If we get here we have searched all our children.
596  // Since this process was started at the root node then
597  // we have searched all the elements in the tree without
598  // success. So, we should return nullptr since at this point
599  // _no_ elements in the tree claim to contain point p.
600  return nullptr;
601 }
bool bounds_point(const Point &p, Real relative_tol=0) const
Definition: tree_node.C:201
bool active() const
Definition: tree_node.h:82
std::vector< TreeNode< N > *> children
Definition: tree_node.h:193

◆ 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(), 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 }
std::vector< const Node * > nodes
Definition: tree_node.h:208
bool bounds_node(const Node *nd, Real relative_tol=0) const
Definition: tree_node.C:191
bool active() const
Definition: tree_node.h:82
bool insert(const Node *nd)
Definition: tree_node.C:36
const unsigned int tgt_bin_size
Definition: tree_node.h:214
const MeshBase & mesh
Definition: tree_node.h:182
std::vector< TreeNode< N > *> children
Definition: tree_node.h:193
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 libMesh::MeshTools::bounding_box(), libMesh::MeshBase::elem_dimensions(), libMesh::MeshBase::get_count_lower_dim_elems_in_point_locator(), libMesh::Elem::infinite(), libMesh::BoundingBox::intersects(), libMesh::Elem::loose_bounding_box(), and mesh.

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  // Next, find out whether this cuboid has got non-empty intersection
79  // with the bounding box of the current tree node.
80  //
81  // If not, we should not care about this element.
82  if (!this->bounding_box.intersects(bbox))
83  return false;
84 
85  // Only add the element if we are active
86  if (this->active())
87  {
88  elements.push_back (elem);
89 
90 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
91 
92  // flag indicating this node contains
93  // infinite elements
94  if (elem->infinite())
95  this->contains_ifems = true;
96 
97 #endif
98 
99  unsigned int element_count = cast_int<unsigned int>(elements.size());
101  {
102  const std::set<unsigned char> & elem_dimensions = mesh.elem_dimensions();
103  if (elem_dimensions.size() > 1)
104  {
105  element_count = 0;
106  unsigned char highest_dim_elem = *elem_dimensions.rbegin();
107  for (std::size_t i=0; i<elements.size(); i++)
108  {
109  if (elements[i]->dim() == highest_dim_elem)
110  {
111  element_count++;
112  }
113  }
114  }
115  }
116 
117  // Refine ourself if we reach the target bin size for a TreeNode.
118  if (element_count == tgt_bin_size)
119  this->refine();
120 
121  return true;
122  }
123 
124  // If we are not active simply pass the element along to
125  // our children
126  libmesh_assert_equal_to (children.size(), N);
127 
128  bool was_inserted = false;
129  for (unsigned int c=0; c<N; c++)
130  if (children[c]->insert (elem))
131  was_inserted = true;
132  return was_inserted;
133 }
bool intersects(const BoundingBox &) const
Definition: bounding_box.C:35
bool get_count_lower_dim_elems_in_point_locator() const
Definition: mesh_base.C:531
bool active() const
Definition: tree_node.h:82
std::vector< const Elem * > elements
Definition: tree_node.h:203
bool insert(const Node *nd)
Definition: tree_node.C:36
const unsigned int tgt_bin_size
Definition: tree_node.h:214
BoundingBox bounding_box
Definition: tree_node.h:198
const std::set< unsigned char > & elem_dimensions() const
Definition: mesh_base.h:220
const MeshBase & mesh
Definition: tree_node.h:182
std::vector< TreeNode< N > *> children
Definition: tree_node.h:193

◆ 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 76 of file tree_node.h.

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

76 { return (parent == nullptr); }
const TreeNode< N > * parent
Definition: tree_node.h:187

◆ level()

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

Definition at line 274 of file tree_node.h.

275 {
276  if (parent != nullptr)
277  return parent->level()+1;
278 
279  // if we have no parent, we are a level-0 box
280  return 0;
281 }
const TreeNode< N > * parent
Definition: tree_node.h:187

◆ 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 503 of file tree_node.C.

504 {
505  if (this->active())
506  return 1;
507 
508  else
509  {
510  unsigned int sum=0;
511 
512  for (std::size_t c=0; c<children.size(); c++)
513  sum += children[c]->n_active_bins();
514 
515  return sum;
516  }
517 }
unsigned int n_active_bins() const
Definition: tree_node.C:503
bool active() const
Definition: tree_node.h:82
std::vector< TreeNode< N > *> children
Definition: tree_node.h:193

◆ print_elements()

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

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

Definition at line 367 of file tree_node.C.

368 {
369  if (this->active())
370  {
371  out_stream << "TreeNode Level: " << this->level() << std::endl;
372 
373  for (const auto & elem : elements)
374  out_stream << " " << elem;
375 
376  out_stream << std::endl << std::endl;
377  }
378  else
379  {
380  for (std::size_t child=0; child<children.size(); child++)
381  children[child]->print_elements();
382  }
383 }
bool active() const
Definition: tree_node.h:82
std::vector< const Elem * > elements
Definition: tree_node.h:203
unsigned int level() const
Definition: tree_node.h:274
void print_elements(std::ostream &out=libMesh::out) const
Definition: tree_node.C:367
std::vector< TreeNode< N > *> children
Definition: tree_node.h:193

◆ print_nodes()

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

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

Definition at line 346 of file tree_node.C.

347 {
348  if (this->active())
349  {
350  out_stream << "TreeNode Level: " << this->level() << std::endl;
351 
352  for (std::size_t n=0; n<nodes.size(); n++)
353  out_stream << " " << nodes[n]->id();
354 
355  out_stream << std::endl << std::endl;
356  }
357  else
358  {
359  for (std::size_t child=0; child<children.size(); child++)
360  children[child]->print_nodes();
361  }
362 }
std::vector< const Node * > nodes
Definition: tree_node.h:208
bool active() const
Definition: tree_node.h:82
void print_nodes(std::ostream &out=libMesh::out) const
Definition: tree_node.C:346
unsigned int level() const
Definition: tree_node.h:274
std::vector< TreeNode< N > *> children
Definition: tree_node.h:193

◆ 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 138 of file tree_node.C.

References libMesh::MeshTools::create_bounding_box(), mesh, libMesh::TreeNode< N >::set_bounding_box(), and swap().

139 {
140  // Huh? better be active...
141  libmesh_assert (this->active());
142  libmesh_assert (children.empty());
143 
144  // A TreeNode<N> has by definition N children
145  children.resize(N);
146 
147  // Scale up the target bin size in child TreeNodes if we have reached
148  // the maximum number of refinement levels.
149  unsigned int new_target_bin_size = tgt_bin_size;
151  {
152  new_target_bin_size *= 2;
153  }
154 
155  for (unsigned int c=0; c<N; c++)
156  {
157  // Create the child and set its bounding box.
158  children[c] = new TreeNode<N> (mesh, new_target_bin_size, this);
159  children[c]->set_bounding_box(this->create_bounding_box(c));
160 
161  // Pass off our nodes to our children
162  for (std::size_t n=0; n<nodes.size(); n++)
163  children[c]->insert(nodes[n]);
164 
165  // Pass off our elements to our children
166  for (std::size_t e=0; e<elements.size(); e++)
167  children[c]->insert(elements[e]);
168  }
169 
170  // We don't need to store nodes or elements any more, they have been
171  // added to the children. Use the "swap trick" to actually reduce
172  // the capacity of these vectors.
173  std::vector<const Node *>().swap(nodes);
174  std::vector<const Elem *>().swap(elements);
175 
176  libmesh_assert_equal_to (nodes.capacity(), 0);
177  libmesh_assert_equal_to (elements.capacity(), 0);
178 }
unsigned int target_bin_size_increase_level
Definition: tree_node.h:223
BoundingBox create_bounding_box(unsigned int c) const
Definition: tree_node.C:229
std::vector< const Node * > nodes
Definition: tree_node.h:208
bool active() const
Definition: tree_node.h:82
std::vector< const Elem * > elements
Definition: tree_node.h:203
bool insert(const Node *nd)
Definition: tree_node.C:36
const unsigned int tgt_bin_size
Definition: tree_node.h:214
void swap(Iterator &lhs, Iterator &rhs)
const MeshBase & mesh
Definition: tree_node.h:182
unsigned int level() const
Definition: tree_node.h:274
std::vector< TreeNode< N > *> children
Definition: tree_node.h:193

◆ 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 183 of file tree_node.C.

References libMesh::MeshTools::bounding_box().

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

184 {
185  bounding_box = bbox;
186 }
BoundingBox bounding_box
Definition: tree_node.h:198

◆ 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 388 of file tree_node.C.

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

389 {
390  if (this->active())
391  {
392  elements.clear();
393 
394  // Temporarily use a set. Since multiple nodes
395  // will likely map to the same element we use a
396  // set to eliminate the duplication.
397  std::set<const Elem *> elements_set;
398 
399  for (std::size_t n=0; n<nodes.size(); n++)
400  {
401  // the actual global node number we are replacing
402  // with the connected elements
403  const dof_id_type node_number = nodes[n]->id();
404 
405  libmesh_assert_less (node_number, mesh.n_nodes());
406  libmesh_assert_less (node_number, nodes_to_elem.size());
407 
408  for (std::size_t e=0; e<nodes_to_elem[node_number].size(); e++)
409  elements_set.insert(nodes_to_elem[node_number][e]);
410  }
411 
412  // Done with the nodes.
413  std::vector<const Node *>().swap(nodes);
414 
415  // Now the set is built. We can copy this to the
416  // vector. Note that the resulting vector will
417  // already be sorted, and will require less memory
418  // than the set.
419  elements.reserve(elements_set.size());
420 
421  for (const auto & elem : elements_set)
422  {
423  elements.push_back(elem);
424 
425 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
426 
427  // flag indicating this node contains
428  // infinite elements
429  if (elem->infinite())
430  this->contains_ifems = true;
431 
432 #endif
433  }
434  }
435  else
436  {
437  for (std::size_t child=0; child<children.size(); child++)
438  children[child]->transform_nodes_to_elements (nodes_to_elem);
439  }
440 
441 }
std::vector< const Node * > nodes
Definition: tree_node.h:208
void transform_nodes_to_elements(std::vector< std::vector< const Elem *>> &nodes_to_elem)
Definition: tree_node.C:388
bool active() const
Definition: tree_node.h:82
std::vector< const Elem * > elements
Definition: tree_node.h:203
void swap(Iterator &lhs, Iterator &rhs)
const MeshBase & mesh
Definition: tree_node.h:182
std::vector< TreeNode< N > *> children
Definition: tree_node.h:193
virtual dof_id_type n_nodes() const =0
uint8_t dof_id_type
Definition: id_types.h:64

◆ 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 446 of file tree_node.C.

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

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

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 198 of file tree_node.h.

◆ children

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

Pointers to our children. This vector is empty if the node is active.

Definition at line 193 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 228 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 203 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 182 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 208 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 187 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 223 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 214 of file tree_node.h.

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


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