libMesh
Functions
libMesh::ElemInternal Namespace Reference

The ElemInternal namespace holds helper functions that are used internally by the Elem class. More...

Functions

template<class T >
void family_tree (T elem, std::vector< T > &family, bool reset=true)
 
template<class T >
void total_family_tree (T elem, std::vector< T > &family, bool reset)
 
template<class T >
void active_family_tree (T elem, std::vector< T > &active_family, bool reset=true)
 
template<class T >
void family_tree_by_side (T elem, std::vector< T > &family, unsigned int s, bool reset)
 
template<class T >
void total_family_tree_by_side (T elem, std::vector< T > &family, unsigned int s, bool reset)
 
template<class T >
void active_family_tree_by_side (T elem, std::vector< T > &family, unsigned int side, bool reset=true)
 
template<class T >
void family_tree_by_neighbor (T elem, std::vector< T > &family, T neighbor_in, bool reset=true)
 
template<class T >
void total_family_tree_by_neighbor (T elem, std::vector< T > &family, T neighbor_in, bool reset=true)
 
template<class T >
void family_tree_by_subneighbor (T elem, std::vector< T > &family, T neighbor_in, T subneighbor, bool reset=true)
 
template<class T >
void total_family_tree_by_subneighbor (T elem, std::vector< T > &family, T neighbor_in, T subneighbor, bool reset=true)
 
template<class T >
void active_family_tree_by_neighbor (T elem, std::vector< T > &family, T neighbor_in, bool reset=true)
 
template<class T >
void active_family_tree_by_topological_neighbor (T elem, std::vector< T > &family, T neighbor_in, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb, bool reset=true)
 
template<class T >
void find_point_neighbors (T this_elem, std::set< T > &neighbor_set, T start_elem)
 
template<class T >
void find_interior_neighbors (T this_elem, std::set< T > &neighbor_set)
 

Detailed Description

The ElemInternal namespace holds helper functions that are used internally by the Elem class.

These should not be called directly, call the appropriate member functions on the Elem class instead.

Function Documentation

◆ active_family_tree()

template<class T >
void libMesh::ElemInternal::active_family_tree ( elem,
std::vector< T > &  active_family,
bool  reset = true 
)

Definition at line 90 of file elem_internal.h.

References libMesh::libmesh_assert().

Referenced by libMesh::Elem::active_family_tree().

93 {
94  // The "family tree" doesn't include subactive elements
95  libmesh_assert(!elem->subactive());
96 
97  // Clear the vector if the flag reset tells us to.
98  if (reset)
99  active_family.clear();
100 
101  // Add this element to the family tree if it is active
102  if (elem->active())
103  active_family.push_back(elem);
104 
105  // Otherwise recurse into the element's children.
106  // Do not clear the vector any more.
107  else
108  for (auto & c : elem->child_ref_range())
109  if (!c.is_remote())
110  ElemInternal::active_family_tree (&c, active_family, false);
111 }
void active_family_tree(T elem, std::vector< T > &active_family, bool reset=true)
Definition: elem_internal.h:90
libmesh_assert(ctx)

◆ active_family_tree_by_neighbor()

template<class T >
void libMesh::ElemInternal::active_family_tree_by_neighbor ( elem,
std::vector< T > &  family,
neighbor_in,
bool  reset = true 
)

Definition at line 349 of file elem_internal.h.

References libMesh::libmesh_assert().

Referenced by libMesh::Elem::active_family_tree_by_neighbor(), and libMesh::JumpErrorEstimator::estimate_error().

