Skip to content

Commit 5786158

Browse files
committed
Modify unit test.
1 parent c2f68b1 commit 5786158

File tree

3 files changed

+79
-58
lines changed

3 files changed

+79
-58
lines changed

src/mesh/boundary_info.C

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,16 +1260,14 @@ void BoundaryInfo::boundary_ids (const Elem * const elem,
12601260
// If we have children on the boundaries, we need to search for boundary IDs on the
12611261
// child and its ancestors too if they share the side.
12621262
if (_children_on_boundary)
1263+
{
12631264
for (const auto & pr : as_range(_boundary_side_id.equal_range(searched_elem)))
1264-
if (pr.second.first == side)
1265+
// We check if we already have this ID, we might have inherited it from our ancestors
1266+
if (pr.second.first == side &&
1267+
std::find(vec_to_fill.begin(), vec_to_fill.end(), pr.second.second) ==
1268+
vec_to_fill.end())
12651269
vec_to_fill.push_back(pr.second.second);
12661270

1267-
// If we don't have children on boundaries and we are on an external boundary,
1268-
// we just look for the top parent
1269-
if (elem->neighbor_ptr(side) == nullptr)
1270-
searched_elem = elem->top_parent();
1271-
// Otherwise we loop over the ancestors and check if they have a different BC for us
1272-
else
12731271
while (searched_elem->parent() != nullptr)
12741272
{
12751273
const Elem * parent = searched_elem->parent();
@@ -1282,10 +1280,28 @@ void BoundaryInfo::boundary_ids (const Elem * const elem,
12821280
for (const auto & pr : as_range(_boundary_side_id.equal_range(searched_elem)))
12831281
// Here we need to check if the boundary id already exists
12841282
if (pr.second.first == side &&
1285-
std::find(vec_to_fill.begin(), vec_to_fill.end(), pr.second.second) !=
1283+
std::find(vec_to_fill.begin(), vec_to_fill.end(), pr.second.second) ==
12861284
vec_to_fill.end())
12871285
vec_to_fill.push_back(pr.second.second);
12881286
}
1287+
1288+
return;
1289+
}
1290+
1291+
// If we don't have children on boundaries and we are on an external boundary,
1292+
// we just look for the top parent
1293+
if (elem->neighbor_ptr(side) == nullptr)
1294+
searched_elem = elem->top_parent();
1295+
// Otherwise we loop over the ancestors and check if they have a different BC for us
1296+
else
1297+
while (searched_elem->parent() != nullptr)
1298+
{
1299+
const Elem * parent = searched_elem->parent();
1300+
if (parent->is_child_on_side(parent->which_child_am_i(searched_elem), side) == false)
1301+
return;
1302+
1303+
searched_elem = parent;
1304+
}
12891305
}
12901306

12911307
#endif
@@ -1768,40 +1784,46 @@ BoundaryInfo::transfer_boundary_ids_to_parent(const Elem * const elem)
17681784
// this is only needed when we allow boundary to be associated with children elements
17691785
// also, we only transfer the parent's boundary ids when we are actually coarsen the child element
17701786
if (!_children_on_boundary ||
1771-
!elem->active() ||
1772-
elem->level()==0 ||
1773-
elem->refinement_flag() != Elem::COARSEN)
1787+
!(!elem->active() && elem->refinement_flag() == Elem::COARSEN_INACTIVE))
17741788
return;
17751789

1776-
const Elem * parent = elem->parent();
1777-
1778-
for (const auto & pr : as_range(_boundary_side_id.equal_range(elem)))
1790+
// In this case the input argument elem is the parent element. We need to check all of its sides
1791+
// to grab any potential boundary ids.
1792+
for (unsigned int side_i = 0; side_i < elem->n_sides(); ++side_i)
17791793
{
1780-
auto side = pr.second.first;
1781-
auto bnd_id = pr.second.second;
1782-
// Track if any of the sibling elements is on this boundary.
1783-
// If yes, we make sure that the corresponding parent side is added to the boundary.
1784-
// Otherwise, we remove the parent side from the boundary.
1785-
if (parent->is_child_on_side(parent->which_child_am_i(elem), side))
1786-
for (auto & sibling : parent->child_ref_range())
1794+
// An temporary storage to count how many times the children's boundaries occur. the general
1795+
// consensus is that if the boundary occurs more than once we propagate upon coarsening. Otherwise,
1796+
// it will get deleted.
1797+
std::map<unsigned short int, unsigned short int> boundary_counts;
1798+
1799+
for (auto & child : elem->child_ref_range())
1800+
{
1801+
// We only need to check the children which share the side
1802+
if (elem->is_child_on_side(elem->which_child_am_i(&child), side_i) == true)
1803+
// Fetching the boundary tags on the child's side
1804+
for (const auto & pr : as_range(_boundary_side_id.equal_range(&child)))
17871805
{
1788-
// Check siblings only if they are on the same side
1789-
if (&sibling != elem &&
1790-
parent->is_child_on_side(parent->which_child_am_i(&sibling), side) == true)
1791-
{
1792-
if (this->has_boundary_id(&sibling, side, bnd_id))
1793-
{
1794-
// Do not worry, `add_side` will avoid adding duplicate sides on the
1795-
// same boundary Note: it is assumed that the child and parent
1796-
// elements' side numberings are identical. I.e., a child's ith side
1797-
// is encompassed in the parent's jth side, where i=j.
1798-
this->add_side(parent, side, bnd_id);
1799-
return;
1800-
}
1801-
}
1806+
// Making sure we are on the same boundary
1807+
if (pr.second.first == side_i)
1808+
{
1809+
// If this is the first time we hit this boundary tag, we create an entry for it in the map
1810+
if (!boundary_counts.count(pr.second.second))
1811+
boundary_counts.insert({pr.second.second, 0});
1812+
// Otherwise, just increment the count
1813+
boundary_counts[pr.second.second] += 1;
1814+
}
18021815
}
1803-
// No relatives share the same boundary, therefore, we remove it from the parent, if any.
1804-
this->remove_side(parent, side, bnd_id);
1816+
}
1817+
1818+
// This is where the decision is made. If we the given tags occur more than one, we propagate them
1819+
// upwards upon coarsening. Otherwise, they are deleted.
1820+
for (const auto & boundary : boundary_counts)
1821+
{
1822+
if (boundary.second > 1)
1823+
this->add_side(elem, side_i, boundary.first);
1824+
else
1825+
this->remove_side(elem, side_i, boundary.first);
1826+
}
18051827
}
18061828
}
18071829

