24 #include "libmesh/libmesh_config.h" 
   25 #include "libmesh/libmesh_logging.h" 
   26 #include "libmesh/boundary_info.h" 
   27 #include "libmesh/distributed_mesh.h" 
   28 #include "libmesh/elem.h" 
   29 #include "libmesh/mesh_communication.h" 
   30 #include "libmesh/mesh_serializer.h" 
   31 #include "libmesh/parallel.h" 
   32 #include "libmesh/partitioner.h" 
   33 #include "libmesh/remote_elem.h" 
   34 #include "libmesh/unstructured_mesh.h" 
   42 template <
class Key, 
class T, 
class Pred>
 
   43 void erase_if(std::multimap<Key,T> & map, Key k, 
Pred pred)
 
   45   auto rng = map.equal_range(k);
 
   47   while (it != rng.second)
 
   58 template <
class Key, 
class T, 
class Pred>
 
   59 void erase_if(std::multimap<Key,T> & map, 
Pred pred)
 
   61   auto it = map.begin();
 
   62   while (it != map.end())
 
  202   std::set<boundary_id_type> request_boundary_ids(
_boundary_ids);
 
  205     this->
comm().set_union(request_boundary_ids);
 
  207   this->
sync(request_boundary_ids,
 
  217   std::set<subdomain_id_type> subdomains_relative_to;
 
  220   this->
sync(requested_boundary_ids,
 
  222              subdomains_relative_to);
 
  229                          const std::set<subdomain_id_type> & subdomains_relative_to)
 
  231   LOG_SCOPE(
"sync()", 
"BoundaryInfo");
 
  233   boundary_mesh.
clear();
 
  258   std::map<dof_id_type, dof_id_type> node_id_map;
 
  259   std::map<std::pair<dof_id_type, unsigned char>, 
dof_id_type> side_id_map;
 
  261   this->
_find_id_maps(requested_boundary_ids, 0, &node_id_map, 0, &side_id_map, subdomains_relative_to);
 
  267       if (node_id_map.count(node_id))
 
  269           boundary_mesh.
add_point(*node, node_id_map[node_id], node->processor_id());
 
  272           std::vector<boundary_id_type> node_boundary_ids;
 
  274           for (
const auto & node_bid : node_boundary_ids)
 
  280   this->
add_elements (requested_boundary_ids, boundary_mesh, subdomains_relative_to);
 
  290       for (
auto nn : new_elem->node_index_range())
 
  294             boundary_mesh.
node_ptr(node_id_map[new_elem->node_id(nn)]);
 
  299           libmesh_assert_equal_to (new_node->
id(),
 
  300                                    node_id_map[new_elem->node_id(nn)]);
 
  303           new_elem->set_node(nn) = new_node;
 
  320                                            std::map<dof_id_type, dof_id_type> & node_id_map,
 
  321                                            std::map<dof_id_type, unsigned char> & side_id_map,
 
  324   LOG_SCOPE(
"get_side_and_node_maps()", 
"BoundaryInfo");
 
  330   std::unique_ptr<const Elem> interior_parent_side;
 
  338       unsigned char interior_parent_side_index = 0;
 
  339       bool found_matching_sides = 
false;
 
  343           Real centroid_distance = (boundary_elem->centroid() - interior_parent_side->centroid()).
norm();
 
  345           if (centroid_distance < (tolerance * boundary_elem->hmin()))
 
  347               interior_parent_side_index = cast_int<unsigned char>(side);
 
  348               found_matching_sides = 
true;
 
  353       if (!found_matching_sides)
 
  354         libmesh_error_msg(
"No matching side found within the specified tolerance");
 
  356       side_id_map[boundary_elem->id()] = interior_parent_side_index;
 
  358       for (
auto local_node_index : boundary_elem->node_index_range())
 
  360           dof_id_type boundary_node_id = boundary_elem->node_id(local_node_index);
 
  361           dof_id_type interior_node_id = interior_parent_side->node_id(local_node_index);
 
  363           node_id_map[interior_node_id] = boundary_node_id;
 
  374   std::set<subdomain_id_type> subdomains_relative_to;
 
  379                      subdomains_relative_to);
 
  386                                 const std::set<subdomain_id_type> & subdomains_relative_to)
 
  388   LOG_SCOPE(
"add_elements()", 
"BoundaryInfo");
 
  395   std::map<std::pair<dof_id_type, unsigned char>, 
dof_id_type> side_id_map;
 
  401                       subdomains_relative_to);
 
  407   typedef std::vector<std::pair<dof_id_type, unsigned char>>
 
  409   side_container sides_to_add;
 
  420           !subdomains_relative_to.count(elem->subdomain_id()))
 
  429       for (
auto s : elem->side_index_range())
 
  431           bool add_this_side = 
