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