Skip to content

Commit 9aa806f

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 caac49e commit 9aa806f

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
@@ -88,7 +88,8 @@ const boundary_id_type BoundaryInfo::invalid_id = -123;
8888
// BoundaryInfo functions
8989
BoundaryInfo::BoundaryInfo(MeshBase & m) :
9090
ParallelObject(m.comm()),
91-
_mesh (&m)
91+
_mesh (&m),
92+
_children_on_boundary(false)
9293
{
9394
}
9495

@@ -949,8 +950,11 @@ void BoundaryInfo::add_side(const Elem * elem,
949950
{
950951
libmesh_assert(elem);
951952

952-
// Only add BCs for level-0 elements.
953-
libmesh_assert_equal_to (elem->level(), 0);
953+
// Users try to mark boundary on child elements
954+
// If this happens, we will allow users to remove
955+
// side from child elements as well
956+
if (elem->level())
957+
_children_on_boundary = true;
954958

955959
libmesh_error_msg_if(id == invalid_id, "ERROR: You may not set a boundary ID of "
956960
<< invalid_id
@@ -978,8 +982,11 @@ void BoundaryInfo::add_side(const Elem * elem,
978982

979983
libmesh_assert(elem);
980984

981-
// Only add BCs for level-0 elements.
982-
libmesh_assert_equal_to (elem->level(), 0);
985+
// Users try to mark boundary on child elements
986+
// If this happens, we will allow users to remove
987+
// side from child elements as well
988+
if (elem->level())
989+
_children_on_boundary = true;
983990

984991
// Don't add the same ID twice
985992
auto bounds = _boundary_side_id.equal_range(elem);
@@ -1356,8 +1363,8 @@ void BoundaryInfo::remove_edge (const Elem * elem,
13561363
{
13571364
libmesh_assert(elem);
13581365

1359-
// Only level 0 elements are stored in BoundaryInfo.
1360-
libmesh_assert_equal_to (elem->level(), 0);
1366+
// Only level 0 elements unless the flag "_children_on_boundary" is on.
1367+
libmesh_assert(elem->level()==0 || _children_on_boundary);
13611368

13621369
// Erase (elem, edge, *) entries from map.
13631370
erase_if(_boundary_edge_id, elem,
@@ -1373,8 +1380,8 @@ void BoundaryInfo::remove_edge (const Elem * elem,
13731380
{
13741381
libmesh_assert(elem);
13751382

1376-
// Only level 0 elements are stored in BoundaryInfo.
1377-
libmesh_assert_equal_to (elem->level(), 0);
1383+
// Only level 0 elements unless the flag "_children_on_boundary" is on.
1384+
libmesh_assert(elem->level() == 0 || _children_on_boundary);
13781385

13791386
// Erase (elem, edge, id) entries from map.
13801387
erase_if(_boundary_edge_id, elem,
@@ -1388,8 +1395,8 @@ void BoundaryInfo::remove_shellface (const Elem * elem,
13881395
{
13891396
libmesh_assert(elem);
13901397

1391-
// Only level 0 elements are stored in BoundaryInfo.
1392-
libmesh_assert_equal_to (elem->level(), 0);
1398+
// Only level 0 elements unless the flag "_children_on_boundary" is on.
1399+
libmesh_assert(elem->level() == 0 || _children_on_boundary);
13931400

13941401
// Shells only have 2 faces
13951402
libmesh_assert_less(shellface, 2);
@@ -1408,8 +1415,8 @@ void BoundaryInfo::remove_shellface (const Elem * elem,
14081415
{
14091416
libmesh_assert(elem);
14101417

1411-
// Only level 0 elements are stored in BoundaryInfo.
1412-
libmesh_assert_equal_to (elem->level(), 0);
1418+
// Only level 0 elements unless the flag "_children_on_boundary" is on.
1419+
libmesh_assert(elem->level() == 0 || _children_on_boundary);
14131420

14141421
// Shells only have 2 faces
14151422
libmesh_assert_less(shellface, 2);
@@ -1425,8 +1432,8 @@ void BoundaryInfo::remove_side (const Elem * elem,
14251432
{
14261433
libmesh_assert(elem);
14271434

1428-
// Only level 0 elements are stored in BoundaryInfo.
1429-
libmesh_assert_equal_to (elem->level(), 0);
1435+
// Only level 0 elements unless the flag "_children_on_boundary" is on.
1436+
libmesh_assert(elem->level() == 0 || _children_on_boundary);
14301437

14311438
// Erase (elem, side, *) entries from map.
14321439
erase_if(_boundary_side_id, elem,
@@ -1442,6 +1449,9 @@ void BoundaryInfo::remove_side (const Elem * elem,
14421449
{
14431450
libmesh_assert(elem);
14441451

1452+
// Only level 0 elements unless the flag "_children_on_boundary" is on.
1453+
libmesh_assert(elem->level() == 0 || _children_on_boundary);
1454+
14451455
// Erase (elem, side, id) entries from map.
14461456
erase_if(_boundary_side_id, elem,
14471457
[side, id](decltype(_boundary_side_id)::mapped_type & pr)
@@ -1488,12 +1498,21 @@ void BoundaryInfo::remove_id (boundary_id_type id)
14881498
unsigned int BoundaryInfo::side_with_boundary_id(const Elem * const elem,
14891499
const boundary_id_type boundary_id_in) const
14901500
{
1491-
const Elem * searched_elem = elem;
1501+
std::vector<const Elem *> searched_elem_vec;
1502+
// If elem has boundary information, we return that when
1503+
// the flag "_children_on_boundary" is on
1504+
if (_children_on_boundary)
1505+
searched_elem_vec.push_back(elem);
1506+
// Otherwise, we return boundary information of its
1507+
// parent if any
14921508
if (elem->level() != 0)
1493-
searched_elem = elem->top_parent();
1509+
searched_elem_vec.push_back(elem->top_parent());
14941510

1495-
// elem may have zero or multiple occurrences
1496-
for (const auto & pr : as_range(_boundary_side_id.equal_range(searched_elem)))
1511+
for (auto it = searched_elem_vec.begin(); it != searched_elem_vec.end(); ++it)
1512+
{
1513+
const Elem * searched_elem = *it;
1514+
// elem may have zero or multiple occurrences
1515+
for (const auto & pr : as_range(_boundary_side_id.equal_range(searched_elem)))
14971516
{
14981517
// if this is true we found the requested boundary_id
14991518
// of the element and want to return the side
@@ -1524,7 +1543,8 @@ unsigned int BoundaryInfo::side_with_boundary_id(const Elem * const elem,
15241543
if (!p)
15251544
return side;
15261545
}
1527-
}
1546+
}
1547+
}
15281548

15291549
// if we get here, we found elem in the data structure but not
15301550
// the requested boundary id, so return the default value
@@ -1538,12 +1558,20 @@ BoundaryInfo::sides_with_boundary_id(const Elem * const elem,
15381558
{
15391559
std::vector<unsigned int> returnval;
15401560

1541-
const Elem * searched_elem = elem;
1561+
std::vector<const Elem *> searched_elem_vec;
1562+
// If elem has boundary information, that is part of return when
1563+
// the flag "_children_on_boundary" is on
1564+
if (_children_on_boundary)
1565+
searched_elem_vec.push_back(elem)
1566+
// Return boundary information of its parent as well
15421567
if (elem->level() != 0)
1543-
searched_elem = elem->top_parent();
1568+
searched_elem_vec.push_back(elem->top_parent());
15441569

1545-
// elem may have zero or multiple occurrences
1546-
for (const auto & pr : as_range(_boundary_side_id.equal_range(searched_elem)))
1570+
for (auto it = searched_elem_vec.begin(); it != searched_elem_vec.end(); ++it)
1571+
{
1572+
const Elem * searched_elem = *it;
1573+
// elem may have zero or multiple occurrences
1574+
for (const auto & pr : as_range(_boundary_side_id.equal_range(searched_elem)))
15471575
{
15481576
// if this is true we found the requested boundary_id
15491577
// of the element and want to return the side
@@ -1578,7 +1606,7 @@ BoundaryInfo::sides_with_boundary_id(const Elem * const elem,
15781606
returnval.push_back(side);
15791607
}
15801608
}
1581-
1609+
}
15821610
return returnval;
15831611
}
15841612

@@ -1791,7 +1819,8 @@ BoundaryInfo::build_node_list_from_side_list()
17911819
// Need to loop over the sides of any possible children
17921820
std::vector<const Elem *> family;
17931821
#ifdef LIBMESH_ENABLE_AMR
1794-
pr.first->active_family_tree_by_side (family, pr.second.first);
1822+
if (!pr.first->subactive())
1823+
pr.first->active_family_tree_by_side (family, pr.second.first);
17951824
#else
17961825
family.push_back(pr.first);
17971826
#endif
@@ -2152,7 +2181,8 @@ BoundaryInfo::build_active_side_list () const
21522181
// Loop over the sides of possible children
21532182
std::vector<const Elem *> family;
21542183
#ifdef LIBMESH_ENABLE_AMR
2155-
pr.first->active_family_tree_by_side(family, pr.second.first);
2184+
if (!pr.first->subactive())
2185+
pr.first->active_family_tree_by_side(family, pr.second.first);
21562186
#else
21572187
family.push_back(pr.first);
21582188
#endif

0 commit comments

Comments
 (0)