@@ -89,7 +89,8 @@ const boundary_id_type BoundaryInfo::invalid_id = -123;
8989// BoundaryInfo functions
9090BoundaryInfo ::BoundaryInfo (MeshBase & m ) :
9191 ParallelObject (m .comm ()),
92- _mesh (& m )
92+ _mesh (& m ),
93+ _children_on_boundary (false)
9394{
9495}
9596
@@ -952,8 +953,11 @@ void BoundaryInfo::add_side(const Elem * elem,
952953{
953954 libmesh_assert (elem );
954955
955- // Only add BCs for level-0 elements.
956- libmesh_assert_equal_to (elem -> level (), 0 );
956+ // Users try to mark boundary on child elements
957+ // If this happens, we will allow users to remove
958+ // side from child elements as well
959+ if (elem -> level ())
960+ _children_on_boundary = true;
957961
958962 libmesh_error_msg_if (id == invalid_id , "ERROR: You may not set a boundary ID of "
959963 << invalid_id
@@ -981,8 +985,11 @@ void BoundaryInfo::add_side(const Elem * elem,
981985
982986 libmesh_assert (elem );
983987
984- // Only add BCs for level-0 elements.
985- libmesh_assert_equal_to (elem -> level (), 0 );
988+ // Users try to mark boundary on child elements
989+ // If this happens, we will allow users to remove
990+ // side from child elements as well
991+ if (elem -> level ())
992+ _children_on_boundary = true;
986993
987994 // Don't add the same ID twice
988995 auto bounds = _boundary_side_id .equal_range (elem );
@@ -1359,8 +1366,8 @@ void BoundaryInfo::remove_edge (const Elem * elem,
13591366{
13601367 libmesh_assert (elem );
13611368
1362- // Only level 0 elements are stored in BoundaryInfo .
1363- libmesh_assert_equal_to (elem -> level (), 0 );
1369+ // Only level 0 elements unless the flag "_children_on_boundary" is on .
1370+ libmesh_assert (elem -> level ()== 0 || _children_on_boundary );
13641371
13651372 // Erase (elem, edge, *) entries from map.
13661373 erase_if (_boundary_edge_id , elem ,
@@ -1376,8 +1383,8 @@ void BoundaryInfo::remove_edge (const Elem * elem,
13761383{
13771384 libmesh_assert (elem );
13781385
1379- // Only level 0 elements are stored in BoundaryInfo .
1380- libmesh_assert_equal_to (elem -> level (), 0 );
1386+ // Only level 0 elements unless the flag "_children_on_boundary" is on .
1387+ libmesh_assert (elem -> level () == 0 || _children_on_boundary );
13811388
13821389 // Erase (elem, edge, id) entries from map.
13831390 erase_if (_boundary_edge_id , elem ,
@@ -1391,8 +1398,8 @@ void BoundaryInfo::remove_shellface (const Elem * elem,
13911398{
13921399 libmesh_assert (elem );
13931400
1394- // Only level 0 elements are stored in BoundaryInfo .
1395- libmesh_assert_equal_to (elem -> level (), 0 );
1401+ // Only level 0 elements unless the flag "_children_on_boundary" is on .
1402+ libmesh_assert (elem -> level () == 0 || _children_on_boundary );
13961403
13971404 // Shells only have 2 faces
13981405 libmesh_assert_less (shellface , 2 );
@@ -1411,8 +1418,8 @@ void BoundaryInfo::remove_shellface (const Elem * elem,
14111418{
14121419 libmesh_assert (elem );
14131420
1414- // Only level 0 elements are stored in BoundaryInfo .
1415- libmesh_assert_equal_to (elem -> level (), 0 );
1421+ // Only level 0 elements unless the flag "_children_on_boundary" is on .
1422+ libmesh_assert (elem -> level () == 0 || _children_on_boundary );
14161423
14171424 // Shells only have 2 faces
14181425 libmesh_assert_less (shellface , 2 );
@@ -1428,8 +1435,8 @@ void BoundaryInfo::remove_side (const Elem * elem,
14281435{
14291436 libmesh_assert (elem );
14301437
1431- // Only level 0 elements are stored in BoundaryInfo .
1432- libmesh_assert_equal_to (elem -> level (), 0 );
1438+ // Only level 0 elements unless the flag "_children_on_boundary" is on .
1439+ libmesh_assert (elem -> level () == 0 || _children_on_boundary );
14331440
14341441 // Erase (elem, side, *) entries from map.
14351442 erase_if (_boundary_side_id , elem ,
@@ -1445,6 +1452,9 @@ void BoundaryInfo::remove_side (const Elem * elem,
14451452{
14461453 libmesh_assert (elem );
14471454
1455+ // Only level 0 elements unless the flag "_children_on_boundary" is on.
1456+ libmesh_assert (elem -> level () == 0 || _children_on_boundary );
1457+
14481458 // Erase (elem, side, id) entries from map.
14491459 erase_if (_boundary_side_id , elem ,
14501460 [side , id ](decltype (_boundary_side_id )::mapped_type & pr )
@@ -1491,12 +1501,21 @@ void BoundaryInfo::remove_id (boundary_id_type id)
14911501unsigned int BoundaryInfo ::side_with_boundary_id (const Elem * const elem ,
14921502 const boundary_id_type boundary_id_in ) const
14931503{
1494- const Elem * searched_elem = elem ;
1504+ std ::vector < const Elem * > searched_elem_vec ;
1505+ // If elem has boundary information, we return that when
1506+ // the flag "_children_on_boundary" is on
1507+ if (_children_on_boundary )
1508+ searched_elem_vec .push_back (elem );
1509+ // Otherwise, we return boundary information of its
1510+ // parent if any
14951511 if (elem -> level () != 0 )
1496- searched_elem = elem -> top_parent ();
1512+ searched_elem_vec . push_back ( elem -> top_parent () );
14971513
1498- // elem may have zero or multiple occurrences
1499- for (const auto & pr : as_range (_boundary_side_id .equal_range (searched_elem )))
1514+ for (auto it = searched_elem_vec .begin (); it != searched_elem_vec .end (); ++ it )
1515+ {
1516+ const Elem * searched_elem = * it ;
1517+ // elem may have zero or multiple occurrences
1518+ for (const auto & pr : as_range (_boundary_side_id .equal_range (searched_elem )))
15001519 {
15011520 // if this is true we found the requested boundary_id
15021521 // of the element and want to return the side
@@ -1527,7 +1546,8 @@ unsigned int BoundaryInfo::side_with_boundary_id(const Elem * const elem,
15271546 if (!p )
15281547 return side ;
15291548 }
1530- }
1549+ }
1550+ }
15311551
15321552 // if we get here, we found elem in the data structure but not
15331553 // the requested boundary id, so return the default value
@@ -1541,12 +1561,20 @@ BoundaryInfo::sides_with_boundary_id(const Elem * const elem,
15411561{
15421562 std ::vector < unsigned int > returnval ;
15431563
1544- const Elem * searched_elem = elem ;
1564+ std ::vector < const Elem * > searched_elem_vec ;
1565+ // If elem has boundary information, that is part of return when
1566+ // the flag "_children_on_boundary" is on
1567+ if (_children_on_boundary )
1568+ searched_elem_vec .push_back (elem );
1569+ // Return boundary information of its parent as well
15451570 if (elem -> level () != 0 )
1546- searched_elem = elem -> top_parent ();
1571+ searched_elem_vec . push_back ( elem -> top_parent () );
15471572
1548- // elem may have zero or multiple occurrences
1549- for (const auto & pr : as_range (_boundary_side_id .equal_range (searched_elem )))
1573+ for (auto it = searched_elem_vec .begin (); it != searched_elem_vec .end (); ++ it )
1574+ {
1575+ const Elem * searched_elem = * it ;
1576+ // elem may have zero or multiple occurrences
1577+ for (const auto & pr : as_range (_boundary_side_id .equal_range (searched_elem )))
15501578 {
15511579 // if this is true we found the requested boundary_id
15521580 // of the element and want to return the side
@@ -1581,7 +1609,7 @@ BoundaryInfo::sides_with_boundary_id(const Elem * const elem,
15811609 returnval .push_back (side );
15821610 }
15831611 }
1584-
1612+ }
15851613 return returnval ;
15861614}
15871615
@@ -1796,7 +1824,8 @@ BoundaryInfo::build_node_list_from_side_list()
17961824 // Need to loop over the sides of any possible children
17971825 std ::vector < const Elem * > family ;
17981826#ifdef LIBMESH_ENABLE_AMR
1799- pr .first -> active_family_tree_by_side (family , pr .second .first );
1827+ if (!pr .first -> subactive ())
1828+ pr .first -> active_family_tree_by_side (family , pr .second .first );
18001829#else
18011830 family .push_back (pr .first );
18021831#endif
@@ -2159,7 +2188,8 @@ BoundaryInfo::build_active_side_list () const
21592188 // Loop over the sides of possible children
21602189 std ::vector < const Elem * > family ;
21612190#ifdef LIBMESH_ENABLE_AMR
2162- pr .first -> active_family_tree_by_side (family , pr .second .first );
2191+ if (!pr .first -> subactive ())
2192+ pr .first -> active_family_tree_by_side (family , pr .second .first );
21632193#else
21642194 family .push_back (pr .first );
21652195#endif
0 commit comments