Skip to content

Commit 125f664

Browse files
committed
Allow boundary be associated with child elements
Use case: moving boundary with AMR. Boundary needs to be defined on child elements
1 parent ced9eb5 commit 125f664

File tree

2 files changed

+64
-27
lines changed

2 files changed

+64
-27
lines changed

include/mesh/boundary_info.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,13 @@ class BoundaryInfo : public ParallelObject
924924
std::pair<unsigned short int, boundary_id_type>>
925925
_boundary_side_id;
926926

927+
/*
928+
* Whether or not children elements are associated to any boundary
929+
* It is false by default. The flag will be turnned on if add_side
930+
* function is called with a child element
931+
*/
932+
bool _children_on_boundary;
933+
927934
/**
928935
* A collection of user-specified boundary ids for sides, edges, nodes,
929936
* and shell faces.

src/mesh/boundary_info.C

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ const boundary_id_type BoundaryInfo::invalid_id = -123;
8989
// BoundaryInfo functions
9090
BoundaryInfo::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)
14911501
unsigned 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

Comments
 (0)