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())
771 for (
auto & elem :
mesh.active_local_element_ptr_range())
772 nl = std::max(elem->level() + 1, nl);
785 for (
const auto & elem :
as_range(
mesh.unpartitioned_elements_begin(),
786 mesh.unpartitioned_elements_end()))
788 nl = std::max(elem->level() + 1, nl);
800 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
801 mesh.local_elements_end()))
802 nl = std::max(elem->level() + 1, nl);
815 for (
const auto & elem :
as_range(
mesh.unpartitioned_elements_begin(),
816 mesh.unpartitioned_elements_end()))
817 nl = std::max(elem->level() + 1, nl);
826 libmesh_assert_equal_to(nl, paranoid_nl);
838 for (
const auto & elem :
mesh.element_ptr_range())
839 nl = std::max(elem->level() + 1, nl);
850 LOG_SCOPE(
"n_connected_components()",
"MeshTools");
855 libmesh_not_implemented();
868 std::vector<std::unordered_set<const Node *>> components;
874 auto find_component = [&components](
const Node * n) {
875 std::unordered_set<const Node *> * component =
nullptr;
877 for (
auto & c: components)
878 if (c.find(n) != c.end())
887 auto add_to_component =
889 (std::unordered_set<const Node *> & component,
const Node * n) {
891 auto current_component = find_component(n);
893 if (&component == current_component)
897 else if (!current_component)
904 component.merge(*current_component);
911 for (
const auto & elem :
mesh.element_ptr_range())
913 const Node * first_node = elem->node_ptr(0);
915 auto component = find_component(first_node);
920 for (
auto & c: components)
925 component = &components.emplace_back();
927 for (
const Node & n : elem->node_ref_range())
929 add_to_component(*component, &n);
931 auto it = constraint_rows.find(&n);
932 if (it == constraint_rows.end())
935 for (
const auto & [pr, val] : it->second)
939 if (std::abs(val) < constraint_tol)
942 const Elem * spline_elem = pr.first;
945 const Node * spline_node =
948 add_to_component(*component, spline_node);
953 for (
auto & component : components)
954 if (!component.empty())
966 std::set<dof_id_type> & not_subactive_node_ids)
968 for (
const auto & elem :
mesh.element_ptr_range())
969 if (!elem->subactive())
970 for (
auto & n : elem->node_ref_range())
971 not_subactive_node_ids.insert(n.id());
1003 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
1004 mesh.local_elements_end()))
1005 if (elem->dim() ==
dim)
1006 vol += elem->volume();
1010 for (
const auto & elem :
as_range(
mesh.unpartitioned_elements_begin(),
1011 mesh.unpartitioned_elements_end()))
1012 if (elem->dim() ==
dim)
1013 vol += elem->volume();
1023 libmesh_parallel_only(
mesh.
comm());
1025 unsigned int max_p_level = 0;
1028 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
1029 mesh.local_elements_end()))
1030 max_p_level = std::max(elem->p_level(), max_p_level);
1033 for (
const auto & elem :
as_range(
mesh.unpartitioned_elements_begin(),
1034 mesh.unpartitioned_elements_end()))
1035 max_p_level = std::max(elem->p_level(), max_p_level);
1038 return max_p_level + 1;
1045 const std::vector<std::vector<const Elem *>> & nodes_to_elem_map,
1046 std::vector<const Node *> & neighbors)
1048 find_nodal_neighbors_helper(node.
id(), nodes_to_elem_map[node.
id()],
1056 const std::unordered_map<
dof_id_type, std::vector<const Elem *>> & nodes_to_elem_map,
1057 std::vector<const Node *> & neighbors)
1059 const std::vector<const Elem *> node_to_elem_vec =
1060 libmesh_map_find(nodes_to_elem_map, node.
id());
1061 find_nodal_neighbors_helper(node.
id(), node_to_elem_vec, neighbors);
1067 std::map<
dof_id_type, std::vector<dof_id_type>> & hanging_nodes)
1070 for (
auto & elem :
mesh.active_local_element_ptr_range())
1071 if (elem->type() ==
QUAD4)
1072 for (
auto s : elem->side_index_range())
1079 if (neigh !=
nullptr)
1082 if (neigh->
level() < elem->level())
1084 const Elem * ancestor = elem;
1086 ancestor = ancestor->
parent();
1088 libmesh_assert_less (s_neigh, neigh->
n_neighbors());
1091 unsigned int local_node1=0;
1092 unsigned int local_node2=0;
1094 bool found_in_neighbor =
false;
1097 while (!elem->is_node_on_side(local_node1++,s)) { }
1101 local_node2=local_node1+1;
1104 while (!elem->is_node_on_side(local_node2++,s)) { }
1117 for (
unsigned int n=0;n<neigh->
n_sides();n++)
1118 if (neigh->
node_id(n) == node1)
1119 found_in_neighbor=
true;
1123 if (!found_in_neighbor)
1135 local_node2=local_node1+1;
1142 if (hanging_nodes[hanging_node].size()<2)
1144 hanging_nodes[hanging_node].push_back(neigh->
node_id(local_node1));
1145 hanging_nodes[hanging_node].push_back(neigh->
node_id(local_node2));
1156 std::vector<Elem *> nodeelem_to_delete;
1158 for (
auto & elem :
mesh.element_ptr_range())
1161 nodeelem_to_delete.push_back(elem);
1168 for (
auto & node_row : constraint_rows)
1169 for (
auto pr : node_row.second)
1171 const Elem * elem = pr.first.first;
1177 constraint_rows.clear();
1179 for (
Elem * elem : nodeelem_to_delete)
1181 Node * node = elem->node_ptr(0);
1191 LOG_SCOPE(
"libmesh_assert_valid_is_prepared()",
"MeshTools");
1196 std::unique_ptr<MeshBase> mesh_clone =
mesh.
clone();
1200 bool old_allow_renumbering = mesh_clone->allow_renumbering();
1201 mesh_clone->allow_renumbering(
false);
1202 bool old_allow_remote_element_removal =
1203 mesh_clone->allow_remote_element_removal();
1204 bool old_skip_partitioning = mesh_clone->skip_partitioning();
1205 mesh_clone->skip_partitioning(
true);
1206 mesh_clone->allow_remote_element_removal(
false);
1207 mesh_clone->prepare_for_use();
1208 mesh_clone->allow_renumbering(old_allow_renumbering);
1209 mesh_clone->allow_remote_element_removal(old_allow_remote_element_removal);
1210 mesh_clone->skip_partitioning(old_skip_partitioning);
1212 return (
mesh == *mesh_clone);
1221 LOG_SCOPE(
"libmesh_assert_equal_n_systems()",
"MeshTools");
1225 for (
const auto & elem :
mesh.element_ptr_range())
1228 n_sys = elem->n_systems();
1230 libmesh_assert_equal_to (elem->n_systems(), n_sys);
1233 for (
const auto & node :
mesh.node_ptr_range())
1236 n_sys = node->n_systems();
1238 libmesh_assert_equal_to (node->n_systems(), n_sys);
1244 #ifdef LIBMESH_ENABLE_AMR 1247 LOG_SCOPE(
"libmesh_assert_old_dof_objects()",
"MeshTools");
1249 for (
const auto & elem :
mesh.element_ptr_range())
1255 if (elem->has_dofs())
1258 for (
auto & node : elem->node_ref_range())
1259 if (node.has_dofs())
1265 #endif // LIBMESH_ENABLE_AMR 1271 LOG_SCOPE(
"libmesh_assert_valid_node_pointers()",
"MeshTools");
1276 for (
const Elem * elem :
mesh.element_ptr_range())
1281 elem->libmesh_assert_valid_node_pointers();
1282 for (
auto n : elem->neighbor_ptr_range())
1284 n->libmesh_assert_valid_node_pointers();
1286 libmesh_assert_not_equal_to (elem->parent(),
remote_elem);
1287 elem = elem->parent();
1296 LOG_SCOPE(
"libmesh_assert_valid_remote_elems()",
"MeshTools");
1298 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
1299 mesh.local_elements_end()))
1306 for (
auto n : elem->neighbor_ptr_range())
1309 #ifdef LIBMESH_ENABLE_AMR 1312 libmesh_assert_not_equal_to (parent,
remote_elem);
1316 if (elem->active() && elem->has_children())
1317 for (
auto & child : elem->child_ref_range())
1318 libmesh_assert_not_equal_to (&child,
remote_elem);
1327 LOG_SCOPE(
"libmesh_assert_valid_elem_ids()",
"MeshTools");
1332 for (
const auto & elem :
mesh.active_element_ptr_range())
1338 libmesh_assert_greater_equal (elemid, lastelemid);
1339 libmesh_assert_greater_equal (elemprocid, lastprocid);
1341 lastelemid = elemid;
1342 lastprocid = elemprocid;
1350 LOG_SCOPE(
"libmesh_assert_valid_amr_elem_ids()",
"MeshTools");
1352 for (
const auto & elem :
mesh.element_ptr_range())
1360 libmesh_assert_greater_equal (elem->id(), parent->
id());
1361 libmesh_assert_greater_equal (elem->processor_id(), parent->
processor_id());
1370 LOG_SCOPE(
"libmesh_assert_valid_amr_interior_parents()",
"MeshTools");
1372 for (
const auto & elem :
mesh.element_ptr_range())
1378 if (elem->dim() >= LIBMESH_DIM)
1390 if (ip->
level() == elem->level())
1391 libmesh_assert_equal_to (ip->
parent(),
1395 libmesh_assert_less (ip->
level(), elem->level());
1406 LOG_SCOPE(
"libmesh_assert_contiguous_dof_ids()",
"MeshTools");
1411 libmesh_parallel_only(
mesh.
comm());
1413 dof_id_type min_dof_id = std::numeric_limits<dof_id_type>::max(),
1414 max_dof_id = std::numeric_limits<dof_id_type>::min();
1417 for (
const auto * node :
mesh.local_node_ptr_range())
1419 for (
auto v :
make_range(node->n_vars(sysnum)))
1420 for (
auto c :
make_range(node->n_comp(sysnum, v)))
1423 min_dof_id = std::min (min_dof_id,
id);
1424 max_dof_id = std::max (max_dof_id,
id);
1429 for (
const auto * node :
mesh.node_ptr_range())
1433 for (
auto v :
make_range(node->n_vars(sysnum)))
1434 for (
auto c :
make_range(node->n_comp(sysnum, v)))
1448 LOG_SCOPE(
"libmesh_assert_topology_consistent_procids()",
"MeshTools");
1455 #ifdef LIBMESH_ENABLE_AMR 1459 for (
const auto & elem :
mesh.element_ptr_range())
1463 if (!elem->active() && !elem->subactive())
1472 bool matching_child_id =
false;
1480 matching_child_id =
true;
1492 LOG_SCOPE(
"libmesh_assert_topology_consistent_procids()",
"MeshTools");
1497 libmesh_parallel_only(
mesh.
comm());
1508 for (
const auto & node :
mesh.node_ptr_range())
1509 parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
1514 std::vector<bool> node_touched_by_me(parallel_max_node_id,
false);
1516 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
1517 mesh.local_elements_end()))
1521 for (
auto & node : elem->node_ref_range())
1524 node_touched_by_me[nodeid] =
true;
1527 std::vector<bool> node_touched_by_anyone(node_touched_by_me);
1530 for (
const auto & node :
mesh.local_node_ptr_range())
1535 node_touched_by_me[nodeid]);
1543 for (
const auto & elem :
mesh.active_element_ptr_range())
1544 for (
auto & node : elem->node_ref_range())
1545 libmesh_assert_equal_to
1546 (node.processor_id(),
1547 node.choose_processor_id(node.processor_id(),
1548 elem->processor_id()));
1553 #ifdef LIBMESH_ENABLE_AMR 1556 LOG_SCOPE(
"libmesh_assert_valid_refinement_tree()",
"MeshTools");
1558 for (
const auto & elem :
mesh.element_ptr_range())
1561 if (elem->has_children())
1562 for (
auto & child : elem->child_ref_range())
1564 libmesh_assert_equal_to (child.parent(), elem);
1570 else if (elem->ancestor())
1578 libmesh_assert_greater(elem->p_level(), 0);
1585 #endif // LIBMESH_ENABLE_AMR 1594 const Elem * bad_elem)
1596 for (
const auto & elem :
mesh.element_ptr_range())
1599 libmesh_assert_not_equal_to (elem->parent(), bad_elem);
1600 for (
auto n : elem->neighbor_ptr_range())
1601 libmesh_assert_not_equal_to (n, bad_elem);
1603 #ifdef LIBMESH_ENABLE_AMR 1604 if (elem->has_children())
1605 for (
auto & child : elem->child_ref_range())
1606 libmesh_assert_not_equal_to (&child, bad_elem);
1614 LOG_SCOPE(
"libmesh_assert_equal_points()",
"MeshTools");
1630 LOG_SCOPE(
"libmesh_assert_equal_connectivity()",
"MeshTools");
1639 std::vector<dof_id_type> nodes;
1642 nodes.push_back(e->
node_id(n));
1651 LOG_SCOPE(
"libmesh_assert_connected_nodes()",
"MeshTools");
1653 std::set<const Node *> used_nodes;
1655 for (
const auto & elem :
mesh.element_ptr_range())
1659 for (
auto & n : elem->node_ref_range())
1660 used_nodes.insert(&n);
1663 for (
const auto & node :
mesh.node_ptr_range())
1674 libmesh_parallel_only(
mesh.
comm());
1678 bool have_constraint_rows = !constraint_rows.empty();
1680 if (!have_constraint_rows)
1683 for (
auto & row : constraint_rows)
1685 const Node * node = row.first;
1688 for (
auto & pr : row.second)
1690 const Elem * spline_elem = pr.first.first;
1702 bool have_constraint = constraint_rows.count(node);
1704 const std::size_t my_n_constraints = have_constraint ?
1705 libmesh_map_find(constraint_rows, node).size() : std::size_t(-1);
1706 const std::size_t * n_constraints = node ?
1707 &my_n_constraints :
nullptr;
1717 LOG_SCOPE(
"libmesh_assert_valid_boundary_ids()",
"MeshTools");
1722 libmesh_parallel_only(
mesh.
comm());
1732 const unsigned int my_n_nodes = elem ? elem->
n_nodes() : 0;
1733 const unsigned int my_n_edges = elem ? elem->
n_edges() : 0;
1734 const unsigned int my_n_sides = elem ? elem->
n_sides() : 0;
1737 n_edges = my_n_edges,
1738 n_sides = my_n_sides;
1746 libmesh_assert_equal_to(my_n_nodes,
n_nodes);
1747 libmesh_assert_equal_to(my_n_edges, n_edges);
1748 libmesh_assert_equal_to(my_n_sides, n_sides);
1754 std::vector<boundary_id_type> all_bcids;
1756 for (
unsigned int n=0; n !=
n_nodes; ++n)
1758 std::vector<boundary_id_type> bcids;
1761 boundary_info.boundary_ids(elem->
node_ptr(n), bcids);
1764 std::sort(bcids.begin(), bcids.end());
1768 all_bcids.insert(all_bcids.end(), bcids.begin(),
1774 for (
unsigned short e=0; e != n_edges; ++e)
1776 std::vector<boundary_id_type> bcids;
1780 boundary_info.edge_boundary_ids(elem, e, bcids);
1783 std::sort(bcids.begin(), bcids.end());
1788 all_bcids.insert(all_bcids.end(), bcids.begin(),
1795 boundary_info.raw_edge_boundary_ids(elem, e, bcids);
1798 std::sort(bcids.begin(), bcids.end());
1800 all_bcids.insert(all_bcids.end(), bcids.begin(),
1809 for (
unsigned short s=0; s != n_sides; ++s)
1811 std::vector<boundary_id_type> bcids;
1815 boundary_info.boundary_ids(elem, s, bcids);
1818 std::sort(bcids.begin(), bcids.end());
1820 all_bcids.insert(all_bcids.end(), bcids.begin(),
1830 boundary_info.raw_boundary_ids(elem, s, bcids);
1833 std::sort(bcids.begin(), bcids.end());
1835 all_bcids.insert(all_bcids.end(), bcids.begin(),
1844 for (
unsigned short sf=0; sf != 2; ++sf)
1846 std::vector<boundary_id_type> bcids;
1850 boundary_info.shellface_boundary_ids(elem, sf, bcids);
1853 std::sort(bcids.begin(), bcids.end());
1855 all_bcids.insert(all_bcids.end(), bcids.begin(),
1865 boundary_info.raw_shellface_boundary_ids(elem, sf, bcids);
1868 std::sort(bcids.begin(), bcids.end());
1870 all_bcids.insert(all_bcids.end(), bcids.begin(),
1880 (elem ? &all_bcids :
nullptr));
1887 LOG_SCOPE(
"libmesh_assert_valid_dof_ids()",
"MeshTools");
1892 libmesh_parallel_only(
mesh.
comm());
1898 assert_semiverify_dofobj(
mesh.
comm(),
1906 assert_semiverify_dofobj(
mesh.
comm(),
1912 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1915 LOG_SCOPE(
"libmesh_assert_valid_unique_ids()",
"MeshTools");
1917 libmesh_parallel_only(
mesh.
comm());
1921 std::unordered_set<unique_id_type> semilocal_unique_ids;
1923 for (
auto const & elem :
mesh.active_element_ptr_range())
1926 semilocal_unique_ids.insert(elem->unique_id());
1929 for (
auto const & node :
mesh.node_ptr_range())
1932 semilocal_unique_ids.insert(node->unique_id());
1944 assert_dofobj_unique_id(
mesh.
comm(), elem, semilocal_unique_ids);
1956 assert_dofobj_unique_id(
mesh.
comm(), node, semilocal_unique_ids);
1963 libmesh_parallel_only(
mesh.
comm());
1968 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
1980 for (
dof_id_type i=0; i != parallel_max_node_id; ++i)
1993 libmesh_parallel_only(
mesh.
comm());
1999 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
2003 const unsigned int my_n_nodes = elem ? elem->
n_nodes() : 0;
2004 unsigned int n_nodes = my_n_nodes;
2010 for (
unsigned int n=0; n !=
n_nodes; ++n)
2012 const Node * node = elem ? elem->
node_ptr(n) :
nullptr;
2026 LOG_SCOPE(
"libmesh_assert_parallel_consistent_procids()",
"MeshTools");
2031 libmesh_parallel_only(
mesh.
comm());
2038 for (
const auto & elem :
mesh.element_ptr_range())
2039 parallel_max_elem_id = std::max<dof_id_type>(parallel_max_elem_id,
2045 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
2051 std::numeric_limits<processor_id_type>::max();
2056 std::numeric_limits<processor_id_type>::min();
2061 libmesh_assert_equal_to (min_id, elem->
processor_id());
2062 libmesh_assert_equal_to (max_id, elem->
processor_id());
2074 LOG_SCOPE(
"libmesh_assert_parallel_consistent_new_node_procids()",
"MeshTools");
2079 libmesh_parallel_only(
mesh.
comm());
2087 std::vector<bool> elem_touched_by_anyone(parallel_max_elem_id,
false);
2089 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
2093 const unsigned int my_n_nodes = elem ? elem->
n_nodes() : 0;
2094 unsigned int n_nodes = my_n_nodes;
2100 for (
unsigned int n=0; n !=
n_nodes; ++n)
2102 const Node * node = elem ? elem->
node_ptr(n) :
nullptr;
2112 LOG_SCOPE(
"libmesh_assert_parallel_consistent_procids()",
"MeshTools");
2117 libmesh_parallel_only(
mesh.
comm());
2128 for (
const auto & node :
mesh.node_ptr_range())
2129 parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
2133 std::vector<bool> node_touched_by_anyone(parallel_max_node_id,
false);
2135 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
2136 mesh.local_elements_end()))
2140 for (
auto & node : elem->node_ref_range())
2143 node_touched_by_anyone[nodeid] =
true;
2150 for (
dof_id_type i=0; i != parallel_max_node_id; ++i)
2152 if (!node_touched_by_anyone[i])
2164 #ifdef LIBMESH_ENABLE_AMR 2167 LOG_SCOPE(
"libmesh_assert_valid_refinement_flags()",
"MeshTools");
2169 libmesh_parallel_only(
mesh.
comm());
2176 std::vector<unsigned char> my_elem_h_state(pmax_elem_id, 255);
2177 std::vector<unsigned char> my_elem_p_state(pmax_elem_id, 255);
2179 for (
const auto & elem :
mesh.element_ptr_range())
2184 my_elem_h_state[elemid] =
2185 static_cast<unsigned char>(elem->refinement_flag());
2187 my_elem_p_state[elemid] =
2188 static_cast<unsigned char>(elem->p_refinement_flag());
2190 std::vector<unsigned char> min_elem_h_state(my_elem_h_state);
2193 std::vector<unsigned char> min_elem_p_state(my_elem_p_state);
2199 my_elem_h_state[i] == min_elem_h_state[i]);
2201 my_elem_p_state[i] == min_elem_p_state[i]);
2208 #endif // LIBMESH_ENABLE_AMR 2213 bool assert_valid_remote_elems)
2215 LOG_SCOPE(
"libmesh_assert_valid_neighbors()",
"MeshTools");
2217 for (
const auto & elem :
mesh.element_ptr_range())
2220 elem->libmesh_assert_valid_neighbors();
2226 libmesh_parallel_only(
mesh.
comm());
2235 const unsigned int my_n_neigh = elem ? elem->
n_neighbors() : 0;
2236 unsigned int n_neigh = my_n_neigh;
2239 libmesh_assert_equal_to (my_n_neigh, n_neigh);
2241 for (
unsigned int n = 0; n != n_neigh; ++n)
2250 p_my_neighbor = &my_neighbor;
2257 if (!assert_valid_remote_elems &&
2260 p_my_neighbor =
nullptr;
2273 typedef std::unordered_map<dof_id_type, processor_id_type> proc_id_map_type;
2277 typedef unsigned char datum;
2279 SyncNodeSet(std::unordered_set<const Node *> & _set,
2288 void gather_data (
const std::vector<dof_id_type> & ids,
2289 std::vector<datum> & data)
2292 data.resize(ids.size());
2307 bool act_on_data (
const std::vector<dof_id_type> & ids,
2308 const std::vector<datum> in_set)
2310 bool data_changed =
false;
2321 data_changed =
true;
2326 return data_changed;
2331 struct NodesNotInSet
2333 NodesNotInSet(
const std::unordered_set<const Node *> _set)
2336 bool operator() (
const Node * node)
const 2343 const std::unordered_set<const Node *>
node_set;
2347 struct SyncProcIdsFromMap
2351 SyncProcIdsFromMap(
const proc_id_map_type & _map,
2360 void gather_data (
const std::vector<dof_id_type> & ids,
2361 std::vector<datum> & data)
2364 data.resize(ids.size());
2374 data[i] = it->second;
2385 void act_on_data (
const std::vector<dof_id_type> & ids,
2386 const std::vector<datum> proc_ids)
2402 LOG_SCOPE(
"correct_node_proc_ids()",
"MeshTools");
2405 libmesh_parallel_only(
mesh.
comm());
2416 mesh.unpartitioned_elements_end()) == 0);
2435 std::unordered_set<const Node *> valid_nodes;
2442 if (!repartition_all_nodes)
2444 for (
const auto & elem :
mesh.active_element_ptr_range())
2445 for (
const auto & node : elem->node_ref_range())
2446 if (elem->processor_id() == node.processor_id())
2447 valid_nodes.insert(&node);
2449 SyncNodeSet syncv(valid_nodes,
mesh);
2458 for (
auto & elem :
mesh.active_element_ptr_range())
2462 for (
auto & node : elem->node_ref_range())
2469 it->second = node.choose_processor_id(it->second, pid);
2474 std::map<processor_id_type, std::vector<std::pair<dof_id_type, processor_id_type>>>
2477 for (
const auto & node :
mesh.node_ptr_range())
2478 if (
const auto it = std::as_const(
new_proc_ids).find(node->id());
2480 ids_to_push[node->processor_id()].emplace_back(node->id(), it->second);
2482 auto action_functor =
2485 const std::vector<std::pair<dof_id_type, processor_id_type>> & data)
2487 for (
const auto & [
id, pid] : data)
2500 Parallel::push_parallel_vector_data
2501 (
mesh.
comm(), ids_to_push, action_functor);
2507 std::unordered_set<Node *> ex_local_nodes;
2508 for (
auto & node :
mesh.local_node_ptr_range())
2511 ex_local_nodes.insert(node);
2514 if (repartition_all_nodes)
2519 NodesNotInSet nnis(valid_nodes);
2526 for (
const auto & node : ex_local_nodes)
2528 if (valid_nodes.count(node))
2532 const proc_id_map_type::iterator it =
new_proc_ids.find(
id);
2534 node->processor_id() = it->second;
2541 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.
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
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
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
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