From: bangerth Date: Wed, 27 Dec 2006 17:26:28 +0000 (+0000) Subject: Fix refine_and_coarsen at least for the 1d and 2d cases. 3d has some additional quirk... X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fee96a1f7a39f6c50d100ad025127566041218d3;p=dealii-svn.git Fix refine_and_coarsen at least for the 1d and 2d cases. 3d has some additional quirks that I will need to find out about this afternoon. git-svn-id: https://svn.dealii.org/trunk@14276 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/deal.II/source/grid/tria.cc b/deal.II/deal.II/source/grid/tria.cc index 207f9d10aa..95190e9cde 100644 --- a/deal.II/deal.II/source/grid/tria.cc +++ b/deal.II/deal.II/source/grid/tria.cc @@ -7423,39 +7423,60 @@ void Triangulation::fix_coarsen_flags () Assert (cell->coarsen_flag_set() == false, ExcInternalError()); #endif - // revert change of flags: use - // coarsen flags again and delete - // user flags + // now loop over all cells which have the + // user flag set. their children were + // flagged for coarsening. set the coarsen + // flag again if we are sure that none of + // the neighbors of these children are + // refined, or will be refined, since then + // we would get a two-level jump in + // refinement. on the other hand, if one of + // the children's neighbors has their user + // flag set, then we know that its children + // will go away by coarsening, and we will + // be ok. + // + // note on the other hand that we do allow + // level-2 jumps in refinement between + // neighbors in 1d, so this whole procedure + // is only necessary if we are not in 1d + // + // since we remove some coarsening/user + // flags in the process, we have to work + // from the finest level to the coarsest + // one, since we occasionally inspect user + // flags of cells on finer levels and need + // to be sure that these flags are final for (cell=last(); cell!=endc; --cell) if (cell->user_flag_set()) { - cell->clear_user_flag(); - - // find out whether the - // children of this cell may - // be flagged for refinement bool coarsening_allowed = true; - for (unsigned int c=0; c::children_per_cell; ++c) - for (unsigned int n=0; n::faces_per_cell; ++n) - { - const cell_iterator child_neighbor = cell->child(c)->neighbor(n); - if (child_neighbor.state() == IteratorState::valid) - if (child_neighbor->has_children() || - // neighbor has children, - // then only allow coarsening - // if this neighbor will be - // coarsened as well. however, - // I don't see the consequences - // of this case, so simply - // disallow coarsening if - // any neighbor is more - // refined. maybe someone - // else will want to do this - // some time - (child_neighbor->refine_flag_set() && - (child_neighbor->level()==cell->level()+1))) - coarsening_allowed = false; - } + + if (dim > 1) + { + for (unsigned int c=0; + (c::children_per_cell) && (coarsening_allowed==true); + ++c) + for (unsigned int n=0; n::faces_per_cell; ++n) + { + const cell_iterator child_neighbor = cell->child(c)->neighbor(n); + if ((child_neighbor.state() == IteratorState::valid) + && + (child_neighbor->level()==cell->level()+1) + && + ((child_neighbor->has_children() + && + !child_neighbor->user_flag_set()) + || + (child_neighbor->has_children() + && + child_neighbor->refine_flag_set()))) + { + coarsening_allowed = false; + break; + } + } + } // if allowed: tag the // children for coarsening @@ -7468,6 +7489,10 @@ void Triangulation::fix_coarsen_flags () cell->child(c)->set_coarsen_flag(); } } + + // clear all user flags again, now that we + // don't need them any more + clear_user_flags (); } diff --git a/deal.II/doc/news/changes.html b/deal.II/doc/news/changes.html index 6d31f4f082..72da0b2d35 100644 --- a/deal.II/doc/news/changes.html +++ b/deal.II/doc/news/changes.html @@ -959,6 +959,20 @@ inconvenience this causes.

deal.II

    +
  1. + Fixed: The Triangulation::execute_coarsening_and_refinement function has to + discard coarsening flags in 2d and 3d if a neighbor of a flagged cell is + refined or will be refined, in order to avoid that we end up with + neighboring cells that differ in refinement by two levels. The function + was overly conservative, however, in that it didn't allow a cell to be + coarsened if its neighbor is once refined but is also marked for + coarsening. This is now fixed and will lead to a few more cells being + coarsened. +
    + (Yaqi Wang, WB 2006/12/27) +

    +
  2. Fixed: The Triangulation:: MeshSmoothing flag patch_level_1 wrongly produced cells diff --git a/tests/bits/Makefile b/tests/bits/Makefile index c92056f0dc..4b8e16ce35 100644 --- a/tests/bits/Makefile +++ b/tests/bits/Makefile @@ -82,7 +82,8 @@ tests_x = grid_generator_?? \ hp_constraints* \ face_interpolation \ subface_interpolation \ - face_orientation_crash + face_orientation_crash \ + refine_and_coarsen # tests for the hp branch: # fe_collection_* diff --git a/tests/bits/refine_and_coarsen.cc b/tests/bits/refine_and_coarsen.cc new file mode 100644 index 0000000000..46b868f264 --- /dev/null +++ b/tests/bits/refine_and_coarsen.cc @@ -0,0 +1,88 @@ +//---------------------------- refine_and_coarsen.cc --------------------------- +// $Id: refine_and_coarsen.cc 11749 2005-11-09 19:11:20Z wolf $ +// Version: $Name$ +// +// Copyright (C) 2006 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- refine_and_coarsen.cc --------------------------- + + +// check that if we take an locally refined mesh, refine it globally once, +// then coarsen it globally again, that we get the same mesh + +#include "../tests.h" + +#include +#include +#include +#include +#include +#include + +#include + + + +template +void check () +{ + Triangulation tria; + GridGenerator::hyper_cube (tria); + tria.refine_global (2); + tria.begin_active()->set_refine_flag(); + tria.execute_coarsening_and_refinement (); + + // store which cells we have here + std::vector::active_cell_iterator> cells; + for (typename Triangulation::active_cell_iterator cell=tria.begin_active(); + cell != tria.end(); ++cell) + cells.push_back (cell); + + const unsigned int n_cells = tria.n_active_cells(); + deallog << n_cells << std::endl; + + // refine the mesh globally, then coarsen + // it again globally + tria.refine_global (1); + + for (typename Triangulation::active_cell_iterator cell=tria.begin_active(); + cell != tria.end(); ++cell) + cell->set_coarsen_flag (); + tria.execute_coarsening_and_refinement (); + + + // verify that we get the same cells again + deallog << n_cells << ' ' << tria.n_active_cells() + << std::endl; + + Assert (tria.n_active_cells() == n_cells, + ExcInternalError()); + + unsigned int index = 0; + for (typename Triangulation::active_cell_iterator cell=tria.begin_active(); + cell != tria.end(); ++cell, ++index) + Assert (cells[index] == cell, + ExcInternalError()); + +} + + +int main () +{ + std::ofstream logfile("refine_and_coarsen/output"); + deallog.attach(logfile); + deallog.depth_console(0); + deallog.threshold_double(1.e-10); + + check<1> (); + check<2> (); + check<3> (); +} + + + diff --git a/tests/bits/refine_and_coarsen/cmp/generic b/tests/bits/refine_and_coarsen/cmp/generic new file mode 100644 index 0000000000..f08e311b42 --- /dev/null +++ b/tests/bits/refine_and_coarsen/cmp/generic @@ -0,0 +1,37 @@ + +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.