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 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 320 of file elem_internal.h.

References libMesh::libmesh_assert().

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

324 {
325  // The "family tree" doesn't include subactive elements or
326  // remote_elements
327  libmesh_assert(!elem->subactive());
328  libmesh_assert(!elem->is_remote());
329 
330  // Clear the vector if the flag reset tells us to.
331  if (reset)
332  family.clear();
333 
334  // This only makes sense if we're already a neighbor
335 #ifndef NDEBUG
336  if (elem->level() >= neighbor_in->level())
337  libmesh_assert (elem->has_neighbor(neighbor_in));
338 #endif
339 
340  // Add an active element to the family tree.
341  if (elem->active())
342  family.push_back(elem);
343 
344  // Or recurse into an ancestor element's children.
345  // Do not clear the vector any more.
346  else if (!elem->active())
347  for (auto & c : elem->child_ref_range())
348  if (!c.is_remote() && c.has_neighbor(neighbor_in))
349  ElemInternal::active_family_tree_by_neighbor (&c, family, neighbor_in, false);
350 }
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 149 of file elem_internal.h.

References libMesh::libmesh_assert().

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

153 {
154  // The "family tree" doesn't include subactive or remote elements
155  libmesh_assert(!elem->subactive());
156  libmesh_assert(!elem->is_remote());
157 
158  // Clear the vector if the flag reset tells us to.
159  if (reset)
160  family.clear();
161 
162  libmesh_assert_less (side, elem->n_sides());
163 
164  // Add an active element to the family tree.
165  if (elem->active())
166  family.push_back(elem);
167 
168  // Or recurse into an ancestor element's children.
169  // Do not clear the vector any more.
170  else
171  {
172  const unsigned int nc = elem->n_children();
173  for (unsigned int c = 0; c != nc; c++)
174  if (!elem->child_ptr(c)->is_remote() && elem->is_child_on_side(c, side))
175  ElemInternal::active_family_tree_by_side(elem->child_ptr(c), family, side, false);
176  }
177 }
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 356 of file elem_internal.h.

References libMesh::libmesh_assert(), and mesh.

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

363 {
364  // The "family tree" doesn't include subactive elements or
365  // remote_elements
366  libmesh_assert(!elem->subactive());
367  libmesh_assert(!elem->is_remote());
368 
369  // Clear the vector if the flag reset tells us to.
370  if (reset)
371  family.clear();
372 
373  // This only makes sense if we're already a topological neighbor
374 #ifndef NDEBUG
375  if (elem->level() >= neighbor_in->level())
376  libmesh_assert (elem->has_topological_neighbor(neighbor_in,
377  mesh,
378  point_locator,
379  pb));
380 #endif
381 
382  // Add an active element to the family tree.
383  if (elem->active())
384  family.push_back(elem);
385 
386  // Or recurse into an ancestor element's children.
387  // Do not clear the vector any more.
388  else if (!elem->active())
389  for (auto & c : elem->child_ref_range())
390  if (!c.is_remote() &&
391  c.has_topological_neighbor(neighbor_in, mesh, point_locator, pb))
392  c.active_family_tree_by_topological_neighbor
393  (family, neighbor_in, mesh, point_locator, pb, false);
394 }
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 182 of file elem_internal.h.

References libMesh::libmesh_assert().

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

186 {
187  // The "family tree" doesn't include subactive elements
188  libmesh_assert(!elem->subactive());
189 
190  // Clear the vector if the flag reset tells us to.
191  if (reset)
192  family.clear();
193 
194  // This only makes sense if we're already a neighbor
195  libmesh_assert (elem->has_neighbor(neighbor_in));
196 
197  // Add this element to the family tree.
198  family.push_back(elem);
199 
200  // Recurse into the elements children, if it's not active.
201  // Do not clear the vector any more.
202  if (!elem->active())
203  for (auto & c : elem->child_ref_range())
204  if (!c.is_remote() && c.has_neighbor(neighbor_in))
205  ElemInternal::family_tree_by_neighbor (&c, family, neighbor_in, false);
206 }
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 237 of file elem_internal.h.