false;
 
  434           for (
const auto & pr : 
as_range(bounds))
 
  436               this_bcid = pr.second.second;
 
  440               if ((pr.second.first == s) &&
 
  441                   (requested_boundary_ids.count(this_bcid)))
 
  443                   add_this_side = 
true;
 
  454           if (bounds.first == bounds.second            &&
 
  456               elem->neighbor_ptr(s) == 
nullptr)
 
  457             add_this_side = 
true;
 
  460             sides_to_add.push_back(std::make_pair(elem->id(), s));
 
  464 #ifdef LIBMESH_ENABLE_UNIQUE_ID 
  468   for (
const auto & pr : sides_to_add)
 
  471       const unsigned char s = pr.second;
 
  481       const std::pair<dof_id_type, unsigned char> side_pair(elem_id, s);
 
  485       const dof_id_type new_side_id = side_id_map[side_pair];
 
  487       side->set_id(new_side_id);
 
  489 #ifdef LIBMESH_ENABLE_UNIQUE_ID 
  490       side->set_unique_id() = old_max_unique_id + new_side_id;
 
  494       Elem * new_elem = boundary_mesh.
add_elem(side.release());
 
  496 #ifdef LIBMESH_ENABLE_AMR 
  500           const std::pair<dof_id_type, unsigned char> parent_side_pair(elem->
parent()->
id(), s);
 
  504           Elem * side_parent = boundary_mesh.
elem_ptr(side_id_map[parent_side_pair]);
 
  517           bool found_child = 
false;
 
  519             if (new_elem->
node_ptr(v) == side_parent->node_ptr(v))
 
  521                 side_parent->add_child(new_elem, v);
 
  530               libmesh_assert_equal_to (new_elem->
n_vertices(), 3);
 
  531               side_parent->add_child(new_elem, 3);
 
  545           const unsigned short bdy_n_sides = new_elem->
n_sides();
 
  546           const unsigned short bdy_n_nodes = new_elem->
n_nodes();
 
  557               for (
unsigned short boundary_side = 0;
 
  558                    boundary_side != bdy_n_sides; ++boundary_side)
 
  562                   bool found_all_nodes = 
true;
 
  563                   for (
unsigned short boundary_node = 0;
 
  564                        boundary_node != bdy_n_nodes; ++boundary_node)
 
  570                       bool found_this_node = 
false;
 
  571                       for (
unsigned short interior_node = 0;
 
  572                            interior_node != 
n_nodes; ++interior_node)
 
  578                           if (new_elem->
point(boundary_node) ==
 
  579                               elem->
point(interior_node))
 
  581                               found_this_node = 
true;
 
  585                       if (!found_this_node)
 
  587                           found_all_nodes = 
false;
 
  611 # ifdef LIBMESH_HAVE_RTTI 
  612   DistributedMesh * parmesh = dynamic_cast<DistributedMesh *>(&boundary_mesh);
 
  629     libmesh_error_msg(
"BoundaryInfo::add_node(): Could not retrieve pointer for node " << node_id << 
", no boundary id was added.");
 
  640     libmesh_error_msg(
"ERROR: You may not set a boundary ID of "   \
 
  642                       << 
"\n That is reserved for internal use.");
 
  657                             const std::vector<boundary_id_type> & ids)
 
  672   std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
 
  673   std::sort(unique_ids.begin(), unique_ids.end());
 
  674   std::vector<boundary_id_type>::iterator new_end =
 
  675     std::unique(unique_ids.begin(), unique_ids.end());
 
  677   for (
auto & 
id : 
as_range(unique_ids.begin(), new_end))
 
  680         libmesh_error_msg(
"ERROR: You may not set a boundary ID of "    \
 
  682                           << 
"\n That is reserved for internal use.");
 
  684       bool already_inserted = 
false;
 
  685       for (
const auto & pr : 
as_range(bounds))
 
  688             already_inserted = 
true;
 
  691       if (already_inserted)
 
  708                             const unsigned short int edge,
 
  717                             const unsigned short int edge,
 
  723   libmesh_assert_equal_to (elem->
level(), 0);
 
  726     libmesh_error_msg(
"ERROR: You may not set a boundary ID of "        \
 
  728                       << 
"\n That is reserved for internal use.");
 
  732     if (pr.second.first == edge &&
 
  733         pr.second.second == 
id)
 
  744                             const unsigned short int edge,
 
  745                             const std::vector<boundary_id_type> & ids)
 
  753   libmesh_assert_equal_to (elem->
level(), 0);
 
  763   std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
 
  764   std::sort(unique_ids.begin(), unique_ids.end());
 
  765   std::vector<boundary_id_type>::iterator new_end =
 
  766     std::unique(unique_ids.begin(), unique_ids.end());
 
  768   for (
auto & 
id : 
as_range(unique_ids.begin(), new_end))
 
  771         libmesh_error_msg(
"ERROR: You may not set a boundary ID of "   \
 
  773                           << 
"\n That is reserved for internal use.");
 
  775       bool already_inserted = 
