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/null_output_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" 39 #include "libmesh/elem_side_builder.h" 44 #include <unordered_set> 45 #include <unordered_map> 57 typedef std::vector<dof_id_type> datum;
65 void gather_data (
const std::vector<dof_id_type> & ids,
66 std::vector<datum> & neighbors)
const 68 neighbors.resize(ids.size());
78 neighbors[i].resize(n_neigh);
79 for (
unsigned int n = 0; n != n_neigh; ++n)
85 neighbors[i][n] = neigh->
id();
93 void act_on_data (
const std::vector<dof_id_type> & ids,
94 const std::vector<datum> & neighbors)
const 100 const datum & new_neigh = neighbors[i];
103 libmesh_assert_equal_to (n_neigh, new_neigh.size());
105 for (
unsigned int n = 0; n != n_neigh; ++n)
111 libmesh_assert_equal_to(old_neigh->
id(), new_neigh_id);
145 std::unordered_set<const Elem *> constraining_nodes_elems;
146 for (
const Elem * elem : connected_elements)
151 if (
const auto it = constraint_rows.find(&node);
152 it != constraint_rows.end())
153 for (
auto & p : it->second)
155 const Elem * constraining_elem = p.first.first;
158 if (!connected_elements.count(constraining_elem) &&
159 !new_connected_elements.count(constraining_elem))
160 constraining_nodes_elems.insert(constraining_elem);
165 newer_connected_elements.insert(constraining_nodes_elems.begin(),
166 constraining_nodes_elems.end());
169 #ifdef LIBMESH_ENABLE_AMR 186 connected_elem_set_type::reverse_iterator
187 elem_rit = new_connected_elements.rbegin();
189 for (; elem_rit != new_connected_elements.rend(); ++elem_rit)
191 const Elem * elem = *elem_rit;
197 for (
const Elem * parent = elem->
parent(); parent;
198 parent = parent->
parent())
199 if (!connected_elements.count(parent) &&
200 !new_connected_elements.count(parent))
201 newer_connected_elements.insert (parent);
203 auto total_family_insert =
204 [&connected_elements, &new_connected_elements,
205 &newer_connected_elements]
208 if (e->active() && e->has_children())
210 std::vector<const Elem *> subactive_family;
211 e->total_family_tree(subactive_family);
212 for (
const auto & f : subactive_family)
215 if (!connected_elements.count(f) &&
216 !new_connected_elements.count(f))
217 newer_connected_elements.insert(f);
222 total_family_insert(elem);
234 if (interior_parent &&
236 !connected_elements.count(interior_parent) &&
237 !new_connected_elements.count(interior_parent))
239 newer_connected_elements.insert (interior_parent);
240 total_family_insert(interior_parent);
250 [&connected_elements,
251 &new_connected_elements,
252 &newer_connected_elements]
259 new_connected_elements.count(parent) ||
260 newer_connected_elements.count(parent));
263 for (
const auto & elem : connected_elements)
265 for (
const auto & elem : new_connected_elements)
267 for (
const auto & elem : newer_connected_elements)
271 #endif // LIBMESH_ENABLE_AMR 281 for (
const auto & elem : new_connected_elements)
283 if (!connected_nodes.count(&n) &&
284 !new_connected_nodes.count(&n))
285 newer_connected_nodes.insert(&n);
309 (*gf)(elem_it, elem_end, pid, elements_to_ghost);
313 for (
auto & pr : elements_to_ghost)
315 const Elem * elem = pr.first;
318 connected_elements.insert(elem);
324 for (; elem_it != elem_end; ++elem_it)
325 connected_elements.insert(*elem_it);
337 #ifdef LIBMESH_ENABLE_AMR 341 for (
const auto & elem :
as_range(elem_it, elem_end))
346 connected_elements.insert(&child);
348 #endif // LIBMESH_ENABLE_AMR 357 connected_nodes.clear();
360 connect_nodes(connected_elements, connected_nodes, connected_nodes,
373 new_connected_elements.swap(connected_elements);
374 new_connected_nodes.swap(connected_nodes);
376 while (!new_connected_elements.empty() ||
377 !new_connected_nodes.empty())
379 auto [newer_connected_elements,
380 newer_connected_nodes] =
382 (
mesh, connected_elements, connected_nodes,
383 new_connected_elements, new_connected_nodes);
386 connected_elements.merge(new_connected_elements);
387 connected_nodes.merge(new_connected_nodes);
395 new_connected_elements.swap(newer_connected_elements);
396 new_connected_nodes.swap(newer_connected_nodes);
401 std::pair<connected_elem_set_type, connected_node_set_type>
408 std::pair<connected_elem_set_type, connected_node_set_type> returnval;
409 auto & [newer_connected_elements, newer_connected_nodes] = returnval;
410 connect_element_families(connected_elements, new_connected_elements,
411 newer_connected_elements, &
mesh);
413 connect_nodes(new_connected_elements, connected_nodes,
414 new_connected_nodes, newer_connected_nodes);
431 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings 442 bool newly_coarsened_only)
const 469 mesh.unpartitioned_elements_end()) == 0);
471 LOG_SCOPE(
"redistribute()",
"MeshCommunication");
474 typedef std::remove_const<MeshBase::const_element_iterator::value_type>::type nc_v_t;
478 std::unordered_map<processor_id_type, std::vector<nc_v_t>> send_to_pid;
481 #ifdef LIBMESH_ENABLE_AMR 482 newly_coarsened_only ?
485 mesh.active_elements_begin();
488 #ifdef LIBMESH_ENABLE_AMR 489 newly_coarsened_only ?
492 mesh.active_elements_end();
495 for (
auto & elem :
as_range(send_elems_begin, send_elems_end))
499 std::map<processor_id_type, std::vector<const Node *>> all_nodes_to_send;
500 std::map<processor_id_type, std::vector<const Elem *>> all_elems_to_send;
504 bool have_constraint_rows = !constraint_rows.empty();
512 typedef std::vector<std::pair<std::pair<dof_id_type, unsigned int>,
Real>>
515 std::vector<std::pair<dof_id_type, serialized_row_type>>>
516 all_constraint_rows_to_send;
521 for (
const auto & [pid, p_elements] : send_to_pid)
535 v_t * elempp = p_elements.data();
536 v_t * elemend = elempp + p_elements.size();
538 #ifndef LIBMESH_ENABLE_AMR 561 mesh.pid_elements_end(pid),
569 all_nodes_to_send[pid].assign(connected_nodes.begin(),
570 connected_nodes.end());
572 all_elems_to_send[pid].assign(elements_to_send.begin(),
573 elements_to_send.end());
575 for (
auto & [node, row] : constraint_rows)
577 if (!connected_nodes.count(node))
580 serialized_row_type serialized_row;
581 for (
auto [elem_and_node, coef] : row)
582 serialized_row.emplace_back(std::make_pair(elem_and_node.first->id(),
583 elem_and_node.second),
586 all_constraint_rows_to_send[pid].emplace_back
587 (node->id(), std::move(serialized_row));
592 auto null_node_action = [](
processor_id_type,
const std::vector<const Node*>&){};
593 auto null_elem_action = [](
processor_id_type,
const std::vector<const Elem*>&){};
604 if (have_constraint_rows)
606 auto constraint_row_action =
607 [&
mesh, &constraint_rows]
609 const std::vector<std::pair<dof_id_type, serialized_row_type>> rows)
611 for (
auto & [node_id, serialized_row] : rows)
614 for (
auto [elem_and_node, coef] : serialized_row)
615 row.emplace_back(std::make_pair(
mesh.
elem_ptr(elem_and_node.first),
616 elem_and_node.second),
624 all_constraint_rows_to_send,
625 constraint_row_action);
638 libmesh_assert_equal_to(n_constraint_rows, new_n_constraint_rows);
650 mesh.MeshBase::redistribute();
652 #endif // LIBMESH_HAVE_MPI 656 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings 675 LOG_SCOPE(
"gather_neighboring_elements()",
"MeshCommunication");
721 std::vector<processor_id_type> adjacent_processors;
724 adjacent_processors.push_back (pid);
728 cast_int<processor_id_type>(adjacent_processors.size());
734 std::vector<dof_id_type> my_interface_node_list;
735 std::vector<const Elem *> my_interface_elements;
737 std::set<dof_id_type> my_interface_node_set;
743 for (
const auto & elem :
mesh.active_local_element_ptr_range())
749 my_interface_elements.push_back(elem);
754 const Elem & side = side_builder(*elem, s);
757 my_interface_node_set.insert (side.
node_id(n));
762 my_interface_node_list.reserve (my_interface_node_set.size());
763 my_interface_node_list.insert (my_interface_node_list.end(),
764 my_interface_node_set.begin(),
765 my_interface_node_set.end());
775 std::vector<std::vector<dof_id_type>>
776 my_interface_node_xfer_buffers (n_adjacent_processors, my_interface_node_list);
777 std::map<processor_id_type, unsigned char> n_comm_steps;
779 std::vector<Parallel::Request> send_requests (3*n_adjacent_processors);
780 unsigned int current_request = 0;
782 for (
unsigned int comm_step=0; comm_step<n_adjacent_processors; comm_step++)
784 n_comm_steps[adjacent_processors[comm_step]]=1;
786 my_interface_node_xfer_buffers[comm_step],
787 send_requests[current_request++],
788 element_neighbors_tag);
799 adjacent_processors.clear();
801 std::vector<dof_id_type> common_interface_node_list;
816 for (
unsigned int comm_step=0; comm_step<3*n_adjacent_processors; comm_step++)
822 element_neighbors_tag));
824 source_pid_idx = cast_int<processor_id_type>(
status.source()),
825 dest_pid_idx = source_pid_idx;
829 if (n_comm_steps[source_pid_idx] == 1)
831 n_comm_steps[source_pid_idx]++;
834 common_interface_node_list,
835 element_neighbors_tag);
847 common_interface_node_list.erase
848 (std::set_intersection (my_interface_node_list.begin(),
849 my_interface_node_list.end(),
850 common_interface_node_list.begin(),
851 common_interface_node_list.end(),
852 common_interface_node_list.begin()),
853 common_interface_node_list.end());
881 if (common_interface_node_list.empty())
891 connected_nodes.begin(),
892 connected_nodes.end(),
893 send_requests[current_request++],
894 element_neighbors_tag);
898 elements_to_send.begin(),
899 elements_to_send.end(),
900 send_requests[current_request++],
901 element_neighbors_tag);
906 adjacent_processors.push_back(source_pid_idx);
910 for (
auto & elem : my_interface_elements)
912 std::size_t n_shared_nodes = 0;
915 if (std::binary_search (common_interface_node_list.begin(),
916 common_interface_node_list.end(),
924 if (n_shared_nodes > 0)
break;
933 if (!elements_to_send.count(elem))
935 #ifdef LIBMESH_ENABLE_AMR 944 elements_to_send.insert (elem);
947 connected_nodes.insert (&n);
958 libmesh_assert (connected_nodes.empty() || !elements_to_send.empty());
959 libmesh_assert (!connected_nodes.empty() || elements_to_send.empty());
964 connected_nodes.begin(),
965 connected_nodes.end(),
966 send_requests[current_request++],
967 element_neighbors_tag);
972 elements_to_send.begin(),
973 elements_to_send.end(),
974 send_requests[current_request++],
975 element_neighbors_tag);
980 else if (n_comm_steps[source_pid_idx] == 2)
982 n_comm_steps[source_pid_idx]++;
988 element_neighbors_tag);
992 else if (n_comm_steps[source_pid_idx] == 3)
994 n_comm_steps[source_pid_idx]++;
1000 element_neighbors_tag);
1006 libMesh::err <<
"ERROR: unexpected number of replies: " 1007 << n_comm_steps[source_pid_idx]
1013 Parallel::wait (send_requests);
1027 SyncNeighbors nsync(
mesh);
1032 #endif // LIBMESH_HAVE_MPI 1035 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings 1053 #ifndef LIBMESH_ENABLE_AMR 1054 libmesh_error_msg(
"Calling MeshCommunication::send_coarse_ghosts() requires AMR to be enabled. " 1055 "Please configure libmesh with --enable-amr.");
1064 typedef std::unordered_map<processor_id_type, std::vector<Elem *>> ghost_map;
1065 ghost_map coarsening_elements_to_ghost;
1080 if (their_proc_id != proc_id)
1081 coarsening_elements_to_ghost[their_proc_id].push_back(elem);
1084 std::map<processor_id_type, std::vector<const Node *>> all_nodes_to_send;
1085 std::map<processor_id_type, std::vector<const Elem *>> all_elems_to_send;
1095 std::set<const Node *> nodes_to_send;
1097 if (
const auto it = std::as_const(coarsening_elements_to_ghost).find(p);
1098 it != coarsening_elements_to_ghost.end())
1100 const std::vector<Elem *> & elems = it->second;
1105 Elem *
const * elempp =
const_cast<Elem *
const *
>(elems.data());
1106 Elem *
const * elemend = elempp+elems.size();
1117 (*gf)(elem_it, elem_end, p, elements_to_ghost);
1121 for (
auto & pr : elements_to_ghost)
1123 const Elem * elem = pr.first;
1128 elements_to_send.insert(elem);
1130 nodes_to_send.insert(&n);
1136 all_nodes_to_send[p].assign(nodes_to_send.begin(), nodes_to_send.end());
1137 all_elems_to_send[p].assign(elements_to_send.begin(), elements_to_send.end());
1142 auto null_node_action = [](
processor_id_type,
const std::vector<const Node*>&){};
1143 auto null_elem_action = [](
processor_id_type,
const std::vector<const Elem*>&){};
1152 #endif // LIBMESH_ENABLE_AMR 1155 #endif // LIBMESH_HAVE_MPI 1157 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings 1174 libmesh_parallel_only(
mesh.
comm());
1176 LOG_SCOPE(
"broadcast()",
"MeshCommunication");
1212 for (
unsigned int l=0; l !=
n_levels; ++l)
1214 mesh.level_elements_begin(l),
1215 mesh.level_elements_end(l),
1230 bool have_constraint_rows = !constraint_rows.empty();
1232 if (have_constraint_rows)
1235 std::vector<std::tuple<dof_id_type, unsigned int, Real>>>
1238 for (
auto & row : constraint_rows)
1240 const Node * node = row.first;
1244 std::vector<std::tuple<dof_id_type, unsigned int, Real>>
1246 for (
auto & entry : row.second)
1247 serialized_row.push_back
1248 (std::make_tuple(entry.first.first->id(),
1249 entry.first.second, entry.second));
1251 serialized_rows.emplace(rowid, std::move(serialized_row));
1257 constraint_rows.clear();
1259 for (
auto & row : serialized_rows)
1264 std::vector<std::pair<std::pair<const Elem *, unsigned int>,
Real>>
1266 for (
auto & entry : row.second)
1267 deserialized_row.push_back
1268 (std::make_pair(std::make_pair(
mesh.
elem_ptr(std::get<0>(entry)),
1269 std::get<1>(entry)),
1270 std::get<2>(entry)));
1272 constraint_rows.emplace(node, deserialized_row);
1290 MeshTools::libmesh_assert_valid_procids<Elem>(
mesh);
1291 MeshTools::libmesh_assert_valid_procids<Node>(
mesh);
1294 #endif // LIBMESH_HAVE_MPI 1298 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings 1314 libmesh_parallel_only(
mesh.
comm());
1316 LOG_SCOPE(
"(all)gather()",
"MeshCommunication");
1319 static const std::size_t approx_total_buffer_size = 1e8;
1320 const std::size_t approx_each_buffer_size =
1329 approx_each_buffer_size) :
1336 approx_each_buffer_size);
1342 for (
unsigned int l=0; l !=
n_levels; ++l)
1346 mesh.level_elements_begin(l),
1347 mesh.level_elements_end(l),
1349 approx_each_buffer_size) :
1353 mesh.level_elements_begin(l),
1354 mesh.level_elements_end(l),
1356 approx_each_buffer_size);
1367 bool have_constraint_rows = !constraint_rows.empty();
1369 if (have_constraint_rows)
1372 std::vector<std::tuple<dof_id_type, unsigned int, Real>>>
1375 for (
auto & row : constraint_rows)
1377 const Node * node = row.first;
1381 std::vector<std::tuple<dof_id_type, unsigned int, Real>>
1383 for (
auto & entry : row.second)
1384 serialized_row.push_back
1385 (std::make_tuple(entry.first.first->id(),
1386 entry.first.second, entry.second));
1388 serialized_rows.emplace(rowid, std::move(serialized_row));
1399 for (
auto & row : serialized_rows)
1404 std::vector<std::pair<std::pair<const Elem *, unsigned int>,
Real>>
1406 for (
auto & entry : row.second)
1407 deserialized_row.push_back
1408 (std::make_pair(std::make_pair(
mesh.
elem_ptr(std::get<0>(entry)),
1409 std::get<1>(entry)),
1410 std::get<2>(entry)));
1412 constraint_rows.emplace(node, deserialized_row);
1441 #endif // LIBMESH_HAVE_MPI 1454 SyncIds(
MeshBase & _mesh, renumber_obj _renumberer) :
1464 void gather_data (
const std::vector<dof_id_type> & ids,
1465 std::vector<datum> & ids_out)
const 1470 void act_on_data (
const std::vector<dof_id_type> & old_ids,
1471 const std::vector<datum> & new_ids)
const 1474 if (old_ids[i] != new_ids[i])
1492 typedef std::unordered_set<const Node *> uset_type;
1498 typedef std::unordered_map<dof_id_type, dof_id_type> umap_type;
1506 void gather_data (
const std::vector<dof_id_type> & ids,
1507 std::vector<datum> & ids_out)
const 1522 bool act_on_data (
const std::vector<dof_id_type> & old_ids,
1523 const std::vector<datum> & new_ids)
1525 bool data_changed =
false;
1543 libmesh_assert_equal_to
1556 data_changed =
true;
1562 if (old_id != new_id)
1570 data_changed =
true;
1574 return data_changed;
1579 #ifdef LIBMESH_ENABLE_AMR 1582 typedef std::pair<unsigned char,unsigned char> datum;
1590 void gather_data (
const std::vector<dof_id_type> & ids,
1591 std::vector<datum> & ids_out)
const 1593 ids_out.reserve(ids.size());
1595 for (
const auto &
id : ids)
1599 (std::make_pair(cast_int<unsigned char>(elem.
p_level()),
1604 void act_on_data (
const std::vector<dof_id_type> & old_ids,
1605 const std::vector<datum> & new_p_levels)
const 1612 (new_p_levels[i].first,
1613 static_cast<Elem::RefinementState>(new_p_levels[i].second));
1619 #endif // LIBMESH_ENABLE_AMR 1622 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1623 template <
typename DofObjSub
class>
1624 struct SyncUniqueIds
1629 SyncUniqueIds(
MeshBase &_mesh, query_obj _querier) :
1638 void gather_data (
const std::vector<dof_id_type> & ids,
1639 std::vector<datum> & ids_out)
const 1641 ids_out.reserve(ids.size());
1643 for (
const auto &
id : ids)
1647 ids_out.push_back(d->unique_id());
1651 void act_on_data (
const std::vector<dof_id_type> & ids,
1652 const std::vector<datum> & unique_ids)
const 1656 DofObjSubclass * d = (
mesh.*
query)(ids[i]);
1658 d->set_unique_id(unique_ids[i]);
1662 #endif // LIBMESH_ENABLE_UNIQUE_ID 1664 template <
typename DofObjSub
class>
1667 typedef std::vector<boundary_id_type> datum;
1676 void gather_data (
const std::vector<dof_id_type> & ids,
1677 std::vector<datum> & ids_out)
const 1679 ids_out.reserve(ids.size());
1683 for (
const auto &
id : ids)
1687 std::vector<boundary_id_type> bcids;
1689 ids_out.push_back(std::move(bcids));
1693 void act_on_data (
const std::vector<dof_id_type> & ids,
1694 const std::vector<datum> & bcids)
const 1702 boundary_info.
add_node(n, bcids[i]);
1715 libmesh_parallel_only(
mesh.
comm());
1725 LOG_SCOPE (
"make_node_ids_parallel_consistent()",
"MeshCommunication");
1727 SyncNodeIds syncids(
mesh);
1747 libmesh_parallel_only(
mesh.
comm());
1749 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1750 LOG_SCOPE (
"make_node_unique_ids_parallel_consistent()",
"MeshCommunication");
1768 libmesh_parallel_only(
mesh.
comm());
1770 LOG_SCOPE (
"make_node_bcids_parallel_consistent()",
"MeshCommunication");
1772 SyncBCIds<Node> syncbcids(
mesh);
1787 libmesh_parallel_only(
mesh.
comm());
1789 LOG_SCOPE (
"make_elems_parallel_consistent()",
"MeshCommunication");
1793 (
mesh,
mesh.active_elements_begin(),
1794 mesh.active_elements_end(), syncids);
1796 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1800 mesh.active_elements_end(), syncuniqueids);
1807 #ifdef LIBMESH_ENABLE_AMR 1811 libmesh_parallel_only(
mesh.
comm());
1813 LOG_SCOPE (
"make_p_levels_parallel_consistent()",
"MeshCommunication");
1815 SyncPLevels syncplevels(
mesh);
1820 #endif // LIBMESH_ENABLE_AMR 1836 void gather_data (
const std::vector<dof_id_type> & ids,
1837 std::vector<datum> & data)
1840 data.resize(ids.size());
1858 bool act_on_data (
const std::vector<dof_id_type> & ids,
1859 const std::vector<datum> proc_ids)
1861 bool data_changed =
false;
1877 data_changed =
true;
1882 return data_changed;
1887 struct ElemNodesMaybeNew
1889 ElemNodesMaybeNew() {}
1891 bool operator() (
const Elem * elem)
const 1895 #ifdef LIBMESH_ENABLE_AMR 1915 for (
const auto & node :
mesh.node_ptr_range())
1920 bool operator() (
const Elem * elem,
unsigned int local_node_num)
const 1937 LOG_SCOPE (
"make_node_proc_ids_parallel_consistent()",
"MeshCommunication");
1940 libmesh_parallel_only(
mesh.
comm());
1955 SyncProcIds sync(
mesh);
1966 LOG_SCOPE (
"make_new_node_proc_ids_parallel_consistent()",
"MeshCommunication");
1969 libmesh_parallel_only(
mesh.
comm());
1998 auto node_unpartitioned =
1999 [](
const Elem * elem,
unsigned int local_node_num)
2003 SyncProcIds sync(
mesh);
2006 (
mesh,
mesh.not_local_elements_begin(),
2008 node_unpartitioned, sync);
2016 NodeWasNew node_was_new(
mesh);
2019 for (
auto & elem :
mesh.element_ptr_range())
2021 if (node_was_new.was_new.count(&node))
2030 ElemNodesMaybeNew(), node_was_new, sync);
2045 libmesh_parallel_only(
mesh.
comm());
2090 libmesh_parallel_only(
mesh.
comm());
2130 const std::set<Elem *> & extra_ghost_elem_ids)
const 2135 LOG_SCOPE(
"delete_remote_elements()",
"MeshCommunication");
2152 for (
const auto & elem : extra_ghost_elem_ids)
2154 std::vector<const Elem *> active_family;
2155 #ifdef LIBMESH_ENABLE_AMR 2160 active_family.push_back(elem);
2162 for (
const auto & f : active_family)
2163 elements_to_keep.insert(f);
2198 for (
int l =
n_levels - 1; l >= 0; --l)
2199 for (
auto & elem :
as_range(
mesh.level_elements_begin(l),
2200 mesh.level_elements_end(l)))
2204 const bool keep_me = elements_to_keep.count(elem);
2216 for (
auto & node :
mesh.node_ptr_range())
2219 if (!connected_nodes.count(node))
2235 gf->delete_remote_elements();
2239 libmesh_assert_equal_to(n_constraint_rows, n_new_constraint_rows);
GhostingFunctorIterator ghosting_functors_begin() const
Beginning of range of ghosting functors.
void set_p_level(const unsigned int p)
Sets the value of the p-refinement level for the element.
void gather_packed_range(const unsigned int root_id, Context *context, Iter range_begin, const Iter range_end, OutputIter out, std::size_t approx_buffer_size=1000000) const
RefinementState refinement_flag() const
const Elem * parent() const
void broadcast_packed_range(const Context *context1, Iter range_begin, const Iter range_end, OutputContext *context2, OutputIter out, const unsigned int root_id=0, std::size_t approx_buffer_size=1000000) const
void make_node_unique_ids_parallel_consistent(MeshBase &)
Assuming all unique_ids on local nodes are globally unique, and assuming all processor ids are parall...
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.
virtual void renumber_node(dof_id_type old_id, dof_id_type new_id)=0
Changes the id of node old_id, both by changing node(old_id)->id() and by moving node(old_id) in the ...
std::vector< std::string > _elem_integer_names
The array of names for integer data associated with each element in the mesh.
const Elem * interior_parent() const
void reconnect_nodes(connected_elem_set_type &connected_elements, connected_node_set_type &connected_nodes)
IntRange< unsigned short > side_index_range() const
The definition of the const_element_iterator struct.
const Elem * top_parent() const
std::vector< std::pair< std::pair< const Elem *, unsigned int >, Real > > constraint_rows_mapped_type
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
void make_elems_parallel_consistent(MeshBase &)
Copy ids of ghost elements from their local processors.
RefinementState p_refinement_flag() const
std::unordered_set< const Node * > was_new
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true, const bool assert_valid=true)=0
Locate element face (edge in 2D) neighbors.
void clear()
Clears all data structures and resets to a pristine state.
void family_tree(std::vector< const Elem *> &family, bool reset=true) const
Fills the vector family with the children of this element, recursively.
This is the base class from which all geometric element types are derived.
void active_family_tree(std::vector< const Elem *> &active_family, bool reset=true) const
Same as the family_tree() member, but only adds the active children.
const Parallel::Communicator & comm() const
unsigned int p_level() const
void allgather_packed_range(Context *context, Iter range_begin, const Iter range_end, OutputIter out, std::size_t approx_buffer_size=1000000) 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.
std::map< const Elem *, const CouplingMatrix *, CompareDofObjectsByPIDAndThenID > map_type
What elements do we care about and what variables do we care about on each element?
void make_node_bcids_parallel_consistent(MeshBase &)
Assuming all processor ids are parallel consistent, this function makes all ghost boundary ids on nod...
GhostingFunctorIterator ghosting_functors_end() const
End of range of ghosting functors.
void make_links_to_me_remote()
Resets this element's neighbors' appropriate neighbor pointers and its parent's and children's approp...
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.
std::vector< std::string > _node_integer_names
The array of names for integer data associated with each node in the mesh.
void send_packed_range(const unsigned int dest_processor_id, const Context *context, Iter range_begin, const Iter range_end, const MessageTag &tag=no_tag, std::size_t approx_buffer_size=1000000) const
dof_id_type n_constraint_rows() const
Used to iterate over non-nullptr entries in a container.
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.
ElemMappingType default_mapping_type() const
Returns the default master space to physical space mapping basis functions to be used on newly added ...
processor_id_type size() const
void push_parallel_vector_data(const Communicator &comm, MapToVectors &&data, const ActionFunctor &act_on_data)
uint8_t processor_id_type
std::map< boundary_id_type, std::string > & set_sideset_name_map()
processor_id_type n_processors() const
virtual bool is_serial() const
void libmesh_ignore(const Args &...)
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
void make_new_node_proc_ids_parallel_consistent(MeshBase &)
Assuming all processor ids on nodes touching local elements are parallel consistent, this function makes processor ids on new nodes on other processors parallel consistent as well.
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.
const Node & node_ref(const unsigned int i) const
void query_ghosting_functors(const MeshBase &mesh, processor_id_type pid, MeshBase::const_element_iterator elem_it, MeshBase::const_element_iterator elem_end, connected_elem_set_type &connected_elements)
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
void push_parallel_packed_range(const Communicator &comm, MapToContainers &&data, Context *context, const ActionFunctor &act_on_data)
void receive_packed_range(const unsigned int dest_processor_id, Context *context, OutputIter out, const T *output_type, const MessageTag &tag=any_tag) const
unsigned char default_mapping_data() const
Returns any default data value used by the master space to physical space mapping.
virtual void update_parallel_id_counts()=0
Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors...
void sync_node_data_by_element_id(MeshBase &mesh, const MeshBase::const_element_iterator &range_begin, const MeshBase::const_element_iterator &range_end, const ElemCheckFunctor &elem_check, const NodeCheckFunctor &node_check, SyncFunctor &sync)
Synchronize data about a range of ghost nodes uniquely identified by an element id and local node id...
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
status probe(const unsigned int src_processor_id, const MessageTag &tag=any_tag) const
virtual const Node * query_node_ptr(const dof_id_type i) const =0
void make_p_levels_parallel_consistent(MeshBase &)
Copy p levels of ghost elements from their local processors.
void set_default_mapping_type(const ElemMappingType type)
Set the default master space to physical space mapping basis functions to be used on newly added elem...
virtual dof_id_type max_elem_id() const =0
void clear_point_locator()
Releases the current PointLocator object.
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
void family_tree(T elem, std::vector< T > &family, bool reset=true)
virtual void delete_node(Node *n)=0
Removes the Node n from the mesh.
Helper for building element sides that minimizes the construction of new elements.
void allow_find_neighbors(bool allow)
If false is passed then this mesh will no longer work to find element neighbors when being prepared f...
void hack_p_level_and_refinement_flag(const unsigned int p, RefinementState pflag)
Sets the value of the p-refinement level for the element without altering the p-level of its ancestor...
std::map< subdomain_id_type, std::string > & set_subdomain_name_map()
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 set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
The DistributedMesh class is derived from the MeshBase class, and is intended to provide identical fu...
virtual void clear()
Deletes all the element and node data that is currently stored.
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
umap_type definitive_renumbering
void gather_neighboring_elements(DistributedMesh &) const
A do-nothing class for templated methods that expect output iterator arguments.
void connect_children(const MeshBase &mesh, MeshBase::const_element_iterator elem_it, MeshBase::const_element_iterator elem_end, connected_elem_set_type &connected_elements)
std::set< const Node * > connected_node_set_type
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
virtual const Elem * elem_ptr(const dof_id_type i) const =0
ElemMappingType
Enumeration of possible element master->physical mapping types.
void send_coarse_ghosts(MeshBase &) const
Examine a just-coarsened mesh, and for any newly-coarsened elements, send the associated ghosted elem...
void make_node_ids_parallel_consistent(MeshBase &)
Assuming all ids on local nodes are globally unique, and assuming all processor ids are parallel cons...
std::vector< dof_id_type > _node_integer_default_values
The array of default initialization values for integer data associated with each node in the mesh...
const Elem * neighbor_ptr(unsigned int i) const
std::vector< dof_id_type > _elem_integer_default_values
The array of default initialization values for integer data associated with each element in the mesh...
virtual unsigned int n_vertices() const =0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void gather(const processor_id_type root_id, MeshBase &) const
This method takes an input DistributedMesh which may be distributed among all the processors...
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
timpi_pure bool verify(const T &r) const
virtual void renumber_elem(dof_id_type old_id, dof_id_type new_id)=0
Changes the id of element old_id, both by changing elem(old_id)->id() and by moving elem(old_id) in t...
void max(const T &r, T &o, Request &req) const
const Node * node_ptr(const unsigned int i) const
std::map< boundary_id_type, std::string > & set_nodeset_name_map()
bool sync_node_data_by_element_id_once(MeshBase &mesh, const MeshBase::const_element_iterator &range_begin, const MeshBase::const_element_iterator &range_end, const ElemCheckFunctor &elem_check, const NodeCheckFunctor &node_check, SyncFunctor &sync)
Synchronize data about a range of ghost nodes uniquely identified by an element id and local node id...
void make_nodes_parallel_consistent(MeshBase &)
Copy processor_ids and ids on ghost nodes from their local processors.
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
unsigned int n_neighbors() const
void broadcast(MeshBase &) const
Finds all the processors that may contain elements that neighbor my elements.
void make_node_proc_ids_parallel_consistent(MeshBase &)
Assuming all processor ids on nodes touching local elements are parallel consistent, this function makes all other processor ids parallel consistent as well.
virtual const Elem & elem_ref(const dof_id_type i) const
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...
void connect_element_dependencies(const MeshBase &mesh, connected_elem_set_type &connected_elements, connected_node_set_type &connected_nodes)
std::set< const Elem *, CompareElemIdsByLevel > connected_elem_set_type
void set_default_mapping_data(const unsigned char data)
Set the default master space to physical space mapping basis functions to be used on newly added elem...
virtual const Node & node_ref(const dof_id_type i) const
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Returns a range with all neighbors of an element, usable in range-based for loops.
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
void make_new_nodes_parallel_consistent(MeshBase &)
Copy processor_ids and ids on new nodes from their local processors.
processor_id_type processor_id() const
void delete_remote_elements(DistributedMesh &, const std::set< Elem *> &) const
This method takes an input DistributedMesh which may be distributed among all the processors...
dof_id_type node_id(const unsigned int i) const
bool has_children() const
void redistribute(DistributedMesh &mesh, bool newly_coarsened_only=false) const
This method takes a parallel distributed mesh and redistributes the elements.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
virtual dof_id_type n_nodes() const =0
void sync_element_data_by_parent_id(MeshBase &mesh, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
Request data about a range of ghost elements uniquely identified by their parent id and which child t...
void set_union(T &data, const unsigned int root_id) const
const RemoteElem * remote_elem