References libMesh::libmesh_assert().

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

242 {
243  // The "family tree" doesn't include subactive elements
244  libmesh_assert(!elem->subactive());
245 
246  // Clear the vector if the flag reset tells us to.
247  if (reset)
248  family.clear();
249 
250  // To simplify this function we need an existing neighbor
251  libmesh_assert (neighbor_in);
252  libmesh_assert (!neighbor_in->is_remote());
253  libmesh_assert (elem->has_neighbor(neighbor_in));
254 
255  // This only makes sense if subneighbor descends from neighbor
256  libmesh_assert (subneighbor);
257  libmesh_assert (!subneighbor->is_remote());
258  libmesh_assert (neighbor_in->is_ancestor_of(subneighbor));
259 
260  // Add this element to the family tree if applicable.
261  if (neighbor_in == subneighbor)
262  family.push_back(elem);
263 
264  // Recurse into the elements children, if it's not active.
265  // Do not clear the vector any more.
266  if (!elem->active())
267  for (auto & c : elem->child_ref_range())
268  if (!c.is_remote())
269  for (auto child_neigh : c.neighbor_ptr_range())
270  if (child_neigh &&
271  (child_neigh == neighbor_in || (child_neigh->parent() == neighbor_in &&
272  child_neigh->is_ancestor_of(subneighbor))))
273  ElemInternal::family_tree_by_subneighbor (&c, family, child_neigh, subneighbor, false);
274 }
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 472 of file elem_internal.h.

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

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

474 {
475  neighbor_set.clear();
476 
477  if ((this_elem->dim() >= LIBMESH_DIM) ||
478  !this_elem->interior_parent())
479  return;
480 
481  T ip = this_elem->interior_parent();
482  libmesh_assert (ip->contains_vertex_of(this_elem, true) ||
483  this_elem->contains_vertex_of(ip, true));
484 
485  libmesh_assert (!ip->subactive());
486 
487 #ifdef LIBMESH_ENABLE_AMR
488  while (!ip->active()) // only possible with AMR, be careful because
489  { // ip->child_ptr(c) is only good with AMR.
490  for (auto & child : ip->child_ref_range())
491  {
492  if (child.contains_vertex_of(this_elem, true) ||
493  this_elem->contains_vertex_of(&child, true))
494  {
495  ip = &child;
496  break;
497  }
498  }
499  }
500 #endif
501 
502  ElemInternal::find_point_neighbors(this_elem, neighbor_set, ip);
503 
504  // Now we have all point neighbors from the interior manifold, but
505  // we need to weed out any neighbors that *only* intersect us at one
506  // point (or at one edge, if we're a 1-D element in 3D).
507  //
508  // The refinement hierarchy helps us here: if the interior element
509  // has a lower or equal refinement level then we can discard it iff
510  // it doesn't contain all our vertices. If it has a higher
511  // refinement level then we can discard it iff we don't contain at
512  // least dim()+1 of its vertices
513  auto it = neighbor_set.begin();
514  const auto end = neighbor_set.end();
515 
516  while (it != end)
517  {
518  auto current = it++;
519  T current_elem = *current;
520 
521  // This won't invalidate iterator it, because it is already
522  // pointing to the next element
523  if (current_elem->level() > this_elem->level())
524  {
525  unsigned int vertices_contained = 0;
526  for (auto & n : current_elem->node_ref_range())
527  if (this_elem->contains_point(n))
528  vertices_contained++;
529 
530  if (vertices_contained <= this_elem->dim())
531  {
532  neighbor_set.erase(current);
533  continue;
534  }
535  }
536  else
537  {
538  for (auto & n : this_elem->node_ref_range())
539  {
540  if (!current_elem->contains_point(n))
541  {
542  neighbor_set.erase(current);
543  break;
544  }
545  }
546  }
547  }
548 }
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 400 of file elem_internal.h.

References libMesh::libmesh_assert().

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