false;
 
  776       for (
const auto & pr : 
as_range(bounds))
 
  777         if (pr.second.first == edge &&
 
  778             pr.second.second == 
id)
 
  780             already_inserted = 
true;
 
  783       if (already_inserted)
 
  795                                  const unsigned short int shellface,
 
  804                                  const unsigned short int shellface,
 
  810   libmesh_assert_equal_to (elem->
level(), 0);
 
  813   libmesh_assert_less(shellface, 2);
 
  816     libmesh_error_msg(
"ERROR: You may not set a boundary ID of "        \
 
  818                       << 
"\n That is reserved for internal use.");
 
  822     if (pr.second.first == shellface &&
 
  823         pr.second.second == 
id)
 
  834                                  const unsigned short int shellface,
 
  835                                  const std::vector<boundary_id_type> & ids)
 
  843   libmesh_assert_equal_to (elem->
level(), 0);
 
  846   libmesh_assert_less(shellface, 2);
 
  856   std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
 
  857   std::sort(unique_ids.begin(), unique_ids.end());
 
  858   std::vector<boundary_id_type>::iterator new_end =
 
  859     std::unique(unique_ids.begin(), unique_ids.end());
 
  861   for (
auto & 
id : 
as_range(unique_ids.begin(), new_end))
 
  864         libmesh_error_msg(
"ERROR: You may not set a boundary ID of "   \
 
  866                           << 
"\n That is reserved for internal use.");
 
  868       bool already_inserted = 
false;
 
  869       for (
const auto & pr : 
as_range(bounds))
 
  870         if (pr.second.first == shellface &&
 
  871             pr.second.second == 
id)
 
  873             already_inserted = 
true;
 
  876       if (already_inserted)
 
  887                             const unsigned short int side,
 
  896                             const unsigned short int side,
 
  902   libmesh_assert_equal_to (elem->
level(), 0);
 
  905     libmesh_error_msg(
"ERROR: You may not set a boundary ID of "        \
 
  907                       << 
"\n That is reserved for internal use.");
 
  911     if (pr.second.first == side &&
 
  912         pr.second.second == 
id)
 
  923                             const unsigned short int side,
 
  924                             const std::vector<boundary_id_type> & ids)
 
  932   libmesh_assert_equal_to (elem->
level(), 0);
 
  942   std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
 
  943   std::sort(unique_ids.begin(), unique_ids.end());
 
  944   std::vector<boundary_id_type>::iterator new_end =
 
  945     std::unique(unique_ids.begin(), unique_ids.end());
 
  947   for (
auto & 
id : 
as_range(unique_ids.begin(), new_end))
 
  950         libmesh_error_msg(
"ERROR: You may not set a boundary ID of "    \
 
  952                           << 
"\n That is reserved for internal use.");
 
  954       bool already_inserted = 
false;
 
  955       for (
const auto & pr : 
as_range(bounds))
 
  956         if (pr.second.first == side && pr.second.second == 
id)
 
  958             already_inserted = 
true;
 
  961       if (already_inserted)
 
  984 #ifdef LIBMESH_ENABLE_DEPRECATED 
  987   libmesh_deprecated();
 
  989   std::vector<boundary_id_type> ids;
 
  998                                  std::vector<boundary_id_type> & vec_to_fill)
 const 
 1001   vec_to_fill.clear();
 
 1004     vec_to_fill.push_back(pr.second);
 
 1012   return cast_int<unsigned int>(
std::distance(pos.first, pos.second));
 
 1017 #ifdef LIBMESH_ENABLE_DEPRECATED 
 1019                                                                const unsigned short int edge)
 const 
 1021   libmesh_deprecated();
 
 1023   std::vector<boundary_id_type> ids;
 
 1032                                       const unsigned short int edge,
 
 1033                                       std::vector<boundary_id_type> & vec_to_fill)
 const 
 1038   vec_to_fill.clear();
 
 1042   const Elem * searched_elem = elem;
 
 1043 #ifdef LIBMESH_ENABLE_AMR 
 1044   if (elem->
level() != 0)
 
 1049       bool found_boundary_edge = 
false;
 
 1057                   found_boundary_edge = 
