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 : }
|