32#include "libmesh/bounding_box.h"
33#include "libmesh/boundary_info.h"
34#include "libmesh/mesh_tools.h"
35#include "libmesh/parallel.h"
36#include "libmesh/mesh_communication.h"
37#include "libmesh/periodic_boundary_base.h"
38#include "libmesh/fe_base.h"
39#include "libmesh/fe_interface.h"
40#include "libmesh/mesh_communication.h"
41#include "libmesh/mesh_tools.h"
42#include "libmesh/parallel.h"
43#include "libmesh/parallel_elem.h"
44#include "libmesh/parallel_node.h"
45#include "libmesh/parallel_ghost_sync.h"
46#include "libmesh/utility.h"
47#include "libmesh/remote_elem.h"
48#include "libmesh/linear_partitioner.h"
49#include "libmesh/centroid_partitioner.h"
50#include "libmesh/parmetis_partitioner.h"
51#include "libmesh/hilbert_sfc_partitioner.h"
52#include "libmesh/morton_sfc_partitioner.h"
53#include "libmesh/edge_edge2.h"
54#include "libmesh/checkpoint_io.h"
55#include "libmesh/mesh_refinement.h"
56#include "libmesh/quadrature.h"
57#include "libmesh/boundary_info.h"
58#include "libmesh/periodic_boundaries.h"
59#include "libmesh/quadrature_gauss.h"
60#include "libmesh/point_locator_base.h"
61#include "libmesh/default_coupling.h"
62#include "libmesh/ghost_point_neighbors.h"
63#include "libmesh/fe_type.h"
64#include "libmesh/enum_to_string.h"
65#include "libmesh/elem_side_builder.h"
68#if NANOFLANN_VERSION < 0x150
73template <
typename T,
typename U>
85 MooseEnum parallel_type(
"DEFAULT REPLICATED DISTRIBUTED",
"DEFAULT");
88 "DEFAULT: Use libMesh::ReplicatedMesh unless --distributed-mesh is "
89 "specified on the command line "
90 "REPLICATED: Always use libMesh::ReplicatedMesh "
91 "DISTRIBUTED: Always use libMesh::DistributedMesh");
96 "If allow_renumbering=false, node and element numbers are kept fixed until deletion");
101 "Specifies a mesh partitioner to use when splitting the mesh for a parallel computation.");
105 "Specifies the sort direction if using the centroid partitioner. "
106 "Available options: x, y, z, radial");
108 MooseEnum patch_update_strategy(
"never always auto iteration",
"never");
110 "patch_update_strategy",
111 patch_update_strategy,
112 "How often to update the geometric search 'patch'. The default is to "
113 "never update it (which is the most efficient but could be a problem "
114 "with lots of relative motion). 'always' will update the patch for all "
115 "secondary nodes at the beginning of every timestep which might be time "
116 "consuming. 'auto' will attempt to determine at the start of which "
117 "timesteps the patch for all secondary nodes needs to be updated automatically."
118 "'iteration' updates the patch at every nonlinear iteration for a "
119 "subset of secondary nodes for which penetration is not detected. If there "
120 "can be substantial relative motion between the primary and secondary surfaces "
121 "during the nonlinear iterations within a timestep, it is advisable to use "
122 "'iteration' option to ensure accurate contact detection.");
126 "construct_node_list_from_side_list",
128 "Whether or not to generate nodesets from the sidesets (currently often required).");
130 "displace_node_list_by_side_list",
132 "Whether to renumber existing nodesets with ids matching sidesets that "
133 "lack names matching sidesets, when constructing nodesets from sidesets via the default "
134 "'construct_node_list_from_side_list' option, rather than to merge them with the sideset.");
136 "patch_size", 40,
"The number of nodes to consider in the NearestNode neighborhood.");
137 params.
addParam<
unsigned int>(
"ghosting_patch_size",
138 "The number of nearest neighbors considered "
139 "for ghosting purposes when 'iteration' "
140 "patch update strategy is used. Default is "
142 params.
addParam<
unsigned int>(
"max_leaf_size",
144 "The maximum number of points in each leaf of the KDTree used in "
145 "the nearest neighbor search. As the leaf size becomes larger,"
146 "KDTree construction becomes faster but the nearest neighbor search"
149 params.
addParam<
bool>(
"build_all_side_lowerd_mesh",
151 "True to build the lower-dimensional mesh for all sides.");
153 params.
addParam<
bool>(
"skip_refine_when_use_split",
155 "True to skip uniform refinements when using a pre-split mesh.");
157 params.
addParam<std::vector<SubdomainID>>(
159 "The listed subdomain ids will be assumed valid for the mesh. This permits setting up "
160 "subdomain restrictions for subdomains initially containing no elements, which can occur, "
161 "for example, in additive manufacturing simulations which dynamically add and remove "
162 "elements. Names for this subdomains may be provided using add_subdomain_names. In this case "
163 "this list and add_subdomain_names must contain the same number of items.");
164 params.
addParam<std::vector<SubdomainName>>(
165 "add_subdomain_names",
166 "The listed subdomain names will be assumed valid for the mesh. This permits setting up "
167 "subdomain restrictions for subdomains initially containing no elements, which can occur, "
168 "for example, in additive manufacturing simulations which dynamically add and remove "
169 "elements. IDs for this subdomains may be provided using add_subdomain_ids. Otherwise IDs "
170 "are automatically assigned. In case add_subdomain_ids is set too, both lists must contain "
171 "the same number of items.");
173 params.
addParam<std::vector<BoundaryID>>(
175 "The listed sideset ids will be assumed valid for the mesh. This permits setting up boundary "
176 "restrictions for sidesets initially containing no sides. Names for this sidesets may be "
177 "provided using add_sideset_names. In this case this list and add_sideset_names must contain "
178 "the same number of items.");
179 params.
addParam<std::vector<BoundaryName>>(
181 "The listed sideset names will be assumed valid for the mesh. This permits setting up "
182 "boundary restrictions for sidesets initially containing no sides. Ids for this sidesets may "
183 "be provided using add_sideset_ids. In this case this list and add_sideset_ids must contain "
184 "the same number of items.");
186 params.
addParam<std::vector<BoundaryID>>(
188 "The listed nodeset ids will be assumed valid for the mesh. This permits setting up boundary "
189 "restrictions for node initially containing no sides. Names for this nodesets may be "
190 "provided using add_nodeset_names. In this case this list and add_nodeset_names must contain "
191 "the same number of items.");
192 params.
addParam<std::vector<BoundaryName>>(
194 "The listed nodeset names will be assumed valid for the mesh. This permits setting up "
195 "boundary restrictions for nodesets initially containing no sides. Ids for this nodesets may "
196 "be provided using add_nodesets_ids. In this case this list and add_nodesets_ids must "
197 "contain the same number of items.");
211 params.
addParamNamesToGroup(
"patch_update_strategy patch_size max_leaf_size",
"Geometric search");
213 "add_sideset_names add_nodeset_ids add_nodeset_names",
214 "Pre-declaration of future mesh sub-entities");
216 "displace_node_list_by_side_list",
217 "Automatic definition of mesh element sides entities");
228 _use_distributed_mesh(false),
229 _distribution_overridden(false),
230 _parallel_type_overridden(false),
232 _partitioner_name(getParam<
MooseEnum>(
"partitioner")),
233 _partitioner_overridden(false),
234 _custom_partitioner_requested(false),
235 _uniform_refine_level(0),
236 _skip_refine_when_use_split(getParam<bool>(
"skip_refine_when_use_split")),
237 _skip_deletion_repartition_after_refine(false),
239 _patch_size(getParam<unsigned
int>(
"patch_size")),
240 _ghosting_patch_size(isParamValid(
"ghosting_patch_size")
241 ? getParam<unsigned
int>(
"ghosting_patch_size")
243 _max_leaf_size(getParam<unsigned
int>(
"max_leaf_size")),
244 _patch_update_strategy(
245 getParam<
MooseEnum>(
"patch_update_strategy").getEnum<
Moose::PatchUpdateType>()),
246 _regular_orthogonal_mesh(false),
247 _is_split(getParam<bool>(
"_is_split")),
248 _allow_recovery(true),
249 _construct_node_list_from_side_list(getParam<bool>(
"construct_node_list_from_side_list")),
250 _displace_node_list_by_side_list(getParam<bool>(
"displace_node_list_by_side_list")),
252 _allow_remote_element_removal(true),
253 _need_ghost_ghosted_boundaries(true),
254 _is_displaced(false),
257 _rz_coord_axis(getParam<
MooseEnum>(
"rz_coord_axis")),
258 _coord_system_set(false),
259 _doing_p_refinement(false)
262 mooseError(
"Ghosting patch size parameter has to be set in the mesh block "
263 "only when 'iteration' patch update strategy is used.");
269 "You set both 'Mesh/block' and 'Mesh/coord_block'. The value of "
270 "'Mesh/coord_block' will be used.");
277 if (getParam<bool>(
"build_all_side_lowerd_mesh"))
283#ifdef MOOSE_KOKKOS_ENABLED
285 _kokkos_mesh = std::make_unique<Moose::Kokkos::Mesh>(*
this);
293 _built_from_other_mesh(true),
294 _parallel_type(other_mesh._parallel_type),
295 _use_distributed_mesh(other_mesh._use_distributed_mesh),
296 _distribution_overridden(other_mesh._distribution_overridden),
297 _parallel_type_overridden(other_mesh._parallel_type_overridden),
298 _mesh(other_mesh.getMesh().clone()),
299 _partitioner_name(other_mesh._partitioner_name),
300 _partitioner_overridden(other_mesh._partitioner_overridden),
301 _custom_partitioner_requested(other_mesh._custom_partitioner_requested),
302 _uniform_refine_level(other_mesh.uniformRefineLevel()),
303 _skip_refine_when_use_split(other_mesh._skip_refine_when_use_split),
304 _skip_deletion_repartition_after_refine(other_mesh._skip_deletion_repartition_after_refine),
305 _is_nemesis(other_mesh._is_nemesis),
306 _mesh_subdomains(other_mesh._mesh_subdomains),
307 _mesh_boundary_ids(other_mesh._mesh_boundary_ids),
308 _mesh_sideset_ids(other_mesh._mesh_sideset_ids),
309 _mesh_nodeset_ids(other_mesh._mesh_nodeset_ids),
310 _patch_size(other_mesh._patch_size),
311 _ghosting_patch_size(other_mesh._ghosting_patch_size),
312 _max_leaf_size(other_mesh._max_leaf_size),
313 _patch_update_strategy(other_mesh._patch_update_strategy),
314 _regular_orthogonal_mesh(false),
315 _is_split(other_mesh._is_split),
316 _allow_recovery(other_mesh._allow_recovery),
317 _construct_node_list_from_side_list(other_mesh._construct_node_list_from_side_list),
318 _displace_node_list_by_side_list(other_mesh._displace_node_list_by_side_list),
319 _need_delete(other_mesh._need_delete),
320 _allow_remote_element_removal(other_mesh._allow_remote_element_removal),
321 _need_ghost_ghosted_boundaries(other_mesh._need_ghost_ghosted_boundaries),
322 _coord_sys(other_mesh._coord_sys),
323 _rz_coord_axis(other_mesh._rz_coord_axis),
324 _subdomain_id_to_rz_coord_axis(other_mesh._subdomain_id_to_rz_coord_axis),
325 _coord_system_set(other_mesh._coord_system_set),
326 _provided_coord_blocks(other_mesh._provided_coord_blocks),
327 _doing_p_refinement(other_mesh._doing_p_refinement)
330 "The mesh being cloned from must already be fully prepared; we rely on that to "
331 "rebuild our own prepare()-derived caches below");
334 for (std::size_t i = 0; i <
_bounds.size(); ++i)
337 for (std::size_t j = 0; j <
_bounds[i].size(); ++j)
343#ifdef MOOSE_KOKKOS_ENABLED
345 _kokkos_mesh = std::make_unique<Moose::Kokkos::Mesh>(*
this);
399 TIME_SECTION(
"prepare", 2,
"Preparing Mesh",
true);
401 parallel_object_only();
403 mooseAssert(
_mesh,
"The MeshBase has not been constructed");
407 getMesh().allow_renumbering(
false);
409 if (!
_mesh->is_prepared())
411 _mesh->complete_preparation();
420 for (
const auto &
elem :
getMesh().element_ptr_range())
427 const auto & add_subdomain_id = getParam<std::vector<SubdomainID>>(
"add_subdomain_ids");
432 const auto add_subdomain =
433 getParam<SubdomainID, SubdomainName>(
"add_subdomain_ids",
"add_subdomain_names");
434 for (
const auto & [sub_id, sub_name] : add_subdomain)
445 const auto & add_subdomain_names = getParam<std::vector<SubdomainName>>(
"add_subdomain_names");
448 subdomain_id_type offset = 0;
453 for (
const SubdomainName & sub_name : add_subdomain_names)
456 if (
getSubdomainID(sub_name) != libMesh::Elem::invalid_subdomain_id)
458 const auto sub_id = ++offset;
470 const std::set<BoundaryID> & local_bids =
getMesh().get_boundary_info().get_boundary_ids();
473 const std::set<BoundaryID> & local_node_bids =
474 getMesh().get_boundary_info().get_node_boundary_ids();
477 const std::set<BoundaryID> & local_side_bids =
478 getMesh().get_boundary_info().get_side_boundary_ids();
483 auto add_sets = [
this](
const bool sidesets,
auto & set_ids)
485 const std::string
type = sidesets ?
"sideset" :
"nodeset";
486 const std::string id_param =
"add_" +
type +
"_ids";
491 const auto & add_ids = getParam<std::vector<BoundaryID>>(id_param);
493 set_ids.insert(add_ids.begin(), add_ids.end());
496 const auto & add_names = getParam<std::vector<BoundaryName>>(
name_param);
497 mooseAssert(add_names.size() == add_ids.size(),
498 "Id and name sets must be the same size when adding.");
499 for (
const auto i : index_range(add_ids))
506 const auto & add_names = getParam<std::vector<BoundaryName>>(
name_param);
511 boundary_id_type offset = 0;
512 if (!mesh_ids.empty())
513 offset = *mesh_ids.rbegin();
518 for (
const auto &
name : add_names)
523 const auto id = ++offset;
551 "Trying to set coordinate system type information based on the user input file, but "
552 "the coordinate system type information has already been set programmatically! "
553 "Either remove your coordinate system type information from the input file, or contact "
554 "your application developer");
561 const auto rz_coord_blocks = getParam<std::vector<SubdomainName>>(
"rz_coord_blocks");
562 const auto rz_coord_origins = getParam<std::vector<Point>>(
"rz_coord_origins");
563 const auto rz_coord_directions = getParam<std::vector<RealVectorValue>>(
"rz_coord_directions");
564 if (rz_coord_origins.size() == rz_coord_blocks.size() &&
565 rz_coord_directions.size() == rz_coord_blocks.size())
567 std::vector<std::pair<Point, RealVectorValue>> rz_coord_axes;
568 for (
unsigned int i = 0; i < rz_coord_origins.size(); ++i)
569 rz_coord_axes.push_back(std::make_pair(rz_coord_origins[i], rz_coord_directions[i]));
574 mooseError(
"The parameter 'rz_coord_axis' may not be provided if 'rz_coord_blocks', "
575 "'rz_coord_origins', and 'rz_coord_directions' are provided.");
578 mooseError(
"The parameters 'rz_coord_blocks', 'rz_coord_origins', and "
579 "'rz_coord_directions' must all have the same size.");
583 mooseError(
"If any of the parameters 'rz_coord_blocks', 'rz_coord_origins', and "
584 "'rz_coord_directions' are provided, then all must be provided.");
599 mooseDeprecated(
"MooseMesh::prepare(const MeshBase *) is deprecated, please use the "
600 "no-argument MooseMesh::prepare() instead");
601 mooseAssert(!mesh_to_clone,
"Cloning a mesh_to_clone is no longer supported by prepare()");
612 mooseAssert(
_node_to_elem_map.empty(),
"If it hasn't been built, it better well be empty");
625 TIME_SECTION(
"update", 3,
"Updating Mesh",
true);
639 for (
const auto &
elem :
getMesh().active_local_element_ptr_range())
654#ifdef MOOSE_KOKKOS_ENABLED
670 if (!
mesh.is_serial())
672 "Hybrid finite element method must use replicated mesh.\nCurrently lower-dimensional mesh "
673 "does not support mesh re-partitioning and a debug assertion being hit related with "
674 "neighbors of lower-dimensional element, with distributed mesh.");
677 if (!
mesh.is_prepared())
678 mesh.find_neighbors();
681 unsigned int max_n_sides = 0;
684 std::set<Elem *> deleteable_elems;
685 for (
auto &
elem :
mesh.element_ptr_range())
688 deleteable_elems.insert(
elem);
689 else if (
elem->n_sides() > max_n_sides)
690 max_n_sides =
elem->n_sides();
692 for (
auto &
elem : deleteable_elems)
701 mesh.comm().max(max_n_sides);
703 deleteable_elems.clear();
706 std::set<int> interior_side_types;
707 std::set<int> boundary_side_types;
708 for (
const auto &
elem :
mesh.active_element_ptr_range())
709 for (
const auto side :
elem->side_index_range())
711 Elem * neig =
elem->neighbor_ptr(side);
712 std::unique_ptr<Elem> side_elem(
elem->build_side_ptr(side));
714 interior_side_types.insert(side_elem->type());
716 boundary_side_types.insert(side_elem->type());
718 mesh.comm().set_union(interior_side_types);
719 mesh.comm().set_union(boundary_side_types);
722 std::map<ElemType, SubdomainID> interior_block_ids;
723 std::map<ElemType, SubdomainID> boundary_block_ids;
725 auto id = libMesh::Elem::invalid_subdomain_id - 2;
726 for (
const auto & tpid : interior_side_types)
728 const auto type = ElemType(tpid);
729 mesh.set_subdomain_name(
731 interior_block_ids[
type] = id;
734 mooseError(
"Trying to add a mesh block with id ",
id,
" that has existed in the mesh");
738 for (
const auto & tpid : boundary_side_types)
740 const auto type = ElemType(tpid);
741 mesh.set_subdomain_name(
743 boundary_block_ids[
type] = id;
746 mooseError(
"Trying to add a mesh block with id ",
id,
" that has existed in the mesh");
751 dof_id_type max_elem_id =
mesh.max_elem_id();
752 unique_id_type max_unique_id =
mesh.parallel_max_unique_id();
754 std::vector<Elem *> side_elems;
756 for (
const auto &
elem :
mesh.active_element_ptr_range())
759 if (
elem->interior_parent())
762 for (
const auto side :
elem->side_index_range())
764 Elem * neig =
elem->neighbor_ptr(side);
766 bool build_side =
false;
771 mooseAssert(!neig->is_remote(),
"We error if the mesh is not serial");
774 else if (neig->level() ==
elem->level() &&
elem->id() < neig->id())
780 std::unique_ptr<Elem> side_elem(
elem->build_side_ptr(side));
783 side_elem->processor_id() =
elem->processor_id();
787 side_elem->subdomain_id() = interior_block_ids.at(side_elem->type());
789 side_elem->subdomain_id() = boundary_block_ids.at(side_elem->type());
792 side_elem->set_id(max_elem_id +
elem->id() * max_n_sides + side);
793 side_elem->set_unique_id(max_unique_id +
elem->id() * max_n_sides + side);
798 side_elem->set_interior_parent(
elem);
800 side_elems.push_back(side_elem.release());
803 auto pair = std::make_pair(
elem, side);
804 auto link = std::make_pair(pair, side_elems.back());
805 auto ilink = std::make_pair(side_elems.back(), side);
816 for (
auto &
elem : side_elems)
821 const bool skip_partitioning_old =
mesh.skip_partitioning();
822 mesh.skip_partitioning(
true);
824 mesh.allow_find_neighbors(
false);
825 mesh.prepare_for_use();
826 mesh.skip_partitioning(skip_partitioning_old);
832 mooseDeprecated(
"MooseMesh::node() is deprecated, please use MooseMesh::nodeRef() instead");
839 mooseDeprecated(
"MooseMesh::node() is deprecated, please use MooseMesh::nodeRef() instead");
847 mooseAssert(node_ptr,
"Missing node");
872 if (i >
getMesh().max_node_id())
877 auto & node_ptr = it->second;
878 mooseAssert(node_ptr,
"Uninitialized quadrature node");
882 return getMesh().query_node_ptr(i);
894 TIME_SECTION(
"meshChanged", 3,
"Updating Because Mesh Changed");
924 TIME_SECTION(
"cacheChangedLists", 5,
"Caching Changed Lists");
926 ConstElemRange elem_range(
getMesh().local_elements_begin(),
getMesh().local_elements_end(), 1);
951const std::vector<const Elem *> &
956 return elem_to_child_pair->second;
962 TIME_SECTION(
"updateActiveSemiLocalNodeRange", 5,
"Updating ActiveSemiLocalNode Range");
968 for (
const auto &
elem : *active_local_elems)
970 for (
unsigned int n = 0; n <
elem->n_nodes(); ++n)
977 Node *
node =
const_cast<Node *
>(
elem->node_ptr(n));
984 for (
const auto & ghost_elem_id : ghosted_elems)
987 for (
unsigned int n = 0; n <
elem->n_nodes(); n++)
1036 TIME_SECTION(
"buildNodeList", 5,
"Building Node List");
1040 auto bc_tuples =
getMesh().get_boundary_info().build_node_list();
1042 int n = bc_tuples.size();
1045 for (
const auto & t : bc_tuples)
1047 auto node_id = std::get<0>(t);
1048 auto bc_id = std::get<1>(t);
1076 for (
auto &
elem : as_range(
mesh.local_elements_begin(),
mesh.local_elements_end()))
1081 for (
unsigned int side = 0; side <
elem->n_sides(); ++side)
1093 unsigned int n =
getMesh().n_elem_integers() + 1;
1101 _max_ids.resize(n, std::numeric_limits<dof_id_type>::min());
1102 _min_ids.resize(n, std::numeric_limits<dof_id_type>::max());
1104 for (
const auto &
elem :
getMesh().active_local_element_ptr_range())
1105 for (
unsigned int i = 0; i < n; ++i)
1107 auto id = (i == n - 1 ?
elem->subdomain_id() :
elem->get_extra_integer(i));
1113 for (
unsigned int j = 0; j < n; ++j)
1115 auto idj = (j == n - 1 ?
elem->subdomain_id() :
elem->get_extra_integer(j));
1121 for (
unsigned int i = 0; i < n; ++i)
1131std::unordered_map<dof_id_type, std::set<dof_id_type>>
1136 if (!mesh_base.has_elem_integer(from_id_name))
1137 mooseError(
"Mesh does not have the element integer name '", from_id_name,
"'");
1138 if (!mesh_base.has_elem_integer(to_id_name))
1139 mooseError(
"Mesh does not have the element integer name '", to_id_name,
"'");
1141 const auto id1 = mesh_base.get_elem_integer_index(from_id_name);
1142 const auto id2 = mesh_base.get_elem_integer_index(to_id_name);
1144 std::unordered_map<dof_id_type, std::set<dof_id_type>> id_map;
1146 id_map[
id] = std::set<dof_id_type>();
1148 for (
const auto &
elem : mesh_base.active_local_element_ptr_range())
1149 id_map[
elem->get_extra_integer(id1)].insert(
elem->get_extra_integer(id2));
1151 for (
auto & [
id, ids] : id_map)
1160std::set<dof_id_type>
1163 std::set<dof_id_type> unique_ids;
1165 for (
auto &
id : pair.second)
1166 unique_ids.insert(
id);
1170std::set<dof_id_type>
1173 std::set<dof_id_type> unique_ids;
1174 for (
auto & blk : blks)
1178 mooseError(
"Block ", blk,
" is not available on the mesh");
1180 for (
auto & mid : it->second)
1181 unique_ids.insert(mid);
1189 TIME_SECTION(
"buildBndElemList", 5,
"Building Boundary Elements List");
1193 auto bc_tuples =
getMesh().get_boundary_info().build_active_side_list();
1195 int n = bc_tuples.size();
1198 for (
const auto & t : bc_tuples)
1200 auto elem_id = std::get<0>(t);
1201 auto side_id = std::get<1>(t);
1202 auto bc_id = std::get<2>(t);
1209std::unordered_map<dof_id_type, std::vector<dof_id_type>> &
1224 TIME_SECTION(
"nodeToElemMap", 5,
"Building Node To Elem Map");
1228 for (
const auto &
elem :
getMesh().active_element_ptr_range())
1229 for (
unsigned int n = 0; n <
elem->n_nodes(); n++)
1238const std::unordered_map<dof_id_type, std::vector<dof_id_type>> &
1244const ConstElemRange *
1247 return &
getMesh().active_local_element_stored_range();
1255 TIME_SECTION(
"getActiveNodeRange", 5);
1258 std::make_unique<NodeRange>(
getMesh().active_nodes_begin(),
getMesh().active_nodes_end());
1268 "_active_semilocal_node_range has not been created yet!");
1278 TIME_SECTION(
"getLocalNodeRange", 5);
1292 TIME_SECTION(
"getBoundaryNodeRange", 5);
1305 TIME_SECTION(
"getBoundaryElementRange", 5);
1313const std::unordered_map<boundary_id_type, std::unordered_set<dof_id_type>> &
1317 "use MooseMesh::getBoundariesToActiveSemiLocalElemIds");
1321const std::unordered_map<boundary_id_type, std::unordered_set<dof_id_type>> &
1327std::unordered_set<dof_id_type>
1334 return std::unordered_set<dof_id_type>{};
1338std::unordered_set<dof_id_type>
1342 std::unordered_set<dof_id_type> neighbor_elems;
1345 const auto & [elem_ptr, elem_side, elem_bid] = *bnd_elem;
1346 if (elem_bid == bid)
1348 const auto * neighbor = elem_ptr->neighbor_ptr(elem_side);
1353 if (neighbor->active())
1354 neighbor_elems.insert(neighbor->id());
1357 std::vector<const Elem *> family;
1358 neighbor->active_family_tree_by_neighbor(family, elem_ptr);
1359 for (
const auto & child_neighbor : family)
1360 neighbor_elems.insert(child_neighbor->id());
1366 return neighbor_elems;
1371 const std::set<SubdomainID> & blk_group)
const
1373 mooseAssert(
_bnd_elem_range,
"Boundary element range is not initialized");
1378 const auto & [elem_ptr, elem_side, elem_bid] = *bnd_elem;
1379 if (elem_bid == bid)
1382 if (blk_group.find(elem_ptr->subdomain_id()) != blk_group.end())
1384 const auto *
const neighbor = elem_ptr->neighbor_ptr(elem_side);
1388 mooseError(
"Insufficient level of geometrical ghosting to determine "
1389 "if a boundary is internal to the mesh");
1395 if (blk_group.find(neighbor->subdomain_id()) != blk_group.end())
1406 TIME_SECTION(
"cacheInfo", 3);
1419 for (
const auto &
elem :
mesh.element_ptr_range())
1421 const Elem * ip_elem =
elem->interior_parent();
1425 unsigned int ip_side = ip_elem->which_side_am_i(
elem);
1430 auto pair = std::make_pair(ip_elem, ip_side);
1432 std::pair<std::pair<const Elem *, unsigned short int>,
const Elem *>(pair,
elem));
1434 std::pair<const Elem *, unsigned short int>(
elem, ip_side));
1436 auto id =
elem->subdomain_id();
1437 if (ip_elem->neighbor_ptr(ip_side))
1439 if (
mesh.subdomain_name(
id).find(
"INTERNAL_SIDE_LOWERD_SUBDOMAIN_") != std::string::npos)
1444 if (
mesh.subdomain_name(
id).find(
"BOUNDARY_SIDE_LOWERD_SUBDOMAIN_") != std::string::npos)
1450 for (
unsigned int nd = 0; nd <
elem->n_nodes(); ++nd)
1452 const Node &
node = *
elem->node_ptr(nd);
1460 for (
const auto &
elem :
mesh.active_local_element_ptr_range())
1465 for (
unsigned int side = 0; side <
elem->n_sides(); side++)
1467 const auto & boundary_ids = elem_boundary_ids[side];
1468 sub_data.boundary_ids.insert(boundary_ids.begin(), boundary_ids.end());
1470 const Elem * neig =
elem->neighbor_ptr(side);
1474 boundary_ids.end());
1475 SubdomainID neighbor_subdomain_id = neig->subdomain_id();
1476 if (neighbor_subdomain_id != subdomain_id)
1477 sub_data.neighbor_subs.insert(neighbor_subdomain_id);
1491const std::set<SubdomainID> &
1497 mooseError(
"Unable to find node: ",
node.id(),
" in any block list.");
1579 for (
const auto &
node :
getMesh().node_ptr_range())
1583 Node *
node =
nullptr;
1584 for (
unsigned int i = 0; i <
_node_map.size(); ++i)
1586 if (p.relative_fuzzy_equals(*
_node_map[i], tol))
1592 if (
node ==
nullptr)
1598 mooseAssert(
node !=
nullptr,
"Node is NULL");
1604 const unsigned short int side,
1605 const unsigned int qp,
1607 const Point & point)
1621 dof_id_type max_id = std::numeric_limits<unsigned int>::max() - 100;
1624 if (new_id <=
getMesh().max_node_id())
1625 mooseError(
"Quadrature node id collides with existing node id!");
1627 qnode =
new Node(point, new_id);
1653 const unsigned short int side,
1654 const unsigned int qp)
1658 "Elem has no quadrature nodes!");
1661 "Side has no quadrature nodes!");
1664 "qp not found on side!");
1686 if (boundary_name ==
"ANY_BOUNDARY_ID")
1687 mooseError(
"Please use getBoundaryIDs() when passing \"ANY_BOUNDARY_ID\"");
1714std::vector<BoundaryID>
1716 bool generate_unknown)
const
1728std::vector<SubdomainID>
1734std::set<SubdomainID>
1742 const SubdomainName & name,
1743 const bool synchronous)
1751 const SubdomainName & name,
1752 const bool synchronous)
1754 mooseAssert(
name !=
"ANY_BLOCK_ID",
"Cannot set subdomain name to 'ANY_BLOCK_ID'");
1755 mesh.set_subdomain_name(subdomain_id,
name, synchronous);
1761 return getMesh().subdomain_name(subdomain_id);
1764std::vector<SubdomainName>
1767 std::vector<SubdomainName> names(subdomain_ids.size());
1769 for (
unsigned int i = 0; i < subdomain_ids.size(); i++)
1778 BoundaryInfo & boundary_info =
getMesh().get_boundary_info();
1781 if (boundary_info.get_side_boundary_ids().count(boundary_id))
1782 boundary_info.sideset_name(boundary_id) =
name;
1784 boundary_info.nodeset_name(boundary_id) =
name;
1790 const BoundaryInfo & boundary_info =
getMesh().get_boundary_info();
1793 if (boundary_info.get_side_boundary_ids().count(boundary_id))
1794 return boundary_info.get_sideset_name(boundary_id);
1796 return boundary_info.get_nodeset_name(boundary_id);
1803 return name.size() ?
name : std::to_string(boundary_id);
1812 return *(item.first);
1817 unsigned int var_number,
1820 TIME_SECTION(
"buildPeriodicNodeMap", 5);
1823 periodic_node_map.clear();
1826 std::vector<PeriodicNodeInfo> periodic_nodes;
1827 for (
const auto & t :
getMesh().get_boundary_info().build_node_list())
1830 auto node =
_mesh->node_ptr(std::get<0>(t));
1831 mooseAssert(
node !=
nullptr,
1832 "libMesh::BoundaryInfo::build_node_list() returned an ID for a non-existing node");
1833 auto bc_id = std::get<1>(t);
1834 periodic_nodes.emplace_back(
node, bc_id);
1838 std::sort(periodic_nodes.begin(),
1839 periodic_nodes.end(),
1841 { return a.second > b.second; });
1844 using KDTreeType = nanoflann::KDTreeSingleIndexAdaptor<
1845 nanoflann::L2_Simple_Adaptor<Real, PointListAdaptor<PeriodicNodeInfo>, Real, std::size_t>,
1849 const unsigned int max_leaf_size = 20;
1852 auto kd_tree = std::make_unique<KDTreeType>(
1853 LIBMESH_DIM, point_list, nanoflann::KDTreeSingleIndexAdaptorParams(max_leaf_size));
1854 mooseAssert(kd_tree !=
nullptr,
"KDTree was not properly initialized.");
1855 kd_tree->buildIndex();
1859 std::vector<nanoflann::ResultItem<std::size_t, Real>> ret_matches;
1863 BoundaryID current_bc_id = BoundaryInfo::invalid_id;
1864 for (
auto & pair : periodic_nodes)
1867 if (pair.second != current_bc_id)
1869 current_bc_id = pair.second;
1870 periodic = pbs->
boundary(current_bc_id);
1880 ret_matches.clear();
1883 const auto id = pair.first->id();
1889 kd_tree->radiusSearch(&(search_point)(0),
libMesh::TOLERANCE, ret_matches, search_params);
1890 for (
auto & match_pair : ret_matches)
1892 const auto & match = periodic_nodes[match_pair.first];
1895 periodic_node_map.emplace(
id, match.first->id());
1902 unsigned int var_number,
1905 TIME_SECTION(
"buildPeriodicNodeSets", 5);
1907 periodic_node_sets.clear();
1910 for (
const auto & t :
getMesh().get_boundary_info().build_node_list())
1912 auto node_id = std::get<0>(t);
1913 auto bc_id = std::get<1>(t);
1916 if (periodic_node_sets.find(bc_id) != periodic_node_sets.end())
1917 periodic_node_sets[bc_id].insert(node_id);
1922 periodic_node_sets[bc_id].insert(node_id);
1930 TIME_SECTION(
"detectOrthogonalDimRanges", 5);
1935 std::vector<Real> min(3, std::numeric_limits<Real>::max());
1936 std::vector<Real> max(3, std::numeric_limits<Real>::min());
1937 unsigned int dim =
getMesh().mesh_dimension();
1940 for (
const auto &
node :
getMesh().node_ptr_range())
1945 if ((*
node)(i) < min[i])
1946 min[i] = (*node)(i);
1947 if ((*
node)(i) > max[i])
1948 max[i] = (*node)(i);
1956 std::vector<bool> extreme_matches(8,
false);
1957 std::vector<unsigned int> comp_map(3);
1958 for (
const auto &
node :
getMesh().node_ptr_range())
1961 unsigned int coord_match = 0;
1965 if (std::abs((*
node)(i)-min[i]) < tol)
1970 else if (std::abs((*
node)(i)-max[i]) < tol)
1977 if (coord_match == LIBMESH_DIM)
1980 extreme_matches[comp_map[
X] * 4 + comp_map[
Y] * 2 + comp_map[
Z]] =
true;
1985 this->
comm().
max(extreme_matches);
1986 if (std::count(extreme_matches.begin(), extreme_matches.end(),
true) == (1 <<
dim))
2004 TIME_SECTION(
"detectPairedSidesets", 5);
2018 const unsigned int mesh_dim =
getMesh().mesh_dimension();
2021 static constexpr std::array<std::size_t, 3> unit_dims{0, 1, 2};
2023 static const std::array<std::string, 3> unit_dim_names{
"x",
"y",
"z"};
2029 std::array<std::array<std::array<std::set<BoundaryID>, 2>, 3>, 3> ids{};
2032 std::array<std::unique_ptr<FEBase>, 3> fe_faces{};
2033 std::array<std::unique_ptr<libMesh::QGauss>, 3> qfaces{};
2034 for (
const auto side_dim : make_range(mesh_dim))
2038 qfaces[side_dim] = std::unique_ptr<libMesh::QGauss>(
new libMesh::QGauss(side_dim, CONSTANT));
2041 fe_faces[side_dim] = FEBase::build(side_dim + 1, FEType(FIRST,
libMesh::LAGRANGE));
2042 fe_faces[side_dim]->attach_quadrature_rule(qfaces[side_dim].get());
2043 fe_faces[side_dim]->get_normals();
2047 const auto & boundary_info =
getMesh().get_boundary_info();
2049 std::vector<boundary_id_type> face_ids;
2052 std::set<unsigned int> side_dims;
2056 for (
auto &
elem : as_range(
getMesh().level_elements_begin(0),
getMesh().level_elements_end(0)))
2059 if (!
elem->on_boundary())
2062 const auto side_dim =
elem->dim() - 1;
2063 side_dims.insert(side_dim);
2066 for (
const auto s :
elem->side_index_range())
2067 if (!
elem->neighbor_ptr(s))
2070 fe_faces[side_dim]->reinit(
elem, s);
2071 const auto & normal = fe_faces[side_dim]->get_normals()[0];
2077 boundary_info.boundary_ids(
elem, s, face_ids);
2080 for (
const auto unit_dim : unit_dims)
2084 nonzero_dims[unit_dim] =
true;
2086 for (
const auto plus : {
false,
true})
2090 ids[side_dim][unit_dim][plus].insert(face_ids.begin(), face_ids.end());
2110 std::vector<std::tuple<unsigned int, unsigned int, unsigned char, boundary_id_type>> id_data;
2111 for (
const auto side_dim : side_dims)
2112 for (
const auto unit_dim : unit_dims)
2113 for (
const auto plus : {
false,
true})
2114 for (
const auto bd : ids[side_dim][unit_dim][plus])
2115 id_data.emplace_back(side_dim, unit_dim, plus, bd);
2117 for (
const auto & [side_dim, unit_dim, plus_char, bd] : id_data)
2118 ids[side_dim][unit_dim][
bool(plus_char)].insert(bd);
2121 for (
auto & entry : nonzero_dims)
2129 std::ostringstream oss_found, oss_missing;
2130 for (
const auto side_dim : side_dims)
2132 for (
const auto unit_dim : unit_dims)
2133 if (nonzero_dims[unit_dim])
2135 const auto & unit_name = unit_dim_names[unit_dim];
2136 const auto & minus = ids[side_dim][unit_dim][
false];
2137 const auto & plus = ids[side_dim][unit_dim][
true];
2139 if (minus.size() == 1 && plus.size() == 1)
2141 const auto get_boundary_name = [
this](
const auto id)
2144 return name.size() ?
name : std::to_string(
id);
2147 oss_found <<
"\n " << side_dim + 1 <<
"D " << unit_name
2148 <<
"-direction: " << get_boundary_name(*minus.begin()) <<
" <-> "
2149 << get_boundary_name(*plus.begin());
2150 _paired_boundary->emplace_back(std::make_pair(*minus.begin(), *plus.begin()));
2153 oss_missing <<
"\n " << side_dim + 1 <<
"D -" << unit_name <<
"/+" << unit_name
2154 <<
": Found " << minus.size() <<
" -" << unit_name <<
" boundaries and "
2155 << plus.size() <<
" +" << unit_name <<
" boundaries";
2159 std::ostringstream oss;
2160 const auto found = oss_found.str();
2161 const auto missing = oss_missing.str();
2163 oss <<
"The following paired boundaries were automatically detected for periodicity:\n"
2169 oss <<
"Paired boundaries were not automatically detected for the following:\n"
2171 <<
"\n\nAutomatic detection requires that exactly one boundary is found in each unit "
2187 mooseAssert(
_mesh,
"The MeshBase has not been constructed");
2188 mooseAssert(component <
_bounds.size(),
"Requested dimension out of bounds");
2196 mooseAssert(
_mesh,
"The MeshBase has not been constructed");
2197 mooseAssert(component <
_bounds.size(),
"Requested dimension out of bounds");
2204 const unsigned int var_num,
2211 const auto key = std::make_pair(sys_num, var_num);
2216 bool component_found =
false;
2217 for (
const auto component : make_range(
dimension()))
2221 if (boundary_ids && ((boundary_ids->first == primary && boundary_ids->second == secondary) ||
2222 (boundary_ids->first == secondary && boundary_ids->second == primary)))
2224 entry[component] =
true;
2225 component_found =
true;
2229 if (!component_found)
2230 mooseWarning(
"Could not find a match between boundary '",
2234 "' to set periodic boundary conditions for variable (index:",
2236 ") in either the X, Y or Z direction. The periodic dimension of the mesh for this "
2237 "variable will not be stored.");
2240const std::array<bool, 3> &
2243 const auto key = std::make_pair(sys_num, var_num);
2249const std::array<bool, 3> &
2257 const unsigned int var_num,
2258 const unsigned int component)
const
2260 mooseAssert(component <
dimension(),
"Requested dimension out of bounds");
2274 "MooseMesh::isTranslatedPeriodic(const unsigned int, const unsigned int) is deprecated. Use "
2275 "the method that additionally takes the system number or the MooseVariableBase instead."));
2281 const unsigned int var_num,
2287 for (
const auto i : make_range(
dimension()))
2290 if (periodic_dims[i])
2318 mooseDoOnce(
mooseDeprecated(
"MooseMesh::minPeriodicVector(const unsigned int, const Point &, "
2319 "const Point &) is deprecated. Use the method that additionally "
2320 "takes the system number or the MooseVariableBase instead."));
2326 const unsigned int var_num,
2328 const Point & q)
const
2336 const Point & q)
const
2344 mooseDoOnce(
mooseDeprecated(
"MooseMesh::minPeriodicDistance(const unsigned int, const Point &, "
2345 "const Point &) is deprecated. Use the method that additionally "
2346 "takes the system number or the MooseVariableBase instead."));
2350const std::pair<BoundaryID, BoundaryID> *
2354 mooseError(
"Trying to retrieve automatic paired mapping for a mesh that is not regular and "
2357 mooseAssert(component <
dimension(),
"Requested dimension out of bounds");
2360 mooseError(
"MooseMesh::getPairedBoundaryMapping(): Paired boundaries not built; must call "
2361 "detectPairedSidesets() first");
2363 if (component < _paired_boundary->size())
2364 return &(*_paired_boundary)[component];
2372 std::map<ElemType, Elem *> canonical_elems;
2376 for (
const auto &
elem :
getMesh().element_ptr_range())
2380 if (canonical_elems.find(
type) ==
2381 canonical_elems.end())
2385 Elem * stored = canonical_elems[
type];
2386 if (
elem->id() < stored->id())
2392 for (
const auto & can_it : canonical_elems)
2394 Elem *
elem = can_it.second;
2410 for (
unsigned int side = 0; side <
elem->n_sides(); side++)
2418 for (
unsigned int child = 0; child <
elem->n_children(); ++child)
2419 for (
unsigned int side = 0; side <
elem->n_sides();
2421 if (!
elem->is_child_on_side(child, side))
2434 std::map<ElemType, std::pair<Elem *, unsigned int>> elems_and_max_p_level;
2436 for (
const auto &
elem :
getMesh().active_element_ptr_range())
2439 auto & [picked_elem, max_p_level] = elems_and_max_p_level[
type];
2442 max_p_level = std::max(max_p_level,
elem->p_level());
2447 std::vector<Point> volume_ref_points_coarse, volume_ref_points_fine, face_ref_points_coarse,
2448 face_ref_points_fine;
2449 std::vector<unsigned int> p_levels;
2451 for (
auto & [elem_type, elem_p_level_pair] : elems_and_max_p_level)
2453 auto & [moose_elem, max_p_level] = elem_p_level_pair;
2454 const auto dim = moose_elem->dim();
2457 assembly->
reinit(moose_elem);
2458 assembly->
reinit(moose_elem, 0);
2463 ReplicatedMesh
mesh(self_comm);
2465 for (
const auto & nd : moose_elem->node_ref_range())
2468 Elem *
const elem =
mesh.add_elem(Elem::build(elem_type).release());
2469 for (
const auto i :
elem->node_index_range())
2470 elem->set_node(i,
mesh.node_ptr(i));
2472 std::unique_ptr<FEBase> fe_face(FEBase::build(
dim, p_refinable_fe_type));
2474 const auto & face_phys_points = fe_face->get_xyz();
2475 fe_face->attach_quadrature_rule(qrule_face);
2478 volume_ref_points_coarse = qrule->get_points();
2479 fe_face->reinit(
elem, (
unsigned int)0);
2482 p_levels.resize(max_p_level + 1);
2483 std::iota(p_levels.begin(), p_levels.end(), 0);
2486 for (
const auto p_level : p_levels)
2490 volume_ref_points_fine = qrule->get_points();
2491 fe_face->reinit(
elem, (
unsigned int)0);
2494 const auto map_key = std::make_pair(elem_type, p_level);
2500 auto fill_maps = [
this](
const auto & coarse_ref_points,
2501 const auto & fine_ref_points,
2505 mapPoints(fine_ref_points, coarse_ref_points, refine_map);
2506 mapPoints(coarse_ref_points, fine_ref_points, coarsen_map);
2510 volume_ref_points_coarse, volume_ref_points_fine, volume_coarsen_map, volume_refine_map);
2511 fill_maps(face_ref_points_coarse, face_ref_points_fine, face_coarsen_map, face_refine_map);
2514 volume_ref_points_fine.swap(volume_ref_points_coarse);
2515 face_ref_points_fine.swap(face_ref_points_coarse);
2523 TIME_SECTION(
"buildRefinementAndCoarseningMaps", 5,
"Building Refinement And Coarsening Maps");
2538 TIME_SECTION(
"buildRefinementMap", 5,
"Building Refinement Map");
2542 mooseAssert(parent_side == child_side,
2543 "Parent side must match child_side if not passing a specific child!");
2545 std::pair<int, ElemType> the_pair(parent_side,
elem.type());
2548 mooseError(
"Already built a qp refinement map!");
2550 std::vector<std::pair<unsigned int, QpMap>> coarsen_map;
2553 &
elem, qrule, qrule_face, refinement_map, coarsen_map, parent_side, child, child_side);
2557 std::pair<int, int> child_pair(child, child_side);
2563 mooseError(
"Already built a qp refinement map!");
2565 std::vector<std::pair<unsigned int, QpMap>> coarsen_map;
2566 std::vector<std::vector<QpMap>> & refinement_map =
2569 &
elem, qrule, qrule_face, refinement_map, coarsen_map, parent_side, child, child_side);
2573const std::vector<std::vector<QpMap>> &
2578 mooseAssert(parent_side == child_side,
2579 "Parent side must match child_side if not passing a specific child!");
2581 std::pair<int, ElemType> the_pair(parent_side,
elem.type());
2584 mooseError(
"Could not find a suitable qp refinement map!");
2590 std::pair<int, int> child_pair(child, child_side);
2596 mooseError(
"Could not find a suitable qp refinement map!");
2612 TIME_SECTION(
"buildCoarseningMap", 5,
"Building Coarsening Map");
2614 std::pair<int, ElemType> the_pair(input_side,
elem.type());
2617 mooseError(
"Already built a qp coarsening map!");
2619 std::vector<std::vector<QpMap>> refinement_map;
2620 std::vector<std::pair<unsigned int, QpMap>> & coarsen_map =
2627 &
elem, qrule, qrule_face, refinement_map, coarsen_map, input_side, -1, input_side);
2637const std::vector<std::pair<unsigned int, QpMap>> &
2640 std::pair<int, ElemType> the_pair(input_side,
elem.type());
2643 mooseError(
"Could not find a suitable qp refinement map!");
2650 const std::vector<Point> & to,
2651 std::vector<QpMap> & qp_map)
2653 unsigned int n_from = from.size();
2654 unsigned int n_to = to.size();
2656 qp_map.resize(n_from);
2658 for (
unsigned int i = 0; i < n_from; ++i)
2660 const Point & from_point = from[i];
2662 QpMap & current_map = qp_map[i];
2664 for (
unsigned int j = 0; j < n_to; ++j)
2666 const Point & to_point = to[j];
2667 Real
distance = (from_point - to_point).norm();
2672 current_map.
_from = i;
2673 current_map.
_to = j;
2683 std::vector<std::vector<QpMap>> & refinement_map,
2684 std::vector<std::pair<unsigned int, QpMap>> & coarsen_map,
2689 TIME_SECTION(
"findAdaptivityQpMaps", 5);
2692 mesh.skip_partitioning(
true);
2694 unsigned int dim = template_elem->dim();
2697 for (
unsigned int i = 0; i < template_elem->n_nodes(); ++i)
2698 mesh.add_point(template_elem->point(i));
2700 Elem *
elem =
mesh.add_elem(Elem::build(template_elem->type()).release());
2702 for (
unsigned int i = 0; i < template_elem->n_nodes(); ++i)
2703 elem->set_node(i,
mesh.node_ptr(i));
2705 std::unique_ptr<FEBase> fe(FEBase::build(
dim, FEType()));
2707 const std::vector<Point> & q_points_volume = fe->get_xyz();
2709 std::unique_ptr<FEBase> fe_face(FEBase::build(
dim, FEType()));
2711 const std::vector<Point> & q_points_face = fe_face->get_xyz();
2713 fe->attach_quadrature_rule(&qrule);
2714 fe_face->attach_quadrature_rule(&qrule_face);
2717 const std::vector<Point> * q_points;
2719 if (parent_side != -1)
2721 fe_face->reinit(
elem, parent_side);
2722 q_points = &q_points_face;
2727 q_points = &q_points_volume;
2730 std::vector<Point> parent_ref_points;
2739 std::map<unsigned int, std::vector<Point>> child_to_ref_points;
2741 unsigned int n_children =
elem->n_children();
2743 refinement_map.resize(n_children);
2745 std::vector<unsigned int> children;
2748 children.push_back(child);
2751 children.resize(n_children);
2752 for (
unsigned int child = 0; child < n_children; ++child)
2753 children[child] = child;
2756 for (
unsigned int i = 0; i < children.size(); ++i)
2758 unsigned int child = children[i];
2760 if ((parent_side != -1 && !
elem->is_child_on_side(child, parent_side)))
2763 const Elem * child_elem =
elem->child_ptr(child);
2765 if (child_side != -1)
2767 fe_face->reinit(child_elem, child_side);
2768 q_points = &q_points_face;
2772 fe->reinit(child_elem);
2773 q_points = &q_points_volume;
2776 std::vector<Point> child_ref_points;
2779 child_to_ref_points[child] = child_ref_points;
2781 std::vector<QpMap> & qp_map = refinement_map[child];
2784 mapPoints(child_ref_points, parent_ref_points, qp_map);
2787 coarsen_map.resize(parent_ref_points.size());
2790 for (
unsigned int child = 0; child < n_children; child++)
2792 if (parent_side != -1 && !
elem->is_child_on_side(child, child_side))
2795 std::vector<Point> & child_ref_points = child_to_ref_points[child];
2797 std::vector<QpMap> qp_map;
2800 mapPoints(parent_ref_points, child_ref_points, qp_map);
2803 for (
unsigned int parent_qp = 0; parent_qp < parent_ref_points.size(); ++parent_qp)
2805 std::pair<unsigned int, QpMap> & child_and_map = coarsen_map[parent_qp];
2806 unsigned int & closest_child = child_and_map.first;
2807 QpMap & closest_map = child_and_map.second;
2809 QpMap & current_map = qp_map[parent_qp];
2813 closest_child = child;
2814 closest_map = current_map;
2822 const boundary_id_type new_id,
2825 TIME_SECTION(
"changeBoundaryId", 6);
2831 const boundary_id_type old_id,
2832 const boundary_id_type new_id,
2836 BoundaryInfo & boundary_info =
mesh.get_boundary_info();
2839 std::vector<boundary_id_type> old_ids;
2842 for (
auto &
elem : as_range(
mesh.level_elements_begin(0),
mesh.level_elements_end(0)))
2844 unsigned int n_sides =
elem->n_sides();
2845 for (
unsigned int s = 0; s != n_sides; ++s)
2847 boundary_info.boundary_ids(
elem, s, old_ids);
2848 if (std::find(old_ids.begin(), old_ids.end(), old_id) != old_ids.end())
2850 std::vector<boundary_id_type> new_ids(old_ids);
2851 std::replace(new_ids.begin(), new_ids.end(), old_id, new_id);
2854 boundary_info.remove_side(
elem, s);
2855 boundary_info.add_side(
elem, s, new_ids);
2858 boundary_info.add_side(
elem, s, new_ids);
2867 boundary_info.remove_id(old_id);
2870 mesh.unset_has_boundary_id_sets();
2873const RealVectorValue &
2886 mooseError(
"MooseMesh::clone() is no longer supported, use MooseMesh::safeClone() instead.");
2917std::unique_ptr<MeshBase>
2920 std::unique_ptr<MeshBase>
mesh;
2922 mesh = buildTypedMesh<DistributedMesh>(
dim);
2924 mesh = buildTypedMesh<ReplicatedMesh>(
dim);
2932 _mesh = std::move(mesh_base);
2949 mooseError(
"You cannot use the mesh splitter capability with DistributedMesh!");
2951 TIME_SECTION(
"init", 2);
2958 const bool skip_partitioning_later =
getMesh().skip_partitioning();
2959 getMesh().skip_partitioning(
true);
2960 const bool allow_renumbering_later =
getMesh().allow_renumbering();
2961 getMesh().allow_renumbering(
false);
2966 TIME_SECTION(
"readRecoveredMesh", 2);
2970 getMesh().allow_renumbering(allow_renumbering_later);
2971 getMesh().skip_partitioning(skip_partitioning_later);
2977 getMesh().skip_partitioning(
true);
2980 if (getParam<bool>(
"build_all_side_lowerd_mesh"))
2985std::vector<std::filesystem::path>
2989 io.
write(file_base);
2996 return getMesh().mesh_dimension();
3002 const Real abs_zero = 1e-12;
3006 for (
unsigned int dim = LIBMESH_DIM;
dim >= 1; --
dim)
3020 if (
const auto & elem_dims =
mesh.elem_dimensions();
mesh.is_prepared() && elem_dims.size() == 1)
3021 return *elem_dims.begin();
3023 unsigned short dim = 0;
3025 const std::set<SubdomainID> subdomain_ids_set(subdomain_ids.begin(), subdomain_ids.end());
3026 for (
const auto &
elem :
mesh.active_subdomain_set_elements_ptr_range(subdomain_ids_set))
3034std::vector<BoundaryID>
3037 std::vector<BoundaryID> ids;
3038 getMesh().get_boundary_info().boundary_ids(
elem, side, ids);
3042std::vector<std::vector<BoundaryID>>
3045 std::vector<std::vector<BoundaryID>> ids;
3046 getMesh().get_boundary_info().side_boundary_ids(
elem, ids);
3050const std::set<BoundaryID> &
3053 return getMesh().get_boundary_info().get_boundary_ids();
3059 auto & boundary_info =
getMesh().get_boundary_info();
3063 const std::set<boundary_id_type> & side_bcids = boundary_info.get_side_boundary_ids();
3070 const std::set<boundary_id_type> & node_bcids = boundary_info.get_node_boundary_ids();
3074 boundary_id_type next_bcid = 0;
3075 if (!node_bcids.empty())
3076 next_bcid = std::max(next_bcid, cast_int<boundary_id_type>(*node_bcids.rbegin() + 1));
3077 if (!side_bcids.empty())
3078 next_bcid = std::max(next_bcid, cast_int<boundary_id_type>(*side_bcids.rbegin() + 1));
3088 if (next_bcid > 1000 || next_bcid <= 0)
3094 for (
auto bcid : side_bcids)
3095 if (node_bcids.count(bcid) &&
3096 (boundary_info.get_sideset_name(bcid) != boundary_info.get_nodeset_name(bcid)))
3098 boundary_info.renumber_node_id(bcid, next_bcid);
3102 }
while (node_bcids.count(next_bcid) || side_bcids.count(next_bcid));
3110 for (
auto & [
id,
name] : boundary_info.get_sideset_name_map())
3111 boundary_info.nodeset_name(
id) =
name;
3113 boundary_info.build_node_list_from_side_list();
3117std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>>
3120 return getMesh().get_boundary_info().build_side_list();
3123std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>>
3126 return getMesh().get_boundary_info().build_active_side_list();
3132 return getMesh().get_boundary_info().side_with_boundary_id(
elem, boundary_id);
3135MeshBase::node_iterator
3138 return getMesh().local_nodes_begin();
3141MeshBase::node_iterator
3144 return getMesh().local_nodes_end();
3147MeshBase::const_node_iterator
3150 return getMesh().local_nodes_begin();
3153MeshBase::const_node_iterator
3156 return getMesh().local_nodes_end();
3159MeshBase::element_iterator
3162 return getMesh().active_local_elements_begin();
3165const MeshBase::element_iterator
3168 return getMesh().active_local_elements_end();
3171MeshBase::const_element_iterator
3174 return getMesh().active_local_elements_begin();
3177const MeshBase::const_element_iterator
3180 return getMesh().active_local_elements_end();
3198 return getMesh().max_node_id();
3204 return getMesh().max_elem_id();
3210 mooseDeprecated(
"MooseMesh::elem() is deprecated, please use MooseMesh::elemPtr() instead");
3217 mooseDeprecated(
"MooseMesh::elem() is deprecated, please use MooseMesh::elemPtr() instead");
3236 return getMesh().query_elem_ptr(i);
3242 return getMesh().query_elem_ptr(i);
3255 mooseError(
"We don't have any right to tell the libmesh mesh that it *is* prepared. Only a "
3256 "call to prepare_for_use should tell us that");
3261 _mesh->unset_is_prepared();
3279const std::set<SubdomainID> &
3285const std::set<BoundaryID> &
3291const std::set<BoundaryID> &
3297const std::set<BoundaryID> &
3311 std::unique_ptr<std::map<BoundaryID, RealVectorValue>> boundary_map)
3319 mooseDeprecated(
"setBoundaryToNormalMap(std::map<BoundaryID, RealVectorValue> * boundary_map) is "
3320 "deprecated, use the unique_ptr version instead");
3349const std::set<unsigned int> &
3355const std::vector<Real> &
3369template <
typename T>
3370struct extra_ghost_elem_inserter
3372 using iterator_category = std::output_iterator_tag;
3373 using value_type = T;
3375 extra_ghost_elem_inserter(DistributedMesh & m) :
mesh(m) {}
3377 void operator=(
const Elem * e) {
mesh.add_extra_ghost_elem(
const_cast<Elem *
>(e)); }
3379 void operator=(Node * n) {
mesh.add_node(n); }
3381 void operator=(Point * p) {
mesh.add_point(*p); }
3383 extra_ghost_elem_inserter & operator++() {
return *
this; }
3385 extra_ghost_elem_inserter operator++(
int) {
return extra_ghost_elem_inserter(*
this); }
3391 extra_ghost_elem_inserter &
operator*() {
return *
this; }
3394 DistributedMesh &
mesh;
3407struct CompareElemsByLevel
3409 bool operator()(
const Elem * a,
const Elem * b)
const
3413 const unsigned int al = a->level(), bl = b->level();
3416 return (al == bl) ? aid < bid : al < bl;
3432 TIME_SECTION(
"GhostGhostedBoundaries", 3);
3434 parallel_object_only();
3436 DistributedMesh &
mesh =
dynamic_cast<DistributedMesh &
>(
getMesh());
3444 std::set<const Elem *, CompareElemsByLevel> boundary_elems_to_ghost;
3445 std::set<Node *> connected_nodes_to_ghost;
3447 std::vector<const Elem *> family_tree;
3449 for (
const auto & t :
mesh.get_boundary_info().build_side_list())
3451 auto elem_id = std::get<0>(t);
3452 auto bc_id = std::get<2>(t);
3456 Elem *
elem =
mesh.elem_ptr(elem_id);
3458#ifdef LIBMESH_ENABLE_AMR
3459 elem->family_tree(family_tree);
3460 Elem * parent =
elem->parent();
3463 family_tree.push_back(parent);
3464 parent = parent->parent();
3467 family_tree.clear();
3468 family_tree.push_back(
elem);
3470 for (
const auto & felem : family_tree)
3472 boundary_elems_to_ghost.insert(felem);
3480 for (
unsigned int n = 0; n < felem->n_nodes(); ++n)
3481 connected_nodes_to_ghost.insert(
const_cast<Node *
>(felem->node_ptr(n)));
3487 const auto prior_ghost_elems =
mesh.extra_ghost_elems();
3489 mesh.comm().allgather_packed_range(&
mesh,
3490 connected_nodes_to_ghost.begin(),
3491 connected_nodes_to_ghost.end(),
3492 extra_ghost_elem_inserter<Node>(
mesh));
3494 mesh.comm().allgather_packed_range(&
mesh,
3495 boundary_elems_to_ghost.begin(),
3496 boundary_elems_to_ghost.end(),
3497 extra_ghost_elem_inserter<Elem>(
mesh));
3499 const auto & current_ghost_elems =
mesh.extra_ghost_elems();
3501 std::set_difference(current_ghost_elems.begin(),
3502 current_ghost_elems.end(),
3503 prior_ghost_elems.begin(),
3504 prior_ghost_elems.end(),
3537 Real inflation_amount = inflation_multiplier * (bbox.max() - bbox.min()).norm();
3538 Point inflation(inflation_amount, inflation_amount, inflation_amount);
3540 bbox.first -= inflation;
3541 bbox.second += inflation;
3559 mooseAssert(
_mesh,
"Mesh hasn't been created");
3566 mooseAssert(
_mesh,
"Mesh hasn't been created");
3574 getMesh().print_info(os, verbosity);
3578const std::vector<dof_id_type> &
3581 std::map<boundary_id_type, std::vector<dof_id_type>>::const_iterator it =
3591 static const std::vector<dof_id_type> empty_vec;
3598 mooseError(
"Unable to nodeset ID: ", nodeset_id,
'.');
3605const std::set<BoundaryID> &
3611 mooseError(
"Unable to find subdomain ID: ", subdomain_id,
'.');
3613 return it->second.boundary_ids;
3620 std::set<BoundaryID> boundary_ids(bnd_ids.begin(), bnd_ids.end());
3621 std::unordered_map<SubdomainID, std::set<BoundaryID>>::const_iterator it =
3624 boundary_ids.insert(it->second.begin(), it->second.end());
3626 return boundary_ids;
3629std::set<SubdomainID>
3632 std::set<SubdomainID> subdomain_ids;
3634 if (data.boundary_ids.find(bid) != data.boundary_ids.end())
3635 subdomain_ids.insert(sub_id);
3637 return subdomain_ids;
3640std::set<SubdomainID>
3643 std::set<SubdomainID> subdomain_ids;
3645 if (it.second.find(bid) != it.second.end())
3646 subdomain_ids.insert(it.first);
3648 return subdomain_ids;
3651std::set<SubdomainID>
3656 if (it.second.find(bid) != it.second.end())
3657 subdomain_ids.insert(it.first);
3659 return subdomain_ids;
3662const std::set<SubdomainID> &
3668 mooseError(
"Unable to find subdomain ID: ", subdomain_id,
'.');
3670 return it->second.neighbor_subs;
3676 bool found_node =
false;
3679 if (it.second.find(node_id) != it.second.end())
3691 bool found_node =
false;
3692 std::map<boundary_id_type, std::set<dof_id_type>>::const_iterator it =
_bnd_node_ids.find(bnd_id);
3694 if (it->second.find(node_id) != it->second.end())
3702 bool found_elem =
false;
3705 if (it.second.find(elem_id) != it.second.end())
3717 bool found_elem =
false;
3720 if (it->second.find(elem_id) != it->second.end())
3731 " with DistributedMesh!\n",
3732 "Consider specifying parallel_type = 'replicated' in your input file\n",
3733 "to prevent it from being run with DistributedMesh.");
3751 bool use_distributed_mesh,
3756 switch (partitioner)
3760 if (use_distributed_mesh)
3761 partitioner =
"parmetis";
3763 partitioner =
"metis";
3777 if (!params.
isParamValid(
"centroid_partitioner_direction"))
3779 "centroid_partitioner_direction",
3780 "If using the centroid partitioner you _must_ specify centroid_partitioner_direction!");
3784 if (direction ==
"x")
3785 mesh_base.partitioner().reset(
3787 else if (direction ==
"y")
3788 mesh_base.partitioner().reset(
3790 else if (direction ==
"z")
3791 mesh_base.partitioner().reset(
3793 else if (direction ==
"radial")
3794 mesh_base.partitioner().reset(
3826 bool mesh_has_second_order_elements =
false;
3828 if ((*it)->default_order() == SECOND)
3830 mesh_has_second_order_elements =
true;
3835 comm().
max(mesh_has_second_order_elements);
3836 return mesh_has_second_order_elements;
3845std::unique_ptr<libMesh::PointLocatorBase>
3848 return getMesh().sub_point_locator();
3855 "This routine has not been implemented for threads. Please query this routine before "
3856 "a threaded region or contact a MOOSE developer to discuss.");
3859 using Keytype = std::pair<const Elem *, unsigned short int>;
3862 std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>> side_list =
3864 std::map<Keytype, std::set<boundary_id_type>> side_map;
3865 for (
auto & [elem_id, side, bc_id] : side_list)
3867 const Elem *
elem =
_mesh->elem_ptr(elem_id);
3868 Keytype key(
elem, side);
3869 auto & bc_set = side_map[key];
3870 bc_set.insert(bc_id);
3884 auto begin =
getMesh().active_elements_begin();
3885 auto end =
getMesh().active_elements_end();
3890 unsigned int num_sides = 0;
3891 for (
const Elem *
elem : as_range(begin, end))
3894 num_sides +=
elem->n_sides();
3902 dof_id_type face_index = 0;
3903 for (
const Elem *
elem : as_range(begin, end))
3905 for (
unsigned int side = 0; side <
elem->n_sides(); ++side)
3908 const Elem * neighbor =
elem->neighbor_ptr(side);
3915 mooseAssert(!neighbor || (neighbor->level() <
elem->level() ? neighbor->active() :
true),
3916 "If the neighbor is coarser than the element, we expect that the neighbor must "
3920 mooseAssert(
elem->default_order() < 4,
"Did not expect such high element orders in FV");
3928 std::set<boundary_id_type> & boundary_ids = fi.boundaryIDs();
3929 boundary_ids.clear();
3935 fi.computeBoundaryCoefficients();
3939 auto lit = side_map.find(Keytype(&fi.elem(), fi.elemSideID()));
3940 if (lit != side_map.end())
3941 boundary_ids.insert(lit->second.begin(), lit->second.end());
3943 if (fi.neighborPtr())
3945 auto rit = side_map.find(Keytype(fi.neighborPtr(), fi.neighborSideID()));
3946 if (rit != side_map.end())
3947 boundary_ids.insert(rit->second.begin(), rit->second.end());
3961 const Elem *
const elem = &fi.elem();
3962 const auto side = fi.elemSideID();
3968 mooseAssert(pair_it.second,
"We should be adding unique FaceInfo objects.");
3972 if (fi.elem().processor_id() == this->processor_id() ||
3973 (fi.neighborPtr() && (fi.neighborPtr()->processor_id() == this->processor_id())))
3979 if (ei.second.elem()->processor_id() == this->
processor_id())
3992 mooseAssert(it->second,
3993 "For some reason, the FaceInfo object is NULL! Try calling "
3994 "`buildFiniteVolumeInfo()` before using this accessor!");
4009 mooseError(
"Trying to compute face- and elem-info coords when the information is dirty");
4014 const SubdomainID elem_subdomain_id = fi.elemSubdomainID();
4015 const SubdomainID neighbor_subdomain_id = fi.neighborSubdomainID();
4018 *
this, elem_subdomain_id, fi.faceCentroid(), fi.faceCoord(), neighbor_subdomain_id);
4023 *
this, ei.second.subdomain_id(), ei.second.centroid(), ei.second.coordFactor());
4030 "default=-3 metis=-2 parmetis=-1 linear=0 centroid hilbert_sfc morton_sfc custom",
"default");
4038 "EDGE EDGE2 EDGE3 EDGE4 QUAD QUAD4 QUAD8 QUAD9 TRI3 TRI6 HEX HEX8 HEX20 HEX27 TET4 TET10 "
4039 "PRISM6 PRISM15 PRISM18 PYRAMID5 PYRAMID13 PYRAMID14");
4048 _mesh->allow_remote_element_removal(allow_remote_element_removal);
4050 if (!allow_remote_element_removal)
4062 mooseError(
"Cannot delete remote elements because we have not yet attached a MeshBase");
4064 _mesh->allow_remote_element_removal(
true);
4066 _mesh->delete_remote_elements();
4074 "Performing writes to faceInfo variable association maps. This must be done unthreaded!");
4078 auto face_lambda = [
this](
const SubdomainID elem_subdomain_id,
4081 std::vector<std::vector<FaceInfo::VarFaceNeighbors>> & face_type_vector)
4084 const auto & variables = sys.getVariables(0);
4086 for (
const auto & var : variables)
4088 const unsigned int var_num = var->number();
4089 const unsigned int sys_num = var->sys().number();
4090 std::set<SubdomainID> var_subdomains = var->blockIDs();
4100 bool var_defined_elem = var_subdomains.find(elem_subdomain_id) != var_subdomains.end();
4101 bool var_defined_neighbor =
4102 var_subdomains.find(neighbor_subdomain_id) != var_subdomains.end();
4103 if (var_defined_elem && var_defined_neighbor)
4105 else if (!var_defined_elem && !var_defined_neighbor)
4110 if (var_defined_elem)
4112 else if (var_defined_neighbor)
4124 const SubdomainID elem_subdomain_id = face.elemSubdomainID();
4125 const SubdomainID neighbor_subdomain_id = face.neighborSubdomainID();
4127 auto & face_type_vector = face.faceType();
4129 face_type_vector.clear();
4130 face_type_vector.resize(num_eqs);
4134 face_lambda(elem_subdomain_id,
4135 neighbor_subdomain_id,
4140 face_lambda(elem_subdomain_id,
4141 neighbor_subdomain_id,
4151 "Performing writes to elemInfo dof indices. This must be done unthreaded!");
4153 auto elem_lambda = [](
const ElemInfo & elem_info,
4155 std::vector<std::vector<dof_id_type>> & dof_vector)
4157 if (sys.nFVVariables())
4160 const auto & variables = sys.getVariables(0);
4162 for (
const auto & var : variables)
4165 const auto & var_subdomains = var->blockIDs();
4168 if (var_subdomains.find(elem_info.
subdomain_id()) != var_subdomains.end())
4170 std::vector<dof_id_type> indices;
4171 var->dofMap().dof_indices(elem_info.
elem(), indices, var->number());
4172 mooseAssert(indices.size() == 1,
"We expect to have only one dof per element!");
4173 dof_vector[sys.number()][var->number()] = indices[0];
4185 auto & elem_info = ei_pair.second;
4189 dof_vector.resize(num_eqs);
4213 TIME_SECTION(
"setCoordSystem", 5,
"Setting Coordinate System");
4216 const std::string param_name =
isParamValid(
"coord_block") ?
"coord_block" :
"block";
4217 mooseWarning(
"Supplied blocks in the 'setCoordSystem' method do not match the value of the "
4220 "' parameter. Did you provide different parameter values for 'Mesh/",
4222 "' and 'Problem/block'?. We will honor the parameter value from 'Mesh/",
4226 "If we are arriving here due to a bad specification in the Problem block, then we "
4227 "should have already set our coordinate system subdomains from the Mesh block");
4231 mooseError(
"Supplied coordinate systems in the 'setCoordSystem' method do not match the value "
4232 "of the 'Mesh/coord_type' parameter. Did you provide different parameter values for "
4233 "'coord_type' to 'Mesh' and 'Problem'?");
4240 if (coord_sys.
size() > 1)
4241 mooseError(
"If you specify ANY_BLOCK_ID as the only block, you must also specify a single "
4242 "coordinate system for it.");
4243 if (!
_mesh->is_prepared())
4245 "You cannot set the coordinate system for ANY_BLOCK_ID before the mesh is prepared. "
4246 "Please call this method after the mesh is prepared.");
4247 const auto coord_type = coord_sys.
size() == 0
4249 : Moose::stringToEnum<Moose::CoordinateSystemType>(coord_sys[0]);
4257 mooseError(
"You cannot specify ANY_BLOCK_ID together with other blocks in the "
4258 "setCoordSystem() method. If you want to set the same coordinate system for all "
4259 "blocks, use ANY_BLOCK_ID as the only block.");
4264 for (
const auto & sub_name :
blocks)
4267 subdomains.insert(sub_id);
4270 if (coord_sys.
size() <= 1)
4273 const auto coord_type = coord_sys.
size() == 0
4275 : Moose::stringToEnum<Moose::CoordinateSystemType>(coord_sys[0]);
4276 for (
const auto sid : subdomains)
4282 mooseError(
"Number of blocks and coordinate systems does not match.");
4284 for (
const auto i : index_range(
blocks))
4288 Moose::stringToEnum<Moose::CoordinateSystemType>(coord_sys[i]);
4292 for (
const auto & sid : subdomains)
4295 "' does not have a coordinate system specified.");
4308 return (*it).second;
4310 mooseError(
"Requested subdomain ", sid,
" does not exist.");
4318 bool result = std::all_of(
4322 typename std::unordered_map<SubdomainID, Moose::CoordinateSystemType>::const_reference
4323 item) { return (item.second == unique_system); });
4325 mooseError(
"The unique coordinate system of the mesh was requested by the mesh contains "
4326 "multiple blocks with different coordinate systems");
4329 mooseError(
"General axisymmetric coordinate axes are being used, and it is currently "
4330 "conservatively assumed that in this case there is no unique coordinate system.");
4332 return unique_system;
4335const std::map<SubdomainID, Moose::CoordinateSystemType> &
4351 const std::vector<SubdomainName> &
blocks,
4352 const std::vector<std::pair<Point, RealVectorValue>> & axes)
4355 mooseAssert(
blocks.size() == axes.size(),
"Blocks and axes vectors must be the same length.");
4356 for (
const auto i : index_range(
blocks))
4359 const auto it =
_coord_sys.find(subdomain_id);
4363 "' has not set a coordinate system. Make sure to call setCoordSystem() before "
4364 "setGeneralAxisymmetricCoordAxes().");
4369 const auto direction = axes[i].second;
4370 if (direction.is_zero())
4371 mooseError(
"Only nonzero vectors may be supplied for RZ directions.");
4374 std::make_pair(axes[i].first, direction.unit());
4379 "' was provided in setGeneralAxisymmetricCoordAxes(), but the coordinate system "
4380 "for this block is not 'RZ'.");
4386 for (
const auto subdomain_id : all_subdomain_ids)
4391 "' was specified to use the 'RZ' coordinate system but was not given in "
4392 "setGeneralAxisymmetricCoordAxes().");
4397const std::pair<Point, RealVectorValue> &
4402 return (*it).second;
4404 mooseError(
"Requested subdomain ", subdomain_id,
" does not exist.");
4426 mooseError(
"getAxisymmetricRadialCoord() should not be called if "
4427 "setGeneralAxisymmetricCoordAxes() has been called.");
4438 for (
const auto &
elem :
getMesh().element_ptr_range())
4443 " which contains 3D elements.");
4445 mooseError(
"An RSPHERICAL coordinate system was requested for subdomain " +
4468 std::map<SubdomainName, SubdomainID> subdomain;
4472 if (!sub_name.empty() && subdomain.count(sub_name) > 0)
4475 " is used for both subdomain with ID=",
4476 subdomain[sub_name],
4479 ", Please rename one of them!");
4481 subdomain[sub_name] = sbd_id;
4485const std::vector<QpMap> &
4488 const std::map<std::pair<ElemType, unsigned int>, std::vector<QpMap>> & map)
const
4492 return libmesh_map_find(map,
4493 std::make_pair(
elem.type(), cast_int<unsigned int>(
elem.p_level() - 1)));
4496const std::vector<QpMap> &
4499 const std::map<std::pair<ElemType, unsigned int>, std::vector<QpMap>> & map)
const
4501 mooseAssert(
elem.active() &&
elem.p_refinement_flag() == Elem::JUST_COARSENED,
4502 "These are the conditions that should be met for requesting a coarsening map");
4503 return libmesh_map_find(map, std::make_pair(
elem.type(),
elem.p_level()));
4506const std::vector<QpMap> &
4512const std::vector<QpMap> &
4518const std::vector<QpMap> &
4524const std::vector<QpMap> &
4533 return _mesh->skip_noncritical_partitioning();
void coordTransformFactor(const SubProblem &s, SubdomainID sub_id, const P &point, C &factor, SubdomainID neighbor_sub_id=libMesh::Elem::invalid_subdomain_id)
Computes a conversion multiplier for use when computing integraals for the current coordinate system ...
boundary_id_type BoundaryID
subdomain_id_type SubdomainID
void mooseInfoRepeated(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
auto operator*(const T1 &a, const RankFourTensorTempl< T2 > &b) -> typename std::enable_if< libMesh::ScalarTraits< T1 >::value, RankFourTensorTempl< decltype(T1() *T2())> >::type
void ErrorVector unsigned int
Keeps track of stuff related to assembling.
libMesh::QBase *const & writeableQRule()
Returns the reference to the current quadrature being used.
libMesh::QBase *const & writeableQRuleFace()
Returns the reference to the current quadrature being used on a current face.
void setCurrentSubdomainID(SubdomainID i)
set the current subdomain ID
void reinit(const Elem *elem)
Reinitialize objects (JxW, q_points, ...) for an elements.
Helper class for sorting Boundary Nodes so that we always get the same order of application for bound...
bool operator()(const BndNode *const &lhs, const BndNode *const &rhs)
std::vector< const Elem * > _refined_elements
The elements that were just refined.
std::map< const Elem *, std::vector< const Elem * > > _coarsened_element_children
Map of Parent elements to children elements for elements that were just coarsened.
std::vector< const Elem * > _coarsened_elements
The elements that were just coarsened.
Class used for caching additional information for elements such as the volume and centroid.
SubdomainID subdomain_id() const
We return the subdomain ID of the corresponding libmesh element.
const Elem * elem() const
const std::vector< std::vector< dof_id_type > > & dofIndices() const
virtual libMesh::EquationSystems & es() override
AuxiliarySystem & getAuxiliarySystem()
virtual std::size_t numSolverSystems() const override
bool hasKokkosObjects() const
SolverSystem & getSolverSystem(unsigned int sys_num)
Get non-constant reference to a solver system.
This data structure is used to store geometric and variable related metadata about each cell face in ...
bool isKokkosAvailable() const
Get whether Kokkos is available.
bool isSplitMesh() const
Whether or not this is a split mesh operation.
Executioner * getExecutioner() const
Retrieve the Executioner for this App.
static const std::string & checkpointSuffix()
The file suffix for the checkpoint mesh.
bool isUltimateMaster() const
Whether or not this app is the ultimate master app.
bool getDistributedMeshOnCommandLine() const
Returns true if the user specified –distributed-mesh (or –parallel-mesh, for backwards compatibility)...
FEProblemBase & feProblem() const
std::string getRestartRecoverFileBase() const
The file_base for the recovery file.
bool isRecovering() const
Whether or not this is a "recover" calculation.
const std::string & type() const
Get the type of this class.
static const std::string name_param
The name of the parameter that contains the object name.
const std::string & name() const
Get the name of the class.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
const InputParameters & _pars
The object's parameters.
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
std::set< SubdomainID > getInterfaceConnectedBlocks(const BoundaryID bid) const
Get the list of subdomains contacting the given boundary.
virtual bnd_node_iterator bndNodesBegin()
Return iterators to the beginning/end of the boundary nodes list.
const Moose::PatchUpdateType & getPatchUpdateStrategy() const
Get the current patch update strategy.
std::vector< std::vector< bool > > _id_identical_flag
Flags to indicate whether or not any two extra element integers are the same.
bool _need_delete
Whether we need to delete remote elements after init'ing the EquationSystems.
void setBoundaryName(BoundaryID boundary_id, BoundaryName name)
This method sets the boundary name of the boundary based on the id parameter.
virtual bnd_node_iterator bndNodesEnd()
bool isBoundaryElem(dof_id_type elem_id) const
Returns true if the requested element is in the list of boundary elements, false otherwise.
void setupFiniteVolumeMeshData() const
Sets up the additional data needed for finite volume computations.
const std::set< BoundaryID > & getSubdomainBoundaryIds(const SubdomainID subdomain_id) const
Get the list of boundary ids associated with the given subdomain id.
void printInfo(std::ostream &os=libMesh::out, const unsigned int verbosity=0) const
Calls print_info() on the underlying Mesh.
const Elem * getLowerDElem(const Elem *, unsigned short int) const
Returns a const pointer to a lower dimensional element that corresponds to a side of a higher dimensi...
virtual std::vector< std::filesystem::path > writeRecoveryFiles(const std::filesystem::path &file_base)
Write the mesh files needed for recovery/checkpointing.
bool _allow_recovery
Whether or not this Mesh is allowed to read a recovery file.
MeshBase::node_iterator localNodesEnd()
unsigned int _max_p_level
Maximum p-refinement level of all elements.
std::map< const Elem *, std::vector< const Elem * > > _coarsened_element_children
Map of Parent elements to child elements for elements that were just coarsened.
std::unordered_set< dof_id_type > getBoundaryActiveSemiLocalElemIds(BoundaryID bid) const
Return all ids of elements which have a side which is part of a sideset.
std::unique_ptr< ConstElemPointerRange > _coarsened_elements
The elements that were just coarsened.
unsigned int getAxisymmetricRadialCoord() const
Returns the desired radial direction for RZ coordinate transformation.
face_info_iterator ownedFaceInfoEnd()
unsigned int sideWithBoundaryID(const Elem *const elem, const BoundaryID boundary_id) const
Calls BoundaryInfo::side_with_boundary_id().
void meshChanged()
Declares that the MooseMesh has changed, invalidates cached data and rebuilds caches.
virtual const Node & nodeRef(const dof_id_type i) const
const std::vector< QpMap > & getPRefinementMap(const Elem &elem) const
Get the map describing for each volumetric quadrature point (qp) on the refined level which qp on the...
bool _displace_node_list_by_side_list
Whether or not to displace unrelated nodesets by nodesets constructed from sidesets.
void changeBoundaryId(const boundary_id_type old_id, const boundary_id_type new_id, bool delete_prev)
Change all the boundary IDs for a given side from old_id to new_id.
const std::vector< const Elem * > & coarsenedElementChildren(const Elem *elem) const
Get the newly removed children element ids for an element that was just coarsened.
void mapPoints(const std::vector< Point > &from, const std::vector< Point > &to, std::vector< QpMap > &qp_map)
Find the closest points that map "from" to "to" and fill up "qp_map".
libMesh::BoundingBox getInflatedProcessorBoundingBox(Real inflation_multiplier=0.01) const
Get a (slightly inflated) processor bounding box.
RealVectorValue minPeriodicVector(const unsigned int sys_num, const unsigned int var_num, Point p, Point q) const
Returns the minimum vector between two points on the mesh taking into account periodicity for the giv...
std::set< Node * > _semilocal_node_list
Used for generating the semilocal node range.
Real minPeriodicDistance(const unsigned int sys_num, const unsigned int var_num, const Point &p, const Point &q) const
Returns the distance between two points on the mesh taking into account periodicity for the given var...
std::unordered_map< dof_id_type, ElemInfo > _elem_to_elem_info
Map connecting elems with their corresponding ElemInfo, we use the element ID as the key.
unsigned int uniformRefineLevel() const
Returns the level of uniform refinement requested (zero if AMR is disabled).
virtual dof_id_type maxElemId() const
const std::vector< std::pair< unsigned int, QpMap > > & getCoarseningMap(const Elem &elem, int input_side)
Get the coarsening map for a given element type.
bool possiblyRebuildNodeToElemMap()
rebuild the node to element map if it's been requsted previously
std::vector< const FaceInfo * > _face_info
Holds only those FaceInfo objects that have processor_id equal to this process's id,...
virtual unsigned int dimension() const
Returns MeshBase::mesh_dimension(), (not MeshBase::spatial_dimension()!) of the underlying libMesh me...
static const std::array< bool, 3 > periodic_dim_default
Default value for the automatically detected paired boundaries for each unit dimension,...
virtual Elem * elem(const dof_id_type i)
Various accessors (pointers/references) for Elem "i".
std::unique_ptr< ConstElemPointerRange > _refined_elements
The elements that were just refined.
bool _custom_partitioner_requested
bool _need_ghost_ghosted_boundaries
A parallel mesh generator such as DistributedRectilinearMeshGenerator already make everything ready.
std::vector< std::tuple< dof_id_type, unsigned short int, boundary_id_type > > buildSideList()
Calls BoundaryInfo::build_side_list(), returns a std::vector of (elem-id, side-id,...
Node * getQuadratureNode(const Elem *elem, const unsigned short int side, const unsigned int qp)
Get a specified quadrature node.
void updateCoordTransform()
Update the coordinate transformation object based on our coordinate system data.
elem_info_iterator ownedElemInfoEnd()
virtual MooseMesh & clone() const
Clone method.
std::unordered_map< SubdomainID, std::pair< Point, RealVectorValue > > _subdomain_id_to_rz_coord_axis
Map of subdomain ID to general axisymmetric axis.
virtual Elem * elemPtr(const dof_id_type i)
virtual void onMeshChanged()
Declares a callback function that is executed at the conclusion of meshChanged().
bool _coord_system_set
Whether the coordinate system has been set.
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
MooseEnum _partitioner_name
The partitioner used on this mesh.
bool _parallel_type_overridden
void buildRefinementAndCoarseningMaps(Assembly *assembly)
Create the refinement and coarsening maps necessary for projection of stateful material properties wh...
void detectPairedSidesets()
This routine detects paired sidesets of a regular orthogonal mesh (.i.e.
virtual void buildMesh()=0
Must be overridden by child classes.
std::map< std::pair< libMesh::ElemType, unsigned int >, std::vector< QpMap > > _elem_type_to_p_coarsening_map
std::set< BoundaryID > _mesh_boundary_ids
A set of boundary IDs currently present in the mesh.
const std::vector< Real > & getGhostedBoundaryInflation() const
Return a writable reference to the _ghosted_boundaries_inflation vector.
virtual void init()
Initialize the Mesh object.
virtual const Node & node(const dof_id_type i) const
Various accessors (pointers/references) for Node "i".
std::vector< SubdomainName > getSubdomainNames(const std::vector< SubdomainID > &subdomain_ids) const
Get the associated subdomainNames for the subdomain ids that are passed in.
Real dimensionWidth(unsigned int component) const
Returns the width of the requested dimension.
std::map< std::pair< libMesh::ElemType, unsigned int >, std::vector< QpMap > > _elem_type_to_p_coarsening_side_map
void prepare()
Calls prepare_for_use() if the underlying MeshBase object isn't prepared, then communicates various b...
void computeMaxPerElemAndSide()
Compute the maximum numbers per element and side.
virtual dof_id_type nActiveLocalElem() const
void update()
Calls buildNodeListFromSideList(), buildNodeList(), and buildBndElemList().
std::map< boundary_id_type, std::vector< dof_id_type > > _node_set_nodes
list of nodes that belongs to a specified nodeset: indexing [nodeset_id] -> [array of node ids]
std::set< dof_id_type > getElemIDsOnBlocks(unsigned int elem_id_index, const std::set< SubdomainID > &blks) const
Return all the unique element IDs for an extra element integer with its index on a set of subdomains.
std::vector< FaceInfo > _all_face_info
FaceInfo object storing information for face based loops.
const std::string & getBoundaryName(const BoundaryID boundary_id) const
Return the name of the boundary given the id.
std::unique_ptr< libMesh::MeshBase > _mesh
Pointer to underlying libMesh mesh object.
void determineUseDistributedMesh()
Determine whether to use a distributed mesh.
std::vector< Node * > _node_map
Vector of all the Nodes in the mesh for determining when to add a new point.
std::unique_ptr< libMesh::StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > > _bnd_elem_range
bool hasDetectedPairedSidesets() const
Whether or not detectedPairedSidesets() has been called.
std::map< SubdomainID, Moose::CoordinateSystemType > & _coord_sys
Type of coordinate system per subdomain.
std::map< std::pair< int, libMesh::ElemType >, std::vector< std::vector< QpMap > > > _elem_type_to_refinement_map
Holds mappings for volume to volume and parent side to child side Map key:
std::unique_ptr< libMesh::StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > > _bnd_node_range
const MeshBase * getMeshPtr() const
ParallelType _parallel_type
Can be set to DISTRIBUTED, REPLICATED, or DEFAULT.
Moose::CoordinateSystemType getUniqueCoordSystem() const
Get the coordinate system from the mesh, it must be the same in all subdomains otherwise this will er...
std::pair< const Node *, BoundaryID > PeriodicNodeInfo
Helper type for building periodic node maps.
void buildNodeListFromSideList()
Calls BoundaryInfo::build_node_list_from_side_list().
void setMeshBoundaryIDs(std::set< BoundaryID > boundary_IDs)
Sets the set of BoundaryIDs Is called by AddAllSideSetsByNormals.
const std::map< SubdomainID, Moose::CoordinateSystemType > & getCoordSystem() const
Get the map from subdomain ID to coordinate system type, e.g.
unsigned int _max_h_level
Maximum h-refinement level of all elements.
virtual unsigned int effectiveSpatialDimension() const
Returns the effective spatial dimension determined by the coordinates actually used by the mesh.
bool prepared() const
Setter/getter for whether the mesh is prepared.
std::vector< std::unordered_map< SubdomainID, std::set< dof_id_type > > > _block_id_mapping
Unique element integer IDs for each subdomain and each extra element integers.
std::map< std::pair< int, libMesh::ElemType >, std::vector< std::pair< unsigned int, QpMap > > > _elem_type_to_coarsening_map
Holds mappings for volume to volume and parent side to child side Map key:
std::unordered_map< std::pair< const Elem *, unsigned short int >, const Elem * > _higher_d_elem_side_to_lower_d_elem
Holds a map from a high-order element side to its corresponding lower-d element.
std::unordered_map< dof_id_type, std::set< dof_id_type > > getElemIDMapping(const std::string &from_id_name, const std::string &to_id_name) const
bool _use_distributed_mesh
False by default.
void addGhostedBoundary(BoundaryID boundary_id)
This will add the boundary ids to be ghosted to this processor.
unsigned int getHigherDSide(const Elem *elem) const
Returns the local side ID of the interior parent aligned with the lower dimensional element.
std::set< SubdomainID > _mesh_subdomains
A set of subdomain IDs currently present in the mesh.
static MooseEnum partitioning()
returns MooseMesh partitioning options so other classes can use it
virtual dof_id_type maxNodeId() const
Calls max_node/elem_id() on the underlying libMesh mesh object.
void setCoordData(const MooseMesh &other_mesh)
Set the coordinate system data to that of other_mesh.
void checkDuplicateSubdomainNames()
Loop through all subdomain IDs and check if there is name duplication used for the subdomains with sa...
std::map< dof_id_type, std::map< unsigned int, std::map< dof_id_type, Node * > > > _elem_to_side_to_qp_to_quadrature_nodes
bool _regular_orthogonal_mesh
Boolean indicating whether this mesh was detected to be regular and orthogonal.
SemiLocalNodeRange * getActiveSemiLocalNodeRange() const
ConstElemPointerRange * refinedElementRange() const
Return a range that is suitable for threaded execution over elements that were just refined.
SubdomainID getSubdomainID(const SubdomainName &subdomain_name) const
Get the associated subdomain ID for the subdomain name.
void clearQuadratureNodes()
Clear out any existing quadrature nodes.
void cacheFaceInfoVariableOwnership() const
Cache if variables live on the elements connected by the FaceInfo objects.
virtual Real getMaxInDimension(unsigned int component) const
void buildFiniteVolumeInfo() const
Builds the face and elem info vectors that store meta-data needed for looping over and doing calculat...
static InputParameters validParams()
Typical "Moose-style" constructor and copy constructor.
const std::set< BoundaryID > & meshNodesetIds() const
Returns a read-only reference to the set of nodesets currently present in the Mesh.
const std::unordered_map< dof_id_type, std::vector< dof_id_type > > & nodeToElemMap()
If not already created, creates a map from every node to all elements to which they are connected.
face_info_iterator ownedFaceInfoBegin()
Iterators to owned faceInfo objects.
libMesh::ConstNodeRange * getLocalNodeRange()
void setIsCustomPartitionerRequested(bool cpr)
void deleteRemoteElements()
Delete remote elements.
bool allowRemoteElementRemoval() const
Whether we are allow remote element removal.
elem_info_iterator ownedElemInfoBegin()
Iterators to owned faceInfo objects.
std::vector< BndElement * > _bnd_elems
array of boundary elems
void ghostGhostedBoundaries()
Actually do the ghosting of boundaries that need to be ghosted to this processor.
const std::vector< QpMap > & getPCoarseningMap(const Elem &elem) const
Get the map describing for each volumetric quadrature point (qp) on the coarse level which qp on the ...
bool _is_nemesis
True if a Nemesis Mesh was read in.
void updateActiveSemiLocalNodeRange(std::set< dof_id_type > &ghosted_elems)
Clears the "semi-local" node list and rebuilds it.
virtual bool skipNoncriticalPartitioning() const
void checkCoordinateSystems()
Performs a sanity check for every element in the mesh.
void buildRefinementMap(const Elem &elem, libMesh::QBase &qrule, libMesh::QBase &qrule_face, int parent_side, int child, int child_side)
Build the refinement map for a given element type.
const std::vector< const FaceInfo * > & faceInfo() const
Accessor for local FaceInfo objects.
void buildElemIDInfo()
Build extra data for faster access to the information of extra element integers.
virtual bnd_elem_iterator bndElemsBegin()
Return iterators to the beginning/end of the boundary elements list.
unsigned int getBlocksMaxDimension(const std::vector< SubdomainName > &blocks) const
Returns the maximum element dimension on the given blocks.
const std::vector< QpMap > & getPCoarseningSideMap(const Elem &elem) const
Get the map describing for each side quadrature point (qp) on the coarse level which qp on the previo...
virtual Elem * queryElemPtr(const dof_id_type i)
const std::set< unsigned int > & getGhostedBoundaries() const
Return a writable reference to the set of ghosted boundary IDs.
void cacheFVElementalDoFs() const
Cache the DoF indices for FV variables on each element.
virtual std::unique_ptr< libMesh::PointLocatorBase > getPointLocator() const
Proxy function to get a (sub)PointLocator from either the underlying libMesh mesh (default),...
bool _partitioner_overridden
const std::set< BoundaryID > & getBoundaryIDs() const
Returns a const reference to a set of all user-specified boundary IDs.
std::vector< std::vector< Real > > _bounds
The bounds in each dimension of the mesh for regular orthogonal meshes.
std::set< SubdomainID > _lower_d_boundary_blocks
Mesh blocks for boundary lower-d elements in different types.
const ElemInfo & elemInfo(const dof_id_type id) const
Accessor for the elemInfo object for a given element ID.
void setBoundaryToNormalMap(std::unique_ptr< std::map< BoundaryID, RealVectorValue > > boundary_map)
Sets the mapping between BoundaryID and normal vector Is called by AddAllSideSetsByNormals.
bool isCustomPartitionerRequested() const
Setter and getter for _custom_partitioner_requested.
const std::vector< QpMap > & getPRefinementSideMap(const Elem &elem) const
Get the map describing for each side quadrature point (qp) on the refined level which qp on the previ...
void computeFiniteVolumeCoords() const
Compute the face coordinate value for all FaceInfo and ElemInfo objects.
bool _moose_mesh_prepared
True if prepare has been called on the mesh.
const std::unordered_map< boundary_id_type, std::unordered_set< dof_id_type > > & getBoundariesToActiveSemiLocalElemIds() const
Returns a map of boundaries to ids of elements on the boundary.
bool _doing_p_refinement
Whether we have p-refinement (whether exclusively p- or hp-refinement)
bool _skip_deletion_repartition_after_refine
Whether or not skip remote deletion and repartition after uniform refinements.
void buildNodeList()
Calls BoundaryInfo::build_node_list()/build_side_list() and makes separate copies of Nodes/Elems in t...
virtual dof_id_type nNodes() const
Calls n_nodes/elem() on the underlying libMesh mesh object.
std::vector< Node * > _extreme_nodes
A vector containing the nodes at the corners of a regular orthogonal mesh.
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
Get the associated BoundaryID for the boundary name.
std::unique_ptr< libMesh::Partitioner > _custom_partitioner
The custom partitioner.
std::optional< std::vector< std::pair< BoundaryID, BoundaryID > > > _paired_boundary
A vector holding the paired boundaries for a regular orthogonal mesh.
const std::vector< dof_id_type > & getNodeList(boundary_id_type nodeset_id) const
Return a writable reference to a vector of node IDs that belong to nodeset_id.
std::set< SubdomainID > getBoundaryConnectedSecondaryBlocks(const BoundaryID bid) const
Get the list of subdomains associated with the given boundary of its secondary side.
std::unordered_map< std::pair< const Elem *, unsigned int >, FaceInfo * > _elem_side_to_face_info
Map from elem-side pair to FaceInfo.
const std::vector< QpMap > & getPRefinementMapHelper(const Elem &elem, const std::map< std::pair< libMesh::ElemType, unsigned int >, std::vector< QpMap > > &) const
unsigned int _max_nodes_per_elem
The maximum number of nodes per element.
static MooseEnum elemTypes()
returns MooseMesh element type options
std::set< BoundaryID > _mesh_nodeset_ids
void setGeneralAxisymmetricCoordAxes(const std::vector< SubdomainName > &blocks, const std::vector< std::pair< Point, RealVectorValue > > &axes)
Sets the general coordinate axes for axisymmetric blocks.
unsigned int getPatchSize() const
Getter for the patch_size parameter.
void addPeriodicVariable(const unsigned int sys_num, const unsigned int var_num, const BoundaryID primary, const BoundaryID secondary)
For "regular orthogonal" meshes, determine if variable var_num is periodic with respect to the primar...
void cacheChangedLists()
Cache information about what elements were refined and coarsened in the previous step.
bool isTranslatedPeriodic(const unsigned int sys_num, const unsigned int var_num, const unsigned int component) const
Returns whether this generated mesh is periodic in the given dimension for the given variable on the ...
const std::pair< Point, RealVectorValue > & getGeneralAxisymmetricCoordAxis(SubdomainID subdomain_id) const
Gets the general axisymmetric coordinate axis for a block.
std::map< std::pair< libMesh::ElemType, unsigned int >, std::vector< QpMap > > _elem_type_to_p_refinement_side_map
bool _allow_remote_element_removal
Whether to allow removal of remote elements.
bool _construct_node_list_from_side_list
Whether or not to allow generation of nodesets from sidesets.
std::set< BoundaryID > getSubdomainInterfaceBoundaryIds(const SubdomainID subdomain_id) const
Get the list of boundaries that contact the given subdomain.
const Node * addUniqueNode(const Point &p, Real tol=1e-6)
Add a new node to the mesh.
const std::set< BoundaryID > & meshBoundaryIds() const
Returns a read-only reference to the set of boundary IDs currently present in the Mesh.
std::vector< BndNode * > _bnd_nodes
array of boundary nodes
std::unordered_map< dof_id_type, std::vector< dof_id_type > > _node_to_elem_map
A map of all of the current nodes to the elements that they are connected to.
void buildPeriodicNodeSets(std::map< BoundaryID, std::set< dof_id_type > > &periodic_node_sets, unsigned int var_number, libMesh::PeriodicBoundaries *pbs) const
This routine builds a datastructure of node ids organized by periodic boundary ids.
std::unique_ptr< MooseAppCoordTransform > _coord_transform
A coordinate transformation object that describes how to transform this problem's coordinate system i...
const std::set< SubdomainID > & getNodeBlockIds(const Node &node) const
Return list of blocks to which the given node belongs.
std::map< libMesh::ElemType, std::map< std::pair< int, int >, std::vector< std::vector< QpMap > > > > _elem_type_to_child_side_refinement_map
Holds mappings for "internal" child sides to parent volume. The second key is (child,...
void buildPeriodicNodeMap(std::multimap< dof_id_type, dof_id_type > &periodic_node_map, unsigned int var_number, libMesh::PeriodicBoundaries *pbs) const
This routine builds a multimap of boundary ids to matching boundary ids across all periodic boundarie...
const RealVectorValue & getNormalByBoundaryID(BoundaryID id) const
Returns the normal vector associated with a given BoundaryID.
std::unordered_map< SubdomainID, SubdomainData > _sub_to_data
Holds a map from subdomain ids to associated data.
const MooseUnits & lengthUnit() const
std::unique_ptr< std::map< BoundaryID, RealVectorValue > > _boundary_to_normal_map
The boundary to normal map - valid only when AddAllSideSetsByNormals is active.
std::unique_ptr< libMesh::NodeRange > _active_node_range
std::set< SubdomainID > _lower_d_interior_blocks
Mesh blocks for interior lower-d elements in different types.
void setPatchUpdateStrategy(Moose::PatchUpdateType patch_update_strategy)
Set the patch size update strategy.
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_names) const
Get the associated subdomainIDs for the subdomain names that are passed in.
void setPartitionerHelper(MeshBase *mesh=nullptr)
const std::pair< BoundaryID, BoundaryID > * getPairedBoundaryMapping(unsigned int component) const
This function attempts to return the paired boundary ids for the given component.
const std::set< BoundaryID > & meshSidesetIds() const
Returns a read-only reference to the set of sidesets currently present in the Mesh.
std::map< boundary_id_type, std::set< dof_id_type > > _bnd_node_ids
Map of sets of node IDs in each boundary.
unsigned int _rz_coord_axis
Storage for RZ axis selection.
ConstElemPointerRange * coarsenedElementRange() const
Return a range that is suitable for threaded execution over elements that were just coarsened.
std::unordered_map< SubdomainID, std::set< BoundaryID > > _neighbor_subdomain_boundary_ids
Holds a map from neighbor subomdain ids to the boundary ids that are attached to it.
std::unordered_map< boundary_id_type, std::unordered_set< dof_id_type > > _bnd_elem_ids
Map of set of elem IDs connected to each boundary.
unsigned int _uniform_refine_level
The level of uniform refinement requested (set to zero if AMR is disabled)
const std::string & getSubdomainName(SubdomainID subdomain_id) const
Return the name of a block given an id.
void buildCoarseningMap(const Elem &elem, libMesh::QBase &qrule, libMesh::QBase &qrule_face, int input_side)
Build the coarsening map for a given element type.
bool hasSecondOrderElements()
check if the mesh has SECOND order elements
std::unordered_map< const Elem *, unsigned short int > _lower_d_elem_to_higher_d_elem_side
bool _finite_volume_info_dirty
std::unordered_set< dof_id_type > getBoundaryActiveNeighborElemIds(BoundaryID bid) const
Return all ids of neighbors of elements which have a side which is part of a sideset.
virtual const Node * nodePtr(const dof_id_type i) const
std::map< dof_id_type, Node * > _quadrature_nodes
const std::unordered_map< boundary_id_type, std::unordered_set< dof_id_type > > & getBoundariesToElems() const
Returns a map of boundaries to ids of elements on the boundary.
const std::vector< QpMap > & getPCoarseningMapHelper(const Elem &elem, const std::map< std::pair< libMesh::ElemType, unsigned int >, std::vector< QpMap > > &) const
libMesh::NodeRange * getActiveNodeRange()
std::vector< SubdomainName > _provided_coord_blocks
Set for holding user-provided coordinate system type block names.
unsigned int _patch_size
The number of nodes to consider in the NearestNode neighborhood.
void setCustomPartitioner(libMesh::Partitioner *partitioner)
Setter for custom partitioner.
libMesh::StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
void setMeshBase(std::unique_ptr< MeshBase > mesh_base)
Method to set the mesh_base object.
std::unique_ptr< libMesh::ConstNodeRange > _local_node_range
void setSubdomainName(SubdomainID subdomain_id, const SubdomainName &name, const bool synchronous=false)
This method sets the name for subdomain_id to name.
const std::set< SubdomainID > & meshSubdomains() const
Returns a read-only reference to the set of subdomains currently present in the Mesh.
virtual bnd_elem_iterator bndElemsEnd()
MeshBase::node_iterator localNodesBegin()
Calls local_nodes_begin/end() on the underlying libMesh mesh object.
const std::vector< std::vector< QpMap > > & getRefinementMap(const Elem &elem, int parent_side, int child, int child_side)
Get the refinement map for a given element type.
void setCoordSystem(const std::vector< SubdomainName > &blocks, const MultiMooseEnum &coord_sys)
Set the coordinate system for the provided blocks to coord_sys.
Node * addQuadratureNode(const Elem *elem, const unsigned short int side, const unsigned int qp, BoundaryID bid, const Point &point)
Adds a fictitious "QuadratureNode".
void buildLowerDMesh()
Build lower-d mesh for all sides.
bool doingPRefinement() const
Query whether the kind of adaptivity we're doing includes p-refinement.
virtual const Node * queryNodePtr(const dof_id_type i) const
std::map< std::pair< unsigned int, unsigned int >, std::array< bool, 3 > > _periodic_dim
A map from (system number, vector number) to which dimensions are periodic in a regular orthogonal me...
std::vector< dof_id_type > _max_ids
Maximum integer ID for each extra element integer.
std::unique_ptr< Moose::Kokkos::Mesh > _kokkos_mesh
Pointer to Kokkos mesh object.
void findAdaptivityQpMaps(const Elem *template_elem, libMesh::QBase &qrule, libMesh::QBase &qrule_face, std::vector< std::vector< QpMap > > &refinement_map, std::vector< std::pair< unsigned int, QpMap > > &coarsen_map, int parent_side, int child, int child_side)
Given an elem type, get maps that tell us what qp's are closest to each other between a parent and it...
unsigned int _max_nodes_per_side
The maximum number of nodes per side.
bool _node_to_elem_map_built
Whether _node_to_elem_map has been built.
const MeshBase::element_iterator activeLocalElementsEnd()
std::set< BoundaryID > _mesh_sideset_ids
std::vector< Real > _ghosted_boundaries_inflation
void setGhostedBoundaryInflation(const std::vector< Real > &inflation)
This sets the inflation amount for the bounding box for each partition for use in ghosting boundaries...
std::string getBoundaryString(const BoundaryID boundary_id) const
Return the name of the boundary given the id, if it exists.
std::set< SubdomainID > getBoundaryConnectedBlocks(const BoundaryID bid) const
Get the list of subdomains associated with the given boundary.
const std::array< bool, 3 > & queryPeriodicDimensions(const unsigned int sys_num, const unsigned int var_num) const
Query the translated periodic dimension flags for the given variable on the given system.
const bool _is_split
Whether or not we are using a (pre-)split mesh (automatically DistributedMesh)
std::unique_ptr< SemiLocalNodeRange > _active_semilocal_node_range
Ranges for use with threading, cached so they don't have to get rebuilt all the time (which takes tim...
void setUniformRefineLevel(unsigned int, bool deletion=true)
Set uniform refinement level.
Moose::PatchUpdateType _patch_update_strategy
The patch update strategy.
virtual Real getMinInDimension(unsigned int component) const
Returns the min or max of the requested dimension respectively.
bool isBoundaryFullyExternalToSubdomains(BoundaryID bid, const std::set< SubdomainID > &blk_group) const
Returns whether a boundary (given by its id) is not crossing through a group of blocks,...
void errorIfDistributedMesh(std::string name) const
Generate a unified error message if the underlying libMesh mesh is a DistributedMesh.
void setAxisymmetricCoordAxis(const MooseEnum &rz_coord_axis)
For axisymmetric simulations, set the symmetry coordinate axis.
void needsPrepareForUse()
If this method is called, we will call libMesh's prepare_for_use method when we call Moose's prepare ...
const libMesh::ConstElemRange * getActiveLocalElementRange()
Return pointers to range objects for various types of ranges (local nodes, boundary elems,...
std::map< std::pair< libMesh::ElemType, unsigned int >, std::vector< QpMap > > _elem_type_to_p_refinement_map
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
Method to construct a libMesh::MeshBase object that is normally set and used by the MooseMesh object ...
bool _built_from_other_mesh
Whether or not this mesh was built from another mesh.
virtual dof_id_type nElem() const
const std::set< SubdomainID > & getBlockConnectedBlocks(const SubdomainID subdomain_id) const
Get the list of subdomains neighboring a given subdomain.
std::set< Elem * > _ghost_elems_from_ghost_boundaries
Set of elements ghosted by ghostGhostedBoundaries.
std::vector< const ElemInfo * > _elem_info
Holds only those ElemInfo objects that have processor_id equal to this process's id,...
bool usingGeneralAxisymmetricCoordAxes() const
Returns true if general axisymmetric coordinate axes are being used.
std::set< dof_id_type > getAllElemIDs(unsigned int elem_id_index) const
Return all the unique element IDs for an extra element integer with its index.
std::vector< BndNode > _extra_bnd_nodes
void buildHRefinementAndCoarseningMaps(Assembly *assembly)
std::set< unsigned int > _ghosted_boundaries
std::vector< dof_id_type > _min_ids
Minimum integer ID for each extra element integer.
libMesh::StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > * getBoundaryElementRange()
bool isBoundaryNode(dof_id_type node_id) const
Returns true if the requested node is in the list of boundary nodes, false otherwise.
RealVectorValue _half_range
A convenience vector used to hold values in each dimension representing half of the range.
MeshBase::element_iterator activeLocalElementsBegin()
Calls active_local_nodes_begin/end() on the underlying libMesh mesh object.
std::map< dof_id_type, std::set< SubdomainID > > _block_node_list
list of nodes that belongs to a specified block (domain)
unsigned int _max_sides_per_elem
The maximum number of sides per element.
bool isSemiLocal(Node *const node) const
Returns true if the node is semi-local.
void buildPRefinementAndCoarseningMaps(Assembly *assembly)
static void setPartitioner(MeshBase &mesh_base, MooseEnum &partitioner, bool use_distributed_mesh, const InputParameters ¶ms, MooseObject &context_obj)
Method for setting the partitioner on the passed in mesh_base object.
std::vector< std::tuple< dof_id_type, unsigned short int, boundary_id_type > > buildActiveSideList() const
Calls BoundaryInfo::build_active_side_list.
bool detectOrthogonalDimRanges(Real tol=1e-6)
This routine determines whether the Mesh is a regular orthogonal mesh (i.e.
std::unordered_map< dof_id_type, std::vector< dof_id_type > > & internalNodeToElemMap()
If not already created, creates a map from every node to all elements to which they are connected.
Every object that can be built by the factory should be derived from this class.
static InputParameters validParams()
MooseApp & _app
The MOOSE application this is associated with.
Physical unit management class with runtime unit string parsing, unit checking, unit conversion,...
SystemBase & sys()
Get the system this variable is part of.
unsigned int number() const
Get variable number coming from libMesh.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type.
unsigned int size() const
Return the number of active items in the MultiMooseEnum.
Interface for objects interacting with the PerfGraph.
const Point & getPoint(const PointObject &item) const
get a Point reference from the PointData object at index idx in the list
Helper object for holding qp mapping info.
unsigned int _from
The qp to map from.
unsigned int _to
The qp to map to.
Real _distance
The distance between them.
A class for creating restricted objects.
void mooseWarning(Args &&... args) const
void paramWarning(const std::string ¶m, Args... args) const
void mooseDeprecated(Args &&... args) const
Base class for a system (of equations)
unsigned int number() const
Gets the number of this system.
void max(const T &r, T &o, Request &req) const
void min(const T &r, T &o, Request &req) const
void set_union(T &data, const unsigned int root_id) const
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
virtual void write(const std::string &name) override
static constexpr dof_id_type invalid_id
unsigned int n_systems() const
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
void uniformly_refine(unsigned int n=1)
void uniformly_p_refine(unsigned int n=1)
const Parallel::Communicator & _communicator
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
PeriodicBoundaryBase * boundary(boundary_id_type id)
bool is_my_variable(unsigned int var_num) const
virtual Point get_corresponding_pos(const Point &pt) const=0
boundary_id_type pairedboundary
std::vector< subdomain_id_type > getSubdomainIDs(const libMesh::MeshBase &mesh, const std::vector< SubdomainName > &subdomain_name)
Get the associated subdomainIDs for the subdomain names that are passed in.
std::vector< BoundaryID > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown, const std::set< BoundaryID > &mesh_boundary_ids)
Gets the boundary IDs with their names.
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
Gets the boundary ID associated with the given BoundaryName.
SubdomainID getSubdomainID(const SubdomainName &subdomain_name, const MeshBase &mesh)
Gets the subdomain ID associated with the given SubdomainName.
bool elemHasFaceInfo(const Elem &elem, const Elem *const neighbor)
This function infers based on elements if the faceinfo between them belongs to the element or not.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
PatchUpdateType
Type of patch update strategy for modeling node-face constraints or contact.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
std::string stringify(const T &t)
conversion to string
const BoundaryID INVALID_BOUNDARY_ID
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
std::string enum_to_string(const T e)
bool absolute_fuzzy_equals(const T &var1, const T2 &var2, const Real tol=TOLERANCE *TOLERANCE)
const unsigned int invalid_uint
const RemoteElem * remote_elem
static constexpr Real TOLERANCE
std::pair< T, U > ResultItem
SearchParams SearchParameters
const boundary_id_type side_id
BoundaryID _bnd_id
boundary id for the node
libMesh::Node * _node
pointer to the node
The definition of the bnd_elem_iterator struct.
The definition of the bnd_node_iterator struct.
The definition of the elem_info_iterator struct.
The definition of the face_info_iterator struct.
Real distance(const Point &p)
const dof_id_type n_nodes