src/mesh/mesh_refinement.C

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1393,7 +1393,7 @@ bool MeshRefinement::_coarsen_elements ()
13931393
// otherwise we will have trouble in boundary info consistency among
13941394
// parent and children elements
13951395
if (!_mesh.get_boundary_info().is_children_on_boundary_side())
1396-
_mesh.get_boundary_info().remove (elem);
1396+
_mesh.get_boundary_info().remove(elem);
13971397

13981398
// Add this iterator to the _unused_elements
13991399
// data structure so we might fill it.

tests/mesh/boundary_info.C

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public:
2929
CPPUNIT_TEST( testMesh );
3030
CPPUNIT_TEST( testRenumber );
3131
#ifdef LIBMESH_ENABLE_AMR
32-
CPPUNIT_TEST( testBoundaryOnChildrenElements );
32+
CPPUNIT_TEST( testBoundaryOnChildrenElementsRefineCoarsen );
3333
# endif
3434
# ifdef LIBMESH_ENABLE_DIRICHLET
3535
CPPUNIT_TEST( testShellFaceConstraints );
@@ -479,7 +479,7 @@ public:
479479
#endif // LIBMESH_ENABLE_DIRICHLET
480480

481481
#ifdef LIBMESH_ENABLE_AMR
482-
void testBoundaryOnChildrenElements()
482+
void testBoundaryOnChildrenElementsRefineCoarsen()
483483
{
484484
LOG_UNIT_TEST;
485485

@@ -494,7 +494,8 @@ public:
494494

495495
BoundaryInfo & bi = mesh->get_boundary_info();
496496

497-
// Set subdomain ids for specific elements
497+
// Set subdomain ids for specific elements, we will refine/coarsen
498+
// the cell on subdomain 1
498499
// _____________
499500
// | 1 | 2 |
500501
// |_____|_____|
@@ -524,56 +525,54 @@ public:
524525
mesh->prepare_for_use();
525526

526527
// Check the middle boundary, we expect to have two sides in boundary 5
527-
auto boundary_side_id = bi.get_sideset_map();
528528
unsigned int count = 0;
529529
for (auto & elem : mesh->active_element_ptr_range())
530-
{
531-
if (bi.has_boundary_id(elem, 1, 5))
532-
count++;
533-
}
530+
if (bi.has_boundary_id(elem, 1, 5))
531+
count++;
532+
534533
CPPUNIT_ASSERT_EQUAL((unsigned int) 2, count);
535534
CPPUNIT_ASSERT(bi.is_children_on_boundary_side());
536535

537-
// Remove the top element side on boundary 5, mark it to coarsen
536+
// First, we will coarsen the the elements on subdomain 1. This
537+
// is to check if the boundary information propagates upward upon
538+
// coarsening.
538539
for (auto & elem : mesh->active_element_ptr_range())
539540
{
540541
const Point c = elem->vertex_average();
541-
if (c(0) > 0.5 && c(0) < 1 && c(1) > 0.5)
542-
{
542+
if (c(0) < 1)
543543
elem->set_refinement_flag(Elem::COARSEN);
544-
bi.remove_side(elem, 1, 5);
545-
CPPUNIT_ASSERT(!bi.has_boundary_id(elem, 1, 5));
546-
}
547544
}
548545
mesh->prepare_for_use();
549546

550547
// The coarsened element should have its side on boundary 5
551548
// This is boundary info transferred from this child element
552549
MeshRefinement(*mesh).coarsen_elements();
553550
mesh->prepare_for_use();
551+
554552
for (auto & elem : mesh->active_element_ptr_range())
555553
{
556554
const Point c = elem->vertex_average();
557555
if (c(0) < 1)
558556
{
559557
CPPUNIT_ASSERT(bi.has_boundary_id(elem, 1, 5));
560-
// we refine again later
558+
// we will refine this element again
561559
elem->set_refinement_flag(Elem::REFINE);
562560
}
563561
}
564562

565563
MeshRefinement(*mesh).refine_elements();
566564
mesh->prepare_for_use();
567565

568-
// This time we remove boundary 5 from all children sides
566+
// This time we remove boundary 5 from one of the children. We expect
567+
// the boundary not to propagate to the next level. Furthermore we
568+
// expect boundary 5 to be deleted from the parent's boundaries
569569
for (auto & elem : mesh->active_element_ptr_range())
570570
{
571571
const Point c = elem->vertex_average();
572-
if (c(0) < 1 && c(0) > 0.5)
573-
{
574-
bi.remove_side(elem, 1, 5);
572+
if (c(0) < 1)
575573
elem->set_refinement_flag(Elem::COARSEN);
576-
}
574+
if (c(1) > 0.5)
575+
bi.remove_side(elem, 1, 5);
577576
}
578577
mesh->prepare_for_use();
579578

0 commit comments

Comments
 (0)