21 #include "libmesh/libmesh_config.h" 22 #include "libmesh/libmesh_logging.h" 23 #include "libmesh/boundary_info.h" 24 #include "libmesh/distributed_mesh.h" 25 #include "libmesh/elem.h" 26 #include "libmesh/mesh_communication.h" 27 #include "libmesh/mesh_serializer.h" 28 #include "libmesh/parallel.h" 29 #include "libmesh/partitioner.h" 30 #include "libmesh/remote_elem.h" 31 #include "libmesh/unstructured_mesh.h" 32 #include "libmesh/elem_side_builder.h" 47 template <
class Key,
class T,
class Pred>
48 void erase_if(std::multimap<Key,T> & map, Key k, Pred pred)
50 auto rng = map.equal_range(k);
52 while (it != rng.second)
63 template <
class Key,
class T,
class Pred>
64 void erase_if(std::multimap<Key,T> & map, Pred pred)
66 auto it = map.begin();
67 while (it != map.end())
77 template <
typename Map,
typename T>
78 void renumber_name(Map & m, T old_id, T new_id)
80 if (
const auto it = std::as_const(m).find(old_id);
83 m[new_id] = it->second;
106 _children_on_boundary(false)
168 const Node * other_node =
176 auto compare_edges = [&](
const Elem * elem,
177 const Elem * other_elem,
178 unsigned short int edge)
185 std::vector<boundary_id_type> our_edges, other_edges;
188 if (our_edges.size() != other_edges.size())
191 std::sort(our_edges.begin(), our_edges.end());
192 std::sort(other_edges.begin(), other_edges.end());
194 if (our_edges[i] != other_edges[i])
199 for (
const auto & [other_elem, edge_id_pair] : other_boundary_info.
_boundary_edge_id)
202 if (!compare_edges(elem, other_elem, edge_id_pair.first))
209 if (!compare_edges(elem, other_elem, edge_id_pair.first))
213 auto compare_sides = [&](
const Elem * elem,
214 const Elem * other_elem,
215 unsigned short int side)
222 std::vector<boundary_id_type> our_sides, other_sides;
224 other_boundary_info.
boundary_ids(other_elem, side, other_sides);
225 if (our_sides.size() != other_sides.size())
228 std::sort(our_sides.begin(), our_sides.end());
229 std::sort(other_sides.begin(), other_sides.end());
231 if (our_sides[i] != other_sides[i])
236 for (
const auto & [other_elem, side_id_pair] : other_boundary_info.
_boundary_side_id)
239 if (!compare_sides(elem, other_elem, side_id_pair.first))
246 if (!compare_sides(elem, other_elem, side_id_pair.first))
250 auto compare_shellfaces = [&](
const Elem * elem,
251 const Elem * other_elem,
252 unsigned short int shellface)
259 std::vector<boundary_id_type> our_shellfaces, other_shellfaces;
262 if (our_shellfaces.size() != other_shellfaces.size())
265 std::sort(our_shellfaces.begin(), our_shellfaces.end());
266 std::sort(other_shellfaces.begin(), other_shellfaces.end());
268 if (our_shellfaces[i] != other_shellfaces[i])
276 if (!compare_shellfaces(elem, other_elem, shellface_id_pair.first))
283 if (!compare_shellfaces(elem, other_elem, shellface_id_pair.first))
290 auto compare_sets = [](
const auto & set1,
const auto & set2)
292 if (set1.size() != set2.size())
295 if (!set2.count(bid))
315 auto compare_maps = [](
const auto & map1,
const auto & map2)
317 if (map1.size() != map2.size())
319 for (
const auto & pair : map1)
320 if (!map2.count(pair.first) ||
321 map2.at(pair.first) != pair.second)
383 if (
const auto it = old_ns_id_to_name.find(
id);
384 it != old_ns_id_to_name.end())
393 if (
const auto it = old_es_id_to_name.find(
id);
394 it != old_es_id_to_name.end())
403 if (
const auto it = old_ss_id_to_name.find(
id);
404 it != old_ss_id_to_name.end())
442 std::set<boundary_id_type> request_boundary_ids(
_boundary_ids);
447 this->
sync(request_boundary_ids,
457 std::set<subdomain_id_type> subdomains_relative_to;
460 this->
sync(requested_boundary_ids,
462 subdomains_relative_to);
469 const std::set<subdomain_id_type> & subdomains_relative_to)
471 LOG_SCOPE(
"sync()",
"BoundaryInfo");
473 boundary_mesh.
clear();
500 std::unique_ptr<MeshBase> mesh_copy;
504 auto serializer = std::make_unique<MeshSerializer>
513 std::map<dof_id_type, dof_id_type> node_id_map;
514 std::map<std::pair<dof_id_type, unsigned char>,
dof_id_type> side_id_map;
516 this->
_find_id_maps(requested_boundary_ids, 0, &node_id_map, 0, &side_id_map, subdomains_relative_to);
519 for (
const auto & node :
_mesh->node_ptr_range())
522 if (node_id_map.count(node_id))
524 boundary_mesh.
add_point(*node, node_id_map[node_id], node->processor_id());
527 std::vector<boundary_id_type> node_boundary_ids;
529 for (
const auto & node_bid : node_boundary_ids)
539 subdomains_relative_to,
548 for (
auto & new_elem : boundary_mesh.element_ptr_range())
550 for (
auto nn : new_elem->node_index_range())
554 boundary_mesh.
node_ptr(node_id_map[new_elem->node_id(nn)]);
559 libmesh_assert_equal_to (new_node->
id(),
560 node_id_map[new_elem->node_id(nn)]);
563 new_elem->set_node(nn, new_node);
572 for (
auto & new_elem : boundary_mesh.element_ptr_range())
575 new_elem->interior_parent()->id();
577 if (!mesh_copy->query_elem_ptr(interior_parent_id))
578 new_elem->set_interior_parent
601 std::map<dof_id_type, dof_id_type> & node_id_map,
602 std::map<dof_id_type, unsigned char> & side_id_map,
605 LOG_SCOPE(
"get_side_and_node_maps()",
"BoundaryInfo");
613 const Elem * interior_parent_side;
615 for (
const auto & boundary_elem : boundary_mesh.active_element_ptr_range())
621 unsigned char interior_parent_side_index = 0;
622 bool found_matching_sides =
false;
625 interior_parent_side = &side_builder(*interior_parent, side);
628 if (va_distance < (tolerance * boundary_elem->hmin()))
630 interior_parent_side_index = cast_int<unsigned char>(side);
631 found_matching_sides =
true;
636 libmesh_error_msg_if(!found_matching_sides,
"No matching side found within the specified tolerance");
638 side_id_map[boundary_elem->id()] = interior_parent_side_index;
640 for (
auto local_node_index : boundary_elem->node_index_range())
642 dof_id_type boundary_node_id = boundary_elem->node_id(local_node_index);
645 node_id_map[interior_node_id] = boundary_node_id;
654 bool store_parent_side_ids)
657 std::set<subdomain_id_type> subdomains_relative_to;
662 subdomains_relative_to,
663 store_parent_side_ids);
670 const std::set<subdomain_id_type> & subdomains_relative_to,
671 bool store_parent_side_ids)
673 LOG_SCOPE(
"add_elements()",
"BoundaryInfo");
692 std::map<std::pair<dof_id_type, unsigned char>,
dof_id_type> side_id_map;
698 subdomains_relative_to);
704 typedef std::vector<std::pair<dof_id_type, unsigned char>>
706 side_container sides_to_add;
708 for (
const auto & elem :
_mesh->element_ptr_range())
717 !subdomains_relative_to.count(elem->subdomain_id()))
720 for (
auto s : elem->side_index_range())
722 bool add_this_side =
false;
725 std::vector<boundary_id_type> bcids;
731 if (requested_boundary_ids.count(bcid))
733 add_this_side =
true;
744 if (requested_boundary_ids.count(
invalid_id) &&
745 elem->neighbor_ptr(s) ==
nullptr)
746 add_this_side =
true;
749 sides_to_add.emplace_back(elem->id(), s);
753 #ifdef LIBMESH_ENABLE_UNIQUE_ID 760 unsigned int parent_side_index_tag = store_parent_side_ids ?
763 for (
const auto & [elem_id, s] : sides_to_add)
771 const std::pair<dof_id_type, unsigned char> side_pair(elem_id, s);
775 const dof_id_type new_side_id = side_id_map[side_pair];
777 side->set_id(new_side_id);
779 #ifdef LIBMESH_ENABLE_UNIQUE_ID 780 side->set_unique_id(old_max_unique_id + new_side_id);
784 Elem * new_elem = boundary_mesh.
add_elem(std::move(side));
788 if (store_parent_side_ids)
791 #ifdef LIBMESH_ENABLE_AMR 798 const std::pair<dof_id_type, unsigned char> parent_side_pair(elem->
parent()->
id(), s);
802 Elem * side_parent = boundary_mesh.
elem_ptr(side_id_map[parent_side_pair]);
813 bool found_child =
false;
815 if (new_elem->
node_ptr(v) == side_parent->node_ptr(v))
817 side_parent->add_child(new_elem, v);
826 libmesh_assert_equal_to (new_elem->
n_vertices(), 3);
827 side_parent->add_child(new_elem, 3);
857 const unsigned short bdy_n_sides = new_elem->
n_sides();
858 const unsigned short bdy_n_nodes = new_elem->
n_nodes();
869 for (
unsigned short boundary_side = 0;
870 boundary_side != bdy_n_sides; ++boundary_side)
874 bool found_all_nodes =
true;
875 for (
unsigned short boundary_node = 0;
876 boundary_node != bdy_n_nodes; ++boundary_node)
882 bool found_this_node =
false;
883 for (
unsigned short interior_node = 0;
884 interior_node !=
n_nodes; ++interior_node)
890 if (new_elem->
point(boundary_node) ==
891 elem->
point(interior_node))
893 found_this_node =
true;
897 if (!found_this_node)
899 found_all_nodes =
false;
924 # ifdef LIBMESH_HAVE_RTTI 941 libmesh_error_msg_if(!node_ptr,
942 "BoundaryInfo::add_node(): Could not retrieve pointer for node " 944 <<
", no boundary id was added.");
955 "ERROR: You may not set a boundary ID of " 957 <<
"\n That is reserved for internal use.");
972 const std::vector<boundary_id_type> & ids)
987 std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
988 std::sort(unique_ids.begin(), unique_ids.end());
989 std::vector<boundary_id_type>::iterator new_end =
990 std::unique(unique_ids.begin(), unique_ids.end());
992 for (
auto &
id :
as_range(unique_ids.begin(), new_end))
995 "ERROR: You may not set a boundary ID of " 997 <<
"\n That is reserved for internal use.");
999 bool already_inserted =
false;
1000 for (
const auto & pr :
as_range(bounds))
1001 if (pr.second ==
id)
1003 already_inserted =
true;
1006 if (already_inserted)
1023 const unsigned short int edge,
1032 const unsigned short int edge,
1038 libmesh_assert_equal_to (elem->
level(), 0);
1041 libmesh_assert_less (edge, elem->
n_edges());
1044 "ERROR: You may not set a boundary ID of " 1046 <<
"\n That is reserved for internal use.");
1050 if (pr.second.first == edge &&
1051 pr.second.second ==
id)
1062 const unsigned short int edge,
1063 const std::vector<boundary_id_type> & ids)
1071 libmesh_assert_equal_to (elem->
level(), 0);
1074 libmesh_assert_less (edge, elem->
n_edges());
1084 std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
1085 std::sort(unique_ids.begin(), unique_ids.end());
1086 std::vector<boundary_id_type>::iterator new_end =
1087 std::unique(unique_ids.begin(), unique_ids.end());
1089 for (
auto &
id :
as_range(unique_ids.begin(), new_end))
1092 "ERROR: You may not set a boundary ID of " 1094 <<
"\n That is reserved for internal use.");
1096 bool already_inserted =
false;
1097 for (
const auto & pr :
as_range(bounds))
1098 if (pr.second.first == edge &&
1099 pr.second.second ==
id)
1101 already_inserted =
true;
1104 if (already_inserted)
1116 const unsigned short int shellface,
1125 const unsigned short int shellface,
1131 libmesh_assert_equal_to (elem->
level(), 0);
1134 libmesh_assert_less(shellface, 2);
1137 "ERROR: You may not set a boundary ID of " 1139 <<
"\n That is reserved for internal use.");
1143 if (pr.second.first == shellface &&
1144 pr.second.second ==
id)
1155 const unsigned short int shellface,
1156 const std::vector<boundary_id_type> & ids)
1164 libmesh_assert_equal_to (elem->
level(), 0);
1167 libmesh_assert_less(shellface, 2);
1177 std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
1178 std::sort(unique_ids.begin(), unique_ids.end());
1179 std::vector<boundary_id_type>::iterator new_end =
1180 std::unique(unique_ids.begin(), unique_ids.end());
1182 for (
auto &
id :
as_range(unique_ids.begin(), new_end))
1185 "ERROR: You may not set a boundary ID of " 1187 <<
"\n That is reserved for internal use.");
1189 bool already_inserted =
false;
1190 for (
const auto & pr :
as_range(bounds))
1191 if (pr.second.first == shellface &&
1192 pr.second.second ==
id)
1194 already_inserted =
true;
1197 if (already_inserted)
1208 const unsigned short int side,
1217 const unsigned short int side,
1223 libmesh_assert_less (side, elem->
n_sides());
1225 libmesh_error_msg_if(
id ==
invalid_id,
"ERROR: You may not set a boundary ID of " 1227 <<
"\n That is reserved for internal use.");
1231 if (pr.second.first == side &&
1232 pr.second.second ==
id)
1235 #ifdef LIBMESH_ENABLE_AMR 1245 std::vector<boundary_id_type> bd_ids;
1248 if(std::find(bd_ids.begin(), bd_ids.end(), id) != bd_ids.end())
1249 libmesh_not_implemented_msg(
"Trying to add boundary ID " 1250 + std::to_string(
id)
1251 +
" which already exists on the ancestors.");
1263 const unsigned short int side,
1264 const std::vector<boundary_id_type> & ids)
1272 libmesh_assert_less (side, elem->
n_sides());
1274 #ifdef LIBMESH_ENABLE_AMR 1284 std::vector<boundary_id_type> bd_ids;
1287 for (
const auto id : ids)
1288 if(std::find(bd_ids.begin(), bd_ids.end(), id) != bd_ids.end())
1289 libmesh_not_implemented_msg(
"Trying to add boundary ID " 1290 + std::to_string(
id)
1291 +
" which already exists on the ancestors.");
1303 std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
1304 std::sort(unique_ids.begin(), unique_ids.end());
1305 std::vector<boundary_id_type>::iterator new_end =
1306 std::unique(unique_ids.begin(), unique_ids.end());
1308 for (
auto &
id :
as_range(unique_ids.begin(), new_end))
1311 "ERROR: You may not set a boundary ID of " 1313 <<
"\n That is reserved for internal use.");
1315 bool already_inserted =
false;
1316 for (
const auto & pr :
as_range(bounds))
1317 if (pr.second.first == side && pr.second.second ==
id)
1319 already_inserted =
true;
1322 if (already_inserted)
1337 if (pr.second ==
id)
1346 std::vector<boundary_id_type> & vec_to_fill)
const 1349 vec_to_fill.clear();
1352 vec_to_fill.push_back(pr.second);
1360 return cast_int<unsigned int>(
std::distance(pos.first, pos.second));
1366 const unsigned short int edge,
1367 std::vector<boundary_id_type> & vec_to_fill)
const 1372 vec_to_fill.clear();
1375 libmesh_assert_less (edge, elem->
n_edges());
1379 const Elem * searched_elem = elem;
1380 #ifdef LIBMESH_ENABLE_AMR 1381 if (elem->
level() != 0)
1386 bool found_boundary_edge =
false;
1394 found_boundary_edge =
true;
1400 if (!found_boundary_edge)
1406 while (searched_elem->parent() !=
nullptr)
1408 const Elem * parent = searched_elem->
parent();
1411 searched_elem = parent;
1419 if (pr.second.first == edge)
1420 vec_to_fill.push_back(pr.second.second);
1426 const unsigned short int edge)
const 1428 std::vector<boundary_id_type> ids;
1430 return cast_int<unsigned int>(ids.size());
1436 const unsigned short int edge,
1437 std::vector<boundary_id_type> & vec_to_fill)
const 1442 libmesh_assert_less (edge, elem->
n_edges());
1445 vec_to_fill.clear();
1453 if (pr.second.first == edge)
1454 vec_to_fill.push_back(pr.second.second);
1460 const unsigned short int shellface,
1461 std::vector<boundary_id_type> & vec_to_fill)
const 1466 libmesh_assert_less(shellface, 2);
1469 vec_to_fill.clear();
1473 const Elem * searched_elem = elem;
1474 #ifdef LIBMESH_ENABLE_AMR 1475 if (elem->
level() != 0)
1477 while (searched_elem->
parent() !=
nullptr)
1479 const Elem * parent = searched_elem->
parent();
1480 searched_elem = parent;
1487 if (pr.second.first == shellface)
1488 vec_to_fill.push_back(pr.second.second);
1494 const unsigned short int shellface)
const 1496 std::vector<boundary_id_type> ids;
1498 return cast_int<unsigned int>(ids.size());
1504 const unsigned short int shellface,
1505 std::vector<boundary_id_type> & vec_to_fill)
const 1510 libmesh_assert_less(shellface, 2);
1513 vec_to_fill.clear();
1521 if (pr.second.first == shellface)
1522 vec_to_fill.push_back(pr.second.second);
1528 const unsigned short int side,
1531 std::vector<boundary_id_type> ids;
1533 return (std::find(ids.begin(), ids.end(), id) != ids.end());
1538 std::vector<std::vector<boundary_id_type>> & vec_to_fill)
const 1543 vec_to_fill.clear();
1545 vec_to_fill.resize(elem->
n_sides());
1551 const Elem * searched_elem = elem;
1553 #ifdef LIBMESH_ENABLE_AMR 1554 if (elem->
level() != 0)
1561 std::vector<bool> search_on_side(elem->
n_sides(),
true);
1562 bool keep_searching =
true;
1563 while (searched_elem && keep_searching)
1569 if (search_on_side[side] && pr.second.first == side &&
1570 std::find(vec_to_fill[side].begin(), vec_to_fill[side].end(), pr.second.second) ==
1571 vec_to_fill[side].end())
1572 vec_to_fill[side].push_back(pr.second.second);
1575 const Elem * parent = searched_elem->
parent();
1580 if (search_on_side[side] &&
1582 search_on_side[side] =
false;
1584 searched_elem = parent;
1586 keep_searching = *std::max_element(search_on_side.begin(), search_on_side.end());
1595 std::vector<bool> search_on_side(elem->
n_sides(),
true);
1604 while (searched_elem->
parent() !=
nullptr)
1606 const Elem * parent = searched_elem->
parent();
1608 search_on_side[side] =
false;
1609 searched_elem = parent;
1613 if (*std::max_element(search_on_side.begin(), search_on_side.end()))
1615 if (search_on_side[pr.second.first])
1616 vec_to_fill[pr.second.first].push_back(pr.second.second);
1623 vec_to_fill[pr.second.first].push_back(pr.second.second);
1627 const unsigned short int side,
1628 std::vector<boundary_id_type> & vec_to_fill)
const 1633 libmesh_assert_less (side, elem->
n_sides());
1636 vec_to_fill.clear();
1642 const Elem * searched_elem = elem;
1644 #ifdef LIBMESH_ENABLE_AMR 1646 if (elem->
level() != 0)
1653 while (searched_elem)
1657 if (pr.second.first == side &&
1658 std::find(vec_to_fill.begin(), vec_to_fill.end(), pr.second.second) ==
1660 vec_to_fill.push_back(pr.second.second);
1663 const Elem * parent = searched_elem->
parent();
1669 searched_elem = parent;
1681 while (searched_elem->
parent() !=
nullptr)
1683 const Elem * parent = searched_elem->
parent();
1687 searched_elem = parent;
1695 if (pr.second.first == side)
1696 vec_to_fill.push_back(pr.second.second);
1703 const unsigned short int side)
const 1705 std::vector<boundary_id_type> ids;
1707 return cast_int<unsigned int>(ids.size());
1712 const unsigned short int side)
const 1714 std::vector<boundary_id_type> ids;
1716 return cast_int<unsigned int>(ids.size());
1722 const unsigned short int side,
1723 std::vector<boundary_id_type> & vec_to_fill)
const 1728 libmesh_assert_less (side, elem->
n_sides());
1731 vec_to_fill.clear();
1739 if (pr.second.first == side)
1740 vec_to_fill.push_back(pr.second.second);
1746 const Elem *
const old_elem,
1747 const Elem *
const new_elem)
1749 libmesh_assert_equal_to (old_elem->
n_sides(), new_elem->
n_sides());
1750 libmesh_assert_equal_to (old_elem->
n_edges(), new_elem->
n_edges());
1752 std::vector<boundary_id_type> bndry_ids;
1757 this->
add_side (new_elem, s, bndry_ids);
1763 this->
add_edge (new_elem, e, bndry_ids);
1766 for (
unsigned short sf=0; sf != 2; sf++)
1793 {
return val == id;});
1811 const unsigned short int edge)
1816 libmesh_assert_less (edge, elem->
n_edges());
1819 libmesh_assert_equal_to (elem->
level(), 0);
1824 {
return pr.first == edge;});
1830 const unsigned short int edge,
1836 libmesh_assert_less (edge, elem->
n_edges());
1839 libmesh_assert_equal_to (elem->
level(), 0);
1844 {
return pr.first == edge && pr.second == id;});
1849 const unsigned short int shellface)
1854 libmesh_assert_equal_to (elem->
level(), 0);
1857 libmesh_assert_less(shellface, 2);
1862 {
return pr.first == shellface;});
1868 const unsigned short int shellface,
1874 libmesh_assert_equal_to (elem->
level(), 0);
1877 libmesh_assert_less(shellface, 2);
1882 {
return pr.first == shellface && pr.second == id;});
1886 const unsigned short int side)
1891 libmesh_assert_less (side, elem->
n_sides());
1896 {
return pr.first == side;});
1902 const unsigned short int side,
1908 libmesh_assert_less (side, elem->
n_sides());
1910 #ifdef LIBMESH_ENABLE_AMR 1915 std::vector<boundary_id_type> bd_ids;
1917 if(std::find(bd_ids.begin(), bd_ids.end(), id) != bd_ids.end())
1919 std::vector<boundary_id_type> raw_bd_ids;
1921 if(std::find(raw_bd_ids.begin(), raw_bd_ids.end(), id) == raw_bd_ids.end())
1922 libmesh_not_implemented_msg(
"We cannot delete boundary ID " 1923 + std::to_string(
id) +
1924 " using a child because it is inherited from an ancestor.");
1932 {
return pr.first == side && pr.second == id;});
1966 this->
comm().
max(someone_has_it);
1967 if (!someone_has_it)
1974 {
return pr.second == id;});
1993 this->
comm().
max(someone_has_it);
1994 if (!someone_has_it)
2001 {
return pr.second == id;});
2019 this->
comm().
max(someone_has_it);
2020 if (!someone_has_it)
2027 {
return pr.second == id;});
2045 this->
comm().
max(someone_has_it);
2046 if (!someone_has_it)
2053 {
return val == id;});
2061 if (old_id == new_id)
2067 bool found_node =
false;
2069 if (p.second == old_id)
2083 bool found_edge =
false;
2085 if (p.second.second == old_id)
2089 this->
remove_edge(p.first, p.second.first, new_id);
2090 p.second.second = new_id;
2099 bool found_shellface =
false;
2101 if (p.second.second == old_id)
2106 p.second.second = new_id;
2107 found_shellface =
true;
2109 if (found_shellface)
2115 bool found_side =
false;
2117 if (p.second.second == old_id)
2121 this->
remove_side(p.first, p.second.first, new_id);
2122 p.second.second = new_id;
2131 if (found_node || found_edge || found_shellface || found_side)
2150 if (old_id == new_id)
2153 bool found_side =
false;
2155 if (p.second.second == old_id)
2159 this->
remove_side(p.first, p.second.first, new_id);
2160 p.second.second = new_id;
2189 if (old_id == new_id)
2192 bool found_edge =
false;
2194 if (p.second.second == old_id)
2198 this->
remove_edge(p.first, p.second.first, new_id);
2199 p.second.second = new_id;
2228 if (old_id == new_id)
2231 bool found_shellface =
false;
2233 if (p.second.second == old_id)
2238 p.second.second = new_id;
2239 found_shellface =
true;
2243 if (found_shellface)
2265 if (old_id == new_id)
2268 bool found_node =
false;
2270 if (p.second == old_id)
2303 const Elem * searched_elem = elem;
2315 if (pr.second.second == boundary_id_in)
2317 unsigned int side = pr.second.first;
2330 const Elem * p = elem;
2332 #ifdef LIBMESH_ENABLE_AMR 2334 while (p !=
nullptr)
2353 #ifdef LIBMESH_ENABLE_AMR 2361 const Elem * p = elem;
2362 while (p->
parent() !=
nullptr)
2373 if (pr.second.first == side && pr.second.second == boundary_id_in)
2392 std::vector<unsigned int>
2396 std::vector<unsigned int> returnval;
2398 const Elem * searched_elem = elem;
2407 if (pr.second.second == boundary_id_in)
2409 unsigned int side = pr.second.first;
2419 returnval.push_back(side);
2425 const Elem * p = elem;
2427 #ifdef LIBMESH_ENABLE_AMR 2429 while (p !=
nullptr)
2439 returnval.push_back(side);
2443 returnval.push_back(side);
2447 #ifdef LIBMESH_ENABLE_AMR 2454 const Elem * p = elem;
2455 while (p->
parent() !=
nullptr)
2468 if (pr.second.first == side && pr.second.second == boundary_id_in &&
2469 std::find(returnval.begin(), returnval.end(), side) == returnval.end())
2470 returnval.push_back(side);
2494 if (std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
2495 b_ids.push_back(
id);
2508 if (std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
2509 b_ids.push_back(
id);
2522 if (std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
2523 b_ids.push_back(
id);
2527 #ifdef LIBMESH_ENABLE_AMR 2540 const double number_of_sides_on_children =
std::pow(2, parent->
dim()-1);
2544 for (
unsigned int side_i = 0; side_i < parent->
n_sides(); ++side_i)
2549 std::map<unsigned short int, unsigned short int> boundary_counts;
2560 if (pr.second.first == side_i)
2561 ++boundary_counts[pr.second.second];
2568 for (
const auto & boundary : boundary_counts)
2569 if (boundary.second / number_of_sides_on_children > 0.5)
2570 this->
add_side(parent, side_i, boundary.first);
2574 this->
remove(parent->
child_ptr(child_i));
2586 parallel_object_only();
2607 parallel_object_only();
2609 std::size_t n_edge_bcs=0;
2615 this->
comm().
sum (n_edge_bcs);
2629 parallel_object_only();
2631 std::size_t n_shellface_bcs=0;
2637 this->
comm().
sum (n_shellface_bcs);
2639 return n_shellface_bcs;
2651 parallel_object_only();
2653 std::size_t n_nodesets=0;
2659 this->
comm().
sum (n_nodesets);
2666 #ifdef LIBMESH_ENABLE_DEPRECATED 2668 std::vector<boundary_id_type> & il)
const 2670 libmesh_deprecated();
2681 nl.reserve (bc_tuples.size());
2682 il.reserve (bc_tuples.size());
2684 for (
const auto & t : bc_tuples)
2686 nl.push_back(std::get<0>(t));
2687 il.push_back(std::get<1>(t));
2693 std::vector<BoundaryInfo::NodeBCTuple>
2696 std::vector<NodeBCTuple> bc_tuples;
2700 bc_tuples.emplace_back(node->id(), bid);
2705 std::sort(bc_tuples.begin(), bc_tuples.end());
2707 std::sort(bc_tuples.begin(), bc_tuples.end(),
2709 {
return std::get<1>(left) < std::get<1>(right);});
2724 typedef std::set<std::pair<dof_id_type, boundary_id_type>> set_type;
2725 typedef std::vector<std::pair<dof_id_type, boundary_id_type>> vec_type;
2728 std::unordered_map<processor_id_type, set_type> nodes_to_push;
2729 std::unordered_map<processor_id_type, vec_type> node_vecs_to_push;
2740 if (elem->is_remote())
2743 auto [sidenum, bcid] = id_pair;
2745 if (!sideset_list.empty() && !sideset_list.count(bcid))
2749 std::vector<const Elem *> family;
2750 #ifdef LIBMESH_ENABLE_AMR 2753 family.push_back(elem);
2756 for (
const auto & cur_elem : family)
2758 side = &side_builder(*cur_elem, sidenum);
2764 if (!mesh_is_serial)
2768 if (proc_id != my_proc_id)
2769 nodes_to_push[proc_id].emplace(side->
node_id(i), bcid);
2782 for (
auto & [proc_id, s] : nodes_to_push)
2784 node_vecs_to_push[proc_id].assign(s.begin(), s.end());
2788 auto nodes_action_functor =
2791 const vec_type & received_nodes)
2793 for (
const auto & [dof_id, bndry_id] : received_nodes)
2797 Parallel::push_parallel_vector_data
2798 (this->
comm(), node_vecs_to_push, nodes_action_functor);
2802 std::unordered_map<processor_id_type, std::vector<dof_id_type>>
2806 for (
const auto & node :
_mesh->node_ptr_range())
2809 if (pid != my_proc_id)
2810 node_ids_requested[pid].push_back(node->id());
2813 typedef std::vector<boundary_id_type> datum_type;
2815 auto node_bcid_gather_functor =
2818 const std::vector<dof_id_type> & ids,
2819 std::vector<datum_type> & data)
2821 const std::size_t query_size = ids.size();
2822 data.resize(query_size);
2824 for (std::size_t i=0; i != query_size; ++i)
2828 auto node_bcid_action_functor =
2831 const std::vector<dof_id_type> & ids,
2832 const std::vector<datum_type> & data)
2838 datum_type * datum_type_ex =
nullptr;
2839 Parallel::pull_parallel_vector_data
2840 (this->
comm(), node_ids_requested, node_bcid_gather_functor,
2841 node_bcid_action_functor, datum_type_ex);
2847 std::unordered_map<processor_id_type, std::vector<dof_id_type>>
2851 for (
const auto & elem :
_mesh->element_ptr_range())
2855 elem_ids_requested[pid].push_back(elem->id());
2858 typedef std::vector<std::pair<unsigned short int, boundary_id_type>> datum_type;
2861 auto elem_id_gather_functor =
2864 const std::vector<dof_id_type> & ids,
2865 std::vector<datum_type> & data)
2867 data.resize(ids.size());
2872 data[i].push_back(std::make_pair(pr.second.first, pr.second.second));
2876 auto elem_id_action_functor =
2879 const std::vector<dof_id_type> & ids,
2880 std::vector<datum_type> & data)
2888 for (
const auto & [
side_id, bndry_id] : data[i])
2894 datum_type * datum_type_ex =
nullptr;
2895 Parallel::pull_parallel_vector_data
2896 (this->
comm(), elem_ids_requested, elem_id_gather_functor,
2897 elem_id_action_functor, datum_type_ex);
2903 std::unordered_map<processor_id_type, std::vector<dof_id_type>>
2907 for (
const auto & node :
_mesh->node_ptr_range())
2911 node_ids_requested[pid].push_back(node->id());
2914 typedef std::vector<boundary_id_type> datum_type;
2917 auto node_id_gather_functor =
2920 const std::vector<dof_id_type> & ids,
2921 std::vector<datum_type> & data)
2923 data.resize(ids.size());
2928 data[i].push_back(pr.second);
2933 auto node_id_action_functor =
2936 const std::vector<dof_id_type> & ids,
2937 std::vector<datum_type> & data)
2945 for (
const auto & pr : data[i])
2951 datum_type * datum_type_ex =
nullptr;
2952 Parallel::pull_parallel_vector_data
2953 (this->
comm(), node_ids_requested, node_id_gather_functor,
2954 node_id_action_functor, datum_type_ex);
2962 libMesh::out <<
"No boundary node IDs have been added: cannot build side list!" << std::endl;
2969 const Elem * side_elem;
2971 for (
const auto & elem :
_mesh->active_element_ptr_range())
2972 for (
auto side : elem->side_index_range())
2974 side_elem = &side_builder(*elem, side);
2977 std::map<boundary_id_type, unsigned> nodesets_node_count;
2983 if (nodeset_list.empty() || nodeset_list.count(pr.second))
2984 nodesets_node_count[pr.second]++;
2990 for (
const auto & pr : nodesets_node_count)
2991 if (pr.second == side_elem->
n_nodes())
2998 if (nset_name !=
"")
3007 #ifdef LIBMESH_ENABLE_DEPRECATED 3009 std::vector<unsigned short int> & sl,
3010 std::vector<boundary_id_type> & il)
const 3012 libmesh_deprecated();
3024 el.reserve (bc_tuples.size());
3025 sl.reserve (bc_tuples.size());
3026 il.reserve (bc_tuples.size());
3028 for (
const auto & t : bc_tuples)
3030 el.push_back(std::get<0>(t));
3031 sl.push_back(std::get<1>(t));
3032 il.push_back(std::get<2>(t));
3038 std::vector<BoundaryInfo::BCTuple>
3041 std::vector<BCTuple> bc_triples;
3045 bc_triples.emplace_back(elem->id(), id_pair.first, id_pair.second);
3052 std::sort(bc_triples.begin(), bc_triples.end());
3054 std::sort(bc_triples.begin(), bc_triples.end(),
3056 {
return std::get<1>(left) < std::get<1>(right);});
3058 std::sort(bc_triples.begin(), bc_triples.end(),
3060 {
return std::get<2>(left) < std::get<2>(right);});
3067 #ifdef LIBMESH_ENABLE_DEPRECATED 3069 std::vector<unsigned short int> & sl,
3070 std::vector<boundary_id_type> & il)
const 3072 libmesh_deprecated();
3084 el.reserve (bc_tuples.size());
3085 sl.reserve (bc_tuples.size());
3086 il.reserve (bc_tuples.size());
3088 for (
const auto & t : bc_tuples)
3090 el.push_back(std::get<0>(t));
3091 sl.push_back(std::get<1>(t));
3092 il.push_back(std::get<2>(t));
3098 std::vector<BoundaryInfo::BCTuple>
3101 std::vector<BCTuple> bc_triples;
3107 if (elem->is_remote())
3111 std::vector<const Elem *> family;
3112 #ifdef LIBMESH_ENABLE_AMR 3113 elem->active_family_tree_by_side(family, id_pair.first);
3115 family.push_back(elem);
3119 for (
const auto & f : family)
3120 bc_triples.emplace_back(f->id(), id_pair.first, id_pair.second);
3125 std::sort(bc_triples.begin(), bc_triples.end());
3131 #ifdef LIBMESH_ENABLE_DEPRECATED 3133 std::vector<unsigned short int> & sl,
3134 std::vector<boundary_id_type> & il)
const 3136 libmesh_deprecated();
3148 el.reserve (bc_tuples.size());
3149 sl.reserve (bc_tuples.size());
3150 il.reserve (bc_tuples.size());
3152 for (
const auto & t : bc_tuples)
3154 el.push_back(std::get<0>(t));
3155 sl.push_back(std::get<1>(t));
3156 il.push_back(std::get<2>(t));
3162 std::vector<BoundaryInfo::BCTuple>
3165 std::vector<BCTuple> bc_triples;
3169 bc_triples.emplace_back(elem->id(), id_pair.first, id_pair.second);
3173 std::sort(bc_triples.begin(), bc_triples.end());
3179 #ifdef LIBMESH_ENABLE_DEPRECATED 3181 std::vector<unsigned short int> & sl,
3182 std::vector<boundary_id_type> & il)
const 3184 libmesh_deprecated();
3196 el.reserve (bc_tuples.size());
3197 sl.reserve (bc_tuples.size());
3198 il.reserve (bc_tuples.size());
3200 for (
const auto & t : bc_tuples)
3202 el.push_back(std::get<0>(t));
3203 sl.push_back(std::get<1>(t));
3204 il.push_back(std::get<2>(t));
3210 std::vector<BoundaryInfo::BCTuple>
3213 std::vector<BCTuple> bc_triples;
3217 bc_triples.emplace_back(elem->id(), id_pair.first, id_pair.second);
3221 std::sort(bc_triples.begin(), bc_triples.end());
3232 out_stream <<
"Nodal Boundary conditions:" << std::endl
3233 <<
"--------------------------" << std::endl
3234 <<
" (Node No., ID) " << std::endl;
3237 out_stream <<
" (" << node->id()
3239 <<
")" << std::endl;
3245 out_stream << std::endl
3246 <<
"Edge Boundary conditions:" << std::endl
3247 <<
"-------------------------" << std::endl
3248 <<
" (Elem No., Edge No., ID) " << std::endl;
3251 out_stream <<
" (" << elem->id()
3252 <<
", " << id_pair.first
3253 <<
", " << id_pair.second
3254 <<
")" << std::endl;
3260 out_stream << std::endl
3261 <<
"Shell-face Boundary conditions:" << std::endl
3262 <<
"-------------------------" << std::endl
3263 <<
" (Elem No., Shell-face No., ID) " << std::endl;
3266 out_stream <<
" (" << elem->id()
3267 <<
", " << id_pair.first
3268 <<
", " << id_pair.second
3269 <<
")" << std::endl;
3275 out_stream << std::endl
3276 <<
"Side Boundary conditions:" << std::endl
3277 <<
"-------------------------" << std::endl
3278 <<
" (Elem No., Side No., ID) " << std::endl;
3281 out_stream <<
" (" << elem->id()
3282 <<
", " << id_pair.first
3283 <<
", " << id_pair.second
3284 <<
")" << std::endl;
3295 out_stream <<
"Nodal Boundary conditions:" << std::endl
3296 <<
"--------------------------" << std::endl
3297 <<
" (ID, number of nodes) " << std::endl;
3299 std::map<boundary_id_type, std::size_t> ID_counts;
3302 ID_counts[pr.second]++;
3304 for (
const auto & [bndry_id, cnt] : ID_counts)
3305 out_stream <<
" (" << bndry_id
3307 <<
")" << std::endl;
3313 out_stream << std::endl
3314 <<
"Edge Boundary conditions:" << std::endl
3315 <<
"-------------------------" << std::endl
3316 <<
" (ID, number of edges) " << std::endl;
3318 std::map<boundary_id_type, std::size_t> ID_counts;
3321 ID_counts[pr.second.second]++;
3323 for (
const auto & [bndry_id, cnt] : ID_counts)
3324 out_stream <<
" (" << bndry_id
3326 <<
")" << std::endl;
3333 out_stream << std::endl
3334 <<
"Shell-face Boundary conditions:" << std::endl
3335 <<
"-------------------------" << std::endl
3336 <<
" (ID, number of shellfaces) " << std::endl;
3338 std::map<boundary_id_type, std::size_t> ID_counts;
3341 ID_counts[pr.second.second]++;
3343 for (
const auto & [bndry_id, cnt] : ID_counts)
3344 out_stream <<
" (" << bndry_id
3346 <<
")" << std::endl;
3352 out_stream << std::endl
3353 <<
"Side Boundary conditions:" << std::endl
3354 <<
"-------------------------" << std::endl
3355 <<
" (ID, number of sides) " << std::endl;
3357 std::map<boundary_id_type, std::size_t> ID_counts;
3360 ID_counts[pr.second.second]++;
3362 for (
const auto & [bndry_id, cnt] : ID_counts)
3363 out_stream <<
" (" << bndry_id
3365 <<
")" << std::endl;
3372 static const std::string empty_string;
3375 return empty_string;
3388 static const std::string empty_string;
3391 return empty_string;
3403 static const std::string empty_string;
3406 return empty_string;
3421 if (ss_name ==
name)
3426 if (ns_name ==
name)
3431 if (es_name ==
name)
3443 std::map<dof_id_type, dof_id_type> * node_id_map,
3445 std::map<std::pair<dof_id_type, unsigned char>,
dof_id_type> * side_id_map,
3446 const std::set<subdomain_id_type> & subdomains_relative_to)
3451 next_node_id = first_free_node_id + this->
processor_id(),
3452 next_elem_id = first_free_elem_id + this->
processor_id();
3470 bool hit_end_el =
false;
3475 !hit_end_el || (el != end_unpartitioned_el); ++el)
3477 if ((el == end_el) && !hit_end_el)
3491 next_node_id = first_free_node_id + this->
n_processors();
3492 next_elem_id = first_free_elem_id + this->
n_processors();
3495 if (el == end_unpartitioned_el)
3499 const Elem * elem = *el;
3513 bool add_this_side =
false;
3516 std::vector<boundary_id_type> bcids;
3522 if (requested_boundary_ids.count(bcid))
3524 add_this_side =
true;
3535 if (requested_boundary_ids.count(
invalid_id) &&
3537 add_this_side =
true;
3548 std::pair<dof_id_type, unsigned char> side_pair(elem->
id(), s);
3550 (*side_id_map)[side_pair] = next_elem_id;
3554 side = &side_builder(*elem, s);
3566 if (node_id_map && !node_id_map->count(node_id))
3568 (*node_id_map)[node_id] = next_node_id;
3582 const bool clear_nodeset_data)
3593 [sideset_id, other_sideset_id](
3594 const std::pair<const Elem *, std::pair<unsigned short int, boundary_id_type>> & pred_pr,
3595 const std::multimap<const Elem *, std::pair<unsigned short int, boundary_id_type>> &
3597 const Elem & elem = *pred_pr.first;
3598 const auto elem_side = pred_pr.second.first;
3601 return std::make_pair(
false, pred_container.end());
3603 const auto elem_side_bnd_id = pred_pr.second.second;
3605 if (elem_side_bnd_id == sideset_id)
3606 other_elem_side_bnd_id = other_sideset_id;
3607 else if (elem_side_bnd_id == other_sideset_id)
3608 other_elem_side_bnd_id = sideset_id;
3610 return std::make_pair(
false, pred_container.end());
3613 const typename std::decay<decltype(pred_container)>::type::value_type other_sideset_info(
3614 other_elem, std::make_pair(other_elem_side, other_elem_side_bnd_id));
3615 auto other_range = pred_container.equal_range(other_elem);
3617 other_range.first != other_range.second,
3618 "No matching sideset information for other element in boundary information");
3619 auto other_it = std::find(other_range.first, other_range.second, other_sideset_info);
3621 other_it != pred_container.end(),
3622 "No matching sideset information for other element in boundary information");
3623 return std::make_pair(
true, other_it);
3626 for (; it != end_it;)
3629 if (pred_result.first)
3635 if (clear_nodeset_data)
3637 const Elem & elem = *it->first;
3638 const Elem & neigh = *pred_result.second->first;
3639 const auto elem_side = it->second.first;
3641 const auto elem_bcid = it->second.second;
3644 for (
const auto local_node_num : elem.
nodes_on_side(elem_side))
3647 for (
const auto local_node_num : neigh.
nodes_on_side(neigh_side))
3668 const std::set<boundary_id_type> &
3679 auto verify_multimap = [](
const auto & themap) {
3680 for (
const auto & [key, val] : themap)
3682 auto range = themap.equal_range(key);
3685 for (
auto it = range.first; it != range.second; ++it)
3686 if (it->second == val)
void remove_shellface_id(boundary_id_type id, bool global=false)
Removes all shellfaces with boundary id id from the BoundaryInfo object, removes it from the set of s...
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
void renumber_shellface_id(boundary_id_type old_id, boundary_id_type new_id)
Changes all shellfaces with boundary id old_id to instead be labeled by boundary id new_id...
void remove_id(boundary_id_type id, bool global=false)
Removes all entities (nodes, sides, edges, shellfaces) with boundary id id from their respective cont...
void libmesh_assert_valid_multimaps() const
Helper method for ensuring that our multimaps don't contain entries with duplicate keys and values...
std::size_t n_boundary_conds() const
RefinementState refinement_flag() const
std::tuple< dof_id_type, unsigned short int, boundary_id_type > BCTuple
As above, but the library creates and fills in a vector of (elem-id, side-id, bc-id) triplets and ret...
std::map< boundary_id_type, std::string > _ns_id_to_name
This structure maintains the mapping of named node sets for file formats (Exodus, Gmsh) that support ...
bool _children_on_boundary
std::set< boundary_id_type > _node_boundary_ids
Set of user-specified boundary IDs for nodes only.
std::vector< BCTuple > build_shellface_list() const
As above, but the library creates and fills in a vector of (elem-id, side-id, bc-id) triplets and ret...
const Elem * parent() const
void raw_boundary_ids(const Elem *const elem, const unsigned short int side, std::vector< boundary_id_type > &vec_to_fill) const
void make_node_unique_ids_parallel_consistent(MeshBase &)
Assuming all unique_ids on local nodes are globally unique, and assuming all processor ids are parall...
static constexpr processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
std::vector< BCTuple > build_active_side_list() const
As above, but the library creates and fills in a vector of (elem-id, side-id, bc-id) triplets and ret...
void active_family_tree_by_side(std::vector< const Elem *> &family, unsigned int side, bool reset=true) const
Same as the active_family_tree() member, but only adds elements which are next to side...
void remove_edge(const Elem *elem, const unsigned short int edge)
Removes all boundary conditions associated with edge edge of element elem, if any exist...
A Node is like a Point, but with more information.
const MeshBase & interior_mesh() const
virtual unique_id_type parallel_max_unique_id() const =0
std::string & nodeset_name(boundary_id_type id)
void set_interior_mesh(MeshBase &int_mesh)
Sets the interior mesh.
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
void set_parent(Elem *p)
Sets the pointer to the element's parent.
std::set< boundary_id_type > _edge_boundary_ids
Set of user-specified boundary IDs for edges only.
virtual void libmesh_assert_valid_parallel_ids() const override
Verify id and processor_id consistency of our elements and nodes containers.
void sync(UnstructuredMesh &boundary_mesh)
Generates boundary_mesh data structures corresponding to the mesh data structures.
void add_elements(const std::set< boundary_id_type > &requested_boundary_ids, UnstructuredMesh &boundary_mesh, bool store_parent_side_ids=false)
Generates elements along the boundary of our _mesh, which use pre-existing nodes on the boundary_mesh...
const Elem * interior_parent() const
~BoundaryInfo()
Destructor.
std::vector< unsigned int > sides_with_boundary_id(const Elem *const elem, const boundary_id_type boundary_id) const
void remove_node(const Node *node, const boundary_id_type id)
Removes boundary id id from node node, if it exists.
void synchronize_global_id_set()
Synchronizes the boundary_ids set on each processor to determine global_boundary_ids.
std::size_t n_edge_conds() const
IntRange< unsigned short > side_index_range() const
void side_boundary_ids(const Elem *const elem, std::vector< std::vector< boundary_id_type >> &vec_to_fill) const
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i)=0
The definition of the const_element_iterator struct.
BoundaryInfo(MeshBase &m)
Constructor.
const Elem * top_parent() const
bool operator==(const BoundaryInfo &other_boundary_info) const
This tests for data equality via element ids.
virtual bool is_edge_on_side(const unsigned int e, const unsigned int s) const =0
void remove_shellface(const Elem *elem, const unsigned short int shellface)
Removes all boundary conditions associated with shell face shellface of element elem, if any exist.
static void set_node_processor_ids(MeshBase &mesh)
This function is called after partitioning to set the processor IDs for the nodes.
std::size_t n_shellface_conds() const
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const =0
void raw_edge_boundary_ids(const Elem *const elem, const unsigned short int edge, std::vector< boundary_id_type > &vec_to_fill) const
unsigned int n_shellface_boundary_ids(const Elem *const elem, const unsigned short int shellface) const
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly ecreated (or read) mesh for use.
RefinementState p_refinement_flag() const
void build_node_list_from_side_list(const std::set< boundary_id_type > &sideset_list={})
Adds nodes with boundary ids based on the side's boundary ids they are connected to.
const boundary_id_type side_id
std::set< boundary_id_type > _boundary_ids
A collection of user-specified boundary ids for sides, edges, nodes, and shell faces.
void remove(const Node *node)
Removes the boundary conditions associated with node node, if any exist.
unsigned int add_elem_integer(std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
Register an integer datum (of type dof_id_type) to be added to each element in the mesh...
void remove_side_id(boundary_id_type id, bool global=false)
Removes all sides with boundary id id from the BoundaryInfo object, removes it from the set of side b...
unsigned int side_with_boundary_id(const Elem *const elem, const boundary_id_type boundary_id) const
This is the base class from which all geometric element types are derived.
void add_child(Elem *elem)
Adds a child pointer to the array of children of this element.
virtual std::unique_ptr< Partitioner > & partitioner()
A partitioner to use at each prepare_for_use()
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
const Parallel::Communicator & comm() const
virtual unsigned int n_children() const =0
std::set< boundary_id_type > _side_boundary_ids
Set of user-specified boundary IDs for sides only.
void build_side_boundary_ids(std::vector< boundary_id_type > &b_ids) const
Builds the list of unique side boundary ids.
void shellface_boundary_ids(const Elem *const elem, const unsigned short int shellface, std::vector< boundary_id_type > &vec_to_fill) const
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
const Parallel::Communicator & _communicator
MeshBase * _mesh
A pointer to the Mesh this boundary info pertains to.
The libMesh namespace provides an interface to certain functionality in the library.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
void renumber_id(boundary_id_type old_id, boundary_id_type new_id)
Changes all entities (nodes, sides, edges, shellfaces) with boundary id old_id to instead be labeled ...
std::multimap< const Elem *, std::pair< unsigned short int, boundary_id_type > > _boundary_side_id
Data structure that maps sides of elements to boundary ids.
virtual std::unique_ptr< MeshBase > clone() const =0
Virtual "copy constructor".
Real distance(const Point &p)
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
void set_interior_parent(Elem *p)
Sets the pointer to the element's interior_parent.
std::set< boundary_id_type > _global_boundary_ids
A collection of user-specified boundary ids for sides, edges, nodes, and shell faces.
uint8_t processor_id_type
This is the MeshBase class.
std::size_t n_boundary_ids() const
void build_side_list(std::vector< dof_id_type > &element_id_list, std::vector< unsigned short int > &side_list, std::vector< boundary_id_type > &bc_id_list) const
Creates a list of element numbers, sides, and ids for those sides.
void build_side_list_from_node_list(const std::set< boundary_id_type > &nodeset_list={})
Adds sides to a sideset if every node on that side are in the same sideset.
IntRange< unsigned short > edge_index_range() const
std::tuple< dof_id_type, boundary_id_type > NodeBCTuple
As above, but the library creates and fills in a vector of (node-id, bc-id) pairs and returns it to t...
std::map< boundary_id_type, std::string > _ss_id_to_name
This structure maintains the mapping of named side sets for file formats (Exodus, Gmsh) that support ...
void renumber_side_id(boundary_id_type old_id, boundary_id_type new_id)
Changes all sides with boundary id old_id to instead be labeled by boundary id new_id.
boundary_id_type get_id_by_name(std::string_view name) const
void clear_boundary_node_ids()
Clears all the boundary information from all of the nodes in the mesh.
processor_id_type n_processors() const
virtual bool is_serial() const
void build_node_list(std::vector< dof_id_type > &node_id_list, std::vector< boundary_id_type > &bc_id_list) const
Creates a list of nodes and ids for those nodes.
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
const dof_id_type n_nodes
void remove_edge_id(boundary_id_type id, bool global=false)
Removes all edges with boundary id id from the BoundaryInfo object, removes it from the set of edge b...
const std::string & get_edgeset_name(boundary_id_type id) const
static const boundary_id_type invalid_id
Number used for internal use.
unsigned int n_raw_boundary_ids(const Elem *const elem, const unsigned short int side) const
This is the MeshCommunication class.
const Node & node_ref(const unsigned int i) const
std::map< boundary_id_type, std::string > _es_id_to_name
This structure maintains the mapping of named edge sets for file formats (Exodus, Gmsh) that support ...
virtual unsigned int n_nodes() const =0
std::multimap< const Node *, boundary_id_type > _boundary_node_id
Data structure that maps nodes in the mesh to boundary ids.
The UnstructuredMesh class is derived from the MeshBase class.
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
void print_info(std::ostream &out_stream=libMesh::out) const
Prints the boundary information data structure.
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
void raw_shellface_boundary_ids(const Elem *const elem, const unsigned short int shellface, std::vector< boundary_id_type > &vec_to_fill) const
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
virtual const Node * query_node_ptr(const dof_id_type i) const =0
void parallel_sync_side_ids()
Synchronize the boundary element side and node across processors.
virtual dof_id_type max_elem_id() const =0
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
std::vector< BCTuple > build_edge_list() const
As above, but the library creates and fills in a vector of (elem-id, side-id, bc-id) triplets and ret...
void parallel_sync_node_ids()
Helper for building element sides that minimizes the construction of new elements.
virtual unsigned int n_edges() const =0
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
The DistributedMesh class is derived from the MeshBase class, and is intended to provide identical fu...
An object whose state is distributed along a set of processors.
void regenerate_id_sets()
Clears and regenerates the cached sets of ids.
const std::string & get_nodeset_name(boundary_id_type id) const
virtual void clear()
Deletes all the element and node data that is currently stored.
void clear()
Clears the underlying data structures and restores the object to a pristine state with no data stored...
unsigned int which_child_am_i(const Elem *e) const
std::string & sideset_name(boundary_id_type id)
void renumber_node_id(boundary_id_type old_id, boundary_id_type new_id)
Changes all nodes with boundary id old_id to instead be labeled by boundary id new_id.
BoundaryInfo & operator=(const BoundaryInfo &other_boundary_info)
Copy assignment operator.
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
unsigned int n_partitions() const
virtual const Elem * elem_ptr(const dof_id_type i) const =0
void build_node_boundary_ids(std::vector< boundary_id_type > &b_ids) const
Builds the list of unique node boundary ids.
virtual unsigned int n_sides() const =0
const Elem * neighbor_ptr(unsigned int i) const
void remove_side(const Elem *elem, const unsigned short int side)
Removes all boundary conditions associated with side side of element elem, if any exist...
unsigned int level() const
const Elem * raw_child_ptr(unsigned int i) const
virtual unsigned int n_vertices() const =0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
unsigned int n_edge_boundary_ids(const Elem *const elem, const unsigned short int edge) const
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
subdomain_id_type subdomain_id() const
void copy_boundary_ids(const BoundaryInfo &old_boundary_info, const Elem *const old_elem, const Elem *const new_elem)
void max(const T &r, T &o, Request &req) const
virtual unsigned short dim() const =0
const Node * node_ptr(const unsigned int i) const
void clear_stitched_boundary_side_ids(boundary_id_type sideset_id, boundary_id_type other_sideset_id, bool clear_nodeset_data=false)
Clear sideset information along a stitched mesh interface.
virtual bool is_replicated() const
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure...
const std::string & get_sideset_name(boundary_id_type id) const
const std::set< boundary_id_type > & get_global_boundary_ids() const
void add_shellface(const dof_id_type elem, const unsigned short int shellface, const boundary_id_type id)
Add shell face shellface of element number elem with boundary id id to the boundary information data ...
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...
std::size_t n_nodeset_conds() const
std::string & edgeset_name(boundary_id_type id)
IntRange< unsigned short > node_index_range() const
void renumber_edge_id(boundary_id_type old_id, boundary_id_type new_id)
Changes all edges with boundary id old_id to instead be labeled by boundary id new_id.
void edge_boundary_ids(const Elem *const elem, const unsigned short int edge, std::vector< boundary_id_type > &vec_to_fill) const
std::set< boundary_id_type > _shellface_boundary_ids
Set of user-specified boundary IDs for shellfaces only.
void _find_id_maps(const std::set< boundary_id_type > &requested_boundary_ids, dof_id_type first_free_node_id, std::map< dof_id_type, dof_id_type > *node_id_map, dof_id_type first_free_elem_id, std::map< std::pair< dof_id_type, unsigned char >, dof_id_type > *side_id_map, const std::set< subdomain_id_type > &subdomains_relative_to)
Helper method for finding consistent maps of interior to boundary dof_object ids. ...
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
std::multimap< const Elem *, std::pair< unsigned short int, boundary_id_type > > _boundary_shellface_id
Data structure that maps faces of shell elements to boundary ids.
virtual void delete_remote_elements()
When supported, deletes all nonlocal elements of the mesh except for "ghosts" which touch a local ele...
void print_summary(std::ostream &out_stream=libMesh::out) const
Prints a summary of the boundary information.
virtual const Node * node_ptr(const dof_id_type i) const =0
processor_id_type processor_id() const
static constexpr subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
void remove_node_id(boundary_id_type id, bool global=false)
Removes all nodes with boundary id id from the BoundaryInfo object, removes it from the set of node b...
processor_id_type processor_id() const
dof_id_type node_id(const unsigned int i) const
const Point & point(const unsigned int i) const
bool has_children() const
unsigned int & set_n_partitions()
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
void build_shellface_boundary_ids(std::vector< boundary_id_type > &b_ids) const
Builds the list of unique shellface boundary ids.
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
void set_extra_integer(const unsigned int index, const dof_id_type value)
Sets the value on this object of the extra integer associated with index, which should have been obta...
std::multimap< const Elem *, std::pair< unsigned short int, boundary_id_type > > _boundary_edge_id
Data structure that maps edges of elements to boundary ids.
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0
Point vertex_average() const
const Elem * child_ptr(unsigned int i) const
void get_side_and_node_maps(UnstructuredMesh &boundary_mesh, std::map< dof_id_type, dof_id_type > &node_id_map, std::map< dof_id_type, unsigned char > &side_id_map, Real tolerance=1.e-6)
Suppose we have used sync to create boundary_mesh.
void add_edge(const dof_id_type elem, const unsigned short int edge, const boundary_id_type id)
Add edge edge of element number elem with boundary id id to the boundary information data structure...
void transfer_boundary_ids_from_children(const Elem *const parent)
Update parent's boundary id list so that this information is consistent with its children.
void set_union(T &data, const unsigned int root_id) const
const RemoteElem * remote_elem