true;
 
 1063       if (!found_boundary_edge)
 
 1069           while (searched_elem->
parent() != 
nullptr)
 
 1071               const Elem * parent = searched_elem->
parent();
 
 1074               searched_elem = parent;
 
 1082     if (pr.second.first == edge)
 
 1083       vec_to_fill.push_back(pr.second.second);
 
 1089                                                 const unsigned short int edge)
 const 
 1091   std::vector<boundary_id_type> ids;
 
 1093   return cast_int<unsigned int>(ids.size());
 
 1098 #ifdef LIBMESH_ENABLE_DEPRECATED 
 1100                                                                    const unsigned short int edge)
 const 
 1102   libmesh_deprecated();
 
 1104   std::vector<boundary_id_type> ids;
 
 1113                                           const unsigned short int edge,
 
 1114                                           std::vector<boundary_id_type> & vec_to_fill)
 const 
 1119   vec_to_fill.clear();
 
 1127     if (pr.second.first == edge)
 
 1128       vec_to_fill.push_back(pr.second.second);
 
 1134                                            const unsigned short int shellface,
 
 1135                                            std::vector<boundary_id_type> & vec_to_fill)
 const 
 1140   libmesh_assert_less(shellface, 2);
 
 1143   vec_to_fill.clear();
 
 1147   const Elem * searched_elem = elem;
 
 1148 #ifdef LIBMESH_ENABLE_AMR 
 1149   if (elem->
level() != 0)
 
 1151       while (searched_elem->
parent() != 
nullptr)
 
 1153           const Elem * parent = searched_elem->
parent();
 
 1154           searched_elem = parent;
 
 1161     if (pr.second.first == shellface)
 
 1162       vec_to_fill.push_back(pr.second.second);
 
 1168                                                      const unsigned short int shellface)
 const 
 1170   std::vector<boundary_id_type> ids;
 
 1172   return cast_int<unsigned int>(ids.size());
 
 1178                                                const unsigned short int shellface,
 
 1179                                                std::vector<boundary_id_type> & vec_to_fill)
 const 
 1184   libmesh_assert_less(shellface, 2);
 
 1187   vec_to_fill.clear();
 
 1195     if (pr.second.first == shellface)
 
 1196       vec_to_fill.push_back(pr.second.second);
 
 1200 #ifdef LIBMESH_ENABLE_DEPRECATED 
 1202                                            const unsigned short int side)
 const 
 1204   libmesh_deprecated();
 
 1206   std::vector<boundary_id_type> ids;
 
 1215   return *(ids.begin());
 
 1222                                    const unsigned short int side,
 
 1225   std::vector<boundary_id_type> ids;
 
 1227   return (std::find(ids.begin(), ids.end(), id) != ids.end());
 
 1232 #ifdef LIBMESH_ENABLE_DEPRECATED 
 1234                                                           const unsigned short int side)
 const 
 1236   libmesh_deprecated();
 
 1238   std::vector<boundary_id_type> ids;
 
 1247                                  const unsigned short int side,
 
 1248                                  std::vector<boundary_id_type> & vec_to_fill)
 const 
 1253   vec_to_fill.clear();
 
 1257   const Elem * searched_elem = elem;
 
 1258   if (elem->
level() != 0)
 
 1262 #ifdef LIBMESH_ENABLE_AMR 
 1264         while (searched_elem->
parent() != 
nullptr)
 
 1266             const Elem * parent = searched_elem->
parent();
 
 1269             searched_elem = parent;
 
 1276     if (pr.second.first == side)
 
 1277       vec_to_fill.push_back(pr.second.second);
 
 1284                                            const unsigned short int side)
 const 
 1286   std::vector<boundary_id_type> ids;
 
 1288   return cast_int<unsigned int>(ids.size());
 
 1293 #ifdef LIBMESH_ENABLE_DEPRECATED 
 1295                                                               const unsigned short int side)
 const 
 1297   libmesh_deprecated();
 
 1299   std::vector<boundary_id_type> ids;
 
 1308                                      const unsigned short int side,
 
 1309                                      std::vector<boundary_id_type> & vec_to_fill)
 const 
 1314   vec_to_fill.clear();
 
 1322     if (pr.second.first == side)
 
 1323       vec_to_fill.push_back(pr.second.second);
 
 1329                                       const Elem * 
const old_elem,
 
 1330                                       const Elem * 
const new_elem)
 
 1332   libmesh_assert_equal_to (old_elem->
n_sides(), new_elem->
n_sides());
 
 1333   libmesh_assert_equal_to (old_elem->
n_edges(), new_elem->
n_edges());
 
 1335   std::vector<boundary_id_type> bndry_ids;
 
 1340       this->
add_side (new_elem, s, bndry_ids);
 
 1346       this->
