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_tools.h"
27 #include "libmesh/node_range.h"
28 #include "libmesh/parallel.h"
29 #include "libmesh/parallel_algebra.h"
30 #include "libmesh/parallel_ghost_sync.h"
31 #include "libmesh/sphere.h"
32 #include "libmesh/threads.h"
33 #include "libmesh/enum_to_string.h"
34 #include "libmesh/enum_elem_type.h"
35 #include "libmesh/int_range.h"
36 #include "libmesh/utility.h"
39 # include "libmesh/remote_elem.h"
46 #include <unordered_map>
47 #include <unordered_set>
77 for (
const auto & elem : range)
78 _weight += elem->n_nodes();
86 #if LIBMESH_USING_THREADS
87 void join (
const SumElemWeight & other)
88 { _weight += other.weight(); }
105 FindBBox () : _bbox()
114 for (
const auto & node : range)
117 _bbox.union_with(*node);
123 for (
const auto & elem : range)
126 _bbox.union_with(elem->loose_bounding_box());
130 Point & min() {
return _bbox.min(); }
132 Point & max() {
return _bbox.max(); }
136 #if LIBMESH_USING_THREADS
137 void join (
const FindBBox & other)
139 _bbox.union_with(other._bbox);
153 void assert_semiverify_dofobj(
const Parallel::Communicator & communicator,
159 const unsigned int n_sys = d->
n_systems();
161 std::vector<unsigned int>
n_vars (n_sys, 0);
162 for (
unsigned int s = 0; s != n_sys; ++s)
167 const unsigned int tot_n_vars =
170 std::vector<unsigned int> n_comp (tot_n_vars, 0);
171 std::vector<dof_id_type> first_dof (tot_n_vars, 0);
173 for (
unsigned int s = 0, i=0; s != n_sys; ++s)
179 for (
unsigned int v = 0; v !=
n_vars[s]; ++v, ++i)
181 n_comp[i] = d->
n_comp(s,v);
193 const unsigned int * p_ui =
nullptr;
194 const std::vector<unsigned int> * p_vui =
nullptr;
195 const std::vector<dof_id_type> * p_vdid =
nullptr;
222 return weight + unpartitioned_weight;
249 std::vector<std::vector<dof_id_type>> & nodes_to_elem_map)
254 for (
auto & node : elem->node_ref_range())
256 libmesh_assert_less (node.id(), nodes_to_elem_map.size());
257 libmesh_assert_less (elem->id(),
mesh.
n_elem());
259 nodes_to_elem_map[node.id()].push_back(elem->id());
266 std::vector<std::vector<const Elem *>> & nodes_to_elem_map)
271 for (
auto & node : elem->node_ref_range())
273 libmesh_assert_less (node.id(), nodes_to_elem_map.size());
275 nodes_to_elem_map[node.id()].push_back(elem);
282 std::unordered_map<
dof_id_type, std::vector<dof_id_type>> & nodes_to_elem_map)
284 nodes_to_elem_map.clear();
287 for (
auto & node : elem->node_ref_range())
288 nodes_to_elem_map[node.id()].push_back(elem->id());
294 std::unordered_map<
dof_id_type, std::vector<const Elem *>> & nodes_to_elem_map)
296 nodes_to_elem_map.clear();
299 for (
auto & node : elem->node_ref_range())
300 nodes_to_elem_map[node.id()].push_back(elem);
305 #ifdef LIBMESH_ENABLE_DEPRECATED
307 std::vector<bool> & on_boundary)
309 libmesh_deprecated();
313 std::fill(on_boundary.begin(),
320 for (
auto s : elem->side_index_range())
321 if (elem->neighbor_ptr(s) ==
nullptr)
323 std::unique_ptr<const Elem> side = elem->build_side_ptr(s);
325 auto nodes_on_side = elem->nodes_on_side(s);
327 for (
auto & node_id : nodes_on_side)
328 on_boundary[node_id] =
true;
333 std::unordered_set<dof_id_type>
336 std::unordered_set<dof_id_type> boundary_nodes;
341 for (
auto s : elem->side_index_range())
342 if (elem->neighbor_ptr(s) ==
nullptr)
344 auto nodes_on_side = elem->nodes_on_side(s);
346 for (
auto & local_id : nodes_on_side)
347 boundary_nodes.insert(elem->node_ptr(local_id)->id());
350 return boundary_nodes;
353 std::unordered_set<dof_id_type>
356 std::unordered_set<dof_id_type> block_boundary_nodes;
361 for (
auto s : elem->side_index_range())
362 if (elem->neighbor_ptr(s) && (elem->neighbor_ptr(s)->subdomain_id() != elem->subdomain_id()))
364 auto nodes_on_side = elem->nodes_on_side(s);
366 for (
auto & local_id : nodes_on_side)
367 block_boundary_nodes.insert(elem->node_ptr(local_id)->id());
370 return block_boundary_nodes;
374 #ifdef LIBMESH_ENABLE_DEPRECATED
381 libmesh_deprecated();
408 return find_bbox.bbox();
435 return find_bbox.bbox();
445 const Real diag = (bbox.second - bbox.first).
norm();
446 const Point cent = (bbox.second + bbox.first)/2;
448 return Sphere (cent, .5*diag);
462 return find_bbox.bbox();
467 #ifdef LIBMESH_ENABLE_DEPRECATED
472 libmesh_deprecated();
499 return find_bbox.bbox();
511 const Real diag = (bbox.second - bbox.first).
norm();
512 const Point cent = (bbox.second + bbox.first)/2;
514 return Sphere (cent, .5*diag);
519 #ifdef LIBMESH_ENABLE_DEPRECATED
524 libmesh_deprecated();
550 return find_bbox.bbox();
562 const Real diag = (bbox.second - bbox.first).
norm();
563 const Point cent = (bbox.second + bbox.first)/2;
565 return Sphere (cent, .5*diag);
571 std::vector<ElemType> & et)
576 if (!std::count(et.begin(), et.end(), elem->type()))
577 et.push_back(elem->type());
600 const unsigned int level)
607 if ((elem->level() == level) && !elem->subactive())
619 nl = std::max(elem->level() + 1, nl);
635 nl = std::max(elem->level() + 1, nl);
649 nl = std::max(elem->level() + 1, nl);
664 nl = std::max(elem->level() + 1, nl);
673 libmesh_assert_equal_to(nl, paranoid_nl);
686 nl = std::max(elem->level() + 1, nl);
695 std::set<dof_id_type> & not_subactive_node_ids)
698 if (!elem->subactive())
699 for (
auto & n : elem->node_ref_range())
700 not_subactive_node_ids.insert(n.id());
725 unsigned int max_p_level = 0;
730 max_p_level = std::max(elem->p_level(), max_p_level);
735 max_p_level = std::max(elem->p_level(), max_p_level);
738 return max_p_level + 1;
745 const std::vector<std::vector<const Elem *>> & nodes_to_elem_map,
746 std::vector<const Node *> & neighbors)
754 std::set<const Node *> neighbor_set;
761 for (
const auto & elem : nodes_to_elem_map[global_id])
767 unsigned local_node_number = elem->local_node(global_id);
772 const unsigned short n_edges = elem->n_edges();
777 switch (elem->type())
781 switch (local_node_number)
785 neighbor_set.insert(elem->node_ptr(1));
790 neighbor_set.insert(elem->node_ptr(0));
794 libmesh_error_msg(
"Invalid local node number: " << local_node_number <<
" found." << std::endl);
801 switch (local_node_number)
806 neighbor_set.insert(elem->node_ptr(2));
811 neighbor_set.insert(elem->node_ptr(0));
812 neighbor_set.insert(elem->node_ptr(1));
816 libmesh_error_msg(
"Invalid local node number: " << local_node_number <<
" found." << std::endl);
823 switch (local_node_number)
827 neighbor_set.insert(elem->node_ptr(2));
832 neighbor_set.insert(elem->node_ptr(3));
837 neighbor_set.insert(elem->node_ptr(0));
838 neighbor_set.insert(elem->node_ptr(3));
843 neighbor_set.insert(elem->node_ptr(1));
844 neighbor_set.insert(elem->node_ptr(2));
848 libmesh_error_msg(
"Invalid local node number: " << local_node_number <<
" found." << std::endl);
859 unsigned current_edge = 0;
861 const unsigned short n_nodes = elem->n_nodes();
863 while (current_edge < n_edges)
866 bool found_edge =
false;
867 for (; current_edge<n_edges; ++current_edge)
868 if (elem->is_node_on_edge(local_node_number, current_edge))
877 const Node * node_to_save =
nullptr;
880 for (
unsigned other_node_this_edge = 0; other_node_this_edge !=
n_nodes; other_node_this_edge++)
881 if ( (elem->is_node_on_edge(other_node_this_edge, current_edge)) &&
882 (elem->node_id(other_node_this_edge) != global_id))
885 node_to_save = elem->node_ptr(other_node_this_edge);
892 neighbor_set.insert(node_to_save);
904 neighbors.assign(neighbor_set.begin(), neighbor_set.end());
911 const std::unordered_map<
dof_id_type, std::vector<const Elem *>> & nodes_to_elem_map,
912 std::vector<const Node *> & neighbors)
920 std::set<const Node *> neighbor_set;
923 const auto & elem_vec = libmesh_map_find(nodes_to_elem_map, global_id);
930 for (
const auto & elem : elem_vec)
936 unsigned local_node_number = elem->local_node(global_id);
941 const unsigned short n_edges = elem->n_edges();
946 switch (elem->type())
950 switch (local_node_number)
954 neighbor_set.insert(elem->node_ptr(1));
959 neighbor_set.insert(elem->node_ptr(0));
963 libmesh_error_msg(
"Invalid local node number: " << local_node_number <<
" found." << std::endl);
970 switch (local_node_number)
975 neighbor_set.insert(elem->node_ptr(2));
980 neighbor_set.insert(elem->node_ptr(0));
981 neighbor_set.insert(elem->node_ptr(1));
985 libmesh_error_msg(
"Invalid local node number: " << local_node_number <<
" found." << std::endl);
992 switch (local_node_number)
996 neighbor_set.insert(elem->node_ptr(2));
1001 neighbor_set.insert(elem->node_ptr(3));
1006 neighbor_set.insert(elem->node_ptr(0));
1007 neighbor_set.insert(elem->node_ptr(3));
1012 neighbor_set.insert(elem->node_ptr(1));
1013 neighbor_set.insert(elem->node_ptr(2));
1017 libmesh_error_msg(
"Invalid local node number: " << local_node_number <<
" found." << std::endl);
1028 unsigned current_edge = 0;
1030 const unsigned short n_nodes = elem->n_nodes();
1032 while (current_edge < n_edges)
1035 bool found_edge =
false;
1036 for (; current_edge<n_edges; ++current_edge)
1037 if (elem->is_node_on_edge(local_node_number, current_edge))
1046 const Node * node_to_save =
nullptr;
1049 for (
unsigned other_node_this_edge = 0; other_node_this_edge !=
n_nodes; other_node_this_edge++)
1050 if ( (elem->is_node_on_edge(other_node_this_edge, current_edge)) &&
1051 (elem->node_id(other_node_this_edge) != global_id))
1054 node_to_save = elem->node_ptr(other_node_this_edge);
1061 neighbor_set.insert(node_to_save);
1073 neighbors.assign(neighbor_set.begin(), neighbor_set.end());
1079 std::map<
dof_id_type, std::vector<dof_id_type>> & hanging_nodes)
1083 if (elem->type() ==
QUAD4)
1084 for (
auto s : elem->side_index_range())
1091 if (neigh !=
nullptr)
1094 if (neigh->
level() < elem->level())
1096 const Elem * ancestor = elem;
1098 ancestor = ancestor->
parent();
1100 libmesh_assert_less (s_neigh, neigh->
n_neighbors());
1103 unsigned int local_node1=0;
1104 unsigned int local_node2=0;
1106 bool found_in_neighbor =
false;
1109 while (!elem->is_node_on_side(local_node1++,s)) { }
1113 local_node2=local_node1+1;
1116 while (!elem->is_node_on_side(local_node2++,s)) { }
1129 for (
unsigned int n=0;n<neigh->
n_sides();n++)
1130 if (neigh->
node_id(n) == node1)
1131 found_in_neighbor=
true;
1135 if (!found_in_neighbor)
1148 local_node2=local_node1+1;
1155 if (hanging_nodes[hanging_node].size()<2)
1157 hanging_nodes[hanging_node].push_back(neigh->
node_id(local_node1));
1158 hanging_nodes[hanging_node].push_back(neigh->
node_id(local_node2));
1170 LOG_SCOPE(
"libmesh_assert_equal_n_systems()",
"MeshTools");
1177 n_sys = elem->n_systems();
1179 libmesh_assert_equal_to (elem->n_systems(), n_sys);
1185 n_sys = node->n_systems();
1187 libmesh_assert_equal_to (node->n_systems(), n_sys);
1193 #ifdef LIBMESH_ENABLE_AMR
1196 LOG_SCOPE(
"libmesh_assert_old_dof_objects()",
"MeshTools");
1204 if (elem->has_dofs())
1207 for (
auto & node : elem->node_ref_range())
1208 if (node.has_dofs())
1214 #endif // LIBMESH_ENABLE_AMR
1220 LOG_SCOPE(
"libmesh_assert_valid_node_pointers()",
"MeshTools");
1230 elem->libmesh_assert_valid_node_pointers();
1231 for (
auto n : elem->neighbor_ptr_range())
1233 n->libmesh_assert_valid_node_pointers();
1235 libmesh_assert_not_equal_to (elem->parent(),
remote_elem);
1236 elem = elem->parent();
1244 LOG_SCOPE(
"libmesh_assert_valid_remote_elems()",
"MeshTools");
1254 for (
auto n : elem->neighbor_ptr_range())
1257 #ifdef LIBMESH_ENABLE_AMR
1260 libmesh_assert_not_equal_to (parent,
remote_elem);
1264 if (elem->active() && elem->has_children())
1265 for (
auto & child : elem->child_ref_range())
1266 libmesh_assert_not_equal_to (&child,
remote_elem);
1273 const Elem * bad_elem)
1278 libmesh_assert_not_equal_to (elem->parent(), bad_elem);
1279 for (
auto n : elem->neighbor_ptr_range())
1280 libmesh_assert_not_equal_to (n, bad_elem);
1282 #ifdef LIBMESH_ENABLE_AMR
1283 if (elem->has_children())
1284 for (
auto & child : elem->child_ref_range())
1285 libmesh_assert_not_equal_to (&child, bad_elem);
1294 LOG_SCOPE(
"libmesh_assert_valid_elem_ids()",
"MeshTools");
1305 libmesh_assert_greater_equal (elemid, lastelemid);
1306 libmesh_assert_greater_equal (elemprocid, lastprocid);
1308 lastelemid = elemid;
1309 lastprocid = elemprocid;
1317 LOG_SCOPE(
"libmesh_assert_valid_amr_elem_ids()",
"MeshTools");
1327 libmesh_assert_greater_equal (elem->id(), parent->
id());
1328 libmesh_assert_greater_equal (elem->processor_id(), parent->
processor_id());
1337 LOG_SCOPE(
"libmesh_assert_valid_amr_interior_parents()",
"MeshTools");
1345 if (elem->dim() >= LIBMESH_DIM)
1357 if (ip->
level() == elem->level())
1358 libmesh_assert_equal_to (ip->
parent(),
1362 libmesh_assert_less (ip->
level(), elem->level());
1373 LOG_SCOPE(
"libmesh_assert_connected_nodes()",
"MeshTools");
1375 std::set<const Node *> used_nodes;
1381 for (
auto & n : elem->node_ref_range())
1382 used_nodes.insert(&n);
1394 namespace MeshTools {
1398 LOG_SCOPE(
"libmesh_assert_valid_boundary_ids()",
"MeshTools");
1403 libmesh_parallel_only(
mesh.
comm());
1413 const unsigned int my_n_nodes = elem ? elem->
n_nodes() : 0;
1414 const unsigned int my_n_edges = elem ? elem->
n_edges() : 0;
1415 const unsigned int my_n_sides = elem ? elem->
n_sides() : 0;
1418 n_edges = my_n_edges,
1419 n_sides = my_n_sides;
1427 libmesh_assert_equal_to(my_n_nodes,
n_nodes);
1428 libmesh_assert_equal_to(my_n_edges, n_edges);
1429 libmesh_assert_equal_to(my_n_sides, n_sides);
1435 std::vector<boundary_id_type> all_bcids;
1437 for (
unsigned int n=0; n !=
n_nodes; ++n)
1439 std::vector<boundary_id_type> bcids;
1442 boundary_info.boundary_ids(elem->
node_ptr(n), bcids);
1445 std::sort(bcids.begin(), bcids.end());
1449 all_bcids.insert(all_bcids.end(), bcids.begin(),
1455 for (
unsigned short e=0; e != n_edges; ++e)
1457 std::vector<boundary_id_type> bcids;
1461 boundary_info.edge_boundary_ids(elem, e, bcids);
1464 std::sort(bcids.begin(), bcids.end());
1469 all_bcids.insert(all_bcids.end(), bcids.begin(),
1476 boundary_info.raw_edge_boundary_ids(elem, e, bcids);
1479 std::sort(bcids.begin(), bcids.end());
1481 all_bcids.insert(all_bcids.end(), bcids.begin(),
1490 for (
unsigned short s=0; s != n_sides; ++s)
1492 std::vector<boundary_id_type> bcids;
1496 boundary_info.boundary_ids(elem, s, bcids);
1499 std::sort(bcids.begin(), bcids.end());
1501 all_bcids.insert(all_bcids.end(), bcids.begin(),
1511 boundary_info.raw_boundary_ids(elem, s, bcids);
1514 std::sort(bcids.begin(), bcids.end());
1516 all_bcids.insert(all_bcids.end(), bcids.begin(),
1525 for (
unsigned short sf=0; sf != 2; ++sf)
1527 std::vector<boundary_id_type> bcids;
1531 boundary_info.shellface_boundary_ids(elem, sf, bcids);
1534 std::sort(bcids.begin(), bcids.end());
1536 all_bcids.insert(all_bcids.end(), bcids.begin(),
1546 boundary_info.raw_shellface_boundary_ids(elem, sf, bcids);
1549 std::sort(bcids.begin(), bcids.end());
1551 all_bcids.insert(all_bcids.end(), bcids.begin(),
1561 (elem ? &all_bcids :
nullptr));
1568 LOG_SCOPE(
"libmesh_assert_valid_dof_ids()",
"MeshTools");
1573 libmesh_parallel_only(
mesh.
comm());
1579 assert_semiverify_dofobj(
mesh.
comm(),
1587 assert_semiverify_dofobj(
mesh.
comm(),
1595 LOG_SCOPE(
"libmesh_assert_contiguous_dof_ids()",
"MeshTools");
1600 libmesh_parallel_only(
mesh.
comm());
1602 dof_id_type min_dof_id = std::numeric_limits<dof_id_type>::max(),
1603 max_dof_id = std::numeric_limits<dof_id_type>::min();
1612 min_dof_id = std::min (min_dof_id,
id);
1613 max_dof_id = std::max (max_dof_id,
id);
1633 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1636 LOG_SCOPE(
"libmesh_assert_valid_unique_ids()",
"MeshTools");
1638 libmesh_parallel_only(
mesh.
comm());
1666 libmesh_parallel_only(
mesh.
comm());
1669 mesh.
comm().max(parallel_max_elem_id);
1671 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
1681 mesh.
comm().max(parallel_max_node_id);
1683 for (
dof_id_type i=0; i != parallel_max_node_id; ++i)
1696 libmesh_parallel_only(
mesh.
comm());
1700 mesh.
comm().max(parallel_max_elem_id);
1702 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
1706 const unsigned int my_n_nodes = elem ? elem->
n_nodes() : 0;
1707 unsigned int n_nodes = my_n_nodes;
1713 for (
unsigned int n=0; n !=
n_nodes; ++n)
1715 const Node * node = elem ? elem->
node_ptr(n) :
nullptr;
1728 LOG_SCOPE(
"libmesh_assert_topology_consistent_procids()",
"MeshTools");
1735 #ifdef LIBMESH_ENABLE_AMR
1743 if (!elem->active() && !elem->subactive())
1752 bool matching_child_id =
false;
1760 matching_child_id =
true;
1772 LOG_SCOPE(
"libmesh_assert_parallel_consistent_procids()",
"MeshTools");
1777 libmesh_parallel_only(
mesh.
comm());
1785 parallel_max_elem_id = std::max<dof_id_type>(parallel_max_elem_id,
1787 mesh.
comm().max(parallel_max_elem_id);
1791 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
1797 std::numeric_limits<processor_id_type>::max();
1802 std::numeric_limits<processor_id_type>::min();
1807 libmesh_assert_equal_to (min_id, elem->
processor_id());
1808 libmesh_assert_equal_to (max_id, elem->
processor_id());
1821 LOG_SCOPE(
"libmesh_assert_topology_consistent_procids()",
"MeshTools");
1826 libmesh_parallel_only(
mesh.
comm());
1838 parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
1840 mesh.
comm().max(parallel_max_node_id);
1843 std::vector<bool> node_touched_by_me(parallel_max_node_id,
false);
1850 for (
auto & node : elem->node_ref_range())
1853 node_touched_by_me[nodeid] =
true;
1856 std::vector<bool> node_touched_by_anyone(node_touched_by_me);
1857 mesh.
comm().max(node_touched_by_anyone);
1864 node_touched_by_me[nodeid]);
1872 LOG_SCOPE(
"libmesh_assert_parallel_consistent_new_node_procids()",
"MeshTools");
1877 libmesh_parallel_only(
mesh.
comm());
1883 mesh.
comm().max(parallel_max_elem_id);
1885 std::vector<bool> elem_touched_by_anyone(parallel_max_elem_id,
false);
1887 for (
dof_id_type i=0; i != parallel_max_elem_id; ++i)
1891 const unsigned int my_n_nodes = elem ? elem->
n_nodes() : 0;
1892 unsigned int n_nodes = my_n_nodes;
1898 for (
unsigned int n=0; n !=
n_nodes; ++n)
1900 const Node * node = elem ? elem->
node_ptr(n) :
nullptr;
1910 LOG_SCOPE(
"libmesh_assert_parallel_consistent_procids()",
"MeshTools");
1915 libmesh_parallel_only(
mesh.
comm());
1927 parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
1929 mesh.
comm().max(parallel_max_node_id);
1931 std::vector<bool> node_touched_by_anyone(parallel_max_node_id,
false);
1938 for (
auto & node : elem->node_ref_range())
1941 node_touched_by_anyone[nodeid] =
true;
1944 mesh.
comm().max(node_touched_by_anyone);
1948 for (
dof_id_type i=0; i != parallel_max_node_id; ++i)
1950 if (!node_touched_by_anyone[i])
1964 for (
auto & node : elem->node_ref_range())
1965 libmesh_assert_equal_to
1966 (node.processor_id(),
1967 node.choose_processor_id(node.processor_id(),
1968 elem->processor_id()));
1977 #ifdef LIBMESH_ENABLE_AMR
1980 LOG_SCOPE(
"libmesh_assert_valid_refinement_flags()",
"MeshTools");
1982 libmesh_parallel_only(
mesh.
comm());
1989 std::vector<unsigned char> my_elem_h_state(pmax_elem_id, 255);
1990 std::vector<unsigned char> my_elem_p_state(pmax_elem_id, 255);
1997 my_elem_h_state[elemid] =
1998 static_cast<unsigned char>(elem->refinement_flag());
2000 my_elem_p_state[elemid] =
2001 static_cast<unsigned char>(elem->p_refinement_flag());
2003 std::vector<unsigned char> min_elem_h_state(my_elem_h_state);
2006 std::vector<unsigned char> min_elem_p_state(my_elem_p_state);
2012 my_elem_h_state[i] == min_elem_h_state[i]);
2014 my_elem_p_state[i] == min_elem_p_state[i]);
2021 #endif // LIBMESH_ENABLE_AMR
2025 #ifdef LIBMESH_ENABLE_AMR
2028 LOG_SCOPE(
"libmesh_assert_valid_refinement_tree()",
"MeshTools");
2033 if (elem->has_children())
2034 for (
auto & child : elem->child_ref_range())
2036 libmesh_assert_equal_to (child.parent(), elem);
2042 else if (elem->ancestor())
2050 libmesh_assert_greater(elem->p_level(), 0);
2057 #endif // LIBMESH_ENABLE_AMR
2062 bool assert_valid_remote_elems)
2064 LOG_SCOPE(
"libmesh_assert_valid_neighbors()",
"MeshTools");
2069 elem->libmesh_assert_valid_neighbors();
2075 libmesh_parallel_only(
mesh.
comm());
2084 const unsigned int my_n_neigh = elem ? elem->
n_neighbors() : 0;
2085 unsigned int n_neigh = my_n_neigh;
2088 libmesh_assert_equal_to (my_n_neigh, n_neigh);
2090 for (
unsigned int n = 0; n != n_neigh; ++n)
2099 p_my_neighbor = &my_neighbor;
2106 if (!assert_valid_remote_elems &&
2109 p_my_neighbor =
nullptr;
2125 typedef std::unordered_map<dof_id_type, processor_id_type> proc_id_map_type;
2129 typedef unsigned char datum;
2131 SyncNodeSet(std::unordered_set<const Node *> & _set,
2140 void gather_data (
const std::vector<dof_id_type> & ids,
2141 std::vector<datum> &
data)
2144 data.resize(ids.size());
2159 bool act_on_data (
const std::vector<dof_id_type> & ids,
2160 const std::vector<datum> in_set)
2162 bool data_changed =
false;
2173 data_changed =
true;
2178 return data_changed;
2183 struct NodesNotInSet
2185 NodesNotInSet(
const std::unordered_set<const Node *> _set)
2188 bool operator() (
const Node * node)
const
2195 const std::unordered_set<const Node *>
node_set;
2199 struct SyncProcIdsFromMap
2203 SyncProcIdsFromMap(
const proc_id_map_type & _map,
2212 void gather_data (
const std::vector<dof_id_type> & ids,
2213 std::vector<datum> &
data)
2216 data.resize(ids.size());
2221 const proc_id_map_type::const_iterator it =
new_proc_ids.find(
id);
2226 data[i] = it->second;
2231 data[i] = node.processor_id();
2237 void act_on_data (
const std::vector<dof_id_type> & ids,
2238 const std::vector<datum> proc_ids)
2254 LOG_SCOPE(
"correct_node_proc_ids()",
"MeshTools");
2257 libmesh_parallel_only(
mesh.
comm());
2287 std::unordered_set<const Node *> valid_nodes;
2294 if (!repartition_all_nodes)
2297 for (
const auto & node : elem->node_ref_range())
2298 if (elem->processor_id() == node.processor_id())
2299 valid_nodes.insert(&node);
2301 SyncNodeSet syncv(valid_nodes,
mesh);
2314 for (
auto & node : elem->node_ref_range())
2317 const proc_id_map_type::iterator it =
new_proc_ids.find(
id);
2321 it->second = node.choose_processor_id(it->second, pid);
2326 std::map<processor_id_type, std::vector<std::pair<dof_id_type, processor_id_type>>>
2332 const proc_id_map_type::iterator it =
new_proc_ids.find(
id);
2336 if (node->processor_id() != DofObject::invalid_processor_id)
2337 ids_to_push[node->processor_id()].push_back(std::make_pair(
id, pid));
2340 auto action_functor =
2343 const std::vector<std::pair<dof_id_type, processor_id_type>> &
data)
2345 for (
auto & p :
data)
2349 const proc_id_map_type::iterator it =
new_proc_ids.find(
id);
2360 Parallel::push_parallel_vector_data
2361 (
mesh.
comm(), ids_to_push, action_functor);
2367 std::unordered_set<Node *> ex_local_nodes;
2370 const proc_id_map_type::iterator it =
new_proc_ids.find(node->id());
2372 ex_local_nodes.insert(node);
2376 if (repartition_all_nodes)
2381 NodesNotInSet nnis(valid_nodes);
2388 for (
const auto & node : ex_local_nodes)
2390 if (valid_nodes.count(node))
2394 const proc_id_map_type::iterator it =
new_proc_ids.find(
id);
2396 node->processor_id() = it->second;
2403 MeshTools::libmesh_assert_valid_procids<Node>(
mesh);