21 #include "libmesh/elem.h" 22 #include "libmesh/elem_range.h" 23 #include "libmesh/libmesh_logging.h" 24 #include "libmesh/mesh_base.h" 25 #include "libmesh/mesh_communication.h" 26 #include "libmesh/mesh_serializer.h" 27 #include "libmesh/mesh_tools.h" 28 #include "libmesh/node_range.h" 29 #include "libmesh/parallel.h" 30 #include "libmesh/parallel_algebra.h" 31 #include "libmesh/parallel_ghost_sync.h" 32 #include "libmesh/sphere.h" 33 #include "libmesh/threads.h" 34 #include "libmesh/enum_to_string.h" 35 #include "libmesh/enum_elem_type.h" 36 #include "libmesh/int_range.h" 37 #include "libmesh/utility.h" 38 #include "libmesh/boundary_info.h" 41 # include "libmesh/remote_elem.h" 48 #include <unordered_map> 49 #include <unordered_set> 79 for (
const auto & elem : range)
80 _weight += elem->n_nodes();
88 #if LIBMESH_USING_THREADS 89 void join (
const SumElemWeight & other)
90 { _weight += other.weight(); }
107 FindBBox () : _bbox()
116 for (
const auto & node : range)
119 _bbox.union_with(*node);
125 for (
const auto & elem : range)
128 _bbox.union_with(elem->loose_bounding_box());
132 Point & min() {
return _bbox.min(); }
134 Point & max() {
return _bbox.max(); }
138 #if LIBMESH_USING_THREADS 139 void join (
const FindBBox & other)
141 _bbox.union_with(other._bbox);
161 const unsigned int n_sys = d->
n_systems();
163 std::vector<unsigned int>
n_vars (n_sys, 0);
164 for (
unsigned int s = 0; s != n_sys; ++s)
169 const unsigned int tot_n_vars =
172 std::vector<unsigned int> n_comp (tot_n_vars, 0);
173 std::vector<dof_id_type> first_dof (tot_n_vars, 0);
175 for (
unsigned int s = 0, i=0; s != n_sys; ++s)
181 for (
unsigned int v = 0; v !=
n_vars[s]; ++v, ++i)
183 n_comp[i] = d->
n_comp(s,v);
195 const unsigned int * p_ui =
nullptr;
196 const std::vector<unsigned int> * p_vui =
nullptr;
197 const std::vector<dof_id_type> * p_vdid =
nullptr;
208 #ifdef LIBMESH_ENABLE_UNIQUE_ID 211 const std::unordered_set<unique_id_type> & unique_ids)
228 bool invalid = d && ((d->
unique_id() != tempmin) ||
236 if (!d && tempmin == tempmax)
239 #endif // LIBMESH_ENABLE_UNIQUE_ID 242 void find_nodal_neighbors_helper(
const dof_id_type global_id,
243 const std::vector<const Elem *> & node_to_elem_vec,
244 std::vector<const Node *> & neighbors)
249 std::set<const Node *> neighbor_set;
256 for (
const auto & elem : node_to_elem_vec)
262 unsigned local_node_number = elem->local_node(global_id);
267 const unsigned short n_edges = elem->n_edges();
272 switch (elem->type())
276 switch (local_node_number)
280 neighbor_set.insert(elem->node_ptr(1));
285 neighbor_set.insert(elem->node_ptr(0));
289 libmesh_error_msg(
"Invalid local node number: " << local_node_number <<
" found." << std::endl);
296 switch (local_node_number)
301 neighbor_set.insert(elem->node_ptr(2));
306 neighbor_set.insert(elem->node_ptr(0));
307 neighbor_set.insert(elem->node_ptr(1));
311 libmesh_error_msg(
"Invalid local node number: " << local_node_number <<
" found." << std::endl);
318 switch (local_node_number)
322 neighbor_set.insert(elem->node_ptr(2));
327 neighbor_set.insert(elem->node_ptr(3));
332 neighbor_set.insert(elem->node_ptr(0));
333 neighbor_set.insert(elem->node_ptr(3));
338 neighbor_set.insert(elem->node_ptr(1));
339 neighbor_set.insert(elem->node_ptr(2));
343 libmesh_error_msg(
"Invalid local node number: " << local_node_number <<
" found." << std::endl);
356 unsigned current_edge = 0;
358 const unsigned short n_nodes = elem->n_nodes();
360 while (current_edge < n_edges)
363 bool found_edge =
false;
364 for (; current_edge<n_edges; ++current_edge)
365 if (elem->is_node_on_edge(local_node_number, current_edge))
374 const Node * node_to_save =
nullptr;
377 for (
unsigned other_node_this_edge = 0; other_node_this_edge !=
n_nodes; other_node_this_edge++)
379 const bool both_vertices = elem->is_vertex(local_node_number) &&
380 elem->is_vertex(other_node_this_edge);
381 if ( elem->is_node_on_edge(other_node_this_edge, current_edge) &&
382 elem->node_id(other_node_this_edge) != global_id &&
384 (elem_order == 1 || !both_vertices))
387 node_to_save = elem->node_ptr(other_node_this_edge);
392 neighbor_set.insert(node_to_save);
406 neighbors.assign(neighbor_set.begin(), neighbor_set.end());
430 return weight + unpartitioned_weight;
436 mesh.elements_end()),
449 mesh.pid_elements_end(pid)),
457 std::vector<std::vector<dof_id_type>> & nodes_to_elem_map)
462 libmesh_deprecated();
466 for (
const auto & elem :
mesh.element_ptr_range())
467 for (
auto & node : elem->node_ref_range())
469 libmesh_assert_less (node.id(), nodes_to_elem_map.size());
470 libmesh_assert_less (elem->id(),
mesh.
n_elem());
472 nodes_to_elem_map[node.id()].push_back(elem->id());
479 std::vector<std::vector<const Elem *>> & nodes_to_elem_map)
484 libmesh_deprecated();
488 for (
const auto & elem :
mesh.element_ptr_range())
489 for (
auto & node : elem->node_ref_range())
491 libmesh_assert_less (node.id(), nodes_to_elem_map.size());
493 nodes_to_elem_map[node.id()].push_back(elem);
500 std::unordered_map<
dof_id_type, std::vector<dof_id_type>> & nodes_to_elem_map)
502 nodes_to_elem_map.clear();
504 for (
const auto & elem :
mesh.element_ptr_range())
505 for (
auto & node : elem->node_ref_range())
506 nodes_to_elem_map[node.id()].push_back(elem->id());
512 std::unordered_map<
dof_id_type, std::vector<const Elem *>> & nodes_to_elem_map)
514 nodes_to_elem_map.clear();
516 for (
const auto & elem :
mesh.element_ptr_range())
517 for (
auto & node : elem->node_ref_range())
518 nodes_to_elem_map[node.id()].push_back(elem);
523 std::unordered_set<dof_id_type>
526 std::unordered_set<dof_id_type> boundary_nodes;
530 for (
const auto & elem :
mesh.active_element_ptr_range())
531 for (
auto s : elem->side_index_range())
532 if (elem->neighbor_ptr(s) ==
nullptr)
534 auto nodes_on_side = elem->nodes_on_side(s);
536 for (
auto & local_id : nodes_on_side)
537 boundary_nodes.insert(elem->node_ptr(local_id)->id());
540 return boundary_nodes;
543 std::unordered_set<dof_id_type>
546 std::unordered_set<dof_id_type> block_boundary_nodes;
550 for (
const auto & elem :
mesh.active_element_ptr_range())
551 for (
auto s : elem->side_index_range())
552 if (elem->neighbor_ptr(s) && (elem->neighbor_ptr(s)->subdomain_id() != elem->subdomain_id()))
554 auto nodes_on_side = elem->nodes_on_side(s);
556 for (
auto & local_id : nodes_on_side)
557 block_boundary_nodes.insert(elem->node_ptr(local_id)->id());
560 return block_boundary_nodes;
585 return find_bbox.bbox();
605 mesh.local_nodes_end()),
612 return find_bbox.bbox();
622 const Real diag = (bbox.second - bbox.first).
norm();
623 const Point cent = (bbox.second + bbox.first)/2;
625 return Sphere (cent, .5*diag);
636 mesh.local_elements_end()),
639 return find_bbox.bbox();
657 mesh.pid_elements_end(pid)),
664 return find_bbox.bbox();
676 const Real diag = (bbox.second - bbox.first).
norm();
677 const Point cent = (bbox.second + bbox.first)/2;
679 return Sphere (cent, .5*diag);
696 mesh.active_local_subdomain_elements_end(sid)),
703 return find_bbox.bbox();
715 const Real diag = (bbox.second - bbox.first).
norm();
716 const Point cent = (bbox.second + bbox.first)/2;
718 return Sphere (cent, .5*diag);
724 std::vector<ElemType> & et)
728 for (
const auto & elem :
mesh.element_ptr_range())
729 if (!std::count(et.begin(), et.end(), elem->type()))
730 et.push_back(elem->type());
739 mesh.type_elements_end (type)));
748 mesh.active_type_elements_end (type)));
753 const unsigned int level)
758 for (
const auto & elem :
as_range(
mesh.type_elements_begin(type),
759 mesh.type_elements_end(type)))
760 if ((elem->level() == level) && !elem->subactive())
769 struct LevelCounter {
772 LevelCounter () : nl(0) {}
778 for (
const Elem * elem : range)
779 nl = std::max(elem->level() + 1, nl);
782 void join(
const LevelCounter & other) {
783 nl = std::max(nl, other.nl);
787 LevelCounter counter;
802 for (
const auto & elem :
as_range(
mesh.unpartitioned_elements_begin(),
803 mesh.unpartitioned_elements_end()))
805 nl = std::max(elem->level() + 1, nl);
817 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
818 mesh.local_elements_end()))
819 nl = std::max(elem->level() + 1, nl);
832 for (
const auto & elem :
as_range(
mesh.unpartitioned_elements_begin(),
833 mesh.unpartitioned_elements_end()))
834 nl = std::max(elem->level() + 1, nl);
843 libmesh_assert_equal_to(nl, paranoid_nl);
855 for (
const auto & elem :
mesh.element_ptr_range())
856 nl = std::max(elem->level() + 1, nl);
867 LOG_SCOPE(
"n_connected_components()",
"MeshTools");
872 libmesh_not_implemented();
890 std::vector<std::unordered_set<node_entry_type>> components;
896 auto find_component = [&components](node_entry_type n) {
897 for (
auto & c: components)
898 if (c.find(n) != c.end())
901 return (std::unordered_set<node_entry_type> *)(
nullptr);
904 auto add_to_component =
906 (std::unordered_set<node_entry_type> & component, node_entry_type n) {
908 if (component.find(n) != component.end())
911 auto current_component = find_component(n);
917 if (!current_component)
927 current_component->merge(component);
928 current_component->swap(component);
935 for (
const auto & elem :
mesh.element_ptr_range())
938 const node_entry_type first_node = elem->node_id(0);
940 auto component = find_component(first_node);
945 for (
auto & c: components)
950 component = &components.emplace_back();
952 for (
const Node & node : elem->node_ref_range())
955 const node_entry_type n = node.id();
956 add_to_component(*component, n);
958 auto it = constraint_rows.find(&node);
959 if (it == constraint_rows.end())
962 for (
const auto & [pr, val] : it->second)
966 if (std::abs(val) < constraint_tol)
969 const Elem * spline_elem = pr.first;
972 const Node * spline_node =
976 add_to_component(*component, spline_node->
id());
981 for (
auto & component : components)
982 if (!component.empty())
994 std::set<dof_id_type> & not_subactive_node_ids)
996 for (
const auto & elem :
mesh.element_ptr_range())
997 if (!elem->subactive())
998 for (
auto & n : elem->node_ref_range())
999 not_subactive_node_ids.insert(n.id());
1023 libmesh_parallel_only(
mesh.
comm());
1031 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
1032 mesh.local_elements_end()))
1033 if (elem->dim() ==
dim)
1034 vol += elem->volume();
1038 for (
const auto & elem :
as_range(
mesh.unpartitioned_elements_begin(),
1039 mesh.unpartitioned_elements_end()))
1040 if (elem->dim() ==
dim)
1041 vol += elem->volume();
1051 libmesh_parallel_only(
mesh.
comm());
1053 unsigned int max_p_level = 0;
1056 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
1057 mesh.local_elements_end()))
1058 max_p_level = std::max(elem->p_level(), max_p_level);
1061 for (
const auto & elem :
as_range(
mesh.unpartitioned_elements_begin(),
1062 mesh.unpartitioned_elements_end()))
1063 max_p_level = std::max(elem->p_level(), max_p_level);
1066 return max_p_level + 1;
1073 const std::vector<std::vector<const Elem *>> & nodes_to_elem_map,
1074 std::vector<const Node *> & neighbors)
1076 find_nodal_neighbors_helper(node.
id(), nodes_to_elem_map[node.
id()],
1084 const std::unordered_map<
dof_id_type, std::vector<const Elem *>> & nodes_to_elem_map,
1085 std::vector<const Node *> & neighbors)
1087 const std::vector<const Elem *> node_to_elem_vec =
1088 libmesh_map_find(nodes_to_elem_map, node.
id());
1089 find_nodal_neighbors_helper(node.
id(), node_to_elem_vec, neighbors);
1095 const std::unordered_map<
dof_id_type, std::vector<const Elem *>> & nodes_to_elem_map,
1096 std::vector<const Node *> & neighbors)
1104 if (!neighbors.size())
1107 const auto * elem = libmesh_map_find(nodes_to_elem_map, node.
id()).front();
1109 for (
const auto &side : elem->side_index_range())
1111 const auto &nodes_on_side = elem->nodes_on_side(side);
1113 std::find_if(nodes_on_side.begin(), nodes_on_side.end(), [&](
auto local_node_id) {
1114 return elem->node_id(local_node_id) == node.
id();
1117 if (it != nodes_on_side.end())
1119 for (
const auto &local_node_id : nodes_on_side)
1121 if (
const auto *node_ptr = elem->node_ptr(local_node_id);
1123 neighbors.push_back(node_ptr);
1134 std::map<
dof_id_type, std::vector<dof_id_type>> & hanging_nodes)
1137 for (
auto & elem :
mesh.active_local_element_ptr_range())
1138 if (elem->type() ==
QUAD4)
1139 for (
auto s : elem->side_index_range())
1146 if (neigh !=
nullptr)
1149 if (neigh->
level() < elem->level())
1151 const Elem * ancestor = elem;
1153 ancestor = ancestor->
parent();
1155 libmesh_assert_less (s_neigh, neigh->
n_neighbors());
1158 unsigned int local_node1=0;
1159 unsigned int local_node2=0;
1161 bool found_in_neighbor =
false;
1164 while (!elem->is_node_on_side(local_node1++,s)) { }
1168 local_node2=local_node1+1;
1171 while (!elem->is_node_on_side(local_node2++,s)) { }
1184 for (
unsigned int n=0;n<neigh->
n_sides();n++)
1185 if (neigh->
node_id(n) == node1)
1186 found_in_neighbor=
true;
1190 if (!found_in_neighbor)
1202 local_node2=local_node1+1;
1209 if (hanging_nodes[hanging_node].size()<2)
1211 hanging_nodes[hanging_node].push_back(neigh->
node_id(local_node1));
1212 hanging_nodes[hanging_node].push_back(neigh->
node_id(local_node2));
1223 std::vector<Elem *> nodeelem_to_delete;
1225 for (
auto & elem :
mesh.element_ptr_range())
1228 nodeelem_to_delete.push_back(elem);
1235 for (
auto & node_row : constraint_rows)
1236 for (
auto pr : node_row.second)
1238 const Elem * elem = pr.first.first;
1244 constraint_rows.clear();
1246 for (
Elem * elem : nodeelem_to_delete)
1248 Node * node = elem->node_ptr(0);
1258 LOG_SCOPE(
"valid_is_prepared()",
"MeshTools");
1263 std::unique_ptr<MeshBase> mesh_clone =
mesh.
clone();
1267 bool old_allow_renumbering = mesh_clone->allow_renumbering();
1268 mesh_clone->allow_renumbering(
false);
1270 bool old_skip_partitioning = mesh_clone->skip_partitioning();
1271 mesh_clone->skip_partitioning(
true);
1273 bool old_allow_remote_element_removal = mesh_clone->allow_remote_element_removal();
1274 mesh_clone->allow_remote_element_removal(
false);
1277 mesh_clone->prepare_for_use();
1280 mesh_clone->allow_renumbering(old_allow_renumbering);
1281 mesh_clone->skip_partitioning(old_skip_partitioning);
1282 mesh_clone->allow_remote_element_removal(old_allow_remote_element_removal);
1285 return (
mesh == *mesh_clone);
1294 LOG_SCOPE(
"libmesh_assert_equal_n_systems()",
"MeshTools");
1298 for (
const auto & elem :
mesh.element_ptr_range())
1301 n_sys = elem->n_systems();
1303 libmesh_assert_equal_to (elem->n_systems(), n_sys);
1306 for (
const auto & node :
mesh.node_ptr_range())
1309 n_sys = node->n_systems();
1311 libmesh_assert_equal_to (node->n_systems(), n_sys);
1317 #ifdef LIBMESH_ENABLE_AMR 1320 LOG_SCOPE(
"libmesh_assert_old_dof_objects()",
"MeshTools");
1322 for (
const auto & elem :
mesh.element_ptr_range())
1328 if (elem->has_dofs())
1331 for (
auto & node : elem->node_ref_range())
1332 if (node.has_dofs())
1338 #endif // LIBMESH_ENABLE_AMR 1344 LOG_SCOPE(
"libmesh_assert_valid_node_pointers()",
"MeshTools");
1349 for (
const Elem * elem :
mesh.element_ptr_range())
1354 elem->libmesh_assert_valid_node_pointers();
1355 for (
auto n : elem->neighbor_ptr_range())
1357 n->libmesh_assert_valid_node_pointers();
1359 libmesh_assert_not_equal_to (elem->parent(),
remote_elem);
1360 elem = elem->parent();
1369 LOG_SCOPE(
"libmesh_assert_valid_remote_elems()",
"MeshTools");
1371 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
1372 mesh.local_elements_end()))
1379 for (
auto n : elem->neighbor_ptr_range())
1382 #ifdef LIBMESH_ENABLE_AMR 1385 libmesh_assert_not_equal_to (parent,
remote_elem);
1389 if (elem->active() && elem->has_children())
1390 for (
auto & child : elem->child_ref_range())
1391 libmesh_assert_not_equal_to (&child,
remote_elem);
1400 LOG_SCOPE(
"libmesh_assert_valid_elem_ids()",
"MeshTools");
1405 for (
const auto & elem :
mesh.active_element_ptr_range())
1411 libmesh_assert_greater_equal (elemid, lastelemid);
1412 libmesh_assert_greater_equal (elemprocid, lastprocid);
1414 lastelemid = elemid;
1415 lastprocid = elemprocid;
1423 LOG_SCOPE(
"libmesh_assert_valid_amr_elem_ids()",
"MeshTools");
1425 for (
const auto & elem :
mesh.element_ptr_range())
1433 libmesh_assert_greater_equal (elem->id(), parent->
id());
1434 libmesh_assert_greater_equal (elem->processor_id(), parent->
processor_id());
1443 LOG_SCOPE(
"libmesh_assert_valid_amr_interior_parents()",
"MeshTools");
1445 for (
const auto & elem :
mesh.element_ptr_range())
1451 if (elem->dim() >= LIBMESH_DIM)
1463 if (ip->
level() == elem->level())
1464 libmesh_assert_equal_to (ip->
parent(),
1468 libmesh_assert_less (ip->
level(), elem->level());
1479 LOG_SCOPE(
"libmesh_assert_contiguous_dof_ids()",
"MeshTools");
1484 libmesh_parallel_only(
mesh.
comm());
1486 dof_id_type min_dof_id = std::numeric_limits<dof_id_type>::max(),
1487 max_dof_id = std::numeric_limits<dof_id_type>::min();
1490 for (
const auto * node :
mesh.local_node_ptr_range())
1492 for (
auto v :
make_range(node->n_vars(sysnum)))
1493 for (
auto c :
make_range(node->n_comp(sysnum, v)))
1496 min_dof_id = std::min (min_dof_id,
id);
1497 max_dof_id = std::max (max_dof_id,
id);
1502 for (
const auto * node :
mesh.node_ptr_range())
1506 for (
auto v :
make_range(node->n_vars(sysnum)))
1507 for (
auto c :
make_range(node->n_comp(sysnum, v)))
1521 LOG_SCOPE(
"libmesh_assert_topology_consistent_procids()",
"MeshTools");
1528 #ifdef LIBMESH_ENABLE_AMR 1532 for (
const auto & elem :
mesh.element_ptr_range())
1536 if (!elem->active() && !elem->subactive())
1545 bool matching_child_id =
false;
1553 matching_child_id =
true;
1565 LOG_SCOPE(
"libmesh_assert_topology_consistent_procids()",
"MeshTools");
1570 libmesh_parallel_only(
mesh.
comm());
1581 for (
const auto & node :
mesh.node_ptr_range())
1582 parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
1587 std::vector<bool> node_touched_by_me(parallel_max_node_id,
false);
1589 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
1590 mesh.local_elements_end()))
1594 for (
auto & node : elem->node_ref_range())
1597 node_touched_by_me[nodeid] =
true;
1600 std::vector<bool> node_touched_by_anyone(node_touched_by_me);
1603 for (
const auto & node :
mesh.local_node_ptr_range())
1608 node_touched_by_me[nodeid]);
1616 for (
const auto & elem :
mesh.active_element_ptr_range())
1617 for (
auto & node : elem->node_ref_range())
1618 libmesh_assert_equal_to
1619 (node.processor_id(),
1620 node.choose_processor_id(node.processor_id(),
1621 elem->processor_id()));
1626 #ifdef LIBMESH_ENABLE_AMR 1629 LOG_SCOPE(
"libmesh_assert_valid_refinement_tree()",
"MeshTools");
1631 for (
const auto & elem :
mesh.element_ptr_range())
1634 if (elem->has_children())
1635 for (
auto & child : elem->child_ref_range())
1637 libmesh_assert_equal_to (child.parent(), elem);
1643 else if (elem->ancestor())
1651 libmesh_assert_greater(elem->p_level(), 0);
1658 #endif // LIBMESH_ENABLE_AMR 1667 const Elem * bad_elem)
1669 for (
const auto & elem :
mesh.element_ptr_range())
1672 libmesh_assert_not_equal_to (elem->parent(), bad_elem);
1673 for (
auto n : elem->neighbor_ptr_range())
1674 libmesh_assert_not_equal_to (n, bad_elem);
1676 #ifdef LIBMESH_ENABLE_AMR 1677 if (elem->has_children())
1678 for (
auto & child : elem->child_ref_range())
1679 libmesh_assert_not_equal_to (&child, bad_elem);
1687 LOG_SCOPE(
"libmesh_assert_equal_points()",
"MeshTools");
1703 LOG_SCOPE(
"libmesh_assert_equal_connectivity()",
"MeshTools");
1712 std::vector<dof_id_type> nodes;
1715 nodes.push_back(e->
node_id(n));
1724 LOG_SCOPE(
"libmesh_assert_connected_nodes()",
"MeshTools");
1726 std::set<const Node *> used_nodes;
1728 for (
const auto & elem :
mesh.element_ptr_range())
1732 for (
auto & n : elem->node_ref_range())
1733 used_nodes.insert(&n);
1736 for (
const auto & node :
mesh.node_ptr_range())
1747 libmesh_parallel_only(
mesh.
comm());
1751 bool have_constraint_rows = !constraint_rows.empty();
1753 if (!have_constraint_rows)
1756 for (
auto & row : constraint_rows)
1758 const Node * node = row.first;
1761 for (
auto & pr : row.second)
1763 const Elem * spline_elem = pr.first.first;
1775 bool have_constraint = constraint_rows.count(node);
1777 const std::size_t my_n_constraints = have_constraint ?
1778 libmesh_map_find(constraint_rows, node).size() : std::size_t(-1);
1779 const std::size_t * n_constraints = node ?
1780 &my_n_constraints :
nullptr;
1790 LOG_SCOPE(
"libmesh_assert_valid_boundary_ids()",
"MeshTools");
1795 libmesh_parallel_only(
mesh.
comm());
1805 const unsigned int my_n_nodes = elem ? elem->
n_nodes() : 0;
1806 const unsigned int my_n_edges = elem ? elem->
n_edges() : 0;
1807 const unsigned int my_n_sides = elem ? elem->
n_sides() : 0;
1810 n_edges = my_n_edges,
1811 n_sides = my_n_sides;
1819 libmesh_assert_equal_to(my_n_nodes,
n_nodes);
1820 libmesh_assert_equal_to(my_n_edges, n_edges);
1821 libmesh_assert_equal_to(my_n_sides, n_sides);
1827 std::vector<boundary_id_type> all_bcids;
1829 for (
unsigned int n=0; n !=
n_nodes; ++n)
1831 std::vector<boundary_id_type> bcids;
1834 boundary_info.boundary_ids(elem->
node_ptr(n), bcids);
1837 std::sort(bcids.begin(), bcids.end());
1841 all_bcids.insert(all_bcids.end(), bcids.begin(),
1847 for (
unsigned short e=0; e != n_edges; ++e)
1849 std::vector<boundary_id_type> bcids;
1853 boundary_info.edge_boundary_ids(elem, e, bcids);
1856 std::sort(bcids.begin(), bcids.end());
1861 all_bcids.insert(all_bcids.end(), bcids.begin(),
1868 boundary_info.raw_edge_boundary_ids(elem, e, bcids);
1871 std::sort(bcids.begin(), bcids.end());
1873 all_bcids.insert(all_bcids.end(), bcids.begin(),
1882 for (
unsigned short s=0; s != n_sides; ++s)
1884 std::vector<boundary_id_type> bcids;
1888 boundary_info.boundary_ids(elem, s, bcids);
1891 std::sort(bcids.begin(), bcids.end());
1893 all_bcids.insert(all_bcids.end(), bcids.begin(),
1903 boundary_info.raw_boundary_ids(elem, s, bcids);
1906 std::sort(bcids.begin(), bcids.end());
1908 all_bcids.insert(all_bcids.end(), bcids.begin(),
1917 for (
unsigned short sf=0; sf != 2; ++sf)
1919 std::vector<boundary_id_type> bcids;
1923 boundary_info.shellface_boundary_ids(elem, sf, bcids);
1926 std::sort(bcids.begin(), bcids.end());
1928 all_bcids.insert(all_bcids.end(), bcids.begin(),
1938 boundary_info.raw_shellface_boundary_ids(elem, sf, bcids);
1941 std::sort(bcids.begin(), bcids.end());
1943 all_bcids.insert(all_bcids.end(), bcids.begin(),
1953 (elem ? &all_bcids :
nullptr));
1960 LOG_SCOPE(
"libmesh_assert_valid_dof_ids()",
"MeshTools");
1965 libmesh_parallel_only(
mesh.
comm());
1971 assert_semiverify_dofobj(
mesh.
comm(),
1979 assert_semiverify_dofobj(
mesh.
comm(),
1985 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1988 LOG_SCOPE(
"libmesh_assert_valid_unique_ids()",
"MeshTools");
1990 libmesh_parallel_only(
mesh.
comm());
1993 std::unordered_set<unique_id_type> semilocal_unique_ids;
1995 auto gather_elem_ids = [&]()
1997 for (
auto const & elem :
mesh.active_element_ptr_range())
1999 auto [it, inserted] = semilocal_unique_ids.insert(elem->unique_id());
2005 auto gather_node_ids = [&]()
2007 for (
auto const & node :
mesh.node_ptr_range())
2009 auto [it, inserted] = semilocal_unique_ids.insert(node->unique_id());
2015 auto verify_elems = [&]()
2023 assert_dofobj_unique_id(
mesh.
comm(), elem, semilocal_unique_ids);
2027 auto verify_nodes = [&]()
2035 assert_dofobj_unique_id(
mesh.
comm(), node, semilocal_unique_ids);
2060 semilocal_unique_ids.clear();
2071 libmesh_parallel_only(
mesh.
comm());
2076 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
2088 for (
dof_id_type i=0; i != parallel_max_node_id; ++i)
2101 libmesh_parallel_only(
mesh.
comm());
2107 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
2111 const unsigned int my_n_nodes = elem ? elem->
n_nodes() : 0;
2112 unsigned int n_nodes = my_n_nodes;
2118 for (
unsigned int n=0; n !=
n_nodes; ++n)
2120 const Node * node = elem ? elem->
node_ptr(n) :
nullptr;
2134 LOG_SCOPE(
"libmesh_assert_parallel_consistent_procids()",
"MeshTools");
2139 libmesh_parallel_only(
mesh.
comm());
2146 for (
const auto & elem :
mesh.element_ptr_range())
2147 parallel_max_elem_id = std::max<dof_id_type>(parallel_max_elem_id,
2153 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
2159 std::numeric_limits<processor_id_type>::max();
2164 std::numeric_limits<processor_id_type>::min();
2169 libmesh_assert_equal_to (min_id, elem->
processor_id());
2170 libmesh_assert_equal_to (max_id, elem->
processor_id());
2182 LOG_SCOPE(
"libmesh_assert_parallel_consistent_new_node_procids()",
"MeshTools");
2187 libmesh_parallel_only(
mesh.
comm());
2195 std::vector<bool> elem_touched_by_anyone(parallel_max_elem_id,
false);
2197 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
2201 const unsigned int my_n_nodes = elem ? elem->
n_nodes() : 0;
2202 unsigned int n_nodes = my_n_nodes;
2208 for (
unsigned int n=0; n !=
n_nodes; ++n)
2210 const Node * node = elem ? elem->
node_ptr(n) :
nullptr;
2220 LOG_SCOPE(
"libmesh_assert_parallel_consistent_procids()",
"MeshTools");
2225 libmesh_parallel_only(
mesh.
comm());
2236 for (
const auto & node :
mesh.node_ptr_range())
2237 parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
2241 std::vector<bool> node_touched_by_anyone(parallel_max_node_id,
false);
2243 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
2244 mesh.local_elements_end()))
2248 for (
auto & node : elem->node_ref_range())
2251 node_touched_by_anyone[nodeid] =
true;
2258 for (
dof_id_type i=0; i != parallel_max_node_id; ++i)
2260 if (!node_touched_by_anyone[i])
2272 #ifdef LIBMESH_ENABLE_AMR 2275 LOG_SCOPE(
"libmesh_assert_valid_refinement_flags()",
"MeshTools");
2277 libmesh_parallel_only(
mesh.
comm());
2284 std::vector<unsigned char> my_elem_h_state(pmax_elem_id, 255);
2285 std::vector<unsigned char> my_elem_p_state(pmax_elem_id, 255);
2287 for (
const auto & elem :
mesh.element_ptr_range())
2292 my_elem_h_state[elemid] =
2293 static_cast<unsigned char>(elem->refinement_flag());
2295 my_elem_p_state[elemid] =
2296 static_cast<unsigned char>(elem->p_refinement_flag());
2298 std::vector<unsigned char> min_elem_h_state(my_elem_h_state);
2301 std::vector<unsigned char> min_elem_p_state(my_elem_p_state);
2307 my_elem_h_state[i] == min_elem_h_state[i]);
2309 my_elem_p_state[i] == min_elem_p_state[i]);
2316 #endif // LIBMESH_ENABLE_AMR 2321 bool assert_valid_remote_elems)
2323 LOG_SCOPE(
"libmesh_assert_valid_neighbors()",
"MeshTools");
2325 for (
const auto & elem :
mesh.element_ptr_range())
2328 elem->libmesh_assert_valid_neighbors();
2334 libmesh_parallel_only(
mesh.
comm());
2343 const unsigned int my_n_neigh = elem ? elem->
n_neighbors() : 0;
2344 unsigned int n_neigh = my_n_neigh;
2347 libmesh_assert_equal_to (my_n_neigh, n_neigh);
2349 for (
unsigned int n = 0; n != n_neigh; ++n)
2358 p_my_neighbor = &my_neighbor;
2365 if (!assert_valid_remote_elems &&
2368 p_my_neighbor =
nullptr;
2381 typedef std::unordered_map<dof_id_type, processor_id_type> proc_id_map_type;
2385 typedef unsigned char datum;
2387 SyncNodeSet(std::unordered_set<const Node *> & _set,
2396 void gather_data (
const std::vector<dof_id_type> & ids,
2397 std::vector<datum> & data)
2400 data.resize(ids.size());
2415 bool act_on_data (
const std::vector<dof_id_type> & ids,
2416 const std::vector<datum> in_set)
2418 bool data_changed =
false;
2429 data_changed =
true;
2434 return data_changed;
2439 struct NodesNotInSet
2441 NodesNotInSet(
const std::unordered_set<const Node *> _set)
2444 bool operator() (
const Node * node)
const 2451 const std::unordered_set<const Node *>
node_set;
2455 struct SyncProcIdsFromMap
2459 SyncProcIdsFromMap(
const proc_id_map_type & _map,
2468 void gather_data (
const std::vector<dof_id_type> & ids,
2469 std::vector<datum> & data)
2472 data.resize(ids.size());
2482 data[i] = it->second;
2493 void act_on_data (
const std::vector<dof_id_type> & ids,
2494 const std::vector<datum> proc_ids)
2510 LOG_SCOPE(
"correct_node_proc_ids()",
"MeshTools");
2513 libmesh_parallel_only(
mesh.
comm());
2524 mesh.unpartitioned_elements_end()) == 0);
2543 std::unordered_set<const Node *> valid_nodes;
2550 if (!repartition_all_nodes)
2552 for (
const auto & elem :
mesh.active_element_ptr_range())
2553 for (
const auto & node : elem->node_ref_range())
2554 if (elem->processor_id() == node.processor_id())
2555 valid_nodes.insert(&node);
2557 SyncNodeSet syncv(valid_nodes,
mesh);
2566 for (
auto & elem :
mesh.active_element_ptr_range())
2570 for (
auto & node : elem->node_ref_range())
2577 it->second = node.choose_processor_id(it->second, pid);
2582 std::map<processor_id_type, std::vector<std::pair<dof_id_type, processor_id_type>>>
2585 for (
const auto & node :
mesh.node_ptr_range())
2586 if (
const auto it = std::as_const(
new_proc_ids).find(node->id());
2588 ids_to_push[node->processor_id()].emplace_back(node->id(), it->second);
2590 auto action_functor =
2593 const std::vector<std::pair<dof_id_type, processor_id_type>> & data)
2595 for (
const auto & [
id, pid] : data)
2608 Parallel::push_parallel_vector_data
2609 (
mesh.
comm(), ids_to_push, action_functor);
2615 std::unordered_set<Node *> ex_local_nodes;
2616 for (
auto & node :
mesh.local_node_ptr_range())
2619 ex_local_nodes.insert(node);
2622 if (repartition_all_nodes)
2627 NodesNotInSet nnis(valid_nodes);
2634 for (
const auto & node : ex_local_nodes)
2636 if (valid_nodes.count(node))
2640 const proc_id_map_type::iterator it =
new_proc_ids.find(
id);
2642 node->processor_id() = it->second;
2649 libmesh_assert_valid_procids<Node>(
mesh);
static const Order type_to_default_order_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the default approximation order of...
ElemType
Defines an enum for geometric element types.
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
const Elem * parent() const
static constexpr processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
A Node is like a Point, but with more information.
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
unsigned int n_comp(const unsigned int s, const unsigned int var) const
std::unique_ptr< PointLocatorBase > sub_point_locator() const
This class defines a sphere.
const Elem * interior_parent() const
The definition of the const_element_iterator struct.
const Elem * top_parent() const
Dummy "splitting object" used to distinguish splitting constructors from copy constructors.
This is the base class from which all geometric element types are derived.
void assign_global_indices(MeshBase &) const
This method assigns globally unique, partition-agnostic indices to the nodes and elements in the mesh...
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
void skip_noncritical_partitioning(bool skip)
If true is passed in then the elements on this mesh will no longer be (re)partitioned, and the nodes on this mesh will only be repartitioned if they are found "orphaned" via coarsening or other removal of the last element responsible for their node/element processor id consistency.
unique_id_type unique_id() const
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
The libMesh namespace provides an interface to certain functionality in the library.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
virtual std::unique_ptr< MeshBase > clone() const =0
Virtual "copy constructor".
Real distance(const Point &p)
processor_id_type choose_processor_id(processor_id_type pid1, processor_id_type pid2) const
Return which of pid1 and pid2 would be preferred by the current load-balancing heuristic applied to t...
uint8_t processor_id_type
This is the MeshBase class.
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
virtual bool is_serial_on_zero() const
uint8_t processor_id_type
processor_id_type n_processors() const
virtual bool is_serial() const
void libmesh_ignore(const Args &...)
const dof_id_type n_nodes
static const boundary_id_type invalid_id
Number used for internal use.
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.
ElemMappingType mapping_type() const
This is the MeshCommunication class.
void min(const T &r, T &o, Request &req) const
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
virtual unsigned int n_nodes() const =0
unsigned int n_vars(const unsigned int s, const unsigned int vg) const
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
unsigned int n_systems() const
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
virtual const Node * query_node_ptr(const dof_id_type i) const =0
virtual dof_id_type max_elem_id() const =0
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
virtual void delete_node(Node *n)=0
Removes the Node n from the mesh.
const ConstElemRange & active_local_element_stored_range() const
void allow_node_and_elem_unique_id_overlap(bool allow)
If true is passed, then this mesh will no longer require unique_ids to be unique across the set of al...
virtual unsigned int n_edges() const =0
timpi_pure bool semiverify(const T *r) const
void sync_dofobject_data_by_id(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
Request data about a range of ghost dofobjects uniquely identified by their id.
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
std::string enum_to_string(const T e)
Defines a Cartesian bounding box by the two corner extremum.
virtual const Elem * elem_ptr(const dof_id_type i) const =0
virtual unsigned int n_sides() const =0
const Elem * neighbor_ptr(unsigned int i) const
unsigned int level() const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
timpi_pure bool verify(const T &r) const
void max(const T &r, T &o, Request &req) const
DIE A HORRIBLE DEATH HERE typedef MPI_Comm communicator
const Node * node_ptr(const unsigned int i) const
unsigned int n_neighbors() const
The definition of the const_node_iterator struct.
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
unsigned int mesh_dimension() const
IntRange< unsigned short > node_index_range() const
virtual const Node & node_ref(const dof_id_type i) const
virtual dof_id_type max_node_id() const =0
virtual dof_id_type n_elem() const =0
virtual const Node * node_ptr(const dof_id_type i) const =0
processor_id_type processor_id() const
processor_id_type processor_id() const
virtual ElemType type() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
dof_id_type node_id(const unsigned int i) const
bool has_children() const
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
const RemoteElem * remote_elem