@@ -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
0 commit comments