add_edge (new_elem, e, bndry_ids);
 
 1349   for (
unsigned short sf=0; sf != 2; sf++)
 
 1376            {
return val == id;});
 
 1394                                 const unsigned short int edge)
 
 1399   libmesh_assert_equal_to (elem->
level(), 0);
 
 1404            {
return pr.first == edge;});
 
 1410                                 const unsigned short int edge,
 
 1416   libmesh_assert_equal_to (elem->
level(), 0);
 
 1421            {
return pr.first == edge && pr.second == id;});
 
 1426                                      const unsigned short int shellface)
 
 1431   libmesh_assert_equal_to (elem->
level(), 0);
 
 1434   libmesh_assert_less(shellface, 2);
 
 1439            {
return pr.first == shellface;});
 
 1445                                      const unsigned short int shellface,
 
 1451   libmesh_assert_equal_to (elem->
level(), 0);
 
 1454   libmesh_assert_less(shellface, 2);
 
 1459            {
return pr.first == shellface && pr.second == id;});
 
 1463                                 const unsigned short int side)
 
 1468   libmesh_assert_equal_to (elem->
level(), 0);
 
 1473            {
return pr.first == side;});
 
 1479                                 const unsigned short int side,
 
 1487            {
return pr.first == side && pr.second == id;});
 
 1507            {
return val == id;});
 
 1512            {
return pr.second == id;});
 
 1517            {
return pr.second == id;});
 
 1522            {
return pr.second == id;});
 
 1530   const Elem * searched_elem = elem;
 
 1531   if (elem->
level() != 0)
 
 1539       if (pr.second.second == boundary_id_in)
 
 1541           unsigned int side = pr.second.first;
 
 1550           const Elem * p = elem;
 
 1552 #ifdef LIBMESH_ENABLE_AMR 
 1554           while (p != 
nullptr)
 
 1582       if (std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
 
 1583         b_ids.push_back(
id);
 
 1596       if (std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
 
 1597         b_ids.push_back(
id);
 
 1610       if (std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
 
 1611         b_ids.push_back(
id);
 
 1623   parallel_object_only();
 
 1631   this->
comm().sum (nbcs);
 
 1644   parallel_object_only();
 
 1646   std::size_t n_edge_bcs=0;
 
 1652   this->
comm().sum (n_edge_bcs);
 
 1666   parallel_object_only();
 
 1668   std::size_t n_shellface_bcs=0;
 
 1674   this->
comm().sum (n_shellface_bcs);
 
 1676   return n_shellface_bcs;
 
 1688   parallel_object_only();
 
 1690   std::size_t n_nodesets=0;
 
 1696   this->
comm().sum (n_nodesets);
 
 1703 #ifdef LIBMESH_ENABLE_DEPRECATED 
 1705                                     std::vector<boundary_id_type> & il)
 const 
 1707   libmesh_deprecated();
 
 1718   nl.reserve (bc_tuples.size());
 
 1719   il.reserve (bc_tuples.size());
 
 1721   for (
const auto & t : bc_tuples)
 
 1723       nl.push_back(std::get<0>(t));
 
 1724       il.push_back(std::get<1>(t));
 
 1730 std::vector<std::tuple<dof_id_type, boundary_id_type>>
 
 1733   std::vector<std::tuple<dof_id_type, boundary_id_type>> bc_tuples;
 
 1737     bc_tuples.emplace_back(pr.first->id(), pr.second);
 
 1741   std::sort(bc_tuples.begin(), bc_tuples.end());
 
 1756   typedef std::set<std::pair<dof_id_type, boundary_id_type>> set_type;
 
 1760   std::vector<set_type> nodes_to_push(n_proc);
 
 1763   std::unique_ptr<const Elem> side;
 
 1769       if (pr.first->is_remote())
 
 1773       std::vector<const Elem *> family;
 
 1774 #ifdef LIBMESH_ENABLE_AMR 
 1775       pr.first->active_family_tree_by_side (family, pr.second.first);
 
 1777       family.push_back(pr.first);
 
 1780       for (
const auto & cur_elem : family)
 
 1782           cur_elem->build_side_ptr(side, pr.second.first);
 
 1785           for (
auto i : side->node_index_range())
 
 1788               this->
add_node(side->node_ptr(i), bcid);
 
 1789               if (!mesh_is_serial)
 
 1792                     side->node_ptr(i)->processor_id();
 
 1793                   if (proc_id != my_proc_id)
 
 1794                     nodes_to_push[proc_id].insert
 
 1795                       (std::make_pair(side->node_id(i), bcid));
 
 1807   Parallel::MessageTag
 
 1808     node_pushes_tag = this->
comm().get_unique_tag(),
 
 1809     node_pulls_tag = this->
comm().get_unique_tag(),
 
 1810     node_responses_tag = this->
comm().get_unique_tag();
 
 1812   std::vector<Parallel::Request> node_push_requests(n_proc-1);
 
 1816       if (p == my_proc_id)
 
 1819       Parallel::Request &request =
 
 1820         node_push_requests[p - (p > my_proc_id)];
 
 1823         (p, nodes_to_push[p], request, node_pushes_tag);
 
 1828       set_type received_nodes;
 
 1830       this->
comm().receive
 
 1831         (Parallel::any_source, received_nodes, node_pushes_tag);
 
 1833       for (
const auto & pr : received_nodes)
 
 1842   std::vector<std::vector<dof_id_type>> node_ids_requested(n_proc);
 
 1848       if (pid != my_proc_id)
 
 1849         node_ids_requested[pid].push_back(node->id());
 
 1852   typedef std::vector<std::pair<dof_id_type, boundary_id_type>> vec_type;
 
 1854   std::vector<Parallel::Request>
 
 1855     node_pull_requests(n_proc-1),
 
 1856     node_response_requests(n_proc-1);
 
 1861       if (p == my_proc_id)
 
 1864       Parallel::Request &request =
 
 1865         node_pull_requests[p - (p > my_proc_id)];
 
 1868         (p, node_ids_requested[p], request, node_pulls_tag);
 
 1872   std::vector<vec_type> responses(n_proc-1);
 
 1876       std::vector<dof_id_type> requested_nodes;
 
 1879         status(this->
comm().probe (Parallel::any_source, node_pulls_tag));
 
 1881         source_pid = cast_int<processor_id_type>(status.source());
 
 1883       this->
comm().receive
 
 1884         (source_pid, requested_nodes, node_pulls_tag);
 
 1886       Parallel::Request &request =
 
 1887         node_response_requests[p-1];
 
 1889       std::vector<boundary_id_type> bcids;
 
 1891       for (
const auto & 
id : requested_nodes)
 
 1895           for (
const auto & b : bcids)
 
 1896             responses[p-1].push_back(std::make_pair(
id, b));
 
 1900         (source_pid, responses[p-1], request, node_responses_tag);
 
 1907         status(this->
comm().probe (Parallel::any_source, node_responses_tag));
 
 1909         source_pid = cast_int<processor_id_type>(status.source());
 
 1913       this->
comm().receive
 
 1914         (source_pid, response, node_responses_tag);
 
 1916       for (
const auto & pr : response)
 
 1920   Parallel::wait (node_push_requests);
 
 1921   Parallel::wait (node_pull_requests);
 
 1922   Parallel::wait (node_response_requests);
 
 1933       libMesh::out << 
"No boundary node IDs have been added: cannot build side list!" << std::endl;
 
 1938   std::unique_ptr<const Elem> side_elem;
 
 1941     for (
auto side : elem->side_index_range())
 
 1943         elem->build_side_ptr(side_elem, side);
 
 1946         std::map<boundary_id_type, unsigned> nodesets_node_count;
 
 1950         for (
const auto & node : side_elem->node_ref_range())
 
 1952             nodesets_node_count[pr.second]++;
 
 1958         for (
const auto & pr : nodesets_node_count)
 
 1959           if (pr.second == side_elem->n_nodes())
 
 1966               if (nset_name != 
"")
 
 1975 #ifdef LIBMESH_ENABLE_DEPRECATED 
 1977                                     std::vector<unsigned short int> & sl,
 
 1978                                     std::vector<boundary_id_type> & il)
 const 
 1980   libmesh_deprecated();
 
 1992   el.reserve (bc_tuples.size());
 
 1993   sl.reserve (bc_tuples.size());
 
 1994   il.reserve (bc_tuples.size());
 
 1996   for (
const auto & t : bc_tuples)
 
 1998       el.push_back(std::get<0>(t));
 
 1999       sl.push_back(std::get<1>(t));
 
 2000       il.push_back(std::get<2>(t));
 
 2006 std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>>
 
 2009   std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>> bc_triples;
 
 2013     bc_triples.emplace_back(pr.first->id(), pr.second.first, pr.second.second);
 
 2019   std::sort(bc_triples.begin(), bc_triples.end());
 
 2026 #ifdef LIBMESH_ENABLE_DEPRECATED 
 2028                                            std::vector<unsigned short int> & sl,
 
 2029                                            std::vector<boundary_id_type> & il)
 const 
 2031   libmesh_deprecated();
 
 2043   el.reserve (bc_tuples.size());
 
 2044   sl.reserve (bc_tuples.size());
 
 2045   il.reserve (bc_tuples.size());
 
 2047   for (
const auto & t : bc_tuples)
 
 2049       el.push_back(std::get<0>(t));
 
 2050       sl.push_back(std::get<1>(t));
 
 2051       il.push_back(std::get<2>(t));
 
 2057 std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>>
 
 2060   std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>> bc_triples;
 
 2066       if (pr.first->is_remote())
 
 2070       std::vector<const Elem *> family;
 
 2071 #ifdef LIBMESH_ENABLE_AMR 
 2072       pr.first->active_family_tree_by_side(family, pr.second.first);
 
 2074       family.push_back(pr.first);
 
 2078       for (
const auto & elem : family)
 
 2079         bc_triples.emplace_back(elem->id(), pr.second.first, pr.second.second);
 
 2084   std::sort(bc_triples.begin(), bc_triples.end());
 
 2090 #ifdef LIBMESH_ENABLE_DEPRECATED 
 2092                                     std::vector<unsigned short int> & sl,
 
 2093                                     std::vector<boundary_id_type> & il)
 const 
 2095   libmesh_deprecated();
 
 2107   el.reserve (bc_tuples.size());
 
 2108   sl.reserve (bc_tuples.size());
 
 2109   il.reserve (bc_tuples.size());
 
 2111   for (
const auto & t : bc_tuples)
 
 2113       el.push_back(std::get<0>(t));
 
 2114       sl.push_back(std::get<1>(t));
 
 2115       il.push_back(std::get<2>(t));
 
 2121 std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>>
 
 2124   std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>> bc_triples;
 
 2128     bc_triples.emplace_back(pr.first->id(), pr.second.first, pr.second.second);
 
 2132   std::sort(bc_triples.begin(), bc_triples.end());
 
 2138 #ifdef LIBMESH_ENABLE_DEPRECATED 
 2140                                          std::vector<unsigned short int> & sl,
 
 2141                                          std::vector<boundary_id_type> & il)
 const 
 2143   libmesh_deprecated();
 
 2155   el.reserve (bc_tuples.size());
 
 2156   sl.reserve (bc_tuples.size());
 
 2157   il.reserve (bc_tuples.size());
 
 2159   for (
const auto & t : bc_tuples)
 
 2161       el.push_back(std::get<0>(t));
 
 2162       sl.push_back(std::get<1>(t));
 
 2163       il.push_back(std::get<2>(t));
 
 2169 std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>>
 
 2172   std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>> bc_triples;
 
 2176     bc_triples.emplace_back(pr.first->id(), pr.second.first, pr.second.second);
 
 2180   std::sort(bc_triples.begin(), bc_triples.end());
 
 2191       out_stream << 