353 {
354  // The "family tree" doesn't include subactive elements or
355  // remote_elements
356  libmesh_assert(!elem->subactive());
357  libmesh_assert(!elem->is_remote());
358 
359  // Clear the vector if the flag reset tells us to.
360  if (reset)
361  family.clear();
362 
363  // This only makes sense if we're already a neighbor
364 #ifndef NDEBUG
365  if (elem->level() >= neighbor_in->level())
366  libmesh_assert (elem->has_neighbor(neighbor_in));
367 #endif
368 
369  // Add an active element to the family tree.
370  if (elem->active())
371  family.push_back(elem);
372 
373  // Or recurse into an ancestor element's children.
374  // Do not clear the vector any more.
375  else if (!elem->active())
376  for (auto & c : elem->child_ref_range())
377  if (!c.is_remote() && c.has_neighbor(neighbor_in))
378  ElemInternal::active_family_tree_by_neighbor (&c, family, neighbor_in, false);
379 }
void active_family_tree_by_neighbor(T elem, std::vector< T > &family, T neighbor_in, bool reset=true)
libmesh_assert(ctx)

◆ active_family_tree_by_side()

template<class T >
void libMesh::ElemInternal::active_family_tree_by_side ( elem,
std::vector< T > &  family,
unsigned int  side,
bool  reset = true 
)

Definition at line 178 of file elem_internal.h.

References libMesh::libmesh_assert().

Referenced by libMesh::Elem::active_family_tree_by_side().

182 {
183  // The "family tree" doesn't include subactive or remote elements
184  libmesh_assert(!elem->subactive());
185  libmesh_assert(!elem->is_remote());
186 
187  // Clear the vector if the flag reset tells us to.
188  if (reset)
189  family.clear();
190 
191  libmesh_assert_less (side, elem->n_sides());
192 
193  // Add an active element to the family tree.
194  if (elem->active())
195  family.push_back(elem);
196 
197  // Or recurse into an ancestor element's children.
198  // Do not clear the vector any more.
199  else
200  {
201  const unsigned int nc = elem->n_children();
202  for (unsigned int c = 0; c != nc; c++)
203  if (!elem->child_ptr(c)->is_remote() && elem->is_child_on_side(c, side))
204  ElemInternal::active_family_tree_by_side(elem->child_ptr(c), family, side, false);
205  }
206 }
void active_family_tree_by_side(T elem, std::vector< T > &family, unsigned int side, bool reset=true)
libmesh_assert(ctx)

◆ active_family_tree_by_topological_neighbor()

template<class T >
void libMesh::ElemInternal::active_family_tree_by_topological_neighbor ( elem,
std::vector< T > &  family,
neighbor_in,
const MeshBase mesh,
const PointLocatorBase point_locator,
const PeriodicBoundaries pb,
bool  reset = true 
)

Definition at line 385 of file elem_internal.h.

References libMesh::libmesh_assert(), and mesh.

Referenced by libMesh::Elem::active_family_tree_by_topological_neighbor().

392 {
393  // The "family tree" doesn't include subactive elements or
394  // remote_elements
395  libmesh_assert(!elem->subactive());
396  libmesh_assert(!elem->is_remote());
397 
398  // Clear the vector if the flag reset tells us to.
399  if (reset)
400  family.clear();
401 
402  // This only makes sense if we're already a topological neighbor
403 #ifndef NDEBUG
404  if (elem->level() >= neighbor_in->level())
405  libmesh_assert (elem->has_topological_neighbor(neighbor_in,
406  mesh,
407  point_locator,
408  pb));
409 #endif
410 
411  // Add an active element to the family tree.
412  if (elem->active())
413  family.push_back(elem);
414 
415  // Or recurse into an ancestor element's children.
416  // Do not clear the vector any more.
417  else if (!elem->active())
418  for (auto & c : elem->child_ref_range())
419  if (!c.is_remote() &&
420  c.has_topological_neighbor(neighbor_in, mesh, point_locator, pb))
421  c.active_family_tree_by_topological_neighbor
422  (family, neighbor_in, mesh, point_locator, pb, false);
423 }
MeshBase & mesh
libmesh_assert(ctx)

◆ family_tree()

template<class T >
void libMesh::ElemInternal::family_tree ( elem,
std::vector< T > &  family,
bool  reset = true 
)