403 {
404  libmesh_assert(start_elem);
405  libmesh_assert(start_elem->active());
406  libmesh_assert(start_elem->contains_vertex_of(this_elem, true) ||
407  this_elem->contains_vertex_of(start_elem, true));
408 
409  neighbor_set.clear();
410  neighbor_set.insert(start_elem);
411 
412  std::set<T> untested_set, next_untested_set;
413  untested_set.insert(start_elem);
414 
415  while (!untested_set.empty())
416  {
417  // Loop over all the elements in the patch that haven't already
418  // been tested
419  for (const auto & elem : untested_set)
420  for (auto current_neighbor : elem->neighbor_ptr_range())
421  {
422  if (current_neighbor &&
423  !current_neighbor->is_remote()) // we have a real neighbor on this side
424  {
425  if (current_neighbor->active()) // ... if it is active
426  {
427  if (this_elem->contains_vertex_of(current_neighbor, true) // ... and touches us
428  || current_neighbor->contains_vertex_of(this_elem, true))
429  {
430  // Make sure we'll test it
431  if (!neighbor_set.count(current_neighbor))
432  next_untested_set.insert (current_neighbor);
433 
434  // And add it
435  neighbor_set.insert (current_neighbor);
436  }
437  }
438 #ifdef LIBMESH_ENABLE_AMR
439  else // ... the neighbor is *not* active,
440  { // ... so add *all* neighboring
441  // active children
442  std::vector<T> active_neighbor_children;
443 
444  current_neighbor->active_family_tree_by_neighbor
445  (active_neighbor_children, elem);
446 
447  for (const auto & current_child : active_neighbor_children)
448  {
449  if (this_elem->contains_vertex_of(current_child, true) ||
450  current_child->contains_vertex_of(this_elem, true))
451  {
452  // Make sure we'll test it
453  if (!neighbor_set.count(current_child))
454  next_untested_set.insert (current_child);
455 
456  neighbor_set.insert (current_child);
457  }
458  }
459  }
460 #endif // #ifdef LIBMESH_ENABLE_AMR
461  }
462  }
463  untested_set.swap(next_untested_set);
464  next_untested_set.clear();
465  }
466 }
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 211 of file elem_internal.h.

References libMesh::libmesh_assert().

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

215 {
216  // Clear the vector if the flag reset tells us to.
217  if (reset)
218  family.clear();
219 
220  // This only makes sense if we're already a neighbor
221  libmesh_assert (elem->has_neighbor(neighbor_in));
222 
223  // Add this element to the family tree.
224  family.push_back(elem);
225 
226  // Recurse into the elements children, if it has any.
227  // Do not clear the vector any more.
228  if (elem->has_children())
229  for (auto & c : elem->child_ref_range())
230  if (!c.is_remote() && c.has_neighbor(neighbor_in))
231  ElemInternal::total_family_tree_by_neighbor (&c, family, neighbor_in, false);
232 }
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_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 280 of file elem_internal.h.

References libMesh::libmesh_assert().

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

285 {
286  // Clear the vector if the flag reset tells us to.
287  if (reset)
288  family.clear();
289 
290  // To simplify this function we need an existing neighbor
291  libmesh_assert (neighbor_in);
292  libmesh_assert (!neighbor_in->is_remote());
293  libmesh_assert (elem->has_neighbor(neighbor_in));
294 
295  // This only makes sense if subneighbor descends from neighbor
296  libmesh_assert (subneighbor);
297  libmesh_assert (!subneighbor->is_remote());
298  libmesh_assert (neighbor_in->is_ancestor_of(subneighbor));
299 
300  // Add this element to the family tree if applicable.
301  if (neighbor_in == subneighbor)
302  family.push_back(elem);
303 
304  // Recurse into the elements children, if it has any.
305  // Do not clear the vector any more.
306  if (elem->has_children())
307  for (auto & c : elem->child_ref_range())
308  if (!c.is_remote())
309  for (auto child_neigh : c.neighbor_ptr_range())
310  if (child_neigh &&
311  (child_neigh == neighbor_in ||
312  (child_neigh->parent() == neighbor_in && child_neigh->is_ancestor_of(subneighbor))))
313  c.total_family_tree_by_subneighbor(family, child_neigh, subneighbor, false);
314 }
libmesh_assert(ctx)