"Nodal Boundary conditions:" << std::endl
 
 2192                  << 
"--------------------------" << std::endl
 
 2193                  << 
"  (Node No., ID)               " << std::endl;
 
 2196         out_stream << 
"  (" << pr.first->id()
 
 2197                    << 
", "  << pr.second
 
 2198                    << 
")"  << std::endl;
 
 2204       out_stream << std::endl
 
 2205                  << 
"Edge Boundary conditions:" << std::endl
 
 2206                  << 
"-------------------------" << std::endl
 
 2207                  << 
"  (Elem No., Edge No., ID)      " << std::endl;
 
 2210         out_stream << 
"  (" << pr.first->id()
 
 2211                    << 
", "  << pr.second.first
 
 2212                    << 
", "  << pr.second.second
 
 2213                    << 
")"   << std::endl;
 
 2219       out_stream << std::endl
 
 2220                  << 
"Shell-face Boundary conditions:" << std::endl
 
 2221                  << 
"-------------------------" << std::endl
 
 2222                  << 
"  (Elem No., Shell-face No., ID)      " << std::endl;
 
 2225         out_stream << 
"  (" << pr.first->id()
 
 2226                    << 
", "  << pr.second.first
 
 2227                    << 
", "  << pr.second.second
 
 2228                    << 