Definition at line 41 of file elem_internal.h.

References libMesh::libmesh_assert().

Referenced by libMesh::Elem::family_tree().

44 {
45  // The "family tree" doesn't include subactive elements
46  libmesh_assert(!elem->subactive());
47 
48  // Clear the vector if the flag reset tells us to.
49  if (reset)
50  family.clear();
51 
52  // Add this element to the family tree.
53  family.push_back(elem);
54 
55  // Recurse into the elements children, if it has them.
56  // Do not clear the vector any more.
57  if (!elem->active())
58  for (auto & c : elem->child_ref_range())
59  if (!c.is_remote())
60  ElemInternal::family_tree (&c, family, false);
61 }
void family_tree(T elem, std::vector< T > &family, bool reset=true)
Definition: elem_internal.h:41
libmesh_assert(ctx)

◆ family_tree_by_neighbor()

template<class T >
void libMesh::ElemInternal::family_tree_by_neighbor ( elem,
std::vector< T > &  family,
neighbor_in,
bool  reset = true 
)

Definition at line 211 of file elem_internal.h.

References libMesh::libmesh_assert().

Referenced by libMesh::Elem::family_tree_by_neighbor().

215 {
216  // The "family tree" doesn't include subactive elements
217  libmesh_assert(!elem->subactive());
218 
219  // Clear the vector if the flag reset tells us to.
220  if (reset)
221  family.clear();
222 
223  // This only makes sense if we're already a neighbor
224  libmesh_assert (elem->has_neighbor(neighbor_in));
225 
226  // Add this element to the family tree.
227  family.push_back(elem);
228 
229  // Recurse into the elements children, if it's not active.
230  // Do not clear the vector any more.
231  if (!elem->active())
232  for (auto & c : elem->child_ref_range())
233  if (!c.is_remote() && c.has_neighbor(neighbor_in))
234  ElemInternal::family_tree_by_neighbor (&c, family, neighbor_in, false);
235 }
void family_tree_by_neighbor(T elem, std::vector< T > &family, T neighbor_in, bool reset=true)
libmesh_assert(ctx)

◆ family_tree_by_side()

template<class T >
void libMesh::ElemInternal::family_tree_by_side ( elem,
std::vector< T > &  family,
unsigned int  s,
bool  reset 
)

Definition at line 117 of file elem_internal.h.

References libMesh::libmesh_assert().

Referenced by libMesh::Elem::family_tree_by_side().

121 {
122  // The "family tree" doesn't include subactive elements
123  libmesh_assert(!elem->subactive());
124 
125  // Clear the vector if the flag reset tells us to.
126  if (reset)
127  family.clear();
128 
129  libmesh_assert_less (s, elem->n_sides());
130 
131  // Add this element to the family tree.
132  family.push_back(elem);
133 
134  // Recurse into the elements children, if it has them.
135  // Do not clear the vector any more.
136  if (!elem->active())
137  {
138  const unsigned int nc = elem->n_children();
139  for (unsigned int c = 0; c != nc; c++)
140  if (!elem->child_ptr(c)->is_remote() && elem->is_child_on_side(c, s))
141  ElemInternal::family_tree_by_side (elem->child_ptr(c), family, s, false);
142  }
143 }
libmesh_assert(ctx)
void family_tree_by_side(T elem, std::vector< T > &family, unsigned int s, bool reset)

◆ family_tree_by_subneighbor()

template<class T >
void libMesh::ElemInternal::family_tree_by_subneighbor ( elem,
std::vector< T > &  family,
neighbor_in,
subneighbor,
bool  reset = true 
)

Definition at line 266 of file elem_internal.h.

References libMesh::libmesh_assert().

Referenced by libMesh::Elem::family_tree_by_subneighbor().

