@@ -1247,9 +1247,9 @@ void BoundaryInfo::boundary_ids (const Elem * const elem,
12471247 // Clear out any previous contents
12481248 vec_to_fill .clear ();
12491249
1250- // In most of the cases only level-0 elements store BCs.
1250+ // In most cases only level-0 elements store BCs.
12511251 // In certain application (such as time-dependent domains), however, children
1252- // need to store BSc too. This case is covered with the _children_on_boundary
1252+ // need to store BCs too. This case is covered with the _children_on_boundary
12531253 // flag.
12541254 const Elem * searched_elem = elem ;
12551255
@@ -1261,29 +1261,24 @@ void BoundaryInfo::boundary_ids (const Elem * const elem,
12611261 // child and its ancestors too if they share the side.
12621262 if (_children_on_boundary )
12631263 {
1264- for (const auto & pr : as_range (_boundary_side_id .equal_range (searched_elem )))
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 ())
1269- vec_to_fill .push_back (pr .second .second );
1270-
12711264 // Loop over ancestors to check if they have boundary ids on the same side
1272- while (searched_elem -> parent () != nullptr )
1265+ while (searched_elem )
12731266 {
1267+ for (const auto & pr : as_range (_boundary_side_id .equal_range (searched_elem )))
1268+ // Here we need to check if the boundary id already exists
1269+ if (pr .second .first == side &&
1270+ std ::find (vec_to_fill .begin (), vec_to_fill .end (), pr .second .second ) ==
1271+ vec_to_fill .end ())
1272+ vec_to_fill .push_back (pr .second .second );
1273+
1274+
12741275 const Elem * parent = searched_elem -> parent ();
1275- if (parent -> is_child_on_side (parent -> which_child_am_i (searched_elem ), side ) == false)
1276+ // If the parent doesn't exist or if the child is not on the correct side of the
1277+ // parent we are done checking the ancestors
1278+ if (!parent || parent -> is_child_on_side (parent -> which_child_am_i (searched_elem ), side ) == false)
12761279 return ;
12771280
12781281 searched_elem = parent ;
1279-
1280- if (_children_on_boundary )
1281- for (const auto & pr : as_range (_boundary_side_id .equal_range (searched_elem )))
1282- // Here we need to check if the boundary id already exists
1283- if (pr .second .first == side &&
1284- std ::find (vec_to_fill .begin (), vec_to_fill .end (), pr .second .second ) ==
1285- vec_to_fill .end ())
1286- vec_to_fill .push_back (pr .second .second );
12871282 }
12881283
12891284 return ;
@@ -1775,7 +1770,7 @@ BoundaryInfo::sides_with_boundary_id(const Elem * const elem,
17751770
17761771#ifdef LIBMESH_ENABLE_AMR
17771772 // We might have instances (especially with moving boundary domains) when we
1778- // query the paren't boundary ID on a child.
1773+ // query the parent boundary ID on a child.
17791774 if (_children_on_boundary && elem -> level () != 0 )
17801775 {
17811776 for (auto side : make_range (elem -> n_sides ()))
@@ -1854,58 +1849,57 @@ BoundaryInfo::build_shellface_boundary_ids(std::vector<boundary_id_type> & b_ids
18541849}
18551850
18561851void
1857- BoundaryInfo ::transfer_boundary_ids_to_parent (const Elem * const elem )
1852+ BoundaryInfo ::transfer_boundary_ids_from_children (const Elem * const parent )
18581853{
18591854
18601855 // this is only needed when we allow boundary to be associated with children elements
18611856 // also, we only transfer the parent's boundary ids when we are actually coarsen the child element
18621857 if (!_children_on_boundary ||
1863- !(!elem -> active () && elem -> refinement_flag () == Elem ::COARSEN_INACTIVE ))
1858+ !(!parent -> active () && parent -> refinement_flag () == Elem ::COARSEN_INACTIVE ))
18641859 return ;
18651860
1861+ // We assume that edges can be divided ito two pieces, while triangles and
1862+ // quads can be divided into four smaller areas. This is double because we'll need
1863+ // to convert the ratio of the children with given boundary id to a double.
1864+ const double number_of_sides_on_children = std ::pow (2 , parent -> dim ()- 1 );
1865+
18661866 // In this case the input argument elem is the parent element. We need to check all of its sides
18671867 // to grab any potential boundary ids.
1868- for (unsigned int side_i = 0 ; side_i < elem -> n_sides (); ++ side_i )
1868+ for (unsigned int side_i = 0 ; side_i < parent -> n_sides (); ++ side_i )
18691869 {
18701870 // An temporary storage to count how many times the children's boundaries occur. the general
18711871 // consensus is that if the boundary occurs more than once we propagate upon coarsening. Otherwise,
18721872 // it will get deleted.
18731873 std ::map < unsigned short int , unsigned short int > boundary_counts ;
18741874
1875- for (const auto & child_i : make_range (elem -> n_children ()))
1875+ for (const auto & child_i : make_range (parent -> n_children ()))
18761876 {
18771877 // We only need to check the children which share the side
1878- if (elem -> is_child_on_side (child_i , side_i ))
1878+ if (parent -> is_child_on_side (child_i , side_i ))
18791879 {
18801880 // Fetching the boundary tags on the child's side
1881- for (const auto & pr : as_range (_boundary_side_id .equal_range (elem -> child_ptr (child_i ))))
1881+ for (const auto & pr : as_range (_boundary_side_id .equal_range (parent -> child_ptr (child_i ))))
18821882 {
18831883 // Making sure we are on the same boundary
18841884 if (pr .second .first == side_i )
1885- {
1886- // If this is the first time we hit this boundary tag, we create an entry for it in the map
1887- if (!boundary_counts .count (pr .second .second ))
1888- boundary_counts .insert ({pr .second .second , 0 });
1889- // Otherwise, just increment the count
1890- boundary_counts [pr .second .second ] += 1 ;
1891- }
1885+ ++ boundary_counts [pr .second .second ];
18921886 }
18931887 }
18941888 }
18951889
1896- // This is where the decision is made. If we the given tags occur more than one, we propagate them
1897- // upwards upon coarsening. Otherwise, they are deleted.
1890+ // This is where the decision is made. If 50% of the children have the tags,
1891+ // we propagate them upwards upon coarsening. Otherwise, they are deleted.
18981892 for (const auto & boundary : boundary_counts )
18991893 {
1900- if (boundary .second > 1 )
1901- this -> add_side (elem , side_i , boundary .first );
1894+ if (boundary .second / number_of_sides_on_children > 0.5 )
1895+ this -> add_side (parent , side_i , boundary .first );
19021896 else
1903- this -> remove_side (elem , side_i , boundary .first );
1897+ this -> remove_side (parent , side_i , boundary .first );
19041898 }
19051899 }
19061900
1907- for (const auto & child_i : make_range (elem -> n_children ()))
1908- this -> remove (elem -> child_ptr (child_i ));
1901+ for (const auto & child_i : make_range (parent -> n_children ()))
1902+ this -> remove (parent -> child_ptr (child_i ));
19091903}
19101904
19111905std ::size_t BoundaryInfo ::n_boundary_conds () const
0 commit comments