LCOV - code coverage report
Current view: top level - include/geom - elem.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4343 (6ea38c) with base 8c3130 Lines: 355 436 81.4 %
Date: 2026-10-13 21:47:33 Functions: 143 182 78.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2026 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             : #ifndef LIBMESH_ELEM_H
      21             : #define LIBMESH_ELEM_H
      22             : 
      23             : // Local includes
      24             : #include "libmesh/libmesh_common.h"
      25             : #include "libmesh/bounding_box.h"
      26             : #include "libmesh/dof_object.h"
      27             : #include "libmesh/id_types.h"
      28             : #include "libmesh/reference_counted_object.h"
      29             : #include "libmesh/node.h"
      30             : #include "libmesh/enum_elem_type.h" // INVALID_ELEM
      31             : #include "libmesh/multi_predicates.h"
      32             : #include "libmesh/pointer_to_pointer_iter.h"
      33             : #include "libmesh/int_range.h"
      34             : #include "libmesh/simple_range.h"
      35             : #include "libmesh/variant_filter_iterator.h"
      36             : #include "libmesh/hashword.h" // Used in compute_key() functions
      37             : 
      38             : // C++ includes
      39             : #include <algorithm>
      40             : #include <cstddef>
      41             : #include <iostream>
      42             : #include <limits.h> // CHAR_BIT
      43             : #include <set>
      44             : #include <vector>
      45             : #include <memory>
      46             : #include <array>
      47             : 
      48             : namespace libMesh
      49             : {
      50             : 
      51             : // Forward declarations
      52             : class BoundaryInfo;
      53             : class Elem;
      54             : class MeshBase;
      55             : class MeshRefinement;
      56             : #ifdef LIBMESH_ENABLE_PERIODIC
      57             : class PeriodicBoundaries;
      58             : class PointLocatorBase;
      59             : #endif
      60             : template <class SideType, class ParentType>
      61             : class Side;
      62             : enum ElemQuality : int;
      63             : enum IOPackage : int;
      64             : enum Order : int;
      65             : 
      66             : 
      67             : /**
      68             :  * This is the base class from which all geometric element types are
      69             :  * derived.  The \p Elem class provides standard information such as
      70             :  * the number of nodes, edges, faces, vertices, children, and
      71             :  * neighbors it has, as well as access to (or the ability to
      72             :  * construct) these entities.
      73             :  *
      74             :  * An \p Elem has pointers to its \p Node objects.  Some of these
      75             :  * nodes live at the vertices of the element, while others may live on
      76             :  * edges (and faces in 3D), or interior to the element.  The number of
      77             :  * nodes in a given element, \p n_nodes(), is encoded into the name of
      78             :  * the class.  For example, a \p Tri3 has three nodes which correspond
      79             :  * to the vertices, while a \p Tri6 has six nodes, three of which are
      80             :  * located at vertices, and three which are located at the midpoint of
      81             :  * each edge.  Nodes on edges, faces, and element interiors are called
      82             :  * second-order nodes.
      83             :  *
      84             :  * A 1D Elem is an \p Edge, a 2D Elem is a \p Face, and a 3D Elem is a
      85             :  * \p Cell.  An \p Elem is composed of a number of sides, which can
      86             :  * be accessed as dim-1 dimensional \p Elem types.  For example, a \p
      87             :  * Hex8 is a 3D hexahedral element. A \p Hex8 has 6 sides, which are
      88             :  * \p Faces of type Quad4.
      89             :  *
      90             :  * \author Benjamin S. Kirk
      91             :  * \date 2002-2007
      92             :  * \brief The base class for all geometric element types.
      93             :  */
      94             : class Elem : public ReferenceCountedObject<Elem>,
      95             :              public DofObject
      96             : {
      97             : protected:
      98             : 
      99             :   /**
     100             :    * Constructor.  Creates an element with \p n_nodes nodes,
     101             :    * \p n_sides sides, \p n_children possible children, and
     102             :    * parent \p p.  The constructor allocates the memory necessary
     103             :    * to support this data.
     104             :    */
     105             :   Elem (const unsigned int n_nodes,
     106             :         const unsigned int n_sides,
     107             :         Elem * parent,
     108             :         Elem ** elemlinkdata,
     109             :         Node ** nodelinkdata);
     110             : 
     111             : public:
     112             : 
     113             :   /**
     114             :    * Elems are responsible for allocating and deleting space for
     115             :    * storing pointers to their children during refinement, so they
     116             :    * cannot currently be (default) copy-constructed or copy-
     117             :    * assigned. We therefore explicitly delete these operations. In
     118             :    * addition, the DofObject base class currently has private copy
     119             :    * construction and assignment operators, so that prevents us from
     120             :    * copying Elems as well.
     121             :    */
     122             :   Elem (Elem &&) = delete;
     123             :   Elem (const Elem &) = delete;
     124             :   Elem & operator= (const Elem &) = delete;
     125             :   Elem & operator= (Elem &&) = delete;
     126             : 
     127             :   /**
     128             :    * Destructor.
     129             :    */
     130  3548088023 :   virtual ~Elem() = default;
     131             : 
     132             :   /**
     133             :    * \returns The \p Point associated with local \p Node \p i.
     134             :    */
     135             :   const Point & point (const unsigned int i) const;
     136             : 
     137             :   /**
     138             :    * \returns The \p Point associated with local \p Node \p i
     139             :    * as a writable reference.
     140             :    */
     141             :   Point & point (const unsigned int i);
     142             : 
     143             :   /**
     144             :    * \returns The \p Point associated with local \p Node \p i,
     145             :    * in master element rather than physical coordinates.
     146             :    */
     147             :   virtual Point master_point (const unsigned int i) const = 0;
     148             : 
     149             :   /**
     150             :    * \returns The global id number of local \p Node \p i.
     151             :    */
     152             :   dof_id_type node_id (const unsigned int i) const;
     153             : 
     154             :   /**
     155             :    * \returns The local id number of global \p Node id \p i,
     156             :    * or \p invalid_uint if Node id \p i is not local.
     157             :    */
     158             :   unsigned int local_node (const dof_id_type i) const;
     159             : 
     160             :   /**
     161             :    * \returns The local index for the \p Node pointer \p node_ptr,
     162             :    * or \p invalid_uint if \p node_ptr is not a local node.
     163             :    */
     164             :   unsigned int get_node_index (const Node * node_ptr) const;
     165             : 
     166             :   /**
     167             :    * \returns A pointer to an array of local node pointers.
     168             :    */
     169             :   const Node * const * get_nodes () const;
     170             : 
     171             :   /**
     172             :    * \returns A const pointer to local \p Node \p i.
     173             :    */
     174             :   const Node * node_ptr (const unsigned int i) const;
     175             : 
     176             :   /**
     177             :    * \returns A non-const pointer to local \p Node \p i.
     178             :    */
     179             :   Node * node_ptr (const unsigned int i);
     180             : 
     181             :   /**
     182             :    * \returns A const reference to local \p Node \p i.
     183             :    */
     184             :   const Node & node_ref (const unsigned int i) const;
     185             : 
     186             :   /**
     187             :    * \returns A writable reference to local \p Node \p i.
     188             :    */
     189             :   Node & node_ref (const unsigned int i);
     190             : 
     191             : #ifdef LIBMESH_ENABLE_DEPRECATED
     192             :   /**
     193             :    * \returns The pointer to the \p Node with local number \p i as a
     194             :    * writable reference.
     195             :    *
     196             :    * \deprecated This setter cannot update the multiple node pointers
     197             :    * used in a general polyhedron; use the \p set_node overload that
     198             :    * takes an argument.
     199             :    */
     200             :   virtual Node * & set_node (const unsigned int i);
     201             : #endif // LIBMESH_ENABLE_DEPRECATED
     202             : 
     203             :   /**
     204             :    * Sets local \p Node \p i to refer to \p node.
     205             :    */
     206             :   virtual void set_node (const unsigned int i,
     207             :                          Node * node);
     208             : 
     209             :   /**
     210             :    * Nested classes for use iterating over all nodes of an element.
     211             :    */
     212             :   class NodeRefIter;
     213             :   class ConstNodeRefIter;
     214             : 
     215             :   /**
     216             :    * Returns a range with all nodes of an element, usable in
     217             :    * range-based for loops.  The exact type of the return value here
     218             :    * may be subject to change in future libMesh releases, but the
     219             :    * iterators will always dereference to produce a reference to a
     220             :    * Node.
     221             :    */
     222             :   SimpleRange<NodeRefIter> node_ref_range();
     223             : 
     224             :   SimpleRange<ConstNodeRefIter> node_ref_range() const;
     225             : 
     226             :   /**
     227             :    * \returns The subdomain that this element belongs to.
     228             :    */
     229             :   subdomain_id_type subdomain_id () const;
     230             : 
     231             :   /**
     232             :    * \returns The subdomain that this element belongs to as a
     233             :    * writable reference.
     234             :    */
     235             :   subdomain_id_type & subdomain_id ();
     236             : 
     237             :   /**
     238             :    * A static integral constant representing an invalid subdomain id.
     239             :    * See also DofObject::{invalid_id, invalid_unique_id, invalid_processor_id}.
     240             :    *
     241             :    * \note We don't use the static_cast(-1) trick here since
     242             :    * \p subdomain_id_type is sometimes a *signed* integer for
     243             :    * compatibility reasons (see libmesh/id_types.h).
     244             :    */
     245             :   static constexpr subdomain_id_type invalid_subdomain_id
     246             :     = std::numeric_limits<subdomain_id_type>::max();
     247             : 
     248             :   /**
     249             :    * \returns true iff this element type can vary in topology (e.g.
     250             :    * have different numbers of sides and/or nodes) at runtime.  For
     251             :    * such general polygons or polyhedra, APIs which assume a fixed
     252             :    * topology are not safe to use.
     253             :    */
     254   293555941 :   virtual bool runtime_topology() const { return false; }
     255             : 
     256             :   /**
     257             :    * \returns A pointer to the "reference element" associated
     258             :    * with this element.  The reference element is the image of this
     259             :    * element in reference parametric space. Importantly, it is *not*
     260             :    * an actual element in the mesh, but rather a Singleton-type
     261             :    * object, so for example all \p Quad4 elements share the same
     262             :    * \p reference_elem().
     263             :    *
     264             :    * If the element is of a type that can admit multiple topologies,
     265             :    * such as a Polygon subtype, then there is no reference element;
     266             :    * for such types this method should not be used.
     267             :    */
     268             :   const Elem * reference_elem () const;
     269             : 
     270             :   /**
     271             :    * \returns An id associated with the \p s side of this element.
     272             :    * The id is not necessarily unique, but should be close.
     273             :    */
     274             :   virtual dof_id_type key (const unsigned int s) const = 0;
     275             : 
     276             :   /**
     277             :    * \returns An id associated with the \p s side of this element, as
     278             :    * defined solely by element vertices.  The id is not necessarily
     279             :    * unique, but should be close.  This is particularly useful in the
     280             :    * \p MeshBase::find_neighbors() routine.
     281             :    */
     282             :   virtual dof_id_type low_order_key (const unsigned int s) const = 0;
     283             : 
     284             :   /**
     285             :    * \returns An id associated with the global node ids of this
     286             :    * element.  The id is not necessarily unique, but should be
     287             :    * close. Uses the same hash as the key(s) function, so for example
     288             :    * if "tri3" is side 0 of "tet4", then tri3->key()==tet4->key(0).
     289             :    */
     290             :   virtual dof_id_type key () const;
     291             : 
     292             :   /**
     293             :    * \returns \p true if two elements are equivalent, \p false
     294             :    * otherwise.  This is true if the elements are connected to
     295             :    * identical global nodes, regardless of how those nodes might be
     296             :    * numbered local to the elements.
     297             :    */
     298             :   bool operator == (const Elem & rhs) const;
     299             : 
     300             :   /**
     301             :    * \returns \p false if two elements are equivalent, \p true
     302             :    * otherwise.
     303             :    */
     304             :   bool operator != (const Elem & rhs) const;
     305             : 
     306             :   /**
     307             :    * \returns \p true if two elements have equal topologies, false
     308             :    * otherwise.
     309             :    * This is true if the elements connect to nodes of the same id in
     310             :    * the same order, and neighbors of the same id on each side, the
     311             :    * same id on any parent and/or interior_parent link, etc.
     312             :    */
     313             :   bool topologically_equal (const Elem & rhs) const;
     314             : 
     315             :   /**
     316             :    * \returns A const pointer to the \f$ i^{th} \f$ neighbor of this
     317             :    * element, or \p nullptr if \p MeshBase::find_neighbors() has not been
     318             :    * called.
     319             :    *
     320             :    * \note If \p MeshBase::find_neighbors() has been called and this
     321             :    * function still returns \p nullptr, then the side is on a boundary of
     322             :    * the domain.
     323             :    */
     324             :   const Elem * neighbor_ptr (unsigned int i) const;
     325             : 
     326             :   /**
     327             :    * \returns A non-const pointer to the \f$ i^{th} \f$ neighbor of this element.
     328             :    */
     329             :   Elem * neighbor_ptr (unsigned int i);
     330             : 
     331             :   /**
     332             :    * Nested "classes" for use iterating over all neighbors of an element.
     333             :    */
     334             :   typedef Elem * const *       NeighborPtrIter;
     335             :   typedef const Elem * const * ConstNeighborPtrIter;
     336             : 
     337             :   /**
     338             :    * Returns a range with all neighbors of an element, usable in
     339             :    * range-based for loops.  The exact type of the return value here
     340             :    * may be subject to change in future libMesh releases, but the
     341             :    * iterators will always dereference to produce a pointer to a
     342             :    * neighbor element (or a null pointer, for sides which have no
     343             :    * neighbors).
     344             :    */
     345             :   SimpleRange<NeighborPtrIter> neighbor_ptr_range();
     346             : 
     347             :   SimpleRange<ConstNeighborPtrIter> neighbor_ptr_range() const;
     348             : 
     349             : #ifdef LIBMESH_ENABLE_PERIODIC
     350             :   /**
     351             :    * \returns A pointer to the \f$ i^{th} \f$ neighbor of this element
     352             :    * for interior elements.  If an element is on a periodic
     353             :    * boundary, it will return a corresponding element on the opposite
     354             :    * side.
     355             :    */
     356             :   const Elem * topological_neighbor (const unsigned int i,
     357             :                                      const MeshBase & mesh,
     358             :                                      const PointLocatorBase & point_locator,
     359             :                                      const PeriodicBoundaries * pb) const;
     360             : 
     361             :   /**
     362             :    * \returns A writable pointer to the \f$ i^{th} \f$ neighbor of
     363             :    * this element for interior elements.  If an element is on a
     364             :    * periodic boundary, it will return a corresponding element on the
     365             :    * opposite side.
     366             :    */
     367             :   Elem * topological_neighbor (const unsigned int i,
     368             :                                MeshBase & mesh,
     369             :                                const PointLocatorBase & point_locator,
     370             :                                const PeriodicBoundaries * pb);
     371             : 
     372             :   /**
     373             :    * \returns \p true if the element \p elem in question is a neighbor or
     374             :    * topological neighbor of this element, \p false otherwise.
     375             :    */
     376             :   bool has_topological_neighbor (const Elem * elem,
     377             :                                  const MeshBase & mesh,
     378             :                                  const PointLocatorBase & point_locator,
     379             :                                  const PeriodicBoundaries * pb) const;
     380             : #endif
     381             : 
     382             :   /**
     383             :    * Assigns \p n as the \f$ i^{th} \f$ neighbor.
     384             :    */
     385             :   void set_neighbor (const unsigned int i, Elem * n);
     386             : 
     387             :   /**
     388             :    * \returns \p true if the element \p elem in question is a neighbor
     389             :    * of this element, \p false otherwise.
     390             :    */
     391             :   bool has_neighbor (const Elem * elem) const;
     392             : 
     393             :   /**
     394             :    * \returns If \p elem is a neighbor of a child of this element, a
     395             :    * pointer to that child, otherwise \p nullptr.
     396             :    */
     397             :   Elem * child_neighbor (Elem * elem);
     398             : 
     399             :   /**
     400             :    * \returns If \p elem is a neighbor of a child of this element, a
     401             :    * pointer to that child, otherwise \p nullptr.
     402             :    */
     403             :   const Elem * child_neighbor (const Elem * elem) const;
     404             : 
     405             :   /**
     406             :    * \returns \p true if this element has a side coincident
     407             :    * with a boundary (indicated by a \p nullptr neighbor), \p false
     408             :    * otherwise.
     409             :    */
     410             :   bool on_boundary () const;
     411             : 
     412             :   /**
     413             :    * \returns \p true if this element is "semilocal" to the calling
     414             :    * processor, which must specify its rank.
     415             :    *
     416             :    * This method is discouraged, as it uses the *old* definition of
     417             :    * semilocal (elements which are not local but which are point
     418             :    * neighbors of something local) rather than any of the new
     419             :    * definitions discussed in ghosting_functor.h
     420             :    */
     421             :   bool is_semilocal (const processor_id_type my_pid) const;
     422             : 
     423             :   /**
     424             :    * This function tells you which neighbor \p e is.
     425             :    * I.e. if s = a->which_neighbor_am_i(e); then
     426             :    * a->neighbor(s) will be an ancestor of e.
     427             :    */
     428             :   unsigned int which_neighbor_am_i(const Elem * e) const;
     429             : 
     430             :   /**
     431             :    * This function tells you which side the boundary element \p e is.
     432             :    * I.e. if e = a->build_side_ptr(s) or e = a->side_ptr(s); then
     433             :    * a->which_side_am_i(e) will be s.
     434             :    *
     435             :    * \note An \e exact floating point comparison of the nodal
     436             :    * positions of \p e is made with the nodal positions of \p this in
     437             :    * order to perform this test. The idea is that the test will return
     438             :    * a valid side id if \p e either directly shares Node pointers with
     439             :    * \p this, or was created by exactly copying some of the nodes of
     440             :    * \p this (e.g. through BoundaryMesh::sync()). In these
     441             :    * circumstances, non-fuzzy floating point equality is expected.
     442             :    *
     443             :    * \returns The side of \p this the element which \p e is, otherwise
     444             :    * \p invalid_uint.
     445             :    */
     446             :   unsigned int which_side_am_i(const Elem * e) const;
     447             : 
     448             :   /**
     449             :    * \returns The local node id for node \p side_node on side \p side of
     450             :    * this Elem. Simply relies on the \p side_nodes_map for each of the
     451             :    * derived types. For example,
     452             :    * Tri3::local_side_node(0, 0) -> 0
     453             :    * Tri3::local_side_node(0, 1) -> 1
     454             :    * Tri3::local_side_node(1, 0) -> 1
     455             :    * Tri3::local_side_node(1, 1) -> 2
     456             :    * etc...
     457             :    */
     458             :   virtual unsigned int local_side_node(unsigned int side,
     459             :                                        unsigned int side_node) const = 0;
     460             : 
     461             :   /**
     462             :    * Similar to Elem::local_side_node(), but instead of a side id, takes
     463             :    * an edge id and a node id on that edge and returns a local node number
     464             :    * for the Elem. The implementation relies on the "edge_nodes_map" tables
     465             :    * for 3D elements. For 2D elements, calls local_side_node(). Throws an
     466             :    * error if called on 1D elements.
     467             :    */
     468             :   virtual unsigned int local_edge_node(unsigned int edge,
     469             :                                        unsigned int edge_node) const = 0;
     470             : 
     471             :   /**
     472             :    * \returns The local node id for node \p side_node on side \p side of
     473             :    * an element of type \p t, without needing an instantiated Elem.
     474             :    * The Polygon and Polyhedron subclasses have no such map, and the
     475             :    * infinite elements' maps are not read here, so those must be queried
     476             :    * through an actual Elem.
     477             :    */
     478             :   static unsigned int local_side_node(ElemType t,
     479             :                                       unsigned int side,
     480             :                                       unsigned int side_node);
     481             : 
     482             :   /**
     483             :    * \returns The local node id for node \p edge_node on edge \p edge of
     484             :    * an element of type \p t, without needing an instantiated Elem.  For
     485             :    * 2D types this is local_side_node(); 1D types have no edges.  The
     486             :    * same types are unsupported here as in local_side_node().
     487             :    */
     488             :   static unsigned int local_edge_node(ElemType t,
     489             :                                       unsigned int edge,
     490             :                                       unsigned int edge_node);
     491             : 
     492             :   /**
     493             :    * \returns \p true if a vertex of \p e is contained
     494             :    * in this element.  If \p mesh_connection is true, looks
     495             :    * specifically for containment possibilities of an element \p e
     496             :    * that is connected to \p this via membership in the same manifold
     497             :    * of the same mesh.
     498             :    */
     499             :   bool contains_vertex_of(const Elem * e, bool mesh_connection=false) const;
     500             : 
     501             :   /**
     502             :    * \returns \p true if an edge of \p e is contained in
     503             :    * this element.  (Internally, this is done by checking whether at
     504             :    * least two vertices of \p e are contained in this element).
     505             :    */
     506             :   bool contains_edge_of(const Elem * e) const;
     507             : 
     508             :   /**
     509             :    * This function finds all active elements (including this one)
     510             :    * which are in the same manifold as this element and which touch
     511             :    * the current active element at the specified point, which should
     512             :    * be a point in the current element.
     513             :    *
     514             :    * Elements which are not "in the same manifold" (e.g. the
     515             :    * interior_parent of a boundary element) will not be found with
     516             :    * this method.
     517             :    *
     518             :    * Elements which overlap the specified point but which are only
     519             :    * connected to the current element via elements which do not
     520             :    * overlap that point (e.g. in a folded or tangled mesh) are not
     521             :    * considered to "touch" the current element and will not be found
     522             :    * with this method.
     523             :    */
     524             :   void find_point_neighbors(const Point & p,
     525             :                             std::set<const Elem *> & neighbor_set) const;
     526             : 
     527             :   /**
     528             :    * This function finds all active elements (including this one) in
     529             :    * the same manifold as this element which touch this active element
     530             :    * at any point.
     531             :    */
     532             :   void find_point_neighbors(std::set<const Elem *> & neighbor_set) const;
     533             : 
     534             :   /**
     535             :    * This function finds all active elements (including this one) in
     536             :    * the same manifold as start_elem (which must be active and must
     537             :    * touch this element) which touch this element at any point.
     538             :    */
     539             :   void find_point_neighbors(std::set<const Elem *> & neighbor_set,
     540             :                             const Elem * start_elem) const;
     541             : 
     542             :   /**
     543             :    * Non-const version of function above. Fills a set of non-const Elem pointers.
     544             :    */
     545             :   void find_point_neighbors(std::set<Elem *> & neighbor_set,
     546             :                             Elem * start_elem);
     547             : 
     548             :   /**
     549             :    * This function finds all active elements in the same manifold as
     550             :    * this element which touch the current active element along the
     551             :    * whole edge defined by the two points \p p1 and \p p2.
     552             :    */
     553             :   void find_edge_neighbors(const Point & p1,
     554             :                            const Point & p2,
     555             :                            std::set<const Elem *> & neighbor_set) const;
     556             : 
     557             :   /**
     558             :    * This function finds all active elements in the same manifold as
     559             :    * this element which touch the current active element along any
     560             :    * edge (more precisely, at at least two points).
     561             :    *
     562             :    * In this case, elements are included even if they do not touch a
     563             :    * *whole* edge of this element.
     564             :    */
     565             :   void find_edge_neighbors(std::set<const Elem *> & neighbor_set) const;
     566             : 
     567             :   /**
     568             :    * This function finds all active elements (*not* including this
     569             :    * one) in the parent manifold of this element whose intersection
     570             :    * with this element has non-zero measure.
     571             :    */
     572             :   void find_interior_neighbors(std::set<const Elem *> & neighbor_set) const;
     573             : 
     574             :   /**
     575             :    * Non-const version of function above that fills up a vector of
     576             :    * non-const Elem pointers instead.
     577             :    */
     578             :   void find_interior_neighbors(std::set<Elem *> & neighbor_set);
     579             : 
     580             :   /**
     581             :    * Resets this element's neighbors' appropriate neighbor pointers
     582             :    * and its parent's and children's appropriate pointers
     583             :    * to point to null instead of to this.
     584             :    *
     585             :    * To be used before an element is deleted from a mesh.
     586             :    */
     587             :   void remove_links_to_me ();
     588             : 
     589             :   /**
     590             :    * Resets this element's neighbors' appropriate neighbor pointers
     591             :    * and its parent's and children's appropriate pointers
     592             :    * to point to the global remote_elem instead of this.
     593             :    * Used by the library before an element becomes remote on the
     594             :    * local processor.
     595             :    */
     596             :   void make_links_to_me_remote ();
     597             : 
     598             :   /**
     599             :    * Resets the \p neighbor_side pointers of our nth neighbor (and
     600             :    * its descendants, if appropriate) to point to this Elem instead of
     601             :    * to the global remote_elem.  Used by the library when a formerly
     602             :    * remote element is being added to the local processor.
     603             :    */
     604             :   void make_links_to_me_local (unsigned int n, unsigned int neighbor_side);
     605             : 
     606             :   /**
     607             :    * \returns \p true if this element is remote, false otherwise.
     608             :    *
     609             :    * A remote element (see \p RemoteElem) is a syntactic convenience --
     610             :    * it is a placeholder for an element which exists on some other
     611             :    * processor.  Local elements are required to have valid neighbors,
     612             :    * and these ghost elements may have remote neighbors for data
     613             :    * structure consistency.  The use of remote elements helps ensure
     614             :    * that any element we may access has a \p nullptr neighbor only if it
     615             :    * lies on the physical boundary of the domain.
     616             :    */
     617     7280126 :   virtual bool is_remote () const
     618     7280126 :   { return false; }
     619             : 
     620             :   /**
     621             :    * \returns The connectivity for this element in a specific
     622             :    * format, which is specified by the IOPackage tag.
     623             :    */
     624             :   virtual void connectivity(const unsigned int sc,
     625             :                             const IOPackage iop,
     626             :                             std::vector<dof_id_type> & conn) const = 0;
     627             : 
     628             :   /**
     629             :    * Writes the element connectivity for various IO packages
     630             :    * to the passed ostream "out".  Not virtual, since it is
     631             :    * implemented in the base class.
     632             :    */
     633             :   void write_connectivity (std::ostream & out,
     634             :                            const IOPackage iop) const;
     635             : 
     636             :   /**
     637             :    * \returns The type of element that has been derived from this
     638             :    * base class.
     639             :    */
     640             :   virtual ElemType type () const = 0;
     641             : 
     642             :   /**
     643             :    * This array maps the integer representation of the \p ElemType enum
     644             :    * to the geometric dimension of the element.
     645             :    *
     646             :    * This is currently usable even for complicated subclasses with
     647             :    * runtime-varying topology.
     648             :    */
     649             :   static const unsigned int type_to_dim_map[INVALID_ELEM];
     650             : 
     651             :   /**
     652             :    * \returns The dimensionality of the object.
     653             :    */
     654             :   virtual unsigned short dim () const = 0;
     655             : 
     656             :   /**
     657             :    * This array maps the integer representation of the \p ElemType enum
     658             :    * to the number of nodes in the element.
     659             :    *
     660             :    * This is only usable for simple types for which the node number
     661             :    * is fixed; for more general types like Polygon subclasses an actual
     662             :    * instantiated Elem must be queried.
     663             :    */
     664             :   static constexpr unsigned int type_to_n_nodes_map[INVALID_ELEM] =
     665             :     {
     666             :       2,  // EDGE2
     667             :       3,  // EDGE3
     668             :       4,  // EDGE4
     669             : 
     670             :       3,  // TRI3
     671             :       6,  // TRI6
     672             : 
     673             :       4,  // QUAD4
     674             :       8,  // QUAD8
     675             :       9,  // QUAD9
     676             : 
     677             :       4,  // TET4
     678             :       10, // TET10
     679             : 
     680             :       8,  // HEX8
     681             :       20, // HEX20
     682             :       27, // HEX27
     683             : 
     684             :       6,  // PRISM6
     685             :       15, // PRISM15
     686             :       18, // PRISM18
     687             : 
     688             :       5,  // PYRAMID5
     689             :       13, // PYRAMID13
     690             :       14, // PYRAMID14
     691             : 
     692             :       2,  // INFEDGE2
     693             : 
     694             :       4,  // INFQUAD4
     695             :       6,  // INFQUAD6
     696             : 
     697             :       8,  // INFHEX8
     698             :       16, // INFHEX16
     699             :       18, // INFHEX18
     700             : 
     701             :       6,  // INFPRISM6
     702             :       12, // INFPRISM12
     703             : 
     704             :       1,  // NODEELEM
     705             : 
     706             :       0,  // REMOTEELEM
     707             : 
     708             :       3,  // TRI3SUBDIVISION
     709             :       3,  // TRISHELL3
     710             :       4,  // QUADSHELL4
     711             :       8,  // QUADSHELL8
     712             : 
     713             :       7,  // TRI7
     714             :       14, // TET14
     715             :       20, // PRISM20
     716             :       21, // PRISM21
     717             :       18, // PYRAMID18
     718             : 
     719             :       9,  // QUADSHELL9
     720             : 
     721             :       invalid_uint,  // C0POLYGON
     722             :       invalid_uint,  // C0POLYHEDRON
     723             : 
     724             :     };
     725             : 
     726             :   /**
     727             :    * \returns The number of nodes this element contains.
     728             :    */
     729             :   virtual unsigned int n_nodes () const = 0;
     730             : 
     731             :   /**
     732             :    * The maximum number of nodes *any* element can contain.
     733             :    * This is useful for replacing heap vectors with stack arrays.
     734             :    */
     735             :   static const unsigned int max_n_nodes = 27;
     736             : 
     737             :   /**
     738             :    * \returns An integer range from 0 up to (but not including)
     739             :    * the number of nodes this element contains.
     740             :    */
     741             :   IntRange<unsigned short> node_index_range () const;
     742             : 
     743             :   /**
     744             :    * \returns The number of nodes the given child of this element
     745             :    * contains.  Except in odd cases like pyramid refinement this will
     746             :    * be the same as the number of nodes in the parent element.
     747             :    */
     748    21580541 :   virtual unsigned int n_nodes_in_child (unsigned int /*c*/) const
     749    21580541 :   { return this->n_nodes(); }
     750             : 
     751             :   /**
     752             :    * This array maps the integer representation of the \p ElemType enum
     753             :    * to the number of sides on the element.
     754             :    *
     755             :    * This is only usable for simple types for which the node number
     756             :    * is fixed; for more general types like Polygon subclasses an actual
     757             :    * instantiated Elem must be queried.
     758             :    */
     759             :   static const unsigned int type_to_n_sides_map[INVALID_ELEM];
     760             : 
     761             :   /**
     762             :    * \returns The number of sides the element that has been derived
     763             :    * from this class has. In 2D the number of sides is the number
     764             :    * of edges, in 3D the number of sides is the number of faces.
     765             :    */
     766             :   virtual unsigned int n_sides () const = 0;
     767             : 
     768             :   /**
     769             :    * \returns The type of element for side \p s.
     770             :    */
     771             :   virtual ElemType side_type (const unsigned int s) const = 0;
     772             : 
     773             :   /**
     774             :    * \returns The type of side \p s of an element of type \p t, without
     775             :    * needing an instantiated Elem.  The Polygon and Polyhedron subclasses
     776             :    * have one side type but no fixed number of sides, so \p s goes
     777             :    * unchecked for them; query an actual Elem when you have one.
     778             :    */
     779             :   static ElemType side_type (const ElemType t,
     780             :                              const unsigned int s);
     781             : 
     782             :   /**
     783             :    * \returns The type of every edge of an element of type \p t, or
     784             :    * \p INVALID_ELEM for the 1D types, which have no edges.  Unlike its
     785             :    * sides, a finite element's edges all have the same type, so no edge
     786             :    * index is needed; the infinite elements, whose finite and infinite
     787             :    * edges differ, are not answered here.
     788             :    */
     789             :   static ElemType edge_type (const ElemType t);
     790             : 
     791             :   /**
     792             :    * \returns the normal (outwards-facing) of the side of the element at the vertex-average of the side
     793             :    * @param s the side of interest
     794             :    */
     795             :   virtual Point side_vertex_average_normal(const unsigned int s) const;
     796             : 
     797             :   /**
     798             :    * \returns An integer range from 0 up to (but not including)
     799             :    * the number of sides this element has.
     800             :    */
     801             :   IntRange<unsigned short> side_index_range () const;
     802             : 
     803             :   /**
     804             :    * \returns The number of neighbors the element that has been derived
     805             :    * from this class has.
     806             :    *
     807             :    * Only face (or edge in 2D) neighbors are stored, so this method
     808             :    * returns n_sides().  At one point we intended to allow derived
     809             :    * classes to override this, but too much current libMesh code
     810             :    * assumes n_neighbors==n_sides.
     811             :    */
     812    84783191 :   unsigned int n_neighbors () const
     813   164568003 :   { return this->n_sides(); }
     814             : 
     815             :   /**
     816             :    * \returns The number of vertices the element that has been derived
     817             :    * from this class has.
     818             :    */
     819             :   virtual unsigned int n_vertices () const = 0;
     820             : 
     821             :   /**
     822             :    * \returns The number of edges the element that has been derived
     823             :    * from this class has.
     824             :    */
     825             :   virtual unsigned int n_edges () const = 0;
     826             : 
     827             :   /**
     828             :    * \returns An integer range from 0 up to (but not including)
     829             :    * the number of edges this element has.
     830             :    */
     831             :   IntRange<unsigned short> edge_index_range () const;
     832             : 
     833             :   /**
     834             :    * This array maps the integer representation of the \p ElemType enum
     835             :    * to the number of edges on the element.
     836             :    *
     837             :    * This is only usable for simple types for which the node number
     838             :    * is fixed; for more general types like Polygon subclasses an actual
     839             :    * instantiated Elem must be queried.
     840             :    */
     841             :   static const unsigned int type_to_n_edges_map[INVALID_ELEM];
     842             : 
     843             :   /**
     844             :    * \returns The number of faces the element that has been derived
     845             :    * from this class has.
     846             :    */
     847             :   virtual unsigned int n_faces () const = 0;
     848             : 
     849             :   /**
     850             :    * \returns An integer range from 0 up to (but not including)
     851             :    * the number of faces this element has.
     852             :    */
     853             :   IntRange<unsigned short> face_index_range () const;
     854             : 
     855             :   /**
     856             :    * \returns The number of children the element that has been derived
     857             :    * from this class may have.
     858             :    */
     859             :   virtual unsigned int n_children () const = 0;
     860             : 
     861             :   /**
     862             :    * \returns \p true if the specified (local) node number is a vertex node.
     863             :    */
     864             :   virtual bool is_vertex(const unsigned int i) const = 0;
     865             : 
     866             :   /**
     867             :    * \returns \p true if the specified child has a vertex at the
     868             :    * specified (child-local) node number.
     869             :    * Except in odd cases like pyramid refinement the child will have
     870             :    * the same local structure as the parent element.
     871             :    */
     872      177423 :   virtual bool is_vertex_on_child (unsigned int /*c*/,
     873             :                                    unsigned int n) const
     874      177423 :   { return this->is_vertex(n); }
     875             : 
     876             :   /**
     877             :    * \returns \p true if this element has a vertex at the specified
     878             :    * (child-local) node number \p n of the specified child \p c.
     879             :    */
     880             :   virtual bool is_vertex_on_parent(unsigned int c,
     881             :                                    unsigned int n) const;
     882             : 
     883             :   /**
     884             :    * \returns \p true if the specified (local) node number is an edge node.
     885             :    * For 1D elements, is_edge() is equivalent to is_internal().
     886             :    */
     887             :   virtual bool is_edge(const unsigned int i) const = 0;
     888             : 
     889             :   /**
     890             :    * \returns \p true if the specified (local) node number is a face node.
     891             :    * For 2D elements, is_face() is equivalent to is_internal().
     892             :    * For 1D elements, is_face() == false.
     893             :    */
     894             :   virtual bool is_face(const unsigned int i) const = 0;
     895             : 
     896             :   /**
     897             :    * \returns \p true if the specified (local) node number is an internal node.
     898             :    */
     899             :   bool is_internal(const unsigned int i) const;
     900             : 
     901             :   /**
     902             :    * \returns \p true if the specified (local) node number is on the
     903             :    * specified side.
     904             :    */
     905             :   virtual bool is_node_on_side(const unsigned int n,
     906             :                                const unsigned int s) const = 0;
     907             : 
     908             :   /**
     909             :    * \returns the (local) node numbers on the specified side
     910             :    */
     911             :   virtual std::vector<unsigned int> nodes_on_side(const unsigned int /*s*/) const = 0;
     912             : 
     913             :   /**
     914             :    * \returns the (local) node numbers on the specified edge
     915             :    */
     916             :   virtual std::vector<unsigned int> nodes_on_edge(const unsigned int /*e*/) const = 0;
     917             : 
     918             :   /**
     919             :    * \returns the (local) side numbers that touch the specified edge
     920             :    */
     921             :   virtual std::vector<unsigned int> sides_on_edge(const unsigned int /*e*/) const = 0;
     922             : 
     923             :   /**
     924             :    * \returns the (local) edge numbers that touch the specified node
     925             :    */
     926             :   virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int /*n*/) const = 0;
     927             : 
     928             :   /**
     929             :    * \returns \p true if the specified (local) node number is on the
     930             :    * specified edge.
     931             :    */
     932             :   virtual bool is_node_on_edge(const unsigned int n,
     933             :                                const unsigned int e) const = 0;
     934             : 
     935             :   /**
     936             :    * \returns \p true if the specified edge is on the specified side.
     937             :    */
     938             :   virtual bool is_edge_on_side(const unsigned int e,
     939             :                                const unsigned int s) const = 0;
     940             : 
     941             :   /**
     942             :    * \returns The side number opposite to \p s (for a tensor product
     943             :    * element), or throws an error otherwise.
     944             :    */
     945             :   virtual unsigned int opposite_side(const unsigned int s) const;
     946             : 
     947             :   /**
     948             :    * \returns The local node number for the node opposite to node n
     949             :    * on side \p opposite_side(s) (for a tensor product element), or
     950             :    * throws an error otherwise.
     951             :    */
     952             :   virtual unsigned int opposite_node(const unsigned int n,
     953             :                                      const unsigned int s) const;
     954             : 
     955             :   /**
     956             :    * \returns The number of sub-elements this element may be broken
     957             :    * down into for visualization purposes.  For example, 1 for a
     958             :    * linear triangle, 4 for a quadratic (6-noded) triangle, etc...
     959             :    */
     960             :   virtual unsigned int n_sub_elem () const = 0;
     961             : 
     962             :   /**
     963             :    * \returns A temporary element coincident with side \p i.
     964             :    *
     965             :    * This method returns the _minimum_ element necessary to uniquely
     966             :    * identify the side.  For example, the side of a hexahedron is
     967             :    * always returned as a 4-noded quadrilateral, regardless of what
     968             :    * type of hex you are dealing with.  Important data like subdomain
     969             :    * id, p level, or mapping type may be omitted from the temporary
     970             :    * element.  If you want a first-class full-ordered face (i.e. a
     971             :    * 9-noded quad face for a 27-noded hexahedron), use the
     972             :    * build_side_ptr method.
     973             :    *
     974             :    * \note The const version of this function is non-virtual; it
     975             :    * simply calls the virtual non-const version and const_casts the
     976             :    * return type.
     977             :    */
     978             :   virtual std::unique_ptr<Elem> side_ptr (unsigned int i) = 0;
     979             :   std::unique_ptr<const Elem> side_ptr (unsigned int i) const;
     980             : 
     981             :   /**
     982             :    * Resets the loose element \p side, which may currently point to a
     983             :    * different side than \p i or even a different element than \p
     984             :    * this, to point to side \p i on \p this.  If \p side is currently
     985             :    * an element of the wrong type, it will be freed and a new element
     986             :    * allocated; otherwise no memory allocation will occur.
     987             :    *
     988             :    * This will cause \p side to be a minimum-ordered element, even if
     989             :    * it is handed a higher-ordered element that must be replaced.
     990             :    *
     991             :    * The const version of this function is non-virtual; it simply
     992             :    * calls the virtual non-const version and const_casts the return
     993             :    * type.
     994             :    */
     995             :   virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
     996             :   void side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
     997             : 
     998             :   /**
     999             :    * \returns An temporary element coincident with side \p i wrapped
    1000             :    * in a smart pointer.
    1001             :    *
    1002             :    * The element returned is full-ordered and full-featured, in
    1003             :    * contrast to the side method.  For example, calling
    1004             :    * build_side_ptr(0) on a 20-noded hex in subdomain 5 will build a
    1005             :    * 8-noded quadrilateral coincident with face 0, assign it subdomain
    1006             :    * id 5, and pass back the pointer.
    1007             :    *
    1008             :    * The side element's id() is undefined; it is a temporary element
    1009             :    * not added to any mesh.
    1010             :    *
    1011             :    * A \p std::unique_ptr<Elem> is returned to prevent a memory leak.
    1012             :    * This way the user need not remember to delete the object.
    1013             :    *
    1014             :    * The const version of this function is non-virtual; it simply
    1015             :    * calls the virtual non-const version and const_casts the return
    1016             :    * type.
    1017             :    */
    1018             :   virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) = 0;
    1019             :   std::unique_ptr<const Elem> build_side_ptr (const unsigned int i) const;
    1020             : 
    1021             : #ifdef LIBMESH_ENABLE_DEPRECATED
    1022             :   /*
    1023             :    * Older versions of libMesh supported a "proxy" option here.
    1024             :    */
    1025           0 :   virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i, bool proxy)
    1026           0 :   { if (proxy) libmesh_error(); libmesh_deprecated(); return this->build_side_ptr(i); }
    1027             : 
    1028             :   std::unique_ptr<const Elem> build_side_ptr (const unsigned int i, bool proxy) const
    1029             :   { if (proxy) libmesh_error(); libmesh_deprecated(); return this->build_side_ptr(i); }
    1030             : #endif
    1031             : 
    1032             :   /**
    1033             :    * Resets the loose element \p side, which may currently point to a
    1034             :    * different side than \p i or even a different element than \p
    1035             :    * this, to point to side \p i on \p this.  If \p side is currently
    1036             :    * an element of the wrong type, it will be freed and a new element
    1037             :    * allocated; otherwise no memory allocation will occur.
    1038             :    *
    1039             :    * This will cause \p side to be a full-ordered element, even if it
    1040             :    * is handed a lower-ordered element that must be replaced.
    1041             :    *
    1042             :    * The const version of this function is non-virtual; it simply
    1043             :    * calls the virtual non-const version and const_casts the return
    1044             :    * type.
    1045             :    */
    1046             :   virtual void build_side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
    1047             :   void build_side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
    1048             : 
    1049             :   /**
    1050             :    * \returns An element coincident with edge \p i wrapped in a smart pointer.
    1051             :    *
    1052             :    * The element returned is full-ordered.  For example, calling
    1053             :    * build_edge_ptr(0) on a 20-noded hex will build a 3-noded edge
    1054             :    * coincident with edge 0 and pass back the pointer.  A \p
    1055             :    * std::unique_ptr<Elem> is returned to prevent a memory leak.  This way
    1056             :    * the user need not remember to delete the object.
    1057             :    *
    1058             :    * The const version of this function is non-virtual; it simply
    1059             :    * calls the virtual non-const version and const_casts the return
    1060             :    * type.
    1061             :    */
    1062             :   virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) = 0;
    1063             :   std::unique_ptr<const Elem> build_edge_ptr (const unsigned int i) const;
    1064             : 
    1065             :   /**
    1066             :    * Resets the loose element \p edge, which may currently point to a
    1067             :    * different edge than \p i or even a different element than \p
    1068             :    * this, to point to edge \p i on \p this.  If \p edge is currently
    1069             :    * an element of the wrong type, it will be freed and a new element
    1070             :    * allocated; otherwise no memory allocation will occur.
    1071             :    *
    1072             :    * This will cause \p edge to be a full-ordered element, even if it
    1073             :    * is handed a lower-ordered element that must be replaced.
    1074             :    *
    1075             :    * The const version of this function is non-virtual; it simply
    1076             :    * calls the virtual non-const version and const_casts the return
    1077             :    * type.
    1078             :    */
    1079             :   virtual void build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i) = 0;
    1080             :   void build_edge_ptr (std::unique_ptr<const Elem> & edge, const unsigned int i) const;
    1081             : 
    1082             :   /**
    1083             :    * This array maps the integer representation of the \p ElemType enum
    1084             :    * to the default approximation order of elements of that type.
    1085             :    *
    1086             :    * This is currently usable even for complicated subclasses with
    1087             :    * runtime-varying topology.
    1088             :    */
    1089             :   static const Order type_to_default_order_map[INVALID_ELEM];
    1090             : 
    1091             :   /**
    1092             :    * \returns The default approximation order for this element.  This
    1093             :    * is the order that will be used to compute the map to the
    1094             :    * reference element.
    1095             :    */
    1096             :   virtual Order default_order () const = 0;
    1097             : 
    1098             :   /**
    1099             :    * \returns The maximum supported approximation order for nodal
    1100             :    * (Lagrange or Rational Bezier-Bernstein) variables on this element
    1101             :    * type.  This is usually the same as the default order.
    1102             :    */
    1103    34911223 :   virtual Order supported_nodal_order() const { return default_order(); }
    1104             : 
    1105             :   /**
    1106             :    * \returns The default approximation order for side elements of
    1107             :    * this element type.  This may be lower for elements with 'bubble
    1108             :    * functions' in the Lagrange basis.
    1109             :    */
    1110      517279 :   virtual Order default_side_order () const { return default_order(); }
    1111             : 
    1112             :   /**
    1113             :    * \returns The "true" geometric centroid of the element, c=(cx, cy,
    1114             :    * cz), where:
    1115             :    *
    1116             :    * [cx]            [\int x dV]
    1117             :    * [cy] := (1/V) * [\int y dV]
    1118             :    * [cz]            [\int z dV]
    1119             :    *
    1120             :    * This method is virtual since some derived elements might want to
    1121             :    * use shortcuts to compute their centroid. For most element types,
    1122             :    * this method is more expensive than calling vertex_average(), so
    1123             :    * if you only need a point which is located "somewhere" in the
    1124             :    * interior of the element, consider calling vertex_average() instead.
    1125             :    */
    1126             :   virtual Point true_centroid () const;
    1127             : 
    1128             :   /**
    1129             :    * \returns A Point at the average of the elment's vertices.
    1130             :    *
    1131             :    * \note This used to be the base class centroid() implementation, but
    1132             :    * the centroid is only equal to the vertex average in some special cases.
    1133             :    * The centroid() implementation now returns the "true" centroid of the
    1134             :    * element (up to quadrature error).
    1135             :    */
    1136             :   Point vertex_average () const;
    1137             : 
    1138             :   /**
    1139             :    * \returns The "circumcenter of mass" (area-weighted average of
    1140             :    * triangulation circumcenters) of the element.
    1141             :    *
    1142             :    * Not implemented for infinite elements, not currently implemented
    1143             :    * for 3D elements, currently ignores curvature of element edges.
    1144             :    */
    1145           0 :   virtual Point quasicircumcenter () const
    1146           0 :   { libmesh_not_implemented(); }
    1147             : 
    1148             :   /**
    1149             :    * \returns The minimum vertex separation for the element.
    1150             :    */
    1151             :   virtual Real hmin () const;
    1152             : 
    1153             :   /**
    1154             :    * \returns The maximum vertex separation for the element.
    1155             :    */
    1156             :   virtual Real hmax () const;
    1157             : 
    1158             :   /**
    1159             :    * \returns The (length/area/volume) of the geometric element.
    1160             :    *
    1161             :    * If the element is twisted or inverted such that the mapping
    1162             :    * Jacobian is singular at any point, implementations of this method
    1163             :    * may return a "net" volume or may simply return NaN.
    1164             :    */
    1165             :   virtual Real volume () const;
    1166             : 
    1167             :   /**
    1168             :    * \returns A bounding box (not necessarily the minimal bounding box)
    1169             :    * containing the geometric element.
    1170             :    *
    1171             :    * The base class implementation determines a bounding box for the
    1172             :    * element *nodes*, which should be sufficient for first order
    1173             :    * finite elements.  Higher order geometric elements will need to
    1174             :    * override with an implementation which takes curved elements into
    1175             :    * account.
    1176             :    */
    1177             :   virtual BoundingBox loose_bounding_box () const;
    1178             : 
    1179             :   /**
    1180             :    * \returns A quantitative assessment of element quality based on
    1181             :    * the quality metric \p q specified by the user. Not all ElemQuality
    1182             :    * metrics are supported for all Elem types; consult the Elem::quality()
    1183             :    * overrides for specific Elem types to determine which quality metrics
    1184             :    * are supported. The ElemQuality metrics with generic support for all
    1185             :    * Elems with dimension > 1 are:
    1186             :    * .) EDGE_LENGTH_RATIO - ratio of maximum to minimum edge (in 2D,
    1187             :    *    side) length, where the min/max is taken over all Elem edges.
    1188             :    * .) MIN,MAX_ANGLE - The minimum (respectively maximum) angle
    1189             :    *    between all pairs of adjacent Elem edges, in degrees. In 3D,
    1190             :    *    these are *not* the dihedral angles between adjacent planar
    1191             :    *    faces of the element. In 2D, we compute the angle between
    1192             :    *    adjacent sides for this metric.
    1193             :    * .) MIN,MAX_DIHEDRAL_ANGLE - In 3D, the minimum (respectively
    1194             :    *    maximum) unoriented angle between adjacent side planes, folded
    1195             :    *    into the range [0, 90] degrees. In 2D, these are equivalent to
    1196             :    *    MIN,MAX_ANGLE.
    1197             :    */
    1198             :   virtual Real quality (const ElemQuality q) const;
    1199             : 
    1200             :   /**
    1201             :    * \returns The suggested quality bounds for the Elem based on
    1202             :    * quality measure \p q.
    1203             :    *
    1204             :    * These are the values suggested by the CUBIT User's Manual.  Since
    1205             :    * this function can have no possible meaning for an abstract Elem,
    1206             :    * it is an error in the base class.
    1207             :    */
    1208           0 :   virtual std::pair<Real,Real> qual_bounds (const ElemQuality) const
    1209           0 :   { libmesh_not_implemented(); return std::make_pair(0.,0.); }
    1210             : 
    1211             :   /**
    1212             :    * \returns \p true if the physical point p is contained in this
    1213             :    * element, false otherwise.
    1214             :    *
    1215             :    * For linear elements, performs an initial tight bounding box check
    1216             :    * (as an optimization step) and (if that passes) then uses the
    1217             :    * user-defined tolerance "tol" in a call to inverse_map() to actually
    1218             :    * test if the point is in the element.  For quadratic elements, the
    1219             :    * bounding box optimization is skipped, and only the inverse_map()
    1220             :    * steps are performed.
    1221             :    *
    1222             :    * \note This routine should not be used to determine if a point
    1223             :    * is merely "nearby" an element to within some tolerance. For that,
    1224             :    * use Elem::close_to_point() instead.
    1225             :    */
    1226             :   virtual bool contains_point (const Point & p, Real tol=TOLERANCE) const;
    1227             : 
    1228             :   /**
    1229             :    * \returns \p true if the master-space point p is contained in the
    1230             :    * reference element corresponding to this element, false otherwise.
    1231             :    *
    1232             :    * Since we are doing floating point comparisons here the parameter
    1233             :    * \p eps can be specified to indicate a tolerance.  For example,
    1234             :    * \f$ x \le 1 \f$  becomes \f$ x \le 1 + \epsilon \f$.
    1235             :    */
    1236             :   virtual bool on_reference_element(const Point & p,
    1237             :                                     const Real eps = TOLERANCE) const = 0;
    1238             : 
    1239             :   /**
    1240             :    * \returns \p true if this element is "close" to the point p, where
    1241             :    * "close" is determined by the tolerance tol.
    1242             :    */
    1243             :   virtual bool close_to_point(const Point & p, Real tol) const;
    1244             : 
    1245             :   /**
    1246             :    * \returns \p true if edge \p i is positively oriented. An edge is
    1247             :    * positively oriented iff its first vertex (i.e. zeroth node) is
    1248             :    * lexicographically greater than its second vertex (i.e. first node).
    1249             :    */
    1250             :   bool positive_edge_orientation(const unsigned int i) const;
    1251             : 
    1252             :   /**
    1253             :    * \returns \p true if face \p i is positively oriented. A face is
    1254             :    * positively oriented iff the triangle defined by the lexicographically
    1255             :    * least vertex and its two adjacent vertices on the same face is
    1256             :    * positively oriented. Said triangle is positively oriented iff its
    1257             :    * vertices are an odd permutation of their lexicographic ordering.
    1258             :    */
    1259             :   bool positive_face_orientation(const unsigned int i) const;
    1260             : 
    1261             :   /**
    1262             :    * \returns An index over the symmetries of face \p i (six for a
    1263             :    * triangle, eight for a quadrilateral): twice the position of the
    1264             :    * lexicographically least vertex in the face's node map, plus 1 if
    1265             :    * the face is positively oriented.
    1266             :    *
    1267             :    * Unlike \p positive_face_orientation(), this fixes the full ordering
    1268             :    * of the face's vertices, which a basis with face degrees of freedom
    1269             :    * (e.g. HIERARCHIC of order three or above) needs in order to be
    1270             :    * conforming across the face.
    1271             :    */
    1272             :   unsigned int face_orientation(const unsigned int i) const;
    1273             : 
    1274             :   /**
    1275             :    * \returns The local indices of the vertices of face \p i, starting
    1276             :    * at its lexicographically least vertex and continuing toward the
    1277             :    * lesser of that vertex's two neighbors on the face, as encoded by
    1278             :    * \p face_orientation(). Every element sharing the face returns the
    1279             :    * same vertices in the same order.
    1280             :    */
    1281             :   std::vector<unsigned int> oriented_face_vertices(const unsigned int i) const;
    1282             : 
    1283             :   /**
    1284             :    * \returns \p true iff, for an edge \p e on side \p s, the node map for
    1285             :    * side \p s is such that the first vertex (i.e. zeroth node) of \p e is
    1286             :    * lower positioned than the second vertex (i.e. first node) of \p e.
    1287             :    */
    1288             :   bool relative_edge_face_order(const unsigned int e, const unsigned int s) const;
    1289             : 
    1290             :   /**
    1291             :    * A helper function for copying generic element data (mapping,
    1292             :    * subdomain, processor) from an element to a derived (child, side,
    1293             :    * edge) element.  Useful for forwards compatibility when new data
    1294             :    * is added.
    1295             :    */
    1296             :   void inherit_data_from(const Elem & src);
    1297             : 
    1298             : private:
    1299             :   /**
    1300             :    * Shared private implementation used by the contains_point()
    1301             :    * and close_to_point() routines.  The box_tol tolerance is
    1302             :    * used in the bounding box optimization, the map_tol tolerance is used
    1303             :    * in the calls to inverse_map() and on_reference_element().
    1304             :    */
    1305             :   bool point_test(const Point & p, Real box_tol, Real map_tol) const;
    1306             : 
    1307             : public:
    1308             :   /**
    1309             :    * \returns \p true if the element map is definitely affine (i.e. the same at
    1310             :    * every quadrature point) within numerical tolerances.
    1311             :    */
    1312           0 :   virtual bool has_affine_map () const { return false; }
    1313             : 
    1314             :   /**
    1315             :    * \returns \p true if the element map is invertible everywhere on
    1316             :    * the element, to within a user-specified tolerance. The tolerance
    1317             :    * is generally used in comparisons against zero, so it should be an
    1318             :    * absolute rather than a relative tolerance. Throws a
    1319             :    * libmesh_not_implemented() error unless specialized by derived
    1320             :    * classes.
    1321             :    */
    1322             :   virtual bool has_invertible_map(Real tol = TOLERANCE*TOLERANCE) const;
    1323             : 
    1324             :   /**
    1325             :    * \returns \p true if the Lagrange shape functions on this element
    1326             :    * are linear.
    1327             :    */
    1328           0 :   virtual bool is_linear () const { return false; }
    1329             : 
    1330             :   /**
    1331             :    * Prints relevant information about the element.
    1332             :    */
    1333             :   void print_info (std::ostream & os=libMesh::out) const;
    1334             : 
    1335             :   /**
    1336             :    * Prints relevant information about the element to a string.
    1337             :    */
    1338             :   std::string get_info () const;
    1339             : 
    1340             :   /**
    1341             :    * \returns \p true if the element is active (i.e. has no active
    1342             :    * descendants) or AMR is disabled, \p false otherwise.
    1343             :    *
    1344             :    * \note It suffices to check the first child only.
    1345             :    */
    1346             :   bool active () const;
    1347             : 
    1348             :   /**
    1349             :    * \returns \p true if the element is an ancestor (i.e. has an
    1350             :    * active child or ancestor child), \p false otherwise or when AMR
    1351             :    * is disabled.
    1352             :    */
    1353             :   bool ancestor () const;
    1354             : 
    1355             :   /**
    1356             :    * \returns \p true if the element is subactive (i.e. has no active
    1357             :    * descendants), \p false otherwise or if AMR is disabled.
    1358             :    */
    1359             :   bool subactive () const;
    1360             : 
    1361             :   /**
    1362             :    * \returns \p true if the element has any children (active or not),
    1363             :    * \p false otherwise, or if AMR is disabled.
    1364             :    */
    1365             :   bool has_children () const;
    1366             : 
    1367             :   /**
    1368             :    * \returns \p true if the element has any descendants other than
    1369             :    * its immediate children, \p false otherwise, or if AMR is disabled.
    1370             :    */
    1371             :   bool has_ancestor_children () const;
    1372             : 
    1373             :   /**
    1374             :    * \returns \p true if \p descendant is a child of \p this, or a
    1375             :    * child of a child of \p this, etc., \p false otherwise or if AMR
    1376             :    * is disabled.
    1377             :    */
    1378             :   bool is_ancestor_of(const Elem * descendant) const;
    1379             : 
    1380             :   /**
    1381             :    * \returns A const pointer to the element's parent, or \p nullptr if
    1382             :    * the element was not created via refinement.
    1383             :    */
    1384             :   const Elem * parent () const;
    1385             : 
    1386             :   /**
    1387             :    * \returns A pointer to the element's parent, or \p nullptr if
    1388             :    * the element was not created via refinement.
    1389             :    */
    1390             :   Elem * parent ();
    1391             : 
    1392             :   /**
    1393             :    * Sets the pointer to the element's parent.
    1394             :    * Dangerous! Only use this if you know what you are doing!
    1395             :    */
    1396             :   void set_parent (Elem * p);
    1397             : 
    1398             :   /**
    1399             :    * \returns A pointer to the element's top-most (i.e. level-0) parent.
    1400             :    *
    1401             :    * That is, \p this if this is a level-0 element, this element's parent
    1402             :    * if this is a level-1 element, this element's grandparent if this is
    1403             :    * a level-2 element, etc...
    1404             :    */
    1405             :   const Elem * top_parent () const;
    1406             : 
    1407             :   /**
    1408             :    * \returns The higher-dimensional Elem for which this Elem is a face.
    1409             :    *
    1410             :    * In some cases it is desirable to extract the boundary (or a subset thereof)
    1411             :    * of a D-dimensional mesh as a (D-1)-dimensional manifold.  In this case
    1412             :    * we may want to know the 'parent' element from which the manifold elements
    1413             :    * were extracted.  We can easily do that for the level-0 manifold elements
    1414             :    * by storing the D-dimensional parent.  This method provides access to that
    1415             :    * element.
    1416             :    *
    1417             :    * This method returns nullptr if this->dim() == LIBMESH_DIM; in
    1418             :    * such cases no data storage for an interior parent pointer has
    1419             :    * been allocated.
    1420             :    */
    1421             :   const Elem * interior_parent () const;
    1422             : 
    1423             :   Elem * interior_parent ();
    1424             : 
    1425             :   /**
    1426             :    * Sets the pointer to the element's interior_parent.
    1427             :    * Dangerous! Only use this if you know what you are doing!
    1428             :    */
    1429             :   void set_interior_parent (Elem * p);
    1430             : 
    1431             :   /**
    1432             :    * \returns The distance between nodes n1 and n2.
    1433             :    *
    1434             :    * Useful for computing the lengths of the sides of elements.
    1435             :    */
    1436             :   Real length (const unsigned int n1,
    1437             :                const unsigned int n2) const;
    1438             : 
    1439             :   /**
    1440             :    * \returns The number of adjacent vertices that uniquely define the
    1441             :    * location of the \f$ n^{th} \f$ second-order node, or 0 for linear
    1442             :    * elements.
    1443             :    *
    1444             :    * This method is useful when converting linear elements to quadratic
    1445             :    * elements.
    1446             :    *
    1447             :    * \note \p n has to be greater than or equal to \p this->n_vertices().
    1448             :    */
    1449             :   virtual unsigned int n_second_order_adjacent_vertices (const unsigned int n) const;
    1450             : 
    1451             :   /**
    1452             :    * \returns The element-local number of the \f$ v^{th} \f$ vertex
    1453             :    * that defines the \f$ n^{th} \f$ second-order node, or 0 for
    1454             :    * linear elements.
    1455             :    *
    1456             :    * \note The value is always less than \p this->n_vertices(), while
    1457             :    * \p n has to be greater than or equal to \p this->n_vertices().
    1458             :    */
    1459             :   virtual unsigned short int second_order_adjacent_vertex (const unsigned int n,
    1460             :                                                            const unsigned int v) const;
    1461             : 
    1462             :   /**
    1463             :    * \returns A pair (c,v), where
    1464             :    * c == child index, and
    1465             :    * v == element-local index of the \p \f$ n^{th} \f$
    1466             :    *      second-order node on the parent element.
    1467             :    * For linear elements, (0,0) is returned.
    1468             :    *
    1469             :    * \note The return values are always less than \p this->n_children()
    1470             :    * and \p this->child_ptr(c)->n_vertices().
    1471             :    *
    1472             :    * \note \p n has to be greater than or equal to \p this->n_vertices().
    1473             :    *
    1474             :    * \note On refined second-order elements, the return value will
    1475             :    * satisfy \p this->node_ptr(n) == this->child_ptr(c)->node_ptr(v).
    1476             :    */
    1477             :   virtual std::pair<unsigned short int, unsigned short int>
    1478             :   second_order_child_vertex (const unsigned int n) const;
    1479             : 
    1480             :   /**
    1481             :    * \returns The ElemType of the associated second-order element
    1482             :    * (which will be the same as the input if the input is already a
    1483             :    * second-order ElemType) or INVALID_ELEM for elements that cannot be
    1484             :    * converted into higher order equivalents.
    1485             :    *
    1486             :    * For example, when \p this is a \p TET4, then \p TET10 is returned.
    1487             :    *
    1488             :    * For some elements, there exist two second-order equivalents, e.g.
    1489             :    * for \p Quad4 there is \p Quad8 and \p Quad9.  When the optional
    1490             :    * \p full_ordered is \p true, then \p QUAD9 is returned.  When
    1491             :    * \p full_ordered is \p false, then \p QUAD8 is returned.
    1492             :    */
    1493             :   static ElemType second_order_equivalent_type (const ElemType et,
    1494             :                                                 const bool full_ordered=true);
    1495             : 
    1496             :   /**
    1497             :    * \returns The element type of the associated first-order element,
    1498             :    * or \p INVALID_ELEM for first-order or other elements that cannot be
    1499             :    * converted into lower order equivalents.
    1500             :    *
    1501             :    * For example, when \p this is a \p TET10, then \p TET4 is returned.
    1502             :    */
    1503             :   static ElemType first_order_equivalent_type (const ElemType et);
    1504             : 
    1505             :   /**
    1506             :    * \returns The ElemType of the associated "complete" order element
    1507             :    * (which will be the same as the input if the input is already a
    1508             :    * complete-order ElemType), or INVALID_ELEM for elements that cannot be
    1509             :    * converted into complete-order equivalents.
    1510             :    *
    1511             :    * The "complete" version of an element is an element which can
    1512             :    * represent the same geometry but which has nodes available to
    1513             :    * restore degrees of freedom on any vertex, edge, or face.
    1514             :    *
    1515             :    * For example, when \p this is a \p TET4, then \p TET14 is returned.
    1516             :    */
    1517             :   static ElemType complete_order_equivalent_type (const ElemType et);
    1518             : 
    1519             :   /**
    1520             :    * \returns The refinement level of the current element.
    1521             :    *
    1522             :    * If the element's parent is \p nullptr then by convention it is at
    1523             :    * level 0, otherwise it is simply at one level greater than its
    1524             :    * parent.
    1525             :    */
    1526             :   unsigned int level () const;
    1527             : 
    1528             :   /**
    1529             :    * \returns The value of the p refinement level of an active
    1530             :    * element, or the minimum value of the p refinement levels
    1531             :    * of an ancestor element's descendants.
    1532             :    */
    1533             :   unsigned int p_level () const;
    1534             : 
    1535             :   /**
    1536             :    * \returns \p true if the specified child is on the specified side.
    1537             :    */
    1538             :   virtual bool is_child_on_side(const unsigned int c,
    1539             :                                 const unsigned int s) const = 0;
    1540             : 
    1541             :   /**
    1542             :    * \returns The value of the mapping type for the element.
    1543             :    */
    1544             :   ElemMappingType mapping_type () const;
    1545             : 
    1546             :   /**
    1547             :    * Sets the value of the mapping type for the element.
    1548             :    */
    1549             :   void set_mapping_type (const ElemMappingType type);
    1550             : 
    1551             :   /**
    1552             :    * \returns The value of the mapping data for the element.
    1553             :    */
    1554             :   unsigned char mapping_data () const;
    1555             : 
    1556             :   /**
    1557             :    * Sets the value of the mapping data for the element.
    1558             :    */
    1559             :   void set_mapping_data (const unsigned char data);
    1560             : 
    1561             : 
    1562             : #ifdef LIBMESH_ENABLE_AMR
    1563             : 
    1564             :   /**
    1565             :    * Enumeration of possible element refinement states.
    1566             :    */
    1567             :   enum RefinementState { COARSEN = 0,
    1568             :                          DO_NOTHING,
    1569             :                          REFINE,
    1570             :                          JUST_REFINED,
    1571             :                          JUST_COARSENED,
    1572             :                          INACTIVE,
    1573             :                          COARSEN_INACTIVE,
    1574             :                          INVALID_REFINEMENTSTATE };
    1575             : 
    1576             :   /**
    1577             :    * \returns A constant pointer to the \f$ i^{th} \f$ child for this element.
    1578             :    * For internal use only - skips assertions about null pointers.
    1579             :    */
    1580             :   const Elem * raw_child_ptr (unsigned int i) const;
    1581             : 
    1582             :   /**
    1583             :    * \returns A constant pointer to the \f$ i^{th} \f$ child for this element.
    1584             :    * Do not call if this element has no children, i.e. is active.
    1585             :    */
    1586             :   const Elem * child_ptr (unsigned int i) const;
    1587             : 
    1588             :   /**
    1589             :    * \returns A non-constant pointer to the \f$ i^{th} \f$ child for this element.
    1590             :    * Do not call if this element has no children, i.e. is active.
    1591             :    */
    1592             :   Elem * child_ptr (unsigned int i);
    1593             : 
    1594             :   /**
    1595             :    * Nested classes for use iterating over all children of a parent
    1596             :    * element.
    1597             :    */
    1598             :   class ChildRefIter;
    1599             :   class ConstChildRefIter;
    1600             : 
    1601             :   /**
    1602             :    * Returns a range with all children of a parent element, usable in
    1603             :    * range-based for loops.  The exact type of the return value here
    1604             :    * may be subject to change in future libMesh releases, but the
    1605             :    * iterators will always dereference to produce a reference to a
    1606             :    * child element.
    1607             :    */
    1608             :   SimpleRange<ChildRefIter> child_ref_range();
    1609             : 
    1610             :   SimpleRange<ConstChildRefIter> child_ref_range() const;
    1611             : 
    1612             : private:
    1613             :   /**
    1614             :    * Sets the pointer to the \f$ i^{th} \f$ child for this element.
    1615             :    * Do not call if this element has no children, i.e. is active.
    1616             :    */
    1617             :   void set_child (unsigned int c, Elem * elem);
    1618             : 
    1619             : public:
    1620             :   /**
    1621             :    * \returns The child index which \p e corresponds to.
    1622             :    *
    1623             :    * I.e. if c = a->which_child_am_i(e); then a->child_ptr(c) will be
    1624             :    * e.
    1625             :    */
    1626             :   unsigned int which_child_am_i(const Elem * e) const;
    1627             : 
    1628             :   /**
    1629             :    * \returns \p true if the specified child is on the specified edge.
    1630             :    */
    1631             :   virtual bool is_child_on_edge(const unsigned int c,
    1632             :                                 const unsigned int e) const;
    1633             : 
    1634             :   /**
    1635             :    * Adds a child pointer to the array of children of this element.
    1636             :    * If this is the first child to be added, this method allocates
    1637             :    * memory in the parent's _children array, otherwise, it just sets
    1638             :    * the pointer.
    1639             :    */
    1640             :   void add_child (Elem * elem);
    1641             : 
    1642             :   /**
    1643             :    * Adds a new child pointer to the specified index in the array of
    1644             :    * children of this element.  If this is the first child to be added,
    1645             :    * this method allocates memory in the parent's _children array,
    1646             :    * otherwise, it just sets the pointer.
    1647             :    */
    1648             :   void add_child (Elem * elem, unsigned int c);
    1649             : 
    1650             :   /**
    1651             :    * Replaces the child pointer at the specified index in the child array.
    1652             :    */
    1653             :   void replace_child (Elem * elem, unsigned int c);
    1654             : 
    1655             :   /**
    1656             :    * Fills the vector \p family with the children of this element,
    1657             :    * recursively.  Calling this method on a twice-refined element
    1658             :    * will give you the element itself, its direct children, and their
    1659             :    * children, etc...  When the optional parameter \p reset is
    1660             :    * true, the vector will be cleared before the element and its
    1661             :    * descendants are added.
    1662             :    *
    1663             :    * The family tree only includes ancestor and active elements. To
    1664             :    * include subactive elements as well, use total_family_tree().
    1665             :    */
    1666             :   void family_tree (std::vector<const Elem *> & family,
    1667             :                     bool reset = true) const;
    1668             : 
    1669             :   /**
    1670             :    * Non-const version of function above; fills a vector of non-const pointers.
    1671             :    */
    1672             :   void family_tree (std::vector<Elem *> & family,
    1673             :                     bool reset = true);
    1674             : 
    1675             :   /**
    1676             :    * Same as the \p family_tree() member, but also adds any subactive
    1677             :    * descendants.
    1678             :    */
    1679             :   void total_family_tree (std::vector<const Elem *> & family,
    1680             :                           bool reset = true) const;
    1681             : 
    1682             :   /**
    1683             :    * Non-const version of function above; fills a vector of non-const pointers.
    1684             :    */
    1685             :   void total_family_tree (std::vector<Elem *> & family,
    1686             :                           bool reset = true);
    1687             : 
    1688             :   /**
    1689             :    * Same as the \p family_tree() member, but only adds the active
    1690             :    * children.  Can be thought of as removing all the inactive
    1691             :    * elements from the vector created by \p family_tree, but is
    1692             :    * implemented more efficiently.
    1693             :    */
    1694             :   void active_family_tree (std::vector<const Elem *> & active_family,
    1695             :                            bool reset = true) const;
    1696             : 
    1697             :   /**
    1698             :    * Non-const version of function above; fills a vector of non-const pointers.
    1699             :    */
    1700             :   void active_family_tree (std::vector<Elem *> & active_family,
    1701             :                            bool reset = true);
    1702             : 
    1703             :   /**
    1704             :    * Same as the \p family_tree() member, but only adds elements
    1705             :    * which are next to \p side.
    1706             :    */
    1707             :   void family_tree_by_side (std::vector<const Elem *> & family,
    1708             :                             unsigned int side,
    1709             :                             bool reset = true) const;
    1710             : 
    1711             :   /**
    1712             :    * Non-const version of function above; fills a vector of non-const pointers.
    1713             :    */
    1714             :   void family_tree_by_side (std::vector<Elem *> & family,
    1715             :                             unsigned int side,
    1716             :                             bool reset = true);
    1717             : 
    1718             :   /**
    1719             :    * Same as the \p total_family_tree() member, but only adds elements
    1720             :    * which are next to \p side.
    1721             :    */
    1722             :   void total_family_tree_by_side (std::vector<const Elem *> & family,
    1723             :                                   unsigned int side,
    1724             :                                   bool reset = true) const;
    1725             : 
    1726             :   /**
    1727             :    * Non-const version of function above; fills a vector of non-const pointers.
    1728             :    */
    1729             :   void total_family_tree_by_side (std::vector<Elem *> & family,
    1730             :                                   unsigned int side,
    1731             :                                   bool reset = true);
    1732             : 
    1733             :   /**
    1734             :    * Same as the \p active_family_tree() member, but only adds elements
    1735             :    * which are next to \p side.
    1736             :    */
    1737             :   void active_family_tree_by_side (std::vector<const Elem *> & family,
    1738             :                                    unsigned int side,
    1739             :                                    bool reset = true) const;
    1740             : 
    1741             :   /**
    1742             :    * Non-const version of function above; fills a vector of non-const pointers.
    1743             :    */
    1744             :   void active_family_tree_by_side (std::vector<Elem *> & family,
    1745             :                                    unsigned int side,
    1746             :                                    bool reset = true);
    1747             : 
    1748             :   /**
    1749             :    * Same as the \p family_tree() member, but only adds elements
    1750             :    * which are next to \p neighbor.
    1751             :    */
    1752             :   void family_tree_by_neighbor (std::vector<const Elem *> & family,
    1753             :                                 const Elem * neighbor,
    1754             :                                 bool reset = true) const;
    1755             : 
    1756             :   /**
    1757             :    * Non-const version of function above; fills a vector of non-const pointers.
    1758             :    */
    1759             :   void family_tree_by_neighbor (std::vector<Elem *> & family,
    1760             :                                 Elem * neighbor,
    1761             :                                 bool reset = true);
    1762             : 
    1763             :   /**
    1764             :    * Same as the \p family_tree_by_neighbor() member, but also adds
    1765             :    * any subactive descendants.
    1766             :    */
    1767             :   void total_family_tree_by_neighbor (std::vector<const Elem *> & family,
    1768             :                                       const Elem * neighbor,
    1769             :                                       bool reset = true) const;
    1770             : 
    1771             :   /**
    1772             :    * Non-const version of function above; fills a vector of non-const pointers.
    1773             :    */
    1774             :   void total_family_tree_by_neighbor (std::vector<Elem *> & family,
    1775             :                                       Elem * neighbor,
    1776             :                                       bool reset = true);
    1777             : 
    1778             :   /**
    1779             :    * Same as the \p family_tree() member, but only adds elements
    1780             :    * which are next to \p subneighbor.  Only applicable when
    1781             :    * \p this->has_neighbor(neighbor) and
    1782             :    * \p neighbor->is_ancestor(subneighbor)
    1783             :    */
    1784             :   void family_tree_by_subneighbor (std::vector<const Elem *> & family,
    1785             :                                    const Elem * neighbor,
    1786             :                                    const Elem * subneighbor,
    1787             :                                    bool reset = true) const;
    1788             : 
    1789             :   /**
    1790             :    * Non-const version of function above; fills a vector of non-const pointers.
    1791             :    */
    1792             :   void family_tree_by_subneighbor (std::vector<Elem *> & family,
    1793             :                                    Elem * neighbor,
    1794             :                                    Elem * subneighbor,
    1795             :                                    bool reset = true);
    1796             : 
    1797             :   /**
    1798             :    * Same as the \p family_tree_by_subneighbor() member, but also adds
    1799             :    * any subactive descendants.
    1800             :    */
    1801             :   void total_family_tree_by_subneighbor (std::vector<const Elem *> & family,
    1802             :                                          const Elem * neighbor,
    1803             :                                          const Elem * subneighbor,
    1804             :                                          bool reset = true) const;
    1805             : 
    1806             :   /**
    1807             :    * Non-const version of function above; fills a vector of non-const pointers.
    1808             :    */
    1809             :   void total_family_tree_by_subneighbor (std::vector<Elem *> & family,
    1810             :                                          Elem * neighbor,
    1811             :                                          Elem * subneighbor,
    1812             :                                          bool reset = true);
    1813             : 
    1814             :   /**
    1815             :    * Same as the \p active_family_tree() member, but only adds elements
    1816             :    * which are next to \p neighbor.
    1817             :    */
    1818             :   void active_family_tree_by_neighbor (std::vector<const Elem *> & family,
    1819             :                                        const Elem * neighbor,
    1820             :                                        bool reset = true) const;
    1821             : 
    1822             :   /**
    1823             :    * Non-const version of function above; fills a vector of non-const pointers.
    1824             :    */
    1825             :   void active_family_tree_by_neighbor (std::vector<Elem *> & family,
    1826             :                                        Elem * neighbor,
    1827             :                                        bool reset = true);
    1828             : 
    1829             :   /**
    1830             :    * Same as the \p active_family_tree_by_neighbor() member, but the
    1831             :    * \p neighbor here may be a topological (e.g. periodic boundary
    1832             :    * condition) neighbor, not just a local neighbor.
    1833             :    */
    1834             :   void active_family_tree_by_topological_neighbor (std::vector<const Elem *> & family,
    1835             :                                                    const Elem * neighbor,
    1836             :                                                    const MeshBase & mesh,
    1837             :                                                    const PointLocatorBase & point_locator,
    1838             :                                                    const PeriodicBoundaries * pb,
    1839             :                                                    bool reset = true) const;
    1840             : 
    1841             :   /**
    1842             :    * Non-const version of function above; fills a vector of non-const pointers.
    1843             :    */
    1844             :   void active_family_tree_by_topological_neighbor (std::vector<Elem *> & family,
    1845             :                                                    Elem * neighbor,
    1846             :                                                    const MeshBase & mesh,
    1847             :                                                    const PointLocatorBase & point_locator,
    1848             :                                                    const PeriodicBoundaries * pb,
    1849             :                                                    bool reset = true);
    1850             : 
    1851             :   /**
    1852             :    * \returns The value of the refinement flag for the element.
    1853             :    */
    1854             :   RefinementState refinement_flag () const;
    1855             : 
    1856             :   /**
    1857             :    * Sets the value of the refinement flag for the element.
    1858             :    */
    1859             :   void set_refinement_flag (const RefinementState rflag);
    1860             : 
    1861             :   /**
    1862             :    * \returns The value of the p-refinement flag for the element.
    1863             :    */
    1864             :   RefinementState p_refinement_flag () const;
    1865             : 
    1866             :   /**
    1867             :    * Sets the value of the p-refinement flag for the element.
    1868             :    */
    1869             :   void set_p_refinement_flag (const RefinementState pflag);
    1870             : 
    1871             :   /**
    1872             :    * \returns The maximum value of the p-refinement levels of
    1873             :    * an ancestor element's descendants.
    1874             :    */
    1875             :   unsigned int max_descendant_p_level () const;
    1876             : 
    1877             :   /**
    1878             :    * \returns The minimum p-refinement level of elements which are
    1879             :    * descended from this element, and which share a side with the
    1880             :    * active \p neighbor.
    1881             :    */
    1882             :   unsigned int min_p_level_by_neighbor (const Elem * neighbor,
    1883             :                                         unsigned int current_min) const;
    1884             : 
    1885             :   /**
    1886             :    * \returns The minimum new p-refinement level (i.e. after refinement
    1887             :    * and coarsening is done) of elements which are descended from this
    1888             :    * element and which share a side with the active \p neighbor.
    1889             :    */
    1890             :   unsigned int min_new_p_level_by_neighbor (const Elem * neighbor,
    1891             :                                             unsigned int current_min) const;
    1892             : 
    1893             :   /**
    1894             :    * Sets the value of the p-refinement level for the element.
    1895             :    *
    1896             :    * \note The maximum p-refinement level is currently 255.
    1897             :    */
    1898             :   void set_p_level (const unsigned int p);
    1899             : 
    1900             :   /**
    1901             :    * Sets the value of the p-refinement level for the element
    1902             :    * without altering the p-level of its ancestors
    1903             :    */
    1904             :   void hack_p_level (const unsigned int p);
    1905             : 
    1906             :   /**
    1907             :    * Sets the value of the p-refinement level for the element
    1908             :    * without altering the p-level of its ancestors; also sets the
    1909             :    * p_refinement_flag, simultaneously so that they can be safely
    1910             :    * checked for mutual consistency
    1911             :    */
    1912             :   void hack_p_level_and_refinement_flag (const unsigned int p,
    1913             :                                          RefinementState pflag);
    1914             : 
    1915             :   /**
    1916             :    * Refine the element.
    1917             :    */
    1918             :   virtual void refine (MeshRefinement & mesh_refinement);
    1919             : 
    1920             :   /**
    1921             :    * Coarsen the element.  This function is non-virtual since it is the same
    1922             :    * for all element types.
    1923             :    */
    1924             :   void coarsen ();
    1925             : 
    1926             :   /**
    1927             :    * Contract an active element, i.e. remove pointers to any
    1928             :    * subactive children.  This should only be called via
    1929             :    * MeshRefinement::contract, which will also remove subactive
    1930             :    * children from the mesh.
    1931             :    */
    1932             :   void contract ();
    1933             : 
    1934             : #endif
    1935             : 
    1936             : #ifndef NDEBUG
    1937             :   /**
    1938             :    * Checks for consistent neighbor links on this element.
    1939             :    */
    1940             :   void libmesh_assert_valid_neighbors() const;
    1941             : 
    1942             :   /**
    1943             :    * Checks for a valid id and pointers to nodes with valid ids on
    1944             :    * this element.
    1945             :    */
    1946             :   void libmesh_assert_valid_node_pointers() const;
    1947             : #endif // !NDEBUG
    1948             : 
    1949             :   /**
    1950             :    * \returns The local node index of the given point IF said node
    1951             :    * has a singular Jacobian for this element. If the given point
    1952             :    * is not a node or is a node and does not have a singular Jacobian,
    1953             :    * this will return invalid_uint.
    1954             :    *
    1955             :    * The intention is for this to be overridden in derived element
    1956             :    * classes that do have nodes that have singular Jacobians. When
    1957             :    * mapping failures are caught, we can check this to see if the
    1958             :    * failed physical point is actually a singular point and
    1959             :    * return the correct master point.
    1960             :    */
    1961           0 :   virtual unsigned int local_singular_node(const Point & /* p */, const Real /* tol */ = TOLERANCE*TOLERANCE) const
    1962           0 :   { return invalid_uint; }
    1963             : 
    1964             :   /**
    1965             :    * \returns true iff the node at the given index has a singular
    1966             :    * mapping; i.e. is the degree-4 node on a Pyramid.
    1967             :    */
    1968           0 :   virtual bool is_singular_node(unsigned int /* node_i */) const { return false; }
    1969             : 
    1970             :   /**
    1971             :    * \returns The local index of the center node on the side \p side.
    1972             :    *
    1973             :    * A center node is a node that is located at the centroid of the given side.
    1974             :    * If the given side does not have a center node, this will return invalid_uint.
    1975             :    */
    1976             :   virtual unsigned int center_node_on_side(const unsigned short side) const;
    1977             : 
    1978             : protected:
    1979             : 
    1980             :   /**
    1981             :    * The protected nested SideIter class is used to iterate over the
    1982             :    * sides of this Elem.  It is a specially-designed class since
    1983             :    * no sides are actually stored by the element.  This iterator-like
    1984             :    * class has to provide the following three operations
    1985             :    * 1) operator*
    1986             :    * 2) operator++
    1987             :    * 3) operator==
    1988             :    * The definition can be found at the end of this header file.
    1989             :    */
    1990             :   class SideIter;
    1991             : 
    1992             : public:
    1993             :   /**
    1994             :    * Useful iterator typedefs
    1995             :    */
    1996             :   typedef Predicates::multi_predicate Predicate;
    1997             : 
    1998             :   /**
    1999             :    * Data structure for iterating over sides.  Defined at the end of
    2000             :    * this header file.
    2001             :    */
    2002             :   struct side_iterator;
    2003             : 
    2004             :   /**
    2005             :    * Iterator accessor functions
    2006             :    */
    2007             :   side_iterator boundary_sides_begin();
    2008             :   side_iterator boundary_sides_end();
    2009             : 
    2010             : private:
    2011             :   /**
    2012             :    * Side iterator helper functions.  Used to replace the begin()
    2013             :    * and end() functions of the STL containers.
    2014             :    */
    2015             :   SideIter _first_side();
    2016             :   SideIter _last_side();
    2017             : 
    2018             : public:
    2019             : 
    2020             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
    2021             : 
    2022             :   /**
    2023             :    * \returns \p true if the element is an infinite element,
    2024             :    * \p false otherwise.
    2025             :    */
    2026             :   virtual bool infinite () const = 0;
    2027             : 
    2028             :   /**
    2029             :    * \returns \p true if the specified (local) node number is a
    2030             :    * "mid-edge" node on an infinite element edge.
    2031             :    *
    2032             :    * This is false for all nodes on non-infinite elements, so we won't
    2033             :    * make it pure virtual, to simplify their code.
    2034             :    */
    2035           0 :   virtual bool is_mid_infinite_edge_node(const unsigned int /* n */) const
    2036           0 :   { libmesh_assert (!this->infinite()); return false; }
    2037             : 
    2038             :   /**
    2039             :    * \returns The origin for an infinite element.
    2040             :    *
    2041             :    * Currently, all infinite elements used in a mesh share the same
    2042             :    * origin.  Override this in infinite element classes.
    2043             :    */
    2044           0 :   virtual Point origin () const { libmesh_not_implemented(); return Point(); }
    2045             : 
    2046             : #else
    2047             : 
    2048             :   static constexpr bool infinite () { return false; }
    2049             : 
    2050             : #endif
    2051             : 
    2052             :   /**
    2053             :    * \returns An Elem of type \p type wrapped in a smart pointer.
    2054             :    */
    2055             :   static std::unique_ptr<Elem> build (const ElemType type,
    2056             :                                       Elem * p=nullptr);
    2057             : 
    2058             :   /**
    2059             :    * Calls the build() method above with a nullptr parent, and
    2060             :    * additionally sets the newly-created Elem's id. This can be useful
    2061             :    * when adding pre-numbered Elems to a Mesh via add_elem() calls.
    2062             :    */
    2063             :   static std::unique_ptr<Elem> build_with_id (const ElemType type,
    2064             :                                               dof_id_type id);
    2065             : 
    2066             :   /**
    2067             :    * \returns An Elem of the same type as \p this, wrapped in a smart
    2068             :    * pointer.
    2069             :    *
    2070             :    * This is not a complete clone() method (since e.g. it does not set
    2071             :    * node pointers; the standard use case reassigns node pointers from
    2072             :    * a different mesh), but it is necessary to use this instead of
    2073             :    * build() for runtime-polymorphic elements like Polygon subtypes
    2074             :    * whose "type" depends on more than their type(), and it is useful
    2075             :    * to use this for elements whose id, unique_id, extra integers,
    2076             :    * etc. should be preserved in the near-clone.
    2077             :    */
    2078             :   virtual std::unique_ptr<Elem> disconnected_clone () const;
    2079             : 
    2080             :   /**
    2081             :    * Returns the number of independent permutations of element nodes -
    2082             :    * e.g. a cube can be reoriented to put side 0 where side N is (for
    2083             :    * 0 <= N < 6) and then rotated in one of four ways, giving 24
    2084             :    * possible permutations.
    2085             :    *
    2086             :    * Permutations which change the mapping Jacobian of an element
    2087             :    * (i.e. flipping the element) are not allowed in this definition.
    2088             :    */
    2089             :   virtual unsigned int n_permutations() const = 0;
    2090             : 
    2091             :   /**
    2092             :    * Permutes the element (by swapping node and neighbor pointers)
    2093             :    * according to the specified index.
    2094             :    *
    2095             :    * This is useful for regression testing, by making it easy to make
    2096             :    * a structured mesh behave more like an arbitrarily unstructured
    2097             :    * mesh.
    2098             :    *
    2099             :    * This is so far *only* used for regression testing, so we do
    2100             :    * not currently provide a way to permute any boundary side/edge ids
    2101             :    * along with the element permutation.
    2102             :    */
    2103             :   virtual void permute(unsigned int perm_num) = 0;
    2104             : 
    2105             :   /**
    2106             :    * Flips the element (by swapping node and neighbor pointers) to
    2107             :    * have a mapping Jacobian of opposite sign.
    2108             :    *
    2109             :    * This is useful for automatically fixing up elements that have
    2110             :    * been newly created (e.g. from extrusions) with a negative
    2111             :    * Jacobian.
    2112             :    *
    2113             :    * If \p boundary_info is not null, swap boundary side/edge ids
    2114             :    * consistently.
    2115             :    */
    2116             :   virtual void flip(BoundaryInfo * boundary_info) = 0;
    2117             : 
    2118             :   /**
    2119             :    * \returns Whether the element is flipped compared to standard
    2120             :    * libMesh (e.g. clockwise for 2D elements) node orientations.
    2121             :    *
    2122             :    * Always returns \p false if a 2D element is not in the XY plane or
    2123             :    * a 1D element is not on the X axis; user code designed to work for
    2124             :    * embedded manifolds should handle any consistent orientation, and
    2125             :    * determining whether an orientation is consistent is not a local
    2126             :    * operation.
    2127             :    */
    2128             :    virtual bool is_flipped() const = 0;
    2129             : 
    2130             :   /**
    2131             :    * Flips the element (by swapping node and neighbor pointers) to
    2132             :    * have a mapping Jacobian of opposite sign, iff we find a negative
    2133             :    * orientation.  This only fixes flipped elements; for tangled
    2134             :    * elements the only fixes possible are non-local.
    2135             :    */
    2136             :   void orient(BoundaryInfo * boundary_info);
    2137             : 
    2138             : #ifdef LIBMESH_ENABLE_AMR
    2139             : 
    2140             :   /**
    2141             :    * \returns The local node id on the parent which corresponds to node
    2142             :    * \p n of child \p c, or \p invalid_uint if no such parent
    2143             :    * node exists.
    2144             :    */
    2145             :   virtual unsigned int as_parent_node (unsigned int c,
    2146             :                                        unsigned int n) const;
    2147             : 
    2148             :   /**
    2149             :    * \returns All the pairs of nodes (indexed by local node id) which
    2150             :    * should bracket node \p n of child \p c.
    2151             :    */
    2152             :   virtual
    2153             :   const std::vector<std::pair<unsigned char, unsigned char>> &
    2154             :   parent_bracketing_nodes(unsigned int c,
    2155             :                           unsigned int n) const;
    2156             : 
    2157             :   /**
    2158             :    * \returns All the pairs of nodes (indexed by global node id) which
    2159             :    * should bracket node \p n of child \p c.
    2160             :    */
    2161             :   virtual
    2162             :   const std::vector<std::pair<dof_id_type, dof_id_type>>
    2163             :   bracketing_nodes(unsigned int c,
    2164             :                    unsigned int n) const;
    2165             : 
    2166             : 
    2167             :   /**
    2168             :    * \returns The embedding matrix entry for the requested child.
    2169             :    */
    2170             :   virtual Real embedding_matrix (const unsigned int child_num,
    2171             :                                  const unsigned int child_node_num,
    2172             :                                  const unsigned int parent_node_num) const = 0;
    2173             : 
    2174             :   /**
    2175             :    * \returns A "version number" that identifies which embedding
    2176             :    * matrix is in use.
    2177             :    *
    2178             :    * Some element types may use a different embedding matrix depending
    2179             :    * on their geometric characteristics.
    2180             :    */
    2181           0 :   virtual unsigned int embedding_matrix_version () const { return 0; }
    2182             : 
    2183             : #endif // LIBMESH_ENABLE_AMR
    2184             : 
    2185             : 
    2186             : protected:
    2187             : 
    2188             :   /**
    2189             :    * Default tolerance to use in has_affine_map().
    2190             :    */
    2191             :   static constexpr Real affine_tol = TOLERANCE*TOLERANCE;
    2192             : 
    2193             :   /**
    2194             :    * \returns A hash key computed from a single node id.
    2195             :    */
    2196             :   static dof_id_type compute_key (dof_id_type n0);
    2197             : 
    2198             :   /**
    2199             :    * \returns A hash key computed from two node ids.
    2200             :    */
    2201             :   static dof_id_type compute_key (dof_id_type n0,
    2202             :                                   dof_id_type n1);
    2203             : 
    2204             :   /**
    2205             :    * \returns A hash key computed from three node ids.
    2206             :    */
    2207             :   static dof_id_type compute_key (dof_id_type n0,
    2208             :                                   dof_id_type n1,
    2209             :                                   dof_id_type n2);
    2210             : 
    2211             :   /**
    2212             :    * \returns A hash key computed from four node ids.
    2213             :    */
    2214             :   static dof_id_type compute_key (dof_id_type n0,
    2215             :                                   dof_id_type n1,
    2216             :                                   dof_id_type n2,
    2217             :                                   dof_id_type n3);
    2218             : 
    2219             :   /**
    2220             :    * Swaps two node_ptrs
    2221             :    */
    2222    38320352 :   void swap2nodes(unsigned int n1, unsigned int n2)
    2223             :   {
    2224     4583072 :     Node * temp = this->node_ptr(n1);
    2225    40611888 :     this->set_node(n1, this->node_ptr(n2));
    2226    38320352 :     this->set_node(n2, temp);
    2227    38320352 :   }
    2228             : 
    2229             :   /**
    2230             :    * Swaps two neighbor_ptrs
    2231             :    */
    2232     9239867 :   void swap2neighbors(unsigned int n1, unsigned int n2)
    2233             :   {
    2234      883484 :     Elem * temp = this->neighbor_ptr(n1);
    2235      606374 :     this->set_neighbor(n1, this->neighbor_ptr(n2));
    2236      606374 :     this->set_neighbor(n2, temp);
    2237     9344418 :   }
    2238             : 
    2239             :   /**
    2240             :    * Swaps two sides in \p boundary_info, if it is non-null.
    2241             :    */
    2242             :   void swap2boundarysides(unsigned short s1, unsigned short s2,
    2243             :                           BoundaryInfo * boundary_info) const;
    2244             : 
    2245             :   /**
    2246             :    * Swaps two edges in \p boundary_info, if it is non-null.
    2247             :    */
    2248             :   void swap2boundaryedges(unsigned short e1, unsigned short e2,
    2249             :                           BoundaryInfo * boundary_info) const;
    2250             : 
    2251             :   /**
    2252             :    * Swaps three node_ptrs, "rotating" them.
    2253             :    */
    2254    15440326 :   void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
    2255             :   {
    2256    16395266 :     swap2nodes(n1, n2);
    2257    16395266 :     swap2nodes(n2, n3);
    2258    15440326 :   }
    2259             : 
    2260             :   /**
    2261             :    * Swaps three neighbor_ptrs, "rotating" them.
    2262             :    */
    2263     4212277 :   void swap3neighbors(unsigned int n1, unsigned int n2,
    2264             :                       unsigned int n3)
    2265             :   {
    2266     4212277 :     swap2neighbors(n1, n2);
    2267     4212277 :     swap2neighbors(n2, n3);
    2268     4212277 :   }
    2269             : 
    2270             :   /**
    2271             :    * Swaps four node_ptrs, "rotating" them.
    2272             :    */
    2273     4096402 :   void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3,
    2274             :                   unsigned int n4)
    2275             :   {
    2276     3809538 :     swap3nodes(n1, n2, n3);
    2277     4096402 :     swap2nodes(n3, n4);
    2278     4096402 :   }
    2279             : 
    2280             :   /**
    2281             :    * Swaps four neighbor_ptrs, "rotating" them.
    2282             :    */
    2283      787893 :   void swap4neighbors(unsigned int n1, unsigned int n2,
    2284             :                       unsigned int n3, unsigned int n4)
    2285             :   {
    2286      787893 :     swap3neighbors(n1, n2, n3);
    2287      787893 :     swap2neighbors(n3, n4);
    2288      787893 :   }
    2289             : 
    2290             : 
    2291             :   /**
    2292             :    * An implementation for simple (all sides equal) elements
    2293             :    */
    2294             :   template <typename Sideclass, typename Subclass>
    2295             :   std::unique_ptr<Elem>
    2296             :   simple_build_side_ptr(const unsigned int i);
    2297             : 
    2298             :   /**
    2299             :    * An implementation for simple (all sides equal) elements
    2300             :    */
    2301             :   template <typename Subclass>
    2302             :   void simple_build_side_ptr(std::unique_ptr<Elem> & side,
    2303             :                              const unsigned int i,
    2304             :                              ElemType sidetype);
    2305             : 
    2306             :   /**
    2307             :    * An implementation for simple (all sides equal) elements
    2308             :    */
    2309             :   template <typename Subclass, typename Mapclass>
    2310             :   void simple_side_ptr(std::unique_ptr<Elem> & side,
    2311             :                        const unsigned int i,
    2312             :                        ElemType sidetype);
    2313             : 
    2314             :   /**
    2315             :    * An implementation for simple (all edges equal) elements
    2316             :    */
    2317             :   template <typename Edgeclass, typename Subclass>
    2318             :   std::unique_ptr<Elem>
    2319             :   simple_build_edge_ptr(const unsigned int i);
    2320             : 
    2321             :   /**
    2322             :    * An implementation for simple (all edges equal) elements
    2323             :    */
    2324             :   template <typename Subclass>
    2325             :   void simple_build_edge_ptr(std::unique_ptr<Elem> & edge,
    2326             :                              const unsigned int i,
    2327             :                              ElemType edgetype);
    2328             : 
    2329             : 
    2330             : #ifdef LIBMESH_ENABLE_AMR
    2331             : 
    2332             :   /**
    2333             :    * Elem subclasses which don't do their own bracketing node
    2334             :    * calculations will need to supply a static cache, since the
    2335             :    * default calculation is slow.
    2336             :    */
    2337             :   virtual
    2338             :   std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> &
    2339           0 :   _get_bracketing_node_cache() const
    2340             :   {
    2341           0 :     static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c;
    2342           0 :     libmesh_error();
    2343             :     return c;
    2344             :   }
    2345             : 
    2346             :   /**
    2347             :    * Elem subclasses which don't do their own child-to-parent node
    2348             :    * calculations will need to supply a static cache, since the
    2349             :    * default calculation is slow.
    2350             :    */
    2351             :   virtual
    2352             :   std::vector<std::vector<std::vector<signed char>>> &
    2353           0 :   _get_parent_indices_cache() const
    2354             :   {
    2355           0 :     static std::vector<std::vector<std::vector<signed char>>> c;
    2356           0 :     libmesh_error();
    2357             :     return c;
    2358             :   }
    2359             : 
    2360             : #endif // LIBMESH_ENABLE_AMR
    2361             : 
    2362             : public:
    2363             : 
    2364             :   /**
    2365             :    * Replaces this element with \p nullptr for all of its neighbors.
    2366             :    * This is useful when deleting an element.
    2367             :    */
    2368             :   void nullify_neighbors ();
    2369             : 
    2370             : protected:
    2371             : 
    2372             :   /**
    2373             :    * Pointers to the nodes we are connected to.
    2374             :    */
    2375             :   Node ** _nodes;
    2376             : 
    2377             :   /**
    2378             :    * Pointers to this element's parent and neighbors, and for
    2379             :    * lower-dimensional elements' interior_parent.
    2380             :    */
    2381             :   Elem ** _elemlinks;
    2382             : 
    2383             : #ifdef LIBMESH_ENABLE_AMR
    2384             :   /**
    2385             :    * unique_ptr to array of this element's children.
    2386             :    *
    2387             :    * A Mesh ultimately owns the child Elems so we are not responsible
    2388             :    * for deleting them, but we are responsible for cleaning up the
    2389             :    * array allocated to hold those Elems, hence the unique_ptr.
    2390             :    */
    2391             :   std::unique_ptr<Elem *[]> _children;
    2392             : #endif
    2393             : 
    2394             :   /**
    2395             :    * The subdomain to which this element belongs.
    2396             :    */
    2397             :   subdomain_id_type _sbd_id;
    2398             : 
    2399             : #ifdef LIBMESH_ENABLE_AMR
    2400             :   /**
    2401             :    * h refinement flag. This is stored as an unsigned char
    2402             :    * to save space.
    2403             :    */
    2404             :   unsigned char _rflag;
    2405             : 
    2406             :   /**
    2407             :    * p refinement flag. This is stored as an unsigned char
    2408             :    * to save space.
    2409             :    */
    2410             :   unsigned char _pflag;
    2411             : 
    2412             :   /**
    2413             :    * p refinement level - the difference between the
    2414             :    * polynomial degree on this element and the minimum
    2415             :    * polynomial degree on the mesh.
    2416             :    * This is stored as an unsigned char to save space.
    2417             :    * In theory, these last four bytes might have
    2418             :    * been padding anyway.
    2419             :    */
    2420             :   unsigned char _p_level;
    2421             : #endif
    2422             : 
    2423             :   /**
    2424             :    * Mapping function type; currently either 0 (LAGRANGE) or 1
    2425             :    * (RATIONAL_BERNSTEIN).
    2426             :    */
    2427             :   unsigned char _map_type;
    2428             : 
    2429             :   /**
    2430             :    * Mapping function data; currently used when needed to store the
    2431             :    * RATIONAL_BERNSTEIN nodal weight data index.
    2432             :    */
    2433             :   unsigned char _map_data;
    2434             : };
    2435             : 
    2436             : 
    2437             : 
    2438             : // ------------------------------------------------------------
    2439             : // Elem helper classes
    2440             : //
    2441             : class
    2442             : Elem::NodeRefIter : public PointerToPointerIter<Node>
    2443             : {
    2444             : public:
    2445    22718754 :   NodeRefIter (Node * const * nodepp) : PointerToPointerIter<Node>(nodepp) {}
    2446             : };
    2447             : 
    2448             : 
    2449             : class
    2450             : Elem::ConstNodeRefIter : public PointerToPointerIter<const Node>
    2451             : {
    2452             : public:
    2453    17734942 :   ConstNodeRefIter (const Node * const * nodepp) : PointerToPointerIter<const Node>(nodepp) {}
    2454             : };
    2455             : 
    2456             : 
    2457             : #ifdef LIBMESH_ENABLE_AMR
    2458             : class
    2459             : Elem::ChildRefIter : public PointerToPointerIter<Elem>
    2460             : {
    2461             : public:
    2462     6914084 :   ChildRefIter (Elem * const * childpp) : PointerToPointerIter<Elem>(childpp) {}
    2463             : };
    2464             : 
    2465             : 
    2466             : class
    2467             : Elem::ConstChildRefIter : public PointerToPointerIter<const Elem>
    2468             : {
    2469             : public:
    2470     2756130 :   ConstChildRefIter (const Elem * const * childpp) : PointerToPointerIter<const Elem>(childpp) {}
    2471             : };
    2472             : 
    2473             : 
    2474             : 
    2475             : inline
    2476    64794745 : SimpleRange<Elem::ChildRefIter> Elem::child_ref_range()
    2477             : {
    2478     3457042 :   libmesh_assert(_children);
    2479    67655973 :   return {_children.get(), _children.get() + this->n_children()};
    2480             : }
    2481             : 
    2482             : 
    2483             : inline
    2484     7523089 : SimpleRange<Elem::ConstChildRefIter> Elem::child_ref_range() const
    2485             : {
    2486     1378065 :   libmesh_assert(_children);
    2487     7808784 :   return {_children.get(), _children.get() + this->n_children()};
    2488             : }
    2489             : #endif // LIBMESH_ENABLE_AMR
    2490             : 
    2491             : 
    2492             : 
    2493             : 
    2494             : // ------------------------------------------------------------
    2495             : // global Elem functions
    2496             : 
    2497             : inline
    2498           0 : std::ostream & operator << (std::ostream & os, const Elem & e)
    2499             : {
    2500           0 :   e.print_info(os);
    2501           0 :   return os;
    2502             : }
    2503             : 
    2504             : 
    2505             : // ------------------------------------------------------------
    2506             : // Elem class member functions
    2507             : inline
    2508   421158836 : Elem::Elem(const unsigned int nn,
    2509             :            const unsigned int ns,
    2510             :            Elem * p,
    2511             :            Elem ** elemlinkdata,
    2512   421158836 :            Node ** nodelinkdata) :
    2513   129199446 :   _nodes(nodelinkdata),
    2514   129199446 :   _elemlinks(elemlinkdata),
    2515   129199446 :   _sbd_id(0),
    2516             : #ifdef LIBMESH_ENABLE_AMR
    2517   129199446 :   _rflag(Elem::DO_NOTHING),
    2518   129199446 :   _pflag(Elem::DO_NOTHING),
    2519   129199446 :   _p_level(0),
    2520             : #endif
    2521   129791038 :   _map_type(p ? p->mapping_type() : 0),
    2522   450240141 :   _map_data(p ? p->mapping_data() : 0)
    2523             : {
    2524   421158836 :   this->processor_id() = DofObject::invalid_processor_id;
    2525             : 
    2526             :   // If this ever legitimately fails we need to increase max_n_nodes
    2527    37031927 :   libmesh_assert_less_equal(nn, max_n_nodes);
    2528             : 
    2529             :   // We currently only support refinement of elements into child
    2530             :   // elements of the same type.  We can't test elem->type() here,
    2531             :   // because that's virtual and we're still in the base class
    2532             :   // constructor, but we can at least usually verify constency with
    2533             :   // the arguments we were handed.
    2534             : #ifndef NDEBUG
    2535    37031927 :   if (p && !p->runtime_topology())
    2536             :     {
    2537      294636 :       libmesh_assert_equal_to(nn, p->n_nodes());
    2538      294636 :       libmesh_assert_equal_to(ns, p->n_sides());
    2539             :     }
    2540             : #endif
    2541             : 
    2542             :   // Initialize the nodes data structure if we're given a pointer to
    2543             :   // memory for it.
    2544   421158836 :   if (_nodes)
    2545             :     {
    2546  1892624904 :       for (unsigned int n=0; n<nn; n++)
    2547  1471663510 :         _nodes[n] = nullptr;
    2548             :     }
    2549             : 
    2550             :   // Initialize the neighbors/parent data structure
    2551             :   // _elemlinks = new Elem *[ns+1];
    2552             : 
    2553             :   // Initialize the elements data structure if we're given a pointer
    2554             :   // to memory for it.  If we *weren't* given memory for it, e.g.
    2555             :   // because a subclass like an arbitrary Polygon needs to
    2556             :   // heap-allocate this memory, then that subclass will have to handle
    2557             :   // this initialization too.
    2558   421158836 :   if (_elemlinks)
    2559             :     {
    2560   420978134 :       _elemlinks[0] = p;
    2561             : 
    2562  1693622618 :       for (unsigned int n=1; n<ns+1; n++)
    2563  1272644484 :         _elemlinks[n] = nullptr;
    2564             : 
    2565             :       // Optionally initialize data from the parent
    2566   420978134 :       if (this->parent())
    2567             :         {
    2568    29081305 :           this->subdomain_id() = this->parent()->subdomain_id();
    2569    29081305 :           this->processor_id() = this->parent()->processor_id();
    2570    29081305 :           _map_type = this->parent()->_map_type;
    2571    29081305 :           _map_data = this->parent()->_map_data;
    2572             : 
    2573             : #ifdef LIBMESH_ENABLE_AMR
    2574    29378261 :           this->set_p_level(this->parent()->p_level());
    2575             : #endif
    2576             :         }
    2577             :     }
    2578   421158836 : }
    2579             : 
    2580             : 
    2581             : 
    2582             : inline
    2583  3450264285 : const Point & Elem::point (const unsigned int i) const
    2584             : {
    2585  3450264285 :   libmesh_assert_less (i, this->n_nodes());
    2586  3450264285 :   libmesh_assert(_nodes[i]);
    2587  3450264285 :   libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
    2588             : 
    2589 51723664418 :   return *_nodes[i];
    2590             : }
    2591             : 
    2592             : 
    2593             : 
    2594             : inline
    2595     2871960 : Point & Elem::point (const unsigned int i)
    2596             : {
    2597     2871960 :   libmesh_assert_less (i, this->n_nodes());
    2598             : 
    2599   186857721 :   return *_nodes[i];
    2600             : }
    2601             : 
    2602             : 
    2603             : 
    2604             : inline
    2605    91543484 : dof_id_type Elem::node_id (const unsigned int i) const
    2606             : {
    2607    91543484 :   libmesh_assert_less (i, this->n_nodes());
    2608    91543484 :   libmesh_assert(_nodes[i]);
    2609    91543484 :   libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
    2610             : 
    2611  1028299035 :   return _nodes[i]->id();
    2612             : }
    2613             : 
    2614             : 
    2615             : 
    2616             : inline
    2617     1222789 : unsigned int Elem::local_node (const dof_id_type i) const
    2618             : {
    2619     5593887 :   for (auto n : make_range(this->n_nodes()))
    2620     5593887 :     if (this->node_id(n) == i)
    2621        2328 :       return n;
    2622             : 
    2623           0 :   return libMesh::invalid_uint;
    2624             : }
    2625             : 
    2626             : 
    2627             : 
    2628             : inline
    2629    25176463 : const Node * const * Elem::get_nodes () const
    2630             : {
    2631   137807499 :   return _nodes;
    2632             : }
    2633             : 
    2634             : 
    2635             : 
    2636             : inline
    2637   115429943 : const Node * Elem::node_ptr (const unsigned int i) const
    2638             : {
    2639   115429943 :   libmesh_assert_less (i, this->n_nodes());
    2640   115429943 :   libmesh_assert(_nodes[i]);
    2641             : 
    2642 26622261383 :   return _nodes[i];
    2643             : }
    2644             : 
    2645             : 
    2646             : 
    2647             : inline
    2648   128485725 : Node * Elem::node_ptr (const unsigned int i)
    2649             : {
    2650   128485725 :   libmesh_assert_less (i, this->n_nodes());
    2651   128485725 :   libmesh_assert(_nodes[i]);
    2652             : 
    2653  1540495236 :   return _nodes[i];
    2654             : }
    2655             : 
    2656             : 
    2657             : 
    2658             : inline
    2659    19913078 : const Node & Elem::node_ref (const unsigned int i) const
    2660             : {
    2661   187882329 :   return *this->node_ptr(i);
    2662             : }
    2663             : 
    2664             : 
    2665             : 
    2666             : inline
    2667    25707084 : Node & Elem::node_ref (const unsigned int i)
    2668             : {
    2669    54200604 :   return *this->node_ptr(i);
    2670             : }
    2671             : 
    2672             : 
    2673             : 
    2674             : inline
    2675     1205076 : unsigned int Elem::get_node_index (const Node * node_ptr) const
    2676             : {
    2677     3807249 :   for (auto n : make_range(this->n_nodes()))
    2678     3784913 :     if (this->_nodes[n] == node_ptr)
    2679      161381 :       return n;
    2680             : 
    2681           0 :   return libMesh::invalid_uint;
    2682             : }
    2683             : 
    2684             : 
    2685             : 
    2686             : #ifdef LIBMESH_ENABLE_DEPRECATED
    2687             : inline
    2688           0 : Node * & Elem::set_node (const unsigned int i)
    2689             : {
    2690           0 :   libmesh_assert_less (i, this->n_nodes());
    2691             : 
    2692             :   libmesh_deprecated();
    2693             : 
    2694           0 :   return _nodes[i];
    2695             : }
    2696             : #endif // LIBMESH_ENABLE_DEPRECATED
    2697             : 
    2698             : 
    2699             : 
    2700             : inline
    2701  3196643086 : void Elem::set_node (const unsigned int i,
    2702             :                      Node * node)
    2703             : {
    2704      177702 :   libmesh_assert_less (i, this->n_nodes());
    2705             : 
    2706  3663802868 :   _nodes[i] = node;
    2707  2879145168 : }
    2708             : 
    2709             : 
    2710             : 
    2711             : inline
    2712    59594745 : subdomain_id_type Elem::subdomain_id () const
    2713             : {
    2714   561896835 :   return _sbd_id;
    2715             : }
    2716             : 
    2717             : 
    2718             : 
    2719             : inline
    2720    44138193 : subdomain_id_type & Elem::subdomain_id ()
    2721             : {
    2722   123027325 :   return _sbd_id;
    2723             : }
    2724             : 
    2725             : 
    2726             : 
    2727             : inline
    2728           0 : bool Elem::operator != (const Elem & rhs) const
    2729             : {
    2730       25044 :   return !(*this == rhs);
    2731             : }
    2732             : 
    2733             : 
    2734             : 
    2735             : inline
    2736   103788850 : const Elem * Elem::neighbor_ptr (unsigned int i) const
    2737             : {
    2738   103788850 :   libmesh_assert_less (i, this->n_neighbors());
    2739             : 
    2740   524458496 :   return _elemlinks[i+1];
    2741             : }
    2742             : 
    2743             : 
    2744             : 
    2745             : inline
    2746    18312503 : Elem * Elem::neighbor_ptr (unsigned int i)
    2747             : {
    2748    18312503 :   libmesh_assert_less (i, this->n_neighbors());
    2749             : 
    2750  1546655375 :   return _elemlinks[i+1];
    2751             : }
    2752             : 
    2753             : 
    2754             : 
    2755             : inline
    2756     9565410 : void Elem::set_neighbor (const unsigned int i, Elem * n)
    2757             : {
    2758     9565410 :   libmesh_assert_less (i, this->n_neighbors());
    2759             : 
    2760   594430303 :   _elemlinks[i+1] = n;
    2761   716783901 : }
    2762             : 
    2763             : 
    2764             : 
    2765             : inline
    2766    95095364 : bool Elem::has_neighbor (const Elem * elem) const
    2767             : {
    2768   284837227 :   for (auto n : this->neighbor_ptr_range())
    2769   273199057 :     if (n == elem)
    2770    83813731 :       return true;
    2771             : 
    2772    11281633 :   return false;
    2773             : }
    2774             : 
    2775             : 
    2776             : 
    2777             : inline
    2778             : Elem * Elem::child_neighbor (Elem * elem)
    2779             : {
    2780             :   for (auto n : elem->neighbor_ptr_range())
    2781             :     if (n && n->parent() == this)
    2782             :       return n;
    2783             : 
    2784             :   return nullptr;
    2785             : }
    2786             : 
    2787             : 
    2788             : 
    2789             : inline
    2790             : const Elem * Elem::child_neighbor (const Elem * elem) const
    2791             : {
    2792             :   for (auto n : elem->neighbor_ptr_range())
    2793             :     if (n && n->parent() == this)
    2794             :       return n;
    2795             : 
    2796             :   return nullptr;
    2797             : }
    2798             : 
    2799             : 
    2800             : 
    2801             : inline
    2802             : SimpleRange<Elem::NodeRefIter>
    2803   215417828 : Elem::node_ref_range()
    2804             : {
    2805   225344654 :   return {_nodes, _nodes+this->n_nodes()};
    2806             : }
    2807             : 
    2808             : 
    2809             : 
    2810             : inline
    2811             : SimpleRange<Elem::ConstNodeRefIter>
    2812   285332006 : Elem::node_ref_range() const
    2813             : {
    2814   303859934 :   return {_nodes, _nodes+this->n_nodes()};
    2815             : }
    2816             : 
    2817             : 
    2818             : 
    2819             : inline
    2820             : IntRange<unsigned short>
    2821    40284722 : Elem::node_index_range() const
    2822             : {
    2823   596744454 :   return {0, cast_int<unsigned short>(this->n_nodes())};
    2824             : }
    2825             : 
    2826             : 
    2827             : 
    2828             : inline
    2829             : IntRange<unsigned short>
    2830      384081 : Elem::edge_index_range() const
    2831             : {
    2832    54871294 :   return {0, cast_int<unsigned short>(this->n_edges())};
    2833             : }
    2834             : 
    2835             : 
    2836             : 
    2837             : inline
    2838             : IntRange<unsigned short>
    2839      294188 : Elem::face_index_range() const
    2840             : {
    2841     3902256 :   return {0, cast_int<unsigned short>(this->n_faces())};
    2842             : }
    2843             : 
    2844             : 
    2845             : 
    2846             : inline
    2847             : IntRange<unsigned short>
    2848     8739480 : Elem::side_index_range() const
    2849             : {
    2850   406883180 :   return {0, cast_int<unsigned short>(this->n_sides())};
    2851             : }
    2852             : 
    2853             : 
    2854             : 
    2855             : 
    2856             : inline
    2857             : std::unique_ptr<const Elem> Elem::side_ptr (unsigned int i) const
    2858             : {
    2859             :   // Call the non-const version of this function, return the result as
    2860             :   // a std::unique_ptr<const Elem>.
    2861             :   Elem * me = const_cast<Elem *>(this);
    2862             :   return me->side_ptr(i);
    2863             : }
    2864             : 
    2865             : 
    2866             : 
    2867             : inline
    2868             : void
    2869       15904 : Elem::side_ptr (std::unique_ptr<const Elem> & elem,
    2870             :                 const unsigned int i) const
    2871             : {
    2872             :   // Hand off to the non-const version of this function
    2873         448 :   Elem * me = const_cast<Elem *>(this);
    2874         896 :   std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
    2875       15904 :   me->side_ptr(e, i);
    2876       15456 :   elem = std::move(e);
    2877       15904 : }
    2878             : 
    2879             : 
    2880             : 
    2881             : inline
    2882             : std::unique_ptr<const Elem>
    2883   111692887 : Elem::build_side_ptr (const unsigned int i) const
    2884             : {
    2885             :   // Call the non-const version of this function, return the result as
    2886             :   // a std::unique_ptr<const Elem>.
    2887     2809431 :   Elem * me = const_cast<Elem *>(this);
    2888   122148492 :   return me->build_side_ptr(i);
    2889             : }
    2890             : 
    2891             : 
    2892             : 
    2893             : inline
    2894             : void
    2895    41316343 : Elem::build_side_ptr (std::unique_ptr<const Elem> & elem,
    2896             :                       const unsigned int i) const
    2897             : {
    2898             :   // Hand off to the non-const version of this function
    2899      469918 :   Elem * me = const_cast<Elem *>(this);
    2900      939836 :   std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
    2901    41316343 :   me->build_side_ptr(e, i);
    2902    40177014 :   elem = std::move(e);
    2903    41316343 : }
    2904             : 
    2905             : 
    2906             : 
    2907             : template <typename Sideclass, typename Subclass>
    2908             : inline
    2909             : std::unique_ptr<Elem>
    2910   163925201 : Elem::simple_build_side_ptr (const unsigned int i)
    2911             : {
    2912    35175336 :   libmesh_assert_less (i, this->n_sides());
    2913             : 
    2914   163925201 :   std::unique_ptr<Elem> face = std::make_unique<Sideclass>();
    2915  1263240416 :   for (auto n : face->node_index_range())
    2916  1099315215 :     face->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
    2917             : 
    2918   163925201 :   face->set_interior_parent(this);
    2919   152582501 :   face->inherit_data_from(*this);
    2920             : 
    2921   163925201 :   return face;
    2922           0 : }
    2923             : 
    2924             : 
    2925             : 
    2926             : template <typename Subclass>
    2927             : inline
    2928             : void
    2929    40206224 : Elem::simple_build_side_ptr (std::unique_ptr<Elem> & side,
    2930             :                              const unsigned int i,
    2931             :                              ElemType sidetype)
    2932             : {
    2933     1194708 :   libmesh_assert_less (i, this->n_sides());
    2934             : 
    2935    40206224 :   if (!side.get() || side->type() != sidetype)
    2936             :     {
    2937      172603 :       Subclass & real_me = cast_ref<Subclass&>(*this);
    2938     1567045 :       side = real_me.Subclass::build_side_ptr(i);
    2939             :     }
    2940             :   else
    2941             :     {
    2942    39336400 :       side->set_interior_parent(this);
    2943    38314338 :       side->inherit_data_from(*this);
    2944   283770456 :       for (auto n : side->node_index_range())
    2945   244434056 :         side->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
    2946             :     }
    2947    40206224 : }
    2948             : 
    2949             : 
    2950             : 
    2951             : template <typename Subclass, typename Mapclass>
    2952             : inline
    2953             : void
    2954   251338802 : Elem::simple_side_ptr (std::unique_ptr<Elem> & side,
    2955             :                        const unsigned int i,
    2956             :                        ElemType sidetype)
    2957             : {
    2958     4969240 :   libmesh_assert_less (i, this->n_sides());
    2959             : 
    2960   251338802 :   if (!side.get() || side->type() != sidetype)
    2961             :     {
    2962       20132 :       Subclass & real_me = cast_ref<Subclass&>(*this);
    2963     1544702 :       side = real_me.Subclass::side_ptr(i);
    2964             :     }
    2965             :   else
    2966             :     {
    2967   255462909 :       side->subdomain_id() = this->subdomain_id();
    2968             : 
    2969   856234185 :       for (auto n : side->node_index_range())
    2970   605677800 :         side->set_node(n, this->node_ptr(Mapclass::side_nodes_map[i][n]));
    2971             :     }
    2972   251338802 : }
    2973             : 
    2974             : 
    2975             : 
    2976             : inline
    2977             : std::unique_ptr<const Elem>
    2978    48391692 : Elem::build_edge_ptr (const unsigned int i) const
    2979             : {
    2980             :   // Call the non-const version of this function, return the result as
    2981             :   // a std::unique_ptr<const Elem>.
    2982    28887190 :   Elem * me = const_cast<Elem *>(this);
    2983    50502293 :   return me->build_edge_ptr(i);
    2984             : }
    2985             : 
    2986             : 
    2987             : 
    2988             : inline
    2989             : void
    2990      278960 : Elem::build_edge_ptr (std::unique_ptr<const Elem> & elem,
    2991             :                       const unsigned int i) const
    2992             : {
    2993             :   // Hand off to the non-const version of this function
    2994        8180 :   Elem * me = const_cast<Elem *>(this);
    2995       16360 :   std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
    2996      278960 :   me->build_edge_ptr(e, i);
    2997      270780 :   elem = std::move(e);
    2998      278960 : }
    2999             : 
    3000             : 
    3001             : template <typename Edgeclass, typename Subclass>
    3002             : inline
    3003             : std::unique_ptr<Elem>
    3004    27897863 : Elem::simple_build_edge_ptr (const unsigned int i)
    3005             : {
    3006     9745238 :   libmesh_assert_less (i, this->n_edges());
    3007             : 
    3008    27897863 :   std::unique_ptr<Elem> edge = std::make_unique<Edgeclass>();
    3009             : 
    3010    97811846 :   for (auto n : edge->node_index_range())
    3011    69913983 :     edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
    3012             : 
    3013    27897863 :   edge->set_interior_parent(this);
    3014    26104049 :   edge->inherit_data_from(*this);
    3015             : 
    3016    27897863 :   return edge;
    3017           0 : }
    3018             : 
    3019             : 
    3020             : 
    3021             : 
    3022             : template <typename Subclass>
    3023             : inline
    3024             : void
    3025      182246 : Elem::simple_build_edge_ptr (std::unique_ptr<Elem> & edge,
    3026             :                              const unsigned int i,
    3027             :                              ElemType edgetype)
    3028             : {
    3029        6068 :   libmesh_assert_less (i, this->n_edges());
    3030             : 
    3031      182246 :   if (!edge.get() || edge->type() != edgetype)
    3032             :     {
    3033          35 :       Subclass & real_me = cast_ref<Subclass&>(*this);
    3034        1141 :       edge = real_me.Subclass::build_edge_ptr(i);
    3035             :     }
    3036             :   else
    3037             :     {
    3038      175625 :       edge->inherit_data_from(*this);
    3039      591520 :       for (auto n : edge->node_index_range())
    3040      409862 :         edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
    3041             :     }
    3042      182246 : }
    3043             : 
    3044             : 
    3045             : 
    3046             : inline
    3047          39 : bool Elem::on_boundary () const
    3048             : {
    3049             :   // By convention, the element is on the boundary
    3050             :   // if it has a nullptr neighbor.
    3051         351 :   return this->has_neighbor(nullptr);
    3052             : }
    3053             : 
    3054             : 
    3055             : 
    3056             : inline
    3057   164845419 : unsigned int Elem::which_neighbor_am_i (const Elem * e) const
    3058             : {
    3059     8649539 :   libmesh_assert(e);
    3060             : 
    3061     8649539 :   const Elem * eparent = e;
    3062             : 
    3063   165790463 :   while (eparent->level() > this->level())
    3064             :     {
    3065      339060 :       eparent = eparent->parent();
    3066      328992 :       libmesh_assert(eparent);
    3067             :     }
    3068             : 
    3069   436909466 :   for (auto s : make_range(this->n_sides()))
    3070   436902019 :     if (this->neighbor_ptr(s) == eparent)
    3071     8649539 :       return s;
    3072             : 
    3073           0 :   return libMesh::invalid_uint;
    3074             : }
    3075             : 
    3076             : 
    3077             : 
    3078             : inline
    3079   180306759 : bool Elem::active() const
    3080             : {
    3081             : #ifdef LIBMESH_ENABLE_AMR
    3082  4336217484 :   if ((this->refinement_flag() == INACTIVE) ||
    3083   124224546 :       (this->refinement_flag() == COARSEN_INACTIVE))
    3084    56208351 :     return false;
    3085             :   else
    3086   124098408 :     return true;
    3087             : #else
    3088             :   return true;
    3089             : #endif
    3090             : }
    3091             : 
    3092             : 
    3093             : 
    3094             : 
    3095             : 
    3096             : inline
    3097   998681875 : bool Elem::subactive() const
    3098             : {
    3099             : #ifdef LIBMESH_ENABLE_AMR
    3100    48608045 :   if (this->active())
    3101    35480098 :     return false;
    3102    13127947 :   if (!this->has_children())
    3103     3944800 :     return true;
    3104   288314442 :   for (const Elem * my_ancestor = this->parent();
    3105   824676431 :        my_ancestor != nullptr;
    3106    30754775 :        my_ancestor = my_ancestor->parent())
    3107    26663537 :     if (my_ancestor->active())
    3108       10516 :       return true;
    3109             : #endif
    3110             : 
    3111     9172631 :   return false;
    3112             : }
    3113             : 
    3114             : 
    3115             : 
    3116             : inline
    3117    49527448 : bool Elem::has_children() const
    3118             : {
    3119             : #ifdef LIBMESH_ENABLE_AMR
    3120   879240054 :   if (!_children)
    3121     9829996 :     return false;
    3122             :   else
    3123    39697452 :     return true;
    3124             : #else
    3125             :   return false;
    3126             : #endif
    3127             : }
    3128             : 
    3129             : 
    3130             : inline
    3131             : bool Elem::has_ancestor_children() const
    3132             : {
    3133             : #ifdef LIBMESH_ENABLE_AMR
    3134             :   if (!_children)
    3135             :     return false;
    3136             :   else
    3137             :     for (auto & c : child_ref_range())
    3138             :       if (c.has_children())
    3139             :         return true;
    3140             : #endif
    3141             :   return false;
    3142             : }
    3143             : 
    3144             : 
    3145             : 
    3146             : inline
    3147        1630 : bool Elem::is_ancestor_of(const Elem *
    3148             : #ifdef LIBMESH_ENABLE_AMR
    3149             :                           descendant
    3150             : #endif
    3151             :                           ) const
    3152             : {
    3153             : #ifdef LIBMESH_ENABLE_AMR
    3154        1630 :   const Elem * e = descendant;
    3155       12722 :   while (e)
    3156             :     {
    3157       10734 :       if (this == e)
    3158        1630 :         return true;
    3159         466 :       e = e->parent();
    3160             :     }
    3161             : #endif
    3162           0 :   return false;
    3163             : }
    3164             : 
    3165             : 
    3166             : 
    3167             : inline
    3168  1248842646 : const Elem * Elem::parent () const
    3169             : {
    3170  2673249419 :   return _elemlinks[0];
    3171             : }
    3172             : 
    3173             : 
    3174             : 
    3175             : inline
    3176    79976777 : Elem * Elem::parent ()
    3177             : {
    3178   903497148 :   return _elemlinks[0];
    3179             : }
    3180             : 
    3181             : 
    3182             : 
    3183             : inline
    3184      347838 : void Elem::set_parent (Elem * p)
    3185             : {
    3186             :   // We no longer support using parent() as interior_parent()
    3187      347838 :   libmesh_assert_equal_to(this->dim(), p ? p->dim() : this->dim());
    3188    10134273 :   _elemlinks[0] = p;
    3189      530693 : }
    3190             : 
    3191             : 
    3192             : 
    3193             : inline
    3194      802236 : const Elem * Elem::top_parent () const
    3195             : {
    3196      802236 :   const Elem * tp = this;
    3197             : 
    3198             :   // Keep getting the element's parent
    3199             :   // until that parent is at level-0
    3200     4324852 :   while (tp->parent() != nullptr)
    3201     1999768 :     tp = tp->parent();
    3202             : 
    3203      802236 :   libmesh_assert(tp);
    3204      802236 :   libmesh_assert_equal_to (tp->level(), 0);
    3205             : 
    3206      802236 :   return tp;
    3207             : }
    3208             : 
    3209             : 
    3210             : 
    3211             : inline
    3212  8348818996 : unsigned int Elem::level() const
    3213             : {
    3214             : #ifdef LIBMESH_ENABLE_AMR
    3215             : 
    3216             :   // if I don't have a parent I was
    3217             :   // created directly from file
    3218             :   // or by the user, so I am a
    3219             :   // level-0 element
    3220 22537671582 :   if (this->parent() == nullptr)
    3221   111447917 :     return 0;
    3222             : 
    3223             :   // if the parent and this element are of different
    3224             :   // dimensionality we are at the same level as
    3225             :   // the parent (e.g. we are the 2D side of a
    3226             :   // 3D element)
    3227 14511823191 :   if (this->dim() != this->parent()->dim())
    3228           0 :     return this->parent()->level();
    3229             : 
    3230             :   // otherwise we are at a level one
    3231             :   // higher than our parent
    3232 14644668637 :   return (this->parent()->level() + 1);
    3233             : 
    3234             : #else
    3235             : 
    3236             :   // Without AMR all elements are
    3237             :   // at level 0.
    3238             :   return 0;
    3239             : 
    3240             : #endif
    3241             : }
    3242             : 
    3243             : 
    3244             : 
    3245             : inline
    3246  2336110697 : unsigned int Elem::p_level() const
    3247             : {
    3248             : #ifdef LIBMESH_ENABLE_AMR
    3249 60659587908 :   return _p_level;
    3250             : #else
    3251             :   return 0;
    3252             : #endif
    3253             : }
    3254             : 
    3255             : 
    3256             : 
    3257             : inline
    3258   112022421 : ElemMappingType Elem::mapping_type () const
    3259             : {
    3260  1594685809 :   return static_cast<ElemMappingType>(_map_type);
    3261             : }
    3262             : 
    3263             : 
    3264             : 
    3265             : inline
    3266    48323580 : void Elem::set_mapping_type(const ElemMappingType type)
    3267             : {
    3268   317253478 :   _map_type = cast_int<unsigned char>(type);
    3269    48323580 : }
    3270             : 
    3271             : 
    3272             : 
    3273             : inline
    3274    34570399 : unsigned char Elem::mapping_data () const
    3275             : {
    3276   143102444 :   return _map_data;
    3277             : }
    3278             : 
    3279             : 
    3280             : 
    3281             : inline
    3282    48323573 : void Elem::set_mapping_data(const unsigned char data)
    3283             : {
    3284   316976235 :   _map_data = data;
    3285    48602933 : }
    3286             : 
    3287             : 
    3288             : 
    3289             : #ifdef LIBMESH_ENABLE_AMR
    3290             : 
    3291             : inline
    3292           0 : const Elem * Elem::raw_child_ptr (unsigned int i) const
    3293             : {
    3294        4240 :   if (!_children)
    3295           0 :     return nullptr;
    3296             : 
    3297        2880 :   return _children[i];
    3298             : }
    3299             : 
    3300             : inline
    3301    95159599 : const Elem * Elem::child_ptr (unsigned int i) const
    3302             : {
    3303    95159599 :   libmesh_assert(_children);
    3304    95159599 :   libmesh_assert(_children[i]);
    3305             : 
    3306   354988865 :   return _children[i];
    3307             : }
    3308             : 
    3309             : inline
    3310     2247006 : Elem * Elem::child_ptr (unsigned int i)
    3311             : {
    3312     2247006 :   libmesh_assert(_children);
    3313     2247006 :   libmesh_assert(_children[i]);
    3314             : 
    3315   332767448 :   return _children[i];
    3316             : }
    3317             : 
    3318             : 
    3319             : inline
    3320      134936 : void Elem::set_child (unsigned int c, Elem * elem)
    3321             : {
    3322      134936 :   libmesh_assert (this->has_children());
    3323             : 
    3324    52379160 :   _children[c] = elem;
    3325    27131586 : }
    3326             : 
    3327             : 
    3328             : 
    3329             : inline
    3330   114410665 : unsigned int Elem::which_child_am_i (const Elem * e) const
    3331             : {
    3332    29029979 :   libmesh_assert(e);
    3333    29029979 :   libmesh_assert (this->has_children());
    3334             : 
    3335   114410665 :   unsigned int nc = this->n_children();
    3336   304940726 :   for (unsigned int c=0; c != nc; c++)
    3337   304940726 :     if (this->child_ptr(c) == e)
    3338    29029979 :       return c;
    3339             : 
    3340           0 :   libmesh_error_msg("ERROR:  which_child_am_i() was called with a non-child!");
    3341             : 
    3342             :   return libMesh::invalid_uint;
    3343             : }
    3344             : 
    3345             : 
    3346             : 
    3347             : inline
    3348   356811394 : Elem::RefinementState Elem::refinement_flag () const
    3349             : {
    3350  5831362001 :   return static_cast<RefinementState>(_rflag);
    3351             : }
    3352             : 
    3353             : 
    3354             : 
    3355             : inline
    3356     3752416 : void Elem::set_refinement_flag(RefinementState rflag)
    3357             : {
    3358    62896301 :   _rflag = cast_int<unsigned char>(rflag);
    3359    13639320 : }
    3360             : 
    3361             : 
    3362             : 
    3363             : inline
    3364    96100378 : Elem::RefinementState Elem::p_refinement_flag () const
    3365             : {
    3366   273033791 :   return static_cast<RefinementState>(_pflag);
    3367             : }
    3368             : 
    3369             : 
    3370             : 
    3371             : inline
    3372     2603723 : void Elem::set_p_refinement_flag(RefinementState pflag)
    3373             : {
    3374     2603374 :   if (this->p_level() == 0)
    3375     2598110 :     libmesh_assert_not_equal_to
    3376             :       (pflag, Elem::JUST_REFINED);
    3377             : 
    3378    41464352 :   _pflag = cast_int<unsigned char>(pflag);
    3379    28405065 : }
    3380             : 
    3381             : 
    3382             : 
    3383             : inline
    3384           0 : unsigned int Elem::max_descendant_p_level () const
    3385             : {
    3386             :   // This is undefined for subactive elements,
    3387             :   // which have no active descendants
    3388           0 :   libmesh_assert (!this->subactive());
    3389           0 :   if (this->active())
    3390           0 :     return this->p_level();
    3391             : 
    3392           0 :   unsigned int max_p_level = _p_level;
    3393           0 :   for (auto & c : child_ref_range())
    3394           0 :     max_p_level = std::max(max_p_level,
    3395           0 :                            c.max_descendant_p_level());
    3396           0 :   return max_p_level;
    3397             : }
    3398             : 
    3399             : 
    3400             : 
    3401             : inline
    3402    48259417 : void Elem::hack_p_level(unsigned int p)
    3403             : {
    3404    48259417 :   if (p == 0)
    3405    48176006 :     libmesh_assert_not_equal_to
    3406             :       (this->p_refinement_flag(), Elem::JUST_REFINED);
    3407             : 
    3408   378228615 :   _p_level = cast_int<unsigned char>(p);
    3409   309805201 : }
    3410             : 
    3411             : 
    3412             : inline
    3413        4106 : void Elem::hack_p_level_and_refinement_flag (unsigned int p,
    3414             :                                              RefinementState pflag)
    3415             : {
    3416    41965930 :   _pflag = cast_int<unsigned char>(pflag);
    3417        4106 :   this->hack_p_level(p);
    3418    41946599 : }
    3419             : 
    3420             : #endif // ifdef LIBMESH_ENABLE_AMR
    3421             : 
    3422             : 
    3423             : inline
    3424      290979 : void Elem::orient(BoundaryInfo * boundary_info)
    3425             : {
    3426      304259 :   if (this->is_flipped())
    3427      139117 :     this->flip(boundary_info);
    3428      290979 : }
    3429             : 
    3430             : 
    3431             : inline
    3432       45004 : dof_id_type Elem::compute_key (dof_id_type n0)
    3433             : {
    3434       45004 :   return n0;
    3435             : }
    3436             : 
    3437             : 
    3438             : 
    3439             : inline
    3440     6840787 : dof_id_type Elem::compute_key (dof_id_type n0,
    3441             :                                dof_id_type n1)
    3442             : {
    3443             :   // Order the two so that n0 < n1
    3444   185666412 :   if (n0 > n1) std::swap (n0, n1);
    3445             : 
    3446   185666412 :   return Utility::hashword2(n0, n1);
    3447             : }
    3448             : 
    3449             : 
    3450             : 
    3451             : inline
    3452    60259709 : dof_id_type Elem::compute_key (dof_id_type n0,
    3453             :                                dof_id_type n1,
    3454             :                                dof_id_type n2)
    3455             : {
    3456    60259709 :   std::array<dof_id_type, 3> array = {{n0, n1, n2}};
    3457     1918380 :   std::sort(array.begin(), array.end());
    3458    62178089 :   return Utility::hashword(array);
    3459             : }
    3460             : 
    3461             : 
    3462             : 
    3463             : inline
    3464    38602381 : dof_id_type Elem::compute_key (dof_id_type n0,
    3465             :                                dof_id_type n1,
    3466             :                                dof_id_type n2,
    3467             :                                dof_id_type n3)
    3468             : {
    3469    38602381 :   std::array<dof_id_type, 4> array = {{n0, n1, n2, n3}};
    3470     1082532 :   std::sort(array.begin(), array.end());
    3471    39684913 :   return Utility::hashword(array);
    3472             : }
    3473             : 
    3474             : 
    3475             : 
    3476             : inline
    3477   240512262 : void Elem::inherit_data_from (const Elem & src)
    3478             : {
    3479    62168414 :   this->set_mapping_type(src.mapping_type());
    3480    62168414 :   this->set_mapping_data(src.mapping_data());
    3481   255696616 :   this->subdomain_id() = src.subdomain_id();
    3482    62168414 :   this->processor_id(src.processor_id());
    3483             : #ifdef LIBMESH_ENABLE_AMR
    3484   255696616 :   this->set_p_level(src.p_level());
    3485             : #endif
    3486   240512262 : }
    3487             : 
    3488             : 
    3489             : 
    3490             : /**
    3491             :  * The definition of the protected nested SideIter class.
    3492             :  */
    3493           0 : class Elem::SideIter
    3494             : {
    3495             : public:
    3496             :   // Constructor with arguments.
    3497           0 :   SideIter(const unsigned int side_number,
    3498             :            Elem * parent)
    3499           0 :     : _side(),
    3500           0 :       _side_ptr(nullptr),
    3501           0 :       _parent(parent),
    3502           0 :       _side_number(side_number)
    3503           0 :   {}
    3504             : 
    3505             : 
    3506             :   // Empty constructor.
    3507             :   SideIter()
    3508             :     : _side(),
    3509             :       _side_ptr(nullptr),
    3510             :       _parent(nullptr),
    3511             :       _side_number(libMesh::invalid_uint)
    3512             :   {}
    3513             : 
    3514             : 
    3515             :   // Copy constructor
    3516           0 :   SideIter(const SideIter & other)
    3517           0 :     : _side(),
    3518           0 :       _side_ptr(nullptr),
    3519           0 :       _parent(other._parent),
    3520           0 :       _side_number(other._side_number)
    3521           0 :   {}
    3522             : 
    3523             : 
    3524             :   // op=
    3525             :   SideIter & operator=(const SideIter & other)
    3526             :   {
    3527             :     this->_parent      = other._parent;
    3528             :     this->_side_number = other._side_number;
    3529             :     return *this;
    3530             :   }
    3531             : 
    3532             :   // unary op*
    3533           0 :   Elem *& operator*() const
    3534             :   {
    3535             :     // Set the std::unique_ptr
    3536           0 :     this->_update_side_ptr();
    3537             : 
    3538             :     // Return a reference to _side_ptr
    3539           0 :     return this->_side_ptr;
    3540             :   }
    3541             : 
    3542             :   // op++
    3543           0 :   SideIter & operator++()
    3544             :   {
    3545           0 :     ++_side_number;
    3546           0 :     return *this;
    3547             :   }
    3548             : 
    3549             :   // op==  Two side iterators are equal if they have
    3550             :   // the same side number and the same parent element.
    3551           0 :   bool operator == (const SideIter & other) const
    3552             :   {
    3553           0 :     return (this->_side_number == other._side_number &&
    3554           0 :             this->_parent      == other._parent);
    3555             :   }
    3556             : 
    3557             : 
    3558             :   // Consults the parent Elem to determine if the side
    3559             :   // is a boundary side.  Note: currently side N is a
    3560             :   // boundary side if neighbor N is nullptr.  Be careful,
    3561             :   // this could possibly change in the future?
    3562           0 :   bool side_on_boundary() const
    3563             :   {
    3564           0 :     return this->_parent->neighbor_ptr(_side_number) == nullptr;
    3565             :   }
    3566             : 
    3567             : private:
    3568             :   // Update the _side pointer by building the correct side.
    3569             :   // This has to be called before dereferencing.
    3570           0 :   void _update_side_ptr() const
    3571             :   {
    3572             :     // Construct new side, store in std::unique_ptr
    3573           0 :     this->_side = this->_parent->build_side_ptr(this->_side_number);
    3574             : 
    3575             :     // Also set our internal naked pointer.  Memory is still owned
    3576             :     // by the std::unique_ptr.
    3577           0 :     this->_side_ptr = _side.get();
    3578           0 :   }
    3579             : 
    3580             :   // std::unique_ptr to the actual side, handles memory management for
    3581             :   // the sides which are created during the course of iteration.
    3582             :   mutable std::unique_ptr<Elem> _side;
    3583             : 
    3584             :   // Raw pointer needed to facilitate passing back to the user a
    3585             :   // reference to a non-temporary raw pointer in order to conform to
    3586             :   // the variant_filter_iterator interface.  It points to the same
    3587             :   // thing the std::unique_ptr "_side" above holds.  What happens if the user
    3588             :   // calls delete on the pointer passed back?  Well, this is an issue
    3589             :   // which is not addressed by the iterators in libMesh.  Basically it
    3590             :   // is a bad idea to ever call delete on an iterator from the library.
    3591             :   mutable Elem * _side_ptr;
    3592             : 
    3593             :   // Pointer to the parent Elem class which generated this iterator
    3594             :   Elem * _parent;
    3595             : 
    3596             :   // A counter variable which keeps track of the side number
    3597             :   unsigned int _side_number;
    3598             : };
    3599             : 
    3600             : 
    3601             : 
    3602             : 
    3603             : 
    3604             : 
    3605             : // Private implementation functions in the Elem class for the side iterators.
    3606             : // They have to come after the definition of the SideIter class.
    3607             : inline
    3608           0 : Elem::SideIter Elem::_first_side()
    3609             : {
    3610           0 :   return SideIter(0, this);
    3611             : }
    3612             : 
    3613             : 
    3614             : 
    3615             : inline
    3616           0 : Elem::SideIter Elem::_last_side()
    3617             : {
    3618           0 :   return SideIter(this->n_neighbors(), this);
    3619             : }
    3620             : 
    3621             : 
    3622             : 
    3623             : 
    3624             : /**
    3625             :  * The definition of the struct used for iterating over sides.
    3626             :  */
    3627             : struct
    3628             : Elem::side_iterator : variant_filter_iterator<Elem::Predicate, Elem *>
    3629             : {
    3630             :   // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
    3631             :   template <typename PredType, typename IterType>
    3632           0 :   side_iterator (const IterType & d,
    3633             :                  const IterType & e,
    3634             :                  const PredType & p ) :
    3635           0 :     variant_filter_iterator<Elem::Predicate, Elem *>(d,e,p) {}
    3636             : };
    3637             : 
    3638             : 
    3639             : 
    3640             : inline
    3641    87551786 : SimpleRange<Elem::NeighborPtrIter> Elem::neighbor_ptr_range()
    3642             : {
    3643    90886790 :   return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
    3644             : }
    3645             : 
    3646             : 
    3647             : inline
    3648   421669113 : SimpleRange<Elem::ConstNeighborPtrIter> Elem::neighbor_ptr_range() const
    3649             : {
    3650   423222503 :   return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
    3651             : }
    3652             : 
    3653             : } // namespace libMesh
    3654             : 
    3655             : 
    3656             : // Helper function for default caches in Elem subclasses
    3657             : 
    3658             : #define LIBMESH_ENABLE_TOPOLOGY_CACHES                                  \
    3659             :   virtual                                                               \
    3660             :   std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> & \
    3661             :   _get_bracketing_node_cache() const override                   \
    3662             :   {                                                                     \
    3663             :     static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c; \
    3664             :     return c;                                                           \
    3665             :   }                                                                     \
    3666             :                                                                         \
    3667             :   virtual                                                               \
    3668             :   std::vector<std::vector<std::vector<signed char>>> &                  \
    3669             :   _get_parent_indices_cache() const override                    \
    3670             :   {                                                                     \
    3671             :     static std::vector<std::vector<std::vector<signed char>>> c;        \
    3672             :     return c;                                                           \
    3673             :   }
    3674             : 
    3675             : 
    3676             : 
    3677             : 
    3678             : 
    3679             : 
    3680             : #endif // LIBMESH_ELEM_H

Generated by: LCOV version 1.14