271 {
272  // The "family tree" doesn't include subactive elements
273  libmesh_assert(!elem->subactive());
274 
275  // Clear the vector if the flag reset tells us to.
276  if (reset)
277  family.clear();
278 
279  // To simplify this function we need an existing neighbor
280  libmesh_assert (neighbor_in);
281  libmesh_assert (!neighbor_in->is_remote());
282  libmesh_assert (elem->has_neighbor(neighbor_in));
283 
284  // This only makes sense if subneighbor descends from neighbor
285  libmesh_assert (subneighbor);
286  libmesh_assert (!subneighbor->is_remote());
287  libmesh_assert (neighbor_in->is_ancestor_of(subneighbor));
288 
289  // Add this element to the family tree if applicable.
290  if (neighbor_in == subneighbor)
291  family.push_back(elem);
292 
293  // Recurse into the elements children, if it's not active.
294  // Do not clear the vector any more.
295  if (!elem->active())
296  for (auto & c : elem->child_ref_range())
297  if (!c.is_remote())
298  for (auto child_neigh : c.neighbor_ptr_range())
299  if (child_neigh &&
300  (child_neigh == neighbor_in || (child_neigh->parent() == neighbor_in &&
301  child_neigh->is_ancestor_of(subneighbor))))
302  ElemInternal::family_tree_by_subneighbor (&c, family, child_neigh, subneighbor, false);
303 }
libmesh_assert(ctx)
void family_tree_by_subneighbor(T elem, std::vector< T > &family, T neighbor_in, T subneighbor, bool reset=true)

◆ find_interior_neighbors()

template<class T >
void libMesh::ElemInternal::find_interior_neighbors ( this_elem,
std::set< T > &  neighbor_set 
)

Definition at line 501 of file elem_internal.h.

References dim, find_point_neighbors(), and libMesh::libmesh_assert().

Referenced by libMesh::Elem::find_interior_neighbors().

503 {
504  neighbor_set.clear();
505 
506  if ((this_elem->dim() >= LIBMESH_DIM) ||
507  !this_elem->interior_parent())
508  return;
509 
510  T ip = this_elem->interior_parent();
511  libmesh_assert (ip->contains_vertex_of(this_elem, true) ||
512  this_elem->contains_vertex_of(ip, true));
513 
514  libmesh_assert (!ip->subactive());
515 
516 #ifdef LIBMESH_ENABLE_AMR
517  while (!ip->active()) // only possible with AMR, be careful because
518  { // ip->child_ptr(c) is only good with AMR.
519  for (auto & child : ip->child_ref_range())
520  {
521  if (child.contains_vertex_of(this_elem, true) ||
522  this_elem->contains_vertex_of(&child, true))
523  {
524  ip = &child;
525  break;
526  }
527  }
528  }
529 #endif
530 
531  ElemInternal::find_point_neighbors(this_elem, neighbor_set, ip);
532 
533  // Now we have all point neighbors from the interior manifold, but
534  // we need to weed out any neighbors that *only* intersect us at one
535  // point (or at one edge, if we're a 1-D element in 3D).
536  //
537  // The refinement hierarchy helps us here: if the interior element
538  // has a lower or equal refinement level then we can discard it iff
539  // it doesn't contain all our vertices. If it has a higher
540  // refinement level then we can discard it iff we don't contain at
541  // least dim()+1 of its vertices
542  auto it = neighbor_set.begin();
543  const auto end = neighbor_set.end();
544 
545  while (it != end)
546  {
547  auto current = it++;
548  T current_elem = *current;
549 
550  // This won't invalidate iterator it, because it is already
551  // pointing to the next element
552  if (current_elem->level() > this_elem->level())
553  {
554  unsigned int vertices_contained = 0;
555  for (auto & n : current_elem->node_ref_range())
556  if (this_elem->contains_point(n))
557  vertices_contained++;
558 
559  if (vertices_contained <= this_elem->dim())
560  {
561  neighbor_set.erase(current);
562  continue;
563  }
564  }
565  else
566  {
567  for (auto & n : this_elem->node_ref_range())
568  {
569  if (!current_elem->contains_point(n))
570  {
571  neighbor_set.erase(current);
572  break;
573  }
574  }
575  }
576  }
577 }
unsigned int dim
libmesh_assert(ctx)
void find_point_neighbors(T this_elem, std::set< T > &neighbor_set, T start_elem)

