]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Fix refine_and_coarsen at least for the 1d and 2d cases. 3d has some additional quirk...
authorbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 27 Dec 2006 17:26:28 +0000 (17:26 +0000)
committerbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 27 Dec 2006 17:26:28 +0000 (17:26 +0000)
git-svn-id: https://svn.dealii.org/trunk@14276 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/deal.II/source/grid/tria.cc
deal.II/doc/news/changes.html
tests/bits/Makefile
tests/bits/refine_and_coarsen.cc [new file with mode: 0644]
tests/bits/refine_and_coarsen/cmp/generic [new file with mode: 0644]

index 207f9d10aa97497aa2f1ed8faa7e6d9ae400c554..95190e9cde59e780f3fc330adf2c51dc9cc393a4 100644 (file)
@@ -7423,39 +7423,60 @@ void Triangulation<dim>::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<GeometryInfo<dim>::children_per_cell; ++c)
-         for (unsigned int n=0; n<GeometryInfo<dim>::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<GeometryInfo<dim>::children_per_cell) && (coarsening_allowed==true);
+                ++c)
+             for (unsigned int n=0; n<GeometryInfo<dim>::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<dim>::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 ();
 }
 
 
index 6d31f4f082f7eec2e3e2b2191d23f920af979c76..72da0b2d356204bcb44a51ac87d1aa82c2a776de 100644 (file)
@@ -959,6 +959,20 @@ inconvenience this causes.
 <h3>deal.II</h3>
 
 <ol>
+  <li> <p>
+       Fixed: The <code class="class">Triangulation</code>::<code
+       class="member">execute_coarsening_and_refinement</code> 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.
+       <br>
+       (Yaqi Wang, WB 2006/12/27)
+       </p>
+
   <li> <p>
        Fixed: The <code class="class">Triangulation</code>::<code class="member">
        MeshSmoothing</code> flag <code>patch_level_1</code> wrongly produced cells
index c92056f0dc0645ab764b8be1d5ce982c1acf4b3e..4b8e16ce35bfe5011e67be4643e8e8a851099f16 100644 (file)
@@ -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 (file)
index 0000000..46b868f
--- /dev/null
@@ -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 <base/logstream.h>
+#include <base/quadrature_lib.h>
+#include <grid/tria.h>
+#include <grid/tria_accessor.h>
+#include <grid/tria_iterator.h>
+#include <grid/grid_generator.h>
+
+#include <fstream>
+
+
+
+template <int dim>
+void check ()
+{
+  Triangulation<dim> 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<typename Triangulation<dim>::active_cell_iterator> cells;
+  for (typename Triangulation<dim>::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<dim>::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<dim>::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 (file)
index 0000000..f08e311
--- /dev/null
@@ -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.

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.