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;