21 #include "libmesh/boundary_info.h"
22 #include "libmesh/distributed_mesh.h"
23 #include "libmesh/elem.h"
24 #include "libmesh/ghosting_functor.h"
25 #include "libmesh/libmesh_config.h"
26 #include "libmesh/libmesh_common.h"
27 #include "libmesh/libmesh_logging.h"
28 #include "libmesh/mesh_base.h"
29 #include "libmesh/mesh_communication.h"
30 #include "libmesh/mesh_inserter_iterator.h"
31 #include "libmesh/mesh_tools.h"
32 #include "libmesh/parallel.h"
33 #include "libmesh/parallel_elem.h"
34 #include "libmesh/parallel_node.h"
35 #include "libmesh/parallel_ghost_sync.h"
36 #include "libmesh/utility.h"
37 #include "libmesh/remote_elem.h"
38 #include "libmesh/int_range.h"
43 #include <unordered_set>
44 #include <unordered_map>
56 typedef std::vector<dof_id_type> datum;
64 void gather_data (
const std::vector<dof_id_type> & ids,
65 std::vector<datum> & neighbors)
const
67 neighbors.resize(ids.size());
77 neighbors[i].resize(n_neigh);
78 for (
unsigned int n = 0; n != n_neigh; ++n)
84 neighbors[i][n] = neigh->
id();
92 void act_on_data (
const std::vector<dof_id_type> & ids,
93 const std::vector<datum> & neighbors)
const
99 const datum & new_neigh = neighbors[i];
102 libmesh_assert_equal_to (n_neigh, new_neigh.size());
104 for (
unsigned int n = 0; n != n_neigh; ++n)
110 libmesh_assert_equal_to(old_neigh->
id(), new_neigh_id);
142 std::set<const Elem *, CompareElemIdsByLevel> & connected_elements)
150 (*gf)(elem_it, elem_end, pid, elements_to_ghost);
154 for (
auto & pr : elements_to_ghost)
156 const Elem * elem = pr.first;
158 connected_elements.insert(elem);
164 for (; elem_it != elem_end; ++elem_it)
165 connected_elements.insert(*elem_it);
172 std::set<const Elem *, CompareElemIdsByLevel> & connected_elements)
177 #ifdef LIBMESH_ENABLE_AMR
181 for (
const auto & elem :
as_range(elem_it, elem_end))
186 connected_elements.insert(&child);
188 #endif // LIBMESH_ENABLE_AMR
197 #ifdef LIBMESH_ENABLE_AMR
214 std::set<const Elem *, CompareElemIdsByLevel>::reverse_iterator
215 elem_rit = connected_elements.rbegin();
217 for (; elem_rit != connected_elements.rend(); ++elem_rit)
219 const Elem * elem = *elem_rit;
227 connected_elements.insert (parent);
231 std::vector<const Elem *> subactive_family;
233 for (
const auto & f : subactive_family)
236 connected_elements.insert(f);
246 for (
const auto & elem : connected_elements)
255 #endif // LIBMESH_ENABLE_AMR
259 void reconnect_nodes (
const std::set<const Elem *, CompareElemIdsByLevel> & connected_elements,
260 std::set<const Node *> & connected_nodes)
264 connected_nodes.clear();
266 for (
const auto & elem : connected_elements)
268 connected_nodes.insert(&n);
283 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings
294 bool newly_coarsened_only)
const
323 LOG_SCOPE(
"redistribute()",
"MeshCommunication");
328 nodestag =
mesh.
comm().get_unique_tag(3141),
329 elemstag =
mesh.
comm().get_unique_tag(3142);
338 std::vector<dof_id_type> send_n_nodes_and_elem_per_proc(2*
mesh.
n_processors(), 0);
340 std::vector<Parallel::Request>
341 node_send_requests, element_send_requests;
345 std::unordered_map<processor_id_type, std::vector<Elem *>> send_to_pid;
348 #ifdef LIBMESH_ENABLE_AMR
349 newly_coarsened_only ?
355 #ifdef LIBMESH_ENABLE_AMR
356 newly_coarsened_only ?
361 for (
auto & elem :
as_range(send_elems_begin, send_elems_end))
367 for (
auto pair : send_to_pid)
380 const auto & p_elements = pair.second;
383 Elem *
const * elempp = p_elements.data();
384 Elem *
const * elemend = elempp + p_elements.size();
386 #ifndef LIBMESH_ENABLE_AMR
400 std::set<const Elem *, CompareElemIdsByLevel> elements_to_send;
416 std::set<const Node *> connected_nodes;
420 send_n_nodes_and_elem_per_proc[2*pid+0] =
421 cast_int<dof_id_type>(connected_nodes.size());
425 node_send_requests.push_back(Parallel::request());
428 connected_nodes.begin(),
429 connected_nodes.end(),
430 node_send_requests.back(),
434 send_n_nodes_and_elem_per_proc[2*pid+1] =
435 cast_int<dof_id_type>(elements_to_send.size());
439 element_send_requests.push_back(Parallel::request());
442 elements_to_send.begin(),
443 elements_to_send.end(),
444 element_send_requests.back(),
448 std::vector<dof_id_type> recv_n_nodes_and_elem_per_proc(send_n_nodes_and_elem_per_proc);
450 mesh.
comm().alltoall (recv_n_nodes_and_elem_per_proc);
460 n_send_node_pairs=0, n_send_elem_pairs=0,
461 n_recv_node_pairs=0, n_recv_elem_pairs=0;
465 if (send_n_nodes_and_elem_per_proc[2*pid+0])
467 send_node_pair[pid] =
true;
471 if (send_n_nodes_and_elem_per_proc[2*pid+1])
473 send_elem_pair[pid] =
true;
477 if (recv_n_nodes_and_elem_per_proc[2*pid+0])
479 recv_node_pair[pid] =
true;
483 if (recv_n_nodes_and_elem_per_proc[2*pid+1])
485 recv_elem_pair[pid] =
true;
489 libmesh_assert_equal_to (n_send_node_pairs, node_send_requests.size());
490 libmesh_assert_equal_to (n_send_elem_pairs, element_send_requests.size());
494 for (
unsigned int node_comm_step=0; node_comm_step<n_recv_node_pairs; node_comm_step++)
497 mesh.
comm().receive_packed_range (Parallel::any_source,
506 for (
unsigned int elem_comm_step=0; elem_comm_step<n_recv_elem_pairs; elem_comm_step++)
507 mesh.
comm().receive_packed_range (Parallel::any_source,
514 Parallel::wait (node_send_requests);
515 Parallel::wait (element_send_requests);
534 #endif // LIBMESH_HAVE_MPI
538 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings
557 LOG_SCOPE(
"gather_neighboring_elements()",
"MeshCommunication");
592 element_neighbors_tag =
mesh.
comm().get_unique_tag();
603 std::vector<processor_id_type> adjacent_processors;
606 adjacent_processors.push_back (pid);
610 cast_int<processor_id_type>(adjacent_processors.size());
616 std::vector<dof_id_type> my_interface_node_list;
617 std::vector<const Elem *> my_interface_elements;
619 std::set<dof_id_type> my_interface_node_set;
622 std::unique_ptr<const Elem> side;
631 my_interface_elements.push_back(elem);
639 my_interface_node_set.insert (side->node_id(n));
644 my_interface_node_list.reserve (my_interface_node_set.size());
645 my_interface_node_list.insert (my_interface_node_list.end(),
646 my_interface_node_set.begin(),
647 my_interface_node_set.end());
657 std::vector<std::vector<dof_id_type>>
658 my_interface_node_xfer_buffers (n_adjacent_processors, my_interface_node_list);
659 std::map<processor_id_type, unsigned char> n_comm_steps;
661 std::vector<Parallel::Request> send_requests (3*n_adjacent_processors);
662 unsigned int current_request = 0;
664 for (
unsigned int comm_step=0; comm_step<n_adjacent_processors; comm_step++)
666 n_comm_steps[adjacent_processors[comm_step]]=1;
667 mesh.
comm().send (adjacent_processors[comm_step],
668 my_interface_node_xfer_buffers[comm_step],
669 send_requests[current_request++],
670 element_neighbors_tag);
681 adjacent_processors.clear();
683 std::vector<dof_id_type> common_interface_node_list;
698 for (
unsigned int comm_step=0; comm_step<3*n_adjacent_processors; comm_step++)
703 status(
mesh.
comm().probe (Parallel::any_source,
704 element_neighbors_tag));
706 source_pid_idx = cast_int<processor_id_type>(status.source()),
707 dest_pid_idx = source_pid_idx;
711 if (n_comm_steps[source_pid_idx] == 1)
713 n_comm_steps[source_pid_idx]++;
715 mesh.
comm().receive (source_pid_idx,
716 common_interface_node_list,
717 element_neighbors_tag);
729 common_interface_node_list.erase
730 (std::set_intersection (my_interface_node_list.begin(),
731 my_interface_node_list.end(),
732 common_interface_node_list.begin(),
733 common_interface_node_list.end(),
734 common_interface_node_list.begin()),
735 common_interface_node_list.end());
755 std::set<const Elem *, CompareElemIdsByLevel> elements_to_send;
756 std::set<const Node *> connected_nodes;
759 if (common_interface_node_list.empty())
767 mesh.
comm().send_packed_range (dest_pid_idx,
769 connected_nodes.begin(),
770 connected_nodes.end(),
771 send_requests[current_request++],
772 element_neighbors_tag);
774 mesh.
comm().send_packed_range (dest_pid_idx,
776 elements_to_send.begin(),
777 elements_to_send.end(),
778 send_requests[current_request++],
779 element_neighbors_tag);
784 adjacent_processors.push_back(source_pid_idx);
788 for (
auto & elem : my_interface_elements)
790 std::size_t n_shared_nodes = 0;
793 if (std::binary_search (common_interface_node_list.begin(),
794 common_interface_node_list.end(),
802 if (n_shared_nodes > 0)
break;
811 if (!elements_to_send.count(elem))
813 #ifdef LIBMESH_ENABLE_AMR
822 elements_to_send.insert (elem);
825 connected_nodes.insert (&n);
836 libmesh_assert (connected_nodes.empty() || !elements_to_send.empty());
837 libmesh_assert (!connected_nodes.empty() || elements_to_send.empty());
840 mesh.
comm().send_packed_range (dest_pid_idx,
842 connected_nodes.begin(),
843 connected_nodes.end(),
844 send_requests[current_request++],
845 element_neighbors_tag);
848 mesh.
comm().send_packed_range (dest_pid_idx,
850 elements_to_send.begin(),
851 elements_to_send.end(),
852 send_requests[current_request++],
853 element_neighbors_tag);
858 else if (n_comm_steps[source_pid_idx] == 2)
860 n_comm_steps[source_pid_idx]++;
862 mesh.
comm().receive_packed_range (source_pid_idx,
866 element_neighbors_tag);
870 else if (n_comm_steps[source_pid_idx] == 3)
872 n_comm_steps[source_pid_idx]++;
874 mesh.
comm().receive_packed_range (source_pid_idx,
878 element_neighbors_tag);
885 << n_comm_steps[source_pid_idx]
891 Parallel::wait (send_requests);
905 SyncNeighbors nsync(
mesh);
910 #endif // LIBMESH_HAVE_MPI
913 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings
931 #ifndef LIBMESH_ENABLE_AMR
932 libmesh_error_msg(
"Calling MeshCommunication::send_coarse_ghosts() requires AMR to be enabled. "
933 "Please configure libmesh with --enable-amr.");
942 typedef std::unordered_map<processor_id_type, std::vector<Elem *>> ghost_map;
943 ghost_map coarsening_elements_to_ghost;
958 if (their_proc_id != proc_id)
959 coarsening_elements_to_ghost[their_proc_id].push_back(elem);
967 nodestag =
mesh.
comm().get_unique_tag(3141),
968 elemstag =
mesh.
comm().get_unique_tag(3142);
970 std::vector<Parallel::Request> send_requests;
974 std::vector<unsigned char> send_to_proc(n_proc, 0);
984 std::set<const Elem *, CompareElemIdsByLevel> elements_to_send;
985 std::set<const Node *> nodes_to_send;
987 const ghost_map::const_iterator it =
988 coarsening_elements_to_ghost.find(p);
989 if (it != coarsening_elements_to_ghost.end())
991 const std::vector<Elem *> & elems = it->second;
996 Elem *
const * elempp = const_cast<Elem * const *>(elems.data());
997 Elem *
const * elemend = elempp+elems.size();
1008 (*gf)(elem_it, elem_end, p, elements_to_ghost);
1012 for (
auto & pr : elements_to_ghost)
1014 const Elem * elem = pr.first;
1019 elements_to_send.insert(elem);
1021 nodes_to_send.insert(&n);
1027 send_requests.push_back(Parallel::request());
1030 nodes_to_send.begin(),
1031 nodes_to_send.end(),
1032 send_requests.back(),
1035 send_requests.push_back(Parallel::request());
1037 send_to_proc[p] = 1;
1040 elements_to_send.begin(),
1041 elements_to_send.end(),
1042 send_requests.back(),
1048 std::vector<unsigned char> recv_from_proc(send_to_proc);
1049 mesh.
comm().alltoall(recv_from_proc);
1052 (std::count(recv_from_proc.begin(), recv_from_proc.end(), 1));
1058 (Parallel::any_source,
1068 (Parallel::any_source,
1076 Parallel::wait (send_requests);
1077 #endif // LIBMESH_ENABLE_AMR
1080 #endif // LIBMESH_HAVE_MPI
1082 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings
1099 libmesh_parallel_only(
mesh.
comm());
1101 LOG_SCOPE(
"broadcast()",
"MeshCommunication");
1135 for (
unsigned int l=0; l !=
n_levels; ++l)
1158 MeshTools::libmesh_assert_valid_procids<Elem>(
mesh);
1159 MeshTools::libmesh_assert_valid_procids<Node>(
mesh);
1162 #endif // LIBMESH_HAVE_MPI
1166 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings
1182 libmesh_parallel_only(
mesh.
comm());
1184 LOG_SCOPE(
"(all)gather()",
"MeshCommunication");
1193 mesh.
comm().gather_packed_range (root_id,
1203 for (
unsigned int l=0; l !=
n_levels; ++l)
1211 mesh.
comm().gather_packed_range (root_id,
1240 #endif // LIBMESH_HAVE_MPI
1253 SyncIds(
MeshBase & _mesh, renumber_obj _renumberer) :
1263 void gather_data (
const std::vector<dof_id_type> & ids,
1264 std::vector<datum> & ids_out)
const
1269 void act_on_data (
const std::vector<dof_id_type> & old_ids,
1270 const std::vector<datum> & new_ids)
const
1273 if (old_ids[i] != new_ids[i])
1291 typedef std::unordered_set<const Node *> uset_type;
1297 typedef std::unordered_map<dof_id_type, dof_id_type> umap_type;
1305 void gather_data (
const std::vector<dof_id_type> & ids,
1306 std::vector<datum> & ids_out)
const
1321 bool act_on_data (
const std::vector<dof_id_type> & old_ids,
1322 const std::vector<datum> & new_ids)
1324 bool data_changed =
false;
1342 libmesh_assert_equal_to
1355 data_changed =
true;
1361 if (old_id != new_id)
1369 data_changed =
true;
1373 return data_changed;
1378 #ifdef LIBMESH_ENABLE_AMR
1381 typedef unsigned char datum;
1389 void gather_data (
const std::vector<dof_id_type> & ids,
1390 std::vector<datum> & ids_out)
const
1392 ids_out.reserve(ids.size());
1394 for (
const auto &
id : ids)
1397 ids_out.push_back(cast_int<unsigned char>(elem.
p_level()));
1401 void act_on_data (
const std::vector<dof_id_type> & old_ids,
1402 const std::vector<datum> & new_p_levels)
const
1411 #endif // LIBMESH_ENABLE_AMR
1414 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1415 template <
typename DofObjSub
class>
1416 struct SyncUniqueIds
1421 SyncUniqueIds(
MeshBase &_mesh, query_obj _querier) :
1430 void gather_data (
const std::vector<dof_id_type> & ids,
1431 std::vector<datum> & ids_out)
const
1433 ids_out.reserve(ids.size());
1435 for (
const auto &
id : ids)
1439 ids_out.push_back(d->unique_id());
1443 void act_on_data (
const std::vector<dof_id_type> & ids,
1444 const std::vector<datum> & unique_ids)
const
1448 DofObjSubclass * d = (
mesh.*
query)(ids[i]);
1450 d->set_unique_id() = unique_ids[i];
1454 #endif // LIBMESH_ENABLE_UNIQUE_ID
1463 libmesh_parallel_only(
mesh.
comm());
1473 LOG_SCOPE (
"make_node_ids_parallel_consistent()",
"MeshCommunication");
1475 SyncNodeIds syncids(
mesh);
1495 libmesh_parallel_only(
mesh.
comm());
1497 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1498 LOG_SCOPE (
"make_node_unique_ids_parallel_consistent()",
"MeshCommunication");
1516 libmesh_parallel_only(
mesh.
comm());
1518 LOG_SCOPE (
"make_elems_parallel_consistent()",
"MeshCommunication");
1525 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1536 #ifdef LIBMESH_ENABLE_AMR
1540 libmesh_parallel_only(
mesh.
comm());
1542 LOG_SCOPE (
"make_p_levels_parallel_consistent()",
"MeshCommunication");
1544 SyncPLevels syncplevels(
mesh);
1549 #endif // LIBMESH_ENABLE_AMR
1565 void gather_data (
const std::vector<dof_id_type> & ids,
1566 std::vector<datum> &
data)
1569 data.resize(ids.size());
1587 bool act_on_data (
const std::vector<dof_id_type> & ids,
1588 const std::vector<datum> proc_ids)
1590 bool data_changed =
false;
1606 data_changed =
true;
1611 return data_changed;
1616 struct ElemNodesMaybeNew
1618 ElemNodesMaybeNew() {}
1620 bool operator() (
const Elem * elem)
const
1624 #ifdef LIBMESH_ENABLE_AMR
1649 bool operator() (
const Elem * elem,
unsigned int local_node_num)
const
1666 LOG_SCOPE (
"make_node_proc_ids_parallel_consistent()",
"MeshCommunication");
1669 libmesh_parallel_only(
mesh.
comm());
1684 SyncProcIds sync(
mesh);
1695 LOG_SCOPE (
"make_new_node_proc_ids_parallel_consistent()",
"MeshCommunication");
1698 libmesh_parallel_only(
mesh.
comm());
1727 auto node_unpartitioned =
1728 [](
const Elem * elem,
unsigned int local_node_num)
1732 SyncProcIds sync(
mesh);
1737 node_unpartitioned, sync);
1745 NodeWasNew node_was_new(
mesh);
1750 if (node_was_new.was_new.count(&node))
1759 ElemNodesMaybeNew(), node_was_new, sync);
1774 libmesh_parallel_only(
mesh.
comm());
1816 libmesh_parallel_only(
mesh.
comm());
1853 const std::set<Elem *> & extra_ghost_elem_ids)
const
1858 LOG_SCOPE(
"delete_remote_elements()",
"MeshCommunication");
1871 std::set<const Elem *, CompareElemIdsByLevel> elements_to_keep;
1874 for (
const auto & elem : extra_ghost_elem_ids)
1876 std::vector<const Elem *> active_family;
1877 #ifdef LIBMESH_ENABLE_AMR
1882 active_family.push_back(elem);
1884 for (
const auto & f : active_family)
1885 elements_to_keep.insert(f);
1916 std::set<const Node *> connected_nodes;
1924 for (
int l =
n_levels - 1; l >= 0; --l)
1930 const bool keep_me = elements_to_keep.count(elem);
1945 if (!connected_nodes.count(node))
1961 gf->delete_remote_elements();