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)
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)
242void 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);
523std::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;
543std::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());
738 return static_cast<dof_id_type>(std::distance(
mesh.type_elements_begin(type),
739 mesh.type_elements_end (type)));
747 return static_cast<dof_id_type>(std::distance(
mesh.active_type_elements_begin(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());
1007 return cast_int<dof_id_type>(std::distance(begin, end));
1015 return cast_int<dof_id_type>(std::distance(begin, end));
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())
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);
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;
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;
1856 std::sort(bcids.begin(), bcids.end());
1861 all_bcids.insert(all_bcids.end(), bcids.begin(),
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;
1891 std::sort(bcids.begin(), bcids.end());
1893 all_bcids.insert(all_bcids.end(), bcids.begin(),
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;
1926 std::sort(bcids.begin(), bcids.end());
1928 all_bcids.insert(all_bcids.end(), bcids.begin(),
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]);
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;
2381typedef 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;
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;
2455struct 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)
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);
void max(const T &r, T &o, Request &req) const
timpi_pure bool semiverify(const T *r) const
void min(const T &r, T &o, Request &req) const
timpi_pure bool verify(const T &r) const
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
void shellface_boundary_ids(const Elem *const elem, const unsigned short int shellface, std::vector< boundary_id_type > &vec_to_fill) const
void raw_shellface_boundary_ids(const Elem *const elem, const unsigned short int shellface, std::vector< boundary_id_type > &vec_to_fill) const
void edge_boundary_ids(const Elem *const elem, const unsigned short int edge, std::vector< boundary_id_type > &vec_to_fill) const
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
void raw_boundary_ids(const Elem *const elem, const unsigned short int side, std::vector< boundary_id_type > &vec_to_fill) const
void raw_edge_boundary_ids(const Elem *const elem, const unsigned short int edge, std::vector< boundary_id_type > &vec_to_fill) const
static const boundary_id_type invalid_id
Number used for internal use.
Defines a Cartesian bounding box by the two corner extremum.
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
unsigned int n_systems() const
unsigned int n_comp(const unsigned int s, const unsigned int var) const
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
processor_id_type processor_id() const
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
unique_id_type unique_id() const
static constexpr processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
unsigned int n_vars(const unsigned int s, const unsigned int vg) const
This is the base class from which all geometric element types are derived.
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
bool has_children() const
virtual unsigned int n_nodes() const =0
const Elem * parent() const
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
unsigned int n_neighbors() const
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
unsigned int level() const
ElemMappingType mapping_type() const
const Node * node_ptr(const unsigned int i) const
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...
virtual ElemType type() const =0
IntRange< unsigned short > node_index_range() const
const Elem * interior_parent() const
virtual unsigned int n_edges() const =0
virtual unsigned int n_sides() const =0
dof_id_type node_id(const unsigned int i) const
const Elem * neighbor_ptr(unsigned int i) const
const Elem * top_parent() const
This is the MeshBase class.
virtual const Node & node_ref(const dof_id_type i) const
virtual bool is_serial() const
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
virtual const Node * node_ptr(const dof_id_type i) const =0
unsigned int mesh_dimension() const
virtual dof_id_type n_elem() const =0
virtual void delete_node(Node *n)=0
Removes the Node n from the mesh.
const ConstElemRange & active_local_element_stored_range() const
virtual std::unique_ptr< MeshBase > clone() const =0
Virtual "copy constructor".
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.
virtual dof_id_type max_node_id() const =0
virtual const Node * query_node_ptr(const dof_id_type i) const =0
virtual const Elem * elem_ptr(const dof_id_type i) const =0
virtual dof_id_type max_elem_id() const =0
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
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...
std::unique_ptr< PointLocatorBase > sub_point_locator() const
virtual bool is_serial_on_zero() const
void skip_noncritical_partitioning(bool skip)
If true is passed in then the elements on this mesh will no longer be (re)partitioned,...
This is the MeshCommunication class.
void assign_global_indices(MeshBase &) const
This method assigns globally unique, partition-agnostic indices to the nodes and elements in the mesh...
A Node is like a Point, but with more information.
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...
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
This class defines a sphere.
The StoredRange class defines a contiguous, divisible set of objects.
Dummy "splitting object" used to distinguish splitting constructors from copy constructors.
DIE A HORRIBLE DEATH HERE typedef MPI_Comm communicator
void push_parallel_vector_data(const Communicator &comm, MapToVectors &&data, const ActionFunctor &act_on_data)
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 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)
The libMesh namespace provides an interface to certain functionality in the library.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
ElemType
Defines an enum for geometric element types.
void libmesh_ignore(const Args &...)
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
const RemoteElem * remote_elem
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
uint8_t processor_id_type
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 definition of the const_element_iterator struct.
The definition of the const_node_iterator struct.
const dof_id_type n_nodes