")"   << std::endl;
 
 2234       out_stream << std::endl
 
 2235                  << 
"Side Boundary conditions:" << std::endl
 
 2236                  << 
"-------------------------" << std::endl
 
 2237                  << 
"  (Elem No., Side No., ID)      " << std::endl;
 
 2240         out_stream << 
"  (" << pr.first->id()
 
 2241                    << 
", "  << pr.second.first
 
 2242                    << 
", "  << pr.second.second
 
 2243                    << 
")"   << std::endl;
 
 2254       out_stream << 
"Nodal Boundary conditions:" << std::endl
 
 2255                  << 
"--------------------------" << std::endl
 
 2256                  << 
"  (ID, number of nodes)   " << std::endl;
 
 2258       std::map<boundary_id_type, std::size_t> ID_counts;
 
 2261         ID_counts[pr.second]++;
 
 2263       for (
const auto & pr : ID_counts)
 
 2264         out_stream << 
"  (" << pr.first
 
 2265                    << 
", "  << pr.second
 
 2266                    << 
")"  << std::endl;
 
 2272       out_stream << std::endl
 
 2273                  << 
"Edge Boundary conditions:" << std::endl
 
 2274                  << 
"-------------------------" << std::endl
 
 2275                  << 
"  (ID, number of edges)   " << std::endl;
 
 2277       std::map<boundary_id_type, std::size_t> ID_counts;
 
 2280         ID_counts[pr.second.second]++;
 
 2282       for (
const auto & pr : ID_counts)
 
 2283         out_stream << 
