From 53c009aa751232596a2d4f2baee4feb5b43e10dd Mon Sep 17 00:00:00 2001 From: bangerth Date: Sat, 30 Dec 2006 05:01:35 +0000 Subject: [PATCH] Fix the problem demonstrated in tria_crash_01, which was caused of using 'cell' instead of 'edge_neighbor'. git-svn-id: https://svn.dealii.org/trunk@14291 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/deal.II/source/grid/tria.cc | 288 ++++++++++++++------------- tests/bits/Makefile | 3 +- tests/bits/tria_crash_01.cc | 7 +- tests/bits/tria_crash_01/cmp/generic | 40 +--- 4 files changed, 155 insertions(+), 183 deletions(-) diff --git a/deal.II/deal.II/source/grid/tria.cc b/deal.II/deal.II/source/grid/tria.cc index 25e79f7d79..b1b601d803 100644 --- a/deal.II/deal.II/source/grid/tria.cc +++ b/deal.II/deal.II/source/grid/tria.cc @@ -7314,147 +7314,156 @@ void Triangulation<3>::prepare_refinement_dim_dependent () break; } } + } + - // there is another thing here: - // if any of the lines will be - // refined, then we may not - // coarsen the present cell - if (cell->line(line)->user_flag_set() - && - cell->coarsen_flag_set()) + // there is another thing here: + // if any of the lines will be + // refined, then we may not + // coarsen the present cell + for (active_cell_iterator cell=last_active(); cell!=end(); --cell) + { + if (cell->coarsen_flag_set()) + for (unsigned int line=0; line::lines_per_cell; ++line) { - cell->clear_coarsen_flag (); - mesh_changed = true; + if (cell->line(line)->user_flag_set()) + { + cell->clear_coarsen_flag (); + mesh_changed = true; - break; - } + goto next_cell; + } - // similarly, if any of the lines - // *is* already refined, we may - // not coarsen the current - // cell. however, there's a - // catch: if the line is refined, - // but the cell behind it is - // going to be coarsened, then - // the situation changes. if we - // forget this second condition, - // the refine_and_coarsen_3d test - // will start to fail. note that - // to know which cells are going - // to be coarsened, the call for - // fix_coarsen_flags above is - // necessary - // - // the problem is that finding - // all cells that are behind an - // edge in 3d is somewhat of a - // pain and worst of all - // introduces a quadratic - // behavior in this algorithm. on - // the other hand, not many cells - // have their coarsen flag set - // usually, and fixing - // refine_and_coarsen_3d is a - // somewhat important case - if (cell->line(line)->has_children() && - cell->coarsen_flag_set()) - { - bool cant_be_coarsened = false; - - // loop over all cells of this - // level to find neighbors of - // this cell and edge - for (cell_iterator edge_neighbor=begin(cell->level()); - ((edge_neighbor != end(cell->level())) - && - (cant_be_coarsened == false)); - ++edge_neighbor) - if (edge_neighbor != cell) - for (unsigned int e=0; e::lines_per_cell; ++e) - if (edge_neighbor->line(e) == cell->line(line)) - { - // this is a cell - // that is adjacent - // to the present - // cell across this - // edge. so treat - // it, but only if - // it is actually - // refined or will - // be refined - if (! (cell->has_children() - || - (!cell->has_children() && - cell->refine_flag_set()))) - break; - - // figure out if - // the neighbor is - // going to be - // coarsened. as a - // post-condition - // of the call to - // fix_coarsen_flags(), - // either all - // children of a - // cell must be - // flagged for - // coarsening, or - // none may. above - // we delete some - // coarsen flags, - // and in the next - // call to - // fix_coarsen_flags() - // the flags to all - // siblings will be - // removed. we will - // check here if - // still all - // children have - // that flag set - unsigned int n_children_flagged = 0; - for (unsigned int c=0; c::children_per_cell; ++c) - if ((edge_neighbor->child(c)->has_children() == false) - && - edge_neighbor->child(c)->coarsen_flag_set()) - ++n_children_flagged; + // similarly, if any of the lines + // *is* already refined, we may + // not coarsen the current + // cell. however, there's a + // catch: if the line is refined, + // but the cell behind it is + // going to be coarsened, then + // the situation changes. if we + // forget this second condition, + // the refine_and_coarsen_3d test + // will start to fail. note that + // to know which cells are going + // to be coarsened, the call for + // fix_coarsen_flags above is + // necessary + // + // the problem is that finding + // all cells that are behind an + // edge in 3d is somewhat of a + // pain and worst of all + // introduces a quadratic + // behavior in this algorithm. on + // the other hand, not many cells + // have their coarsen flag set + // usually, and fixing + // refine_and_coarsen_3d is a + // somewhat important case + if (cell->line(line)->has_children()) + { + bool cant_be_coarsened = false; + + // loop over all cells of this + // level to find neighbors of + // this cell and edge + for (cell_iterator edge_neighbor=begin(cell->level()); + ((edge_neighbor != end(cell->level())) + && + (cant_be_coarsened == false)); + ++edge_neighbor) + if (edge_neighbor != cell) + for (unsigned int e=0; e::lines_per_cell; ++e) + if (edge_neighbor->line(e) == cell->line(line)) + { + // this is a cell + // that is adjacent + // to the present + // cell across this + // edge. so treat + // it, but only if + // it is actually + // refined or will + // be refined + if (! (edge_neighbor->has_children() + || + (!edge_neighbor->has_children() && + edge_neighbor->refine_flag_set()))) + break; + + // figure out if + // the neighbor is + // going to be + // coarsened. as a + // post-condition + // of the call to + // fix_coarsen_flags(), + // either all + // children of a + // cell must be + // flagged for + // coarsening, or + // none may. above + // we delete some + // coarsen flags, + // and in the next + // call to + // fix_coarsen_flags() + // the flags to all + // siblings will be + // removed. we will + // check here if + // still all + // children have + // that flag set + unsigned int n_children_flagged = 0; + for (unsigned int c=0; c::children_per_cell; ++c) + if ((edge_neighbor->child(c)->has_children() == false) + && + edge_neighbor->child(c)->coarsen_flag_set()) + ++n_children_flagged; - // now, if not all - // children are - // flagged, then - // the neighboring - // cell isn't going - // to be - // coarsened. that - // means that the - // common edge - // isn't going to - // be coarsened and - // that we can't - // coarsen the - // present cell - if (n_children_flagged != - GeometryInfo::children_per_cell) - cant_be_coarsened = true; - - - // neighbor was - // found. no reason - // to keep looping - // over edges of - // the possible - // edge_neighbor - break; - } + // now, if not all + // children are + // flagged, then + // the neighboring + // cell isn't going + // to be + // coarsened. that + // means that the + // common edge + // isn't going to + // be coarsened and + // that we can't + // coarsen the + // present cell + if (n_children_flagged != + GeometryInfo::children_per_cell) + cant_be_coarsened = true; + + + // neighbor was + // found. no reason + // to keep looping + // over edges of + // the possible + // edge_neighbor + break; + } - if (cant_be_coarsened == true) - { - cell->clear_coarsen_flag (); - mesh_changed = true; + if (cant_be_coarsened == true) + { + cell->clear_coarsen_flag (); + mesh_changed = true; + + goto next_cell; + } } } - } + next_cell: + ; + } } while (mesh_changed == true); } @@ -7491,11 +7500,6 @@ void Triangulation::fix_coarsen_flags () // i.e. on the coarsest level are // deleted explicitly. clear_user_flags (); - // number of active children of - // @p{cell}. number of children of - // @p{cell} which are flagged for - // coarsening - unsigned int flagged_children; cell_iterator cell = begin(), endc = end(); @@ -7513,7 +7517,7 @@ void Triangulation::fix_coarsen_flags () continue; } - flagged_children = 0; + unsigned int flagged_children = 0; for (unsigned int child=0; child::children_per_cell; ++child) if (cell->child(child)->active() && cell->child(child)->coarsen_flag_set()) @@ -7612,6 +7616,7 @@ void Triangulation::fix_coarsen_flags () } + template bool Triangulation::prepare_coarsening_and_refinement () { @@ -8404,6 +8409,7 @@ bool Triangulation::prepare_coarsening_and_refinement () } while (mesh_changed_in_this_loop); + // find out whether something was really // changed in this function. Note that // @p{flags_before_loop} represents the @@ -8891,8 +8897,8 @@ void Triangulation<3>::delete_children (cell_iterator &cell) Assert (cell->line(line)->has_children(), ExcInternalError()); for (unsigned int c=0; c<2; ++c) - Assert (!cell->line(line)->child(c)->has_children(), - ExcInternalError()); + Assert (!cell->line(line)->child(c)->has_children(), + ExcInternalError()); } diff --git a/tests/bits/Makefile b/tests/bits/Makefile index a04d9c6b0b..e95fede3d9 100644 --- a/tests/bits/Makefile +++ b/tests/bits/Makefile @@ -83,7 +83,8 @@ tests_x = grid_generator_?? \ face_interpolation \ subface_interpolation \ face_orientation_crash \ - refine_and_coarsen_* + refine_and_coarsen_* \ + tria_crash_* # tests for the hp branch: # fe_collection_* diff --git a/tests/bits/tria_crash_01.cc b/tests/bits/tria_crash_01.cc index 0cc81cd7db..ccb8cbb9f0 100644 --- a/tests/bits/tria_crash_01.cc +++ b/tests/bits/tria_crash_01.cc @@ -41,10 +41,7 @@ int main () deallog.depth_console(0); const unsigned int dim=3; - Point origin; - CylinderBoundary boundary; Triangulation tria; - tria.set_boundary(0, boundary); GridGenerator::cylinder(tria, 1, .7); deallog << "n_cells=" << tria.n_active_cells() << std::endl; @@ -68,7 +65,7 @@ int main () deallog << "n_cells=" << tria.n_active_cells() << std::endl; - + for (cell=tria.begin_active(); cell!=endc; ++cell) if (!predicate (cell->center(), cell->diameter())) cell->set_coarsen_flag (); @@ -78,7 +75,7 @@ int main () tria.prepare_coarsening_and_refinement(); for (cell=tria.begin_active(); cell!=endc; ++cell) Assert (!cell->refine_flag_set(), ExcInternalError()); - + tria.execute_coarsening_and_refinement(); deallog << "n_cells=" << tria.n_active_cells() << std::endl; diff --git a/tests/bits/tria_crash_01/cmp/generic b/tests/bits/tria_crash_01/cmp/generic index f08e311b42..ffef124a61 100644 --- a/tests/bits/tria_crash_01/cmp/generic +++ b/tests/bits/tria_crash_01/cmp/generic @@ -1,37 +1,5 @@ -DEAL::Initial check -DEAL:: ok. -DEAL::Check 0 -DEAL:: ok. -DEAL::Check 1 -DEAL:: ok. -DEAL::Check 2 -DEAL:: ok. -DEAL::Check 1 -DEAL:: ok. -DEAL::Check 2 -DEAL:: ok. -DEAL::Initial check -DEAL:: ok. -DEAL::Check 0 -DEAL:: ok. -DEAL::Check 1 -DEAL:: ok. -DEAL::Check 2 -DEAL:: ok. -DEAL::Check 1 -DEAL:: ok. -DEAL::Check 2 -DEAL:: ok. -DEAL::Initial check -DEAL:: ok. -DEAL::Check 0 -DEAL:: ok. -DEAL::Check 1 -DEAL:: ok. -DEAL::Check 2 -DEAL:: ok. -DEAL::Check 1 -DEAL:: ok. -DEAL::Check 2 -DEAL:: ok. +DEAL::n_cells=10 +DEAL::n_cells=640 +DEAL::n_cells=1452 +DEAL::n_cells=696 -- 2.39.5