Skip to content

Commit b930170

Browse files
committed
Transfer child element's boundary info (add or remove) during coarsening, if the child element has boundary info associated with itself
1 parent 7476940 commit b930170

File tree

4 files changed

+70
-3
lines changed

4 files changed

+70
-3
lines changed

include/mesh/boundary_info.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,20 @@ class BoundaryInfo : public ParallelObject
550550
*/
551551
void build_shellface_boundary_ids(std::vector<boundary_id_type> & b_ids) const;
552552

553+
/**
554+
* Update parent's boundary id list so that this information is consistent with
555+
* its children elements
556+
*
557+
* This is useful when `_children_on_boundary = true`, and is used when the
558+
* element is about to get coarsened i.e., in MeshRefinement::_coarsen_elements()
559+
*
560+
* Specifically, when coarsen a child element who is the last child on that
561+
* boundary, we remove that boundary on the parent's side accordingly.
562+
*
563+
* Otherwise, we add the parent's side to the boundary.
564+
*/
565+
void transfer_boundary_ids_to_parent(const Elem * const elem);
566+
553567
/**
554568
* \returns The number of element-side-based boundary conditions.
555569
*

include/mesh/mesh_refinement.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ class MeshRefinement : public ParallelObject
241241
*
242242
* \note This function used to take an argument, \p maintain_level_one,
243243
* new code should use face_level_mismatch_limit() instead.
244+
*
245+
* \note When we allow boundary be associated with children elements,
246+
* i.e., `_children_on_boundary = true`. A tpyical child boundary ID may be
247+
* lost during coarsening if that child has different IDs from its siblings.
244248
*/
245249
bool coarsen_elements ();
246250

src/mesh/boundary_info.C

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1600,7 +1600,7 @@ unsigned int BoundaryInfo::side_with_boundary_id(const Elem * const elem,
16001600
// Otherwise, we return boundary information of all its ancestors
16011601
if (elem->level() != 0)
16021602
{
1603-
Elem * parent = elem->parent();
1603+
const Elem * parent = elem->parent();
16041604
while (parent != nullptr)
16051605
{
16061606
searched_elem_vec.push_back(parent);
@@ -1757,6 +1757,47 @@ BoundaryInfo::build_shellface_boundary_ids(std::vector<boundary_id_type> & b_ids
17571757
}
17581758
}
17591759

1760+
void
1761+
BoundaryInfo::transfer_boundary_ids_to_parent(const Elem * const elem)
1762+
{
1763+
// this is only needed when we allow boundary to be associated with children elements
1764+
if (!_children_on_boundary || !elem->active())
1765+
return;
1766+
1767+
// we only transfer the parent's boundary ids when we are actually coarsen the child element
1768+
libmesh_assert (elem->level()!=0 && elem->refinement_flag() == Elem::COARSEN);
1769+
1770+
const Elem * parent = elem->parent();
1771+
1772+
for (const auto & pr : as_range(_boundary_side_id.equal_range(elem)))
1773+
{
1774+
auto side = pr.second.first;
1775+
auto bnd_id = pr.second.second;
1776+
// Track if any of the sibling elements is on this boundary.
1777+
// If yes, we make sure that the corresponding parent side is added to the boundary.
1778+
// Otherwise, we remove the parent side from the boundary.
1779+
std::vector<const Elem *> family_on_side;
1780+
elem->family_tree_by_side(family_on_side, side);
1781+
for (auto relative : family_on_side)
1782+
{
1783+
if (relative != elem && relative->level() == elem->level()) // check only siblings
1784+
{
1785+
for (unsigned int i = 0; i < relative->n_sides(); ++i)
1786+
if (this->has_boundary_id(relative, i, bnd_id))
1787+
{
1788+
// Do not worry, `add_side` will avoid adding duplicate sides on the same boundary
1789+
// Note: it is assumed that the child and parent elements' side numberings are identical.
1790+
// I.e., a child's ith side is encompassed in the parent's jth side, where i=j.
1791+
this->add_side(parent, side, bnd_id);
1792+
return;
1793+
}
1794+
}
1795+
}
1796+
// No relative share the same boundary, therefore, we remove it from the parent, if any.
1797+
this->remove_side(parent, side, bnd_id);
1798+
}
1799+
}
1800+
17601801
std::size_t BoundaryInfo::n_boundary_conds () const
17611802
{
17621803
// in serial we know the number of bcs from the

src/mesh/mesh_refinement.C

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,11 @@ bool MeshRefinement::_coarsen_elements ()
13711371

13721372
for (auto & elem : _mesh.element_ptr_range())
13731373
{
1374+
// Make sure we transfer the element's boundary id(s)
1375+
// up to its parent when necessary before coarsening.
1376+
// This can be adding or removing the corresonding boundary info.
1377+
_mesh.get_boundary_info().transfer_boundary_ids_to_parent(elem);
1378+
13741379
// active elements flagged for coarsening will
13751380
// no longer be deleted until MeshRefinement::contract()
13761381
if (elem->refinement_flag() == Elem::COARSEN)
@@ -1384,8 +1389,11 @@ bool MeshRefinement::_coarsen_elements ()
13841389
elem->nullify_neighbors();
13851390

13861391
// Remove any boundary information associated
1387-
// with this element
1388-
_mesh.get_boundary_info().remove (elem);
1392+
// with this element if we do not allow children to have boundary info
1393+
// otherwise we will have trouble in boundary info consistency among
1394+
// parent and children elements
1395+
if (!_mesh.get_boundary_info().is_children_on_boundary_side())
1396+
_mesh.get_boundary_info().remove (elem);
13891397

13901398
// Add this iterator to the _unused_elements
13911399
// data structure so we might fill it.

0 commit comments

Comments
 (0)