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)
148 for (
const Node & node : elem->node_ref_range())
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)
281 for (
const auto & elem : new_connected_elements)
282 for (auto & n : elem->node_ref_range())
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);
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);
401std::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
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))
496 if (elem->processor_id() !=
mesh.processor_id())
497 send_to_pid[elem->processor_id()].push_back(elem);
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();
656#ifndef LIBMESH_HAVE_MPI
675 LOG_SCOPE(
"gather_neighboring_elements()",
"MeshCommunication");
721 std::vector<processor_id_type> adjacent_processors;
723 if (pid !=
mesh.processor_id())
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);
751 for (
auto s : elem->side_index_range())
752 if (elem->neighbor_ptr(s) == nullptr)
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);
946 for (
auto & n : elem->node_ref_range())
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]
1027 SyncNeighbors nsync(
mesh);
1035#ifndef LIBMESH_HAVE_MPI
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;
1069 for (
auto elem :
as_range(
mesh.flagged_pid_elements_begin(
Elem::COARSEN, proc_id),
1070 mesh.flagged_pid_elements_end(
Elem::COARSEN, proc_id)))
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();
1112 for (
auto & gf :
as_range(
mesh.ghosting_functors_begin(),
1113 mesh.ghosting_functors_end()))
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);
1129 for (
auto & n : elem->node_ref_range())
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*>&){};
1157#ifndef LIBMESH_HAVE_MPI
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);
1292 MeshTools::libmesh_assert_valid_procids<Elem>(
mesh);
1293 MeshTools::libmesh_assert_valid_procids<Node>(
mesh);
1300#ifndef LIBMESH_HAVE_MPI
1316 libmesh_parallel_only(
mesh.
comm());
1318 LOG_SCOPE(
"(all)gather()",
"MeshCommunication");
1321 static const std::size_t approx_total_buffer_size = 1e8;
1322 const std::size_t approx_each_buffer_size =
1331 approx_each_buffer_size) :
1333 mesh.comm().gather_packed_range (root_id,
1338 approx_each_buffer_size);
1344 for (
unsigned int l=0; l != n_levels; ++l)
1348 mesh.level_elements_begin(l),
1349 mesh.level_elements_end(l),
1351 approx_each_buffer_size) :
1355 mesh.level_elements_begin(l),
1356 mesh.level_elements_end(l),
1358 approx_each_buffer_size);
1369 bool have_constraint_rows = !constraint_rows.empty();
1371 if (have_constraint_rows)
1374 std::vector<std::tuple<dof_id_type, unsigned int, Real>>>
1377 for (
auto & row : constraint_rows)
1379 const Node * node = row.first;
1383 std::vector<std::tuple<dof_id_type, unsigned int, Real>>
1385 for (
auto & entry : row.second)
1386 serialized_row.push_back
1387 (
std::make_tuple(entry.first.first->id(),
1388 entry.first.second, entry.second));
1390 serialized_rows.emplace(rowid, std::move(serialized_row));
1401 for (
auto & row : serialized_rows)
1406 std::vector<std::pair<std::pair<const Elem *, unsigned int>,
Real>>
1408 for (
auto & entry : row.second)
1409 deserialized_row.push_back
1410 (
std::make_pair(
std::make_pair(
mesh.elem_ptr(
std::get<0>(entry)),
1411 std::get<1>(entry)),
1412 std::get<2>(entry)));
1414 constraint_rows.emplace(node, deserialized_row);
1456 SyncIds(
MeshBase & _mesh, renumber_obj _renumberer) :
1466 void gather_data (
const std::vector<dof_id_type> & ids,
1467 std::vector<datum> & ids_out)
const
1472 void act_on_data (
const std::vector<dof_id_type> & old_ids,
1473 const std::vector<datum> & new_ids)
const
1476 if (old_ids[i] != new_ids[i])
1494 typedef std::unordered_set<const Node *> uset_type;
1500 typedef std::unordered_map<dof_id_type, dof_id_type> umap_type;
1508 void gather_data (
const std::vector<dof_id_type> & ids,
1509 std::vector<datum> & ids_out)
const
1524 bool act_on_data (
const std::vector<dof_id_type> & old_ids,
1525 const std::vector<datum> & new_ids)
1527 bool data_changed =
false;
1545 libmesh_assert_equal_to
1546 (new_id, definitive_renumbering[old_id]);
1558 data_changed =
true;
1564 if (old_id != new_id)
1572 data_changed =
true;
1576 return data_changed;
1581#ifdef LIBMESH_ENABLE_AMR
1584 typedef std::pair<unsigned char,unsigned char> datum;
1592 void gather_data (
const std::vector<dof_id_type> & ids,
1593 std::vector<datum> & ids_out)
const
1595 ids_out.reserve(ids.size());
1597 for (
const auto &
id : ids)
1601 (std::make_pair(cast_int<unsigned char>(elem.
p_level()),
1606 void act_on_data (
const std::vector<dof_id_type> & old_ids,
1607 const std::vector<datum> & new_p_levels)
const
1614 (new_p_levels[i].first,
1624#ifdef LIBMESH_ENABLE_UNIQUE_ID
1625template <
typename DofObjSub
class>
1631 SyncUniqueIds(
MeshBase &_mesh, query_obj _querier) :
1640 void gather_data (
const std::vector<dof_id_type> & ids,
1641 std::vector<datum> & ids_out)
const
1643 ids_out.reserve(ids.size());
1645 for (
const auto &
id : ids)
1649 ids_out.push_back(d->unique_id());
1653 void act_on_data (
const std::vector<dof_id_type> & ids,
1654 const std::vector<datum> & unique_ids)
const
1658 DofObjSubclass * d = (
mesh.*
query)(ids[i]);
1660 d->set_unique_id(unique_ids[i]);
1666template <
typename DofObjSub
class>
1669 typedef std::vector<boundary_id_type> datum;
1678 void gather_data (
const std::vector<dof_id_type> & ids,
1679 std::vector<datum> & ids_out)
const
1681 ids_out.reserve(ids.size());
1685 for (
const auto &
id : ids)
1689 std::vector<boundary_id_type> bcids;
1691 ids_out.push_back(std::move(bcids));
1695 void act_on_data (
const std::vector<dof_id_type> & ids,
1696 const std::vector<datum> & bcids)
const
1704 boundary_info.
add_node(n, bcids[i]);
1717 libmesh_parallel_only(
mesh.
comm());
1727 LOG_SCOPE (
"make_node_ids_parallel_consistent()",
"MeshCommunication");
1729 SyncNodeIds syncids(
mesh);
1749 libmesh_parallel_only(
mesh.
comm());
1751#ifdef LIBMESH_ENABLE_UNIQUE_ID
1752 LOG_SCOPE (
"make_node_unique_ids_parallel_consistent()",
"MeshCommunication");
1770 libmesh_parallel_only(
mesh.
comm());
1772 LOG_SCOPE (
"make_node_bcids_parallel_consistent()",
"MeshCommunication");
1774 SyncBCIds<Node> syncbcids(
mesh);
1789 libmesh_parallel_only(
mesh.
comm());
1791 LOG_SCOPE (
"make_elems_parallel_consistent()",
"MeshCommunication");
1795 (
mesh,
mesh.active_elements_begin(),
1796 mesh.active_elements_end(), syncids);
1798#ifdef LIBMESH_ENABLE_UNIQUE_ID
1802 mesh.active_elements_end(), syncuniqueids);
1809#ifdef LIBMESH_ENABLE_AMR
1813 libmesh_parallel_only(
mesh.
comm());
1815 LOG_SCOPE (
"make_p_levels_parallel_consistent()",
"MeshCommunication");
1817 SyncPLevels syncplevels(
mesh);
1838 void gather_data (
const std::vector<dof_id_type> & ids,
1839 std::vector<datum> & data)
1842 data.resize(ids.size());
1860 bool act_on_data (
const std::vector<dof_id_type> & ids,
1861 const std::vector<datum> proc_ids)
1863 bool data_changed =
false;
1879 data_changed =
true;
1884 return data_changed;
1889struct ElemNodesMaybeNew
1891 ElemNodesMaybeNew() {}
1893 bool operator() (
const Elem * elem)
const
1897#ifdef LIBMESH_ENABLE_AMR
1905 for (
auto neigh : elem->neighbor_ptr_range())
1917 for (
const auto & node :
mesh.node_ptr_range())
1918 if (node->processor_id() ==
DofObject::invalid_processor_id)
1922 bool operator() (
const Elem * elem,
unsigned int local_node_num)
const
1939 LOG_SCOPE (
"make_node_proc_ids_parallel_consistent()",
"MeshCommunication");
1942 libmesh_parallel_only(
mesh.
comm());
1957 SyncProcIds sync(
mesh);
1968 LOG_SCOPE (
"make_new_node_proc_ids_parallel_consistent()",
"MeshCommunication");
1971 libmesh_parallel_only(
mesh.
comm());
2000 auto node_unpartitioned =
2001 [](
const Elem * elem,
unsigned int local_node_num)
2005 SyncProcIds sync(
mesh);
2007 sync_node_data_by_element_id_once
2008 (
mesh,
mesh.not_local_elements_begin(),
2010 node_unpartitioned, sync);
2018 NodeWasNew node_was_new(
mesh);
2021 for (
auto & elem :
mesh.element_ptr_range())
2023 if (node_was_new.was_new.count(&node))
2032 ElemNodesMaybeNew(), node_was_new, sync);
2047 libmesh_parallel_only(
mesh.
comm());
2092 libmesh_parallel_only(
mesh.
comm());
2132 const std::set<Elem *> & extra_ghost_elem_ids)
const
2137 LOG_SCOPE(
"delete_remote_elements()",
"MeshCommunication");
2154 for (
const auto & elem : extra_ghost_elem_ids)
2156 std::vector<const Elem *> active_family;
2157#ifdef LIBMESH_ENABLE_AMR
2162 active_family.push_back(elem);
2164 for (
const auto & f : active_family)
2165 elements_to_keep.insert(f);
2200 for (
int l = n_levels - 1; l >= 0; --l)
2201 for (
auto & elem :
as_range(
mesh.level_elements_begin(l),
2202 mesh.level_elements_end(l)))
2206 const bool keep_me = elements_to_keep.count(elem);
2218 for (
auto & node :
mesh.node_ptr_range())
2221 if (!connected_nodes.count(node))
2237 gf->delete_remote_elements();
2241 libmesh_assert_equal_to(n_constraint_rows, n_new_constraint_rows);
void max(const T &r, T &o, Request &req) const
void allgather_packed_range(Context *context, Iter range_begin, const Iter range_end, OutputIter out, std::size_t approx_buffer_size=1000000) const
processor_id_type size() 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
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
void receive_packed_range(const unsigned int dest_processor_id, Context *context, OutputIter out, const T *output_type, const MessageTag &tag=any_tag) const
status probe(const unsigned int src_processor_id, const MessageTag &tag=any_tag) const
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
timpi_pure bool verify(const T &r) const
void set_union(T &data, const unsigned int root_id) const
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
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
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
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
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< boundary_id_type, std::string > & set_sideset_name_map()
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
std::map< boundary_id_type, std::string > & set_nodeset_name_map()
The DistributedMesh class is derived from the MeshBase class, and is intended to provide identical fu...
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
processor_id_type processor_id() const
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
static constexpr processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Helper for building element sides that minimizes the construction of new elements.
This is the base class from which all geometric element types are derived.
void family_tree(std::vector< const Elem * > &family, bool reset=true) const
Fills the vector family with the children of this element, recursively.
RefinementState refinement_flag() const
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...
const Node & node_ref(const unsigned int i) const
bool has_children() const
const Elem * parent() const
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
unsigned int n_neighbors() const
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
RefinementState
Enumeration of possible element refinement states.
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
void make_links_to_me_remote()
Resets this element's neighbors' appropriate neighbor pointers and its parent's and children's approp...
const Node * node_ptr(const unsigned int i) const
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 Elem * interior_parent() const
unsigned int p_level() const
RefinementState p_refinement_flag() const
void set_p_level(const unsigned int p)
Sets the value of the p-refinement level for the element.
const Elem * neighbor_ptr(unsigned int i) const
const Elem * top_parent() const
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?
This is the MeshBase class.
virtual const Node & node_ref(const dof_id_type i) const
virtual bool is_serial() const
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...
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
virtual const Node * node_ptr(const dof_id_type i) const =0
virtual dof_id_type n_elem() const =0
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 allow_find_neighbors(bool allow)
If false is passed then this mesh will no longer work to find element neighbors when being prepared f...
virtual void delete_node(Node *n)=0
Removes the Node n from the mesh.
virtual dof_id_type n_nodes() const =0
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.
ElemMappingType default_mapping_type() const
Returns the default master space to physical space mapping basis functions to be used on newly added ...
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.
virtual dof_id_type max_node_id() const =0
virtual const Node * query_node_ptr(const dof_id_type i) const =0
std::vector< std::pair< std::pair< const Elem *, unsigned int >, Real > > constraint_rows_mapped_type
GhostingFunctorIterator ghosting_functors_begin() const
Beginning of range of ghosting functors.
virtual const Elem * elem_ptr(const dof_id_type i) const =0
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.
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 dof_id_type max_elem_id() const =0
virtual void clear()
Deletes all the element and node data that is currently stored.
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...
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
dof_id_type n_constraint_rows() const
virtual const Elem & elem_ref(const dof_id_type i) const
unsigned char default_mapping_data() const
Returns any default data value used by the master space to physical space mapping.
void clear_point_locator()
Releases the current PointLocator object.
GhostingFunctorIterator ghosting_functors_end() const
End of range of ghosting functors.
std::vector< std::string > _node_integer_names
The array of names for integer data associated with each node in the mesh.
std::map< subdomain_id_type, std::string > & set_subdomain_name_map()
virtual void update_parallel_id_counts()=0
Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors.
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 make_node_unique_ids_parallel_consistent(MeshBase &)
Assuming all unique_ids on local nodes are globally unique, and assuming all processor ids are parall...
void delete_remote_elements(DistributedMesh &, const std::set< Elem * > &) const
This method takes an input DistributedMesh which may be distributed among all the processors.
void clear()
Clears all data structures and resets to a pristine state.
void redistribute(DistributedMesh &mesh, bool newly_coarsened_only=false) const
This method takes a parallel distributed mesh and redistributes the elements.
void make_elems_parallel_consistent(MeshBase &)
Copy ids of ghost elements from their local processors.
void make_node_bcids_parallel_consistent(MeshBase &)
Assuming all processor ids are parallel consistent, this function makes all ghost boundary ids on nod...
void send_coarse_ghosts(MeshBase &) const
Examine a just-coarsened mesh, and for any newly-coarsened elements, send the associated ghosted elem...
void make_p_levels_parallel_consistent(MeshBase &)
Copy p levels of ghost elements from their local processors.
void make_node_ids_parallel_consistent(MeshBase &)
Assuming all ids on local nodes are globally unique, and assuming all processor ids are parallel cons...
void make_node_proc_ids_parallel_consistent(MeshBase &)
Assuming all processor ids on nodes touching local elements are parallel consistent,...
void make_nodes_parallel_consistent(MeshBase &)
Copy processor_ids and ids on ghost nodes from their local processors.
void gather_neighboring_elements(DistributedMesh &) const
void gather(const processor_id_type root_id, MeshBase &) const
This method takes an input DistributedMesh which may be distributed among all the processors.
void make_new_node_proc_ids_parallel_consistent(MeshBase &)
Assuming all processor ids on nodes touching local elements are parallel consistent,...
void make_new_nodes_parallel_consistent(MeshBase &)
Copy processor_ids and ids on new nodes from their local processors.
void broadcast(MeshBase &) const
This method takes a mesh (which is assumed to reside on processor 0) and broadcasts it to all the oth...
A Node is like a Point, but with more information.
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
In parallel meshes where a ghost element has neighbors which do not exist on the local processor,...
std::unordered_set< const Node * > was_new
umap_type definitive_renumbering
void push_parallel_vector_data(const Communicator &comm, MapToVectors &&data, const ActionFunctor &act_on_data)
const unsigned int any_source
void push_parallel_packed_range(const Communicator &comm, MapToContainers &&data, Context *context, const ActionFunctor &act_on_data)
void family_tree(T elem, std::vector< T > &family, bool reset=true)
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 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,...
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.
The libMesh namespace provides an interface to certain functionality in the library.
void reconnect_nodes(connected_elem_set_type &connected_elements, connected_node_set_type &connected_nodes)
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
std::set< const Elem *, CompareElemIdsByLevel > connected_elem_set_type
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)
void libmesh_ignore(const Args &...)
ElemMappingType
Enumeration of possible element master->physical mapping types.
const RemoteElem * remote_elem
std::set< const Node * > connected_node_set_type
void connect_element_dependencies(const MeshBase &mesh, connected_elem_set_type &connected_elements, connected_node_set_type &connected_nodes)
void connect_children(const MeshBase &mesh, MeshBase::const_element_iterator elem_it, MeshBase::const_element_iterator elem_end, connected_elem_set_type &connected_elements)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
uint8_t processor_id_type
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
The definition of the const_element_iterator struct.
Used to iterate over non-nullptr entries in a container.
A do-nothing class for templated methods that expect output iterator arguments.