LCOV - code coverage report
Current view: top level - include/mesh - MooseMesh.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 329044 Lines: 105 109 96.3 %
Date: 2026-08-03 21:12:22 Functions: 59 60 98.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #ifdef MOOSE_KOKKOS_ENABLED
      13             : #include "KokkosMesh.h"
      14             : #endif
      15             : 
      16             : #include "MooseObject.h"
      17             : #include "BndNode.h"
      18             : #include "BndElement.h"
      19             : #include "Restartable.h"
      20             : #include "MooseEnum.h"
      21             : #include "PerfGraphInterface.h"
      22             : #include "MooseHashing.h"
      23             : #include "MooseApp.h"
      24             : #include "FaceInfo.h"
      25             : #include "ElemInfo.h"
      26             : 
      27             : #include <memory> //std::unique_ptr
      28             : #include <filesystem>
      29             : #include <unordered_map>
      30             : #include <unordered_set>
      31             : 
      32             : // libMesh
      33             : #include "libmesh/elem_range.h"
      34             : #include "libmesh/mesh_base.h"
      35             : #include "libmesh/replicated_mesh.h"
      36             : #include "libmesh/distributed_mesh.h"
      37             : #include "libmesh/node_range.h"
      38             : #include "libmesh/nanoflann.hpp"
      39             : #include "libmesh/vector_value.h"
      40             : #include "libmesh/point.h"
      41             : #include "libmesh/partitioner.h"
      42             : 
      43             : class Assembly;
      44             : class RelationshipManager;
      45             : class MooseVariableBase;
      46             : class MooseAppCoordTransform;
      47             : class MooseUnits;
      48             : 
      49             : // libMesh forward declarations
      50             : namespace libMesh
      51             : {
      52             : class ExodusII_IO;
      53             : class QBase;
      54             : class PeriodicBoundaries;
      55             : class Partitioner;
      56             : class GhostingFunctor;
      57             : class BoundingBox;
      58             : }
      59             : // Useful typedefs
      60             : typedef libMesh::StoredRange<std::set<Node *>::iterator, Node *> SemiLocalNodeRange;
      61             : 
      62             : // List of supported geometrical elements
      63             : const std::string LIST_GEOM_ELEM = "EDGE EDGE2 EDGE3 EDGE4 "
      64             :                                    "QUAD QUAD4 QUAD8 QUAD9 "
      65             :                                    "TRI TRI3 TRI6 TRI7 "
      66             :                                    "HEX HEX8 HEX20 HEX27 "
      67             :                                    "TET TET4 TET10 TET14 "
      68             :                                    "PRISM PRISM6 PRISM15 PRISM18 "
      69             :                                    "PYRAMID PYRAMID5 PYRAMID13 PYRAMID14 "
      70             :                                    "C0POLYGON C0POLYHEDRON";
      71             : 
      72             : /**
      73             :  * Helper object for holding qp mapping info.
      74             :  */
      75             : class QpMap
      76             : {
      77             : public:
      78       59216 :   QpMap() : _distance(std::numeric_limits<Real>::max()) {}
      79             : 
      80             :   /// The qp to map from
      81             :   unsigned int _from;
      82             : 
      83             :   /// The qp to map to
      84             :   unsigned int _to;
      85             : 
      86             :   /// The distance between them
      87             :   Real _distance;
      88             : };
      89             : 
      90             : /**
      91             :  * MooseMesh wraps a libMesh::Mesh object and enhances its capabilities
      92             :  * by caching additional data and storing more state.
      93             :  */
      94             : class MooseMesh : public MooseObject, public Restartable, public PerfGraphInterface
      95             : {
      96             : public:
      97             :   /**
      98             :    * Typical "Moose-style" constructor and copy constructor.
      99             :    */
     100             :   static InputParameters validParams();
     101             : 
     102             :   /**
     103             :    * Default value for the automatically detected paired boundaries for
     104             :    * each unit dimension, in which the value for each unit dimension is
     105             :    * false (not detected).
     106             :    */
     107             :   static const std::array<bool, 3> periodic_dim_default;
     108             : 
     109             :   MooseMesh(const InputParameters & parameters);
     110             :   MooseMesh(const MooseMesh & other_mesh);
     111             :   MooseMesh() = delete;
     112             :   MooseMesh & operator=(const MooseMesh & other_mesh) = delete;
     113             : 
     114             :   virtual ~MooseMesh();
     115             : 
     116             :   // The type of libMesh::MeshBase that will be used
     117             :   enum class ParallelType
     118             :   {
     119             :     DEFAULT,
     120             :     REPLICATED,
     121             :     DISTRIBUTED
     122             :   };
     123             : 
     124             :   /**
     125             :    * Clone method.  Allocates memory you are responsible to clean up.
     126             :    */
     127             :   virtual MooseMesh & clone() const;
     128             : 
     129             :   /**
     130             :    * A safer version of the clone() method that hands back an
     131             :    * allocated object wrapped in a smart pointer. This makes it much
     132             :    * less likely that the caller will leak the memory in question.
     133             :    */
     134             :   virtual std::unique_ptr<MooseMesh> safeClone() const = 0;
     135             : 
     136             :   /**
     137             :    * Determine whether to use a distributed mesh. Should be called during construction
     138             :    */
     139             :   void determineUseDistributedMesh();
     140             : 
     141             :   /**
     142             :    * Method to construct a libMesh::MeshBase object that is normally set and used by the MooseMesh
     143             :    * object during the "init()" phase. If the parameter \p dim is not
     144             :    * provided, then its value will be taken from the input file mesh block.
     145             :    */
     146             :   std::unique_ptr<MeshBase> buildMeshBaseObject(unsigned int dim = libMesh::invalid_uint);
     147             : 
     148             :   /**
     149             :    * Shortcut method to construct a unique pointer to a libMesh mesh instance. The created
     150             :    * derived-from-MeshBase object will have its \p allow_remote_element_removal flag set to whatever
     151             :    * our value is. We will also attach any geometric \p RelationshipManagers that have been
     152             :    * requested by our simulation objects to the \p MeshBase object. If the parameter \p dim is not
     153             :    * provided, then its value will be taken from the input file mesh block.
     154             :    */
     155             :   template <typename T>
     156             :   std::unique_ptr<T> buildTypedMesh(unsigned int dim = libMesh::invalid_uint);
     157             : 
     158             :   /**
     159             :    * Method to set the mesh_base object. If this method is NOT called prior to calling init(), a
     160             :    * MeshBase object will be automatically constructed and set.
     161             :    */
     162             :   void setMeshBase(std::unique_ptr<MeshBase> mesh_base);
     163             : 
     164             :   /// returns MooseMesh partitioning options so other classes can use it
     165             :   static MooseEnum partitioning();
     166             : 
     167             :   /// returns MooseMesh element type options
     168             :   static MooseEnum elemTypes();
     169             : 
     170             :   /**
     171             :    * Initialize the Mesh object.  Most of the time this will turn around
     172             :    * and call build_mesh so the child class can build the Mesh object.
     173             :    *
     174             :    * However, during Recovery this will read the CPA file...
     175             :    */
     176             :   virtual void init();
     177             : 
     178             :   /**
     179             :    * Must be overridden by child classes.
     180             :    *
     181             :    * This is where the Mesh object is actually created and filled in.
     182             :    */
     183             :   virtual void buildMesh() = 0;
     184             : 
     185             :   /**
     186             :    * Write the mesh files needed for recovery/checkpointing.
     187             :    *
     188             :    * The base implementation writes the libMesh checkpoint mesh.
     189             :    * Derived classes may extend this to write additional backend-specific files.
     190             :    *
     191             :    * @return The additional backend-specific files written by the derived class.
     192             :    */
     193             :   virtual std::vector<std::filesystem::path>
     194             :   writeRecoveryFiles(const std::filesystem::path & file_base);
     195             : 
     196             :   /**
     197             :    * Returns MeshBase::mesh_dimension(), (not
     198             :    * MeshBase::spatial_dimension()!) of the underlying libMesh mesh
     199             :    * object.
     200             :    */
     201             :   virtual unsigned int dimension() const;
     202             : 
     203             :   /**
     204             :    * Returns MeshBase::spatial_dimension
     205             :    */
     206       54528 :   virtual unsigned int spatialDimension() const { return _mesh->spatial_dimension(); }
     207             : 
     208             :   /**
     209             :    * Returns the effective spatial dimension determined by the coordinates actually used by the
     210             :    * mesh. This means that a 1D mesh that has non-zero z or y coordinates is actually a 2D or 3D
     211             :    * mesh, respectively. Likewise a 2D mesh that has non-zero z coordinates is actually 3D mesh.
     212             :    */
     213             :   virtual unsigned int effectiveSpatialDimension() const;
     214             : 
     215             :   /**
     216             :    * Returns the maximum element dimension on the given blocks
     217             :    */
     218             :   unsigned int getBlocksMaxDimension(const std::vector<SubdomainName> & blocks) const;
     219             : 
     220             :   /**
     221             :    * Returns a vector of boundary IDs for the requested element on the
     222             :    * requested side.
     223             :    */
     224             :   std::vector<BoundaryID> getBoundaryIDs(const Elem * const elem,
     225             :                                          const unsigned short int side) const;
     226             : 
     227             :   /**
     228             :    * Returns a vector of vector of boundary IDs for the requested element on each of its sides
     229             :    */
     230             :   std::vector<std::vector<BoundaryID>> getBoundaryIDs(const Elem * const elem) const;
     231             : 
     232             :   /**
     233             :    * Returns a const pointer to a lower dimensional element that
     234             :    * corresponds to a side of a higher dimensional element. This
     235             :    * relationship is established through an internal_parent; if there is
     236             :    * no lowerDElem, nullptr is returned.
     237             :    */
     238             :   const Elem * getLowerDElem(const Elem *, unsigned short int) const;
     239             : 
     240             :   /**
     241             :    * Returns the local side ID of the interior parent aligned with the lower dimensional element.
     242             :    */
     243             :   unsigned int getHigherDSide(const Elem * elem) const;
     244             : 
     245             :   /**
     246             :    * Returns a const reference to a set of all user-specified
     247             :    * boundary IDs.  On a distributed mesh this will *only* include
     248             :    * boundary IDs which exist on local or ghosted elements; a copy and
     249             :    * a call to _communicator.set_union() will be necessary to get the
     250             :    * global ID set.
     251             :    */
     252             :   const std::set<BoundaryID> & getBoundaryIDs() const;
     253             : 
     254             :   /**
     255             :    * Calls BoundaryInfo::build_node_list()/build_side_list() and *makes separate copies* of
     256             :    * Nodes/Elems in those lists.
     257             :    *
     258             :    * Allocates memory which is cleaned up in the freeBndNodes()/freeBndElems() functions.
     259             :    */
     260             :   void buildNodeList();
     261             :   void buildBndElemList();
     262             : 
     263             :   /**
     264             :    * If not already created, creates a map from every node to all
     265             :    * elements to which they are connected.
     266             :    */
     267             :   const std::unordered_map<dof_id_type, std::vector<dof_id_type>> & nodeToElemMap();
     268             : 
     269             :   /**
     270             :    * These structs are required so that the bndNodes{Begin,End} and
     271             :    * bndElems{Begin,End} functions work...
     272             :    */
     273             :   struct bnd_node_iterator;
     274             :   struct const_bnd_node_iterator;
     275             : 
     276             :   struct bnd_elem_iterator;
     277             :   struct const_bnd_elem_iterator;
     278             : 
     279             :   /**
     280             :    * Return iterators to the beginning/end of the boundary nodes list.
     281             :    */
     282             :   virtual bnd_node_iterator bndNodesBegin();
     283             :   virtual bnd_node_iterator bndNodesEnd();
     284             : 
     285             :   /**
     286             :    * Return iterators to the beginning/end of the boundary elements list.
     287             :    */
     288             :   virtual bnd_elem_iterator bndElemsBegin();
     289             :   virtual bnd_elem_iterator bndElemsEnd();
     290             : 
     291             :   /**
     292             :    * Calls BoundaryInfo::build_node_list_from_side_list().
     293             :    */
     294             :   void buildNodeListFromSideList();
     295             : 
     296             :   /**
     297             :    * Calls BoundaryInfo::build_side_list(), returns a std::vector of
     298             :    * (elem-id, side-id, bc-id) tuples.
     299             :    */
     300             :   std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>> buildSideList();
     301             : 
     302             :   /**
     303             :    * Calls BoundaryInfo::build_active_side_list
     304             :    * @return A container of active (element, side, id) tuples.
     305             :    */
     306             :   std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>>
     307             :   buildActiveSideList() const;
     308             : 
     309             :   /**
     310             :    * Calls BoundaryInfo::side_with_boundary_id().
     311             :    */
     312             :   unsigned int sideWithBoundaryID(const Elem * const elem, const BoundaryID boundary_id) const;
     313             : 
     314             :   /**
     315             :    * Calls local_nodes_begin/end() on the underlying libMesh mesh object.
     316             :    */
     317             :   MeshBase::node_iterator localNodesBegin();
     318             :   MeshBase::node_iterator localNodesEnd();
     319             :   MeshBase::const_node_iterator localNodesBegin() const;
     320             :   MeshBase::const_node_iterator localNodesEnd() const;
     321             : 
     322             :   /**
     323             :    * Calls active_local_nodes_begin/end() on the underlying libMesh mesh object.
     324             :    */
     325             :   MeshBase::element_iterator activeLocalElementsBegin();
     326             :   const MeshBase::element_iterator activeLocalElementsEnd();
     327             :   MeshBase::const_element_iterator activeLocalElementsBegin() const;
     328             :   const MeshBase::const_element_iterator activeLocalElementsEnd() const;
     329             : 
     330             :   /**
     331             :    * Calls n_nodes/elem() on the underlying libMesh mesh object.
     332             :    */
     333             :   virtual dof_id_type nNodes() const;
     334             :   virtual dof_id_type nElem() const;
     335             : 
     336       27859 :   virtual dof_id_type nLocalNodes() const { return _mesh->n_local_nodes(); }
     337       54853 :   virtual dof_id_type nActiveElem() const { return _mesh->n_active_elem(); }
     338       39965 :   virtual dof_id_type nActiveLocalElem() const { return _mesh->n_active_local_elem(); }
     339             :   // NOTE: Expensive operation (iterates through all elements to gather subdomains)
     340       54562 :   virtual SubdomainID nSubdomains() const { return _mesh->n_subdomains(); }
     341       27685 :   virtual unsigned int nPartitions() const { return _mesh->n_partitions(); }
     342       27685 :   virtual bool skipPartitioning() const { return _mesh->skip_partitioning(); }
     343             :   virtual bool skipNoncriticalPartitioning() const;
     344             : 
     345             :   /**
     346             :    * Calls max_node/elem_id() on the underlying libMesh mesh object.
     347             :    * This may be larger than n_nodes/elem() in cases where the id
     348             :    * numbering is not contiguous.
     349             :    */
     350             :   virtual dof_id_type maxNodeId() const;
     351             :   virtual dof_id_type maxElemId() const;
     352             : 
     353             :   /**
     354             :    * Various accessors (pointers/references) for Node "i".
     355             :    *
     356             :    * If the requested node is a remote node on a distributed mesh,
     357             :    * only the query accessors are valid to call, and they return NULL.
     358             :    */
     359             :   virtual const Node & node(const dof_id_type i) const;
     360             :   virtual Node & node(const dof_id_type i);
     361             :   virtual const Node & nodeRef(const dof_id_type i) const;
     362             :   virtual Node & nodeRef(const dof_id_type i);
     363             :   virtual const Node * nodePtr(const dof_id_type i) const;
     364             :   virtual Node * nodePtr(const dof_id_type i);
     365             :   virtual const Node * queryNodePtr(const dof_id_type i) const;
     366             :   virtual Node * queryNodePtr(const dof_id_type i);
     367             : 
     368             :   /**
     369             :    * Various accessors (pointers/references) for Elem "i".
     370             :    *
     371             :    * If the requested elem is a remote element on a distributed mesh,
     372             :    * only the query accessors are valid to call, and they return NULL.
     373             :    */
     374             :   virtual Elem * elem(const dof_id_type i);
     375             :   virtual const Elem * elem(const dof_id_type i) const;
     376             :   virtual Elem * elemPtr(const dof_id_type i);
     377             :   virtual const Elem * elemPtr(const dof_id_type i) const;
     378             :   virtual Elem * queryElemPtr(const dof_id_type i);
     379             :   virtual const Elem * queryElemPtr(const dof_id_type i) const;
     380             : 
     381             :   /**
     382             :    * Setter/getter for whether the mesh is prepared
     383             :    */
     384             :   bool prepared() const;
     385             :   virtual void prepared(bool state);
     386             : 
     387             :   /**
     388             :    * If this method is called, we will call libMesh's prepare_for_use method when we
     389             :    * call Moose's prepare method. This should only be set when the mesh structure is changed
     390             :    * by MeshGenerators (i.e. Element deletion).
     391             :    */
     392             :   void needsPrepareForUse();
     393             : 
     394             :   /**
     395             :    * Declares that the MooseMesh has changed, invalidates cached data
     396             :    * and rebuilds caches.  Sets a flag so that clients of the
     397             :    * MooseMesh also know when it has changed.
     398             :    */
     399             :   void meshChanged();
     400             : 
     401             :   /**
     402             :    * Declares a callback function that is executed at the conclusion
     403             :    * of meshChanged(). Ther user can implement actions required after
     404             :    * changing the mesh here.
     405             :    **/
     406             :   virtual void onMeshChanged();
     407             : 
     408             :   /**
     409             :    * Cache information about what elements were refined and coarsened in the previous step.
     410             :    */
     411             :   void cacheChangedLists();
     412             : 
     413             :   /**
     414             :    * Return a range that is suitable for threaded execution over elements that were just refined.
     415             :    *
     416             :    * @return The _Parent_ elements that are now set to be INACTIVE.  Their _children_ are the new
     417             :    * elements.
     418             :    */
     419             :   ConstElemPointerRange * refinedElementRange() const;
     420             : 
     421             :   /**
     422             :    * Return a range that is suitable for threaded execution over elements that were just coarsened.
     423             :    * Note that these are the _Parent_ elements that are now set to be INACTIVE.  Their _children_
     424             :    * are the elements that were just removed.  Use coarsenedElementChildren() to get the element
     425             :    * IDs for the children that were just removed for a particular parent element.
     426             :    */
     427             :   ConstElemPointerRange * coarsenedElementRange() const;
     428             : 
     429             :   /**
     430             :    * Get the newly removed children element ids for an element that was just coarsened.
     431             :    *
     432             :    * @param elem Pointer to the parent element that was coarsened to.
     433             :    * @return The child element ids in Elem::child() order.
     434             :    */
     435             :   const std::vector<const Elem *> & coarsenedElementChildren(const Elem * elem) const;
     436             : 
     437             :   /**
     438             :    * Clears the "semi-local" node list and rebuilds it.  Semi-local nodes
     439             :    * consist of all nodes that belong to local and ghost elements.
     440             :    */
     441             :   void updateActiveSemiLocalNodeRange(std::set<dof_id_type> & ghosted_elems);
     442             : 
     443             :   /**
     444             :    * Returns true if the node is semi-local
     445             :    * @param node Node pointer
     446             :    * @return true is the node is semi-local, false otherwise
     447             :    */
     448             :   bool isSemiLocal(Node * const node) const;
     449             : 
     450             :   ///@{
     451             :   /**
     452             :    * Return pointers to range objects for various types of ranges
     453             :    * (local nodes, boundary elems, etc.).
     454             :    */
     455             :   const libMesh::ConstElemRange * getActiveLocalElementRange();
     456             :   libMesh::NodeRange * getActiveNodeRange();
     457             :   SemiLocalNodeRange * getActiveSemiLocalNodeRange() const;
     458             :   libMesh::ConstNodeRange * getLocalNodeRange();
     459             :   libMesh::StoredRange<MooseMesh::const_bnd_node_iterator, const BndNode *> *
     460             :   getBoundaryNodeRange();
     461             :   libMesh::StoredRange<MooseMesh::const_bnd_elem_iterator, const BndElement *> *
     462             :   getBoundaryElementRange();
     463             :   ///@}
     464             : 
     465             :   /**
     466             :    * Returns a map of boundaries to ids of elements on the boundary.
     467             :    */
     468             :   const std::unordered_map<boundary_id_type, std::unordered_set<dof_id_type>> &
     469             :   getBoundariesToElems() const;
     470             : 
     471             :   /**
     472             :    * Returns a map of boundaries to ids of elements on the boundary.
     473             :    */
     474             :   const std::unordered_map<boundary_id_type, std::unordered_set<dof_id_type>> &
     475             :   getBoundariesToActiveSemiLocalElemIds() const;
     476             : 
     477             :   /**
     478             :    * Return all ids of elements which have a side which is part of a sideset.
     479             :    * Note that boundaries are sided.
     480             :    * @param bid the id of the sideset of interest
     481             :    */
     482             :   std::unordered_set<dof_id_type> getBoundaryActiveSemiLocalElemIds(BoundaryID bid) const;
     483             : 
     484             :   /**
     485             :    * Return all ids of neighbors of elements which have a side which is part of a sideset.
     486             :    * Note that boundaries are sided, this is on the neighbor side. For the sideset side, use
     487             :    * getBoundariesActiveLocalElemIds.
     488             :    * Note that while the element is local and active, the neighbor is not guaranteed to be local,
     489             :    * it could be ghosted.
     490             :    * Note that if the neighbor is not ghosted, is a remote_elem, then it will not be included
     491             :    * @param bid the id of the sideset of interest
     492             :    */
     493             :   std::unordered_set<dof_id_type> getBoundaryActiveNeighborElemIds(BoundaryID bid) const;
     494             : 
     495             :   /**
     496             :    * Returns whether a boundary (given by its id) is not crossing through a group of blocks,
     497             :    * by which we mean that elements on both sides of the boundary are in those blocks
     498             :    * @param bid the id of the boundary of interest
     499             :    * @param blk_group the group of blocks potentially traversed
     500             :    * @return whether the boundary does not cross between the subdomains in the group
     501             :    */
     502             :   bool isBoundaryFullyExternalToSubdomains(BoundaryID bid,
     503             :                                            const std::set<SubdomainID> & blk_group) const;
     504             : 
     505             :   /**
     506             :    * Returns a read-only reference to the set of subdomains currently
     507             :    * present in the Mesh.
     508             :    */
     509             :   const std::set<SubdomainID> & meshSubdomains() const;
     510             : 
     511             :   /**
     512             :    * Returns a read-only reference to the set of boundary IDs currently
     513             :    * present in the Mesh.
     514             :    */
     515             :   const std::set<BoundaryID> & meshBoundaryIds() const;
     516             : 
     517             :   /**
     518             :    * Returns a read-only reference to the set of sidesets currently
     519             :    * present in the Mesh.
     520             :    */
     521             :   const std::set<BoundaryID> & meshSidesetIds() const;
     522             : 
     523             :   /**
     524             :    * Returns a read-only reference to the set of nodesets currently
     525             :    * present in the Mesh.
     526             :    */
     527             :   const std::set<BoundaryID> & meshNodesetIds() const;
     528             : 
     529             :   /**
     530             :    * Sets the mapping between BoundaryID and normal vector
     531             :    * Is called by AddAllSideSetsByNormals
     532             :    */
     533             :   void setBoundaryToNormalMap(std::unique_ptr<std::map<BoundaryID, RealVectorValue>> boundary_map);
     534             : 
     535             :   // DEPRECATED METHOD
     536             :   void setBoundaryToNormalMap(std::map<BoundaryID, RealVectorValue> * boundary_map);
     537             : 
     538             :   /**
     539             :    * Sets the set of BoundaryIDs
     540             :    * Is called by AddAllSideSetsByNormals
     541             :    */
     542             :   void setMeshBoundaryIDs(std::set<BoundaryID> boundary_IDs);
     543             : 
     544             :   /**
     545             :    * Returns the normal vector associated with a given BoundaryID.
     546             :    * It's only valid to call this when AddAllSideSetsByNormals is active.
     547             :    */
     548             :   const RealVectorValue & getNormalByBoundaryID(BoundaryID id) const;
     549             : 
     550             :   /**
     551             :    * Calls prepare_for_use() if the underlying MeshBase object isn't prepared, then communicates
     552             :    * various boundary information on parallel meshes. Also calls update() internally. Instead of
     553             :    * calling \p prepare_for_use on the currently held \p MeshBase object, a \p mesh_to_clone can be
     554             :    * provided. If it is provided (e.g. this method is given a non-null argument), then \p _mesh will
     555             :    * be assigned a clone of the \p mesh_to_clone. The provided \p mesh_to_clone must already be
     556             :    * prepared
     557             :    * @param mesh_to_clone If nonnull, we will clone this mesh instead of preparing our current one
     558             :    * @return Whether the libMesh mesh was prepared. This should really only be relevant in MOOSE
     559             :    * framework contexts where we need to make a decision about what to do with the displaced mesh.
     560             :    * If the reference mesh base object has \p complete_preparation() called (e.g. this method
     561             :    * returns \p true when called for the reference mesh), then we must pass the reference mesh base
     562             :    * object into this method when we call this for the displaced mesh. This is because the displaced
     563             :    * mesh \emph must be an exact clone of the reference mesh. We have seen that \p
     564             :    * complete_preparation() called on two previously identical meshes can result in two different
     565             :    * meshes even with Metis partitioning
     566             :    */
     567             :   bool prepare(const MeshBase * mesh_to_clone);
     568             : 
     569             :   /**
     570             :    * Calls buildNodeListFromSideList(), buildNodeList(), and buildBndElemList().
     571             :    */
     572             :   void update();
     573             : 
     574             :   /**
     575             :    * Returns the level of uniform refinement requested (zero if AMR is disabled).
     576             :    */
     577             :   unsigned int uniformRefineLevel() const;
     578             : 
     579             :   /**
     580             :    * Set uniform refinement level
     581             :    */
     582             :   void setUniformRefineLevel(unsigned int, bool deletion = true);
     583             : 
     584             :   /**
     585             :    * Return a flag indicating whether or not we should skip remote deletion
     586             :    * and repartition after uniform refinements. If the flag is true, uniform
     587             :    * refinements will run more efficiently, but at the same time, there might
     588             :    * be extra ghosting elements. The number of layers of additional ghosting
     589             :    * elements depends on the number of uniform refinement levels.  This flag
     590             :    * should be used only when you have a "fine enough" coarse mesh and want
     591             :    * to refine the mesh by a few levels. Otherwise, it might introduce an
     592             :    * unbalanced workload and too large ghosting domain.
     593             :    */
     594             :   bool skipDeletionRepartitionAfterRefine() const;
     595             : 
     596             :   /**
     597             :    * Whether or not skip uniform refinements when using a pre-split mesh
     598             :    */
     599         255 :   bool skipRefineWhenUseSplit() const { return _skip_refine_when_use_split; }
     600             : 
     601             :   /**
     602             :    * This will add the boundary ids to be ghosted to this processor
     603             :    */
     604             :   void addGhostedBoundary(BoundaryID boundary_id);
     605             : 
     606             :   /**
     607             :    * This sets the inflation amount for the bounding box for each partition for use in
     608             :    * ghosting boundaries
     609             :    */
     610             :   void setGhostedBoundaryInflation(const std::vector<Real> & inflation);
     611             : 
     612             :   /**
     613             :    * Return a writable reference to the set of ghosted boundary IDs.
     614             :    */
     615             :   const std::set<unsigned int> & getGhostedBoundaries() const;
     616             : 
     617             :   /**
     618             :    * Return a writable reference to the _ghosted_boundaries_inflation vector.
     619             :    */
     620             :   const std::vector<Real> & getGhostedBoundaryInflation() const;
     621             : 
     622             :   /**
     623             :    * Actually do the ghosting of boundaries that need to be ghosted to this processor.
     624             :    */
     625             :   void ghostGhostedBoundaries();
     626             : 
     627             :   /**
     628             :    * Whether or not we want to ghost ghosted boundaries
     629             :    */
     630         779 :   void needGhostGhostedBoundaries(bool needghost) { _need_ghost_ghosted_boundaries = needghost; }
     631             : 
     632             :   /**
     633             :    * Getter for the patch_size parameter.
     634             :    */
     635             :   unsigned int getPatchSize() const;
     636             : 
     637             :   /**
     638             :    * Getter for the ghosting_patch_size parameter.
     639             :    */
     640        8658 :   unsigned int getGhostingPatchSize() const { return _ghosting_patch_size; }
     641             : 
     642             :   /**
     643             :    * Getter for the maximum leaf size parameter.
     644             :    */
     645       64084 :   unsigned int getMaxLeafSize() const { return _max_leaf_size; }
     646             : 
     647             :   /**
     648             :    * Set the patch size update strategy
     649             :    */
     650             :   void setPatchUpdateStrategy(Moose::PatchUpdateType patch_update_strategy);
     651             : 
     652             :   /**
     653             :    * Get the current patch update strategy.
     654             :    */
     655             :   const Moose::PatchUpdateType & getPatchUpdateStrategy() const;
     656             : 
     657             :   /**
     658             :    * Get a (slightly inflated) processor bounding box.
     659             :    *
     660             :    * @param inflation_multiplier This amount will be multiplied by the length of the diagonal of the
     661             :    * bounding box to find the amount to inflate the bounding box by in all directions.
     662             :    */
     663             :   libMesh::BoundingBox getInflatedProcessorBoundingBox(Real inflation_multiplier = 0.01) const;
     664             : 
     665             :   /**
     666             :    * Implicit conversion operator from MooseMesh -> libMesh::MeshBase.
     667             :    */
     668             :   operator libMesh::MeshBase &();
     669             :   operator const libMesh::MeshBase &() const;
     670             : 
     671             :   /**
     672             :    * Accessor for the underlying libMesh Mesh object.
     673             :    */
     674             :   MeshBase & getMesh();
     675             :   MeshBase & getMesh(const std::string & name);
     676             :   const MeshBase & getMesh() const;
     677             :   const MeshBase & getMesh(const std::string & name) const;
     678             :   const MeshBase * getMeshPtr() const;
     679             : 
     680             :   /**
     681             :    * Accessor for Kokkos mesh object.
     682             :    */
     683             : #ifdef MOOSE_KOKKOS_ENABLED
     684       87671 :   Moose::Kokkos::Mesh * getKokkosMesh() { return _kokkos_mesh.get(); }
     685        6072 :   const Moose::Kokkos::Mesh * getKokkosMesh() const { return _kokkos_mesh.get(); }
     686             : #endif
     687             : 
     688             :   /**
     689             :    * Calls print_info() on the underlying Mesh.
     690             :    */
     691             :   void printInfo(std::ostream & os = libMesh::out, const unsigned int verbosity = 0) const;
     692             : 
     693             :   /**
     694             :    * Return list of blocks to which the given node belongs.
     695             :    */
     696             :   const std::set<SubdomainID> & getNodeBlockIds(const Node & node) const;
     697             : 
     698             :   /**
     699             :    * Return a writable reference to a vector of node IDs that belong
     700             :    * to nodeset_id.
     701             :    */
     702             :   const std::vector<dof_id_type> & getNodeList(boundary_id_type nodeset_id) const;
     703             : 
     704             :   /**
     705             :    * Add a new node to the mesh.  If there is already a node located at the point passed
     706             :    * then the node will not be added.  In either case a reference to the node at that location
     707             :    * will be returned
     708             :    */
     709             :   const Node * addUniqueNode(const Point & p, Real tol = 1e-6);
     710             : 
     711             :   /**
     712             :    * Adds a fictitious "QuadratureNode".  This doesn't actually add it to the libMesh mesh...
     713             :    * we just keep track of these here in MooseMesh.
     714             :    *
     715             :    * QuadratureNodes are fictitious "Nodes" that are located at quadrature points.  This is useful
     716             :    * for using the geometric search system to do searches based on quadrature point locations....
     717             :    *
     718             :    * @param elem The element
     719             :    * @param side The side number on which we want to add a quadrature node
     720             :    * @param qp The number of the quadrature point
     721             :    * @param bid The boundary ID for the point to be added with
     722             :    * @param point The physical location of the point
     723             :    */
     724             :   Node * addQuadratureNode(const Elem * elem,
     725             :                            const unsigned short int side,
     726             :                            const unsigned int qp,
     727             :                            BoundaryID bid,
     728             :                            const Point & point);
     729             : 
     730             :   /**
     731             :    * Get a specified quadrature node.
     732             :    *
     733             :    * @param elem The element the quadrature point is on
     734             :    * @param side The side the quadrature point is on
     735             :    * @param qp The quadrature point number associated with the point
     736             :    */
     737             :   Node * getQuadratureNode(const Elem * elem, const unsigned short int side, const unsigned int qp);
     738             : 
     739             :   /**
     740             :    * Clear out any existing quadrature nodes.
     741             :    * Most likely called before re-adding them.
     742             :    */
     743             :   void clearQuadratureNodes();
     744             : 
     745             :   /**
     746             :    * Get the associated BoundaryID for the boundary name.
     747             :    *
     748             :    * @param boundary_name The name of the boundary.
     749             :    * @return the boundary id from the passed boundary name.
     750             :    */
     751             :   BoundaryID getBoundaryID(const BoundaryName & boundary_name) const;
     752             : 
     753             :   /**
     754             :    * Get the associated BoundaryID for the boundary names that are passed in.
     755             :    *
     756             :    * @param boundary_name The names of the boundaries.
     757             :    * @return the boundary ids from the passed boundary names.
     758             :    */
     759             :   std::vector<BoundaryID> getBoundaryIDs(const std::vector<BoundaryName> & boundary_name,
     760             :                                          bool generate_unknown = false) const;
     761             : 
     762             :   /**
     763             :    * Get the associated subdomain ID for the subdomain name.
     764             :    *
     765             :    * @param subdomain_name The name of the subdomain
     766             :    * @return The subdomain id from the passed subdomain name.
     767             :    */
     768             :   SubdomainID getSubdomainID(const SubdomainName & subdomain_name) const;
     769             : 
     770             :   /**
     771             :    * Get the associated subdomainIDs for the subdomain names that are passed in.
     772             :    *
     773             :    * @param subdomain_names The names of the subdomains
     774             :    * @return The subdomain ids from the passed subdomain names.
     775             :    */
     776             :   std::vector<SubdomainID>
     777             :   getSubdomainIDs(const std::vector<SubdomainName> & subdomain_names) const;
     778             :   std::set<SubdomainID> getSubdomainIDs(const std::set<SubdomainName> & subdomain_names) const;
     779             : 
     780             :   /**
     781             :    * This method sets the name for \p subdomain_id to \p name
     782             :    */
     783             :   void setSubdomainName(SubdomainID subdomain_id, const SubdomainName & name);
     784             : 
     785             :   /**
     786             :    * This method sets the name for \p subdomain_id on the provided \p mesh to \p name
     787             :    */
     788             :   static void
     789             :   setSubdomainName(MeshBase & mesh, SubdomainID subdomain_id, const SubdomainName & name);
     790             : 
     791             :   /**
     792             :    * Return the name of a block given an id.
     793             :    */
     794             :   const std::string & getSubdomainName(SubdomainID subdomain_id) const;
     795             : 
     796             :   /**
     797             :    * Get the associated subdomainNames for the subdomain ids that are passed in.
     798             :    *
     799             :    * @param subdomain_ids The ids of the subdomains
     800             :    * @return The subdomain names from the passed subdomain ids.
     801             :    */
     802             :   std::vector<SubdomainName>
     803             :   getSubdomainNames(const std::vector<SubdomainID> & subdomain_ids) const;
     804             : 
     805             :   /**
     806             :    * This method sets the boundary name of the boundary based on the id parameter
     807             :    */
     808             :   void setBoundaryName(BoundaryID boundary_id, BoundaryName name);
     809             : 
     810             :   /**
     811             :    * Return the name of the boundary given the id.
     812             :    */
     813             :   const std::string & getBoundaryName(const BoundaryID boundary_id) const;
     814             : 
     815             :   /**
     816             :    * Return the name of the boundary given the id, if it exists. Otherwise, return
     817             :    * the id as a string.
     818             :    */
     819             :   std::string getBoundaryString(const BoundaryID boundary_id) const;
     820             : 
     821             :   /**
     822             :    * This routine builds a multimap of boundary ids to matching boundary ids across all periodic
     823             :    * boundaries
     824             :    * in the system.
     825             :    */
     826             :   void buildPeriodicNodeMap(std::multimap<dof_id_type, dof_id_type> & periodic_node_map,
     827             :                             unsigned int var_number,
     828             :                             libMesh::PeriodicBoundaries * pbs) const;
     829             : 
     830             :   /**
     831             :    * This routine builds a datastructure of node ids organized by periodic boundary ids
     832             :    */
     833             :   void buildPeriodicNodeSets(std::map<BoundaryID, std::set<dof_id_type>> & periodic_node_sets,
     834             :                              unsigned int var_number,
     835             :                              libMesh::PeriodicBoundaries * pbs) const;
     836             : 
     837             :   /**
     838             :    * Returns the width of the requested dimension
     839             :    */
     840             :   Real dimensionWidth(unsigned int component) const;
     841             : 
     842             :   ///@{
     843             :   /**
     844             :    * Returns the min or max of the requested dimension respectively
     845             :    */
     846             :   virtual Real getMinInDimension(unsigned int component) const;
     847             :   virtual Real getMaxInDimension(unsigned int component) const;
     848             :   ///@}
     849             : 
     850             :   /**
     851             :    * This routine determines whether the Mesh is a regular orthogonal mesh (i.e. square in 2D, cubic
     852             :    * in 3D). If it is, then we can use a number of convenience functions when periodic boundary
     853             :    * conditions are applied.  This routine populates the _range vector which is necessary for these
     854             :    * convenience functions.
     855             :    *
     856             :    * Note:  This routine can potentially identify meshes with concave faces that still "fit" in the
     857             :    * convex hull of the corresponding regular orthogonal mesh.  This case is highly unlikely in
     858             :    * practice and if a user does this, well.... release the kicker!
     859             :    */
     860             :   bool detectOrthogonalDimRanges(Real tol = 1e-6);
     861             : 
     862             :   /**
     863             :    * For "regular orthogonal" meshes, determine if variable var_num is periodic with respect to the
     864             :    * primary and secondary BoundaryIDs, record this fact in the _periodic_dim data structure.
     865             :    */
     866             :   void addPeriodicVariable(const unsigned int sys_num,
     867             :                            const unsigned int var_num,
     868             :                            const BoundaryID primary,
     869             :                            const BoundaryID secondary);
     870             : 
     871             :   /**
     872             :    * Query the translated periodic dimension flags for the given variable on the given system.
     873             :    *
     874             :    * Query here means that it will not error if a variable isn't found to be periodic, instead
     875             :    * the default value is returned (false for each dimension)
     876             :    *
     877             :    * @param sys_num - The number of the system the variable is on
     878             :    * @param var_num - The variable number
     879             :    */
     880             :   const std::array<bool, 3> & queryPeriodicDimensions(const unsigned int sys_num,
     881             :                                                       const unsigned int var_num) const;
     882             :   /**
     883             :    * Query the translated periodic dimension flags for the given variable.\
     884             :    *
     885             :    * Query here means that it will not error if a variable isn't found to be periodic, instead
     886             :    * the default value is returned (false for each dimension)
     887             :    *
     888             :    * @param var - The variable
     889             :    */
     890             :   const std::array<bool, 3> & queryPeriodicDimensions(const MooseVariableBase & var) const;
     891             : 
     892             :   /**
     893             :    * Returns whether this generated mesh is periodic in the given dimension for the given variable
     894             :    * on the given system.
     895             :    * @param sys_num - The number of the system the variable is on
     896             :    * @param var_num - The variable number
     897             :    * @param component - An integer representing the desired component (dimension)
     898             :    */
     899             :   bool isTranslatedPeriodic(const unsigned int sys_num,
     900             :                             const unsigned int var_num,
     901             :                             const unsigned int component) const;
     902             : 
     903             :   /**
     904             :    * Returns whether this generated mesh is periodic in the given dimension for the given variable.
     905             :    * @param var - The variable
     906             :    * @param component - An integer representing the desired component (dimension)
     907             :    */
     908             :   bool isTranslatedPeriodic(const MooseVariableBase & var, const unsigned int component) const;
     909             : 
     910             :   /**
     911             :    * Returns whether this generated mesh is periodic in the given dimension for the given variable.
     912             :    *
     913             :    * Deprecated method; assumes the system number is 0. Use the method that
     914             :    * additionally takes the system number or the MooseVariableBase instead.
     915             :    *
     916             :    * @param var_num - The variable number
     917             :    * @param component - An integer representing the desired component (dimension)
     918             :    */
     919             :   bool isTranslatedPeriodic(const unsigned int var_num, const unsigned int component) const;
     920             : 
     921             :   /**
     922             :    * Returns the minimum vector between two points on the mesh taking into account
     923             :    * periodicity for the given variable on the given system.
     924             :    * @param sys_num - The number of the system the variable is on
     925             :    * @param var_num - The variable number
     926             :    * @param p, q - The points between which to compute a minimum vector
     927             :    * @return RealVectorValue - The vector pointing from p to q
     928             :    */
     929             :   RealVectorValue
     930             :   minPeriodicVector(const unsigned int sys_num, const unsigned int var_num, Point p, Point q) const;
     931             : 
     932             :   /**
     933             :    * Returns the minimum vector between two points on the mesh taking into account
     934             :    * periodicity for the given variable.
     935             :    * @param var - The variable
     936             :    * @param p, q - The points between which to compute a minimum vector
     937             :    * @return RealVectorValue - The vector pointing from p to q
     938             :    */
     939             :   RealVectorValue
     940             :   minPeriodicVector(const MooseVariableBase & var, const Point & p, const Point & q) const;
     941             : 
     942             :   /**
     943             :    * Returns the minimum vector between two points on the mesh taking into account
     944             :    * periodicity for the given variable on the given system.
     945             :    *
     946             :    * Deprecated method; assumes the system number is 0. Use the method that
     947             :    * additionally takes the system number or the MooseVariableBase instead.
     948             :    *
     949             :    * @param var_num - The variable number
     950             :    * @param p, q - The points between which to compute a minimum vector
     951             :    * @return RealVectorValue - The vector pointing from p to q
     952             :    */
     953             :   RealVectorValue
     954             :   minPeriodicVector(const unsigned int var_num, const Point & p, const Point & q) const;
     955             : 
     956             :   /**
     957             :    * Returns the distance between two points on the mesh taking into account
     958             :    * periodicity for the given variable on the given system.
     959             :    * @param sys_num - The number of the system the variable is on
     960             :    * @param var_num - The variable number
     961             :    * @param p, q - The points for which to compute a minimum distance
     962             :    * @return Real - The L2 distance between p and q
     963             :    */
     964             :   Real minPeriodicDistance(const unsigned int sys_num,
     965             :                            const unsigned int var_num,
     966             :                            const Point & p,
     967             :                            const Point & q) const;
     968             : 
     969             :   /**
     970             :    * Returns the distance between two points on the mesh taking into account
     971             :    * periodicity for the given variable.
     972             :    * @param var - The variable
     973             :    * @param p, q - The points for which to compute a minimum distance
     974             :    * @return Real - The L2 distance between p and q
     975             :    */
     976             :   Real minPeriodicDistance(const MooseVariableBase & var, const Point & p, const Point & q) const;
     977             : 
     978             :   /**
     979             :    * Returns the distance between two points on the mesh taking into account
     980             :    * periodicity for the given variable.
     981             :    *
     982             :    * Deprecated method; assumes the system number is 0. Use the method that
     983             :    * additionally takes the system number or the MooseVariableBase instead.
     984             :    *
     985             :    * @param var_num - The variable number
     986             :    * @param p, q - The points for which to compute a minimum distance
     987             :    * @return Real - The L2 distance between p and q
     988             :    */
     989             :   Real minPeriodicDistance(const unsigned int var_num, const Point & p, const Point & q) const;
     990             : 
     991             :   /**
     992             :    * This routine detects paired sidesets of a regular orthogonal mesh (.i.e. parallel sidesets
     993             :    * "across" from one and other).
     994             :    *
     995             :    * The _paired_boundary datastructure is populated with this information.
     996             :    */
     997             :   void detectPairedSidesets();
     998             : 
     999             :   /**
    1000             :    * Whether or not detectedPairedSidesets() has been called.
    1001             :    */
    1002        3045 :   bool hasDetectedPairedSidesets() const { return _paired_boundary.has_value(); }
    1003             : 
    1004             :   /**
    1005             :    * This function attempts to return the paired boundary ids for the given component.  For example,
    1006             :    * in a generated 2D mesh, passing 0 for the "x" component will return (3, 1).
    1007             :    *
    1008             :    * Must have called detectPairedSidesets() prior to using.
    1009             :    *
    1010             :    * @param component - An integer representing the desired component (dimension)
    1011             :    * @return std::pair pointer - The matching boundary pairs for the passed component
    1012             :    */
    1013             :   const std::pair<BoundaryID, BoundaryID> * getPairedBoundaryMapping(unsigned int component) const;
    1014             : 
    1015             :   /**
    1016             :    * Create the refinement and coarsening maps necessary for projection of stateful material
    1017             :    * properties when using adaptivity.
    1018             :    *
    1019             :    * @param assembly Pointer to the Assembly object for this Mesh.
    1020             :    */
    1021             :   void buildRefinementAndCoarseningMaps(Assembly * assembly);
    1022             : 
    1023             :   /**
    1024             :    * Get the refinement map for a given element type.  This will tell you what quadrature points
    1025             :    * to copy from and to for stateful material properties on newly created elements from Adaptivity.
    1026             :    *
    1027             :    * @param elem The element that represents the element type you need the refinement map for.
    1028             :    * @param parent_side The side of the parent to map (-1 if not mapping parent sides)
    1029             :    * @param child The child number (-1 if not mapping child internal sides)
    1030             :    * @param child_side The side number of the child (-1 if not mapping sides)
    1031             :    */
    1032             :   const std::vector<std::vector<QpMap>> &
    1033             :   getRefinementMap(const Elem & elem, int parent_side, int child, int child_side);
    1034             : 
    1035             :   /**
    1036             :    * Get the coarsening map for a given element type.  This will tell you what quadrature points
    1037             :    * to copy from and to for stateful material properties on newly created elements from Adaptivity.
    1038             :    *
    1039             :    * @param elem The element that represents the element type you need the coarsening map for.
    1040             :    * @param input_side The side to map
    1041             :    */
    1042             :   const std::vector<std::pair<unsigned int, QpMap>> & getCoarseningMap(const Elem & elem,
    1043             :                                                                        int input_side);
    1044             : 
    1045             :   /**
    1046             :    * Change all the boundary IDs for a given side from old_id to new_id.  If delete_prev is true,
    1047             :    * also actually remove the side with old_id from the BoundaryInfo object.
    1048             :    */
    1049             :   void
    1050             :   changeBoundaryId(const boundary_id_type old_id, const boundary_id_type new_id, bool delete_prev);
    1051             : 
    1052             :   /**
    1053             :    * Change all the boundary IDs for a given side from old_id to new_id for the given \p mesh.  If
    1054             :    * delete_prev is true, also actually remove the side with old_id from the BoundaryInfo object.
    1055             :    */
    1056             :   static void changeBoundaryId(MeshBase & mesh,
    1057             :                                const boundary_id_type old_id,
    1058             :                                const boundary_id_type new_id,
    1059             :                                bool delete_prev);
    1060             : 
    1061             :   /**
    1062             :    * Get the list of boundary ids associated with the given subdomain id.
    1063             :    *
    1064             :    * @param subdomain_id The subdomain ID you want to get the boundary ids for.
    1065             :    * @return All boundary IDs connected to elements in the give
    1066             :    */
    1067             :   const std::set<BoundaryID> & getSubdomainBoundaryIds(const SubdomainID subdomain_id) const;
    1068             : 
    1069             :   /**
    1070             :    * Get the list of boundaries that contact the given subdomain.
    1071             :    *
    1072             :    * @param subdomain_id The subdomain ID you want to get the boundary ids for.
    1073             :    * @return All boundary IDs connected to elements in the given subdomain
    1074             :    */
    1075             :   std::set<BoundaryID> getSubdomainInterfaceBoundaryIds(const SubdomainID subdomain_id) const;
    1076             : 
    1077             :   /**
    1078             :    * Get the list of subdomains associated with the given boundary.
    1079             :    *
    1080             :    * @param bid The boundary ID you want to get the subdomain IDs for.
    1081             :    * @return All subdomain IDs associated with given boundary ID
    1082             :    */
    1083             :   std::set<SubdomainID> getBoundaryConnectedBlocks(const BoundaryID bid) const;
    1084             : 
    1085             :   /**
    1086             :    * Get the list of subdomains associated with the given boundary of its secondary side.
    1087             :    *
    1088             :    * @param bid The boundary ID you want to get the subdomain IDs for.
    1089             :    * @return All subdomain IDs associated with given boundary ID
    1090             :    */
    1091             :   std::set<SubdomainID> getBoundaryConnectedSecondaryBlocks(const BoundaryID bid) const;
    1092             : 
    1093             :   /**
    1094             :    * Get the list of subdomains contacting the given boundary.
    1095             :    *
    1096             :    * @param bid The boundary ID you want to get the subdomain IDs for.
    1097             :    * @return All subdomain IDs contacting given boundary ID
    1098             :    */
    1099             :   std::set<SubdomainID> getInterfaceConnectedBlocks(const BoundaryID bid) const;
    1100             : 
    1101             :   /**
    1102             :    * Get the list of subdomains neighboring a given subdomain.
    1103             :    *
    1104             :    * @param subdomain_id The boundary ID you want to get the subdomain IDs for.
    1105             :    * @return All subdomain IDs neighboring a given subdomain
    1106             :    */
    1107             :   const std::set<SubdomainID> & getBlockConnectedBlocks(const SubdomainID subdomain_id) const;
    1108             : 
    1109             :   /**
    1110             :    * Returns true if the requested node is in the list of boundary nodes, false otherwise.
    1111             :    */
    1112             :   bool isBoundaryNode(dof_id_type node_id) const;
    1113             : 
    1114             :   /**
    1115             :    * Returns true if the requested node is in the list of boundary nodes for the specified boundary,
    1116             :    * false otherwise.
    1117             :    */
    1118             :   bool isBoundaryNode(dof_id_type node_id, BoundaryID bnd_id) const;
    1119             : 
    1120             :   /**
    1121             :    * Returns true if the requested element is in the list of boundary elements, false otherwise.
    1122             :    */
    1123             :   bool isBoundaryElem(dof_id_type elem_id) const;
    1124             : 
    1125             :   /**
    1126             :    * Returns true if the requested element is in the list of boundary elements for the specified
    1127             :    * boundary, false otherwise.
    1128             :    */
    1129             :   bool isBoundaryElem(dof_id_type elem_id, BoundaryID bnd_id) const;
    1130             : 
    1131             :   /**
    1132             :    * Generate a unified error message if the underlying libMesh mesh is a DistributedMesh.  Clients
    1133             :    * of MooseMesh can use this function to throw an error if they know they don't work with
    1134             :    * DistributedMesh.
    1135             :    *
    1136             :    * See, for example, the NodalVariableValue class.
    1137             :    */
    1138             :   void errorIfDistributedMesh(std::string name) const;
    1139             : 
    1140             :   /**
    1141             :    * Returns the final Mesh distribution type.
    1142             :    */
    1143       65647 :   virtual bool isDistributedMesh() const { return _use_distributed_mesh; }
    1144             : 
    1145             :   /**
    1146             :    * Tell the user if the distribution was overriden for any reason
    1147             :    */
    1148       54528 :   bool isParallelTypeForced() const { return _parallel_type_overridden; }
    1149             : 
    1150             :   /**
    1151             :    *  Allow to change parallel type
    1152             :    */
    1153             :   void setParallelType(ParallelType parallel_type);
    1154             : 
    1155             :   /**
    1156             :    * @return The parallel type
    1157             :    */
    1158        1102 :   ParallelType getParallelType() const { return _parallel_type; }
    1159             : 
    1160             :   /*
    1161             :    * Set/Get the partitioner name
    1162             :    */
    1163       27685 :   const MooseEnum & partitionerName() const { return _partitioner_name; }
    1164             : 
    1165             :   /**
    1166             :    * Tell the user if the partitioner was overriden for any reason
    1167             :    */
    1168       27685 :   bool isPartitionerForced() const { return _partitioner_overridden; }
    1169             : 
    1170             :   /**
    1171             :    * Set whether or not this mesh is allowed to read a recovery file.
    1172             :    */
    1173          10 :   void allowRecovery(bool allow) { _allow_recovery = allow; }
    1174             : 
    1175             :   /**
    1176             :    * Method for setting the partitioner on the passed in mesh_base object.
    1177             :    */
    1178             :   static void setPartitioner(MeshBase & mesh_base,
    1179             :                              MooseEnum & partitioner,
    1180             :                              bool use_distributed_mesh,
    1181             :                              const InputParameters & params,
    1182             :                              MooseObject & context_obj);
    1183             : 
    1184             :   /**
    1185             :    * Setter for custom partitioner
    1186             :    */
    1187             :   void setCustomPartitioner(libMesh::Partitioner * partitioner);
    1188             : 
    1189             :   ///@{
    1190             :   /**
    1191             :    * Setter and getter for _custom_partitioner_requested
    1192             :    */
    1193             :   bool isCustomPartitionerRequested() const;
    1194             :   void setIsCustomPartitionerRequested(bool cpr);
    1195             :   ///@}
    1196             : 
    1197             :   /// Getter to query if the mesh was detected to be regular and orthogonal
    1198        1594 :   bool isRegularOrthogonal() { return _regular_orthogonal_mesh; }
    1199             : 
    1200             :   /// check if the mesh has SECOND order elements
    1201             :   bool hasSecondOrderElements();
    1202             : 
    1203             :   /**
    1204             :    * Proxy function to get a (sub)PointLocator from either the underlying libMesh mesh (default), or
    1205             :    * to allow derived meshes to return a custom point locator.
    1206             :    */
    1207             :   virtual std::unique_ptr<libMesh::PointLocatorBase> getPointLocator() const;
    1208             : 
    1209             :   /**
    1210             :    * Returns the name of the mesh file read to produce this mesh if any or an empty string
    1211             :    * otherwise.
    1212             :    */
    1213         462 :   virtual std::string getFileName() const { return ""; }
    1214             : 
    1215             :   /// Helper type for building periodic node maps
    1216             :   using PeriodicNodeInfo = std::pair<const Node *, BoundaryID>;
    1217             : 
    1218             :   /**
    1219             :    * Set whether we need to delete remote elements
    1220             :    */
    1221          24 :   void needsRemoteElemDeletion(bool need_delete) { _need_delete = need_delete; }
    1222             : 
    1223             :   /**
    1224             :    * Whether we need to delete remote elements
    1225             :    */
    1226       65470 :   bool needsRemoteElemDeletion() const { return _need_delete; }
    1227             : 
    1228             :   /**
    1229             :    * Set whether to allow remote element removal
    1230             :    */
    1231             :   void allowRemoteElementRemoval(bool allow_removal);
    1232             : 
    1233             :   /**
    1234             :    * Whether we are allow remote element removal
    1235             :    */
    1236       28636 :   bool allowRemoteElementRemoval() const { return _allow_remote_element_removal; }
    1237             : 
    1238             :   /**
    1239             :    * Delete remote elements
    1240             :    */
    1241             :   void deleteRemoteElements();
    1242             : 
    1243             :   /**
    1244             :    * Whether mesh base object was constructed or not
    1245             :    */
    1246       90368 :   bool hasMeshBase() const { return _mesh.get() != nullptr; }
    1247             : 
    1248             :   /**
    1249             :    * Whether mesh has an extra element integer with a given name
    1250             :    */
    1251             :   bool hasElementID(const std::string & id_name) const;
    1252             : 
    1253             :   /**
    1254             :    * Return the accessing integer for an extra element integer with its name
    1255             :    */
    1256             :   unsigned int getElementIDIndex(const std::string & id_name) const;
    1257             : 
    1258             :   /**
    1259             :    * Return the maximum element ID for an extra element integer with its accessing index
    1260             :    */
    1261             :   dof_id_type maxElementID(unsigned int elem_id_index) const { return _max_ids[elem_id_index]; }
    1262             : 
    1263             :   /**
    1264             :    * Return the minimum element ID for an extra element integer with its accessing index
    1265             :    */
    1266             :   dof_id_type minElementID(unsigned int elem_id_index) const { return _min_ids[elem_id_index]; }
    1267             : 
    1268             :   /**
    1269             :    * Whether or not two extra element integers are identical
    1270             :    */
    1271             :   bool areElemIDsIdentical(const std::string & id_name1, const std::string & id_name2) const;
    1272             : 
    1273             :   /**
    1274             :    * Return all the unique element IDs for an extra element integer with its index
    1275             :    */
    1276             :   std::set<dof_id_type> getAllElemIDs(unsigned int elem_id_index) const;
    1277             : 
    1278             :   /**
    1279             :    * Return all the unique element IDs for an extra element integer with its index on a set of
    1280             :    * subdomains
    1281             :    */
    1282             :   std::set<dof_id_type> getElemIDsOnBlocks(unsigned int elem_id_index,
    1283             :                                            const std::set<SubdomainID> & blks) const;
    1284             : 
    1285             :   /**
    1286             :    * Get the maximum number of sides per element
    1287             :    */
    1288       10915 :   unsigned int getMaxSidesPerElem() const { return _max_sides_per_elem; }
    1289             : 
    1290             :   /**
    1291             :    * Get the maximum number of nodes per element
    1292             :    */
    1293        2622 :   unsigned int getMaxNodesPerElem() const { return _max_nodes_per_elem; }
    1294             : 
    1295             :   /**
    1296             :    * Get the maximum number of nodes per side
    1297             :    */
    1298             :   unsigned int getMaxNodesPerSide() const { return _max_nodes_per_side; }
    1299             : 
    1300             :   std::unordered_map<dof_id_type, std::set<dof_id_type>>
    1301             :   getElemIDMapping(const std::string & from_id_name, const std::string & to_id_name) const;
    1302             : 
    1303             :   ///@{ accessors for the FaceInfo objects
    1304             :   unsigned int nFace() const { return _face_info.size(); }
    1305             : 
    1306             :   /// Accessor for local \p FaceInfo objects.
    1307             :   const std::vector<const FaceInfo *> & faceInfo() const;
    1308             : 
    1309             :   /// Need to declare these iterators here to make sure the iterators below work
    1310             :   struct face_info_iterator;
    1311             :   struct const_face_info_iterator;
    1312             : 
    1313             :   /// Iterators to owned faceInfo objects. These faceInfo-s are required for the
    1314             :   /// face loops and to filter out the faceInfo-s that are not owned by this processor
    1315             :   /// in case we have a distributed mesh and we included FaceInfo objects that
    1316             :   /// are on processor boundaries
    1317             :   face_info_iterator ownedFaceInfoBegin();
    1318             :   face_info_iterator ownedFaceInfoEnd();
    1319             : 
    1320             :   /// Need to declare these iterators here to make sure the iterators below work
    1321             :   struct elem_info_iterator;
    1322             :   struct const_elem_info_iterator;
    1323             : 
    1324             :   /// Iterators to owned faceInfo objects. These faceInfo-s are required for the
    1325             :   /// face loops and to filter out the faceInfo-s that are not owned by this processor
    1326             :   /// in case we have a distributed mesh and we included FaceInfo objects that
    1327             :   /// are on processor boundaries
    1328             :   elem_info_iterator ownedElemInfoBegin();
    1329             :   elem_info_iterator ownedElemInfoEnd();
    1330             : 
    1331             :   /// Accessor for the local FaceInfo object on the side of one element. Returns null if ghosted.
    1332             :   const FaceInfo * faceInfo(const Elem * elem, unsigned int side) const;
    1333             : 
    1334             :   /// Accessor for the elemInfo object for a given element ID
    1335             :   const ElemInfo & elemInfo(const dof_id_type id) const;
    1336             : 
    1337             :   /// Accessor for the element info objects owned by this process
    1338          15 :   const std::vector<const ElemInfo *> & elemInfoVector() const { return _elem_info; }
    1339             : 
    1340             :   /// Accessor for all \p FaceInfo objects.
    1341             :   const std::vector<FaceInfo> & allFaceInfo() const;
    1342             :   ///@}
    1343             : 
    1344             :   /**
    1345             :    * Cache if variables live on the elements connected by the FaceInfo objects
    1346             :    */
    1347             :   void cacheFaceInfoVariableOwnership() const;
    1348             : 
    1349             :   /**
    1350             :    * Cache the DoF indices for FV variables on each element. These indices are used to speed up the
    1351             :    * setup loops of finite volume systems.
    1352             :    */
    1353             :   void cacheFVElementalDoFs() const;
    1354             : 
    1355             :   /**
    1356             :    * Compute the face coordinate value for all \p FaceInfo and \p ElemInfo objects. 'Coordinate'
    1357             :    * here means a coordinate value associated with the coordinate system. For Cartesian coordinate
    1358             :    * systems, 'coordinate' is simply '1'; in RZ, '2*pi*r', and in spherical, '4*pi*r^2'
    1359             :    */
    1360             :   void computeFiniteVolumeCoords() const;
    1361             : 
    1362             :   /**
    1363             :    * Set whether this mesh is a displaced mesh
    1364             :    */
    1365        2032 :   void isDisplaced(bool is_displaced) { _is_displaced = is_displaced; }
    1366             : 
    1367             :   /**
    1368             :    * whether this mesh is a displaced mesh
    1369             :    */
    1370             :   bool isDisplaced() const { return _is_displaced; }
    1371             : 
    1372             :   /**
    1373             :    * @return A map from nodeset ids to the vector of node ids in the nodeset
    1374             :    */
    1375             :   const std::map<boundary_id_type, std::vector<dof_id_type>> & nodeSetNodes() const;
    1376             : 
    1377             :   /**
    1378             :    * Get the coordinate system type, e.g. xyz, rz, or r-spherical, for the provided subdomain id \p
    1379             :    * sid
    1380             :    */
    1381             :   Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) const;
    1382             : 
    1383             :   /**
    1384             :    * Get the coordinate system from the mesh, it must be the same in all subdomains otherwise this
    1385             :    * will error
    1386             :    */
    1387             :   Moose::CoordinateSystemType getUniqueCoordSystem() const;
    1388             : 
    1389             :   /**
    1390             :    * Get the map from subdomain ID to coordinate system type, e.g. xyz, rz, or r-spherical
    1391             :    */
    1392             :   const std::map<SubdomainID, Moose::CoordinateSystemType> & getCoordSystem() const;
    1393             : 
    1394             :   /**
    1395             :    * Set the coordinate system for the provided blocks to \p coord_sys
    1396             :    */
    1397             :   void setCoordSystem(const std::vector<SubdomainName> & blocks, const MultiMooseEnum & coord_sys);
    1398             : 
    1399             :   /**
    1400             :    * For axisymmetric simulations, set the symmetry coordinate axis. For r in the x-direction, z in
    1401             :    * the y-direction the coordinate axis would be y
    1402             :    */
    1403             :   void setAxisymmetricCoordAxis(const MooseEnum & rz_coord_axis);
    1404             : 
    1405             :   /**
    1406             :    * Sets the general coordinate axes for axisymmetric blocks.
    1407             :    *
    1408             :    * This method must be used if any of the following are true:
    1409             :    * - There are multiple axisymmetric coordinate systems
    1410             :    * - Any axisymmetric coordinate system axis/direction is not the +X or +Y axis
    1411             :    * - Any axisymmetric coordinate system does not start at (0,0,0)
    1412             :    *
    1413             :    * @param[in] blocks  Subdomain names
    1414             :    * @param[in] axes  Pair of values defining the axisymmetric coordinate axis
    1415             :    *                  for each subdomain. The first value is the point on the axis
    1416             :    *                  corresponding to the origin. The second value is the direction
    1417             :    *                  vector of the axis (normalization not necessary).
    1418             :    */
    1419             :   void setGeneralAxisymmetricCoordAxes(const std::vector<SubdomainName> & blocks,
    1420             :                                        const std::vector<std::pair<Point, RealVectorValue>> & axes);
    1421             : 
    1422             :   /**
    1423             :    * Gets the general axisymmetric coordinate axis for a block.
    1424             :    *
    1425             :    * @param[in] subdomain_id  Subdomain ID for which to get axisymmetric coordinate axis
    1426             :    */
    1427             :   const std::pair<Point, RealVectorValue> &
    1428             :   getGeneralAxisymmetricCoordAxis(SubdomainID subdomain_id) const;
    1429             : 
    1430             :   /**
    1431             :    * Returns true if general axisymmetric coordinate axes are being used
    1432             :    */
    1433             :   bool usingGeneralAxisymmetricCoordAxes() const;
    1434             : 
    1435             :   /**
    1436             :    * Returns the desired radial direction for RZ coordinate transformation
    1437             :    * @return The coordinate direction for the radial direction
    1438             :    */
    1439             :   unsigned int getAxisymmetricRadialCoord() const;
    1440             : 
    1441             :   /**
    1442             :    * Performs a sanity check for every element in the mesh. If an element dimension is 3 and the
    1443             :    * corresponding coordinate system is RZ, then this will error. If an element dimension is greater
    1444             :    * than 1 and the corresponding system is RPSHERICAL then this will error
    1445             :    */
    1446             :   void checkCoordinateSystems();
    1447             : 
    1448             :   /**
    1449             :    * Set the coordinate system data to that of \p other_mesh
    1450             :    */
    1451             :   void setCoordData(const MooseMesh & other_mesh);
    1452             : 
    1453             :   /**
    1454             :    * Mark the finite volume information as dirty
    1455             :    */
    1456        4159 :   void markFiniteVolumeInfoDirty() { _finite_volume_info_dirty = true; }
    1457             : 
    1458             :   /**
    1459             :    * @return whether the finite volume information is dirty
    1460             :    */
    1461        1238 :   bool isFiniteVolumeInfoDirty() const { return _finite_volume_info_dirty; }
    1462             : 
    1463             :   /**
    1464             :    * @return the coordinate transformation object that describes how to transform this problem's
    1465             :    * coordinate system into the canonical/reference coordinate system
    1466             :    */
    1467             :   MooseAppCoordTransform & coordTransform();
    1468             : 
    1469             :   /**
    1470             :    * @return the length unit of this mesh provided through the coordinate transformation object
    1471             :    */
    1472             :   const MooseUnits & lengthUnit() const;
    1473             : 
    1474             :   /**
    1475             :    * This function attempts to return the map from a high-order element side to its corresponding
    1476             :    * lower-d element
    1477             :    */
    1478             :   const std::unordered_map<std::pair<const Elem *, unsigned short int>, const Elem *> &
    1479             :   getLowerDElemMap() const;
    1480             : 
    1481             :   /**
    1482             :    * @return Whether or not this mesh comes from a split mesh
    1483             :    */
    1484      184718 :   bool isSplit() const { return _is_split; }
    1485             : 
    1486             :   /**
    1487             :    * Builds the face and elem info vectors that store meta-data needed for looping over and doing
    1488             :    * calculations based on mesh faces and elements in a finite volume setting. This should only
    1489             :    * be called when finite volume variables are used in the problem or when the face and elem info
    1490             :    * objects are necessary for functor-based evaluations.
    1491             :    */
    1492             :   void buildFiniteVolumeInfo() const;
    1493             : 
    1494             :   /**
    1495             :    * Sets up the additional data needed for finite volume computations.
    1496             :    * This involves building FaceInfo and ElemInfo objects, caching variable associations
    1497             :    * and elemental DoF indices for FV variables.
    1498             :    */
    1499             :   void setupFiniteVolumeMeshData() const;
    1500             : 
    1501             :   /**
    1502             :    * Indicate whether the kind of adaptivity we're doing includes p-refinement
    1503             :    */
    1504         228 :   void doingPRefinement(bool doing_p_refinement) { _doing_p_refinement = doing_p_refinement; }
    1505             : 
    1506             :   /**
    1507             :    * Query whether the kind of adaptivity we're doing includes p-refinement
    1508             :    */
    1509      129381 :   [[nodiscard]] bool doingPRefinement() const { return _doing_p_refinement; }
    1510             : 
    1511             :   /**
    1512             :    * Returns the maximum p-refinement level of all elements
    1513             :    */
    1514       54895 :   unsigned int maxPLevel() const { return _max_p_level; }
    1515             : 
    1516             :   /**
    1517             :    * Returns the maximum h-refinement level of all elements
    1518             :    */
    1519       59837 :   unsigned int maxHLevel() const { return _max_h_level; }
    1520             : 
    1521             :   /**
    1522             :    * Get the map describing for each volumetric quadrature point (qp) on the refined level which qp
    1523             :    * on the previous coarser level the fine qp is closest to
    1524             :    */
    1525             :   const std::vector<QpMap> & getPRefinementMap(const Elem & elem) const;
    1526             :   /**
    1527             :    * Get the map describing for each side quadrature point (qp) on the refined level which qp
    1528             :    * on the previous coarser level the fine qp is closest to
    1529             :    */
    1530             :   const std::vector<QpMap> & getPRefinementSideMap(const Elem & elem) const;
    1531             :   /**
    1532             :    * Get the map describing for each volumetric quadrature point (qp) on the coarse level which qp
    1533             :    * on the previous finer level the coarse qp is closest to
    1534             :    */
    1535             :   const std::vector<QpMap> & getPCoarseningMap(const Elem & elem) const;
    1536             :   /**
    1537             :    * Get the map describing for each side quadrature point (qp) on the coarse level which qp
    1538             :    * on the previous finer level the coarse qp is closest to
    1539             :    */
    1540             :   const std::vector<QpMap> & getPCoarseningSideMap(const Elem & elem) const;
    1541             : 
    1542             :   void buildPRefinementAndCoarseningMaps(Assembly * assembly);
    1543             : 
    1544             :   /**
    1545             :    * @return Whether there are any lower-dimensional blocks
    1546             :    */
    1547       34356 :   bool hasLowerD() const { return getMesh().elem_dimensions().size() > 1; }
    1548             : 
    1549             :   /**
    1550             :    * @return The set of lower-dimensional blocks for interior sides
    1551             :    */
    1552   380500487 :   const std::set<SubdomainID> & interiorLowerDBlocks() const { return _lower_d_interior_blocks; }
    1553             :   /**
    1554             :    * @return The set of lower-dimensional blocks for boundary sides
    1555             :    */
    1556   379602381 :   const std::set<SubdomainID> & boundaryLowerDBlocks() const { return _lower_d_boundary_blocks; }
    1557             : 
    1558             :   /// Return construct node list from side list boolean
    1559         130 :   bool getConstructNodeListFromSideList() { return _construct_node_list_from_side_list; }
    1560             : 
    1561             :   /// Return displace node list by side list boolean
    1562             :   bool getDisplaceNodeListBySideList() { return _displace_node_list_by_side_list; }
    1563             : 
    1564             :   /**
    1565             :    * rebuild the node to element map if it's been requsted previously
    1566             :    * @returns Whether the map was re-built, or equivalently whether the map had been requested
    1567             :    * previously
    1568             :    */
    1569             :   bool possiblyRebuildNodeToElemMap();
    1570             : 
    1571             : protected:
    1572             :   /**
    1573             :    * Returns whether this mesh is allowed to read a recovery file.
    1574             :    */
    1575          11 :   bool allowRecovery() const { return _allow_recovery; }
    1576             : 
    1577             :   /// Deprecated (DO NOT USE)
    1578             :   std::vector<std::unique_ptr<libMesh::GhostingFunctor>> _ghosting_functors;
    1579             : 
    1580             :   /// The list of active geometric relationship managers (bound to the underlying MeshBase object).
    1581             :   std::vector<std::shared_ptr<RelationshipManager>> _relationship_managers;
    1582             : 
    1583             :   /// Whether or not this mesh was built from another mesh
    1584             :   bool _built_from_other_mesh = false;
    1585             : 
    1586             :   /// Can be set to DISTRIBUTED, REPLICATED, or DEFAULT.  Determines whether
    1587             :   /// the underlying libMesh mesh is a ReplicatedMesh or DistributedMesh.
    1588             :   ParallelType _parallel_type;
    1589             : 
    1590             :   /// False by default.  Final value is determined by several factors
    1591             :   /// including the 'distribution' setting in the input file, and whether
    1592             :   /// or not the Mesh file is a Nemesis file.
    1593             :   bool _use_distributed_mesh;
    1594             :   bool _distribution_overridden;
    1595             :   bool _parallel_type_overridden;
    1596             : 
    1597             :   /// Pointer to underlying libMesh mesh object
    1598             :   std::unique_ptr<libMesh::MeshBase> _mesh;
    1599             : 
    1600             :   /// Pointer to Kokkos mesh object
    1601             : #ifdef MOOSE_KOKKOS_ENABLED
    1602             :   std::unique_ptr<Moose::Kokkos::Mesh> _kokkos_mesh;
    1603             : #endif
    1604             : 
    1605             :   /// The partitioner used on this mesh
    1606             :   MooseEnum _partitioner_name;
    1607             :   bool _partitioner_overridden;
    1608             : 
    1609             :   /// The custom partitioner
    1610             :   std::unique_ptr<libMesh::Partitioner> _custom_partitioner;
    1611             :   bool _custom_partitioner_requested;
    1612             : 
    1613             :   /// Convenience enums
    1614             :   enum
    1615             :   {
    1616             :     X = 0,
    1617             :     Y,
    1618             :     Z
    1619             :   };
    1620             :   enum
    1621             :   {
    1622             :     MIN = 0,
    1623             :     MAX
    1624             :   };
    1625             : 
    1626             :   /// The level of uniform refinement requested (set to zero if AMR is disabled)
    1627             :   unsigned int _uniform_refine_level;
    1628             : 
    1629             :   /// Whether or not to skip uniform refinements when using a pre-split mesh
    1630             :   bool _skip_refine_when_use_split;
    1631             : 
    1632             :   /// Whether or not skip remote deletion and repartition after uniform refinements
    1633             :   bool _skip_deletion_repartition_after_refine;
    1634             : 
    1635             :   /// true if mesh is changed (i.e. after adaptivity step)
    1636             :   bool _is_changed;
    1637             : 
    1638             :   /// True if a Nemesis Mesh was read in
    1639             :   bool _is_nemesis;
    1640             : 
    1641             :   /// True if prepare has been called on the mesh
    1642             :   bool _moose_mesh_prepared = false;
    1643             : 
    1644             :   /// The elements that were just refined.
    1645             :   std::unique_ptr<ConstElemPointerRange> _refined_elements;
    1646             : 
    1647             :   /// The elements that were just coarsened.
    1648             :   std::unique_ptr<ConstElemPointerRange> _coarsened_elements;
    1649             : 
    1650             :   /**
    1651             :    * Map of Parent elements to child elements for elements that were just coarsened.
    1652             :    *
    1653             :    * NOTE: the child element pointers ARE PROBABLY INVALID.  Only use them for indexing!
    1654             :    */
    1655             :   std::map<const Elem *, std::vector<const Elem *>> _coarsened_element_children;
    1656             : 
    1657             :   /// Used for generating the semilocal node range
    1658             :   std::set<Node *> _semilocal_node_list;
    1659             : 
    1660             :   /**
    1661             :    * Ranges for use with threading, cached so they don't have to get
    1662             :    * rebuilt all the time (which takes time).
    1663             :    */
    1664             :   std::unique_ptr<SemiLocalNodeRange> _active_semilocal_node_range;
    1665             :   std::unique_ptr<libMesh::NodeRange> _active_node_range;
    1666             :   std::unique_ptr<libMesh::ConstNodeRange> _local_node_range;
    1667             :   std::unique_ptr<libMesh::StoredRange<MooseMesh::const_bnd_node_iterator, const BndNode *>>
    1668             :       _bnd_node_range;
    1669             :   std::unique_ptr<libMesh::StoredRange<MooseMesh::const_bnd_elem_iterator, const BndElement *>>
    1670             :       _bnd_elem_range;
    1671             : 
    1672             :   /// A map of all of the current nodes to the elements that they are connected to.
    1673             :   std::unordered_map<dof_id_type, std::vector<dof_id_type>> _node_to_elem_map;
    1674             : 
    1675             :   /// Whether @p _node_to_elem_map has been built.
    1676             :   bool _node_to_elem_map_built = false;
    1677             : 
    1678             :   /**
    1679             :    * A set of subdomain IDs currently present in the mesh. For parallel meshes, includes
    1680             :    * subdomains defined on other processors as well.
    1681             :    */
    1682             :   std::set<SubdomainID> _mesh_subdomains;
    1683             : 
    1684             :   ///@{
    1685             :   /**
    1686             :    * A set of boundary IDs currently present in the mesh. In serial, this is equivalent to the
    1687             :    * values returned by _mesh.get_boundary_info().get_boundary_ids(). In parallel, it will contain
    1688             :    * off-processor boundary IDs as well.
    1689             :    */
    1690             :   std::set<BoundaryID> _mesh_boundary_ids;
    1691             :   std::set<BoundaryID> _mesh_sideset_ids;
    1692             :   std::set<BoundaryID> _mesh_nodeset_ids;
    1693             :   ///@}
    1694             : 
    1695             :   /// The boundary to normal map - valid only when AddAllSideSetsByNormals is active
    1696             :   std::unique_ptr<std::map<BoundaryID, RealVectorValue>> _boundary_to_normal_map;
    1697             : 
    1698             :   /// array of boundary nodes
    1699             :   std::vector<BndNode *> _bnd_nodes;
    1700             :   typedef std::vector<BndNode *>::iterator bnd_node_iterator_imp;
    1701             :   typedef std::vector<BndNode *>::const_iterator const_bnd_node_iterator_imp;
    1702             :   /// Map of sets of node IDs in each boundary
    1703             :   std::map<boundary_id_type, std::set<dof_id_type>> _bnd_node_ids;
    1704             : 
    1705             :   /// array of boundary elems
    1706             :   std::vector<BndElement *> _bnd_elems;
    1707             :   typedef std::vector<BndElement *>::iterator bnd_elem_iterator_imp;
    1708             :   typedef std::vector<BndElement *>::const_iterator const_bnd_elem_iterator_imp;
    1709             : 
    1710             :   /// Map of set of elem IDs connected to each boundary
    1711             :   std::unordered_map<boundary_id_type, std::unordered_set<dof_id_type>> _bnd_elem_ids;
    1712             : 
    1713             :   std::map<dof_id_type, Node *> _quadrature_nodes;
    1714             :   std::map<dof_id_type, std::map<unsigned int, std::map<dof_id_type, Node *>>>
    1715             :       _elem_to_side_to_qp_to_quadrature_nodes;
    1716             :   std::vector<BndNode> _extra_bnd_nodes;
    1717             : 
    1718             :   /// list of nodes that belongs to a specified block (domain)
    1719             :   std::map<dof_id_type, std::set<SubdomainID>> _block_node_list;
    1720             : 
    1721             :   /// list of nodes that belongs to a specified nodeset: indexing [nodeset_id] -> [array of node ids]
    1722             :   std::map<boundary_id_type, std::vector<dof_id_type>> _node_set_nodes;
    1723             : 
    1724             :   std::set<unsigned int> _ghosted_boundaries;
    1725             :   std::vector<Real> _ghosted_boundaries_inflation;
    1726             : 
    1727             :   /// The number of nodes to consider in the NearestNode neighborhood.
    1728             :   unsigned int _patch_size;
    1729             : 
    1730             :   /// The number of nearest neighbors to consider for ghosting purposes when iteration patch update strategy is used.
    1731             :   unsigned int _ghosting_patch_size;
    1732             : 
    1733             :   // The maximum number of points in each leaf of the KDTree used in the nearest neighbor search.
    1734             :   unsigned int _max_leaf_size;
    1735             : 
    1736             :   /// The patch update strategy
    1737             :   Moose::PatchUpdateType _patch_update_strategy;
    1738             : 
    1739             :   /// Vector of all the Nodes in the mesh for determining when to add a new point
    1740             :   std::vector<Node *> _node_map;
    1741             : 
    1742             :   /// Boolean indicating whether this mesh was detected to be regular and orthogonal
    1743             :   bool _regular_orthogonal_mesh;
    1744             : 
    1745             :   /// The bounds in each dimension of the mesh for regular orthogonal meshes
    1746             :   std::vector<std::vector<Real>> _bounds;
    1747             : 
    1748             :   /// A vector holding the paired boundaries for a regular orthogonal mesh
    1749             :   std::optional<std::vector<std::pair<BoundaryID, BoundaryID>>> _paired_boundary;
    1750             : 
    1751             :   /// Whether or not we are using a (pre-)split mesh (automatically DistributedMesh)
    1752             :   const bool _is_split;
    1753             : 
    1754             :   void cacheInfo();
    1755             :   void freeBndNodes();
    1756             :   void freeBndElems();
    1757             :   void setPartitionerHelper(MeshBase * mesh = nullptr);
    1758             : 
    1759             : private:
    1760             :   /**
    1761             :    * If not already created, creates a map from every node to all
    1762             :    * elements to which they are connected.
    1763             :    */
    1764             :   std::unordered_map<dof_id_type, std::vector<dof_id_type>> & internalNodeToElemMap();
    1765             : 
    1766             :   /// Map connecting elems with their corresponding ElemInfo, we use the element ID as
    1767             :   /// the key
    1768             :   mutable std::unordered_map<dof_id_type, ElemInfo> _elem_to_elem_info;
    1769             : 
    1770             :   /// Holds only those \p ElemInfo objects that have \p processor_id equal to this process's id,
    1771             :   /// e.g. the local \p ElemInfo objects
    1772             :   mutable std::vector<const ElemInfo *> _elem_info;
    1773             : 
    1774             :   /// FaceInfo object storing information for face based loops. This container holds all the \p
    1775             :   /// FaceInfo objects accessible from this process
    1776             :   mutable std::vector<FaceInfo> _all_face_info;
    1777             : 
    1778             :   /// Holds only those \p FaceInfo objects that have \p processor_id equal to this process's id,
    1779             :   /// e.g. the local \p FaceInfo objects
    1780             :   mutable std::vector<const FaceInfo *> _face_info;
    1781             : 
    1782             :   /// Map from elem-side pair to FaceInfo
    1783             :   mutable std::unordered_map<std::pair<const Elem *, unsigned int>, FaceInfo *>
    1784             :       _elem_side_to_face_info;
    1785             : 
    1786             :   // true if the _face_info member needs to be rebuilt/updated.
    1787             :   mutable bool _finite_volume_info_dirty = true;
    1788             : 
    1789             :   // True if we have cached elemental dofs ids for the linear finite volume variables.
    1790             :   // This happens in the first system which has a linear finite volume variable, considering
    1791             :   // that currently we only support one variable per linear system.
    1792             :   mutable bool _linear_finite_volume_dofs_cached = false;
    1793             : 
    1794             :   /**
    1795             :    * A map from (system number, vector number) to which dimensions are periodic in a regular
    1796             :    * orthogonal mesh.
    1797             :    *
    1798             :    * This data structure is populated by addPeriodicVariable.
    1799             :    */
    1800             :   std::map<std::pair<unsigned int, unsigned int>, std::array<bool, 3>> _periodic_dim;
    1801             : 
    1802             :   /**
    1803             :    * A convenience vector used to hold values in each dimension representing half of the range.
    1804             :    */
    1805             :   RealVectorValue _half_range;
    1806             : 
    1807             :   /// A vector containing the nodes at the corners of a regular orthogonal mesh
    1808             :   std::vector<Node *> _extreme_nodes;
    1809             : 
    1810             :   /**
    1811             :    * Build the refinement map for a given element type.  This will tell you what quadrature points
    1812             :    * to copy from and to for stateful material properties on newly created elements from Adaptivity.
    1813             :    *
    1814             :    * @param elem The element that represents the element type you need the refinement map for.
    1815             :    * @param qrule The quadrature rule in use.
    1816             :    * @param qrule_face The current face quadrature rule
    1817             :    * @param parent_side The side of the parent to map (-1 if not mapping parent sides)
    1818             :    * @param child The child number (-1 if not mapping child internal sides)
    1819             :    * @param child_side The side number of the child (-1 if not mapping sides)
    1820             :    */
    1821             :   void buildRefinementMap(const Elem & elem,
    1822             :                           libMesh::QBase & qrule,
    1823             :                           libMesh::QBase & qrule_face,
    1824             :                           int parent_side,
    1825             :                           int child,
    1826             :                           int child_side);
    1827             : 
    1828             :   /**
    1829             :    * Build the coarsening map for a given element type.  This will tell you what quadrature points
    1830             :    * to copy from and to for stateful material properties on newly created elements from Adaptivity.
    1831             :    *
    1832             :    * @param elem The element that represents the element type you need the coarsening map for.
    1833             :    * @param qrule The quadrature rule in use.
    1834             :    * @param qrule_face The current face quadrature rule
    1835             :    * @param input_side The side to map
    1836             :    */
    1837             :   void buildCoarseningMap(const Elem & elem,
    1838             :                           libMesh::QBase & qrule,
    1839             :                           libMesh::QBase & qrule_face,
    1840             :                           int input_side);
    1841             : 
    1842             :   /**
    1843             :    * Find the closest points that map "from" to "to" and fill up "qp_map".
    1844             :    * Essentially, for each point in "from" find the closest point in "to".
    1845             :    *
    1846             :    * @param from The reference positions in the parent of the the points we're mapping _from_
    1847             :    * @param to The reference positions in the parent of the the points we're mapping _to_
    1848             :    * @param qp_map This will be filled with QpMap objects holding the mappings.
    1849             :    */
    1850             :   void mapPoints(const std::vector<Point> & from,
    1851             :                  const std::vector<Point> & to,
    1852             :                  std::vector<QpMap> & qp_map);
    1853             : 
    1854             :   /**
    1855             :    * Given an elem type, get maps that tell us what qp's are closest to each other between a parent
    1856             :    * and it's children.
    1857             :    * This is mainly used for mapping stateful material properties during adaptivity.
    1858             :    *
    1859             :    * There are 3 cases here:
    1860             :    *
    1861             :    * 1. Volume to volume (parent_side = -1, child = -1, child_side = -1)
    1862             :    * 2. Parent side to child side (parent_side = 0+, child = -1, child_side = 0+)
    1863             :    * 3. Child side to parent volume (parent_side = -1, child = 0+, child_side = 0+)
    1864             :    *
    1865             :    * Case 3 only happens under refinement (need to invent data at internal child sides).
    1866             :    *
    1867             :    * @param template_elem An element of the type that we need to find the maps for
    1868             :    * @param qrule The quadrature rule that we need to find the maps for
    1869             :    * @param qrule_face The face quadrature rule that we need to find the maps for
    1870             :    * @param refinement_map The map to use when an element gets split
    1871             :    * @param coarsen_map The map to use when an element is coarsened.
    1872             :    * @param parent_side - the id of the parent's side
    1873             :    * @param child - the id of the child element
    1874             :    * @param child_side - The id of the child's side
    1875             :    */
    1876             :   void findAdaptivityQpMaps(const Elem * template_elem,
    1877             :                             libMesh::QBase & qrule,
    1878             :                             libMesh::QBase & qrule_face,
    1879             :                             std::vector<std::vector<QpMap>> & refinement_map,
    1880             :                             std::vector<std::pair<unsigned int, QpMap>> & coarsen_map,
    1881             :                             int parent_side,
    1882             :                             int child,
    1883             :                             int child_side);
    1884             : 
    1885             :   void buildHRefinementAndCoarseningMaps(Assembly * assembly);
    1886             : 
    1887             :   const std::vector<QpMap> & getPRefinementMapHelper(
    1888             :       const Elem & elem,
    1889             :       const std::map<std::pair<libMesh::ElemType, unsigned int>, std::vector<QpMap>> &) const;
    1890             :   const std::vector<QpMap> & getPCoarseningMapHelper(
    1891             :       const Elem & elem,
    1892             :       const std::map<std::pair<libMesh::ElemType, unsigned int>, std::vector<QpMap>> &) const;
    1893             : 
    1894             :   /**
    1895             :    * Update the coordinate transformation object based on our coordinate system data. The coordinate
    1896             :    * transformation will be created if it hasn't been already
    1897             :    */
    1898             :   void updateCoordTransform();
    1899             : 
    1900             :   /**
    1901             :    * Loop through all subdomain IDs and check if there is name duplication used for the subdomains
    1902             :    * with same ID. Throw out an error if any name duplication is found.
    1903             :    */
    1904             :   void checkDuplicateSubdomainNames();
    1905             : 
    1906             :   /// Holds mappings for volume to volume and parent side to child side
    1907             :   /// Map key:
    1908             :   /// - first member corresponds to element side. It's -1 for volume quadrature points
    1909             :   /// - second member correponds to the element type
    1910             :   /// Map value:
    1911             :   /// - Outermost index is the child element index
    1912             :   /// - Once we have indexed by the child element index, we have a std::vector of QpMaps. This
    1913             :   ///   vector is sized by the number of reference points in the child element. Then for each
    1914             :   ///   reference point in the child element we have a QpMap whose \p _from index corresponds to
    1915             :   ///   the child element reference point, a \p _to index which corresponds to the reference point
    1916             :   ///   on the parent element that the child element reference point is closest to, and a
    1917             :   ///   \p _distance member which is the distance between the mapped child and parent reference
    1918             :   ///   quadrature points
    1919             :   std::map<std::pair<int, libMesh::ElemType>, std::vector<std::vector<QpMap>>>
    1920             :       _elem_type_to_refinement_map;
    1921             : 
    1922             :   std::map<std::pair<libMesh::ElemType, unsigned int>, std::vector<QpMap>>
    1923             :       _elem_type_to_p_refinement_map;
    1924             :   std::map<std::pair<libMesh::ElemType, unsigned int>, std::vector<QpMap>>
    1925             :       _elem_type_to_p_refinement_side_map;
    1926             : 
    1927             :   /// Holds mappings for "internal" child sides to parent volume.  The second key is (child, child_side).
    1928             :   std::map<libMesh::ElemType, std::map<std::pair<int, int>, std::vector<std::vector<QpMap>>>>
    1929             :       _elem_type_to_child_side_refinement_map;
    1930             : 
    1931             :   /// Holds mappings for volume to volume and parent side to child side
    1932             :   /// Map key:
    1933             :   /// - first member corresponds to element side. It's -1 for volume quadrature points
    1934             :   /// - second member correponds to the element type
    1935             :   /// Map value:
    1936             :   /// - Vector is sized based on the number of quadrature points in the parent (e.g. coarser)
    1937             :   ///   element.
    1938             :   /// - For each parent quadrature point we store a pair
    1939             :   ///   - The first member of the pair identifies which child holds the closest refined-level
    1940             :   ///     quadrature point
    1941             :   ///   - The second member of the pair is the QpMap. The \p _from data member will correspond to
    1942             :   ///     the parent quadrature point index. The \p _to data member will correspond to which child
    1943             :   ///     element quadrature point is closest to the parent quadrature point. And \p _distance is
    1944             :   ///     the distance between the two
    1945             :   std::map<std::pair<int, libMesh::ElemType>, std::vector<std::pair<unsigned int, QpMap>>>
    1946             :       _elem_type_to_coarsening_map;
    1947             : 
    1948             :   std::map<std::pair<libMesh::ElemType, unsigned int>, std::vector<QpMap>>
    1949             :       _elem_type_to_p_coarsening_map;
    1950             :   std::map<std::pair<libMesh::ElemType, unsigned int>, std::vector<QpMap>>
    1951             :       _elem_type_to_p_coarsening_side_map;
    1952             : 
    1953             :   struct SubdomainData
    1954             :   {
    1955             :     /// Neighboring subdomain ids
    1956             :     std::set<SubdomainID> neighbor_subs;
    1957             : 
    1958             :     /// The boundary ids that are attached. This set will include any sideset boundary ID that
    1959             :     /// is a side of any part of the subdomain
    1960             :     std::set<BoundaryID> boundary_ids;
    1961             :   };
    1962             : 
    1963             :   /// Holds a map from subdomain ids to associated data
    1964             :   std::unordered_map<SubdomainID, SubdomainData> _sub_to_data;
    1965             : 
    1966             :   /// Holds a map from neighbor subomdain ids to the boundary ids that are attached to it
    1967             :   std::unordered_map<SubdomainID, std::set<BoundaryID>> _neighbor_subdomain_boundary_ids;
    1968             : 
    1969             :   /// Mesh blocks for interior lower-d elements in different types
    1970             :   std::set<SubdomainID> _lower_d_interior_blocks;
    1971             :   /// Mesh blocks for boundary lower-d elements in different types
    1972             :   std::set<SubdomainID> _lower_d_boundary_blocks;
    1973             :   /// Holds a map from a high-order element side to its corresponding lower-d element
    1974             :   std::unordered_map<std::pair<const Elem *, unsigned short int>, const Elem *>
    1975             :       _higher_d_elem_side_to_lower_d_elem;
    1976             :   std::unordered_map<const Elem *, unsigned short int> _lower_d_elem_to_higher_d_elem_side;
    1977             : 
    1978             :   /// Whether or not this Mesh is allowed to read a recovery file
    1979             :   bool _allow_recovery;
    1980             : 
    1981             :   /// Whether or not to allow generation of nodesets from sidesets
    1982             :   bool _construct_node_list_from_side_list;
    1983             : 
    1984             :   /// Whether or not to displace unrelated nodesets by nodesets
    1985             :   /// constructed from sidesets
    1986             :   bool _displace_node_list_by_side_list;
    1987             : 
    1988             :   /// Whether we need to delete remote elements after init'ing the EquationSystems
    1989             :   bool _need_delete;
    1990             : 
    1991             :   /// Whether to allow removal of remote elements
    1992             :   bool _allow_remote_element_removal;
    1993             : 
    1994             :   /// Set of elements ghosted by ghostGhostedBoundaries
    1995             :   std::set<Elem *> _ghost_elems_from_ghost_boundaries;
    1996             : 
    1997             :   /// A parallel mesh generator such as DistributedRectilinearMeshGenerator
    1998             :   /// already make everything ready. We do not need to gather all boundaries to
    1999             :   /// every single processor. In general, we should avoid using ghostGhostedBoundaries
    2000             :   /// when possible since it is not scalable
    2001             :   bool _need_ghost_ghosted_boundaries;
    2002             : 
    2003             :   /// Unique element integer IDs for each subdomain and each extra element integers
    2004             :   std::vector<std::unordered_map<SubdomainID, std::set<dof_id_type>>> _block_id_mapping;
    2005             :   /// Maximum integer ID for each extra element integer
    2006             :   std::vector<dof_id_type> _max_ids;
    2007             :   /// Minimum integer ID for each extra element integer
    2008             :   std::vector<dof_id_type> _min_ids;
    2009             :   /// Flags to indicate whether or not any two extra element integers are the same
    2010             :   std::vector<std::vector<bool>> _id_identical_flag;
    2011             : 
    2012             :   /// The maximum number of sides per element
    2013             :   unsigned int _max_sides_per_elem;
    2014             : 
    2015             :   /// The maximum number of nodes per element
    2016             :   unsigned int _max_nodes_per_elem;
    2017             : 
    2018             :   /// The maximum number of nodes per side
    2019             :   unsigned int _max_nodes_per_side;
    2020             : 
    2021             :   /// Compute the maximum numbers per element and side
    2022             :   void computeMaxPerElemAndSide();
    2023             : 
    2024             :   /// Whether this mesh is displaced
    2025             :   bool _is_displaced;
    2026             : 
    2027             :   /// Build extra data for faster access to the information of extra element integers
    2028             :   void buildElemIDInfo();
    2029             : 
    2030             :   /// Build lower-d mesh for all sides
    2031             :   void buildLowerDMesh();
    2032             : 
    2033             :   /// Type of coordinate system per subdomain
    2034             :   std::map<SubdomainID, Moose::CoordinateSystemType> & _coord_sys;
    2035             : 
    2036             :   /// Storage for RZ axis selection
    2037             :   unsigned int _rz_coord_axis;
    2038             : 
    2039             :   /// Map of subdomain ID to general axisymmetric axis
    2040             :   std::unordered_map<SubdomainID, std::pair<Point, RealVectorValue>> _subdomain_id_to_rz_coord_axis;
    2041             : 
    2042             :   /// A coordinate transformation object that describes how to transform this problem's coordinate
    2043             :   /// system into the canonical/reference coordinate system
    2044             :   std::unique_ptr<MooseAppCoordTransform> _coord_transform;
    2045             : 
    2046             :   /// Whether the coordinate system has been set
    2047             :   bool _coord_system_set;
    2048             : 
    2049             :   /// Set for holding user-provided coordinate system type block names
    2050             :   std::vector<SubdomainName> _provided_coord_blocks;
    2051             : 
    2052             :   /// Whether we have p-refinement (whether exclusively p- or hp-refinement)
    2053             :   bool _doing_p_refinement;
    2054             :   /// Maximum p-refinement level of all elements
    2055             :   unsigned int _max_p_level;
    2056             :   /// Maximum h-refinement level of all elements
    2057             :   unsigned int _max_h_level;
    2058             : 
    2059             :   template <typename T>
    2060             :   struct MeshType;
    2061             : };
    2062             : 
    2063             : inline MooseAppCoordTransform &
    2064      157311 : MooseMesh::coordTransform()
    2065             : {
    2066             :   mooseAssert(_coord_transform, "The coordinate transformation object is null.");
    2067      157311 :   return *_coord_transform;
    2068             : }
    2069             : 
    2070             : template <>
    2071             : struct MooseMesh::MeshType<libMesh::ReplicatedMesh>
    2072             : {
    2073             :   static const ParallelType value = ParallelType::REPLICATED;
    2074             : };
    2075             : 
    2076             : template <>
    2077             : struct MooseMesh::MeshType<libMesh::DistributedMesh>
    2078             : {
    2079             :   static const ParallelType value = ParallelType::DISTRIBUTED;
    2080             : };
    2081             : 
    2082             : /**
    2083             :  * The definition of the face_info_iterator struct.
    2084             :  */
    2085             : struct MooseMesh::face_info_iterator
    2086             :   : variant_filter_iterator<MeshBase::Predicate, const FaceInfo *>
    2087             : {
    2088             :   // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
    2089             :   template <typename PredType, typename IterType>
    2090      329406 :   face_info_iterator(const IterType & d, const IterType & e, const PredType & p)
    2091      329406 :     : variant_filter_iterator<MeshBase::Predicate, const FaceInfo *>(d, e, p)
    2092             :   {
    2093      329406 :   }
    2094             : };
    2095             : 
    2096             : /**
    2097             :  * The definition of the const_face_info_iterator struct. It is similar to the
    2098             :  * iterator above, but also provides an additional conversion-to-const ctor.
    2099             :  */
    2100             : struct MooseMesh::const_face_info_iterator : variant_filter_iterator<MeshBase::Predicate,
    2101             :                                                                      const FaceInfo * const,
    2102             :                                                                      const FaceInfo * const &,
    2103             :                                                                      const FaceInfo * const *>
    2104             : {
    2105             :   // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
    2106             :   template <typename PredType, typename IterType>
    2107             :   const_face_info_iterator(const IterType & d, const IterType & e, const PredType & p)
    2108             :     : variant_filter_iterator<MeshBase::Predicate,
    2109             :                               const FaceInfo * const,
    2110             :                               const FaceInfo * const &,
    2111             :                               const FaceInfo * const *>(d, e, p)
    2112             :   {
    2113             :   }
    2114             : 
    2115             :   // The conversion-to-const ctor.  Takes a regular iterator and calls the appropriate
    2116             :   // variant_filter_iterator copy constructor.  Note that this one is *not* templated!
    2117      329406 :   const_face_info_iterator(const MooseMesh::face_info_iterator & rhs)
    2118      329406 :     : variant_filter_iterator<MeshBase::Predicate,
    2119             :                               const FaceInfo * const,
    2120             :                               const FaceInfo * const &,
    2121      329406 :                               const FaceInfo * const *>(rhs)
    2122             :   {
    2123      329406 :   }
    2124             : };
    2125             : 
    2126             : /**
    2127             :  * The definition of the elem_info_iterator struct.
    2128             :  */
    2129             : struct MooseMesh::elem_info_iterator
    2130             :   : variant_filter_iterator<MeshBase::Predicate, const ElemInfo *>
    2131             : {
    2132             :   // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
    2133             :   template <typename PredType, typename IterType>
    2134      168500 :   elem_info_iterator(const IterType & d, const IterType & e, const PredType & p)
    2135      168500 :     : variant_filter_iterator<MeshBase::Predicate, const ElemInfo *>(d, e, p)
    2136             :   {
    2137      168500 :   }
    2138             : };
    2139             : 
    2140             : /**
    2141             :  * The definition of the const_elem_info_iterator struct. It is similar to the
    2142             :  * iterator above, but also provides an additional conversion-to-const ctor.
    2143             :  */
    2144             : struct MooseMesh::const_elem_info_iterator : variant_filter_iterator<MeshBase::Predicate,
    2145             :                                                                      const ElemInfo * const,
    2146             :                                                                      const ElemInfo * const &,
    2147             :                                                                      const ElemInfo * const *>
    2148             : {
    2149             :   // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
    2150             :   template <typename PredType, typename IterType>
    2151             :   const_elem_info_iterator(const IterType & d, const IterType & e, const PredType & p)
    2152             :     : variant_filter_iterator<MeshBase::Predicate,
    2153             :                               const ElemInfo * const,
    2154             :                               const ElemInfo * const &,
    2155             :                               const ElemInfo * const *>(d, e, p)
    2156             :   {
    2157             :   }
    2158             : 
    2159             :   // The conversion-to-const ctor.  Takes a regular iterator and calls the appropriate
    2160             :   // variant_filter_iterator copy constructor.  Note that this one is *not* templated!
    2161      168500 :   const_elem_info_iterator(const MooseMesh::elem_info_iterator & rhs)
    2162      168500 :     : variant_filter_iterator<MeshBase::Predicate,
    2163             :                               const ElemInfo * const,
    2164             :                               const ElemInfo * const &,
    2165      168500 :                               const ElemInfo * const *>(rhs)
    2166             :   {
    2167      168500 :   }
    2168             : };
    2169             : 
    2170             : /**
    2171             :  * The definition of the bnd_node_iterator struct.
    2172             :  */
    2173             : struct MooseMesh::bnd_node_iterator : variant_filter_iterator<MeshBase::Predicate, BndNode *>
    2174             : {
    2175             :   // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
    2176             :   template <typename PredType, typename IterType>
    2177      173604 :   bnd_node_iterator(const IterType & d, const IterType & e, const PredType & p)
    2178      173604 :     : variant_filter_iterator<MeshBase::Predicate, BndNode *>(d, e, p)
    2179             :   {
    2180      173604 :   }
    2181             : };
    2182             : 
    2183             : /**
    2184             :  * The definition of the const_bnd_node_iterator struct.  It is similar to the
    2185             :  * iterator above, but also provides an additional conversion-to-const ctor.
    2186             :  */
    2187             : struct MooseMesh::const_bnd_node_iterator : variant_filter_iterator<MeshBase::Predicate,
    2188             :                                                                     BndNode * const,
    2189             :                                                                     BndNode * const &,
    2190             :                                                                     BndNode * const *>
    2191             : {
    2192             :   // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
    2193             :   template <typename PredType, typename IterType>
    2194        4082 :   const_bnd_node_iterator(const IterType & d, const IterType & e, const PredType & p)
    2195             :     : variant_filter_iterator<MeshBase::Predicate,
    2196             :                               BndNode * const,
    2197             :                               BndNode * const &,
    2198        4082 :                               BndNode * const *>(d, e, p)
    2199             :   {
    2200        4082 :   }
    2201             : 
    2202             :   // The conversion-to-const ctor.  Takes a regular iterator and calls the appropriate
    2203             :   // variant_filter_iterator copy constructor.  Note that this one is *not* templated!
    2204      168360 :   const_bnd_node_iterator(const MooseMesh::bnd_node_iterator & rhs)
    2205      168360 :     : variant_filter_iterator<MeshBase::Predicate,
    2206             :                               BndNode * const,
    2207             :                               BndNode * const &,
    2208      168360 :                               BndNode * const *>(rhs)
    2209             :   {
    2210      168360 :   }
    2211             : };
    2212             : 
    2213             : /**
    2214             :  * The definition of the bnd_elem_iterator struct.
    2215             :  */
    2216             : struct MooseMesh::bnd_elem_iterator : variant_filter_iterator<MeshBase::Predicate, BndElement *>
    2217             : {
    2218             :   // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
    2219             :   template <typename PredType, typename IterType>
    2220      168324 :   bnd_elem_iterator(const IterType & d, const IterType & e, const PredType & p)
    2221      168324 :     : variant_filter_iterator<MeshBase::Predicate, BndElement *>(d, e, p)
    2222             :   {
    2223      168324 :   }
    2224             : };
    2225             : 
    2226             : /**
    2227             :  * The definition of the const_bnd_elem_iterator struct.  It is similar to the regular
    2228             :  * iterator above, but also provides an additional conversion-to-const ctor.
    2229             :  */
    2230             : struct MooseMesh::const_bnd_elem_iterator : variant_filter_iterator<MeshBase::Predicate,
    2231             :                                                                     BndElement * const,
    2232             :                                                                     BndElement * const &,
    2233             :                                                                     BndElement * const *>
    2234             : {
    2235             :   // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
    2236             :   template <typename PredType, typename IterType>
    2237             :   const_bnd_elem_iterator(const IterType & d, const IterType & e, const PredType & p)
    2238             :     : variant_filter_iterator<MeshBase::Predicate,
    2239             :                               BndElement * const,
    2240             :                               BndElement * const &,
    2241             :                               BndElement * const *>(d, e, p)
    2242             :   {
    2243             :   }
    2244             : 
    2245             :   // The conversion-to-const ctor.  Takes a regular iterator and calls the appropriate
    2246             :   // variant_filter_iterator copy constructor.  Note that this one is *not* templated!
    2247      168016 :   const_bnd_elem_iterator(const bnd_elem_iterator & rhs)
    2248      168016 :     : variant_filter_iterator<MeshBase::Predicate,
    2249             :                               BndElement * const,
    2250             :                               BndElement * const &,
    2251      168016 :                               BndElement * const *>(rhs)
    2252             :   {
    2253      168016 :   }
    2254             : };
    2255             : 
    2256             : /**
    2257             :  * Some useful StoredRange typedefs.  These are defined *outside* the
    2258             :  * MooseMesh class to mimic the Const{Node,Elem}Range classes in libmesh.
    2259             :  */
    2260             : typedef libMesh::StoredRange<MooseMesh::const_bnd_node_iterator, const BndNode *> ConstBndNodeRange;
    2261             : typedef libMesh::StoredRange<MooseMesh::const_bnd_elem_iterator, const BndElement *>
    2262             :     ConstBndElemRange;
    2263             : 
    2264             : template <typename T>
    2265             : std::unique_ptr<T>
    2266       71726 : MooseMesh::buildTypedMesh(unsigned int dim)
    2267             : {
    2268             :   // If the requested mesh type to build doesn't match our current value for _use_distributed_mesh,
    2269             :   // then we need to make sure to make our state consistent because other objects, like the periodic
    2270             :   // boundary condition action, will be querying isDistributedMesh()
    2271       71726 :   if (_use_distributed_mesh != std::is_same<T, libMesh::DistributedMesh>::value)
    2272             :   {
    2273         823 :     if (getMeshPtr())
    2274           0 :       mooseError("A MooseMesh object is being asked to build a libMesh mesh that is a different "
    2275             :                  "parallel type than the libMesh mesh that it wraps. This is not allowed. Please "
    2276             :                  "create another MooseMesh object to wrap the new libMesh mesh");
    2277         823 :     setParallelType(MeshType<T>::value);
    2278             :   }
    2279             : 
    2280       71726 :   if (dim == libMesh::invalid_uint)
    2281             :   {
    2282      150882 :     if (isParamValid("dim"))
    2283      121935 :       dim = getParam<MooseEnum>("dim");
    2284             :     else
    2285             :       // Legacy selection of the default for the 'dim' parameter
    2286        9649 :       dim = 1;
    2287             :   }
    2288             : 
    2289       71726 :   auto mesh = std::make_unique<T>(_communicator, dim);
    2290             : 
    2291      215178 :   if (!getParam<bool>("allow_renumbering"))
    2292        2471 :     mesh->allow_renumbering(false);
    2293             : 
    2294       71726 :   mesh->allow_remote_element_removal(_allow_remote_element_removal);
    2295       71726 :   _app.attachRelationshipManagers(*mesh, *this);
    2296             : 
    2297       71726 :   if (_custom_partitioner_requested)
    2298             :   {
    2299             :     // Check of partitioner is supplied (not allowed if custom partitioner is used)
    2300        4683 :     if (!parameters().isParamSetByAddParam("partitioner"))
    2301           0 :       mooseError("If partitioner block is provided, partitioner keyword cannot be used!");
    2302             :     // Set custom partitioner
    2303        1561 :     if (!_custom_partitioner.get())
    2304           0 :       mooseError("Custom partitioner requested but not set!");
    2305        1561 :     mesh->partitioner() = _custom_partitioner->clone();
    2306             :   }
    2307             :   else
    2308       70165 :     setPartitionerHelper(mesh.get());
    2309             : 
    2310       71726 :   return mesh;
    2311           0 : }
    2312             : 
    2313             : inline bool
    2314        3855 : MooseMesh::skipDeletionRepartitionAfterRefine() const
    2315             : {
    2316        3855 :   return _skip_deletion_repartition_after_refine;
    2317             : }
    2318             : 
    2319             : inline void
    2320         890 : MooseMesh::setParallelType(ParallelType parallel_type)
    2321             : {
    2322         890 :   _parallel_type = parallel_type;
    2323         890 :   determineUseDistributedMesh();
    2324         890 : }
    2325             : 
    2326             : inline bool
    2327             : MooseMesh::hasElementID(const std::string & id_name) const
    2328             : {
    2329             :   return getMesh().has_elem_integer(id_name);
    2330             : }
    2331             : 
    2332             : inline unsigned int
    2333             : MooseMesh::getElementIDIndex(const std::string & id_name) const
    2334             : {
    2335             :   if (!hasElementID(id_name))
    2336             :     mooseError("Mesh does not have element ID for ", id_name);
    2337             :   return getMesh().get_elem_integer_index(id_name);
    2338             : }
    2339             : 
    2340             : inline bool
    2341             : MooseMesh::areElemIDsIdentical(const std::string & id_name1, const std::string & id_name2) const
    2342             : {
    2343             :   auto id1 = getElementIDIndex(id_name1);
    2344             :   auto id2 = getElementIDIndex(id_name2);
    2345             :   return _id_identical_flag[id1][id2];
    2346             : }
    2347             : 
    2348             : inline const std::vector<const FaceInfo *> &
    2349          46 : MooseMesh::faceInfo() const
    2350             : {
    2351          46 :   return _face_info;
    2352             : }
    2353             : 
    2354             : inline const std::vector<FaceInfo> &
    2355           4 : MooseMesh::allFaceInfo() const
    2356             : {
    2357           4 :   return _all_face_info;
    2358             : }
    2359             : 
    2360             : inline const std::map<boundary_id_type, std::vector<dof_id_type>> &
    2361             : MooseMesh::nodeSetNodes() const
    2362             : {
    2363             :   return _node_set_nodes;
    2364             : }
    2365             : 
    2366             : inline const std::unordered_map<std::pair<const Elem *, unsigned short int>, const Elem *> &
    2367             : MooseMesh::getLowerDElemMap() const
    2368             : {
    2369             :   return _higher_d_elem_side_to_lower_d_elem;
    2370             : }

Generated by: LCOV version 1.14