"  (" << pr.first
 
 2284                    << 
", "  << pr.second
 
 2285                    << 
")"  << std::endl;
 
 2292       out_stream << std::endl
 
 2293                  << 
"Shell-face Boundary conditions:" << std::endl
 
 2294                  << 
"-------------------------" << std::endl
 
 2295                  << 
"  (ID, number of shellfaces)   " << std::endl;
 
 2297       std::map<boundary_id_type, std::size_t> ID_counts;
 
 2300         ID_counts[pr.second.second]++;
 
 2302       for (
const auto & pr : ID_counts)
 
 2303         out_stream << 
"  (" << pr.first
 
 2304                    << 
", "  << pr.second
 
 2305                    << 
")"  << std::endl;
 
 2311       out_stream << std::endl
 
 2312                  << 
"Side Boundary conditions:" << std::endl
 
 2313                  << 
"-------------------------" << std::endl
 
 2314                  << 
"  (ID, number of sides)   " << std::endl;
 
 2316       std::map<boundary_id_type, std::size_t> ID_counts;
 
 2319         ID_counts[pr.second.second]++;
 
 2321       for (
const auto & pr : ID_counts)
 
 2322         out_stream << 
"  (" << pr.first
 
 2323                    << 
", "  << pr.second
 
 2324                    << 
")"  << std::endl;
 
 2331   static const std::string empty_string;
 
 2332   std::map<boundary_id_type, std::string>::const_iterator it =
 
 2335     return empty_string;
 
 2348   static const std::string empty_string;
 
 2349   std::map<boundary_id_type, std::string>::const_iterator it =
 
 2352     return empty_string;
 
 2364   static const std::string empty_string;
 
 2365   std::map<boundary_id_type, std::string>::const_iterator it =
 
 2368     return empty_string;
 
 2383     if (pr.second == 
name)
 
 2388     if (pr.second == 
name)
 
 2393     if (pr.second == 
name)
 
 2405                                  std::map<dof_id_type, dof_id_type> * node_id_map,
 
 2407                                  std::map<std::pair<dof_id_type, unsigned char>, 
dof_id_type> * side_id_map,
 
 2408                                  const std::set<subdomain_id_type> & subdomains_relative_to)
 
 2413     next_node_id = first_free_node_id + this->
processor_id(),
 
 2414     next_elem_id = first_free_elem_id + this->
processor_id();
 
 2417   std::unique_ptr<const Elem> side;
 
 2430   bool hit_end_el = 
false;
 
 2435        !hit_end_el || (el != end_unpartitioned_el); ++el)
 
 2437       if ((el == end_el) && !hit_end_el)
 
 2445             this->
comm().set_union(*side_id_map);
 
 2447             this->
comm().set_union(*node_id_map);
 
 2451           next_node_id = first_free_node_id + this->
n_processors();
 
 2452           next_elem_id = first_free_elem_id + this->
n_processors();
 
 2455           if (el == end_unpartitioned_el)
 
 2459       const Elem * elem = *el;
 
 2480           bool add_this_side = 
false;
 
 2483           for (
const auto & pr : 
as_range(bounds))
 
 2485               this_bcid = pr.second.second;
 
 2489               if ((pr.second.first == s) &&
 
 2490                   (requested_boundary_ids.count(this_bcid)))
 
 2492                   add_this_side = 
true;
 
 2503           if (bounds.first == bounds.second            &&
 
 2506             add_this_side = 
true;
 
 2517                   std::pair<dof_id_type, unsigned char> side_pair(elem->
id(), s);
 
 2519                   (*side_id_map)[side_pair] = next_elem_id;
 
 2524               for (
auto n : side->node_index_range())
 
 2526                   const Node & node = side->node_ref(n);
 
 2535                   if (node_id_map && !node_id_map->count(node_id))
 
 2537                       (*node_id_map)[node_id] = next_node_id;