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" 46 template <
class Key,
class T,
class Pred>
47 void erase_if(std::multimap<Key,T> & map, Key k, Pred pred)
49 auto rng = map.equal_range(k);
51 while (it != rng.second)
62 template <
class Key,
class T,
class Pred>
63 void erase_if(std::multimap<Key,T> & map, Pred pred)
65 auto it = map.begin();
66 while (it != map.end())
76 template <
typename Map,
typename T>
77 void renumber_name(Map & m, T old_id, T new_id)
79 if (
const auto it = std::as_const(m).find(old_id);
82 m[new_id] = it->second;
105 _children_on_boundary(false)
167 const Node * other_node =
175 auto compare_edges = [&](
const Elem * elem,
176 const Elem * other_elem,
177 unsigned short int edge)
184 std::vector<boundary_id_type> our_edges, other_edges;
187 if (our_edges.size() != other_edges.size())
190 std::sort(our_edges.begin(), our_edges.end());
191 std::sort(other_edges.begin(), other_edges.end());
193 if (our_edges[i] != other_edges[i])
198 for (
const auto & [other_elem, edge_id_pair] : other_boundary_info.
_boundary_edge_id)
201 if (!compare_edges(elem, other_elem, edge_id_pair.first))
208 if (!compare_edges(elem, other_elem, edge_id_pair.first))
212 auto compare_sides = [&](
const Elem * elem,
213 const Elem * other_elem,
214 unsigned short int side)
221 std::vector<boundary_id_type> our_sides, other_sides;
223 other_boundary_info.
boundary_ids(other_elem, side, other_sides);
224 if (our_sides.size() != other_sides.size())
227 std::sort(our_sides.begin(), our_sides.end());
228 std::sort(other_sides.begin(), other_sides.end());
230 if (our_sides[i] != other_sides[i])
235 for (
const auto & [other_elem, side_id_pair] : other_boundary_info.
_boundary_side_id)
238 if (!compare_sides(elem, other_elem, side_id_pair.first))
245 if (!compare_sides(elem, other_elem, side_id_pair.first))
249 auto compare_shellfaces = [&](
const Elem * elem,
250 const Elem * other_elem,
251 unsigned short int shellface)
258 std::vector<boundary_id_type> our_shellfaces, other_shellfaces;
261 if (our_shellfaces.size() != other_shellfaces.size())
264 std::sort(our_shellfaces.begin(), our_shellfaces.end());
265 std::sort(other_shellfaces.begin(), other_shellfaces.end());
267 if (our_shellfaces[i] != other_shellfaces[i])
275 if (!compare_shellfaces(elem, other_elem, shellface_id_pair.first))
282 if (!compare_shellfaces(elem, other_elem, shellface_id_pair.first))
289 auto compare_sets = [](
const auto & set1,
const auto & set2)
291 if (set1.size() != set2.size())
294 if (!set2.count(bid))
314 auto compare_maps = [](
const auto & map1,
const auto & map2)
316 if (map1.size() != map2.size())
318 for (
const auto & pair : map1)
319 if (!map2.count(pair.first) ||
320 map2.at(pair.first) != pair.second)
382 if (
const auto it = old_ns_id_to_name.find(
id);
383 it != old_ns_id_to_name.end())
392 if (
const auto it = old_es_id_to_name.find(
id);
393 it != old_es_id_to_name.end())
402 if (
const auto it = old_ss_id_to_name.find(
id);
403 it != old_ss_id_to_name.end())
430 std::set<boundary_id_type> request_boundary_ids(
_boundary_ids);
435 this->
sync(request_boundary_ids,
445 std::set<subdomain_id_type> subdomains_relative_to;
448 this->
sync(requested_boundary_ids,
450 subdomains_relative_to);
457 const std::set<subdomain_id_type> & subdomains_relative_to)
459 LOG_SCOPE(
"sync()",
"BoundaryInfo");
461 boundary_mesh.
clear();
488 std::unique_ptr<MeshBase> mesh_copy;
492 auto serializer = std::make_unique<MeshSerializer>
501 std::map<dof_id_type, dof_id_type> node_id_map;
502 std::map<std::pair<dof_id_type, unsigned char>,
dof_id_type> side_id_map;
504 this->
_find_id_maps(requested_boundary_ids, 0, &node_id_map, 0, &side_id_map, subdomains_relative_to);
507 for (
const auto & node :
_mesh->node_ptr_range())
510 if (node_id_map.count(node_id))
512 boundary_mesh.
add_point(*node, node_id_map[node_id], node->processor_id());
515 std::vector<boundary_id_type> node_boundary_ids;
517 for (
const auto & node_bid : node_boundary_ids)
527 subdomains_relative_to,
536 for (
auto & new_elem : boundary_mesh.element_ptr_range())
538 for (
auto nn : new_elem->node_index_range())
542 boundary_mesh.
node_ptr(node_id_map[new_elem->node_id(nn)]);
547 libmesh_assert_equal_to (new_node->
id(),
548 node_id_map[new_elem->node_id(nn)]);
551 new_elem->set_node(nn, new_node);
560 for (
auto & new_elem : boundary_mesh.element_ptr_range())
563 new_elem->interior_parent()->id();
565 if (!mesh_copy->query_elem_ptr(interior_parent_id))
566 new_elem->set_interior_parent
589 std::map<dof_id_type, dof_id_type> & node_id_map,
590 std::map<dof_id_type, unsigned char> & side_id_map,
593 LOG_SCOPE(
"get_side_and_node_maps()",
"BoundaryInfo");
601 const Elem * interior_parent_side;
603 for (
const auto & boundary_elem : boundary_mesh.active_element_ptr_range())
609 unsigned char interior_parent_side_index = 0;
610 bool found_matching_sides =
false;
613 interior_parent_side = &side_builder(*interior_parent, side);
616 if (va_distance < (tolerance * boundary_elem->hmin()))
618 interior_parent_side_index = cast_int<unsigned char>(side);
619 found_matching_sides =
true;
624 libmesh_error_msg_if(!found_matching_sides,
"No matching side found within the specified tolerance");
626 side_id_map[boundary_elem->id()] = interior_parent_side_index;
628 for (
auto local_node_index : boundary_elem->node_index_range())
630 dof_id_type boundary_node_id = boundary_elem->node_id(local_node_index);
633 node_id_map[interior_node_id] = boundary_node_id;
642 bool store_parent_side_ids)
645 std::set<subdomain_id_type> subdomains_relative_to;
650 subdomains_relative_to,
651 store_parent_side_ids);
658 const std::set<subdomain_id_type> & subdomains_relative_to,
659 bool store_parent_side_ids)
661 LOG_SCOPE(
"add_elements()",
"BoundaryInfo");
680 std::map<std::pair<dof_id_type, unsigned char>,
dof_id_type> side_id_map;
686 subdomains_relative_to);
692 typedef std::vector<std::pair<dof_id_type, unsigned char>>
694 side_container sides_to_add;
696 for (
const auto & elem :
_mesh->element_ptr_range())
705 !subdomains_relative_to.count(elem->subdomain_id()))
708 for (
auto s : elem->side_index_range())
710 bool add_this_side =
false;
713 std::vector<boundary_id_type> bcids;
719 if (requested_boundary_ids.count(bcid))
721 add_this_side =
true;
732 if (requested_boundary_ids.count(
invalid_id) &&
733 elem->neighbor_ptr(s) ==
nullptr)
734 add_this_side =
true;
737 sides_to_add.emplace_back(elem->id(), s);
741 #ifdef LIBMESH_ENABLE_UNIQUE_ID 748 unsigned int parent_side_index_tag = store_parent_side_ids ?
751 for (
const auto & [elem_id, s] : sides_to_add)
759 const std::pair<dof_id_type, unsigned char> side_pair(elem_id, s);
763 const dof_id_type new_side_id = side_id_map[side_pair];
765 side->set_id(new_side_id);
767 #ifdef LIBMESH_ENABLE_UNIQUE_ID 768 side->set_unique_id(old_max_unique_id + new_side_id);
772 Elem * new_elem = boundary_mesh.
add_elem(std::move(side));
776 if (store_parent_side_ids)
779 #ifdef LIBMESH_ENABLE_AMR 786 const std::pair<dof_id_type, unsigned char> parent_side_pair(elem->
parent()->
id(), s);
790 Elem * side_parent = boundary_mesh.
elem_ptr(side_id_map[parent_side_pair]);
801 bool found_child =
false;
803 if (new_elem->
node_ptr(v) == side_parent->node_ptr(v))
805 side_parent->add_child(new_elem, v);
814 libmesh_assert_equal_to (new_elem->
n_vertices(), 3);
815 side_parent->add_child(new_elem, 3);
845 const unsigned short bdy_n_sides = new_elem->
n_sides();
846 const unsigned short bdy_n_nodes = new_elem->
n_nodes();
857 for (
unsigned short boundary_side = 0;
858 boundary_side != bdy_n_sides; ++boundary_side)
862 bool found_all_nodes =
true;
863 for (
unsigned short boundary_node = 0;
864 boundary_node != bdy_n_nodes; ++boundary_node)
870 bool found_this_node =
false;
871 for (
unsigned short interior_node = 0;
872 interior_node !=
n_nodes; ++interior_node)
878 if (new_elem->
point(boundary_node) ==
879 elem->
point(interior_node))
881 found_this_node =
true;
885 if (!found_this_node)
887 found_all_nodes =
false;
912 # ifdef LIBMESH_HAVE_RTTI 929 libmesh_error_msg_if(!node_ptr,
930 "BoundaryInfo::add_node(): Could not retrieve pointer for node " 932 <<
", no boundary id was added.");
943 "ERROR: You may not set a boundary ID of " 945 <<
"\n That is reserved for internal use.");
960 const std::vector<boundary_id_type> & ids)
975 std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
976 std::sort(unique_ids.begin(), unique_ids.end());
977 std::vector<boundary_id_type>::iterator new_end =
978 std::unique(unique_ids.begin(), unique_ids.end());
980 for (
auto &
id :
as_range(unique_ids.begin(), new_end))
983 "ERROR: You may not set a boundary ID of " 985 <<
"\n That is reserved for internal use.");
987 bool already_inserted =
false;
988 for (
const auto & pr :
as_range(bounds))
991 already_inserted =
true;
994 if (already_inserted)
1011 const unsigned short int edge,
1020 const unsigned short int edge,
1026 libmesh_assert_equal_to (elem->
level(), 0);
1029 libmesh_assert_less (edge, elem->
n_edges());
1032 "ERROR: You may not set a boundary ID of " 1034 <<
"\n That is reserved for internal use.");
1038 if (pr.second.first == edge &&
1039 pr.second.second ==
id)
1050 const unsigned short int edge,
1051 const std::vector<boundary_id_type> & ids)
1059 libmesh_assert_equal_to (elem->
level(), 0);
1062 libmesh_assert_less (edge, elem->
n_edges());
1072 std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
1073 std::sort(unique_ids.begin(), unique_ids.end());
1074 std::vector<boundary_id_type>::iterator new_end =
1075 std::unique(unique_ids.begin(), unique_ids.end());
1077 for (
auto &
id :
as_range(unique_ids.begin(), new_end))
1080 "ERROR: You may not set a boundary ID of " 1082 <<
"\n That is reserved for internal use.");
1084 bool already_inserted =
false;
1085 for (
const auto & pr :
as_range(bounds))
1086 if (pr.second.first == edge &&
1087 pr.second.second ==
id)
1089 already_inserted =
true;
1092 if (already_inserted)
1104 const unsigned short int shellface,
1113 const unsigned short int shellface,
1119 libmesh_assert_equal_to (elem->
level(), 0);
1122 libmesh_assert_less(shellface, 2);
1125 "ERROR: You may not set a boundary ID of " 1127 <<
"\n That is reserved for internal use.");
1131 if (pr.second.first == shellface &&
1132 pr.second.second ==
id)
1143 const unsigned short int shellface,
1144 const std::vector<boundary_id_type> & ids)
1152 libmesh_assert_equal_to (elem->
level(), 0);
1155 libmesh_assert_less(shellface, 2);
1165 std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
1166 std::sort(unique_ids.begin(), unique_ids.end());
1167 std::vector<boundary_id_type>::iterator new_end =
1168 std::unique(unique_ids.begin(), unique_ids.end());
1170 for (
auto &
id :
as_range(unique_ids.begin(), new_end))
1173 "ERROR: You may not set a boundary ID of " 1175 <<
"\n That is reserved for internal use.");
1177 bool already_inserted =
false;
1178 for (
const auto & pr :
as_range(bounds))
1179 if (pr.second.first == shellface &&
1180 pr.second.second ==
id)
1182 already_inserted =
true;
1185 if (already_inserted)
1196 const unsigned short int side,
1205 const unsigned short int side,
1211 libmesh_assert_less (side, elem->
n_sides());
1213 libmesh_error_msg_if(
id ==
invalid_id,
"ERROR: You may not set a boundary ID of " 1215 <<
"\n That is reserved for internal use.");
1219 if (pr.second.first == side &&
1220 pr.second.second ==
id)
1223 #ifdef LIBMESH_ENABLE_AMR 1233 std::vector<boundary_id_type> bd_ids;
1236 if(std::find(bd_ids.begin(), bd_ids.end(), id) != bd_ids.end())
1237 libmesh_not_implemented_msg(
"Trying to add boundary ID " 1238 + std::to_string(
id)
1239 +
" which already exists on the ancestors.");
1251 const unsigned short int side,
1252 const std::vector<boundary_id_type> & ids)
1260 libmesh_assert_less (side, elem->
n_sides());
1262 #ifdef LIBMESH_ENABLE_AMR 1272 std::vector<boundary_id_type> bd_ids;
1275 for (
const auto id : ids)
1276 if(std::find(bd_ids.begin(), bd_ids.end(), id) != bd_ids.end())
1277 libmesh_not_implemented_msg(
"Trying to add boundary ID " 1278 + std::to_string(
id)
1279 +
" which already exists on the ancestors.");
1291 std::vector<boundary_id_type> unique_ids(ids.begin(), ids.end());
1292 std::sort(unique_ids.begin(), unique_ids.end());
1293 std::vector<boundary_id_type>::iterator new_end =
1294 std::unique(unique_ids.begin(), unique_ids.end());
1296 for (
auto &
id :
as_range(unique_ids.begin(), new_end))
1299 "ERROR: You may not set a boundary ID of " 1301 <<
"\n That is reserved for internal use.");
1303 bool already_inserted =
false;
1304 for (
const auto & pr :
as_range(bounds))
1305 if (pr.second.first == side && pr.second.second ==
id)
1307 already_inserted =
true;
1310 if (already_inserted)
1325 if (pr.second ==
id)
1334 std::vector<boundary_id_type> & vec_to_fill)
const 1337 vec_to_fill.clear();
1340 vec_to_fill.push_back(pr.second);
1348 return cast_int<unsigned int>(
std::distance(pos.first, pos.second));
1354 const unsigned short int edge,
1355 std::vector<boundary_id_type> & vec_to_fill)
const 1360 vec_to_fill.clear();
1363 libmesh_assert_less (edge, elem->
n_edges());
1367 const Elem * searched_elem = elem;
1368 #ifdef LIBMESH_ENABLE_AMR 1369 if (elem->
level() != 0)
1374 bool found_boundary_edge =
false;
1382 found_boundary_edge =
true;
1388 if (!found_boundary_edge)
1394 while (searched_elem->parent() !=
nullptr)
1396 const Elem * parent = searched_elem->
parent();
1399 searched_elem = parent;
1407 if (pr.second.first == edge)
1408 vec_to_fill.push_back(pr.second.second);
1414 const unsigned short int edge)
const 1416 std::vector<boundary_id_type> ids;
1418 return cast_int<unsigned int>(ids.size());
1424 const unsigned short int edge,
1425 std::vector<boundary_id_type> & vec_to_fill)
const 1430 libmesh_assert_less (edge, elem->
n_edges());
1433 vec_to_fill.clear();
1441 if (pr.second.first == edge)
1442 vec_to_fill.push_back(pr.second.second);
1448 const unsigned short int shellface,
1449 std::vector<boundary_id_type> & vec_to_fill)
const 1454 libmesh_assert_less(shellface, 2);
1457 vec_to_fill.clear();
1461 const Elem * searched_elem = elem;
1462 #ifdef LIBMESH_ENABLE_AMR 1463 if (elem->
level() != 0)
1465 while (searched_elem->
parent() !=
nullptr)
1467 const Elem * parent = searched_elem->
parent();
1468 searched_elem = parent;
1475 if (pr.second.first == shellface)
1476 vec_to_fill.push_back(pr.second.second);
1482 const unsigned short int shellface)
const 1484 std::vector<boundary_id_type> ids;
1486 return cast_int<unsigned int>(ids.size());
1492 const unsigned short int shellface,
1493 std::vector<boundary_id_type> & vec_to_fill)
const 1498 libmesh_assert_less(shellface, 2);
1501 vec_to_fill.clear();
1509 if (pr.second.first == shellface)
1510 vec_to_fill.push_back(pr.second.second);
1516 const unsigned short int side,
1519 std::vector<boundary_id_type> ids;
1521 return (std::find(ids.begin(), ids.end(), id) != ids.end());
1527 const unsigned short int side,
1528 std::vector<boundary_id_type> & vec_to_fill)
const 1533 libmesh_assert_less (side, elem->
n_sides());
1536 vec_to_fill.clear();
1542 const Elem * searched_elem = elem;
1544 #ifdef LIBMESH_ENABLE_AMR 1546 if (elem->
level() != 0)
1553 while (searched_elem)
1557 if (pr.second.first == side &&
1558 std::find(vec_to_fill.begin(), vec_to_fill.end(), pr.second.second) ==
1560 vec_to_fill.push_back(pr.second.second);
1563 const Elem * parent = searched_elem->
parent();
1569 searched_elem = parent;
1581 while (searched_elem->
parent() !=
nullptr)
1583 const Elem * parent = searched_elem->
parent();
1587 searched_elem = parent;
1595 if (pr.second.first == side)
1596 vec_to_fill.push_back(pr.second.second);
1603 const unsigned short int side)
const 1605 std::vector<boundary_id_type> ids;
1607 return cast_int<unsigned int>(ids.size());
1612 const unsigned short int side)
const 1614 std::vector<boundary_id_type> ids;
1616 return cast_int<unsigned int>(ids.size());
1622 const unsigned short int side,
1623 std::vector<boundary_id_type> & vec_to_fill)
const 1628 libmesh_assert_less (side, elem->
n_sides());
1631 vec_to_fill.clear();
1639 if (pr.second.first == side)
1640 vec_to_fill.push_back(pr.second.second);
1646 const Elem *
const old_elem,
1647 const Elem *
const new_elem)
1649 libmesh_assert_equal_to (old_elem->
n_sides(), new_elem->
n_sides());
1650 libmesh_assert_equal_to (old_elem->
n_edges(), new_elem->
n_edges());
1652 std::vector<boundary_id_type> bndry_ids;
1657 this->
add_side (new_elem, s, bndry_ids);
1663 this->
add_edge (new_elem, e, bndry_ids);
1666 for (
unsigned short sf=0; sf != 2; sf++)
1693 {
return val == id;});
1711 const unsigned short int edge)
1716 libmesh_assert_less (edge, elem->
n_edges());
1719 libmesh_assert_equal_to (elem->
level(), 0);
1724 {
return pr.first == edge;});
1730 const unsigned short int edge,
1736 libmesh_assert_less (edge, elem->
n_edges());
1739 libmesh_assert_equal_to (elem->
level(), 0);
1744 {
return pr.first == edge && pr.second == id;});
1749 const unsigned short int shellface)
1754 libmesh_assert_equal_to (elem->
level(), 0);
1757 libmesh_assert_less(shellface, 2);
1762 {
return pr.first == shellface;});
1768 const unsigned short int shellface,
1774 libmesh_assert_equal_to (elem->
level(), 0);
1777 libmesh_assert_less(shellface, 2);
1782 {
return pr.first == shellface && pr.second == id;});
1786 const unsigned short int side)
1791 libmesh_assert_less (side, elem->
n_sides());
1796 {
return pr.first == side;});
1802 const unsigned short int side,
1808 libmesh_assert_less (side, elem->
n_sides());
1810 #ifdef LIBMESH_ENABLE_AMR 1815 std::vector<boundary_id_type> bd_ids;
1817 if(std::find(bd_ids.begin(), bd_ids.end(), id) != bd_ids.end())
1819 std::vector<boundary_id_type> raw_bd_ids;
1821 if(std::find(raw_bd_ids.begin(), raw_bd_ids.end(), id) == raw_bd_ids.end())
1822 libmesh_not_implemented_msg(
"We cannot delete boundary ID " 1823 + std::to_string(
id) +
1824 " using a child because it is inherited from an ancestor.");
1832 {
return pr.first == side && pr.second == id;});
1854 {
return val == id;});
1859 {
return pr.second == id;});
1864 {
return pr.second == id;});
1869 {
return pr.second == id;});
1877 if (old_id == new_id)
1883 bool found_node =
false;
1885 if (p.second == old_id)
1899 bool found_edge =
false;
1901 if (p.second.second == old_id)
1905 this->
remove_edge(p.first, p.second.first, new_id);
1906 p.second.second = new_id;
1915 bool found_shellface =
false;
1917 if (p.second.second == old_id)
1922 p.second.second = new_id;
1923 found_shellface =
true;
1925 if (found_shellface)
1931 bool found_side =
false;
1933 if (p.second.second == old_id)
1937 this->
remove_side(p.first, p.second.first, new_id);
1938 p.second.second = new_id;
1947 if (found_node || found_edge || found_shellface || found_side)
1965 const Elem * searched_elem = elem;
1977 if (pr.second.second == boundary_id_in)
1979 unsigned int side = pr.second.first;
1992 const Elem * p = elem;
1994 #ifdef LIBMESH_ENABLE_AMR 1996 while (p !=
nullptr)
2015 #ifdef LIBMESH_ENABLE_AMR 2023 const Elem * p = elem;
2024 while (p->
parent() !=
nullptr)
2035 if (pr.second.first == side && pr.second.second == boundary_id_in)
2054 std::vector<unsigned int>
2058 std::vector<unsigned int> returnval;
2060 const Elem * searched_elem = elem;
2069 if (pr.second.second == boundary_id_in)
2071 unsigned int side = pr.second.first;
2081 returnval.push_back(side);
2087 const Elem * p = elem;
2089 #ifdef LIBMESH_ENABLE_AMR 2091 while (p !=
nullptr)
2101 returnval.push_back(side);
2105 returnval.push_back(side);
2109 #ifdef LIBMESH_ENABLE_AMR 2116 const Elem * p = elem;
2117 while (p->
parent() !=
nullptr)
2130 if (pr.second.first == side && pr.second.second == boundary_id_in &&
2131 std::find(returnval.begin(), returnval.end(), side) == returnval.end())
2132 returnval.push_back(side);
2156 if (std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
2157 b_ids.push_back(
id);
2170 if (std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
2171 b_ids.push_back(
id);
2184 if (std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
2185 b_ids.push_back(
id);
2189 #ifdef LIBMESH_ENABLE_AMR 2202 const double number_of_sides_on_children =
std::pow(2, parent->
dim()-1);
2206 for (
unsigned int side_i = 0; side_i < parent->
n_sides(); ++side_i)
2211 std::map<unsigned short int, unsigned short int> boundary_counts;
2222 if (pr.second.first == side_i)
2223 ++boundary_counts[pr.second.second];
2230 for (
const auto & boundary : boundary_counts)
2231 if (boundary.second / number_of_sides_on_children > 0.5)
2232 this->
add_side(parent, side_i, boundary.first);
2236 this->
remove(parent->
child_ptr(child_i));
2248 parallel_object_only();
2269 parallel_object_only();
2271 std::size_t n_edge_bcs=0;
2277 this->
comm().
sum (n_edge_bcs);
2291 parallel_object_only();
2293 std::size_t n_shellface_bcs=0;
2299 this->
comm().
sum (n_shellface_bcs);
2301 return n_shellface_bcs;
2313 parallel_object_only();
2315 std::size_t n_nodesets=0;
2321 this->
comm().
sum (n_nodesets);
2328 #ifdef LIBMESH_ENABLE_DEPRECATED 2330 std::vector<boundary_id_type> & il)
const 2332 libmesh_deprecated();
2343 nl.reserve (bc_tuples.size());
2344 il.reserve (bc_tuples.size());
2346 for (
const auto & t : bc_tuples)
2348 nl.push_back(std::get<0>(t));
2349 il.push_back(std::get<1>(t));
2355 std::vector<BoundaryInfo::NodeBCTuple>
2358 std::vector<NodeBCTuple> bc_tuples;
2362 bc_tuples.emplace_back(node->id(), bid);
2367 std::sort(bc_tuples.begin(), bc_tuples.end());
2369 std::sort(bc_tuples.begin(), bc_tuples.end(),
2371 {
return std::get<1>(left) < std::get<1>(right);});
2386 typedef std::set<std::pair<dof_id_type, boundary_id_type>> set_type;
2387 typedef std::vector<std::pair<dof_id_type, boundary_id_type>> vec_type;
2390 std::unordered_map<processor_id_type, set_type> nodes_to_push;
2391 std::unordered_map<processor_id_type, vec_type> node_vecs_to_push;
2402 if (elem->is_remote())
2406 std::vector<const Elem *> family;
2407 #ifdef LIBMESH_ENABLE_AMR 2410 family.push_back(elem);
2413 for (
const auto & cur_elem : family)
2415 side = &side_builder(*cur_elem, id_pair.first);
2422 if (!mesh_is_serial)
2426 if (proc_id != my_proc_id)
2427 nodes_to_push[proc_id].emplace(side->
node_id(i), bcid);
2440 for (
auto & [proc_id, s] : nodes_to_push)
2442 node_vecs_to_push[proc_id].assign(s.begin(), s.end());
2446 auto nodes_action_functor =
2449 const vec_type & received_nodes)
2451 for (
const auto & [dof_id, bndry_id] : received_nodes)
2455 Parallel::push_parallel_vector_data
2456 (this->
comm(), node_vecs_to_push, nodes_action_functor);
2460 std::unordered_map<processor_id_type, std::vector<dof_id_type>>
2464 for (
const auto & node :
_mesh->node_ptr_range())
2467 if (pid != my_proc_id)
2468 node_ids_requested[pid].push_back(node->id());
2471 typedef std::vector<boundary_id_type> datum_type;
2473 auto node_bcid_gather_functor =
2476 const std::vector<dof_id_type> & ids,
2477 std::vector<datum_type> & data)
2479 const std::size_t query_size = ids.size();
2480 data.resize(query_size);
2482 for (std::size_t i=0; i != query_size; ++i)
2486 auto node_bcid_action_functor =
2489 const std::vector<dof_id_type> & ids,
2490 const std::vector<datum_type> & data)
2496 datum_type * datum_type_ex =
nullptr;
2497 Parallel::pull_parallel_vector_data
2498 (this->
comm(), node_ids_requested, node_bcid_gather_functor,
2499 node_bcid_action_functor, datum_type_ex);
2505 std::unordered_map<processor_id_type, std::vector<dof_id_type>>
2509 for (
const auto & elem :
_mesh->element_ptr_range())
2513 elem_ids_requested[pid].push_back(elem->id());
2516 typedef std::vector<std::pair<unsigned short int, boundary_id_type>> datum_type;
2519 auto elem_id_gather_functor =
2522 const std::vector<dof_id_type> & ids,
2523 std::vector<datum_type> & data)
2525 data.resize(ids.size());
2530 data[i].push_back(std::make_pair(pr.second.first, pr.second.second));
2534 auto elem_id_action_functor =
2537 const std::vector<dof_id_type> & ids,
2538 std::vector<datum_type> & data)
2546 for (
const auto & [
side_id, bndry_id] : data[i])
2552 datum_type * datum_type_ex =
nullptr;
2553 Parallel::pull_parallel_vector_data
2554 (this->
comm(), elem_ids_requested, elem_id_gather_functor,
2555 elem_id_action_functor, datum_type_ex);
2561 std::unordered_map<processor_id_type, std::vector<dof_id_type>>
2565 for (
const auto & node :
_mesh->node_ptr_range())
2569 node_ids_requested[pid].push_back(node->id());
2572 typedef std::vector<boundary_id_type> datum_type;
2575 auto node_id_gather_functor =
2578 const std::vector<dof_id_type> & ids,
2579 std::vector<datum_type> & data)
2581 data.resize(ids.size());
2586 data[i].push_back(pr.second);
2591 auto node_id_action_functor =
2594 const std::vector<dof_id_type> & ids,
2595 std::vector<datum_type> & data)
2603 for (
const auto & pr : data[i])
2609 datum_type * datum_type_ex =
nullptr;
2610 Parallel::pull_parallel_vector_data
2611 (this->
comm(), node_ids_requested, node_id_gather_functor,
2612 node_id_action_functor, datum_type_ex);
2620 libMesh::out <<
"No boundary node IDs have been added: cannot build side list!" << std::endl;
2627 const Elem * side_elem;
2629 for (
const auto & elem :
_mesh->active_element_ptr_range())
2630 for (
auto side : elem->side_index_range())
2632 side_elem = &side_builder(*elem, side);
2635 std::map<boundary_id_type, unsigned> nodesets_node_count;
2641 nodesets_node_count[pr.second]++;
2647 for (
const auto & pr : nodesets_node_count)
2648 if (pr.second == side_elem->
n_nodes())
2655 if (nset_name !=
"")
2664 #ifdef LIBMESH_ENABLE_DEPRECATED 2666 std::vector<unsigned short int> & sl,
2667 std::vector<boundary_id_type> & il)
const 2669 libmesh_deprecated();
2681 el.reserve (bc_tuples.size());
2682 sl.reserve (bc_tuples.size());
2683 il.reserve (bc_tuples.size());
2685 for (
const auto & t : bc_tuples)
2687 el.push_back(std::get<0>(t));
2688 sl.push_back(std::get<1>(t));
2689 il.push_back(std::get<2>(t));
2695 std::vector<BoundaryInfo::BCTuple>
2698 std::vector<BCTuple> bc_triples;
2702 bc_triples.emplace_back(elem->id(), id_pair.first, id_pair.second);
2709 std::sort(bc_triples.begin(), bc_triples.end());
2711 std::sort(bc_triples.begin(), bc_triples.end(),
2713 {
return std::get<1>(left) < std::get<1>(right);});
2715 std::sort(bc_triples.begin(), bc_triples.end(),
2717 {
return std::get<2>(left) < std::get<2>(right);});
2724 #ifdef LIBMESH_ENABLE_DEPRECATED 2726 std::vector<unsigned short int> & sl,
2727 std::vector<boundary_id_type> & il)
const 2729 libmesh_deprecated();
2741 el.reserve (bc_tuples.size());
2742 sl.reserve (bc_tuples.size());
2743 il.reserve (bc_tuples.size());
2745 for (
const auto & t : bc_tuples)
2747 el.push_back(std::get<0>(t));
2748 sl.push_back(std::get<1>(t));
2749 il.push_back(std::get<2>(t));
2755 std::vector<BoundaryInfo::BCTuple>
2758 std::vector<BCTuple> bc_triples;
2764 if (elem->is_remote())
2768 std::vector<const Elem *> family;
2769 #ifdef LIBMESH_ENABLE_AMR 2770 elem->active_family_tree_by_side(family, id_pair.first);
2772 family.push_back(elem);
2776 for (
const auto & f : family)
2777 bc_triples.emplace_back(f->id(), id_pair.first, id_pair.second);
2782 std::sort(bc_triples.begin(), bc_triples.end());
2788 #ifdef LIBMESH_ENABLE_DEPRECATED 2790 std::vector<unsigned short int> & sl,
2791 std::vector<boundary_id_type> & il)
const 2793 libmesh_deprecated();
2805 el.reserve (bc_tuples.size());
2806 sl.reserve (bc_tuples.size());
2807 il.reserve (bc_tuples.size());
2809 for (
const auto & t : bc_tuples)
2811 el.push_back(std::get<0>(t));
2812 sl.push_back(std::get<1>(t));
2813 il.push_back(std::get<2>(t));
2819 std::vector<BoundaryInfo::BCTuple>
2822 std::vector<BCTuple> bc_triples;
2826 bc_triples.emplace_back(elem->id(), id_pair.first, id_pair.second);
2830 std::sort(bc_triples.begin(), bc_triples.end());
2836 #ifdef LIBMESH_ENABLE_DEPRECATED 2838 std::vector<unsigned short int> & sl,
2839 std::vector<boundary_id_type> & il)
const 2841 libmesh_deprecated();
2853 el.reserve (bc_tuples.size());
2854 sl.reserve (bc_tuples.size());
2855 il.reserve (bc_tuples.size());
2857 for (
const auto & t : bc_tuples)
2859 el.push_back(std::get<0>(t));
2860 sl.push_back(std::get<1>(t));
2861 il.push_back(std::get<2>(t));
2867 std::vector<BoundaryInfo::BCTuple>
2870 std::vector<BCTuple> bc_triples;
2874 bc_triples.emplace_back(elem->id(), id_pair.first, id_pair.second);
2878 std::sort(bc_triples.begin(), bc_triples.end());
2889 out_stream <<
"Nodal Boundary conditions:" << std::endl
2890 <<
"--------------------------" << std::endl
2891 <<
" (Node No., ID) " << std::endl;
2894 out_stream <<
" (" << node->id()
2896 <<
")" << std::endl;
2902 out_stream << std::endl
2903 <<
"Edge Boundary conditions:" << std::endl
2904 <<
"-------------------------" << std::endl
2905 <<
" (Elem No., Edge No., ID) " << std::endl;
2908 out_stream <<
" (" << elem->id()
2909 <<
", " << id_pair.first
2910 <<
", " << id_pair.second
2911 <<
")" << std::endl;
2917 out_stream << std::endl
2918 <<
"Shell-face Boundary conditions:" << std::endl
2919 <<
"-------------------------" << std::endl
2920 <<
" (Elem No., Shell-face No., ID) " << std::endl;
2923 out_stream <<
" (" << elem->id()
2924 <<
", " << id_pair.first
2925 <<
", " << id_pair.second
2926 <<
")" << std::endl;
2932 out_stream << std::endl
2933 <<
"Side Boundary conditions:" << std::endl
2934 <<
"-------------------------" << std::endl
2935 <<
" (Elem No., Side No., ID) " << std::endl;
2938 out_stream <<
" (" << elem->id()
2939 <<
", " << id_pair.first
2940 <<
", " << id_pair.second
2941 <<
")" << std::endl;
2952 out_stream <<
"Nodal Boundary conditions:" << std::endl
2953 <<
"--------------------------" << std::endl
2954 <<
" (ID, number of nodes) " << std::endl;
2956 std::map<boundary_id_type, std::size_t> ID_counts;
2959 ID_counts[pr.second]++;
2961 for (
const auto & [bndry_id, cnt] : ID_counts)
2962 out_stream <<
" (" << bndry_id
2964 <<
")" << std::endl;
2970 out_stream << std::endl
2971 <<
"Edge Boundary conditions:" << std::endl
2972 <<
"-------------------------" << std::endl
2973 <<
" (ID, number of edges) " << std::endl;
2975 std::map<boundary_id_type, std::size_t> ID_counts;
2978 ID_counts[pr.second.second]++;
2980 for (
const auto & [bndry_id, cnt] : ID_counts)
2981 out_stream <<
" (" << bndry_id
2983 <<
")" << std::endl;
2990 out_stream << std::endl
2991 <<
"Shell-face Boundary conditions:" << std::endl
2992 <<
"-------------------------" << std::endl
2993 <<
" (ID, number of shellfaces) " << std::endl;
2995 std::map<boundary_id_type, std::size_t> ID_counts;
2998 ID_counts[pr.second.second]++;
3000 for (
const auto & [bndry_id, cnt] : ID_counts)
3001 out_stream <<
" (" << bndry_id
3003 <<
")" << std::endl;
3009 out_stream << std::endl
3010 <<
"Side Boundary conditions:" << std::endl
3011 <<
"-------------------------" << std::endl
3012 <<
" (ID, number of sides) " << std::endl;
3014 std::map<boundary_id_type, std::size_t> ID_counts;
3017 ID_counts[pr.second.second]++;
3019 for (
const auto & [bndry_id, cnt] : ID_counts)
3020 out_stream <<
" (" << bndry_id
3022 <<
")" << std::endl;
3029 static const std::string empty_string;
3032 return empty_string;
3045 static const std::string empty_string;
3048 return empty_string;
3060 static const std::string empty_string;
3063 return empty_string;
3078 if (ss_name ==
name)
3083 if (ns_name ==
name)
3088 if (es_name ==
name)
3100 std::map<dof_id_type, dof_id_type> * node_id_map,
3102 std::map<std::pair<dof_id_type, unsigned char>,
dof_id_type> * side_id_map,
3103 const std::set<subdomain_id_type> & subdomains_relative_to)
3108 next_node_id = first_free_node_id + this->
processor_id(),
3109 next_elem_id = first_free_elem_id + this->
processor_id();
3127 bool hit_end_el =
false;
3132 !hit_end_el || (el != end_unpartitioned_el); ++el)
3134 if ((el == end_el) && !hit_end_el)
3148 next_node_id = first_free_node_id + this->
n_processors();
3149 next_elem_id = first_free_elem_id + this->
n_processors();
3152 if (el == end_unpartitioned_el)
3156 const Elem * elem = *el;
3170 bool add_this_side =
false;
3173 std::vector<boundary_id_type> bcids;
3179 if (requested_boundary_ids.count(bcid))
3181 add_this_side =
true;
3192 if (requested_boundary_ids.count(
invalid_id) &&
3194 add_this_side =
true;
3205 std::pair<dof_id_type, unsigned char> side_pair(elem->
id(), s);
3207 (*side_id_map)[side_pair] = next_elem_id;
3211 side = &side_builder(*elem, s);
3223 if (node_id_map && !node_id_map->count(node_id))
3225 (*node_id_map)[node_id] = next_node_id;
3239 const bool clear_nodeset_data)
3250 [sideset_id, other_sideset_id](
3251 const std::pair<const Elem *, std::pair<unsigned short int, boundary_id_type>> & pred_pr,
3252 const std::multimap<const Elem *, std::pair<unsigned short int, boundary_id_type>> &
3254 const Elem & elem = *pred_pr.first;
3255 const auto elem_side = pred_pr.second.first;
3258 return std::make_pair(
false, pred_container.end());
3260 const auto elem_side_bnd_id = pred_pr.second.second;
3262 if (elem_side_bnd_id == sideset_id)
3263 other_elem_side_bnd_id = other_sideset_id;
3264 else if (elem_side_bnd_id == other_sideset_id)
3265 other_elem_side_bnd_id = sideset_id;
3267 return std::make_pair(
false, pred_container.end());
3270 const typename std::decay<decltype(pred_container)>::type::value_type other_sideset_info(
3271 other_elem, std::make_pair(other_elem_side, other_elem_side_bnd_id));
3272 auto other_range = pred_container.equal_range(other_elem);
3274 other_range.first != other_range.second,
3275 "No matching sideset information for other element in boundary information");
3276 auto other_it = std::find(other_range.first, other_range.second, other_sideset_info);
3278 other_it != pred_container.end(),
3279 "No matching sideset information for other element in boundary information");
3280 return std::make_pair(
true, other_it);
3283 for (; it != end_it;)
3286 if (pred_result.first)
3292 if (clear_nodeset_data)
3294 const Elem & elem = *it->first;
3295 const Elem & neigh = *pred_result.second->first;
3296 const auto elem_side = it->second.first;
3298 const auto elem_bcid = it->second.second;
3301 for (
const auto local_node_num : elem.
nodes_on_side(elem_side))
3304 for (
const auto local_node_num : neigh.
nodes_on_side(neigh_side))
3325 const std::set<boundary_id_type> &
3336 auto verify_multimap = [](
const auto & themap) {
3337 for (
const auto & [key, val] : themap)
3339 auto range = themap.equal_range(key);
3342 for (
auto it = range.first; it != range.second; ++it)
3343 if (it->second == val)
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
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...
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 build_node_list_from_side_list()
Adds nodes with boundary ids based on the side's boundary ids they are connected to.
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.
std::size_t n_edge_conds() const
IntRange< unsigned short > side_index_range() 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
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...
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.
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 ...
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.
static const subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
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
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
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
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.
void build_side_list_from_node_list()
Adds sides to a sideset if every node on that side are in the same sideset.
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)
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)
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 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
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