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 352 #ifdef LIBMESH_ENABLE_DEPRECATED 359 libmesh_deprecated();
363 connect_element_families(connected_elements, connected_elements,
364 connected_elements,
mesh);
366 #endif // LIBMESH_ENABLE_DEPRECATED 375 connected_nodes.clear();
378 connect_nodes(connected_elements, connected_nodes, connected_nodes,
391 new_connected_elements.swap(connected_elements);
392 new_connected_nodes.swap(connected_nodes);
394 while (!new_connected_elements.empty() ||
395 !new_connected_nodes.empty())
397 auto [newer_connected_elements,
398 newer_connected_nodes] =
400 (
mesh, connected_elements, connected_nodes,
401 new_connected_elements, new_connected_nodes);
404 connected_elements.merge(new_connected_elements);
405 connected_nodes.merge(new_connected_nodes);
413 new_connected_elements.swap(newer_connected_elements);
414 new_connected_nodes.swap(newer_connected_nodes);
419 std::pair<connected_elem_set_type, connected_node_set_type>
426 std::pair<connected_elem_set_type, connected_node_set_type> returnval;
427 auto & [newer_connected_elements, newer_connected_nodes] = returnval;
428 connect_element_families(connected_elements, new_connected_elements,
429 newer_connected_elements, &
mesh);
431 connect_nodes(new_connected_elements, connected_nodes,
432 new_connected_nodes, newer_connected_nodes);
449 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings 460 bool newly_coarsened_only)
const 487 mesh.unpartitioned_elements_end()) == 0);
489 LOG_SCOPE(
"redistribute()",
"MeshCommunication");
492 typedef std::remove_const<MeshBase::const_element_iterator::value_type>::type nc_v_t;
496 std::unordered_map<processor_id_type, std::vector<nc_v_t>> send_to_pid;
499 #ifdef LIBMESH_ENABLE_AMR 500 newly_coarsened_only ?
503 mesh.active_elements_begin();
506 #ifdef LIBMESH_ENABLE_AMR 507 newly_coarsened_only ?
510 mesh.active_elements_end();
513 for (
auto & elem :
as_range(send_elems_begin, send_elems_end))
517 std::map<processor_id_type, std::vector<const Node *>> all_nodes_to_send;
518 std::map<processor_id_type, std::vector<const Elem *>> all_elems_to_send;
522 bool have_constraint_rows = !constraint_rows.empty();
530 typedef std::vector<std::pair<std::pair<dof_id_type, unsigned int>,
Real>>
533 std::vector<std::pair<dof_id_type, serialized_row_type>>>
534 all_constraint_rows_to_send;
539 for (
const auto & [pid, p_elements] : send_to_pid)
553 v_t * elempp = p_elements.data();
554 v_t * elemend = elempp + p_elements.size();
556 #ifndef LIBMESH_ENABLE_AMR 579 mesh.pid_elements_end(pid),
587 all_nodes_to_send[pid].assign(connected_nodes.begin(),
588 connected_nodes.end());
590 all_elems_to_send[pid].assign(elements_to_send.begin(),
591 elements_to_send.end());
593 for (
auto & [node, row] : constraint_rows)
595 if (!connected_nodes.count(node))
598 serialized_row_type serialized_row;
599 for (
auto [elem_and_node, coef] : row)
600 serialized_row.emplace_back(std::make_pair(elem_and_node.first->id(),
601 elem_and_node.second),
604 all_constraint_rows_to_send[pid].emplace_back
605 (node->id(), std::move(serialized_row));
610 auto null_node_action = [](
processor_id_type,
const std::vector<const Node*>&){};
611 auto null_elem_action = [](
processor_id_type,
const std::vector<const Elem*>&){};
622 if (have_constraint_rows)
624 auto constraint_row_action =
625 [&
mesh, &constraint_rows]
627 const std::vector<std::pair<dof_id_type, serialized_row_type>> rows)
629 for (
auto & [node_id, serialized_row] : rows)
632 for (
auto [elem_and_node, coef] : serialized_row)
633 row.emplace_back(std::make_pair(
mesh.
elem_ptr(elem_and_node.first),
634 elem_and_node.second),
642 all_constraint_rows_to_send,
643 constraint_row_action);
656 libmesh_assert_equal_to(n_constraint_rows, new_n_constraint_rows);
668 mesh.MeshBase::redistribute();
670 #endif // LIBMESH_HAVE_MPI 674 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings 693 LOG_SCOPE(
"gather_neighboring_elements()",
"MeshCommunication");
739 std::vector<processor_id_type> adjacent_processors;
742 adjacent_processors.push_back (pid);
746 cast_int<processor_id_type>(adjacent_processors.size());
752 std::vector<dof_id_type> my_interface_node_list;
753 std::vector<const Elem *> my_interface_elements;
755 std::set<dof_id_type> my_interface_node_set;
761 for (
const auto & elem :
mesh.active_local_element_ptr_range())
767 my_interface_elements.push_back(elem);
772 const Elem & side = side_builder(*elem, s);
775 my_interface_node_set.insert (side.
node_id(n));
780 my_interface_node_list.reserve (my_interface_node_set.size());
781 my_interface_node_list.insert (my_interface_node_list.end(),
782 my_interface_node_set.begin(),
783 my_interface_node_set.end());
793 std::vector<std::vector<dof_id_type>>
794 my_interface_node_xfer_buffers (n_adjacent_processors, my_interface_node_list);
795 std::map<processor_id_type, unsigned char> n_comm_steps;
797 std::vector<Parallel::Request> send_requests (3*n_adjacent_processors);
798 unsigned int current_request = 0;
800 for (
unsigned int comm_step=0; comm_step<n_adjacent_processors; comm_step++)
802 n_comm_steps[adjacent_processors[comm_step]]=1;
804 my_interface_node_xfer_buffers[comm_step],
805 send_requests[current_request++],
806 element_neighbors_tag);
817 adjacent_processors.clear();
819 std::vector<dof_id_type> common_interface_node_list;
834 for (
unsigned int comm_step=0; comm_step<3*n_adjacent_processors; comm_step++)
840 element_neighbors_tag));
842 source_pid_idx = cast_int<processor_id_type>(
status.source()),
843 dest_pid_idx = source_pid_idx;
847 if (n_comm_steps[source_pid_idx] == 1)
849 n_comm_steps[source_pid_idx]++;
852 common_interface_node_list,
853 element_neighbors_tag);
865 common_interface_node_list.erase
866 (std::set_intersection (my_interface_node_list.begin(),
867 my_interface_node_list.end(),
868 common_interface_node_list.begin(),
869 common_interface_node_list.end(),
870 common_interface_node_list.begin()),
871 common_interface_node_list.end());
899 if (common_interface_node_list.empty())
909 connected_nodes.begin(),
910 connected_nodes.end(),
911 send_requests[current_request++],
912 element_neighbors_tag);
916 elements_to_send.begin(),
917 elements_to_send.end(),
918 send_requests[current_request++],
919 element_neighbors_tag);
924 adjacent_processors.push_back(source_pid_idx);
928 for (
auto & elem : my_interface_elements)
930 std::size_t n_shared_nodes = 0;
933 if (std::binary_search (common_interface_node_list.begin(),
934 common_interface_node_list.end(),
942 if (n_shared_nodes > 0)
break;
951 if (!elements_to_send.count(elem))
953 #ifdef LIBMESH_ENABLE_AMR 962 elements_to_send.insert (elem);
965 connected_nodes.insert (&n);
976 libmesh_assert (connected_nodes.empty() || !elements_to_send.empty());
977 libmesh_assert (!connected_nodes.empty() || elements_to_send.empty());
982 connected_nodes.begin(),
983 connected_nodes.end(),
984 send_requests[current_request++],
985 element_neighbors_tag);
990 elements_to_send.begin(),
991 elements_to_send.end(),
992 send_requests[current_request++],
993 element_neighbors_tag);
998 else if (n_comm_steps[source_pid_idx] == 2)
1000 n_comm_steps[source_pid_idx]++;
1006 element_neighbors_tag);
1010 else if (n_comm_steps[source_pid_idx] == 3)
1012 n_comm_steps[source_pid_idx]++;
1018 element_neighbors_tag);
1024 libMesh::err <<
"ERROR: unexpected number of replies: " 1025 << n_comm_steps[source_pid_idx]
1031 Parallel::wait (send_requests);
1045 SyncNeighbors nsync(
mesh);
1050 #endif // LIBMESH_HAVE_MPI 1053 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings 1071 #ifndef LIBMESH_ENABLE_AMR 1072 libmesh_error_msg(
"Calling MeshCommunication::send_coarse_ghosts() requires AMR to be enabled. " 1073 "Please configure libmesh with --enable-amr.");
1082 typedef std::unordered_map<processor_id_type, std::vector<Elem *>> ghost_map;
1083 ghost_map coarsening_elements_to_ghost;
1098 if (their_proc_id != proc_id)
1099 coarsening_elements_to_ghost[their_proc_id].push_back(elem);
1102 std::map<processor_id_type, std::vector<const Node *>> all_nodes_to_send;
1103 std::map<processor_id_type, std::vector<const Elem *>> all_elems_to_send;
1113 std::set<const Node *> nodes_to_send;
1115 if (
const auto it = std::as_const(coarsening_elements_to_ghost).find(p);
1116 it != coarsening_elements_to_ghost.end())
1118 const std::vector<Elem *> & elems = it->second;
1123 Elem *
const * elempp =
const_cast<Elem *
const *
>(elems.data());
1124 Elem *
const * elemend = elempp+elems.size();
1135 (*gf)(elem_it, elem_end, p, elements_to_ghost);
1139 for (
auto & pr : elements_to_ghost)
1141 const Elem * elem = pr.first;
1146 elements_to_send.insert(elem);
1148 nodes_to_send.insert(&n);
1154 all_nodes_to_send[p].assign(nodes_to_send.begin(), nodes_to_send.end());
1155 all_elems_to_send[p].assign(elements_to_send.begin(), elements_to_send.end());
1160 auto null_node_action = [](
processor_id_type,
const std::vector<const Node*>&){};
1161 auto null_elem_action = [](
processor_id_type,
const std::vector<const Elem*>&){};
1170 #endif // LIBMESH_ENABLE_AMR 1173 #endif // LIBMESH_HAVE_MPI 1175 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings 1192 libmesh_parallel_only(
mesh.
comm());
1194 LOG_SCOPE(
"broadcast()",
"MeshCommunication");
1230 for (
unsigned int l=0; l !=
n_levels; ++l)
1232 mesh.level_elements_begin(l),
1233 mesh.level_elements_end(l),
1248 bool have_constraint_rows = !constraint_rows.empty();
1250 if (have_constraint_rows)
1253 std::vector<std::tuple<dof_id_type, unsigned int, Real>>>
1256 for (
auto & row : constraint_rows)
1258 const Node * node = row.first;
1262 std::vector<std::tuple<dof_id_type, unsigned int, Real>>
1264 for (
auto & entry : row.second)
1265 serialized_row.push_back
1266 (std::make_tuple(entry.first.first->id(),
1267 entry.first.second, entry.second));
1269 serialized_rows.emplace(rowid, std::move(serialized_row));
1275 constraint_rows.clear();
1277 for (
auto & row : serialized_rows)
1282 std::vector<std::pair<std::pair<const Elem *, unsigned int>,
Real>>
1284 for (
auto & entry : row.second)
1285 deserialized_row.push_back
1286 (std::make_pair(std::make_pair(
mesh.
elem_ptr(std::get<0>(entry)),
1287 std::get<1>(entry)),
1288 std::get<2>(entry)));
1290 constraint_rows.emplace(node, deserialized_row);
1308 MeshTools::libmesh_assert_valid_procids<Elem>(
mesh);
1309 MeshTools::libmesh_assert_valid_procids<Node>(
mesh);
1312 #endif // LIBMESH_HAVE_MPI 1316 #ifndef LIBMESH_HAVE_MPI // avoid spurious gcc warnings 1332 libmesh_parallel_only(
mesh.
comm());
1334 LOG_SCOPE(
"(all)gather()",
"MeshCommunication");
1337 static const std::size_t approx_total_buffer_size = 1e8;
1338 const std::size_t approx_each_buffer_size =
1347 approx_each_buffer_size) :
1354 approx_each_buffer_size);
1360 for (
unsigned int l=0; l !=
n_levels; ++l)
1364 mesh.level_elements_begin(l),
1365 mesh.level_elements_end(l),
1367 approx_each_buffer_size) :
1371 mesh.level_elements_begin(l),
1372 mesh.level_elements_end(l),
1374 approx_each_buffer_size);
1385 bool have_constraint_rows = !constraint_rows.empty();
1387 if (have_constraint_rows)
1390 std::vector<std::tuple<dof_id_type, unsigned int, Real>>>
1393 for (
auto & row : constraint_rows)
1395 const Node * node = row.first;
1399 std::vector<std::tuple<dof_id_type, unsigned int, Real>>
1401 for (
auto & entry : row.second)
1402 serialized_row.push_back
1403 (std::make_tuple(entry.first.first->id(),
1404 entry.first.second, entry.second));
1406 serialized_rows.emplace(rowid, std::move(serialized_row));
1417 for (
auto & row : serialized_rows)
1422 std::vector<std::pair<std::pair<const Elem *, unsigned int>,
Real>>
1424 for (
auto & entry : row.second)
1425 deserialized_row.push_back
1426 (std::make_pair(std::make_pair(
mesh.
elem_ptr(std::get<0>(entry)),
1427 std::get<1>(entry)),
1428 std::get<2>(entry)));
1430 constraint_rows.emplace(node, deserialized_row);
1459 #endif // LIBMESH_HAVE_MPI 1472 SyncIds(
MeshBase & _mesh, renumber_obj _renumberer) :
1482 void gather_data (
const std::vector<dof_id_type> & ids,
1483 std::vector<datum> & ids_out)
const 1488 void act_on_data (
const std::vector<dof_id_type> & old_ids,
1489 const std::vector<datum> & new_ids)
const 1492 if (old_ids[i] != new_ids[i])
1510 typedef std::unordered_set<const Node *> uset_type;
1516 typedef std::unordered_map<dof_id_type, dof_id_type> umap_type;
1524 void gather_data (
const std::vector<dof_id_type> & ids,
1525 std::vector<datum> & ids_out)
const 1540 bool act_on_data (
const std::vector<dof_id_type> & old_ids,
1541 const std::vector<datum> & new_ids)
1543 bool data_changed =
false;
1561 libmesh_assert_equal_to
1574 data_changed =
true;
1580 if (old_id != new_id)
1588 data_changed =
true;
1592 return data_changed;
1597 #ifdef LIBMESH_ENABLE_AMR 1600 typedef std::pair<unsigned char,unsigned char> datum;
1608 void gather_data (
const std::vector<dof_id_type> & ids,
1609 std::vector<datum> & ids_out)
const 1611 ids_out.reserve(ids.size());
1613 for (
const auto &
id : ids)
1617 (std::make_pair(cast_int<unsigned char>(elem.
p_level()),
1622 void act_on_data (
const std::vector<dof_id_type> & old_ids,
1623 const std::vector<datum> & new_p_levels)
const 1630 (new_p_levels[i].first,
1631 static_cast<Elem::RefinementState>(new_p_levels[i].second));
1637 #endif // LIBMESH_ENABLE_AMR 1640 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1641 template <
typename DofObjSub
class>
1642 struct SyncUniqueIds
1647 SyncUniqueIds(
MeshBase &_mesh, query_obj _querier) :
1656 void gather_data (
const std::vector<dof_id_type> & ids,
1657 std::vector<datum> & ids_out)
const 1659 ids_out.reserve(ids.size());
1661 for (
const auto &
id : ids)
1665 ids_out.push_back(d->unique_id());
1669 void act_on_data (
const std::vector<dof_id_type> & ids,
1670 const std::vector<datum> & unique_ids)
const 1674 DofObjSubclass * d = (
mesh.*
query)(ids[i]);
1676 d->set_unique_id(unique_ids[i]);
1680 #endif // LIBMESH_ENABLE_UNIQUE_ID 1682 template <
typename DofObjSub
class>
1685 typedef std::vector<boundary_id_type> datum;
1694 void gather_data (
const std::vector<dof_id_type> & ids,
1695 std::vector<datum> & ids_out)
const 1697 ids_out.reserve(ids.size());
1701 for (
const auto &
id : ids)
1705 std::vector<boundary_id_type> bcids;
1707 ids_out.push_back(std::move(bcids));
1711 void act_on_data (
const std::vector<dof_id_type> & ids,
1712 const std::vector<datum> & bcids)
const 1720 boundary_info.
add_node(n, bcids[i]);
1733 libmesh_parallel_only(
mesh.
comm());
1743 LOG_SCOPE (
"make_node_ids_parallel_consistent()",
"MeshCommunication");
1745 SyncNodeIds syncids(
mesh);
1765 libmesh_parallel_only(
mesh.
comm());
1767 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1768 LOG_SCOPE (
"make_node_unique_ids_parallel_consistent()",
"MeshCommunication");
1786 libmesh_parallel_only(
mesh.
comm());
1788 LOG_SCOPE (
"make_node_bcids_parallel_consistent()",
"MeshCommunication");
1790 SyncBCIds<Node> syncbcids(
mesh);
1805 libmesh_parallel_only(
mesh.
comm());
1807 LOG_SCOPE (
"make_elems_parallel_consistent()",
"MeshCommunication");
1811 (
mesh,
mesh.active_elements_begin(),
1812 mesh.active_elements_end(), syncids);
1814 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1818 mesh.active_elements_end(), syncuniqueids);
1825 #ifdef LIBMESH_ENABLE_AMR 1829 libmesh_parallel_only(
mesh.
comm());
1831 LOG_SCOPE (
"make_p_levels_parallel_consistent()",
"MeshCommunication");
1833 SyncPLevels syncplevels(
mesh);
1838 #endif // LIBMESH_ENABLE_AMR 1854 void gather_data (
const std::vector<dof_id_type> & ids,
1855 std::vector<datum> & data)
1858 data.resize(ids.size());
1876 bool act_on_data (
const std::vector<dof_id_type> & ids,
1877 const std::vector<datum> proc_ids)
1879 bool data_changed =
false;
1895 data_changed =
true;
1900 return data_changed;
1905 struct ElemNodesMaybeNew
1907 ElemNodesMaybeNew() {}
1909 bool operator() (
const Elem * elem)
const 1913 #ifdef LIBMESH_ENABLE_AMR 1933 for (
const auto & node :
mesh.node_ptr_range())
1938 bool operator() (
const Elem * elem,
unsigned int local_node_num)
const 1955 LOG_SCOPE (
"make_node_proc_ids_parallel_consistent()",
"MeshCommunication");
1958 libmesh_parallel_only(
mesh.
comm());
1973 SyncProcIds sync(
mesh);
1984 LOG_SCOPE (
"make_new_node_proc_ids_parallel_consistent()",
"MeshCommunication");
1987 libmesh_parallel_only(
mesh.
comm());
2016 auto node_unpartitioned =
2017 [](
const Elem * elem,
unsigned int local_node_num)
2021 SyncProcIds sync(
mesh);
2024 (
mesh,
mesh.not_local_elements_begin(),
2026 node_unpartitioned, sync);
2034 NodeWasNew node_was_new(
mesh);
2037 for (
auto & elem :
mesh.element_ptr_range())
2039 if (node_was_new.was_new.count(&node))
2048 ElemNodesMaybeNew(), node_was_new, sync);
2063 libmesh_parallel_only(
mesh.
comm());
2108 libmesh_parallel_only(
mesh.
comm());
2148 const std::set<Elem *> & extra_ghost_elem_ids)
const 2153 LOG_SCOPE(
"delete_remote_elements()",
"MeshCommunication");
2170 for (
const auto & elem : extra_ghost_elem_ids)
2172 std::vector<const Elem *> active_family;
2173 #ifdef LIBMESH_ENABLE_AMR 2178 active_family.push_back(elem);
2180 for (
const auto & f : active_family)
2181 elements_to_keep.insert(f);
2216 for (
int l =
n_levels - 1; l >= 0; --l)
2217 for (
auto & elem :
as_range(
mesh.level_elements_begin(l),
2218 mesh.level_elements_end(l)))
2222 const bool keep_me = elements_to_keep.count(elem);
2234 for (
auto & node :
mesh.node_ptr_range())
2237 if (!connected_nodes.count(node))
2253 gf->delete_remote_elements();
2257 libmesh_assert_equal_to(n_constraint_rows, n_new_constraint_rows);
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...
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
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...
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.
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true)=0
Locate element face (edge in 2D) neighbors.
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 const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
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)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
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...
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::set< GhostingFunctor * >::const_iterator ghosting_functors_begin() const
Beginning of range of ghosting functors.
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.
const DofMap &dof_map LIBMESH_COMMA unsigned int std::string & set_subdomain_name_map()
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
void connect_families(connected_elem_set_type &connected_elements, const MeshBase *mesh=nullptr)
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...
std::set< GhostingFunctor * >::const_iterator ghosting_functors_end() const
End of range of ghosting functors.
void set_union(T &data, const unsigned int root_id) const
const RemoteElem * remote_elem