21 #include "libmesh/distributed_mesh.h"
24 #include "libmesh/boundary_info.h"
25 #include "libmesh/elem.h"
26 #include "libmesh/libmesh_logging.h"
27 #include "libmesh/mesh_communication.h"
28 #include "libmesh/parmetis_partitioner.h"
43 _is_serial_on_proc_0(true),
44 _n_nodes(0), _n_elem(0), _max_node_id(0), _max_elem_id(0),
45 _next_free_local_node_id(this->processor_id()),
46 _next_free_local_elem_id(this->processor_id()),
47 _next_free_unpartitioned_node_id(this->n_processors()),
48 _next_free_unpartitioned_elem_id(this->n_processors())
49 #ifdef LIBMESH_ENABLE_UNIQUE_ID
50 , _next_unpartitioned_unique_id(this->n_processors())
53 #ifdef LIBMESH_ENABLE_UNIQUE_ID
58 _partitioner = libmesh_make_unique<ParmetisPartitioner>();
74 _is_serial_on_proc_0(other_mesh._is_serial_on_proc_0),
75 _n_nodes(0), _n_elem(0), _max_node_id(0), _max_elem_id(0),
76 _next_free_local_node_id(this->processor_id()),
77 _next_free_local_elem_id(this->processor_id()),
78 _next_free_unpartitioned_node_id(this->n_processors()),
79 _next_free_unpartitioned_elem_id(this->n_processors())
94 #ifdef LIBMESH_ENABLE_UNIQUE_ID
104 this_boundary_info = other_boundary_info;
109 std::vector<boundary_id_type> side_boundaries;
110 other_boundary_info.build_side_boundary_ids(side_boundaries);
113 for (
const auto & side_bnd_id : side_boundaries)
114 this_boundary_info.sideset_name(side_bnd_id) =
115 other_boundary_info.get_sideset_name(side_bnd_id);
118 std::vector<boundary_id_type> node_boundaries;
119 other_boundary_info.build_node_boundary_ids(node_boundaries);
121 for (
const auto & node_bnd_id : node_boundaries)
122 this_boundary_info.nodeset_name(node_bnd_id) =
123 other_boundary_info.get_nodeset_name(node_bnd_id);
134 _is_serial_on_proc_0(other_mesh.is_serial()),
135 _n_nodes(0), _n_elem(0), _max_node_id(0), _max_elem_id(0),
136 _next_free_local_node_id(this->processor_id()),
137 _next_free_local_elem_id(this->processor_id()),
138 _next_free_unpartitioned_node_id(this->n_processors()),
139 _next_free_unpartitioned_elem_id(this->n_processors())
146 this_boundary_info = other_boundary_info;
151 std::vector<boundary_id_type> side_boundaries;
152 other_boundary_info.build_side_boundary_ids(side_boundaries);
155 for (
const auto & side_bnd_id : side_boundaries)
156 this_boundary_info.sideset_name(side_bnd_id) =
157 other_boundary_info.get_sideset_name(side_bnd_id);
160 std::vector<boundary_id_type> node_boundaries;
161 other_boundary_info.build_node_boundary_ids(node_boundaries);
163 for (
const auto & node_bnd_id : node_boundaries)
164 this_boundary_info.nodeset_name(node_bnd_id) =
165 other_boundary_info.get_nodeset_name(node_bnd_id);
167 #ifdef LIBMESH_ENABLE_UNIQUE_ID
181 parallel_object_only();
206 #ifdef LIBMESH_ENABLE_UNIQUE_ID
223 parallel_object_only();
226 this->
comm().sum(n_local);
236 parallel_object_only();
249 for (; rit != rend; ++rit)
252 libmesh_assert_equal_to(rit->second->id(), rit->first);
253 max_local = rit->first + 1;
257 this->
comm().max(max_local);
263 #ifdef LIBMESH_ENABLE_UNIQUE_ID
267 parallel_object_only();
271 this->
comm().max(max_local);
281 parallel_object_only();
284 this->
comm().sum(n_local);
294 parallel_object_only();
307 for (; rit != rend; ++rit)
310 libmesh_assert_equal_to(rit->second->id(), rit->first);
311 max_local = rit->first + 1;
315 this->
comm().max(max_local);
331 libmesh_assert_equal_to (
_nodes[i]->
id(), i);
342 libmesh_assert_equal_to (
_nodes[i]->
id(), i);
352 std::map<dof_id_type, Node *>::const_iterator it =
_nodes.find(i);
353 if (it !=
_nodes.end().it)
355 const Node * n = it->second;
368 std::map<dof_id_type, Node *>::const_iterator it =
_nodes.find(i);
369 if (it !=
_nodes.end().it)
371 Node * n = it->second;
385 libmesh_assert_equal_to (
_elements[i]->
id(), i);
396 libmesh_assert_equal_to (
_elements[i]->
id(), i);
406 std::map<dof_id_type, Elem *>::const_iterator it =
_elements.find(i);
409 const Elem * e = it->second;
422 std::map<dof_id_type, Elem *>::const_iterator it =
_elements.find(i);
468 static_cast<dof_id_type>(e->
id()+1));
498 #ifdef LIBMESH_ENABLE_UNIQUE_ID
545 #ifdef LIBMESH_ENABLE_UNIQUE_ID
615 libmesh_assert_equal_to (el->
id(), old_id);
629 auto n_it =
_nodes.find(
id);
630 if (n_it !=
_nodes.end().it)
632 Node * n = n_it->second;
634 libmesh_assert_equal_to (n->
id(), id);
637 n->processor_id() = proc_id;
695 static_cast<dof_id_type>(n->
id()+1));
725 #ifdef LIBMESH_ENABLE_UNIQUE_ID
802 libmesh_assert_equal_to (nd->
id(), old_id);
814 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
911 template <
typename T>
915 parallel_object_only();
919 const dof_id_type pmax_id = std::max(pmax_node_id, pmax_elem_id);
923 T * obj = objects[i];
936 const dof_id_type procid = obj && obj->valid_processor_id() ?
941 this->
comm().min(min_procid);
958 #if defined(LIBMESH_ENABLE_UNIQUE_ID) && !defined(NDEBUG)
980 parallel_object_only();
1001 #if defined(LIBMESH_ENABLE_AMR) && !defined(NDEBUG)
1003 parallel_object_only();
1011 unsigned int refinement_flag = el ?
1013 unsigned int p_refinement_flag = el ?
1022 #endif // LIBMESH_ENABLE_AMR
1027 template <
typename T>
1032 parallel_object_only();
1040 std::unordered_map<processor_id_type, dof_id_type>
1041 ghost_objects_from_proc;
1043 object_iterator it = objects.
begin();
1044 object_iterator
end = objects.
end();
1052 it = objects.
erase(it);
1057 unpartitioned_objects++;
1059 ghost_objects_from_proc[obj_procid]++;
1066 std::vector<dof_id_type> objects_on_proc(this->
n_processors(), 0);
1067 auto this_it = ghost_objects_from_proc.find(this->
processor_id());
1068 this->
comm().allgather
1069 ((this_it == ghost_objects_from_proc.end()) ?
1070 dof_id_type(0) : this_it->second, objects_on_proc);
1075 if (ghost_objects_from_proc.count(p))
1076 libmesh_assert_less_equal (ghost_objects_from_proc[p], objects_on_proc[p]);
1078 libmesh_assert_less_equal (0, objects_on_proc[p]);
1082 std::vector<dof_id_type> first_object_on_proc(this->
n_processors());
1084 first_object_on_proc[i] = first_object_on_proc[i-1] +
1085 objects_on_proc[i-1];
1090 unpartitioned_objects;
1096 std::map<processor_id_type, std::vector<dof_id_type>>
1101 auto ghost_end = ghost_objects_from_proc.end();
1105 const auto p_it = ghost_objects_from_proc.find(p);
1106 if (p_it != ghost_end)
1107 requested_ids[p].reserve(p_it->second);
1111 for (it = objects.
begin(); it !=
end; ++it)
1115 obj->set_id(next_id++);
1117 requested_ids[obj->processor_id()].push_back(obj->id());
1122 auto gather_functor =
1126 &first_object_on_proc,
1131 std::vector<dof_id_type> & new_ids)
1133 std::size_t ids_size = ids.size();
1134 new_ids.resize(ids_size);
1136 for (std::size_t i=0; i != ids_size; ++i)
1138 T * obj = objects[ids[i]];
1140 libmesh_assert_equal_to (obj->processor_id(), this->
processor_id());
1141 new_ids[i] = obj->id();
1143 libmesh_assert_greater_equal (new_ids[i],
1145 libmesh_assert_less (new_ids[i],
1151 auto action_functor =
1154 &first_object_on_proc,
1159 const std::vector<dof_id_type> & ids,
1160 const std::vector<dof_id_type> &
data)
1165 T * obj = objects[ids[i]];
1167 libmesh_assert_equal_to (obj->processor_id(), pid);
1168 libmesh_assert_greater_equal (
data[i],
1169 first_object_on_proc[pid]);
1170 libmesh_assert_less (
data[i],
1171 first_object_on_proc[pid] +
1172 objects_on_proc[pid]);
1173 obj->set_id(
data[i]);
1178 Parallel::pull_parallel_vector_data
1179 (this->
comm(), requested_ids, gather_functor, action_functor, ex);
1181 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1182 auto unique_gather_functor =
1189 std::vector<unique_id_type> &
data)
1191 std::size_t ids_size = ids.size();
1192 data.resize(ids_size);
1194 for (std::size_t i=0; i != ids_size; ++i)
1196 T * obj = objects[ids[i]];
1198 libmesh_assert_equal_to (obj->processor_id(), this->
processor_id());
1203 auto unique_action_functor =
1206 const std::vector<dof_id_type> & ids,
1207 const std::vector<unique_id_type> &
data)
1211 T * obj = objects[ids[i]];
1213 libmesh_assert_equal_to (obj->processor_id(), pid);
1215 obj->set_unique_id() = (
data[i]);
1220 Parallel::pull_parallel_vector_data
1221 (this->
comm(), requested_ids, unique_gather_functor,
1222 unique_action_functor, unique_ex);
1228 next_id += objects_on_proc[i];
1229 for (it = objects.
begin(); it !=
end; ++it)
1233 obj->set_id(next_id++);
1238 it = objects.
begin();
1245 T *
next = objects[obj->id()];
1259 libmesh_assert_not_equal_to (
next->id(), obj->id());
1260 objects[obj->id()] = obj;
1262 next = objects[obj->id()];
1264 objects[obj->id()] = obj;
1270 it = objects.
erase(it);
1275 return first_free_id;
1281 parallel_object_only();
1290 LOG_SCOPE(
"renumber_nodes_and_elements()",
"DistributedMesh");
1292 std::set<dof_id_type> used_nodes;
1297 used_nodes.insert(
node.
id());
1310 else if (!used_nodes.count(nd->
id()))
1349 libmesh_assert_equal_to (this->
max_node_id(), pmax_node_id);
1350 libmesh_assert_equal_to (this->
max_elem_id(), pmax_elem_id);
1373 for (
auto & pr : nodes)
1374 if (pr.second !=
nullptr)
1375 pr.second->set_id() = pr.first;
1378 for (
const auto & pr : elems)
1379 if (pr.second !=
nullptr)
1380 pr.second->set_id() = pr.first;
1387 parallel_object_only();
1393 this->
comm().sum(active_elements);
1401 return active_elements;
1423 libmesh_assert_equal_to (this->
max_node_id(), pmax_node_id);
1424 libmesh_assert_equal_to (this->
max_elem_id(), pmax_elem_id);
1438 while (e_it != e_end)
1446 while (n_it != n_end)
1448 n_it =
_nodes.erase(n_it);
1488 std::set<Elem *> tmp;
1491 std::inserter(tmp, tmp.begin()));
1510 libmesh_assert_equal_to (this->
max_node_id(), pmax_node_id);
1511 libmesh_assert_equal_to (this->
max_elem_id(), pmax_elem_id);