◆ find_point_neighbors()

template<class T >
void libMesh::ElemInternal::find_point_neighbors ( this_elem,
std::set< T > &  neighbor_set,
start_elem 
)

Definition at line 429 of file elem_internal.h.

References libMesh::libmesh_assert().

Referenced by find_interior_neighbors(), and libMesh::Elem::find_point_neighbors().

432 {
433  libmesh_assert(start_elem);
434  libmesh_assert(start_elem->active());
435  libmesh_assert(start_elem->contains_vertex_of(this_elem, true) ||
436  this_elem->contains_vertex_of(start_elem, true));
437 
438  neighbor_set.clear();
439  neighbor_set.insert(start_elem);
440 
441  std::set<T> untested_set, next_untested_set;
442  untested_set.insert(start_elem);
443 
444  while (!untested_set.empty())
445  {
446  // Loop over all the elements in the patch that haven't already
447  // been tested
448  for (const auto & elem : untested_set)
449  for (auto current_neighbor : elem->neighbor_ptr_range())
450  {
451  if (current_neighbor &&
452  !current_neighbor->is_remote()) // we have a real neighbor on this side
453  {
454  if (current_neighbor->active()) // ... if it is active
455  {
456  if (this_elem->contains_vertex_of(current_neighbor, true) // ... and touches us
457  || current_neighbor->contains_vertex_of(this_elem, true))
458  {
459  // Make sure we'll test it
460  if (!neighbor_set.count(current_neighbor))
461  next_untested_set.insert (current_neighbor);
462 
463  // And add it
464  neighbor_set.insert (current_neighbor);
465  }
466  }
467 #ifdef LIBMESH_ENABLE_AMR
468  else // ... the neighbor is *not* active,
469  { // ... so add *all* neighboring
470  // active children
471  std::vector<T> active_neighbor_children;
472 
473  current_neighbor->active_family_tree_by_neighbor
474  (active_neighbor_children, elem);
475 
476  for (const auto & current_child : active_neighbor_children)
477  {
478  if (this_elem->contains_vertex_of(current_child, true) ||
479  current_child->contains_vertex_of(this_elem, true))
480  {
481  // Make sure we'll test it
482  if (!neighbor_set.count(current_child))
483  next_untested_set.insert (current_child);
484 
485  neighbor_set.insert (current_child);
486  }
487  }
488  }
489 #endif // #ifdef LIBMESH_ENABLE_AMR
490  }
491  }
492  untested_set.swap(next_untested_set);
493  next_untested_set.clear();
494  }
495 }
libmesh_assert(ctx)

◆ total_family_tree()

template<class T >
void libMesh::ElemInternal::total_family_tree ( elem,
std::vector< T > &  family,
bool  reset 
)

Definition at line 67 of file elem_internal.h.

Referenced by libMesh::Elem::total_family_tree().

70 {
71  // Clear the vector if the flag reset tells us to.
72  if (reset)
73  family.clear();
74 
75  // Add this element to the family tree.
76  family.push_back(elem);
77 
78  // Recurse into the elements children, if it has them.
79  // Do not clear the vector any more.
80  if (elem->has_children())
81  for (auto & c : elem->child_ref_range())
82  if (!c.is_remote())
83  ElemInternal::total_family_tree (&c, family, false);
84 }
void total_family_tree(T elem, std::vector< T > &family, bool reset)
Definition: elem_internal.h:67

◆ total_family_tree_by_neighbor()

