libMesh
elem.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 // C++ includes
21 #include <algorithm> // for std::sort
22 #include <array>
23 #include <iterator> // for std::ostream_iterator
24 #include <sstream>
25 #include <limits> // for std::numeric_limits<>
26 #include <cmath> // for std::sqrt()
27 
28 // Local includes
29 #include "libmesh/auto_ptr.h" // libmesh_make_unique
30 #include "libmesh/elem.h"
31 #include "libmesh/fe_type.h"
32 #include "libmesh/fe_interface.h"
33 #include "libmesh/node_elem.h"
34 #include "libmesh/edge_edge2.h"
35 #include "libmesh/edge_edge3.h"
36 #include "libmesh/edge_edge4.h"
37 #include "libmesh/edge_inf_edge2.h"
38 #include "libmesh/face_tri3.h"
39 #include "libmesh/face_tri3_subdivision.h"
40 #include "libmesh/face_tri3_shell.h"
41 #include "libmesh/face_tri6.h"
42 #include "libmesh/face_quad4.h"
43 #include "libmesh/face_quad4_shell.h"
44 #include "libmesh/face_quad8.h"
45 #include "libmesh/face_quad8_shell.h"
46 #include "libmesh/face_quad9.h"
47 #include "libmesh/face_inf_quad4.h"
48 #include "libmesh/face_inf_quad6.h"
49 #include "libmesh/cell_tet4.h"
50 #include "libmesh/cell_tet10.h"
51 #include "libmesh/cell_hex8.h"
52 #include "libmesh/cell_hex20.h"
53 #include "libmesh/cell_hex27.h"
54 #include "libmesh/cell_inf_hex8.h"
55 #include "libmesh/cell_inf_hex16.h"
56 #include "libmesh/cell_inf_hex18.h"
57 #include "libmesh/cell_prism6.h"
58 #include "libmesh/cell_prism15.h"
59 #include "libmesh/cell_prism18.h"
60 #include "libmesh/cell_inf_prism6.h"
61 #include "libmesh/cell_inf_prism12.h"
62 #include "libmesh/cell_pyramid5.h"
63 #include "libmesh/cell_pyramid13.h"
64 #include "libmesh/cell_pyramid14.h"
65 #include "libmesh/fe_base.h"
66 #include "libmesh/mesh_base.h"
67 #include "libmesh/quadrature_gauss.h"
68 #include "libmesh/remote_elem.h"
69 #include "libmesh/reference_elem.h"
70 #include "libmesh/enum_to_string.h"
71 #include "libmesh/threads.h"
72 #include "libmesh/enum_elem_quality.h"
73 #include "libmesh/enum_io_package.h"
74 #include "libmesh/enum_order.h"
75 #include "libmesh/elem_internal.h"
76 
77 #ifdef LIBMESH_ENABLE_PERIODIC
78 #include "libmesh/mesh.h"
79 #include "libmesh/periodic_boundaries.h"
80 #include "libmesh/boundary_info.h"
81 #endif
82 
83 namespace libMesh
84 {
85 
88 
89 const subdomain_id_type Elem::invalid_subdomain_id = std::numeric_limits<subdomain_id_type>::max();
90 
91 // Initialize static member variables
92 const unsigned int Elem::max_n_nodes;
93 
94 const unsigned int Elem::type_to_n_nodes_map [] =
95  {
96  2, // EDGE2
97  3, // EDGE3
98  4, // EDGE4
99 
100  3, // TRI3
101  6, // TRI6
102 
103  4, // QUAD4
104  8, // QUAD8
105  9, // QUAD9
106 
107  4, // TET4
108  10, // TET10
109 
110  8, // HEX8
111  20, // HEX20
112  27, // HEX27
113 
114  6, // PRISM6
115  15, // PRISM15
116  18, // PRISM18
117 
118  5, // PYRAMID5
119  13, // PYRAMID13
120  14, // PYRAMID14
121 
122  2, // INFEDGE2
123 
124  4, // INFQUAD4
125  6, // INFQUAD6
126 
127  8, // INFHEX8
128  16, // INFHEX16
129  18, // INFHEX18
130 
131  6, // INFPRISM6
132  16, // INFPRISM12
133 
134  1, // NODEELEM
135 
136  0, // REMOTEELEM
137 
138  3, // TRI3SUBDIVISION
139  3, // TRISHELL3
140  4, // QUADSHELL4
141  8, // QUADSHELL8
142  };
143 
144 const unsigned int Elem::type_to_n_sides_map [] =
145  {
146  2, // EDGE2
147  2, // EDGE3
148  2, // EDGE4
149 
150  3, // TRI3
151  3, // TRI6
152 
153  4, // QUAD4
154  4, // QUAD8
155  4, // QUAD9
156 
157  4, // TET4
158  4, // TET10
159 
160  6, // HEX8
161  6, // HEX20
162  6, // HEX27
163 
164  5, // PRISM6
165  5, // PRISM15
166  5, // PRISM18
167 
168  5, // PYRAMID5
169  5, // PYRAMID13
170  5, // PYRAMID14
171 
172  2, // INFEDGE2
173 
174  3, // INFQUAD4
175  3, // INFQUAD6
176 
177  5, // INFHEX8
178  5, // INFHEX16
179  5, // INFHEX18
180 
181  4, // INFPRISM6
182  4, // INFPRISM12
183 
184  0, // NODEELEM
185 
186  0, // REMOTEELEM
187 
188  3, // TRI3SUBDIVISION
189  3, // TRISHELL3
190  4, // QUADSHELL4
191  4, // QUADSHELL8
192  };
193 
194 const unsigned int Elem::type_to_n_edges_map [] =
195  {
196  0, // EDGE2
197  0, // EDGE3
198  0, // EDGE4
199 
200  3, // TRI3
201  3, // TRI6
202 
203  4, // QUAD4
204  4, // QUAD8
205  4, // QUAD9
206 
207  6, // TET4
208  6, // TET10
209 
210  12, // HEX8
211  12, // HEX20
212  12, // HEX27
213 
214  9, // PRISM6
215  9, // PRISM15
216  9, // PRISM18
217 
218  8, // PYRAMID5
219  8, // PYRAMID13
220  8, // PYRAMID14
221 
222  0, // INFEDGE2
223 
224  4, // INFQUAD4
225  4, // INFQUAD6
226 
227  8, // INFHEX8
228  8, // INFHEX16
229  8, // INFHEX18
230 
231  6, // INFPRISM6
232  6, // INFPRISM12
233 
234  0, // NODEELEM
235 
236  0, // REMOTEELEM
237 
238  3, // TRI3SUBDIVISION
239  3, // TRISHELL3
240  4, // QUADSHELL4
241  4, // QUADSHELL8
242  };
243 
244 // ------------------------------------------------------------
245 // Elem class member functions
246 std::unique_ptr<Elem> Elem::build(const ElemType type,
247  Elem * p)
248 {
249  switch (type)
250  {
251  // 0D elements
252  case NODEELEM:
253  return libmesh_make_unique<NodeElem>(p);
254 
255  // 1D elements
256  case EDGE2:
257  return libmesh_make_unique<Edge2>(p);
258  case EDGE3:
259  return libmesh_make_unique<Edge3>(p);
260  case EDGE4:
261  return libmesh_make_unique<Edge4>(p);
262 
263  // 2D elements
264  case TRI3:
265  return libmesh_make_unique<Tri3>(p);
266  case TRISHELL3:
267  return libmesh_make_unique<TriShell3>(p);
268  case TRI3SUBDIVISION:
269  return libmesh_make_unique<Tri3Subdivision>(p);
270  case TRI6:
271  return libmesh_make_unique<Tri6>(p);
272  case QUAD4:
273  return libmesh_make_unique<Quad4>(p);
274  case QUADSHELL4:
275  return libmesh_make_unique<QuadShell4>(p);
276  case QUAD8:
277  return libmesh_make_unique<Quad8>(p);
278  case QUADSHELL8:
279  return libmesh_make_unique<QuadShell8>(p);
280  case QUAD9:
281  return libmesh_make_unique<Quad9>(p);
282 
283  // 3D elements
284  case TET4:
285  return libmesh_make_unique<Tet4>(p);
286  case TET10:
287  return libmesh_make_unique<Tet10>(p);
288  case HEX8:
289  return libmesh_make_unique<Hex8>(p);
290  case HEX20:
291  return libmesh_make_unique<Hex20>(p);
292  case HEX27:
293  return libmesh_make_unique<Hex27>(p);
294  case PRISM6:
295  return libmesh_make_unique<Prism6>(p);
296  case PRISM15:
297  return libmesh_make_unique<Prism15>(p);
298  case PRISM18:
299  return libmesh_make_unique<Prism18>(p);
300  case PYRAMID5:
301  return libmesh_make_unique<Pyramid5>(p);
302  case PYRAMID13:
303  return libmesh_make_unique<Pyramid13>(p);
304  case PYRAMID14:
305  return libmesh_make_unique<Pyramid14>(p);
306 
307 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
308  // 1D infinite elements
309  case INFEDGE2:
310  return libmesh_make_unique<InfEdge2>(p);
311 
312  // 2D infinite elements
313  case INFQUAD4:
314  return libmesh_make_unique<InfQuad4>(p);
315  case INFQUAD6:
316  return libmesh_make_unique<InfQuad6>(p);
317 
318  // 3D infinite elements
319  case INFHEX8:
320  return libmesh_make_unique<InfHex8>(p);
321  case INFHEX16:
322  return libmesh_make_unique<InfHex16>(p);
323  case INFHEX18:
324  return libmesh_make_unique<InfHex18>(p);
325  case INFPRISM6:
326  return libmesh_make_unique<InfPrism6>(p);
327  case INFPRISM12:
328  return libmesh_make_unique<InfPrism12>(p);
329 #endif
330 
331  default:
332  libmesh_error_msg("ERROR: Undefined element type!");
333  }
334 }
335 
336 
337 
338 const Elem * Elem::reference_elem () const
339 {
340  return &(ReferenceElem::get(this->type()));
341 }
342 
343 
344 
346 {
347  Point cp;
348 
349  const auto n_vertices = this->n_vertices();
350 
351  for (unsigned int n=0; n<n_vertices; n++)
352  cp.add (this->point(n));
353 
354  return (cp /= static_cast<Real>(n_vertices));
355 }
356 
357 
358 
360 {
361  Real h_min=std::numeric_limits<Real>::max();
362 
363  // Avoid calling a virtual a lot of times
364  const auto n_vertices = this->n_vertices();
365 
366  for (unsigned int n_outer=0; n_outer<n_vertices; n_outer++)
367  for (unsigned int n_inner=n_outer+1; n_inner<n_vertices; n_inner++)
368  {
369  const auto diff = (this->point(n_outer) - this->point(n_inner));
370 
371  h_min = std::min(h_min, diff.norm_sq());
372  }
373 
374  return std::sqrt(h_min);
375 }
376 
377 
378 
380 {
381  Real h_max=0;
382 
383  // Avoid calling a virtual a lot of times
384  const auto n_vertices = this->n_vertices();
385 
386  for (unsigned int n_outer=0; n_outer<n_vertices; n_outer++)
387  for (unsigned int n_inner=n_outer+1; n_inner<n_vertices; n_inner++)
388  {
389  const auto diff = (this->point(n_outer) - this->point(n_inner));
390 
391  h_max = std::max(h_max, diff.norm_sq());
392  }
393 
394  return std::sqrt(h_max);
395 }
396 
397 
398 
399 Real Elem::length(const unsigned int n1,
400  const unsigned int n2) const
401 {
402  libmesh_assert_less ( n1, this->n_vertices() );
403  libmesh_assert_less ( n2, this->n_vertices() );
404 
405  return (this->point(n1) - this->point(n2)).norm();
406 }
407 
408 
409 
411 {
412  const unsigned short n_n = this->n_nodes();
413 
414  std::array<dof_id_type, Elem::max_n_nodes> node_ids;
415 
416  for (unsigned short n=0; n != n_n; ++n)
417  node_ids[n] = this->node_id(n);
418 
419  // Always sort, so that different local node numberings hash to the
420  // same value.
421  std::sort (node_ids.begin(), node_ids.begin()+n_n);
422 
423  return Utility::hashword(node_ids.data(), n_n);
424 }
425 
426 
427 
428 bool Elem::operator == (const Elem & rhs) const
429 {
430  // If the elements aren't the same type, they aren't equal
431  if (this->type() != rhs.type())
432  return false;
433 
434  const unsigned short n_n = this->n_nodes();
435  libmesh_assert_equal_to(n_n, rhs.n_nodes());
436 
437  // Make two sorted arrays of global node ids and compare them for
438  // equality.
439  std::array<dof_id_type, Elem::max_n_nodes> this_ids, rhs_ids;
440 
441  for (unsigned short n = 0; n != n_n; n++)
442  {
443  this_ids[n] = this->node_id(n);
444  rhs_ids[n] = rhs.node_id(n);
445  }
446 
447  // Sort the vectors to rule out different local node numberings.
448  std::sort(this_ids.begin(), this_ids.begin()+n_n);
449  std::sort(rhs_ids.begin(), rhs_ids.begin()+n_n);
450 
451  // If the node ids match, the elements are equal!
452  for (unsigned short n = 0; n != n_n; ++n)
453  if (this_ids[n] != rhs_ids[n])
454  return false;
455  return true;
456 }
457 
458 
459 
460 bool Elem::is_semilocal(const processor_id_type my_pid) const
461 {
462  std::set<const Elem *> point_neighbors;
463 
464  this->find_point_neighbors(point_neighbors);
465 
466  for (const auto & elem : point_neighbors)
467  if (elem->processor_id() == my_pid)
468  return true;
469 
470  return false;
471 }
472 
473 
474 
475 unsigned int Elem::which_side_am_i (const Elem * e) const
476 {
477  libmesh_assert(e);
478 
479  const unsigned int ns = this->n_sides();
480  const unsigned int nn = this->n_nodes();
481 
482  const unsigned int en = e->n_nodes();
483 
484  // e might be on any side until proven otherwise
485  std::vector<bool> might_be_side(ns, true);
486 
487  for (unsigned int i=0; i != en; ++i)
488  {
489  Point side_point = e->point(i);
490  unsigned int local_node_id = libMesh::invalid_uint;
491 
492  // Look for a node of this that's contiguous with node i of
493  // e. Note that the exact floating point comparison of Point
494  // positions is intentional, see the class documentation for
495  // this function.
496  for (unsigned int j=0; j != nn; ++j)
497  if (this->point(j) == side_point)
498  local_node_id = j;
499 
500  // If a node of e isn't contiguous with some node of this, then
501  // e isn't a side of this.
502  if (local_node_id == libMesh::invalid_uint)
503  return libMesh::invalid_uint;
504 
505  // If a node of e isn't contiguous with some node on side s of
506  // this, then e isn't on side s.
507  for (unsigned int s=0; s != ns; ++s)
508  if (!this->is_node_on_side(local_node_id, s))
509  might_be_side[s] = false;
510  }
511 
512  for (unsigned int s=0; s != ns; ++s)
513  if (might_be_side[s])
514  {
515 #ifdef DEBUG
516  for (unsigned int s2=s+1; s2 < ns; ++s2)
517  libmesh_assert (!might_be_side[s2]);
518 #endif
519  return s;
520  }
521 
522  // Didn't find any matching side
523  return libMesh::invalid_uint;
524 }
525 
526 
527 
528 bool Elem::contains_vertex_of(const Elem * e) const
529 {
530  // Our vertices are the first numbered nodes
531  for (auto n : IntRange<unsigned int>(0, e->n_vertices()))
532  if (this->contains_point(e->point(n)))
533  return true;
534  return false;
535 }
536 
537 
538 
539 bool Elem::contains_edge_of(const Elem * e) const
540 {
541  unsigned int num_contained_edges = 0;
542 
543  // Our vertices are the first numbered nodes
544  for (auto n : IntRange<unsigned int>(0, e->n_vertices()))
545  {
546  if (this->contains_point(e->point(n)))
547  {
548  num_contained_edges++;
549  if (num_contained_edges>=2)
550  {
551  return true;
552  }
553  }
554  }
555  return false;
556 }
557 
558 
559 
561  std::set<const Elem *> & neighbor_set) const
562 {
563  libmesh_assert(this->contains_point(p));
564  libmesh_assert(this->active());
565 
566  neighbor_set.clear();
567  neighbor_set.insert(this);
568 
569  std::set<const Elem *> untested_set, next_untested_set;
570  untested_set.insert(this);
571 
572  while (!untested_set.empty())
573  {
574  // Loop over all the elements in the patch that haven't already
575  // been tested
576  for (const auto & elem : untested_set)
577  for (auto current_neighbor : elem->neighbor_ptr_range())
578  {
579  if (current_neighbor &&
580  current_neighbor != remote_elem) // we have a real neighbor on this side
581  {
582  if (current_neighbor->active()) // ... if it is active
583  {
584  if (current_neighbor->contains_point(p)) // ... and touches p
585  {
586  // Make sure we'll test it
587  if (!neighbor_set.count(current_neighbor))
588  next_untested_set.insert (current_neighbor);
589 
590  // And add it
591  neighbor_set.insert (current_neighbor);
592  }
593  }
594 #ifdef LIBMESH_ENABLE_AMR
595  else // ... the neighbor is *not* active,
596  { // ... so add *all* neighboring
597  // active children that touch p
598  std::vector<const Elem *> active_neighbor_children;
599 
600  current_neighbor->active_family_tree_by_neighbor
601  (active_neighbor_children, elem);
602 
603  for (const auto & current_child : active_neighbor_children)
604  if (current_child->contains_point(p))
605  {
606  // Make sure we'll test it
607  if (!neighbor_set.count(current_child))
608  next_untested_set.insert (current_child);
609 
610  neighbor_set.insert (current_child);
611  }
612  }
613 #endif // #ifdef LIBMESH_ENABLE_AMR
614  }
615  }
616  untested_set.swap(next_untested_set);
617  next_untested_set.clear();
618  }
619 }
620 
621 
622 
623 void Elem::find_point_neighbors(std::set<const Elem *> & neighbor_set) const
624 {
625  this->find_point_neighbors(neighbor_set, this);
626 }
627 
628 
629 
630 void Elem::find_point_neighbors(std::set<const Elem *> & neighbor_set,
631  const Elem * start_elem) const
632 {
633  ElemInternal::find_point_neighbors(this, neighbor_set, start_elem);
634 }
635 
636 
637 
638 void Elem::find_point_neighbors(std::set<Elem *> & neighbor_set,
639  Elem * start_elem)
640 {
641  ElemInternal::find_point_neighbors(this, neighbor_set, start_elem);
642 }
643 
644 
645 
647  const Point & p2,
648  std::set<const Elem *> & neighbor_set) const
649 {
650  // Simple but perhaps suboptimal code: find elements containing the
651  // first point, then winnow this set down by removing elements which
652  // don't also contain the second point
653 
654  libmesh_assert(this->contains_point(p2));
655  this->find_point_neighbors(p1, neighbor_set);
656 
657  std::set<const Elem *>::iterator it = neighbor_set.begin();
658  const std::set<const Elem *>::iterator end = neighbor_set.end();
659 
660  while (it != end)
661  {
662  // As of C++11, set::erase returns an iterator to the element
663  // following the erased element, or end.
664  if (!(*it)->contains_point(p2))
665  it = neighbor_set.erase(it);
666  else
667  ++it;
668  }
669 }
670 
671 
672 
673 void Elem::find_edge_neighbors(std::set<const Elem *> & neighbor_set) const
674 {
675  neighbor_set.clear();
676  neighbor_set.insert(this);
677 
678  std::set<const Elem *> untested_set, next_untested_set;
679  untested_set.insert(this);
680 
681  while (!untested_set.empty())
682  {
683  // Loop over all the elements in the patch that haven't already
684  // been tested
685  for (const auto & elem : untested_set)
686  {
687  for (auto current_neighbor : elem->neighbor_ptr_range())
688  {
689  if (current_neighbor &&
690  current_neighbor != remote_elem) // we have a real neighbor on this side
691  {
692  if (current_neighbor->active()) // ... if it is active
693  {
694  if (this->contains_edge_of(current_neighbor) // ... and touches us
695  || current_neighbor->contains_edge_of(this))
696  {
697  // Make sure we'll test it
698  if (!neighbor_set.count(current_neighbor))
699  next_untested_set.insert (current_neighbor);
700 
701  // And add it
702  neighbor_set.insert (current_neighbor);
703  }
704  }
705 #ifdef LIBMESH_ENABLE_AMR
706  else // ... the neighbor is *not* active,
707  { // ... so add *all* neighboring
708  // active children
709  std::vector<const Elem *> active_neighbor_children;
710 
711  current_neighbor->active_family_tree_by_neighbor
712  (active_neighbor_children, elem);
713 
714  for (const auto & current_child : active_neighbor_children)
715  if (this->contains_edge_of(current_child) || current_child->contains_edge_of(this))
716  {
717  // Make sure we'll test it
718  if (!neighbor_set.count(current_child))
719  next_untested_set.insert (current_child);
720 
721  neighbor_set.insert (current_child);
722  }
723  }
724 #endif // #ifdef LIBMESH_ENABLE_AMR
725  }
726  }
727  }
728  untested_set.swap(next_untested_set);
729  next_untested_set.clear();
730  }
731 }
732 
733 
734 
735 void Elem::find_interior_neighbors(std::set<const Elem *> & neighbor_set) const
736 {
737  ElemInternal::find_interior_neighbors(this, neighbor_set);
738 }
739 
740 
741 
742 void Elem::find_interior_neighbors(std::set<Elem *> & neighbor_set)
743 {
744  ElemInternal::find_interior_neighbors(this, neighbor_set);
745 }
746 
747 
748 
749 const Elem * Elem::interior_parent () const
750 {
751  // interior parents make no sense for full-dimensional elements.
752  libmesh_assert_less (this->dim(), LIBMESH_DIM);
753 
754  // they USED TO BE only good for level-0 elements, but we now
755  // support keeping interior_parent() valid on refined boundary
756  // elements.
757  // if (this->level() != 0)
758  // return this->parent()->interior_parent();
759 
760  // We store the interior_parent pointer after both the parent
761  // neighbor and neighbor pointers
762  Elem * interior_p = _elemlinks[1+this->n_sides()];
763 
764  // If we have an interior_parent, we USED TO assume it was a
765  // one-higher-dimensional interior element, but we now allow e.g.
766  // edge elements to have a 3D interior_parent with no
767  // intermediate 2D element.
768  // libmesh_assert (!interior_p ||
769  // interior_p->dim() == (this->dim()+1));
770  libmesh_assert (!interior_p ||
771  (interior_p == remote_elem) ||
772  (interior_p->dim() > this->dim()));
773 
774  // We require consistency between AMR of interior and of boundary
775  // elements
776  if (interior_p && (interior_p != remote_elem))
777  libmesh_assert_less_equal (interior_p->level(), this->level());
778 
779  return interior_p;
780 }
781 
782 
783 
785 {
786  // See the const version for comments
787  libmesh_assert_less (this->dim(), LIBMESH_DIM);
788  Elem * interior_p = _elemlinks[1+this->n_sides()];
789 
790  libmesh_assert (!interior_p ||
791  (interior_p == remote_elem) ||
792  (interior_p->dim() > this->dim()));
793  if (interior_p && (interior_p != remote_elem))
794  libmesh_assert_less_equal (interior_p->level(), this->level());
795 
796  return interior_p;
797 }
798 
799 
800 
802 {
803  // interior parents make no sense for full-dimensional elements.
804  libmesh_assert_less (this->dim(), LIBMESH_DIM);
805 
806  // If we have an interior_parent, we USED TO assume it was a
807  // one-higher-dimensional interior element, but we now allow e.g.
808  // edge elements to have a 3D interior_parent with no
809  // intermediate 2D element.
810  // libmesh_assert (!p ||
811  // p->dim() == (this->dim()+1));
812  libmesh_assert (!p ||
813  (p == remote_elem) ||
814  (p->dim() > this->dim()));
815 
816  _elemlinks[1+this->n_sides()] = p;
817 }
818 
819 
820 
821 #ifdef LIBMESH_ENABLE_PERIODIC
822 
823 Elem * Elem::topological_neighbor (const unsigned int i,
824  MeshBase & mesh,
825  const PointLocatorBase & point_locator,
826  const PeriodicBoundaries * pb)
827 {
828  libmesh_assert_less (i, this->n_neighbors());
829 
830  Elem * neighbor_i = this->neighbor_ptr(i);
831  if (neighbor_i != nullptr)
832  return neighbor_i;
833 
834  if (pb)
835  {
836  // Since the neighbor is nullptr it must be on a boundary. We need
837  // see if this is a periodic boundary in which case it will have a
838  // topological neighbor
839  std::vector<boundary_id_type> bc_ids;
840  mesh.get_boundary_info().boundary_ids(this, cast_int<unsigned short>(i), bc_ids);
841  for (const auto & id : bc_ids)
842  if (pb->boundary(id))
843  {
844  // Since the point locator inside of periodic boundaries
845  // returns a const pointer we will retrieve the proper
846  // pointer directly from the mesh object.
847  const Elem * const cn = pb->neighbor(id, point_locator, this, i);
848  neighbor_i = const_cast<Elem *>(cn);
849 
850  // Since coarse elements do not have more refined
851  // neighbors we need to make sure that we don't return one
852  // of these types of neighbors.
853  if (neighbor_i)
854  while (level() < neighbor_i->level())
855  neighbor_i = neighbor_i->parent();
856  return neighbor_i;
857  }
858  }
859 
860  return nullptr;
861 }
862 
863 
864 
865 const Elem * Elem::topological_neighbor (const unsigned int i,
866  const MeshBase & mesh,
867  const PointLocatorBase & point_locator,
868  const PeriodicBoundaries * pb) const
869 {
870  libmesh_assert_less (i, this->n_neighbors());
871 
872  const Elem * neighbor_i = this->neighbor_ptr(i);
873  if (neighbor_i != nullptr)
874  return neighbor_i;
875 
876  if (pb)
877  {
878  // Since the neighbor is nullptr it must be on a boundary. We need
879  // see if this is a periodic boundary in which case it will have a
880  // topological neighbor
881  std::vector<boundary_id_type> bc_ids;
882  mesh.get_boundary_info().boundary_ids(this, cast_int<unsigned short>(i), bc_ids);
883  for (const auto & id : bc_ids)
884  if (pb->boundary(id))
885  {
886  neighbor_i = pb->neighbor(id, point_locator, this, i);
887 
888  // Since coarse elements do not have more refined
889  // neighbors we need to make sure that we don't return one
890  // of these types of neighbors.
891  if (neighbor_i)
892  while (level() < neighbor_i->level())
893  neighbor_i = neighbor_i->parent();
894  return neighbor_i;
895  }
896  }
897 
898  return nullptr;
899 }
900 
901 
903  const MeshBase & mesh,
904  const PointLocatorBase & point_locator,
905  const PeriodicBoundaries * pb) const
906 {
907  // First see if this is a normal "interior" neighbor
908  if (has_neighbor(elem))
909  return true;
910 
911  for (auto n : this->side_index_range())
912  if (this->topological_neighbor(n, mesh, point_locator, pb))
913  return true;
914 
915  return false;
916 }
917 
918 
919 #endif
920 
921 #ifdef DEBUG
922 
924 {
925  libmesh_assert(this->valid_id());
926  for (auto n : this->node_index_range())
927  {
928  libmesh_assert(this->node_ptr(n));
929  libmesh_assert(this->node_ptr(n)->valid_id());
930  }
931 }
932 
933 
934 
936 {
937  for (auto n : this->side_index_range())
938  {
939  const Elem * neigh = this->neighbor_ptr(n);
940 
941  // Any element might have a remote neighbor; checking
942  // to make sure that's not inaccurate is tough.
943  if (neigh == remote_elem)
944  continue;
945 
946  if (neigh)
947  {
948  // Only subactive elements have subactive neighbors
949  libmesh_assert (this->subactive() || !neigh->subactive());
950 
951  const Elem * elem = this;
952 
953  // If we're subactive but our neighbor isn't, its
954  // return neighbor link will be to our first active
955  // ancestor OR to our inactive ancestor of the same
956  // level as neigh,
957  if (this->subactive() && !neigh->subactive())
958  {
959  for (elem = this; !elem->active();
960  elem = elem->parent())
961  libmesh_assert(elem);
962  }
963  else
964  {
965  unsigned int rev = neigh->which_neighbor_am_i(elem);
966  libmesh_assert_less (rev, neigh->n_neighbors());
967 
968  if (this->subactive() && !neigh->subactive())
969  {
970  while (neigh->neighbor_ptr(rev) != elem)
971  {
972  libmesh_assert(elem->parent());
973  elem = elem->parent();
974  }
975  }
976  else
977  {
978  const Elem * nn = neigh->neighbor_ptr(rev);
979  libmesh_assert(nn);
980 
981  for (; elem != nn; elem = elem->parent())
982  libmesh_assert(elem);
983  }
984  }
985  }
986  // If we don't have a neighbor and we're not subactive, our
987  // ancestors shouldn't have any neighbors in this same
988  // direction.
989  else if (!this->subactive())
990  {
991  const Elem * my_parent = this->parent();
992  if (my_parent &&
993  // A parent with a different dimension isn't really one of
994  // our ancestors, it means we're on a boundary mesh and this
995  // is an interior mesh element for which we're on a side.
996  // Nothing to test for in that case.
997  (my_parent->dim() == this->dim()))
998  libmesh_assert (!my_parent->neighbor_ptr(n));
999  }
1000  }
1001 }
1002 
1003 #endif // DEBUG
1004 
1005 
1006 
1007 void Elem::make_links_to_me_local(unsigned int n, unsigned int nn)
1008 {
1009  Elem * neigh = this->neighbor_ptr(n);
1010 
1011  // Don't bother calling this function unless it's necessary
1012  libmesh_assert(neigh);
1013  libmesh_assert(!neigh->is_remote());
1014 
1015  // We never have neighbors more refined than us
1016  libmesh_assert_less_equal (neigh->level(), this->level());
1017 
1018  // We never have subactive neighbors of non subactive elements
1019  libmesh_assert(!neigh->subactive() || this->subactive());
1020 
1021  // If we have a neighbor less refined than us then it must not
1022  // have any more refined descendants we could have pointed to
1023  // instead.
1024  libmesh_assert((neigh->level() == this->level()) ||
1025  (neigh->active() && !this->subactive()) ||
1026  (!neigh->has_children() && this->subactive()));
1027 
1028  // If neigh is at our level, then its family might have
1029  // remote_elem neighbor links which need to point to us
1030  // instead, but if not, then we're done.
1031  if (neigh->level() != this->level())
1032  return;
1033 
1034  // What side of neigh are we on? nn.
1035  //
1036  // We can't use the usual Elem method because we're in the middle of
1037  // restoring topology. We can't compare side_ptr nodes because
1038  // users want to abuse neighbor_ptr to point to
1039  // not-technically-neighbors across mesh slits. We can't compare
1040  // node locations because users want to move those
1041  // not-technically-neighbors until they're
1042  // not-even-geometrically-neighbors.
1043 
1044  // Find any elements that ought to point to elem
1045  std::vector<Elem *> neigh_family;
1046 #ifdef LIBMESH_ENABLE_AMR
1047  if (this->active())
1048  neigh->family_tree_by_side(neigh_family, nn);
1049  else
1050 #endif
1051  neigh_family.push_back(neigh);
1052 
1053  // And point them to elem
1054  for (auto & neigh_family_member : neigh_family)
1055  {
1056  // Only subactive elements point to other subactive elements
1057  if (this->subactive() && !neigh_family_member->subactive())
1058  continue;
1059 
1060  // Ideally, the neighbor link ought to either be correct
1061  // already or ought to be to remote_elem.
1062  //
1063  // However, if we're redistributing a newly created elem,
1064  // after an AMR step but before find_neighbors has fixed up
1065  // neighbor links, we might have an out of date neighbor
1066  // link to elem's parent instead.
1067 #ifdef LIBMESH_ENABLE_AMR
1068  libmesh_assert((neigh_family_member->neighbor_ptr(nn) &&
1069  (neigh_family_member->neighbor_ptr(nn)->active() ||
1070  neigh_family_member->neighbor_ptr(nn)->is_ancestor_of(this))) ||
1071  (neigh_family_member->neighbor_ptr(nn) == remote_elem) ||
1072  ((this->refinement_flag() == JUST_REFINED) &&
1073  (this->parent() != nullptr) &&
1074  (neigh_family_member->neighbor_ptr(nn) == this->parent())));
1075 #else
1076  libmesh_assert((neigh_family_member->neighbor_ptr(nn) == this) ||
1077  (neigh_family_member->neighbor_ptr(nn) == remote_elem));
1078 #endif
1079 
1080  neigh_family_member->set_neighbor(nn, this);
1081  }
1082 }
1083 
1084 
1086 {
1087  libmesh_assert_not_equal_to (this, remote_elem);
1088 
1089  // We need to have handled any children first
1090 #if defined(LIBMESH_ENABLE_AMR) && defined(DEBUG)
1091  if (this->has_children())
1092  for (auto & child : this->child_ref_range())
1093  libmesh_assert_equal_to (&child, remote_elem);
1094 #endif
1095 
1096  // Remotify any neighbor links
1097  for (auto neigh : this->neighbor_ptr_range())
1098  {
1099  if (neigh && neigh != remote_elem)
1100  {
1101  // My neighbor should never be more refined than me; my real
1102  // neighbor would have been its parent in that case.
1103  libmesh_assert_greater_equal (this->level(), neigh->level());
1104 
1105  if (this->level() == neigh->level() &&
1106  neigh->has_neighbor(this))
1107  {
1108 #ifdef LIBMESH_ENABLE_AMR
1109  // My neighbor may have descendants which also consider me a
1110  // neighbor
1111  std::vector<Elem *> family;
1112  neigh->total_family_tree_by_neighbor (family, this);
1113 
1114  // FIXME - There's a lot of ugly const_casts here; we
1115  // may want to make remote_elem non-const
1116  for (auto & n : family)
1117  {
1118  libmesh_assert (n);
1119  if (n == remote_elem)
1120  continue;
1121  unsigned int my_s = n->which_neighbor_am_i(this);
1122  libmesh_assert_less (my_s, n->n_neighbors());
1123  libmesh_assert_equal_to (n->neighbor_ptr(my_s), this);
1124  n->set_neighbor(my_s, const_cast<RemoteElem *>(remote_elem));
1125  }
1126 #else
1127  unsigned int my_s = neigh->which_neighbor_am_i(this);
1128  libmesh_assert_less (my_s, neigh->n_neighbors());
1129  libmesh_assert_equal_to (neigh->neighbor_ptr(my_s), this);
1130  neigh->set_neighbor(my_s, const_cast<RemoteElem *>(remote_elem));
1131 #endif
1132  }
1133 #ifdef LIBMESH_ENABLE_AMR
1134  // Even if my neighbor doesn't link back to me, it might
1135  // have subactive descendants which do
1136  else if (neigh->has_children())
1137  {
1138  // If my neighbor at the same level doesn't have me as a
1139  // neighbor, I must be subactive
1140  libmesh_assert(this->level() > neigh->level() ||
1141  this->subactive());
1142 
1143  // My neighbor must have some ancestor of mine as a
1144  // neighbor
1145  Elem * my_ancestor = this->parent();
1146  libmesh_assert(my_ancestor);
1147  while (!neigh->has_neighbor(my_ancestor))
1148  {
1149  my_ancestor = my_ancestor->parent();
1150  libmesh_assert(my_ancestor);
1151  }
1152 
1153  // My neighbor may have descendants which consider me a
1154  // neighbor
1155  std::vector<Elem *> family;
1156  neigh->total_family_tree_by_subneighbor (family, my_ancestor, this);
1157 
1158  for (auto & n : family)
1159  {
1160  libmesh_assert (n);
1161  if (n->is_remote())
1162  continue;
1163  unsigned int my_s = n->which_neighbor_am_i(this);
1164  libmesh_assert_less (my_s, n->n_neighbors());
1165  libmesh_assert_equal_to (n->neighbor_ptr(my_s), this);
1166  // TODO: we may want to make remote_elem non-const.
1167  n->set_neighbor(my_s, const_cast<RemoteElem *>(remote_elem));
1168  }
1169  }
1170 #endif
1171  }
1172  }
1173 
1174 #ifdef LIBMESH_ENABLE_AMR
1175  // Remotify parent's child link
1176  Elem * my_parent = this->parent();
1177  if (my_parent &&
1178  // As long as it's not already remote
1179  my_parent != remote_elem &&
1180  // And it's a real parent, not an interior parent
1181  this->dim() == my_parent->dim())
1182  {
1183  unsigned int me = my_parent->which_child_am_i(this);
1184  libmesh_assert_equal_to (my_parent->child_ptr(me), this);
1185  my_parent->set_child(me, const_cast<RemoteElem *>(remote_elem));
1186  }
1187 #endif
1188 }
1189 
1190 
1192 {
1193  libmesh_assert_not_equal_to (this, remote_elem);
1194 
1195  // We need to have handled any children first
1196 #ifdef LIBMESH_ENABLE_AMR
1197  libmesh_assert (!this->has_children());
1198 #endif
1199 
1200  // Nullify any neighbor links
1201  for (auto neigh : this->neighbor_ptr_range())
1202  {
1203  if (neigh && neigh != remote_elem)
1204  {
1205  // My neighbor should never be more refined than me; my real
1206  // neighbor would have been its parent in that case.
1207  libmesh_assert_greater_equal (this->level(), neigh->level());
1208 
1209  if (this->level() == neigh->level() &&
1210  neigh->has_neighbor(this))
1211  {
1212 #ifdef LIBMESH_ENABLE_AMR
1213  // My neighbor may have descendants which also consider me a
1214  // neighbor
1215  std::vector<Elem *> family;
1216  neigh->total_family_tree_by_neighbor (family, this);
1217 
1218  for (auto & n : family)
1219  {
1220  libmesh_assert (n);
1221  if (n->is_remote())
1222  continue;
1223  unsigned int my_s = n->which_neighbor_am_i(this);
1224  libmesh_assert_less (my_s, n->n_neighbors());
1225  libmesh_assert_equal_to (n->neighbor_ptr(my_s), this);
1226  n->set_neighbor(my_s, nullptr);
1227  }
1228 #else
1229  unsigned int my_s = neigh->which_neighbor_am_i(this);
1230  libmesh_assert_less (my_s, neigh->n_neighbors());
1231  libmesh_assert_equal_to (neigh->neighbor_ptr(my_s), this);
1232  neigh->set_neighbor(my_s, nullptr);
1233 #endif
1234  }
1235 #ifdef LIBMESH_ENABLE_AMR
1236  // Even if my neighbor doesn't link back to me, it might
1237  // have subactive descendants which do
1238  else if (neigh->has_children())
1239  {
1240  // If my neighbor at the same level doesn't have me as a
1241  // neighbor, I must be subactive
1242  libmesh_assert(this->level() > neigh->level() ||
1243  this->subactive());
1244 
1245  // My neighbor must have some ancestor of mine as a
1246  // neighbor
1247  Elem * my_ancestor = this->parent();
1248  libmesh_assert(my_ancestor);
1249  while (!neigh->has_neighbor(my_ancestor))
1250  {
1251  my_ancestor = my_ancestor->parent();
1252  libmesh_assert(my_ancestor);
1253  }
1254 
1255  // My neighbor may have descendants which consider me a
1256  // neighbor
1257  std::vector<Elem *> family;
1258  neigh->total_family_tree_by_subneighbor (family, my_ancestor, this);
1259 
1260  for (auto & n : family)
1261  {
1262  libmesh_assert (n);
1263  if (n->is_remote())
1264  continue;
1265  unsigned int my_s = n->which_neighbor_am_i(this);
1266  libmesh_assert_less (my_s, n->n_neighbors());
1267  libmesh_assert_equal_to (n->neighbor_ptr(my_s), this);
1268  n->set_neighbor(my_s, nullptr);
1269  }
1270  }
1271 #endif
1272  }
1273  }
1274 
1275 #ifdef LIBMESH_ENABLE_AMR
1276  // We can't currently delete a child with a parent!
1277  libmesh_assert (!this->parent());
1278 #endif
1279 }
1280 
1281 
1282 
1283 void Elem::write_connectivity (std::ostream & out_stream,
1284  const IOPackage iop) const
1285 {
1286  libmesh_assert (out_stream.good());
1288  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
1289 
1290  switch (iop)
1291  {
1292  case TECPLOT:
1293  {
1294  // This connectivity vector will be used repeatedly instead
1295  // of being reconstructed inside the loop.
1296  std::vector<dof_id_type> conn;
1297  for (auto sc : IntRange<unsigned int>(0, this->n_sub_elem()))
1298  {
1299  this->connectivity(sc, TECPLOT, conn);
1300 
1301  std::copy(conn.begin(),
1302  conn.end(),
1303  std::ostream_iterator<dof_id_type>(out_stream, " "));
1304 
1305  out_stream << '\n';
1306  }
1307  return;
1308  }
1309 
1310  case UCD:
1311  {
1312  for (auto i : this->node_index_range())
1313  out_stream << this->node_id(i)+1 << "\t";
1314 
1315  out_stream << '\n';
1316  return;
1317  }
1318 
1319  default:
1320  libmesh_error_msg("Unsupported IO package " << iop);
1321  }
1322 }
1323 
1324 
1325 
1327 {
1328  switch (q)
1329  {
1333  default:
1334  {
1335  libmesh_do_once( libmesh_here();
1336 
1337  libMesh::err << "ERROR: unknown quality metric: "
1339  << std::endl
1340  << "Cowardly returning 1."
1341  << std::endl; );
1342 
1343  return 1.;
1344  }
1345  }
1346 }
1347 
1348 
1349 
1350 bool Elem::ancestor() const
1351 {
1352 #ifdef LIBMESH_ENABLE_AMR
1353 
1354  // Use a fast, DistributedMesh-safe definition
1355  const bool is_ancestor =
1356  !this->active() && !this->subactive();
1357 
1358  // But check for inconsistencies if we have time
1359 #ifdef DEBUG
1360  if (!is_ancestor && this->has_children())
1361  {
1362  for (auto & c : this->child_ref_range())
1363  {
1364  if (&c != remote_elem)
1365  {
1366  libmesh_assert(!c.active());
1367  libmesh_assert(!c.ancestor());
1368  }
1369  }
1370  }
1371 #endif // DEBUG
1372 
1373  return is_ancestor;
1374 
1375 #else
1376  return false;
1377 #endif
1378 }
1379 
1380 
1381 
1382 #ifdef LIBMESH_ENABLE_AMR
1383 
1384 void Elem::add_child (Elem * elem)
1385 {
1386  const unsigned int nc = this->n_children();
1387 
1388  if (_children == nullptr)
1389  {
1390  _children = new Elem *[nc];
1391 
1392  for (unsigned int c = 0; c != nc; c++)
1393  this->set_child(c, nullptr);
1394  }
1395 
1396  for (unsigned int c = 0; c != nc; c++)
1397  {
1398  if (this->_children[c] == nullptr || this->_children[c] == remote_elem)
1399  {
1400  libmesh_assert_equal_to (this, elem->parent());
1401  this->set_child(c, elem);
1402  return;
1403  }
1404  }
1405 
1406  libmesh_error_msg("Error: Tried to add a child to an element with full children array");
1407 }
1408 
1409 
1410 
1411 void Elem::add_child (Elem * elem, unsigned int c)
1412 {
1413  if (!this->has_children())
1414  {
1415  const unsigned int nc = this->n_children();
1416  _children = new Elem *[nc];
1417 
1418  for (unsigned int i = 0; i != nc; i++)
1419  this->set_child(i, nullptr);
1420  }
1421 
1422  libmesh_assert (this->_children[c] == nullptr || this->child_ptr(c) == remote_elem);
1423  libmesh_assert (elem == remote_elem || this == elem->parent());
1424 
1425  this->set_child(c, elem);
1426 }
1427 
1428 
1429 
1430 void Elem::replace_child (Elem * elem, unsigned int c)
1431 {
1432  libmesh_assert(this->has_children());
1433 
1434  libmesh_assert(this->child_ptr(c));
1435 
1436  this->set_child(c, elem);
1437 }
1438 
1439 
1440 
1441 void Elem::family_tree (std::vector<const Elem *> & family,
1442  bool reset) const
1443 {
1444  ElemInternal::family_tree(this, family, reset);
1445 }
1446 
1447 
1448 
1449 void Elem::family_tree (std::vector<Elem *> & family,
1450  bool reset)
1451 {
1452  ElemInternal::family_tree(this, family, reset);
1453 }
1454 
1455 
1456 
1457 void Elem::total_family_tree (std::vector<const Elem *> & family,
1458  bool reset) const
1459 {
1460  ElemInternal::total_family_tree(this, family, reset);
1461 }
1462 
1463 
1464 
1465 void Elem::total_family_tree (std::vector<Elem *> & family,
1466  bool reset)
1467 {
1468  ElemInternal::total_family_tree(this, family, reset);
1469 }
1470 
1471 
1472 
1473 void Elem::active_family_tree (std::vector<const Elem *> & active_family,
1474  bool reset) const
1475 {
1476  ElemInternal::active_family_tree(this, active_family, reset);
1477 }
1478 
1479 
1480 
1481 void Elem::active_family_tree (std::vector<Elem *> & active_family,
1482  bool reset)
1483 {
1484  ElemInternal::active_family_tree(this, active_family, reset);
1485 }
1486 
1487 
1488 
1489 void Elem::family_tree_by_side (std::vector<const Elem *> & family,
1490  unsigned int side,
1491  bool reset) const
1492 {
1493  ElemInternal::family_tree_by_side(this, family, side, reset);
1494 }
1495 
1496 
1497 
1498 void Elem:: family_tree_by_side (std::vector<Elem *> & family,
1499  unsigned int side,
1500  bool reset)
1501 {
1502  ElemInternal::family_tree_by_side(this, family, side, reset);
1503 }
1504 
1505 
1506 
1507 void Elem::active_family_tree_by_side (std::vector<const Elem *> & family,
1508  unsigned int side,
1509  bool reset) const
1510 {
1511  ElemInternal::active_family_tree_by_side(this, family, side, reset);
1512 }
1513 
1514 
1515 
1516 void Elem::active_family_tree_by_side (std::vector<Elem *> & family,
1517  unsigned int side,
1518  bool reset)
1519 {
1520  ElemInternal::active_family_tree_by_side(this, family, side, reset);
1521 }
1522 
1523 
1524 
1525 void Elem::family_tree_by_neighbor (std::vector<const Elem *> & family,
1526  const Elem * neighbor,
1527  bool reset) const
1528 {
1529  ElemInternal::family_tree_by_neighbor(this, family, neighbor, reset);
1530 }
1531 
1532 
1533 
1534 void Elem::family_tree_by_neighbor (std::vector<Elem *> & family,
1535  Elem * neighbor,
1536  bool reset)
1537 {
1538  ElemInternal::family_tree_by_neighbor(this, family, neighbor, reset);
1539 }
1540 
1541 
1542 
1543 void Elem::total_family_tree_by_neighbor (std::vector<const Elem *> & family,
1544  const Elem * neighbor,
1545  bool reset) const
1546 {
1547  ElemInternal::total_family_tree_by_neighbor(this, family, neighbor, reset);
1548 }
1549 
1550 
1551 
1552 void Elem::total_family_tree_by_neighbor (std::vector<Elem *> & family,
1553  Elem * neighbor,
1554  bool reset)
1555 {
1556  ElemInternal::total_family_tree_by_neighbor(this, family, neighbor, reset);
1557 }
1558 
1559 
1560 
1561 void Elem::family_tree_by_subneighbor (std::vector<const Elem *> & family,
1562  const Elem * neighbor,
1563  const Elem * subneighbor,
1564  bool reset) const
1565 {
1566  ElemInternal::family_tree_by_subneighbor(this, family, neighbor, subneighbor, reset);
1567 }
1568 
1569 
1570 
1571 void Elem::family_tree_by_subneighbor (std::vector<Elem *> & family,
1572  Elem * neighbor,
1573  Elem * subneighbor,
1574  bool reset)
1575 {
1576  ElemInternal::family_tree_by_subneighbor(this, family, neighbor, subneighbor, reset);
1577 }
1578 
1579 
1580 
1581 void Elem::total_family_tree_by_subneighbor (std::vector<const Elem *> & family,
1582  const Elem * neighbor,
1583  const Elem * subneighbor,
1584  bool reset) const
1585 {
1586  ElemInternal::total_family_tree_by_subneighbor(this, family, neighbor, subneighbor, reset);
1587 }
1588 
1589 
1590 
1591 void Elem::total_family_tree_by_subneighbor (std::vector<Elem *> & family,
1592  Elem * neighbor,
1593  Elem * subneighbor,
1594  bool reset)
1595 {
1596  ElemInternal::total_family_tree_by_subneighbor(this, family, neighbor, subneighbor, reset);
1597 }
1598 
1599 
1600 
1601 void Elem::active_family_tree_by_neighbor (std::vector<const Elem *> & family,
1602  const Elem * neighbor,
1603  bool reset) const
1604 {
1605  ElemInternal::active_family_tree_by_neighbor(this, family, neighbor, reset);
1606 }
1607 
1608 
1609 
1610 void Elem::active_family_tree_by_neighbor (std::vector<Elem *> & family,
1611  Elem * neighbor,
1612  bool reset)
1613 {
1614  ElemInternal::active_family_tree_by_neighbor(this, family, neighbor, reset);
1615 }
1616 
1617 
1618 
1619 void Elem::active_family_tree_by_topological_neighbor (std::vector<const Elem *> & family,
1620  const Elem * neighbor,
1621  const MeshBase & mesh,
1622  const PointLocatorBase & point_locator,
1623  const PeriodicBoundaries * pb,
1624  bool reset) const
1625 {
1627  mesh, point_locator, pb,
1628  reset);
1629 }
1630 
1631 
1632 
1633 void Elem::active_family_tree_by_topological_neighbor (std::vector<Elem *> & family,
1634  Elem * neighbor,
1635  const MeshBase & mesh,
1636  const PointLocatorBase & point_locator,
1637  const PeriodicBoundaries * pb,
1638  bool reset)
1639 {
1641  mesh, point_locator, pb,
1642  reset);
1643 }
1644 
1645 
1646 bool Elem::is_child_on_edge(const unsigned int libmesh_dbg_var(c),
1647  const unsigned int e) const
1648 {
1649  libmesh_assert_less (c, this->n_children());
1650  libmesh_assert_less (e, this->n_edges());
1651 
1652  std::unique_ptr<const Elem> my_edge = this->build_edge_ptr(e);
1653  std::unique_ptr<const Elem> child_edge = this->build_edge_ptr(e);
1654 
1655  // We're assuming that an overlapping child edge has the same
1656  // number and orientation as its parent
1657  return (child_edge->node_id(0) == my_edge->node_id(0) ||
1658  child_edge->node_id(1) == my_edge->node_id(1));
1659 }
1660 
1661 
1662 
1663 unsigned int Elem::min_p_level_by_neighbor(const Elem * neighbor_in,
1664  unsigned int current_min) const
1665 {
1666  libmesh_assert(!this->subactive());
1667  libmesh_assert(neighbor_in->active());
1668 
1669  // If we're an active element this is simple
1670  if (this->active())
1671  return std::min(current_min, this->p_level());
1672 
1673  libmesh_assert(has_neighbor(neighbor_in));
1674 
1675  // The p_level() of an ancestor element is already the minimum
1676  // p_level() of its children - so if that's high enough, we don't
1677  // need to examine any children.
1678  if (current_min <= this->p_level())
1679  return current_min;
1680 
1681  unsigned int min_p_level = current_min;
1682 
1683  for (auto & c : this->child_ref_range())
1684  if (&c != remote_elem && c.has_neighbor(neighbor_in))
1685  min_p_level =
1686  c.min_p_level_by_neighbor(neighbor_in, min_p_level);
1687 
1688  return min_p_level;
1689 }
1690 
1691 
1692 unsigned int Elem::min_new_p_level_by_neighbor(const Elem * neighbor_in,
1693  unsigned int current_min) const
1694 {
1695  libmesh_assert(!this->subactive());
1696  libmesh_assert(neighbor_in->active());
1697 
1698  // If we're an active element this is simple
1699  if (this->active())
1700  {
1701  unsigned int new_p_level = this->p_level();
1702  if (this->p_refinement_flag() == Elem::REFINE)
1703  new_p_level += 1;
1704  if (this->p_refinement_flag() == Elem::COARSEN)
1705  {
1706  libmesh_assert_greater (new_p_level, 0);
1707  new_p_level -= 1;
1708  }
1709  return std::min(current_min, new_p_level);
1710  }
1711 
1712  libmesh_assert(has_neighbor(neighbor_in));
1713 
1714  unsigned int min_p_level = current_min;
1715 
1716  for (auto & c : this->child_ref_range())
1717  if (&c != remote_elem && c.has_neighbor(neighbor_in))
1718  min_p_level =
1719  c.min_new_p_level_by_neighbor(neighbor_in, min_p_level);
1720 
1721  return min_p_level;
1722 }
1723 
1724 
1725 
1726 unsigned int Elem::as_parent_node (unsigned int child,
1727  unsigned int child_node) const
1728 {
1729  const unsigned int nc = this->n_children();
1730  libmesh_assert_less(child, nc);
1731 
1732  // Cached return values, indexed first by embedding_matrix version,
1733  // then by child number, then by child node number.
1734  std::vector<std::vector<std::vector<signed char>>> &
1735  cached_parent_indices = this->_get_parent_indices_cache();
1736 
1737  unsigned int em_vers = this->embedding_matrix_version();
1738 
1739  // We may be updating the cache on one thread, and while that
1740  // happens we can't safely access the cache from other threads.
1741  Threads::spin_mutex::scoped_lock lock(parent_indices_mutex);
1742 
1743  if (em_vers >= cached_parent_indices.size())
1744  cached_parent_indices.resize(em_vers+1);
1745 
1746  if (child >= cached_parent_indices[em_vers].size())
1747  {
1748  const signed char nn = cast_int<signed char>(this->n_nodes());
1749 
1750  cached_parent_indices[em_vers].resize(nc);
1751 
1752  for (unsigned int c = 0; c != nc; ++c)
1753  {
1754  const unsigned int ncn = this->n_nodes_in_child(c);
1755  cached_parent_indices[em_vers][c].resize(ncn);
1756  for (unsigned int cn = 0; cn != ncn; ++cn)
1757  {
1758  for (signed char n = 0; n != nn; ++n)
1759  {
1760  const float em_val = this->embedding_matrix
1761  (c, cn, n);
1762  if (em_val == 1)
1763  {
1764  cached_parent_indices[em_vers][c][cn] = n;
1765  break;
1766  }
1767 
1768  if (em_val != 0)
1769  {
1770  cached_parent_indices[em_vers][c][cn] =
1771  -1;
1772  break;
1773  }
1774 
1775  // We should never see an all-zero embedding matrix
1776  // row
1777  libmesh_assert_not_equal_to (n+1, nn);
1778  }
1779  }
1780  }
1781  }
1782 
1783  const signed char cache_val =
1784  cached_parent_indices[em_vers][child][child_node];
1785  if (cache_val == -1)
1786  return libMesh::invalid_uint;
1787 
1788  return cached_parent_indices[em_vers][child][child_node];
1789 }
1790 
1791 
1792 
1793 const std::vector<std::pair<unsigned char, unsigned char>> &
1795  unsigned int child_node) const
1796 {
1797  // Indexed first by embedding matrix type, then by child id, then by
1798  // child node, then by bracketing pair
1799  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> &
1800  cached_bracketing_nodes = this->_get_bracketing_node_cache();
1801 
1802  const unsigned int em_vers = this->embedding_matrix_version();
1803 
1804  // We may be updating the cache on one thread, and while that
1805  // happens we can't safely access the cache from other threads.
1806  Threads::spin_mutex::scoped_lock lock(parent_bracketing_nodes_mutex);
1807 
1808  if (cached_bracketing_nodes.size() <= em_vers)
1809  cached_bracketing_nodes.resize(em_vers+1);
1810 
1811  const unsigned int nc = this->n_children();
1812 
1813  // If we haven't cached the bracketing nodes corresponding to this
1814  // embedding matrix yet, let's do so now.
1815  if (cached_bracketing_nodes[em_vers].size() < nc)
1816  {
1817  // If we're a second-order element but we're not a full-order
1818  // element, then some of our bracketing nodes may not exist
1819  // except on the equivalent full-order element. Let's build an
1820  // equivalent full-order element and make a copy of its cache to
1821  // use.
1822  if (this->default_order() != FIRST &&
1823  second_order_equivalent_type(this->type(), /*full_ordered=*/ true) != this->type())
1824  {
1825  // Check that we really are the non-full-order type
1826  libmesh_assert_equal_to
1827  (second_order_equivalent_type (this->type(), false),
1828  this->type());
1829 
1830  // Build the full-order type
1831  ElemType full_type =
1832  second_order_equivalent_type(this->type(), /*full_ordered=*/ true);
1833  std::unique_ptr<Elem> full_elem = Elem::build(full_type);
1834 
1835  // This won't work for elements with multiple
1836  // embedding_matrix versions, but every such element is full
1837  // order anyways.
1838  libmesh_assert_equal_to(em_vers, 0);
1839 
1840  // Make sure its cache has been built. We temporarily
1841  // release our mutex lock so that the inner call can
1842  // re-acquire it.
1843  lock.release();
1844  full_elem->parent_bracketing_nodes(0,0);
1845 
1846  // And then we need to lock again, so that if someone *else*
1847  // grabbed our lock before we did we don't risk accessing
1848  // cached_bracketing_nodes while they're working on it.
1849  // Threading is hard.
1850  lock.acquire(parent_bracketing_nodes_mutex);
1851 
1852  // Copy its cache
1853  cached_bracketing_nodes =
1854  full_elem->_get_bracketing_node_cache();
1855 
1856  // Now we don't need to build the cache ourselves.
1857  return cached_bracketing_nodes[em_vers][child][child_node];
1858  }
1859 
1860  cached_bracketing_nodes[em_vers].resize(nc);
1861 
1862  const unsigned int nn = this->n_nodes();
1863 
1864  // We have to examine each child
1865  for (unsigned int c = 0; c != nc; ++c)
1866  {
1867  const unsigned int ncn = this->n_nodes_in_child(c);
1868 
1869  cached_bracketing_nodes[em_vers][c].resize(ncn);
1870 
1871  // We have to examine each node in that child
1872  for (unsigned int n = 0; n != ncn; ++n)
1873  {
1874  // If this child node isn't a vertex or an infinite
1875  // child element's mid-infinite-edge node, then we need
1876  // to find bracketing nodes on the child.
1877  if (!this->is_vertex_on_child(c, n)
1878 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1879  && !this->is_mid_infinite_edge_node(n)
1880 #endif
1881  )
1882  {
1883  // Use the embedding matrix to find the child node
1884  // location in parent master element space
1885  Point bracketed_pt;
1886 
1887  for (unsigned int pn = 0; pn != nn; ++pn)
1888  {
1889  const float em_val =
1890  this->embedding_matrix(c,n,pn);
1891 
1892  libmesh_assert_not_equal_to (em_val, 1);
1893  if (em_val != 0.)
1894  bracketed_pt.add_scaled(this->master_point(pn), em_val);
1895  }
1896 
1897  // Check each pair of nodes on the child which are
1898  // also both parent nodes
1899  for (unsigned int n1 = 0; n1 != ncn; ++n1)
1900  {
1901  if (n1 == n)
1902  continue;
1903 
1904  unsigned int parent_n1 =
1905  this->as_parent_node(c,n1);
1906 
1907  if (parent_n1 == libMesh::invalid_uint)
1908  continue;
1909 
1910  Point p1 = this->master_point(parent_n1);
1911 
1912  for (unsigned int n2 = n1+1; n2 < nn; ++n2)
1913  {
1914  if (n2 == n)
1915  continue;
1916 
1917  unsigned int parent_n2 =
1918  this->as_parent_node(c,n2);
1919 
1920  if (parent_n2 == libMesh::invalid_uint)
1921  continue;
1922 
1923  Point p2 = this->master_point(parent_n2);
1924 
1925  Point pmid = (p1 + p2)/2;
1926 
1927  if (pmid == bracketed_pt)
1928  {
1929  cached_bracketing_nodes[em_vers][c][n].push_back
1930  (std::make_pair(parent_n1,parent_n2));
1931  break;
1932  }
1933  else
1934  libmesh_assert(!pmid.absolute_fuzzy_equals(bracketed_pt));
1935  }
1936  }
1937  }
1938  // If this child node is a parent node, we need to
1939  // find bracketing nodes on the parent.
1940  else
1941  {
1942  unsigned int parent_node = this->as_parent_node(c,n);
1943 
1944  Point bracketed_pt;
1945 
1946  // If we're not a parent node, use the embedding
1947  // matrix to find the child node location in parent
1948  // master element space
1949  if (parent_node == libMesh::invalid_uint)
1950  {
1951  for (unsigned int pn = 0; pn != nn; ++pn)
1952  {
1953  const float em_val =
1954  this->embedding_matrix(c,n,pn);
1955 
1956  libmesh_assert_not_equal_to (em_val, 1);
1957  if (em_val != 0.)
1958  bracketed_pt.add_scaled(this->master_point(pn), em_val);
1959  }
1960  }
1961  // If we're a parent node then we need no arithmetic
1962  else
1963  bracketed_pt = this->master_point(parent_node);
1964 
1965  for (unsigned int n1 = 0; n1 != nn; ++n1)
1966  {
1967  if (n1 == parent_node)
1968  continue;
1969 
1970  Point p1 = this->master_point(n1);
1971 
1972  for (unsigned int n2 = n1+1; n2 < nn; ++n2)
1973  {
1974  if (n2 == parent_node)
1975  continue;
1976 
1977  Point pmid = (p1 + this->master_point(n2))/2;
1978 
1979  if (pmid == bracketed_pt)
1980  {
1981  cached_bracketing_nodes[em_vers][c][n].push_back
1982  (std::make_pair(n1,n2));
1983  break;
1984  }
1985  else
1986  libmesh_assert(!pmid.absolute_fuzzy_equals(bracketed_pt));
1987  }
1988  }
1989  }
1990  }
1991  }
1992  }
1993 
1994  return cached_bracketing_nodes[em_vers][child][child_node];
1995 }
1996 
1997 
1998 const std::vector<std::pair<dof_id_type, dof_id_type>>
1999 Elem::bracketing_nodes(unsigned int child,
2000  unsigned int child_node) const
2001 {
2002  std::vector<std::pair<dof_id_type, dof_id_type>> returnval;
2003 
2004  const std::vector<std::pair<unsigned char, unsigned char>> & pbc =
2005  this->parent_bracketing_nodes(child,child_node);
2006 
2007  for (const auto & pb : pbc)
2008  {
2009  const unsigned short n_n = this->n_nodes();
2010  if (pb.first < n_n && pb.second < n_n)
2011  returnval.push_back(std::make_pair(this->node_id(pb.first),
2012  this->node_id(pb.second)));
2013  else
2014  {
2015  // We must be on a non-full-order higher order element...
2016  libmesh_assert_not_equal_to(this->default_order(), FIRST);
2017  libmesh_assert_not_equal_to
2018  (second_order_equivalent_type (this->type(), true),
2019  this->type());
2020  libmesh_assert_equal_to
2021  (second_order_equivalent_type (this->type(), false),
2022  this->type());
2023 
2024  // And that's a shame, because this is a nasty search:
2025 
2026  // Build the full-order type
2027  ElemType full_type =
2028  second_order_equivalent_type(this->type(), /*full_ordered=*/ true);
2029  std::unique_ptr<Elem> full_elem = Elem::build(full_type);
2030 
2033 
2034  // Find the bracketing nodes by figuring out what
2035  // already-created children will have them.
2036 
2037  // This only doesn't break horribly because we add children
2038  // and nodes in straightforward + hierarchical orders...
2039  for (unsigned int c=0; c <= child; ++c)
2040  for (auto n : IntRange<unsigned int>(0, this->n_nodes_in_child(c)))
2041  {
2042  if (c == child && n == child_node)
2043  break;
2044 
2045  if (pb.first == full_elem->as_parent_node(c,n))
2046  {
2047  // We should be consistent
2048  if (pt1 != DofObject::invalid_id)
2049  libmesh_assert_equal_to(pt1, this->child_ptr(c)->node_id(n));
2050 
2051  pt1 = this->child_ptr(c)->node_id(n);
2052  }
2053 
2054  if (pb.second == full_elem->as_parent_node(c,n))
2055  {
2056  // We should be consistent
2057  if (pt2 != DofObject::invalid_id)
2058  libmesh_assert_equal_to(pt2, this->child_ptr(c)->node_id(n));
2059 
2060  pt2 = this->child_ptr(c)->node_id(n);
2061  }
2062  }
2063 
2064  // We should *usually* find all bracketing nodes by the time
2065  // we query them (again, because of the child & node add
2066  // order)
2067  //
2068  // The exception is if we're a HEX20, in which case we will
2069  // find pairs of vertex nodes and edge nodes bracketing the
2070  // new central node but we *won't* find the pairs of face
2071  // nodes which we would have had on a HEX27. In that case
2072  // we'll still have enough bracketing nodes for a
2073  // topological lookup, but we won't be able to make the
2074  // following assertions.
2075  if (this->type() != HEX20)
2076  {
2077  libmesh_assert_not_equal_to (pt1, DofObject::invalid_id);
2078  libmesh_assert_not_equal_to (pt2, DofObject::invalid_id);
2079  }
2080 
2081  if (pt1 != DofObject::invalid_id &&
2082  pt2 != DofObject::invalid_id)
2083  returnval.push_back(std::make_pair(pt1, pt2));
2084  }
2085  }
2086 
2087  return returnval;
2088 }
2089 #endif // #ifdef LIBMESH_ENABLE_AMR
2090 
2091 
2092 
2093 
2094 bool Elem::contains_point (const Point & p, Real tol) const
2095 {
2096  // We currently allow the user to enlarge the bounding box by
2097  // providing a tol > TOLERANCE (so this routine is identical to
2098  // Elem::close_to_point()), but print a warning so that the
2099  // user can eventually switch his code over to calling close_to_point()
2100  // instead, which is intended to be used for this purpose.
2101  if (tol > TOLERANCE)
2102  {
2103  libmesh_do_once(libMesh::err
2104  << "WARNING: Resizing bounding box to match user-specified tolerance!\n"
2105  << "In the future, calls to Elem::contains_point() with tol > TOLERANCE\n"
2106  << "will be more optimized, but should not be used\n"
2107  << "to search for points 'close to' elements!\n"
2108  << "Instead, use Elem::close_to_point() for this purpose.\n"
2109  << std::endl;);
2110  return this->point_test(p, tol, tol);
2111  }
2112  else
2113  return this->point_test(p, TOLERANCE, tol);
2114 }
2115 
2116 
2117 
2118 
2119 bool Elem::close_to_point (const Point & p, Real tol) const
2120 {
2121  // This test uses the user's passed-in tolerance for the
2122  // bounding box test as well, thereby allowing the routine to
2123  // find points which are not only "in" the element, but also
2124  // "nearby" to within some tolerance.
2125  return this->point_test(p, tol, tol);
2126 }
2127 
2128 
2129 
2130 
2131 bool Elem::point_test(const Point & p, Real box_tol, Real map_tol) const
2132 {
2133  libmesh_assert_greater (box_tol, 0.);
2134  libmesh_assert_greater (map_tol, 0.);
2135 
2136  // This is a great optimization on first order elements, but it
2137  // could return false negatives on higher orders
2138  if (this->default_order() == FIRST)
2139  {
2140  // Check to make sure the element *could* contain this point, so we
2141  // can avoid an expensive inverse_map call if it doesn't.
2142  bool
2143 #if LIBMESH_DIM > 2
2144  point_above_min_z = false,
2145  point_below_max_z = false,
2146 #endif
2147 #if LIBMESH_DIM > 1
2148  point_above_min_y = false,
2149  point_below_max_y = false,
2150 #endif
2151  point_above_min_x = false,
2152  point_below_max_x = false;
2153 
2154  // For relative bounding box checks in physical space
2155  const Real my_hmax = this->hmax();
2156 
2157  for (auto & n : this->node_ref_range())
2158  {
2159  point_above_min_x = point_above_min_x || (n(0) - my_hmax*box_tol <= p(0));
2160  point_below_max_x = point_below_max_x || (n(0) + my_hmax*box_tol >= p(0));
2161 #if LIBMESH_DIM > 1
2162  point_above_min_y = point_above_min_y || (n(1) - my_hmax*box_tol <= p(1));
2163  point_below_max_y = point_below_max_y || (n(1) + my_hmax*box_tol >= p(1));
2164 #endif
2165 #if LIBMESH_DIM > 2
2166  point_above_min_z = point_above_min_z || (n(2) - my_hmax*box_tol <= p(2));
2167  point_below_max_z = point_below_max_z || (n(2) + my_hmax*box_tol >= p(2));
2168 #endif
2169  }
2170 
2171  if (
2172 #if LIBMESH_DIM > 2
2173  !point_above_min_z ||
2174  !point_below_max_z ||
2175 #endif
2176 #if LIBMESH_DIM > 1
2177  !point_above_min_y ||
2178  !point_below_max_y ||
2179 #endif
2180  !point_above_min_x ||
2181  !point_below_max_x)
2182  return false;
2183  }
2184 
2185  // To be on the safe side, we converge the inverse_map() iteration
2186  // to a slightly tighter tolerance than that requested by the
2187  // user...
2188  const Point mapped_point = FEMap::inverse_map(this->dim(),
2189  this,
2190  p,
2191  0.1*map_tol, // <- this is |dx| tolerance, the Newton residual should be ~ |dx|^2
2192  /*secure=*/ false);
2193 
2194  // Check that the refspace point maps back to p! This is only necessary
2195  // for 1D and 2D elements, 3D elements always live in 3D.
2196  //
2197  // TODO: The contains_point() function could most likely be implemented
2198  // more efficiently in the element sub-classes themselves, at least for
2199  // the linear element types.
2200  if (this->dim() < 3)
2201  {
2202  Point xyz = FEMap::map(this->dim(), this, mapped_point);
2203 
2204  // Compute the distance between the original point and the re-mapped point.
2205  // They should be in the same place.
2206  Real dist = (xyz - p).norm();
2207 
2208 
2209  // If dist is larger than some fraction of the tolerance, then return false.
2210  // This can happen when e.g. a 2D element is living in 3D, and
2211  // FEMap::inverse_map() maps p onto the projection of the element,
2212  // effectively "tricking" FEInterface::on_reference_element().
2213  if (dist > this->hmax() * map_tol)
2214  return false;
2215  }
2216 
2217 
2218 
2219  return FEInterface::on_reference_element(mapped_point, this->type(), map_tol);
2220 }
2221 
2222 
2223 
2224 
2225 void Elem::print_info (std::ostream & os) const
2226 {
2227  os << this->get_info()
2228  << std::endl;
2229 }
2230 
2231 
2232 
2233 std::string Elem::get_info () const
2234 {
2235  std::ostringstream oss;
2236 
2237  oss << " Elem Information" << '\n'
2238  << " id()=";
2239 
2240  if (this->valid_id())
2241  oss << this->id();
2242  else
2243  oss << "invalid";
2244 
2245 #ifdef LIBMESH_ENABLE_UNIQUE_ID
2246  oss << ", unique_id()=";
2247  if (this->valid_unique_id())
2248  oss << this->unique_id();
2249  else
2250  oss << "invalid";
2251 #endif
2252 
2253  oss << ", processor_id()=" << this->processor_id() << '\n';
2254 
2255  oss << " type()=" << Utility::enum_to_string(this->type()) << '\n'
2256  << " dim()=" << this->dim() << '\n'
2257  << " n_nodes()=" << this->n_nodes() << '\n';
2258 
2259  for (auto n : this->node_index_range())
2260  oss << " " << n << this->node_ref(n);
2261 
2262  oss << " n_sides()=" << this->n_sides() << '\n';
2263 
2264  for (auto s : this->side_index_range())
2265  {
2266  oss << " neighbor(" << s << ")=";
2267  if (this->neighbor_ptr(s))
2268  oss << this->neighbor_ptr(s)->id() << '\n';
2269  else
2270  oss << "nullptr\n";
2271  }
2272 
2273 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2274  if (!this->infinite())
2275  {
2276 #endif
2277  oss << " hmin()=" << this->hmin()
2278  << ", hmax()=" << this->hmax() << '\n'
2279  << " volume()=" << this->volume() << '\n';
2280 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2281  }
2282 #endif
2283  oss << " active()=" << this->active()
2284  << ", ancestor()=" << this->ancestor()
2285  << ", subactive()=" << this->subactive()
2286  << ", has_children()=" << this->has_children() << '\n'
2287  << " parent()=";
2288  if (this->parent())
2289  oss << this->parent()->id() << '\n';
2290  else
2291  oss << "nullptr\n";
2292  oss << " level()=" << this->level()
2293  << ", p_level()=" << this->p_level() << '\n'
2294 #ifdef LIBMESH_ENABLE_AMR
2295  << " refinement_flag()=" << Utility::enum_to_string(this->refinement_flag()) << '\n'
2296  << " p_refinement_flag()=" << Utility::enum_to_string(this->p_refinement_flag()) << '\n'
2297 #endif
2298 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2299  << " infinite()=" << this->infinite() << '\n';
2300  if (this->infinite())
2301  oss << " origin()=" << this->origin() << '\n'
2302 #endif
2303  ;
2304 
2305  oss << " DoFs=";
2306  for (auto s : IntRange<unsigned int>(0, this->n_systems()))
2307  for (auto v : IntRange<unsigned int>(0, this->n_vars(s)))
2308  for (auto c : IntRange<unsigned int>(0, this->n_comp(s,v)))
2309  oss << '(' << s << '/' << v << '/' << this->dof_number(s,v,c) << ") ";
2310 
2311 
2312  return oss.str();
2313 }
2314 
2315 
2316 
2318 {
2319  // Tell any of my neighbors about my death...
2320  // Looks strange, huh?
2321  for (auto n : this->side_index_range())
2322  {
2323  Elem * current_neighbor = this->neighbor_ptr(n);
2324  if (current_neighbor && current_neighbor != remote_elem)
2325  {
2326  // Note: it is possible that I see the neighbor
2327  // (which is coarser than me)
2328  // but they don't see me, so avoid that case.
2329  if (current_neighbor->level() == this->level())
2330  {
2331  const unsigned int w_n_a_i = current_neighbor->which_neighbor_am_i(this);
2332  libmesh_assert_less (w_n_a_i, current_neighbor->n_neighbors());
2333  current_neighbor->set_neighbor(w_n_a_i, nullptr);
2334  this->set_neighbor(n, nullptr);
2335  }
2336  }
2337  }
2338 }
2339 
2340 
2341 
2342 
2343 unsigned int Elem::n_second_order_adjacent_vertices (const unsigned int) const
2344 {
2345  // for linear elements, always return 0
2346  return 0;
2347 }
2348 
2349 
2350 
2351 unsigned short int Elem::second_order_adjacent_vertex (const unsigned int,
2352  const unsigned int) const
2353 {
2354  // for linear elements, always return 0
2355  return 0;
2356 }
2357 
2358 
2359 
2360 std::pair<unsigned short int, unsigned short int>
2361 Elem::second_order_child_vertex (const unsigned int) const
2362 {
2363  // for linear elements, always return 0
2364  return std::pair<unsigned short int, unsigned short int>(0,0);
2365 }
2366 
2367 
2368 
2370 {
2371  switch (et)
2372  {
2373  case NODEELEM:
2374  return NODEELEM;
2375  case EDGE2:
2376  case EDGE3:
2377  case EDGE4:
2378  return EDGE2;
2379  case TRI3:
2380  case TRI6:
2381  return TRI3;
2382  case TRISHELL3:
2383  return TRISHELL3;
2384  case QUAD4:
2385  case QUAD8:
2386  case QUAD9:
2387  return QUAD4;
2388  case QUADSHELL4:
2389  case QUADSHELL8:
2390  return QUADSHELL4;
2391  case TET4:
2392  case TET10:
2393  return TET4;
2394  case HEX8:
2395  case HEX27:
2396  case HEX20:
2397  return HEX8;
2398  case PRISM6:
2399  case PRISM15:
2400  case PRISM18:
2401  return PRISM6;
2402  case PYRAMID5:
2403  case PYRAMID13:
2404  case PYRAMID14:
2405  return PYRAMID5;
2406 
2407 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2408 
2409  case INFEDGE2:
2410  return INFEDGE2;
2411  case INFQUAD4:
2412  case INFQUAD6:
2413  return INFQUAD4;
2414  case INFHEX8:
2415  case INFHEX16:
2416  case INFHEX18:
2417  return INFHEX8;
2418  case INFPRISM6:
2419  case INFPRISM12:
2420  return INFPRISM6;
2421 
2422 #endif
2423 
2424  default:
2425  // unknown element
2426  return INVALID_ELEM;
2427  }
2428 }
2429 
2430 
2431 
2433  const bool full_ordered)
2434 {
2435  switch (et)
2436  {
2437  case NODEELEM:
2438  return NODEELEM;
2439  case EDGE2:
2440  case EDGE3:
2441  {
2442  // full_ordered not relevant
2443  return EDGE3;
2444  }
2445 
2446  case EDGE4:
2447  {
2448  // full_ordered not relevant
2449  return EDGE4;
2450  }
2451 
2452  case TRI3:
2453  case TRI6:
2454  {
2455  // full_ordered not relevant
2456  return TRI6;
2457  }
2458 
2459  // Currently there is no TRISHELL6, so similarly to other types
2460  // where this is the case, we just return the input.
2461  case TRISHELL3:
2462  return TRISHELL3;
2463 
2464  case QUAD4:
2465  case QUAD8:
2466  {
2467  if (full_ordered)
2468  return QUAD9;
2469  else
2470  return QUAD8;
2471  }
2472 
2473  case QUADSHELL4:
2474  case QUADSHELL8:
2475  {
2476  // There is no QUADSHELL9, so in that sense QUADSHELL8 is the
2477  // "full ordered" element.
2478  return QUADSHELL8;
2479  }
2480 
2481  case QUAD9:
2482  {
2483  // full_ordered not relevant
2484  return QUAD9;
2485  }
2486 
2487  case TET4:
2488  case TET10:
2489  {
2490  // full_ordered not relevant
2491  return TET10;
2492  }
2493 
2494  case HEX8:
2495  case HEX20:
2496  {
2497  // see below how this correlates with INFHEX8
2498  if (full_ordered)
2499  return HEX27;
2500  else
2501  return HEX20;
2502  }
2503 
2504  case HEX27:
2505  {
2506  // full_ordered not relevant
2507  return HEX27;
2508  }
2509 
2510  case PRISM6:
2511  case PRISM15:
2512  {
2513  if (full_ordered)
2514  return PRISM18;
2515  else
2516  return PRISM15;
2517  }
2518 
2519  case PRISM18:
2520  {
2521  // full_ordered not relevant
2522  return PRISM18;
2523  }
2524 
2525  case PYRAMID5:
2526  case PYRAMID13:
2527  {
2528  if (full_ordered)
2529  return PYRAMID14;
2530  else
2531  return PYRAMID13;
2532  }
2533 
2534  case PYRAMID14:
2535  {
2536  // full_ordered not relevant
2537  return PYRAMID14;
2538  }
2539 
2540 
2541 
2542 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2543 
2544  // infinite elements
2545  case INFEDGE2:
2546  {
2547  return INFEDGE2;
2548  }
2549 
2550  case INFQUAD4:
2551  case INFQUAD6:
2552  {
2553  // full_ordered not relevant
2554  return INFQUAD6;
2555  }
2556 
2557  case INFHEX8:
2558  case INFHEX16:
2559  {
2560  /*
2561  * Note that this matches with \p Hex8:
2562  * For full-ordered, \p InfHex18 and \p Hex27
2563  * belong together, and for not full-ordered,
2564  * \p InfHex16 and \p Hex20 belong together.
2565  */
2566  if (full_ordered)
2567  return INFHEX18;
2568  else
2569  return INFHEX16;
2570  }
2571 
2572  case INFHEX18:
2573  {
2574  // full_ordered not relevant
2575  return INFHEX18;
2576  }
2577 
2578  case INFPRISM6:
2579  case INFPRISM12:
2580  {
2581  // full_ordered not relevant
2582  return INFPRISM12;
2583  }
2584 
2585 #endif
2586 
2587 
2588  default:
2589  {
2590  // what did we miss?
2591  libmesh_error_msg("No second order equivalent element type for et = "
2592  << Utility::enum_to_string(et));
2593  }
2594  }
2595 }
2596 
2597 
2598 
2600 {
2602  return side_iterator(this->_first_side(), this->_last_side(), bsp);
2603 }
2604 
2605 
2606 
2607 
2609 {
2611  return side_iterator(this->_last_side(), this->_last_side(), bsp);
2612 }
2613 
2614 
2615 
2616 
2618 {
2619  // The default implementation builds a finite element of the correct
2620  // order and sums up the JxW contributions. This can be expensive,
2621  // so the various element types can overload this method and compute
2622  // the volume more efficiently.
2623  const FEFamily mapping_family = FEMap::map_fe_type(*this);
2624  const FEType fe_type(this->default_order(), mapping_family);
2625 
2626  std::unique_ptr<FEBase> fe (FEBase::build(this->dim(),
2627  fe_type));
2628 
2629  const std::vector<Real> & JxW = fe->get_JxW();
2630 
2631  // The default quadrature rule should integrate the mass matrix,
2632  // thus it should be plenty to compute the area
2633  QGauss qrule (this->dim(), fe_type.default_quadrature_order());
2634 
2635  fe->attach_quadrature_rule(&qrule);
2636 
2637  fe->reinit(this);
2638 
2639  Real vol=0.;
2640  for (auto jxw : JxW)
2641  vol += jxw;
2642 
2643  return vol;
2644 
2645 }
2646 
2647 
2648 
2650 {
2651  Point pmin = this->point(0);
2652  Point pmax = pmin;
2653 
2654  unsigned int n_points = this->n_nodes();
2655  for (unsigned int p=0; p != n_points; ++p)
2656  for (unsigned d=0; d<LIBMESH_DIM; ++d)
2657  {
2658  const Point & pt = this->point(p);
2659  if (pmin(d) > pt(d))
2660  pmin(d) = pt(d);
2661 
2662  if (pmax(d) < pt(d))
2663  pmax(d) = pt(d);
2664  }
2665 
2666  return BoundingBox(pmin, pmax);
2667 }
2668 
2669 
2670 
2671 bool Elem::is_vertex_on_parent(unsigned int c,
2672  unsigned int n) const
2673 {
2674 #ifdef LIBMESH_ENABLE_AMR
2675 
2676  unsigned int my_n_vertices = this->n_vertices();
2677  for (unsigned int n_parent = 0; n_parent != my_n_vertices;
2678  ++n_parent)
2679  if (this->node_ptr(n_parent) == this->child_ptr(c)->node_ptr(n))
2680  return true;
2681  return false;
2682 
2683 #else
2684 
2685  // No AMR?
2686  libmesh_ignore(c,n);
2687  libmesh_error_msg("ERROR: AMR disabled, how did we get here?");
2688  return true;
2689 
2690 #endif
2691 }
2692 
2693 
2694 
2695 unsigned int Elem::opposite_side(const unsigned int /*s*/) const
2696 {
2697  // If the subclass didn't rederive this, using it is an error
2698  libmesh_not_implemented();
2699 }
2700 
2701 
2702 
2703 unsigned int Elem::opposite_node(const unsigned int /*n*/,
2704  const unsigned int /*s*/) const
2705 {
2706  // If the subclass didn't rederive this, using it is an error
2707  libmesh_not_implemented();
2708 }
2709 
2710 } // namespace libMesh
libMesh::ElemInternal::find_interior_neighbors
void find_interior_neighbors(T this_elem, std::set< T > &neighbor_set)
Definition: elem_internal.h:472
libMesh::HEX20
Definition: enum_elem_type.h:48
libMesh::DofObject::valid_id
bool valid_id() const
Definition: dof_object.h:809
libMesh::Elem::active_family_tree_by_side
void active_family_tree_by_side(std::vector< const Elem * > &family, unsigned int side, bool reset=true) const
Same as the active_family_tree() member, but only adds elements which are next to side.
Definition: elem.C:1507
libMesh::Elem::find_point_neighbors
void find_point_neighbors(const Point &p, std::set< const Elem * > &neighbor_set) const
This function finds all active elements (including this one) which are in the same manifold as this e...
Definition: elem.C:560
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::Elem::nullify_neighbors
void nullify_neighbors()
Replaces this element with nullptr for all of its neighbors.
Definition: elem.C:2317
libMesh::ElemInternal::family_tree
void family_tree(T elem, std::vector< T > &family, bool reset=true)
Definition: elem_internal.h:41
libMesh::PRISM6
Definition: enum_elem_type.h:50
libMesh::Elem::child_ptr
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:2567
libMesh::Elem::bracketing_nodes
virtual const std::vector< std::pair< dof_id_type, dof_id_type > > bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:1999
libMesh::Elem::is_node_on_side
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
libMesh::Elem::is_vertex_on_child
virtual unsigned int is_vertex_on_child(unsigned int, unsigned int n) const
Definition: elem.h:681
libMesh::Elem::_last_side
SideIter _last_side()
Definition: elem.h:2892
libMesh::PeriodicBoundaries
We're using a class instead of a typedef to allow forward declarations and future flexibility.
Definition: periodic_boundaries.h:51
libMesh::Elem::n_edges
virtual unsigned int n_edges() const =0
libMesh::invalid_uint
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value.
Definition: libmesh.h:249
libMesh::Elem::n_second_order_adjacent_vertices
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int n) const
Definition: elem.C:2343
libMesh::FEInterface::on_reference_element
static bool on_reference_element(const Point &p, const ElemType t, const Real eps=TOLERANCE)
Definition: fe_interface.C:677
libMesh::Elem::replace_child
void replace_child(Elem *elem, unsigned int c)
Replaces the child pointer at the specified index in the child array.
Definition: elem.C:1430
libMesh::Elem::total_family_tree
void total_family_tree(std::vector< const Elem * > &family, bool reset=true) const
Same as the family_tree() member, but also adds any subactive descendants.
Definition: elem.C:1457
libMesh::DofObject::n_systems
unsigned int n_systems() const
Definition: dof_object.h:861
libMesh::Elem::JUST_REFINED
Definition: elem.h:1172
libMesh::Elem::set_interior_parent
void set_interior_parent(Elem *p)
Sets the pointer to the element's interior_parent.
Definition: elem.C:801
libMesh::Elem::contains_edge_of
bool contains_edge_of(const Elem *e) const
Definition: elem.C:539
libMesh::QGauss
This class implements specific orders of Gauss quadrature.
Definition: quadrature_gauss.h:39
libMesh::Elem::close_to_point
virtual bool close_to_point(const Point &p, Real tol) const
Definition: elem.C:2119
libMesh::Elem::find_edge_neighbors
void find_edge_neighbors(const Point &p1, const Point &p2, std::set< const Elem * > &neighbor_set) const
This function finds all active elements in the same manifold as this element which touch the current ...
Definition: elem.C:646
libMesh::ElemInternal::family_tree_by_neighbor
void family_tree_by_neighbor(T elem, std::vector< T > &family, T neighbor_in, bool reset=true)
Definition: elem_internal.h:182
libMesh::Elem::level
unsigned int level() const
Definition: elem.h:2478
libMesh::Elem::child_ref_range
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:1839
libMesh::Elem::_first_side
SideIter _first_side()
Side iterator helper functions.
Definition: elem.h:2884
libMesh::Elem::n_nodes
virtual unsigned int n_nodes() const =0
libMesh::HEX8
Definition: enum_elem_type.h:47
libMesh::Elem::embedding_matrix
virtual float embedding_matrix(const unsigned int child_num, const unsigned int child_node_num, const unsigned int parent_node_num) const =0
libMesh::Elem::contains_point
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition: elem.C:2094
libMesh::EDGE4
Definition: enum_elem_type.h:37
libMesh::INFHEX8
Definition: enum_elem_type.h:60
libMesh::Elem::is_semilocal
bool is_semilocal(const processor_id_type my_pid) const
Definition: elem.C:460
libMesh::IOPackage
IOPackage
libMesh interfaces with several different software packages for the purposes of creating,...
Definition: enum_io_package.h:37
libMesh::INFQUAD4
Definition: enum_elem_type.h:58
libMesh::Elem::parent_bracketing_nodes
virtual const std::vector< std::pair< unsigned char, unsigned char > > & parent_bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:1794
libMesh::Elem::COARSEN
Definition: elem.h:1169
libMesh::Elem::n_neighbors
unsigned int n_neighbors() const
Definition: elem.h:631
libMesh::BoundingBox
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
libMesh::Elem::ancestor
bool ancestor() const
Definition: elem.C:1350
libMesh::Elem::_children
Elem ** _children
Pointers to this element's children.
Definition: elem.h:1755
libMesh::TypeVector::add
void add(const TypeVector< T2 > &)
Add to this vector without creating a temporary.
Definition: type_vector.h:641
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::Elem::dim
virtual unsigned short dim() const =0
libMesh::Elem::which_side_am_i
unsigned int which_side_am_i(const Elem *e) const
This function tells you which side the boundary element e is.
Definition: elem.C:475
libMesh::TET10
Definition: enum_elem_type.h:46
libMesh::Elem::add_child
void add_child(Elem *elem)
Adds a child pointer to the array of children of this element.
Definition: elem.C:1384
libMesh::INVALID_IO_PACKAGE
Definition: enum_io_package.h:48
libMesh::ElemInternal::active_family_tree_by_side
void active_family_tree_by_side(T elem, std::vector< T > &family, unsigned int side, bool reset=true)
Definition: elem_internal.h:149
libMesh::Elem::infinite
virtual bool infinite() const =0
end
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end.
Definition: variant_filter_iterator.h:343
libMesh::Elem::min_new_p_level_by_neighbor
unsigned int min_new_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition: elem.C:1692
std::sqrt
MetaPhysicL::DualNumber< T, D > sqrt(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::TOLERANCE
static const Real TOLERANCE
Definition: libmesh_common.h:128
libMesh::Elem::set_neighbor
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
Definition: elem.h:2105
libMesh::Elem::find_interior_neighbors
void find_interior_neighbors(std::set< const Elem * > &neighbor_set) const
This function finds all active elements (not including this one) in the parent manifold of this eleme...
Definition: elem.C:735
libMesh::Elem::contains_vertex_of
bool contains_vertex_of(const Elem *e) const
Definition: elem.C:528
libMesh::Elem::p_level
unsigned int p_level() const
Definition: elem.h:2512
libMesh::Elem::neighbor_ptr_range
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Returns a range with all neighbors of an element, usable in range-based for loops.
Definition: elem.h:2917
libMesh::Elem::second_order_child_vertex
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const
Definition: elem.C:2361
libMesh::Elem::node_index_range
IntRange< unsigned short > node_index_range() const
Definition: elem.h:2170
libMesh::FEMap::map
static Point map(const unsigned int dim, const Elem *elem, const Point &reference_point)
Definition: fe_map.C:2043
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::Elem::print_info
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the element.
Definition: elem.C:2225
libMesh::DofObject::valid_unique_id
bool valid_unique_id() const
Definition: dof_object.h:817
libMesh::Elem::is_remote
virtual bool is_remote() const
Definition: elem.h:542
libMesh::DofObject::processor_id
processor_id_type processor_id() const
Definition: dof_object.h:829
libMesh::INFEDGE2
Definition: enum_elem_type.h:57
libMesh::Elem::is_child_on_edge
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
Definition: elem.C:1646
libMesh::Elem::active
bool active() const
Definition: elem.h:2345
libMesh::Elem::_nodes
Node ** _nodes
Pointers to the nodes we are connected to.
Definition: elem.h:1743
libMesh::ElemInternal::total_family_tree_by_neighbor
void total_family_tree_by_neighbor(T elem, std::vector< T > &family, T neighbor_in, bool reset=true)
Definition: elem_internal.h:211
libMesh::Elem::family_tree_by_side
void family_tree_by_side(std::vector< const Elem * > &family, unsigned int side, bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to side.
Definition: elem.C:1489
libMesh::Elem::length
Real length(const unsigned int n1, const unsigned int n2) const
Definition: elem.C:399
libMesh::Elem::is_vertex_on_parent
virtual bool is_vertex_on_parent(unsigned int c, unsigned int n) const
Definition: elem.C:2671
libMesh::Elem::point
const Point & point(const unsigned int i) const
Definition: elem.h:1955
libMesh::Elem::centroid
virtual Point centroid() const
Definition: elem.C:345
libMesh::Elem::boundary_sides_end
side_iterator boundary_sides_end()
Definition: elem.C:2608
libMesh::Elem::opposite_side
virtual unsigned int opposite_side(const unsigned int s) const
Definition: elem.C:2695
libMesh::TET4
Definition: enum_elem_type.h:45
libMesh::PeriodicBoundaries::boundary
PeriodicBoundaryBase * boundary(boundary_id_type id)
Definition: periodic_boundaries.C:40
libMesh::Elem::invalid_subdomain_id
static const subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
Definition: elem.h:244
libMesh::Elem::make_links_to_me_remote
void make_links_to_me_remote()
Resets this element's neighbors' appropriate neighbor pointers and its parent's and children's approp...
Definition: elem.C:1085
libMesh::parent_indices_mutex
Threads::spin_mutex parent_indices_mutex
Definition: elem.C:86
libMesh::PRISM15
Definition: enum_elem_type.h:51
libMesh::Elem::has_neighbor
bool has_neighbor(const Elem *elem) const
Definition: elem.h:2115
libMesh::Elem::second_order_adjacent_vertex
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const
Definition: elem.C:2351
libMesh::ElemInternal::find_point_neighbors
void find_point_neighbors(T this_elem, std::set< T > &neighbor_set, T start_elem)
Definition: elem_internal.h:400
libMesh::Elem::family_tree_by_subneighbor
void family_tree_by_subneighbor(std::vector< const Elem * > &family, const Elem *neighbor, const Elem *subneighbor, bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to subneighbor.
Definition: elem.C:1561
libMesh::DofObject::dof_number
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:956
libMesh::INFPRISM6
Definition: enum_elem_type.h:63
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::Elem::connectivity
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const =0
libMesh::Elem::is_mid_infinite_edge_node
virtual bool is_mid_infinite_edge_node(const unsigned int) const
Definition: elem.h:1584
libMesh::IntRange
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
libMesh::Elem::libmesh_assert_valid_node_pointers
void libmesh_assert_valid_node_pointers() const
Checks for a valid id and pointers to nodes with valid ids on this element.
Definition: elem.C:923
libMesh::Elem::subactive
bool subactive() const
Definition: elem.h:2363
libMesh::MeshBase
This is the MeshBase class.
Definition: mesh_base.h:78
libMesh::HEX27
Definition: enum_elem_type.h:49
libMesh::Elem::node_ref_range
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
Definition: elem.h:2152
libMesh::FEMap::inverse_map
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
Definition: fe_map.C:1622
libMesh::Elem::active_family_tree_by_topological_neighbor
void active_family_tree_by_topological_neighbor(std::vector< const Elem * > &family, const Elem *neighbor, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb, bool reset=true) const
Same as the active_family_tree_by_neighbor() member, but the neighbor here may be a topological (e....
Definition: elem.C:1619
libMesh::Elem::p_refinement_flag
RefinementState p_refinement_flag() const
Definition: elem.h:2630
libMesh::Elem::volume
virtual Real volume() const
Definition: elem.C:2617
libMesh::DofObject::n_comp
unsigned int n_comp(const unsigned int s, const unsigned int var) const
Definition: dof_object.h:926
libMesh::Elem::type_to_n_edges_map
static const unsigned int type_to_n_edges_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of edges on the element...
Definition: elem.h:656
libMesh::Elem::first_order_equivalent_type
static ElemType first_order_equivalent_type(const ElemType et)
Definition: elem.C:2369
libMesh::libmesh_ignore
void libmesh_ignore(const Args &...)
Definition: libmesh_common.h:526
libMesh::FEGenericBase::build
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
libMesh::DofObject::invalid_id
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:421
libMesh::INFHEX18
Definition: enum_elem_type.h:62
libMesh::Elem::write_connectivity
void write_connectivity(std::ostream &out, const IOPackage iop) const
Writes the element connectivity for various IO packages to the passed ostream "out".
Definition: elem.C:1283
libMesh::QUAD4
Definition: enum_elem_type.h:41
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::Elem::type_to_n_sides_map
static const unsigned int type_to_n_sides_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of sides on the element...
Definition: elem.h:607
libMesh::Predicates::BoundarySide
Used to iterate over the sides of an element which are on the boundary of the Mesh.
Definition: multi_predicates.h:617
libMesh::Elem::key
virtual dof_id_type key() const
Definition: elem.C:410
libMesh::processor_id_type
uint8_t processor_id_type
Definition: id_types.h:104
libMesh::TRI3
Definition: enum_elem_type.h:39
libMesh::TypeVector::add_scaled
void add_scaled(const TypeVector< T2 > &, const T &)
Add a scaled value to this vector without creating a temporary.
Definition: type_vector.h:665
libMesh::Elem::operator==
bool operator==(const Elem &rhs) const
Definition: elem.C:428
libMesh::Elem::total_family_tree_by_neighbor
void total_family_tree_by_neighbor(std::vector< const Elem * > &family, const Elem *neighbor, bool reset=true) const
Same as the family_tree_by_neighbor() member, but also adds any subactive descendants.
Definition: elem.C:1543
libMesh::Elem::n_vertices
virtual unsigned int n_vertices() const =0
libMesh::Elem::side_iterator
The definition of the struct used for iterating over sides.
Definition: elem.h:2903
libMesh::Elem::default_order
virtual Order default_order() const =0
libMesh::Elem::quality
virtual Real quality(const ElemQuality q) const
Definition: elem.C:1326
libMesh::FEMap::map_fe_type
static FEFamily map_fe_type(const Elem &elem)
Definition: fe_map.C:47
libMesh::Elem::REFINE
Definition: elem.h:1171
libMesh::INFHEX16
Definition: enum_elem_type.h:61
libMesh::Elem::n_nodes_in_child
virtual unsigned int n_nodes_in_child(unsigned int) const
Definition: elem.h:600
libMesh::DofObject::unique_id
unique_id_type unique_id() const
Definition: dof_object.h:784
libMesh::ElemInternal::total_family_tree_by_subneighbor
void total_family_tree_by_subneighbor(T elem, std::vector< T > &family, T neighbor_in, T subneighbor, bool reset=true)
Definition: elem_internal.h:280
libMesh::Utility::enum_to_string
std::string enum_to_string(const T e)
libMesh::ElemInternal::active_family_tree_by_neighbor
void active_family_tree_by_neighbor(T elem, std::vector< T > &family, T neighbor_in, bool reset=true)
Definition: elem_internal.h:320
libMesh::Elem::loose_bounding_box
virtual BoundingBox loose_bounding_box() const
Definition: elem.C:2649
libMesh::ElemInternal::active_family_tree
void active_family_tree(T elem, std::vector< T > &active_family, bool reset=true)
Definition: elem_internal.h:90
libMesh::DofObject::n_vars
unsigned int n_vars(const unsigned int s, const unsigned int vg) const
Definition: dof_object.h:891
libMesh::ElemInternal::total_family_tree
void total_family_tree(T elem, std::vector< T > &family, bool reset)
Definition: elem_internal.h:67
libMesh::Elem::set_child
void set_child(unsigned int c, Elem *elem)
Sets the pointer to the child for this element.
Definition: elem.h:2586
libMesh::Elem::as_parent_node
virtual unsigned int as_parent_node(unsigned int c, unsigned int n) const
Definition: elem.C:1726
libMesh::INFPRISM12
Definition: enum_elem_type.h:64
libMesh::Elem::family_tree
void family_tree(std::vector< const Elem * > &family, bool reset=true) const
Fills the vector family with the children of this element, recursively.
Definition: elem.C:1441
libMesh::Elem::make_links_to_me_local
void make_links_to_me_local(unsigned int n, unsigned int neighbor_side)
Resets the neighbor_side pointers of our nth neighbor (and its descendants, if appropriate) to point ...
Definition: elem.C:1007
libMesh::ElemQuality
ElemQuality
Defines an enum for element quality metrics.
Definition: enum_elem_quality.h:34
libMesh::Elem::parent
const Elem * parent() const
Definition: elem.h:2434
libMesh::Elem::boundary_sides_begin
side_iterator boundary_sides_begin()
Iterator accessor functions.
Definition: elem.C:2599
libMesh::TRI6
Definition: enum_elem_type.h:40
libMesh::Elem::refinement_flag
RefinementState refinement_flag() const
Definition: elem.h:2614
libMesh::INVALID_ELEM
Definition: enum_elem_type.h:75
libMesh::Elem::interior_parent
const Elem * interior_parent() const
Definition: elem.C:749
libMesh::Utility::hashword
uint32_t hashword(const uint32_t *k, size_t length, uint32_t initval=0)
The hashword function takes an array of uint32_t's of length 'length' and computes a single key from ...
Definition: hashword.h:153
libMesh::Elem::family_tree_by_neighbor
void family_tree_by_neighbor(std::vector< const Elem * > &family, const Elem *neighbor, bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to neighbor.
Definition: elem.C:1525
libMesh::Elem::remove_links_to_me
void remove_links_to_me()
Resets this element's neighbors' appropriate neighbor pointers and its parent's and children's approp...
Definition: elem.C:1191
libMesh::ReferenceElem::get
const Elem & get(const ElemType type_in)
Definition: reference_elem.C:237
libMesh::FEType
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:178
libMesh::parent_bracketing_nodes_mutex
Threads::spin_mutex parent_bracketing_nodes_mutex
Definition: elem.C:87
libMesh::Elem::type_to_n_nodes_map
static const unsigned int type_to_n_nodes_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of nodes in the element...
Definition: elem.h:576
libMesh::Elem::hmax
virtual Real hmax() const
Definition: elem.C:379
libMesh::Elem::n_children
virtual unsigned int n_children() const =0
libMesh::Elem::opposite_node
virtual unsigned int opposite_node(const unsigned int n, const unsigned int s) const
Definition: elem.C:2703
libMesh::PeriodicBoundaries::neighbor
const Elem * neighbor(boundary_id_type boundary_id, const PointLocatorBase &point_locator, const Elem *e, unsigned int side) const
Definition: periodic_boundaries.C:61
libMesh::Elem::topological_neighbor
const Elem * topological_neighbor(const unsigned int i, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:865
libMesh::FEFamily
FEFamily
Definition: enum_fe_family.h:34
libMesh::INFQUAD6
Definition: enum_elem_type.h:59
libMesh::QUADSHELL8
Definition: enum_elem_type.h:73
libMesh::Elem::reference_elem
const Elem * reference_elem() const
Definition: elem.C:338
libMesh::PYRAMID5
Definition: enum_elem_type.h:53
libMesh::Elem::hmin
virtual Real hmin() const
Definition: elem.C:359
libMesh::Elem::total_family_tree_by_subneighbor
void total_family_tree_by_subneighbor(std::vector< const Elem * > &family, const Elem *neighbor, const Elem *subneighbor, bool reset=true) const
Same as the family_tree_by_subneighbor() member, but also adds any subactive descendants.
Definition: elem.C:1581
libMesh::DofObject::id
dof_id_type id() const
Definition: dof_object.h:767
libMesh::Elem::active_family_tree
void active_family_tree(std::vector< const Elem * > &active_family, bool reset=true) const
Same as the family_tree() member, but only adds the active children.
Definition: elem.C:1473
libMesh::Elem::max_n_nodes
static const unsigned int max_n_nodes
The maximum number of nodes any element can contain.
Definition: elem.h:587
libMesh::EDGE3
Definition: enum_elem_type.h:36
libMesh::Elem::has_children
bool has_children() const
Definition: elem.h:2383
libMesh::QUADSHELL4
Definition: enum_elem_type.h:72
libMesh::Elem::side_index_range
IntRange< unsigned short > side_index_range() const
Definition: elem.h:2188
libMesh::Elem::embedding_matrix_version
virtual unsigned int embedding_matrix_version() const
Definition: elem.h:1649
libMesh::Elem::min_p_level_by_neighbor
unsigned int min_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition: elem.C:1663
libMesh::Elem::master_point
virtual Point master_point(const unsigned int i) const =0
libMesh::Elem::get_info
std::string get_info() const
Prints relevant information about the element to a string.
Definition: elem.C:2233
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::Elem::second_order_equivalent_type
static ElemType second_order_equivalent_type(const ElemType et, const bool full_ordered=true)
Definition: elem.C:2432
std::norm
MetaPhysicL::DualNumber< T, D > norm(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::NODEELEM
Definition: enum_elem_type.h:66
libMesh::Elem::libmesh_assert_valid_neighbors
void libmesh_assert_valid_neighbors() const
Checks for consistent neighbor links on this element.
Definition: elem.C:935
libMesh::QUAD9
Definition: enum_elem_type.h:43
libMesh::Elem::origin
virtual Point origin() const
Definition: elem.h:1593
libMesh::err
OStreamProxy err
libMesh::Elem::neighbor_ptr
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2085
libMesh::TestClass
Definition: id_types.h:33
libMesh::Elem::node_id
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1977
libMesh::Elem::node_ref
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2031
libMesh::TRI3SUBDIVISION
Definition: enum_elem_type.h:69
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::FEType::default_quadrature_order
Order default_quadrature_order() const
Definition: fe_type.h:353
libMesh::Elem::_elemlinks
Elem ** _elemlinks
Pointers to this element's parent and neighbors, and for lower-dimensional elements' interior_parent.
Definition: elem.h:1749
libMesh::Elem::active_family_tree_by_neighbor
void active_family_tree_by_neighbor(std::vector< const Elem * > &family, const Elem *neighbor, bool reset=true) const
Same as the active_family_tree() member, but only adds elements which are next to neighbor.
Definition: elem.C:1601
libMesh::ElemInternal::family_tree_by_subneighbor
void family_tree_by_subneighbor(T elem, std::vector< T > &family, T neighbor_in, T subneighbor, bool reset=true)
Definition: elem_internal.h:237
libMesh::Elem::n_sides
virtual unsigned int n_sides() const =0
libMesh::PRISM18
Definition: enum_elem_type.h:52
libMesh::Elem::_get_parent_indices_cache
virtual std::vector< std::vector< std::vector< signed char > > > & _get_parent_indices_cache() const
Elem subclasses which don't do their own child-to-parent node calculations will need to supply a stat...
Definition: elem.h:1721
libMesh::TRISHELL3
Definition: enum_elem_type.h:71
libMesh::Elem::n_sub_elem
virtual unsigned int n_sub_elem() const =0
libMesh::Elem::build
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition: elem.C:246
libMesh::Elem::build_edge_ptr
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
libMesh::Elem::node_ptr
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2009
libMesh::PointLocatorBase
This is the base class for point locators.
Definition: point_locator_base.h:62
libMesh::UCD
Definition: enum_io_package.h:45
libMesh::Elem::type
virtual ElemType type() const =0
libMesh::FIRST
Definition: enum_order.h:42
libMesh::Elem::which_neighbor_am_i
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
Definition: elem.h:2323
libMesh::Elem::has_topological_neighbor
bool has_topological_neighbor(const Elem *elem, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:902
libMesh::remote_elem
const RemoteElem * remote_elem
Definition: remote_elem.C:57
libMesh::ElemInternal::family_tree_by_side
void family_tree_by_side(T elem, std::vector< T > &family, unsigned int s, bool reset)
Definition: elem_internal.h:117
libMesh::Threads::spin_mutex
Spin mutex.
Definition: threads_none.h:127
libMesh::TECPLOT
Definition: enum_io_package.h:39
libMesh::Elem::which_child_am_i
unsigned int which_child_am_i(const Elem *e) const
Definition: elem.h:2596
libMesh::PYRAMID13
Definition: enum_elem_type.h:54
libMesh::Elem::_get_bracketing_node_cache
virtual std::vector< std::vector< std::vector< std::vector< std::pair< unsigned char, unsigned char > > > > > & _get_bracketing_node_cache() const
Elem subclasses which don't do their own bracketing node calculations will need to supply a static ca...
Definition: elem.h:1707
libMesh::PYRAMID14
Definition: enum_elem_type.h:55
libMesh::EDGE2
Definition: enum_elem_type.h:35
libMesh::ElemInternal::active_family_tree_by_topological_neighbor
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)
Definition: elem_internal.h:356
libMesh::QUAD8
Definition: enum_elem_type.h:42
libMesh::ElemType
ElemType
Defines an enum for geometric element types.
Definition: enum_elem_type.h:33
libMesh::Elem::point_test
bool point_test(const Point &p, Real box_tol, Real map_tol) const
Shared private implementation used by the contains_point() and close_to_point() routines.
Definition: elem.C:2131
libMesh::TypeVector::absolute_fuzzy_equals
bool absolute_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
Definition: type_vector.h:1017