]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Finish documentation.
authorWolfgang Bangerth <bangerth@math.tamu.edu>
Sat, 17 Apr 2004 04:28:10 +0000 (04:28 +0000)
committerWolfgang Bangerth <bangerth@math.tamu.edu>
Sat, 17 Apr 2004 04:28:10 +0000 (04:28 +0000)
git-svn-id: https://svn.dealii.org/trunk@9038 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/examples/step-15/step-15.cc

index f216a398e67a9a32dc2e2e3d31f3c9840ad945d7..995cc3bf4956660b1c0560fe3b8078dbc1904c14 100644 (file)
@@ -1134,29 +1134,111 @@ void MinimizationProblem<1>::refine_grid ()
                                     std::pow(u_prime_right,5));
           error_indicators(cell_index) += right_jump * right_jump *
                                           cell->diameter();
-        }
-      
+        }      
     } 
-  
+
+                                   // Now we have all the refinement
+                                   // indicators computed, and want to refine
+                                   // the grid. In contrast to previous
+                                   // examples, however, we would like to
+                                   // transfer the solution vector from the
+                                   // old to the new grid. This is what the
+                                   // ``SolutionTransfer'' class is good for,
+                                   // but it requires some preliminary
+                                   // work. First, we need to tag the cells
+                                   // that we want to refine or coarsen, as
+                                   // usual:
   GridRefinement::refine_and_coarsen_fixed_number (triangulation,
                                                   error_indicators,
                                                   0.3, 0.03);
+                                   // Then, however, we need an additional
+                                   // step: if, for example, you flag a cell
+                                   // that is once more refined than its
+                                   // neighbor, and that neighbor is not
+                                   // flagged for refinement, we would end up
+                                   // with a jump of two refinement levels
+                                   // across a cell interface. In 1d, this
+                                   // would in general be allowed, but not in
+                                   // higher space dimensions, and some mesh
+                                   // smoothing algorithms in 1d may also
+                                   // disallow this. To avoid these
+                                   // situations, the library will silently
+                                   // also have to refine the neighbor cell
+                                   // once. It does so by calling the
+                                   // ``Triangulation<dim>::prepare_coarsening_and_refinement''
+                                   // function before actually doing the
+                                   // refinement and coarsening. This function
+                                   // flags a set of additional cells for
+                                   // refinement or coarsening, to enforce
+                                   // rules like the one-hanging-node
+                                   // rule. The cells that are flagged for
+                                   // refinement and coarsening after calling
+                                   // this function are exactly the ones that
+                                   // will actually be refined or
+                                   // coarsened. Since the
+                                   // ``SolutionTransfer'' class needs this
+                                   // information in order to store the data
+                                   // from the old mesh and transfer to the
+                                   // new one.
+  triangulation.prepare_coarsening_and_refinement();
 
+                                   // With this out of the way, we initialize
+                                   // a ``SolutionTransfer'' object with the
+                                   // present ``DoFHandler'' and attach the
+                                   // solution vector to it:
   SolutionTransfer<dim,double> solution_transfer(dof_handler);
-  triangulation.prepare_coarsening_and_refinement();
   solution_transfer.prepare_for_coarsening_and_refinement (present_solution);
+
+                                   // Then we do the actual refinement, and
+                                   // distribute degrees of freedom on the new
+                                   // mesh:
   triangulation.execute_coarsening_and_refinement ();
   dof_handler.distribute_dofs (fe);
 
+                                   // Finally, we retrieve the old solution
+                                   // interpolated to the new mesh. Since the
+                                   // ``SolutionTransfer'' function does not
+                                   // actually store the values of the old
+                                   // solution, but rather indices, we need to
+                                   // preserve the old solution vector until
+                                   // we have gotten the new interpolated
+                                   // values. Thus, we have the new values
+                                   // written into a temporary vector, and
+                                   // only afterwards write them into the
+                                   // solution vector object:
   Vector<double> tmp (dof_handler.n_dofs());
   solution_transfer.interpolate (present_solution, tmp);
   present_solution = tmp;
 
+                                   // Here is some final thing, that is
+                                   // actually unnecessary in 1d, but
+                                   // necessary for higher space dimensions,
+                                   // so we show it anyway: the result of what
+                                   // the ``SolutionTransfer'' class provides
+                                   // is a vector that is interpolated from
+                                   // the old to the new mesh. Unfortunately,
+                                   // it does not necessarily have the right
+                                   // values at constrained (hanging) nodes,
+                                   // so we have to fix this up to make the
+                                   // solution conforming again. The simplest
+                                   // way to do this is this:
   hanging_node_constraints.clear ();
   DoFTools::make_hanging_node_constraints (dof_handler,
                                           hanging_node_constraints);
   hanging_node_constraints.close ();  
   hanging_node_constraints.distribute (present_solution);
+                                   // This is wasteful, since we create a
+                                   // ``ConstraintMatrix'' object that will be
+                                   // recreated again in the next call to
+                                   // ``setup_system_on_mesh'' immediately
+                                   // afterwards. A more efficient
+                                   // implementation would make sure that it
+                                   // is created only once. We don't care so
+                                   // much here, since in 1d there are no
+                                   // constraints, so all of these operations
+                                   // are really cheap, but we do not
+                                   // recommend this as general programming
+                                   // strategy.
 }
 
 

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.