template<class T >
void libMesh::ElemInternal::total_family_tree_by_neighbor ( elem,
std::vector< T > &  family,
neighbor_in,
bool  reset = true 
)

Definition at line 240 of file elem_internal.h.

References libMesh::libmesh_assert().

Referenced by libMesh::Elem::total_family_tree_by_neighbor().

244 {
245  // Clear the vector if the flag reset tells us to.
246  if (reset)
247  family.clear();
248 
249  // This only makes sense if we're already a neighbor
250  libmesh_assert (elem->has_neighbor(neighbor_in));
251 
252  // Add this element to the family tree.
253  family.push_back(elem);
254 
255  // Recurse into the elements children, if it has any.
256  // Do not clear the vector any more.
257  if (elem->has_children())
258  for (auto & c : elem->child_ref_range())
259  if (!c.is_remote() && c.has_neighbor(neighbor_in))
260  ElemInternal::total_family_tree_by_neighbor (&c, family, neighbor_in, false);
261 }
void total_family_tree_by_neighbor(T elem, std::vector< T > &family, T neighbor_in, bool reset=true)
libmesh_assert(ctx)

◆ total_family_tree_by_side()

template<class T >
void libMesh::ElemInternal::total_family_tree_by_side ( elem,
std::vector< T > &  family,
unsigned int  s,
bool  reset 
)

Definition at line 149 of file elem_internal.h.

Referenced by libMesh::Elem::total_family_tree_by_side().

153 {
154  // Clear the vector if the flag reset tells us to.
155  if (reset)
156  family.clear();
157 
158  libmesh_assert_less (s, elem->n_sides());
159 
160  // Add this element to the family tree.
161  family.push_back(elem);
162 
163  // Recurse into the elements children, if it has them.
164  // Do not clear the vector any more.
165  if (elem->has_children())
166  {
167  const unsigned int nc = elem->n_children();
168  for (unsigned int c = 0; c != nc; c++)
169  if (!elem->child_ptr(c)->is_remote() && elem->is_child_on_side(c, s))
170  ElemInternal::total_family_tree_by_side (elem->child_ptr(c), family, s, false);
171  }
172 }
void total_family_tree_by_side(T elem, std::vector< T > &family, unsigned int s, bool reset)

◆ total_family_tree_by_subneighbor()

template<class T >
void libMesh::ElemInternal::total_family_tree_by_subneighbor ( elem,
std::vector< T > &  family,
neighbor_in,
subneighbor,
bool  reset = true 
)

Definition at line 309 of file elem_internal.h.

References libMesh::libmesh_assert().

Referenced by libMesh::Elem::total_family_tree_by_subneighbor().

314 {
315  // Clear the vector if the flag reset tells us to.
316  if (reset)
317  family.clear();
318 
319  // To simplify this function we need an existing neighbor
320  libmesh_assert (neighbor_in);
321  libmesh_assert (!neighbor_in->is_remote());
322  libmesh_assert (elem->has_neighbor(neighbor_in));
323 
324  // This only makes sense if subneighbor descends from neighbor
325  libmesh_assert (subneighbor);
326  libmesh_assert (!subneighbor->is_remote());
327  libmesh_assert (neighbor_in->is_ancestor_of(subneighbor));
328 
329  // Add this element to the family tree if applicable.
330  if (neighbor_in == subneighbor)
331  family.push_back(elem);
332 
333  // Recurse into the elements children, if it has any.
334  // Do not clear the vector any more.
335  if (elem->has_children())
336  for (auto & c : elem->child_ref_range())
337  if (!c.is_remote())
338  for (auto child_neigh : c.neighbor_ptr_range())
339  if (child_neigh &&
340  (child_neigh == neighbor_in ||
341  (child_neigh->parent() == neighbor_in && child_neigh->is_ancestor_of(subneighbor))))
342  c.total_family_tree_by_subneighbor(family, child_neigh, subneighbor, false);
343 }
libmesh_assert(ctx)