]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Move everything in these tutorial programs into a namespace StepXX.
authorbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Sat, 20 Aug 2011 05:00:30 +0000 (05:00 +0000)
committerbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Sat, 20 Aug 2011 05:00:30 +0000 (05:00 +0000)
git-svn-id: https://svn.dealii.org/trunk@24119 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/examples/step-11/step-11.cc
deal.II/examples/step-12/step-12.cc
deal.II/examples/step-13/step-13.cc
deal.II/examples/step-14/step-14.cc

index e47b4a1cd5961549ed2aace800309a2ce9e5aaa6..a237ffc6ec31a98a29bc87cda9a3e9845c42f4fd 100644 (file)
@@ -3,7 +3,7 @@
 
 /*    $Id$       */
 /*                                                                */
-/*    Copyright (C) 2001, 2002, 2003, 2004, 2006, 2009 by the deal.II authors */
+/*    Copyright (C) 2001, 2002, 2003, 2004, 2006, 2009, 2011 by the deal.II authors */
 /*                                                                */
 /*    This file is subject to QPL and may not be  distributed     */
 /*    without copyright and license information. Please refer     */
 
                                 // The last step is as in all
                                 // previous programs:
-using namespace dealii;
-
-                                // Then we declare a class which
-                                // represents the solution of a
-                                // Laplace problem. As this example
-                                // program is based on step-5, the
-                                // class looks rather the same, with
-                                // the sole structural difference
-                                // that the functions
-                                // <code>assemble_system</code> now calls
-                                // <code>solve</code> itself, and is thus
-                                // called <code>assemble_and_solve</code>, and
-                                // that the output function was
-                                // dropped since the solution
-                                // function is so boring that it is
-                                // not worth being viewed.
-                                //
-                                // The only other noteworthy change
-                                // is that the constructor takes a
-                                // value representing the polynomial
-                                // degree of the mapping to be used
-                                // later on, and that it has another
-                                // member variable representing
-                                // exactly this mapping. In general,
-                                // this variable will occur in real
-                                // applications at the same places
-                                // where the finite element is
-                                // declared or used.
-template <int dim>
-class LaplaceProblem 
+namespace Step11
 {
-  public:
-    LaplaceProblem (const unsigned int mapping_degree);
-    void run ();
-    
-  private:
-    void setup_system ();
-    void assemble_and_solve ();
-    void solve ();
-
-    Triangulation<dim>   triangulation;
-    FE_Q<dim>            fe;
-    DoFHandler<dim>      dof_handler;
-    MappingQ<dim>        mapping;
-
-    SparsityPattern      sparsity_pattern;
-    SparseMatrix<double> system_matrix;
-    ConstraintMatrix     mean_value_constraints;
-
-    Vector<double>       solution;
-    Vector<double>       system_rhs;
-
-    TableHandler         output_table;
-};
-
-
-
-                                // Construct such an object, by
-                                // initializing the variables. Here,
-                                // we use linear finite elements (the
-                                // argument to the <code>fe</code> variable
-                                // denotes the polynomial degree),
-                                // and mappings of given order. Print
-                                // to screen what we are about to do.
-template <int dim>
-LaplaceProblem<dim>::LaplaceProblem (const unsigned int mapping_degree) :
-                fe (1),
-               dof_handler (triangulation),
-               mapping (mapping_degree)
-{
-  std::cout << "Using mapping with degree " << mapping_degree << ":"
-           << std::endl
-           << "============================"
-           << std::endl;
-}
-
-
-
-                                // The first task is to set up the
-                                // variables for this problem. This
-                                // includes generating a valid
-                                // <code>DoFHandler</code> object, as well as
-                                // the sparsity patterns for the
-                                // matrix, and the object
-                                // representing the constraints that
-                                // the mean value of the degrees of
-                                // freedom on the boundary be zero.
-template <int dim>
-void LaplaceProblem<dim>::setup_system ()
-{
-                                  // The first task is trivial:
-                                  // generate an enumeration of the
-                                  // degrees of freedom, and
-                                  // initialize solution and right
-                                  // hand side vector to their
-                                  // correct sizes:
-  dof_handler.distribute_dofs (fe);
-  solution.reinit (dof_handler.n_dofs());
-  system_rhs.reinit (dof_handler.n_dofs());
-
-                                  // Next task is to construct the
-                                  // object representing the
-                                  // constraint that the mean value
-                                  // of the degrees of freedom on the
-                                  // boundary shall be zero. For
-                                  // this, we first want a list of
-                                  // those nodes which are actually
-                                  // at the boundary. The
-                                  // <code>DoFTools</code> class has a
-                                  // function that returns an array
-                                  // of boolean values where <code>true</code>
-                                  // indicates that the node is at
-                                  // the boundary. The second
-                                  // argument denotes a mask
-                                  // selecting which components of
-                                  // vector valued finite elements we
-                                  // want to be considered. Since we
-                                  // have a scalar finite element
-                                  // anyway, this mask consists of
-                                  // only one entry, and its value
-                                  // must be <code>true</code>.
-  std::vector<bool> boundary_dofs (dof_handler.n_dofs(), false);
-  DoFTools::extract_boundary_dofs (dof_handler, std::vector<bool>(1,true),
-                                  boundary_dofs);
-
-                                  // Now first for the generation of
-                                  // the constraints: as mentioned in
-                                  // the introduction, we constrain
-                                  // one of the nodes on the boundary
-                                  // by the values of all other DoFs
-                                  // on the boundary. So, let us
-                                  // first pick out the first
-                                  // boundary node from this list. We
-                                  // do that by searching for the
-                                  // first <code>true</code> value in the
-                                  // array (note that <code>std::find</code>
-                                  // returns an iterator to this
-                                  // element), and computing its
-                                  // distance to the overall first
-                                  // element in the array to get its
-                                  // index:
-  const unsigned int first_boundary_dof
-    = std::distance (boundary_dofs.begin(),
-                    std::find (boundary_dofs.begin(),
-                               boundary_dofs.end(),
-                               true));
-
-                                  // Then generate a constraints
-                                  // object with just this one
-                                  // constraint. First clear all
-                                  // previous content (which might
-                                  // reside there from the previous
-                                  // computation on a once coarser
-                                  // grid), then add this one line
-                                  // constraining the
-                                  // <code>first_boundary_dof</code> to the
-                                  // sum of other boundary DoFs each
-                                  // with weight -1. Finally, close
-                                  // the constraints object, i.e. do
-                                  // some internal bookkeeping on it
-                                  // for faster processing of what is
-                                  // to come later:
-  mean_value_constraints.clear ();
-  mean_value_constraints.add_line (first_boundary_dof);
-  for (unsigned int i=first_boundary_dof+1; i<dof_handler.n_dofs(); ++i)
-    if (boundary_dofs[i] == true)
-      mean_value_constraints.add_entry (first_boundary_dof,
-                                       i, -1);
-  mean_value_constraints.close ();
-
-                                  // Next task is to generate a
-                                  // sparsity pattern. This is indeed
-                                  // a tricky task here. Usually, we
-                                  // just call
-                                  // <code>DoFTools::make_sparsity_pattern</code>
-                                  // and condense the result using
-                                  // the hanging node constraints. We
-                                  // have no hanging node constraints
-                                  // here (since we only refine
-                                  // globally in this example), but
-                                  // we have this global constraint
-                                  // on the boundary. This poses one
-                                  // severe problem in this context:
-                                  // the <code>SparsityPattern</code> class
-                                  // wants us to state beforehand the
-                                  // maximal number of entries per
-                                  // row, either for all rows or for
-                                  // each row separately. There are
-                                  // functions in the library which
-                                  // can tell you this number in case
-                                  // you just have hanging node
-                                  // constraints (namely
-                                  // <code>DoFHandler::max_coupling_between_dofs</code>),
-                                  // but how is this for the present
-                                  // case? The difficulty arises
-                                  // because the elimination of the
-                                  // constrained degree of freedom
-                                  // requires a number of additional
-                                  // entries in the matrix at places
-                                  // that are not so simple to
-                                  // determine. We would therefore
-                                  // have a problem had we to give a
-                                  // maximal number of entries per
-                                  // row here.
-                                  //
-                                  // Since this can be so difficult
-                                  // that no reasonable answer can be
-                                  // given that allows allocation of
-                                  // only a reasonable amount of
-                                  // memory, there is a class
-                                  // <code>CompressedSparsityPattern</code>,
-                                  // that can help us out here. It
-                                  // does not require that we know in
-                                  // advance how many entries rows
-                                  // could have, but allows just
-                                  // about any length. It is thus
-                                  // significantly more flexible in
-                                  // case you do not have good
-                                  // estimates of row lengths,
-                                  // however at the price that
-                                  // building up such a pattern is
-                                  // also significantly more
-                                  // expensive than building up a
-                                  // pattern for which you had
-                                  // information in
-                                  // advance. Nevertheless, as we
-                                  // have no other choice here, we'll
-                                  // just build such an object by
-                                  // initializing it with the
-                                  // dimensions of the matrix and
-                                  // calling another function
-                                  // <code>DoFTools::make_sparsity_pattern</code>
-                                  // to get the sparsity pattern due
-                                  // to the differential operator,
-                                  // then condense it with the
-                                  // constraints object which adds
-                                  // those positions in the sparsity
-                                  // pattern that are required for
-                                  // the elimination of the
-                                  // constraint.
-  CompressedSparsityPattern csp (dof_handler.n_dofs(),
-                                dof_handler.n_dofs());
-  DoFTools::make_sparsity_pattern (dof_handler, csp);
-  mean_value_constraints.condense (csp);
-
-                                  // Finally, once we have the full
-                                  // pattern, we can initialize an
-                                  // object of type
-                                  // <code>SparsityPattern</code> from it and
-                                  // in turn initialize the matrix
-                                  // with it. Note that this is
-                                  // actually necessary, since the
-                                  // <code>CompressedSparsityPattern</code> is
-                                  // so inefficient compared to the
-                                  // <code>SparsityPattern</code> class due to
-                                  // the more flexible data
-                                  // structures it has to use, that
-                                  // we can impossibly base the
-                                  // sparse matrix class on it, but
-                                  // rather need an object of type
-                                  // <code>SparsityPattern</code>, which we
-                                  // generate by copying from the
-                                  // intermediate object.
-                                  //
-                                  // As a further sidenote, you will
-                                  // notice that we do not explicitly
-                                  // have to <code>compress</code> the
-                                  // sparsity pattern here. This, of
-                                  // course, is due to the fact that
-                                  // the <code>copy_from</code> function
-                                  // generates a compressed object
-                                  // right from the start, to which
-                                  // you cannot add new entries
-                                  // anymore. The <code>compress</code> call
-                                  // is therefore implicit in the
-                                  // <code>copy_from</code> call.
-  sparsity_pattern.copy_from (csp);
-  system_matrix.reinit (sparsity_pattern);
-}
-
-
-
-                                // The next function then assembles
-                                // the linear system of equations,
-                                // solves it, and evaluates the
-                                // solution. This then makes three
-                                // actions, and we will put them into
-                                // eight true statements (excluding
-                                // declaration of variables, and
-                                // handling of temporary
-                                // vectors). Thus, this function is
-                                // something for the very
-                                // lazy. Nevertheless, the functions
-                                // called are rather powerful, and
-                                // through them this function uses a
-                                // good deal of the whole
-                                // library. But let's look at each of
-                                // the steps.
-template <int dim>
-void LaplaceProblem<dim>::assemble_and_solve () 
-{
-
-                                  // First, we have to assemble the
-                                  // matrix and the right hand
-                                  // side. In all previous examples,
-                                  // we have investigated various
-                                  // ways how to do this
-                                  // manually. However, since the
-                                  // Laplace matrix and simple right
-                                  // hand sides appear so frequently
-                                  // in applications, the library
-                                  // provides functions for actually
-                                  // doing this for you, i.e. they
-                                  // perform the loop over all cells,
-                                  // setting up the local matrices
-                                  // and vectors, and putting them
-                                  // together for the end result.
-                                  //
-                                  // The following are the two most
-                                  // commonly used ones: creation of
-                                  // the Laplace matrix and creation
-                                  // of a right hand side vector from
-                                  // body or boundary forces. They
-                                  // take the mapping object, the
-                                  // <code>DoFHandler</code> object
-                                  // representing the degrees of
-                                  // freedom and the finite element
-                                  // in use, a quadrature formula to
-                                  // be used, and the output
-                                  // object. The function that
-                                  // creates a right hand side vector
-                                  // also has to take a function
-                                  // object describing the
-                                  // (continuous) right hand side
-                                  // function.
-                                  //
-                                  // Let us look at the way the
-                                  // matrix and body forces are
-                                  // integrated:
-  const unsigned int gauss_degree
-    = std::max (static_cast<unsigned int>(std::ceil(1.*(mapping.get_degree()+1)/2)),
-               2U);
-  MatrixTools::create_laplace_matrix (mapping, dof_handler,
-                                     QGauss<dim>(gauss_degree),
-                                     system_matrix);
-  VectorTools::create_right_hand_side (mapping, dof_handler,
-                                      QGauss<dim>(gauss_degree),
-                                      ConstantFunction<dim>(-2),
-                                      system_rhs);
-                                  // That's quite simple, right?
+  using namespace dealii;
+
+                                  // Then we declare a class which
+                                  // represents the solution of a
+                                  // Laplace problem. As this example
+                                  // program is based on step-5, the
+                                  // class looks rather the same, with
+                                  // the sole structural difference
+                                  // that the functions
+                                  // <code>assemble_system</code> now calls
+                                  // <code>solve</code> itself, and is thus
+                                  // called <code>assemble_and_solve</code>, and
+                                  // that the output function was
+                                  // dropped since the solution
+                                  // function is so boring that it is
+                                  // not worth being viewed.
                                   //
-                                  // Two remarks are in order,
-                                  // though: First, these functions
-                                  // are used in a lot of
-                                  // contexts. Maybe you want to
-                                  // create a Laplace or mass matrix
-                                  // for a vector values finite
-                                  // element; or you want to use the
-                                  // default Q1 mapping; or you want
-                                  // to assembled the matrix with a
-                                  // coefficient in the Laplace
-                                  // operator. For this reason, there
-                                  // are quite a large number of
-                                  // variants of these functions in
-                                  // the <code>MatrixCreator</code> and
-                                  // <code>MatrixTools</code>
-                                  // classes. Whenever you need a
-                                  // slightly different version of
-                                  // these functions than the ones
-                                  // called above, it is certainly
-                                  // worthwhile to take a look at the
-                                  // documentation and to check
-                                  // whether something fits your
-                                  // needs.
-                                  //
-                                  // The second remark concerns the
-                                  // quadrature formula we use: we
-                                  // want to integrate over bilinear
-                                  // shape functions, so we know that
-                                  // we have to use at least a Gauss2
-                                  // quadrature formula. On the other
-                                  // hand, we want to have the
-                                  // quadrature rule to have at least
-                                  // the order of the boundary
-                                  // approximation. Since the order
-                                  // of Gauss-r is 2r, and the order
-                                  // of the boundary approximation
-                                  // using polynomials of degree p is
-                                  // p+1, we know that 2r@>=p+1. Since
-                                  // r has to be an integer and (as
-                                  // mentioned above) has to be at
-                                  // least 2, this makes up for the
-                                  // formula above computing
-                                  // <code>gauss_degree</code>.
-                                  //
-                                  // Since the generation of the body
-                                  // force contributions to the right
-                                  // hand side vector was so simple,
-                                  // we do that all over again for
-                                  // the boundary forces as well:
-                                  // allocate a vector of the right
-                                  // size and call the right
-                                  // function. The boundary function
-                                  // has constant values, so we can
-                                  // generate an object from the
-                                  // library on the fly, and we use
-                                  // the same quadrature formula as
-                                  // above, but this time of lower
-                                  // dimension since we integrate
-                                  // over faces now instead of cells:
-  Vector<double> tmp (system_rhs.size());
-  VectorTools::create_boundary_right_hand_side (mapping, dof_handler,
-                                               QGauss<dim-1>(gauss_degree),
-                                               ConstantFunction<dim>(1),
-                                               tmp);
-                                  // Then add the contributions from
-                                  // the boundary to those from the
-                                  // interior of the domain:
-  system_rhs += tmp;
-                                  // For assembling the right hand
-                                  // side, we had to use two
-                                  // different vector objects, and
-                                  // later add them together. The
-                                  // reason we had to do so is that
-                                  // the
-                                  // <code>VectorTools::create_right_hand_side</code>
-                                  // and
-                                  // <code>VectorTools::create_boundary_right_hand_side</code>
-                                  // functions first clear the output
-                                  // vector, rather than adding up
-                                  // their results to previous
-                                  // contents. This can reasonably be
-                                  // called a design flaw in the
-                                  // library made in its infancy, but
-                                  // unfortunately things are as they
-                                  // are for some time now and it is
-                                  // difficult to change such things
-                                  // that silently break existing
-                                  // code, so we have to live with
-                                  // that.
-
-                                  // Now, the linear system is set
-                                  // up, so we can eliminate the one
-                                  // degree of freedom which we
-                                  // constrained to the other DoFs on
-                                  // the boundary for the mean value
-                                  // constraint from matrix and right
-                                  // hand side vector, and solve the
-                                  // system. After that, distribute
-                                  // the constraints again, which in
-                                  // this case means setting the
-                                  // constrained degree of freedom to
-                                  // its proper value
-  mean_value_constraints.condense (system_matrix);
-  mean_value_constraints.condense (system_rhs);  
-
-  solve ();
-  mean_value_constraints.distribute (solution);
-
-                                  // Finally, evaluate what we got as
-                                  // solution. As stated in the
-                                  // introduction, we are interested
-                                  // in the H1 semi-norm of the
-                                  // solution. Here, as well, we have
-                                  // a function in the library that
-                                  // does this, although in a
-                                  // slightly non-obvious way: the
-                                  // <code>VectorTools::integrate_difference</code>
-                                  // function integrates the norm of
-                                  // the difference between a finite
-                                  // element function and a
-                                  // continuous function. If we
-                                  // therefore want the norm of a
-                                  // finite element field, we just
-                                  // put the continuous function to
-                                  // zero. Note that this function,
-                                  // just as so many other ones in
-                                  // the library as well, has at
-                                  // least two versions, one which
-                                  // takes a mapping as argument
-                                  // (which we make us of here), and
-                                  // the one which we have used in
-                                  // previous examples which
-                                  // implicitly uses <code>MappingQ1</code>.
-                                  // Also note that we take a
-                                  // quadrature formula of one degree
-                                  // higher, in order to avoid
-                                  // superconvergence effects where
-                                  // the solution happens to be
-                                  // especially close to the exact
-                                  // solution at certain points (we
-                                  // don't know whether this might be
-                                  // the case here, but there are
-                                  // cases known of this, and we just
-                                  // want to make sure):
-  Vector<float> norm_per_cell (triangulation.n_active_cells());
-  VectorTools::integrate_difference (mapping, dof_handler,
-                                    solution,
-                                    ZeroFunction<dim>(),
-                                    norm_per_cell,
-                                    QGauss<dim>(gauss_degree+1),
-                                    VectorTools::H1_seminorm);
-                                  // Then, the function just called
-                                  // returns its results as a vector
-                                  // of values each of which denotes
-                                  // the norm on one cell. To get the
-                                  // global norm, a simple
-                                  // computation shows that we have
-                                  // to take the l2 norm of the
-                                  // vector:
-  const double norm = norm_per_cell.l2_norm();
-
-                                  // Last task -- generate output:
-  output_table.add_value ("cells", triangulation.n_active_cells());
-  output_table.add_value ("|u|_1", norm);
-  output_table.add_value ("error", std::fabs(norm-std::sqrt(3.14159265358/2)));
-}
-
-
-
-                                // The following function solving the
-                                // linear system of equations is
-                                // copied from step-5 and is
-                                // explained there in some detail:
-template <int dim>
-void LaplaceProblem<dim>::solve () 
-{
-  SolverControl           solver_control (1000, 1e-12);
-  SolverCG<>              cg (solver_control);
-
-  PreconditionSSOR<> preconditioner;
-  preconditioner.initialize(system_matrix, 1.2);
-
-  cg.solve (system_matrix, solution, system_rhs,
-           preconditioner);
+                                  // The only other noteworthy change
+                                  // is that the constructor takes a
+                                  // value representing the polynomial
+                                  // degree of the mapping to be used
+                                  // later on, and that it has another
+                                  // member variable representing
+                                  // exactly this mapping. In general,
+                                  // this variable will occur in real
+                                  // applications at the same places
+                                  // where the finite element is
+                                  // declared or used.
+  template <int dim>
+  class LaplaceProblem
+  {
+    public:
+      LaplaceProblem (const unsigned int mapping_degree);
+      void run ();
+
+    private:
+      void setup_system ();
+      void assemble_and_solve ();
+      void solve ();
+
+      Triangulation<dim>   triangulation;
+      FE_Q<dim>            fe;
+      DoFHandler<dim>      dof_handler;
+      MappingQ<dim>        mapping;
+
+      SparsityPattern      sparsity_pattern;
+      SparseMatrix<double> system_matrix;
+      ConstraintMatrix     mean_value_constraints;
+
+      Vector<double>       solution;
+      Vector<double>       system_rhs;
+
+      TableHandler         output_table;
+  };
+
+
+
+                                  // Construct such an object, by
+                                  // initializing the variables. Here,
+                                  // we use linear finite elements (the
+                                  // argument to the <code>fe</code> variable
+                                  // denotes the polynomial degree),
+                                  // and mappings of given order. Print
+                                  // to screen what we are about to do.
+  template <int dim>
+  LaplaceProblem<dim>::LaplaceProblem (const unsigned int mapping_degree) :
+                 fe (1),
+                 dof_handler (triangulation),
+                 mapping (mapping_degree)
+  {
+    std::cout << "Using mapping with degree " << mapping_degree << ":"
+             << std::endl
+             << "============================"
+             << std::endl;
+  }
+
+
+
+                                  // The first task is to set up the
+                                  // variables for this problem. This
+                                  // includes generating a valid
+                                  // <code>DoFHandler</code> object, as well as
+                                  // the sparsity patterns for the
+                                  // matrix, and the object
+                                  // representing the constraints that
+                                  // the mean value of the degrees of
+                                  // freedom on the boundary be zero.
+  template <int dim>
+  void LaplaceProblem<dim>::setup_system ()
+  {
+                                    // The first task is trivial:
+                                    // generate an enumeration of the
+                                    // degrees of freedom, and
+                                    // initialize solution and right
+                                    // hand side vector to their
+                                    // correct sizes:
+    dof_handler.distribute_dofs (fe);
+    solution.reinit (dof_handler.n_dofs());
+    system_rhs.reinit (dof_handler.n_dofs());
+
+                                    // Next task is to construct the
+                                    // object representing the
+                                    // constraint that the mean value
+                                    // of the degrees of freedom on the
+                                    // boundary shall be zero. For
+                                    // this, we first want a list of
+                                    // those nodes which are actually
+                                    // at the boundary. The
+                                    // <code>DoFTools</code> class has a
+                                    // function that returns an array
+                                    // of boolean values where <code>true</code>
+                                    // indicates that the node is at
+                                    // the boundary. The second
+                                    // argument denotes a mask
+                                    // selecting which components of
+                                    // vector valued finite elements we
+                                    // want to be considered. Since we
+                                    // have a scalar finite element
+                                    // anyway, this mask consists of
+                                    // only one entry, and its value
+                                    // must be <code>true</code>.
+    std::vector<bool> boundary_dofs (dof_handler.n_dofs(), false);
+    DoFTools::extract_boundary_dofs (dof_handler, std::vector<bool>(1,true),
+                                    boundary_dofs);
+
+                                    // Now first for the generation of
+                                    // the constraints: as mentioned in
+                                    // the introduction, we constrain
+                                    // one of the nodes on the boundary
+                                    // by the values of all other DoFs
+                                    // on the boundary. So, let us
+                                    // first pick out the first
+                                    // boundary node from this list. We
+                                    // do that by searching for the
+                                    // first <code>true</code> value in the
+                                    // array (note that <code>std::find</code>
+                                    // returns an iterator to this
+                                    // element), and computing its
+                                    // distance to the overall first
+                                    // element in the array to get its
+                                    // index:
+    const unsigned int first_boundary_dof
+      = std::distance (boundary_dofs.begin(),
+                      std::find (boundary_dofs.begin(),
+                                 boundary_dofs.end(),
+                                 true));
+
+                                    // Then generate a constraints
+                                    // object with just this one
+                                    // constraint. First clear all
+                                    // previous content (which might
+                                    // reside there from the previous
+                                    // computation on a once coarser
+                                    // grid), then add this one line
+                                    // constraining the
+                                    // <code>first_boundary_dof</code> to the
+                                    // sum of other boundary DoFs each
+                                    // with weight -1. Finally, close
+                                    // the constraints object, i.e. do
+                                    // some internal bookkeeping on it
+                                    // for faster processing of what is
+                                    // to come later:
+    mean_value_constraints.clear ();
+    mean_value_constraints.add_line (first_boundary_dof);
+    for (unsigned int i=first_boundary_dof+1; i<dof_handler.n_dofs(); ++i)
+      if (boundary_dofs[i] == true)
+       mean_value_constraints.add_entry (first_boundary_dof,
+                                         i, -1);
+    mean_value_constraints.close ();
+
+                                    // Next task is to generate a
+                                    // sparsity pattern. This is indeed
+                                    // a tricky task here. Usually, we
+                                    // just call
+                                    // <code>DoFTools::make_sparsity_pattern</code>
+                                    // and condense the result using
+                                    // the hanging node constraints. We
+                                    // have no hanging node constraints
+                                    // here (since we only refine
+                                    // globally in this example), but
+                                    // we have this global constraint
+                                    // on the boundary. This poses one
+                                    // severe problem in this context:
+                                    // the <code>SparsityPattern</code> class
+                                    // wants us to state beforehand the
+                                    // maximal number of entries per
+                                    // row, either for all rows or for
+                                    // each row separately. There are
+                                    // functions in the library which
+                                    // can tell you this number in case
+                                    // you just have hanging node
+                                    // constraints (namely
+                                    // <code>DoFHandler::max_coupling_between_dofs</code>),
+                                    // but how is this for the present
+                                    // case? The difficulty arises
+                                    // because the elimination of the
+                                    // constrained degree of freedom
+                                    // requires a number of additional
+                                    // entries in the matrix at places
+                                    // that are not so simple to
+                                    // determine. We would therefore
+                                    // have a problem had we to give a
+                                    // maximal number of entries per
+                                    // row here.
+                                    //
+                                    // Since this can be so difficult
+                                    // that no reasonable answer can be
+                                    // given that allows allocation of
+                                    // only a reasonable amount of
+                                    // memory, there is a class
+                                    // <code>CompressedSparsityPattern</code>,
+                                    // that can help us out here. It
+                                    // does not require that we know in
+                                    // advance how many entries rows
+                                    // could have, but allows just
+                                    // about any length. It is thus
+                                    // significantly more flexible in
+                                    // case you do not have good
+                                    // estimates of row lengths,
+                                    // however at the price that
+                                    // building up such a pattern is
+                                    // also significantly more
+                                    // expensive than building up a
+                                    // pattern for which you had
+                                    // information in
+                                    // advance. Nevertheless, as we
+                                    // have no other choice here, we'll
+                                    // just build such an object by
+                                    // initializing it with the
+                                    // dimensions of the matrix and
+                                    // calling another function
+                                    // <code>DoFTools::make_sparsity_pattern</code>
+                                    // to get the sparsity pattern due
+                                    // to the differential operator,
+                                    // then condense it with the
+                                    // constraints object which adds
+                                    // those positions in the sparsity
+                                    // pattern that are required for
+                                    // the elimination of the
+                                    // constraint.
+    CompressedSparsityPattern csp (dof_handler.n_dofs(),
+                                  dof_handler.n_dofs());
+    DoFTools::make_sparsity_pattern (dof_handler, csp);
+    mean_value_constraints.condense (csp);
+
+                                    // Finally, once we have the full
+                                    // pattern, we can initialize an
+                                    // object of type
+                                    // <code>SparsityPattern</code> from it and
+                                    // in turn initialize the matrix
+                                    // with it. Note that this is
+                                    // actually necessary, since the
+                                    // <code>CompressedSparsityPattern</code> is
+                                    // so inefficient compared to the
+                                    // <code>SparsityPattern</code> class due to
+                                    // the more flexible data
+                                    // structures it has to use, that
+                                    // we can impossibly base the
+                                    // sparse matrix class on it, but
+                                    // rather need an object of type
+                                    // <code>SparsityPattern</code>, which we
+                                    // generate by copying from the
+                                    // intermediate object.
+                                    //
+                                    // As a further sidenote, you will
+                                    // notice that we do not explicitly
+                                    // have to <code>compress</code> the
+                                    // sparsity pattern here. This, of
+                                    // course, is due to the fact that
+                                    // the <code>copy_from</code> function
+                                    // generates a compressed object
+                                    // right from the start, to which
+                                    // you cannot add new entries
+                                    // anymore. The <code>compress</code> call
+                                    // is therefore implicit in the
+                                    // <code>copy_from</code> call.
+    sparsity_pattern.copy_from (csp);
+    system_matrix.reinit (sparsity_pattern);
+  }
+
+
+
+                                  // The next function then assembles
+                                  // the linear system of equations,
+                                  // solves it, and evaluates the
+                                  // solution. This then makes three
+                                  // actions, and we will put them into
+                                  // eight true statements (excluding
+                                  // declaration of variables, and
+                                  // handling of temporary
+                                  // vectors). Thus, this function is
+                                  // something for the very
+                                  // lazy. Nevertheless, the functions
+                                  // called are rather powerful, and
+                                  // through them this function uses a
+                                  // good deal of the whole
+                                  // library. But let's look at each of
+                                  // the steps.
+  template <int dim>
+  void LaplaceProblem<dim>::assemble_and_solve ()
+  {
+
+                                    // First, we have to assemble the
+                                    // matrix and the right hand
+                                    // side. In all previous examples,
+                                    // we have investigated various
+                                    // ways how to do this
+                                    // manually. However, since the
+                                    // Laplace matrix and simple right
+                                    // hand sides appear so frequently
+                                    // in applications, the library
+                                    // provides functions for actually
+                                    // doing this for you, i.e. they
+                                    // perform the loop over all cells,
+                                    // setting up the local matrices
+                                    // and vectors, and putting them
+                                    // together for the end result.
+                                    //
+                                    // The following are the two most
+                                    // commonly used ones: creation of
+                                    // the Laplace matrix and creation
+                                    // of a right hand side vector from
+                                    // body or boundary forces. They
+                                    // take the mapping object, the
+                                    // <code>DoFHandler</code> object
+                                    // representing the degrees of
+                                    // freedom and the finite element
+                                    // in use, a quadrature formula to
+                                    // be used, and the output
+                                    // object. The function that
+                                    // creates a right hand side vector
+                                    // also has to take a function
+                                    // object describing the
+                                    // (continuous) right hand side
+                                    // function.
+                                    //
+                                    // Let us look at the way the
+                                    // matrix and body forces are
+                                    // integrated:
+    const unsigned int gauss_degree
+      = std::max (static_cast<unsigned int>(std::ceil(1.*(mapping.get_degree()+1)/2)),
+                 2U);
+    MatrixTools::create_laplace_matrix (mapping, dof_handler,
+                                       QGauss<dim>(gauss_degree),
+                                       system_matrix);
+    VectorTools::create_right_hand_side (mapping, dof_handler,
+                                        QGauss<dim>(gauss_degree),
+                                        ConstantFunction<dim>(-2),
+                                        system_rhs);
+                                    // That's quite simple, right?
+                                    //
+                                    // Two remarks are in order,
+                                    // though: First, these functions
+                                    // are used in a lot of
+                                    // contexts. Maybe you want to
+                                    // create a Laplace or mass matrix
+                                    // for a vector values finite
+                                    // element; or you want to use the
+                                    // default Q1 mapping; or you want
+                                    // to assembled the matrix with a
+                                    // coefficient in the Laplace
+                                    // operator. For this reason, there
+                                    // are quite a large number of
+                                    // variants of these functions in
+                                    // the <code>MatrixCreator</code> and
+                                    // <code>MatrixTools</code>
+                                    // classes. Whenever you need a
+                                    // slightly different version of
+                                    // these functions than the ones
+                                    // called above, it is certainly
+                                    // worthwhile to take a look at the
+                                    // documentation and to check
+                                    // whether something fits your
+                                    // needs.
+                                    //
+                                    // The second remark concerns the
+                                    // quadrature formula we use: we
+                                    // want to integrate over bilinear
+                                    // shape functions, so we know that
+                                    // we have to use at least a Gauss2
+                                    // quadrature formula. On the other
+                                    // hand, we want to have the
+                                    // quadrature rule to have at least
+                                    // the order of the boundary
+                                    // approximation. Since the order
+                                    // of Gauss-r is 2r, and the order
+                                    // of the boundary approximation
+                                    // using polynomials of degree p is
+                                    // p+1, we know that 2r@>=p+1. Since
+                                    // r has to be an integer and (as
+                                    // mentioned above) has to be at
+                                    // least 2, this makes up for the
+                                    // formula above computing
+                                    // <code>gauss_degree</code>.
+                                    //
+                                    // Since the generation of the body
+                                    // force contributions to the right
+                                    // hand side vector was so simple,
+                                    // we do that all over again for
+                                    // the boundary forces as well:
+                                    // allocate a vector of the right
+                                    // size and call the right
+                                    // function. The boundary function
+                                    // has constant values, so we can
+                                    // generate an object from the
+                                    // library on the fly, and we use
+                                    // the same quadrature formula as
+                                    // above, but this time of lower
+                                    // dimension since we integrate
+                                    // over faces now instead of cells:
+    Vector<double> tmp (system_rhs.size());
+    VectorTools::create_boundary_right_hand_side (mapping, dof_handler,
+                                                 QGauss<dim-1>(gauss_degree),
+                                                 ConstantFunction<dim>(1),
+                                                 tmp);
+                                    // Then add the contributions from
+                                    // the boundary to those from the
+                                    // interior of the domain:
+    system_rhs += tmp;
+                                    // For assembling the right hand
+                                    // side, we had to use two
+                                    // different vector objects, and
+                                    // later add them together. The
+                                    // reason we had to do so is that
+                                    // the
+                                    // <code>VectorTools::create_right_hand_side</code>
+                                    // and
+                                    // <code>VectorTools::create_boundary_right_hand_side</code>
+                                    // functions first clear the output
+                                    // vector, rather than adding up
+                                    // their results to previous
+                                    // contents. This can reasonably be
+                                    // called a design flaw in the
+                                    // library made in its infancy, but
+                                    // unfortunately things are as they
+                                    // are for some time now and it is
+                                    // difficult to change such things
+                                    // that silently break existing
+                                    // code, so we have to live with
+                                    // that.
+
+                                    // Now, the linear system is set
+                                    // up, so we can eliminate the one
+                                    // degree of freedom which we
+                                    // constrained to the other DoFs on
+                                    // the boundary for the mean value
+                                    // constraint from matrix and right
+                                    // hand side vector, and solve the
+                                    // system. After that, distribute
+                                    // the constraints again, which in
+                                    // this case means setting the
+                                    // constrained degree of freedom to
+                                    // its proper value
+    mean_value_constraints.condense (system_matrix);
+    mean_value_constraints.condense (system_rhs);
+
+    solve ();
+    mean_value_constraints.distribute (solution);
+
+                                    // Finally, evaluate what we got as
+                                    // solution. As stated in the
+                                    // introduction, we are interested
+                                    // in the H1 semi-norm of the
+                                    // solution. Here, as well, we have
+                                    // a function in the library that
+                                    // does this, although in a
+                                    // slightly non-obvious way: the
+                                    // <code>VectorTools::integrate_difference</code>
+                                    // function integrates the norm of
+                                    // the difference between a finite
+                                    // element function and a
+                                    // continuous function. If we
+                                    // therefore want the norm of a
+                                    // finite element field, we just
+                                    // put the continuous function to
+                                    // zero. Note that this function,
+                                    // just as so many other ones in
+                                    // the library as well, has at
+                                    // least two versions, one which
+                                    // takes a mapping as argument
+                                    // (which we make us of here), and
+                                    // the one which we have used in
+                                    // previous examples which
+                                    // implicitly uses <code>MappingQ1</code>.
+                                    // Also note that we take a
+                                    // quadrature formula of one degree
+                                    // higher, in order to avoid
+                                    // superconvergence effects where
+                                    // the solution happens to be
+                                    // especially close to the exact
+                                    // solution at certain points (we
+                                    // don't know whether this might be
+                                    // the case here, but there are
+                                    // cases known of this, and we just
+                                    // want to make sure):
+    Vector<float> norm_per_cell (triangulation.n_active_cells());
+    VectorTools::integrate_difference (mapping, dof_handler,
+                                      solution,
+                                      ZeroFunction<dim>(),
+                                      norm_per_cell,
+                                      QGauss<dim>(gauss_degree+1),
+                                      VectorTools::H1_seminorm);
+                                    // Then, the function just called
+                                    // returns its results as a vector
+                                    // of values each of which denotes
+                                    // the norm on one cell. To get the
+                                    // global norm, a simple
+                                    // computation shows that we have
+                                    // to take the l2 norm of the
+                                    // vector:
+    const double norm = norm_per_cell.l2_norm();
+
+                                    // Last task -- generate output:
+    output_table.add_value ("cells", triangulation.n_active_cells());
+    output_table.add_value ("|u|_1", norm);
+    output_table.add_value ("error", std::fabs(norm-std::sqrt(3.14159265358/2)));
+  }
+
+
+
+                                  // The following function solving the
+                                  // linear system of equations is
+                                  // copied from step-5 and is
+                                  // explained there in some detail:
+  template <int dim>
+  void LaplaceProblem<dim>::solve ()
+  {
+    SolverControl           solver_control (1000, 1e-12);
+    SolverCG<>              cg (solver_control);
+
+    PreconditionSSOR<> preconditioner;
+    preconditioner.initialize(system_matrix, 1.2);
+
+    cg.solve (system_matrix, solution, system_rhs,
+             preconditioner);
+  }
+
+
+
+                                  // Finally the main function
+                                  // controlling the different steps to
+                                  // be performed. Its content is
+                                  // rather straightforward, generating
+                                  // a triangulation of a circle,
+                                  // associating a boundary to it, and
+                                  // then doing several cycles on
+                                  // subsequently finer grids. Note
+                                  // again that we have put mesh
+                                  // refinement into the loop header;
+                                  // this may be something for a test
+                                  // program, but for real applications
+                                  // you should consider that this
+                                  // implies that the mesh is refined
+                                  // after the loop is executed the
+                                  // last time since the increment
+                                  // clause (the last part of the
+                                  // three-parted loop header) is
+                                  // executed before the comparison
+                                  // part (the second one), which may
+                                  // be rather costly if the mesh is
+                                  // already quite refined. In that
+                                  // case, you should arrange code such
+                                  // that the mesh is not further
+                                  // refined after the last loop run
+                                  // (or you should do it at the
+                                  // beginning of each run except for
+                                  // the first one).
+  template <int dim>
+  void LaplaceProblem<dim>::run ()
+  {
+    GridGenerator::hyper_ball (triangulation);
+    static const HyperBallBoundary<dim> boundary;
+    triangulation.set_boundary (0, boundary);
+
+    for (unsigned int cycle=0; cycle<6; ++cycle, triangulation.refine_global(1))
+      {
+       setup_system ();
+       assemble_and_solve ();
+      };
+
+                                    // After all the data is generated,
+                                    // write a table of results to the
+                                    // screen:
+    output_table.set_precision("|u|_1", 6);
+    output_table.set_precision("error", 6);
+    output_table.write_text (std::cout);
+    std::cout << std::endl;
+  }
 }
 
 
 
-                                // Finally the main function
-                                // controlling the different steps to
-                                // be performed. Its content is
-                                // rather straightforward, generating
-                                // a triangulation of a circle,
-                                // associating a boundary to it, and
-                                // then doing several cycles on
-                                // subsequently finer grids. Note
-                                // again that we have put mesh
-                                // refinement into the loop header;
-                                // this may be something for a test
-                                // program, but for real applications
-                                // you should consider that this
-                                // implies that the mesh is refined
-                                // after the loop is executed the
-                                // last time since the increment
-                                // clause (the last part of the
-                                // three-parted loop header) is
-                                // executed before the comparison
-                                // part (the second one), which may
-                                // be rather costly if the mesh is
-                                // already quite refined. In that
-                                // case, you should arrange code such
-                                // that the mesh is not further
-                                // refined after the last loop run
-                                // (or you should do it at the
-                                // beginning of each run except for
-                                // the first one).
-template <int dim>
-void LaplaceProblem<dim>::run () 
-{
-  GridGenerator::hyper_ball (triangulation);
-  static const HyperBallBoundary<dim> boundary;
-  triangulation.set_boundary (0, boundary);
-  
-  for (unsigned int cycle=0; cycle<6; ++cycle, triangulation.refine_global(1))
-    {
-      setup_system ();
-      assemble_and_solve ();
-    };
-
-                                  // After all the data is generated,
-                                  // write a table of results to the
-                                  // screen:
-  output_table.set_precision("|u|_1", 6);
-  output_table.set_precision("error", 6);
-  output_table.write_text (std::cout);
-  std::cout << std::endl;
-}
-
-    
-
                                 // Finally the main function. It's
                                 // structure is the same as that used
                                 // in several of the previous
                                 // examples, so probably needs no
                                 // more explanation.
-int main () 
+int main ()
 {
   try
     {
-      deallog.depth_console (0);
+      dealii::deallog.depth_console (0);
       std::cout.precision(5);
 
                                       // This is the main loop, doing
@@ -672,7 +675,7 @@ int main ()
                                       // subsequent to which it is
                                       // immediately destroyed again.
       for (unsigned int mapping_degree=1; mapping_degree<=3; ++mapping_degree)
-       LaplaceProblem<2>(mapping_degree).run ();
+       Step11::LaplaceProblem<2>(mapping_degree).run ();
     }
   catch (std::exception &exc)
     {
@@ -686,7 +689,7 @@ int main ()
                << std::endl;
       return 1;
     }
-  catch (...) 
+  catch (...)
     {
       std::cerr << std::endl << std::endl
                << "----------------------------------------------------"
index a2ac8bf8f9033a4c00674679de3d772a537a0cf1..1c2dff25f7ff9064b02e96c1185d0a637504ba1d 100644 (file)
@@ -3,7 +3,7 @@
 
 /*    $Id$       */
 /*                                                                */
-/*    Copyright (C) 2010 by the deal.II authors */
+/*    Copyright (C) 2010, 2011 by the deal.II authors */
 /*                                                                */
 /*    This file is subject to QPL and may not be  distributed     */
 /*    without copyright and license information. Please refer     */
 #include <deal.II/dofs/dof_tools.h>
 #include <deal.II/numerics/data_out.h>
 #include <deal.II/fe/mapping_q1.h>
-                                // Here the discontinuous finite
-                                // elements are defined. They are
-                                // used in the same way as all other
-                                // finite elements, though -- as you
-                                // have seen in previous tutorial
+                                // Here the discontinuous finite elements are
+                                // defined. They are used in the same way as
+                                // all other finite elements, though -- as
+                                // you have seen in previous tutorial
                                 // programs -- there isn't much user
-                                // interaction with finite element
-                                // classes at all: the are passed to
-                                // <code>DoFHandler</code> and <code>FEValues</code>
-                                // objects, and that is about it.
+                                // interaction with finite element classes at
+                                // all: the are passed to
+                                // <code>DoFHandler</code> and
+                                // <code>FEValues</code> objects, and that is
+                                // about it.
 #include <deal.II/fe/fe_dgq.h>
                                 // We are going to use the simplest
                                 // possible solver, called Richardson
 #include <iostream>
 #include <fstream>
 
-using namespace dealii;
-
-                                // @sect3{Equation data}
-                                //
-                                // First, we define a class
-                                // describing the inhomogeneous
-                                // boundary data. Since only its
-                                // values are used, we implement
-                                // value_list(), but leave all other
-                                // functions of Function undefined.
-template <int dim>
-class BoundaryValues:  public Function<dim>
-{
-  public:
-    BoundaryValues () {};
-    virtual void value_list (const std::vector<Point<dim> > &points,
-                            std::vector<double> &values,
-                            const unsigned int component=0) const;
-};
-
-                                // Given the flow direction, the inflow
-                                // boundary of the unit square $[0,1]^2$ are
-                                // the right and the lower boundaries. We
-                                // prescribe discontinuous boundary values 1
-                                // and 0 on the x-axis and value 0 on the
-                                // right boundary. The values of this
-                                // function on the outflow boundaries will
-                                // not be used within the DG scheme.
-template <int dim>
-void BoundaryValues<dim>::value_list(const std::vector<Point<dim> > &points,
-                                      std::vector<double> &values,
-                                      const unsigned int) const
-{
-  Assert(values.size()==points.size(),
-        ExcDimensionMismatch(values.size(),points.size()));
 
-  for (unsigned int i=0; i<values.size(); ++i)
-    {
-      if (points[i](0)<0.5)
-       values[i]=1.;
-      else
-       values[i]=0.;
-    }
-}
-                                // @sect3{Class: Step12}
-                                //
-                                // After this preparations, we
-                                // proceed with the main class of
-                                // this program,
-                                // called Step12. It is basically
-                                // the main class of step-6. We do
-                                // not have a ConstraintMatrix,
-                                // because there are no hanging node
-                                // constraints in DG discretizations.
-
-                                // Major differences will only come
-                                // up in the implementation of the
-                                // assemble functions, since here, we
-                                // not only need to cover the flux
-                                // integrals over faces, we also use
-                                // the MeshWorker interface to
-                                // simplify the loops involved.
-template <int dim>
-class Step12
-{
-  public:
-    Step12 ();
-    void run ();
-
-  private:
-    void setup_system ();
-    void assemble_system ();
-    void solve (Vector<double> &solution);
-    void refine_grid ();
-    void output_results (const unsigned int cycle) const;
-
-    Triangulation<dim>   triangulation;
-    const MappingQ1<dim> mapping;
-
-                                    // Furthermore we want to use DG
-                                    // elements of degree 1 (but this
-                                    // is only specified in the
-                                    // constructor). If you want to
-                                    // use a DG method of a different
-                                    // degree the whole program stays
-                                    // the same, only replace 1 in
-                                    // the constructor by the desired
-                                    // polynomial degree.
-    FE_DGQ<dim>          fe;
-    DoFHandler<dim>      dof_handler;
-
-                                    // The next four members represent the
-                                    // linear system to be
-                                    // solved. <code>system_matrix</code> and
-                                    // <code>right_hand_side</code> are
-                                    // generated by
-                                    // <code>assemble_system()</code>, the
-                                    // <code>solution</code> is computed in
-                                    // <code>solve()</code>. The
-                                    // <code>sparsity_pattern</code> is used
-                                    // to determine the location of nonzero
-                                    // elements in
-                                    // <code>system_matrix</code>.
-    SparsityPattern      sparsity_pattern;
-    SparseMatrix<double> system_matrix;
-
-    Vector<double>       solution;
-    Vector<double>       right_hand_side;
-
-                                    // Finally, we have to provide
-                                    // functions that assemble the
-                                    // cell, boundary, and inner face
-                                    // terms. Within the MeshWorker
-                                    // framework, the loop over all
-                                    // cells and much of the setup of
-                                    // operations will be done
-                                    // outside this class, so all we
-                                    // have to provide are these
-                                    // three operations. They will
-                                    // then work on intermediate
-                                    // objects for which first, we
-                                    // here define typedefs to the
-                                    // info objects handed to the
-                                    // local integration functions in
-                                    // order to make our life easier
-                                    // below.
-    typedef MeshWorker::DoFInfo<dim> DoFInfo;
-    typedef MeshWorker::IntegrationInfo<dim> CellInfo;
-
-                                    // The following three functions
-                                    // are then the ones that get called
-                                    // inside the generic loop over all
-                                    // cells and faces. They are the
-                                    // ones doing the actual
-                                    // integration.
-                                    //
-                                    // In our code below, these
-                                    // functions do not access member
-                                    // variables of the current
-                                    // class, so we can mark them as
-                                    // <code>static</code> and simply
-                                    // pass pointers to these
-                                    // functions to the MeshWorker
-                                    // framework. If, however, these
-                                    // functions would want to access
-                                    // member variables (or needed
-                                    // additional arguments beyond
-                                    // the ones specified below), we
-                                    // could use the facilities of
-                                    // boost::bind (or std::bind,
-                                    // respectively) to provide the
-                                    // MeshWorker framework with
-                                    // objects that act as if they
-                                    // had the required number and
-                                    // types of arguments, but have
-                                    // in fact other arguments
-                                    // already bound.
-    static void integrate_cell_term (DoFInfo& dinfo, CellInfo& info);
-    static void integrate_boundary_term (DoFInfo& dinfo, CellInfo& info);
-    static void integrate_face_term (DoFInfo& dinfo1, DoFInfo& dinfo2,
-                                    CellInfo& info1, CellInfo& info2);
-};
-
-
-                                // We start with the constructor. The 1 in
-                                // the constructor call of <code>fe</code> is
-                                // the polynomial degree.
-template <int dim>
-Step12<dim>::Step12 ()
-               :
-                mapping (),
-                fe (1),
-               dof_handler (triangulation)
-{}
-
-
-template <int dim>
-void Step12<dim>::setup_system ()
+namespace Step12
 {
-                                // In the function that sets up the usual
-                                // finite element data structures, we first
-                                // need to distribute the DoFs.
-  dof_handler.distribute_dofs (fe);
-
-                                  // We start by generating the sparsity
-                                  // pattern. To this end, we first fill an
-                                  // intermediate object of type
-                                  // CompressedSparsityPattern with the
-                                  // couplings appearing in the system. After
-                                  // building the pattern, this object is
-                                  // copied to <code>sparsity_pattern</code>
-                                  // and can be discarded.
-
-                                  // To build the sparsity pattern for DG
-                                  // discretizations, we can call the
-                                  // function analogue to
-                                  // DoFTools::make_sparsity_pattern, which
-                                  // is called
-                                  // DoFTools::make_flux_sparsity_pattern:
-  CompressedSparsityPattern c_sparsity(dof_handler.n_dofs());
-  DoFTools::make_flux_sparsity_pattern (dof_handler, c_sparsity);
-  sparsity_pattern.copy_from(c_sparsity);
-
-                                  // Finally, we set up the structure
-                                  // of all components of the linear system.
-  system_matrix.reinit (sparsity_pattern);
-  solution.reinit (dof_handler.n_dofs());
-  right_hand_side.reinit (dof_handler.n_dofs());
-}
+  using namespace dealii;
 
-                                // @sect4{Function: assemble_system}
-
-                                // Here we see the major difference to
-                                // assembling by hand. Instead of writing
-                                // loops over cells and faces, we leave all
-                                // this to the MeshWorker framework. In order
-                                // to do so, we just have to define local
-                                // integration functions and use one of the
-                                // classes in namespace MeshWorker::Assembler
-                                // to build the global system.
-template <int dim>
-void Step12<dim>::assemble_system ()
-{
-                                  // This is the magic object, which
-                                  // knows everything about the data
-                                  // structures and local
-                                  // integration.  This is the object
-                                  // doing the work in the function
-                                  // MeshWorker::loop(), which is
-                                  // implicitly called by
-                                  // MeshWorker::integration_loop()
-                                  // below. After the functions to
-                                  // which we provide pointers did
-                                  // the local integration, the
-                                  // MeshWorker::Assembler::SystemSimple
-                                  // object distributes these into
-                                  // the global sparse matrix and the
-                                  // right hand side vector.
-  MeshWorker::IntegrationInfoBox<dim> info_box;
-
-                                  // First, we initialize the
-                                  // quadrature formulae and the
-                                  // update flags in the worker base
-                                  // class. For quadrature, we play
-                                  // safe and use a QGauss formula
-                                  // with number of points one higher
-                                  // than the polynomial degree
-                                  // used. Since the quadratures for
-                                  // cells, boundary and interior
-                                  // faces can be selected
-                                  // independently, we have to hand
-                                  // over this value three times.
-  const unsigned int n_gauss_points = dof_handler.get_fe().degree+1;
-  info_box.initialize_gauss_quadrature(n_gauss_points,
-                                      n_gauss_points,
-                                      n_gauss_points);
-
-                                  // These are the types of values we
-                                  // need for integrating our
-                                  // system. They are added to the
-                                  // flags used on cells, boundary
-                                  // and interior faces, as well as
-                                  // interior neighbor faces, which is
-                                  // forced by the four @p true
-                                  // values.
-  info_box.initialize_update_flags();
-  UpdateFlags update_flags = update_quadrature_points |
-                            update_values            |
-                            update_gradients;
-  info_box.add_update_flags(update_flags, true, true, true, true);
-
-                                  // After preparing all data in
-                                  // <tt>info_box</tt>, we initialize
-                                  // the FEValus objects in there.
-  info_box.initialize(fe, mapping);
-
-                                  // The object created so far helps
-                                  // us do the local integration on
-                                  // each cell and face. Now, we need
-                                  // an object which receives the
-                                  // integrated (local) data and
-                                  // forwards them to the assembler.
-  MeshWorker::DoFInfo<dim> dof_info(dof_handler);
-
-                                  // Now, we have to create the
-                                  // assembler object and tell it,
-                                  // where to put the local
-                                  // data. These will be our system
-                                  // matrix and the right hand side.
-  MeshWorker::Assembler::SystemSimple<SparseMatrix<double>, Vector<double> >
-    assembler;
-  assembler.initialize(system_matrix, right_hand_side);
-
-                                  // Finally, the integration loop
-                                  // over all active cells
-                                  // (determined by the first
-                                  // argument, which is an active
-                                  // iterator).
+                                  // @sect3{Equation data}
                                   //
-                                  // As noted in the discussion when
-                                  // declaring the local integration
-                                  // functions in the class
-                                  // declaration, the arguments
-                                  // expected by the assembling
-                                  // integrator class are not
-                                  // actually function
-                                  // pointers. Rather, they are
-                                  // objects that can be called like
-                                  // functions with a certain number
-                                  // of arguments. Consequently, we
-                                  // could also pass objects with
-                                  // appropriate operator()
-                                  // implementations here, or the
-                                  // result of std::bind if the local
-                                  // integrators were, for example,
-                                  // non-static member functions.
-  MeshWorker::integration_loop<dim, dim>
-    (dof_handler.begin_active(), dof_handler.end(),
-     dof_info, info_box,
-     &Step12<dim>::integrate_cell_term,
-     &Step12<dim>::integrate_boundary_term,
-     &Step12<dim>::integrate_face_term,
-     assembler, true);
-}
-
-
-                                // @sect4{The local integrators}
-
-                                // These functions are analogous to
-                                // step-12 and differ only in the
-                                // data structures. Instead of
-                                // providing the local matrices
-                                // explicitly in the argument list,
-                                // they are part of the info object.
-
-                                // Note that here we still have the
-                                // local integration loop inside the
-                                // following functions. The program
-                                // would be even shorter, if we used
-                                // pre-made operators from the
-                                // Operators namespace (which will be
-                                // added soon).
-
-template <int dim>
-void Step12<dim>::integrate_cell_term (DoFInfo& dinfo, CellInfo& info)
-{
-                                  // First, let us retrieve some of
-                                  // the objects used here from
-                                  // @p info. Note that these objects
-                                  // can handle much more complex
-                                  // structures, thus the access here
-                                  // looks more complicated than
-                                  // might seem necessary.
-  const FEValuesBase<dim>& fe_v = info.fe_values();
-  FullMatrix<double>& local_matrix = dinfo.matrix(0).matrix;
-  const std::vector<double> &JxW = fe_v.get_JxW_values ();
-
-                                  // With these objects, we continue
-                                  // local integration like
-                                  // always. First, we loop over the
-                                  // quadrature points and compute
-                                  // the advection vector in the
-                                  // current point.
-  for (unsigned int point=0; point<fe_v.n_quadrature_points; ++point)
-    {
-      Point<dim> beta;
-      beta(0) = -fe_v.quadrature_point(point)(1);
-      beta(1) = fe_v.quadrature_point(point)(0);
-      beta /= beta.norm();
-
-                                      // We solve a homogeneous
-                                      // equation, thus no right
-                                      // hand side shows up in
-                                      // the cell term.
-                                      // What's left is
-                                      // integrating the matrix entries.
-      for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
-       for (unsigned int j=0; j<fe_v.dofs_per_cell; ++j)
-         local_matrix(i,j) -= beta*fe_v.shape_grad(i,point)*
-                              fe_v.shape_value(j,point) *
-                              JxW[point];
-    }
-}
-
-                                // Now the same for the boundary terms. Note
-                                // that now we use FEValuesBase, the base
-                                // class for both FEFaceValues and
-                                // FESubfaceValues, in order to get access to
-                                // normal vectors.
-template <int dim>
-void Step12<dim>::integrate_boundary_term (DoFInfo& dinfo, CellInfo& info)
-{
-  const FEValuesBase<dim>& fe_v = info.fe_values();
-  FullMatrix<double>& local_matrix = dinfo.matrix(0).matrix;
-  Vector<double>& local_vector = dinfo.vector(0).block(0);
-
-  const std::vector<double> &JxW = fe_v.get_JxW_values ();
-  const std::vector<Point<dim> > &normals = fe_v.get_normal_vectors ();
-
-  std::vector<double> g(fe_v.n_quadrature_points);
-
-  static BoundaryValues<dim> boundary_function;
-  boundary_function.value_list (fe_v.get_quadrature_points(), g);
-
-  for (unsigned int point=0; point<fe_v.n_quadrature_points; ++point)
-    {
-      Point<dim> beta;
-      beta(0) = -fe_v.quadrature_point(point)(1);
-      beta(1) = fe_v.quadrature_point(point)(0);
-      beta /= beta.norm();
-
-      const double beta_n=beta * normals[point];
-      if (beta_n>0)
+                                  // First, we define a class
+                                  // describing the inhomogeneous
+                                  // boundary data. Since only its
+                                  // values are used, we implement
+                                  // value_list(), but leave all other
+                                  // functions of Function undefined.
+  template <int dim>
+  class BoundaryValues:  public Function<dim>
+  {
+    public:
+      BoundaryValues () {};
+      virtual void value_list (const std::vector<Point<dim> > &points,
+                              std::vector<double> &values,
+                              const unsigned int component=0) const;
+  };
+
+                                  // Given the flow direction, the inflow
+                                  // boundary of the unit square $[0,1]^2$ are
+                                  // the right and the lower boundaries. We
+                                  // prescribe discontinuous boundary values 1
+                                  // and 0 on the x-axis and value 0 on the
+                                  // right boundary. The values of this
+                                  // function on the outflow boundaries will
+                                  // not be used within the DG scheme.
+  template <int dim>
+  void BoundaryValues<dim>::value_list(const std::vector<Point<dim> > &points,
+                                      std::vector<double> &values,
+                                      const unsigned int) const
+  {
+    Assert(values.size()==points.size(),
+          ExcDimensionMismatch(values.size(),points.size()));
+
+    for (unsigned int i=0; i<values.size(); ++i)
+      {
+       if (points[i](0)<0.5)
+         values[i]=1.;
+       else
+         values[i]=0.;
+      }
+  }
+                                  // @sect3{The AdvectionProblem class}
+                                  //
+                                  // After this preparations, we
+                                  // proceed with the main class of
+                                  // this program,
+                                  // called AdvectionProblem. It is basically
+                                  // the main class of step-6. We do
+                                  // not have a ConstraintMatrix,
+                                  // because there are no hanging node
+                                  // constraints in DG discretizations.
+
+                                  // Major differences will only come
+                                  // up in the implementation of the
+                                  // assemble functions, since here, we
+                                  // not only need to cover the flux
+                                  // integrals over faces, we also use
+                                  // the MeshWorker interface to
+                                  // simplify the loops involved.
+  template <int dim>
+  class AdvectionProblem
+  {
+    public:
+      AdvectionProblem ();
+      void run ();
+
+    private:
+      void setup_system ();
+      void assemble_system ();
+      void solve (Vector<double> &solution);
+      void refine_grid ();
+      void output_results (const unsigned int cycle) const;
+
+      Triangulation<dim>   triangulation;
+      const MappingQ1<dim> mapping;
+
+                                      // Furthermore we want to use DG
+                                      // elements of degree 1 (but this
+                                      // is only specified in the
+                                      // constructor). If you want to
+                                      // use a DG method of a different
+                                      // degree the whole program stays
+                                      // the same, only replace 1 in
+                                      // the constructor by the desired
+                                      // polynomial degree.
+      FE_DGQ<dim>          fe;
+      DoFHandler<dim>      dof_handler;
+
+                                      // The next four members represent the
+                                      // linear system to be
+                                      // solved. <code>system_matrix</code> and
+                                      // <code>right_hand_side</code> are
+                                      // generated by
+                                      // <code>assemble_system()</code>, the
+                                      // <code>solution</code> is computed in
+                                      // <code>solve()</code>. The
+                                      // <code>sparsity_pattern</code> is used
+                                      // to determine the location of nonzero
+                                      // elements in
+                                      // <code>system_matrix</code>.
+      SparsityPattern      sparsity_pattern;
+      SparseMatrix<double> system_matrix;
+
+      Vector<double>       solution;
+      Vector<double>       right_hand_side;
+
+                                      // Finally, we have to provide
+                                      // functions that assemble the
+                                      // cell, boundary, and inner face
+                                      // terms. Within the MeshWorker
+                                      // framework, the loop over all
+                                      // cells and much of the setup of
+                                      // operations will be done
+                                      // outside this class, so all we
+                                      // have to provide are these
+                                      // three operations. They will
+                                      // then work on intermediate
+                                      // objects for which first, we
+                                      // here define typedefs to the
+                                      // info objects handed to the
+                                      // local integration functions in
+                                      // order to make our life easier
+                                      // below.
+      typedef MeshWorker::DoFInfo<dim> DoFInfo;
+      typedef MeshWorker::IntegrationInfo<dim> CellInfo;
+
+                                      // The following three functions
+                                      // are then the ones that get called
+                                      // inside the generic loop over all
+                                      // cells and faces. They are the
+                                      // ones doing the actual
+                                      // integration.
+                                      //
+                                      // In our code below, these
+                                      // functions do not access member
+                                      // variables of the current
+                                      // class, so we can mark them as
+                                      // <code>static</code> and simply
+                                      // pass pointers to these
+                                      // functions to the MeshWorker
+                                      // framework. If, however, these
+                                      // functions would want to access
+                                      // member variables (or needed
+                                      // additional arguments beyond
+                                      // the ones specified below), we
+                                      // could use the facilities of
+                                      // boost::bind (or std::bind,
+                                      // respectively) to provide the
+                                      // MeshWorker framework with
+                                      // objects that act as if they
+                                      // had the required number and
+                                      // types of arguments, but have
+                                      // in fact other arguments
+                                      // already bound.
+      static void integrate_cell_term (DoFInfo& dinfo,
+                                      CellInfo& info);
+      static void integrate_boundary_term (DoFInfo& dinfo,
+                                          CellInfo& info);
+      static void integrate_face_term (DoFInfo& dinfo1,
+                                      DoFInfo& dinfo2,
+                                      CellInfo& info1,
+                                      CellInfo& info2);
+  };
+
+
+                                  // We start with the constructor. The 1 in
+                                  // the constructor call of <code>fe</code> is
+                                  // the polynomial degree.
+  template <int dim>
+  AdvectionProblem<dim>::AdvectionProblem ()
+                 :
+                 mapping (),
+                 fe (1),
+                 dof_handler (triangulation)
+  {}
+
+
+  template <int dim>
+  void AdvectionProblem<dim>::setup_system ()
+  {
+                                    // In the function that sets up the usual
+                                    // finite element data structures, we first
+                                    // need to distribute the DoFs.
+    dof_handler.distribute_dofs (fe);
+
+                                    // We start by generating the sparsity
+                                    // pattern. To this end, we first fill an
+                                    // intermediate object of type
+                                    // CompressedSparsityPattern with the
+                                    // couplings appearing in the system. After
+                                    // building the pattern, this object is
+                                    // copied to <code>sparsity_pattern</code>
+                                    // and can be discarded.
+
+                                    // To build the sparsity pattern for DG
+                                    // discretizations, we can call the
+                                    // function analogue to
+                                    // DoFTools::make_sparsity_pattern, which
+                                    // is called
+                                    // DoFTools::make_flux_sparsity_pattern:
+    CompressedSparsityPattern c_sparsity(dof_handler.n_dofs());
+    DoFTools::make_flux_sparsity_pattern (dof_handler, c_sparsity);
+    sparsity_pattern.copy_from(c_sparsity);
+
+                                    // Finally, we set up the structure
+                                    // of all components of the linear system.
+    system_matrix.reinit (sparsity_pattern);
+    solution.reinit (dof_handler.n_dofs());
+    right_hand_side.reinit (dof_handler.n_dofs());
+  }
+
+                                  // @sect4{The assemble_system function}
+
+                                  // Here we see the major difference to
+                                  // assembling by hand. Instead of writing
+                                  // loops over cells and faces, we leave all
+                                  // this to the MeshWorker framework. In order
+                                  // to do so, we just have to define local
+                                  // integration functions and use one of the
+                                  // classes in namespace MeshWorker::Assembler
+                                  // to build the global system.
+  template <int dim>
+  void AdvectionProblem<dim>::assemble_system ()
+  {
+                                    // This is the magic object, which
+                                    // knows everything about the data
+                                    // structures and local
+                                    // integration.  This is the object
+                                    // doing the work in the function
+                                    // MeshWorker::loop(), which is
+                                    // implicitly called by
+                                    // MeshWorker::integration_loop()
+                                    // below. After the functions to
+                                    // which we provide pointers did
+                                    // the local integration, the
+                                    // MeshWorker::Assembler::SystemSimple
+                                    // object distributes these into
+                                    // the global sparse matrix and the
+                                    // right hand side vector.
+    MeshWorker::IntegrationInfoBox<dim> info_box;
+
+                                    // First, we initialize the
+                                    // quadrature formulae and the
+                                    // update flags in the worker base
+                                    // class. For quadrature, we play
+                                    // safe and use a QGauss formula
+                                    // with number of points one higher
+                                    // than the polynomial degree
+                                    // used. Since the quadratures for
+                                    // cells, boundary and interior
+                                    // faces can be selected
+                                    // independently, we have to hand
+                                    // over this value three times.
+    const unsigned int n_gauss_points = dof_handler.get_fe().degree+1;
+    info_box.initialize_gauss_quadrature(n_gauss_points,
+                                        n_gauss_points,
+                                        n_gauss_points);
+
+                                    // These are the types of values we
+                                    // need for integrating our
+                                    // system. They are added to the
+                                    // flags used on cells, boundary
+                                    // and interior faces, as well as
+                                    // interior neighbor faces, which is
+                                    // forced by the four @p true
+                                    // values.
+    info_box.initialize_update_flags();
+    UpdateFlags update_flags = update_quadrature_points |
+                              update_values            |
+                              update_gradients;
+    info_box.add_update_flags(update_flags, true, true, true, true);
+
+                                    // After preparing all data in
+                                    // <tt>info_box</tt>, we initialize
+                                    // the FEValus objects in there.
+    info_box.initialize(fe, mapping);
+
+                                    // The object created so far helps
+                                    // us do the local integration on
+                                    // each cell and face. Now, we need
+                                    // an object which receives the
+                                    // integrated (local) data and
+                                    // forwards them to the assembler.
+    MeshWorker::DoFInfo<dim> dof_info(dof_handler);
+
+                                    // Now, we have to create the
+                                    // assembler object and tell it,
+                                    // where to put the local
+                                    // data. These will be our system
+                                    // matrix and the right hand side.
+    MeshWorker::Assembler::SystemSimple<SparseMatrix<double>, Vector<double> >
+      assembler;
+    assembler.initialize(system_matrix, right_hand_side);
+
+                                    // Finally, the integration loop
+                                    // over all active cells
+                                    // (determined by the first
+                                    // argument, which is an active
+                                    // iterator).
+                                    //
+                                    // As noted in the discussion when
+                                    // declaring the local integration
+                                    // functions in the class
+                                    // declaration, the arguments
+                                    // expected by the assembling
+                                    // integrator class are not
+                                    // actually function
+                                    // pointers. Rather, they are
+                                    // objects that can be called like
+                                    // functions with a certain number
+                                    // of arguments. Consequently, we
+                                    // could also pass objects with
+                                    // appropriate operator()
+                                    // implementations here, or the
+                                    // result of std::bind if the local
+                                    // integrators were, for example,
+                                    // non-static member functions.
+    MeshWorker::integration_loop<dim, dim>
+      (dof_handler.begin_active(), dof_handler.end(),
+       dof_info, info_box,
+       &AdvectionProblem<dim>::integrate_cell_term,
+       &AdvectionProblem<dim>::integrate_boundary_term,
+       &AdvectionProblem<dim>::integrate_face_term,
+       assembler, true);
+  }
+
+
+                                  // @sect4{The local integrators}
+
+                                  // These functions are analogous to
+                                  // step-12 and differ only in the
+                                  // data structures. Instead of
+                                  // providing the local matrices
+                                  // explicitly in the argument list,
+                                  // they are part of the info object.
+
+                                  // Note that here we still have the
+                                  // local integration loop inside the
+                                  // following functions. The program
+                                  // would be even shorter, if we used
+                                  // pre-made operators from the
+                                  // Operators namespace (which will be
+                                  // added soon).
+
+  template <int dim>
+  void AdvectionProblem<dim>::integrate_cell_term (DoFInfo& dinfo,
+                                                  CellInfo& info)
+  {
+                                    // First, let us retrieve some of
+                                    // the objects used here from
+                                    // @p info. Note that these objects
+                                    // can handle much more complex
+                                    // structures, thus the access here
+                                    // looks more complicated than
+                                    // might seem necessary.
+    const FEValuesBase<dim>& fe_v = info.fe_values();
+    FullMatrix<double>& local_matrix = dinfo.matrix(0).matrix;
+    const std::vector<double> &JxW = fe_v.get_JxW_values ();
+
+                                    // With these objects, we continue
+                                    // local integration like
+                                    // always. First, we loop over the
+                                    // quadrature points and compute
+                                    // the advection vector in the
+                                    // current point.
+    for (unsigned int point=0; point<fe_v.n_quadrature_points; ++point)
+      {
+       Point<dim> beta;
+       beta(0) = -fe_v.quadrature_point(point)(1);
+       beta(1) = fe_v.quadrature_point(point)(0);
+       beta /= beta.norm();
+
+                                        // We solve a homogeneous
+                                        // equation, thus no right
+                                        // hand side shows up in
+                                        // the cell term.
+                                        // What's left is
+                                        // integrating the matrix entries.
        for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
          for (unsigned int j=0; j<fe_v.dofs_per_cell; ++j)
-           local_matrix(i,j) += beta_n *
+           local_matrix(i,j) -= beta*fe_v.shape_grad(i,point)*
                                 fe_v.shape_value(j,point) *
-                                fe_v.shape_value(i,point) *
                                 JxW[point];
-      else
-       for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
-         local_vector(i) -= beta_n *
-                            g[point] *
-                            fe_v.shape_value(i,point) *
-                            JxW[point];
-    }
-}
-
-                                // Finally, the interior face
-                                // terms. The difference here is that
-                                // we receive two info objects, one
-                                // for each cell adjacent to the face
-                                // and we assemble four matrices, one
-                                // for each cell and two for coupling
-                                // back and forth.
-template <int dim>
-void Step12<dim>::integrate_face_term (DoFInfo& dinfo1, DoFInfo& dinfo2,
-                                      CellInfo& info1, CellInfo& info2)
-{
-                                  // For quadrature points, weights,
-                                  // etc., we use the
-                                  // FEValuesBase object of the
-                                  // first argument.
-  const FEValuesBase<dim>& fe_v = info1.fe_values();
-
-                                  // For additional shape functions,
-                                  // we have to ask the neighbors
-                                  // FEValuesBase.
-  const FEValuesBase<dim>& fe_v_neighbor = info2.fe_values();
-
-                                  // Then we get references to the
-                                  // four local matrices. The letters
-                                  // u and v refer to trial and test
-                                  // functions, respectively. The
-                                  // %numbers indicate the cells
-                                  // provided by info1 and info2. By
-                                  // convention, the two matrices in
-                                  // each info object refer to the
-                                  // test functions on the respective
-                                  // cell. The first matrix contains the
-                                  // interior couplings of that cell,
-                                  // while the second contains the
-                                  // couplings between cells.
-  FullMatrix<double>& u1_v1_matrix = dinfo1.matrix(0,false).matrix;
-  FullMatrix<double>& u2_v1_matrix = dinfo1.matrix(0,true).matrix;
-  FullMatrix<double>& u1_v2_matrix = dinfo2.matrix(0,true).matrix;
-  FullMatrix<double>& u2_v2_matrix = dinfo2.matrix(0,false).matrix;
-
-                                  // Here, following the previous
-                                  // functions, we would have the
-                                  // local right hand side
-                                  // vectors. Fortunately, the
-                                  // interface terms only involve the
-                                  // solution and the right hand side
-                                  // does not receive any contributions.
-
-  const std::vector<double> &JxW = fe_v.get_JxW_values ();
-  const std::vector<Point<dim> > &normals = fe_v.get_normal_vectors ();
-
-  for (unsigned int point=0; point<fe_v.n_quadrature_points; ++point)
-    {
-      Point<dim> beta;
-      beta(0) = -fe_v.quadrature_point(point)(1);
-      beta(1) = fe_v.quadrature_point(point)(0);
-      beta /= beta.norm();
-
-      const double beta_n=beta * normals[point];
-      if (beta_n>0)
-       {
-                                          // This term we've already
-                                          // seen:
+      }
+  }
+
+                                  // Now the same for the boundary terms. Note
+                                  // that now we use FEValuesBase, the base
+                                  // class for both FEFaceValues and
+                                  // FESubfaceValues, in order to get access to
+                                  // normal vectors.
+  template <int dim>
+  void AdvectionProblem<dim>::integrate_boundary_term (DoFInfo& dinfo,
+                                                      CellInfo& info)
+  {
+    const FEValuesBase<dim>& fe_v = info.fe_values();
+    FullMatrix<double>& local_matrix = dinfo.matrix(0).matrix;
+    Vector<double>& local_vector = dinfo.vector(0).block(0);
+
+    const std::vector<double> &JxW = fe_v.get_JxW_values ();
+    const std::vector<Point<dim> > &normals = fe_v.get_normal_vectors ();
+
+    std::vector<double> g(fe_v.n_quadrature_points);
+
+    static BoundaryValues<dim> boundary_function;
+    boundary_function.value_list (fe_v.get_quadrature_points(), g);
+
+    for (unsigned int point=0; point<fe_v.n_quadrature_points; ++point)
+      {
+       Point<dim> beta;
+       beta(0) = -fe_v.quadrature_point(point)(1);
+       beta(1) = fe_v.quadrature_point(point)(0);
+       beta /= beta.norm();
+
+       const double beta_n=beta * normals[point];
+       if (beta_n>0)
          for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
            for (unsigned int j=0; j<fe_v.dofs_per_cell; ++j)
-             u1_v1_matrix(i,j) += beta_n *
-                                fe_v.shape_value(j,point) *
-                                fe_v.shape_value(i,point) *
-                                JxW[point];
-
-                                          // We additionally assemble
-                                          // the term $(\beta\cdot n
-                                          // u,\hat v)_{\partial
-                                          // \kappa_+}$,
-         for (unsigned int k=0; k<fe_v_neighbor.dofs_per_cell; ++k)
-           for (unsigned int j=0; j<fe_v.dofs_per_cell; ++j)
-             u1_v2_matrix(k,j) -= beta_n *
-                                 fe_v.shape_value(j,point) *
-                                 fe_v_neighbor.shape_value(k,point) *
-                                 JxW[point];
-       }
-      else
-       {
-                                          // This one we've already
-                                          // seen, too:
-         for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
-           for (unsigned int l=0; l<fe_v_neighbor.dofs_per_cell; ++l)
-             u2_v1_matrix(i,l) += beta_n *
-                                 fe_v_neighbor.shape_value(l,point) *
-                                 fe_v.shape_value(i,point) *
-                                 JxW[point];
-
-                                          // And this is another new
-                                          // one: $(\beta\cdot n \hat
-                                          // u,\hat v)_{\partial
-                                          // \kappa_-}$:
-         for (unsigned int k=0; k<fe_v_neighbor.dofs_per_cell; ++k)
-           for (unsigned int l=0; l<fe_v_neighbor.dofs_per_cell; ++l)
-             u2_v2_matrix(k,l) -= beta_n *
-                                  fe_v_neighbor.shape_value(l,point) *
-                                  fe_v_neighbor.shape_value(k,point) *
+             local_matrix(i,j) += beta_n *
+                                  fe_v.shape_value(j,point) *
+                                  fe_v.shape_value(i,point) *
                                   JxW[point];
-       }
-    }
-}
-
-
-                                // @sect3{All the rest}
-                                //
-                                // For this simple problem we use the
-                                // simplest possible solver, called
-                                // Richardson iteration, that represents a
-                                // simple defect correction. This, in
-                                // combination with a block SSOR
-                                // preconditioner, that uses the special
-                                // block matrix structure of system matrices
-                                // arising from DG discretizations. The size
-                                // of these blocks are the number of DoFs per
-                                // cell. Here, we use a SSOR preconditioning
-                                // as we have not renumbered the DoFs
-                                // according to the flow field. If the DoFs
-                                // are renumbered in the downstream direction
-                                // of the flow, then a block Gauss-Seidel
-                                // preconditioner (see the
-                                // PreconditionBlockSOR class with
-                                // relaxation=1) does a much better job.
-template <int dim>
-void Step12<dim>::solve (Vector<double> &solution)
-{
-  SolverControl           solver_control (1000, 1e-12);
-  SolverRichardson<>      solver (solver_control);
-
-                                  // Here we create the
-                                  // preconditioner,
-  PreconditionBlockSSOR<SparseMatrix<double> > preconditioner;
-
-                                  // then assign the matrix to it and
-                                  // set the right block size:
-  preconditioner.initialize(system_matrix, fe.dofs_per_cell);
-
-                                  // After these preparations we are
-                                  // ready to start the linear solver.
-  solver.solve (system_matrix, solution, right_hand_side,
-               preconditioner);
-}
-
-
-                                // We refine the grid according to a
-                                // very simple refinement criterion,
-                                // namely an approximation to the
-                                // gradient of the solution. As here
-                                // we consider the DG(1) method
-                                // (i.e. we use piecewise bilinear
-                                // shape functions) we could simply
-                                // compute the gradients on each
-                                // cell. But we do not want to base
-                                // our refinement indicator on the
-                                // gradients on each cell only, but
-                                // want to base them also on jumps of
-                                // the discontinuous solution
-                                // function over faces between
-                                // neighboring cells. The simplest
-                                // way of doing that is to compute
-                                // approximative gradients by
-                                // difference quotients including the
-                                // cell under consideration and its
-                                // neighbors. This is done by the
-                                // <code>DerivativeApproximation</code> class
-                                // that computes the approximate
-                                // gradients in a way similar to the
-                                // <code>GradientEstimation</code> described
-                                // in step-9 of this tutorial. In
-                                // fact, the
-                                // <code>DerivativeApproximation</code> class
-                                // was developed following the
-                                // <code>GradientEstimation</code> class of
-                                // step-9. Relating to the
-                                // discussion in step-9, here we
-                                // consider $h^{1+d/2}|\nabla_h
-                                // u_h|$. Furthermore we note that we
-                                // do not consider approximate second
-                                // derivatives because solutions to
-                                // the linear advection equation are
-                                // in general not in $H^2$ but in $H^1$
-                                // (to be more precise, in $H^1_\beta$)
-                                // only.
-template <int dim>
-void Step12<dim>::refine_grid ()
-{
-                                  // The <code>DerivativeApproximation</code>
-                                  // class computes the gradients to
-                                  // float precision. This is
-                                  // sufficient as they are
-                                  // approximate and serve as
-                                  // refinement indicators only.
-  Vector<float> gradient_indicator (triangulation.n_active_cells());
-
-                                  // Now the approximate gradients
-                                  // are computed
-  DerivativeApproximation::approximate_gradient (mapping,
-                                                dof_handler,
-                                                solution,
-                                                gradient_indicator);
-
-                                  // and they are cell-wise scaled by
-                                  // the factor $h^{1+d/2}$
-  typename DoFHandler<dim>::active_cell_iterator
-    cell = dof_handler.begin_active(),
-    endc = dof_handler.end();
-  for (unsigned int cell_no=0; cell!=endc; ++cell, ++cell_no)
-    gradient_indicator(cell_no)*=std::pow(cell->diameter(), 1+1.0*dim/2);
-
-                                  // Finally they serve as refinement
-                                  // indicator.
-  GridRefinement::refine_and_coarsen_fixed_number (triangulation,
-                                                  gradient_indicator,
-                                                  0.3, 0.1);
-
-  triangulation.execute_coarsening_and_refinement ();
-}
-
-
-                                // The output of this program
-                                // consists of eps-files of the
-                                // adaptively refined grids and the
-                                // numerical solutions given in
-                                // gnuplot format. This was covered
-                                // in previous examples and will not
-                                // be further commented on.
-template <int dim>
-void Step12<dim>::output_results (const unsigned int cycle) const
-{
-                                  // Write the grid in eps format.
-  std::string filename = "grid-";
-  filename += ('0' + cycle);
-  Assert (cycle < 10, ExcInternalError());
-
-  filename += ".eps";
-  deallog << "Writing grid to <" << filename << ">" << std::endl;
-  std::ofstream eps_output (filename.c_str());
-
-  GridOut grid_out;
-  grid_out.write_eps (triangulation, eps_output);
-
-                                  // Output of the solution in
-                                  // gnuplot format.
-  filename = "sol-";
-  filename += ('0' + cycle);
-  Assert (cycle < 10, ExcInternalError());
+       else
+         for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
+           local_vector(i) -= beta_n *
+                              g[point] *
+                              fe_v.shape_value(i,point) *
+                              JxW[point];
+      }
+  }
+
+                                  // Finally, the interior face
+                                  // terms. The difference here is that
+                                  // we receive two info objects, one
+                                  // for each cell adjacent to the face
+                                  // and we assemble four matrices, one
+                                  // for each cell and two for coupling
+                                  // back and forth.
+  template <int dim>
+  void AdvectionProblem<dim>::integrate_face_term (DoFInfo& dinfo1,
+                                                  DoFInfo& dinfo2,
+                                                  CellInfo& info1,
+                                                  CellInfo& info2)
+  {
+                                    // For quadrature points, weights,
+                                    // etc., we use the
+                                    // FEValuesBase object of the
+                                    // first argument.
+    const FEValuesBase<dim>& fe_v = info1.fe_values();
+
+                                    // For additional shape functions,
+                                    // we have to ask the neighbors
+                                    // FEValuesBase.
+    const FEValuesBase<dim>& fe_v_neighbor = info2.fe_values();
+
+                                    // Then we get references to the
+                                    // four local matrices. The letters
+                                    // u and v refer to trial and test
+                                    // functions, respectively. The
+                                    // %numbers indicate the cells
+                                    // provided by info1 and info2. By
+                                    // convention, the two matrices in
+                                    // each info object refer to the
+                                    // test functions on the respective
+                                    // cell. The first matrix contains the
+                                    // interior couplings of that cell,
+                                    // while the second contains the
+                                    // couplings between cells.
+    FullMatrix<double>& u1_v1_matrix = dinfo1.matrix(0,false).matrix;
+    FullMatrix<double>& u2_v1_matrix = dinfo1.matrix(0,true).matrix;
+    FullMatrix<double>& u1_v2_matrix = dinfo2.matrix(0,true).matrix;
+    FullMatrix<double>& u2_v2_matrix = dinfo2.matrix(0,false).matrix;
+
+                                    // Here, following the previous
+                                    // functions, we would have the
+                                    // local right hand side
+                                    // vectors. Fortunately, the
+                                    // interface terms only involve the
+                                    // solution and the right hand side
+                                    // does not receive any contributions.
+
+    const std::vector<double> &JxW = fe_v.get_JxW_values ();
+    const std::vector<Point<dim> > &normals = fe_v.get_normal_vectors ();
+
+    for (unsigned int point=0; point<fe_v.n_quadrature_points; ++point)
+      {
+       Point<dim> beta;
+       beta(0) = -fe_v.quadrature_point(point)(1);
+       beta(1) = fe_v.quadrature_point(point)(0);
+       beta /= beta.norm();
+
+       const double beta_n=beta * normals[point];
+       if (beta_n>0)
+         {
+                                            // This term we've already
+                                            // seen:
+           for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
+             for (unsigned int j=0; j<fe_v.dofs_per_cell; ++j)
+               u1_v1_matrix(i,j) += beta_n *
+                                    fe_v.shape_value(j,point) *
+                                    fe_v.shape_value(i,point) *
+                                    JxW[point];
+
+                                            // We additionally assemble
+                                            // the term $(\beta\cdot n
+                                            // u,\hat v)_{\partial
+                                            // \kappa_+}$,
+           for (unsigned int k=0; k<fe_v_neighbor.dofs_per_cell; ++k)
+             for (unsigned int j=0; j<fe_v.dofs_per_cell; ++j)
+               u1_v2_matrix(k,j) -= beta_n *
+                                    fe_v.shape_value(j,point) *
+                                    fe_v_neighbor.shape_value(k,point) *
+                                    JxW[point];
+         }
+       else
+         {
+                                            // This one we've already
+                                            // seen, too:
+           for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
+             for (unsigned int l=0; l<fe_v_neighbor.dofs_per_cell; ++l)
+               u2_v1_matrix(i,l) += beta_n *
+                                    fe_v_neighbor.shape_value(l,point) *
+                                    fe_v.shape_value(i,point) *
+                                    JxW[point];
+
+                                            // And this is another new
+                                            // one: $(\beta\cdot n \hat
+                                            // u,\hat v)_{\partial
+                                            // \kappa_-}$:
+           for (unsigned int k=0; k<fe_v_neighbor.dofs_per_cell; ++k)
+             for (unsigned int l=0; l<fe_v_neighbor.dofs_per_cell; ++l)
+               u2_v2_matrix(k,l) -= beta_n *
+                                    fe_v_neighbor.shape_value(l,point) *
+                                    fe_v_neighbor.shape_value(k,point) *
+                                    JxW[point];
+         }
+      }
+  }
+
+
+                                  // @sect3{All the rest}
+                                  //
+                                  // For this simple problem we use the
+                                  // simplest possible solver, called
+                                  // Richardson iteration, that represents a
+                                  // simple defect correction. This, in
+                                  // combination with a block SSOR
+                                  // preconditioner, that uses the special
+                                  // block matrix structure of system matrices
+                                  // arising from DG discretizations. The size
+                                  // of these blocks are the number of DoFs per
+                                  // cell. Here, we use a SSOR preconditioning
+                                  // as we have not renumbered the DoFs
+                                  // according to the flow field. If the DoFs
+                                  // are renumbered in the downstream direction
+                                  // of the flow, then a block Gauss-Seidel
+                                  // preconditioner (see the
+                                  // PreconditionBlockSOR class with
+                                  // relaxation=1) does a much better job.
+  template <int dim>
+  void AdvectionProblem<dim>::solve (Vector<double> &solution)
+  {
+    SolverControl           solver_control (1000, 1e-12);
+    SolverRichardson<>      solver (solver_control);
+
+                                    // Here we create the
+                                    // preconditioner,
+    PreconditionBlockSSOR<SparseMatrix<double> > preconditioner;
+
+                                    // then assign the matrix to it and
+                                    // set the right block size:
+    preconditioner.initialize(system_matrix, fe.dofs_per_cell);
+
+                                    // After these preparations we are
+                                    // ready to start the linear solver.
+    solver.solve (system_matrix, solution, right_hand_side,
+                 preconditioner);
+  }
+
+
+                                  // We refine the grid according to a
+                                  // very simple refinement criterion,
+                                  // namely an approximation to the
+                                  // gradient of the solution. As here
+                                  // we consider the DG(1) method
+                                  // (i.e. we use piecewise bilinear
+                                  // shape functions) we could simply
+                                  // compute the gradients on each
+                                  // cell. But we do not want to base
+                                  // our refinement indicator on the
+                                  // gradients on each cell only, but
+                                  // want to base them also on jumps of
+                                  // the discontinuous solution
+                                  // function over faces between
+                                  // neighboring cells. The simplest
+                                  // way of doing that is to compute
+                                  // approximative gradients by
+                                  // difference quotients including the
+                                  // cell under consideration and its
+                                  // neighbors. This is done by the
+                                  // <code>DerivativeApproximation</code> class
+                                  // that computes the approximate
+                                  // gradients in a way similar to the
+                                  // <code>GradientEstimation</code> described
+                                  // in step-9 of this tutorial. In
+                                  // fact, the
+                                  // <code>DerivativeApproximation</code> class
+                                  // was developed following the
+                                  // <code>GradientEstimation</code> class of
+                                  // step-9. Relating to the
+                                  // discussion in step-9, here we
+                                  // consider $h^{1+d/2}|\nabla_h
+                                  // u_h|$. Furthermore we note that we
+                                  // do not consider approximate second
+                                  // derivatives because solutions to
+                                  // the linear advection equation are
+                                  // in general not in $H^2$ but in $H^1$
+                                  // (to be more precise, in $H^1_\beta$)
+                                  // only.
+  template <int dim>
+  void AdvectionProblem<dim>::refine_grid ()
+  {
+                                    // The <code>DerivativeApproximation</code>
+                                    // class computes the gradients to
+                                    // float precision. This is
+                                    // sufficient as they are
+                                    // approximate and serve as
+                                    // refinement indicators only.
+    Vector<float> gradient_indicator (triangulation.n_active_cells());
+
+                                    // Now the approximate gradients
+                                    // are computed
+    DerivativeApproximation::approximate_gradient (mapping,
+                                                  dof_handler,
+                                                  solution,
+                                                  gradient_indicator);
+
+                                    // and they are cell-wise scaled by
+                                    // the factor $h^{1+d/2}$
+    typename DoFHandler<dim>::active_cell_iterator
+      cell = dof_handler.begin_active(),
+      endc = dof_handler.end();
+    for (unsigned int cell_no=0; cell!=endc; ++cell, ++cell_no)
+      gradient_indicator(cell_no)*=std::pow(cell->diameter(), 1+1.0*dim/2);
+
+                                    // Finally they serve as refinement
+                                    // indicator.
+    GridRefinement::refine_and_coarsen_fixed_number (triangulation,
+                                                    gradient_indicator,
+                                                    0.3, 0.1);
+
+    triangulation.execute_coarsening_and_refinement ();
+  }
+
+
+                                  // The output of this program
+                                  // consists of eps-files of the
+                                  // adaptively refined grids and the
+                                  // numerical solutions given in
+                                  // gnuplot format. This was covered
+                                  // in previous examples and will not
+                                  // be further commented on.
+  template <int dim>
+  void AdvectionProblem<dim>::output_results (const unsigned int cycle) const
+  {
+                                    // Write the grid in eps format.
+    std::string filename = "grid-";
+    filename += ('0' + cycle);
+    Assert (cycle < 10, ExcInternalError());
+
+    filename += ".eps";
+    deallog << "Writing grid to <" << filename << ">" << std::endl;
+    std::ofstream eps_output (filename.c_str());
+
+    GridOut grid_out;
+    grid_out.write_eps (triangulation, eps_output);
+
+                                    // Output of the solution in
+                                    // gnuplot format.
+    filename = "sol-";
+    filename += ('0' + cycle);
+    Assert (cycle < 10, ExcInternalError());
+
+    filename += ".gnuplot";
+    deallog << "Writing solution to <" << filename << ">" << std::endl;
+    std::ofstream gnuplot_output (filename.c_str());
+
+    DataOut<dim> data_out;
+    data_out.attach_dof_handler (dof_handler);
+    data_out.add_data_vector (solution, "u");
+
+    data_out.build_patches ();
+
+    data_out.write_gnuplot(gnuplot_output);
+  }
+
+
+                                  // The following <code>run</code> function is
+                                  // similar to previous examples.
+  template <int dim>
+  void AdvectionProblem<dim>::run ()
+  {
+    for (unsigned int cycle=0; cycle<6; ++cycle)
+      {
+       deallog << "Cycle " << cycle << std::endl;
+
+       if (cycle == 0)
+         {
+           GridGenerator::hyper_cube (triangulation);
+
+           triangulation.refine_global (3);
+         }
+       else
+         refine_grid ();
+
+
+       deallog << "Number of active cells:       "
+               << triangulation.n_active_cells()
+               << std::endl;
 
-  filename += ".gnuplot";
-  deallog << "Writing solution to <" << filename << ">" << std::endl;
-  std::ofstream gnuplot_output (filename.c_str());
+       setup_system ();
 
-  DataOut<dim> data_out;
-  data_out.attach_dof_handler (dof_handler);
-  data_out.add_data_vector (solution, "u");
+       deallog << "Number of degrees of freedom: "
+               << dof_handler.n_dofs()
+               << std::endl;
 
-  data_out.build_patches ();
+       assemble_system ();
+       solve (solution);
 
-  data_out.write_gnuplot(gnuplot_output);
+       output_results (cycle);
+      }
+  }
 }
 
 
-                                // The following <code>run</code> function is
-                                // similar to previous examples.
-template <int dim>
-void Step12<dim>::run ()
-{
-  for (unsigned int cycle=0; cycle<6; ++cycle)
-    {
-      deallog << "Cycle " << cycle << std::endl;
-
-      if (cycle == 0)
-       {
-         GridGenerator::hyper_cube (triangulation);
-
-         triangulation.refine_global (3);
-       }
-      else
-       refine_grid ();
-
-
-      deallog << "Number of active cells:       "
-             << triangulation.n_active_cells()
-             << std::endl;
-
-      setup_system ();
-
-      deallog << "Number of degrees of freedom: "
-             << dof_handler.n_dofs()
-             << std::endl;
-
-      assemble_system ();
-      solve (solution);
-
-      output_results (cycle);
-    }
-}
-
                                 // The following <code>main</code> function is
                                 // similar to previous examples as well, and
                                 // need not be commented on.
@@ -808,7 +821,7 @@ int main ()
 {
   try
     {
-      Step12<2> dgmethod;
+      Step12::AdvectionProblem<2> dgmethod;
       dgmethod.run ();
     }
   catch (std::exception &exc)
index ee2a5d8299bd51f56fb3313ab8406418f2c1a4c1..bd6fee2888e699a2ed512a6649c765dbda3c10a7 100644 (file)
@@ -3,7 +3,7 @@
 
 /*    $Id$       */
 /*                                                                */
-/*    Copyright (C) 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by the deal.II authors */
+/*    Copyright (C) 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011 by the deal.II authors */
 /*                                                                */
 /*    This file is subject to QPL and may not be  distributed     */
 /*    without copyright and license information. Please refer     */
 
                                 // The last step is as in all
                                 // previous programs:
-using namespace dealii;
-
-                                // @sect3{Evaluation of the solution}
-
-                                // As for the program itself, we
-                                // first define classes that evaluate
-                                // the solutions of a Laplace
-                                // equation. In fact, they can
-                                // evaluate every kind of solution,
-                                // as long as it is described by a
-                                // <code>DoFHandler</code> object, and a
-                                // solution vector. We define them
-                                // here first, even before the
-                                // classes that actually generate the
-                                // solution to be evaluated, since we
-                                // need to declare an abstract base
-                                // class that the solver classes can
-                                // refer to.
-                                //
-                                // From an abstract point of view, we
-                                // declare a pure base class
-                                // that provides an evaluation
-                                // operator() which will
-                                // do the evaluation of the solution
-                                // (whatever derived classes might
-                                // consider an <code>evaluation</code>). Since
-                                // this is the only real function of
-                                // this base class (except for some
-                                // bookkeeping machinery), one
-                                // usually terms such a class that
-                                // only has an <code>operator()</code> a
-                                // <code>functor</code> in C++ terminology,
-                                // since it is used just like a
-                                // function object.
-                                //
-                                // Objects of this functor type will
-                                // then later be passed to the solver
-                                // object, which applies it to the
-                                // solution just computed. The
-                                // evaluation objects may then
-                                // extract any quantity they like
-                                // from the solution. The advantage
-                                // of putting these evaluation
-                                // functions into a separate
-                                // hierarchy of classes is that by
-                                // design they cannot use the
-                                // internals of the solver object and
-                                // are therefore independent of
-                                // changes to the way the solver
-                                // works. Furthermore, it is trivial
-                                // to write another evaluation class
-                                // without modifying the solver
-                                // class, which speeds up programming
-                                // (not being able to use internals
-                                // of another class also means that
-                                // you do not have to worry about
-                                // them -- programming evaluators is
-                                // usually a rather quickly done
-                                // task), as well as compilation (if
-                                // solver and evaluation classes are
-                                // put into different files: the
-                                // solver only needs to see the
-                                // declaration of the abstract base
-                                // class, and therefore does not need
-                                // to be recompiled upon addition of
-                                // a new evaluation class, or
-                                // modification of an old one).
-                                // On a related note, you can reuse
-                                // the evaluation classes for other
-                                // projects, solving different
-                                // equations.
-                                //
-                                // In order to improve separation of
-                                // code into different modules, we
-                                // put the evaluation classes into a
-                                // namespace of their own. This makes
-                                // it easier to actually solve
-                                // different equations in the same
-                                // program, by assembling it from
-                                // existing building blocks. The
-                                // reason for this is that classes
-                                // for similar purposes tend to have
-                                // the same name, although they were
-                                // developed in different
-                                // contexts. In order to be able to
-                                // use them together in one program,
-                                // it is necessary that they are
-                                // placed in different
-                                // namespaces. This we do here:
-namespace Evaluation
+namespace Step13
 {
-
-                                  // Now for the abstract base class
-                                  // of evaluation classes: its main
-                                  // purpose is to declare a pure
-                                  // virtual function <code>operator()</code>
-                                  // taking a <code>DoFHandler</code> object,
-                                  // and the solution vector. In
-                                  // order to be able to use pointers
-                                  // to this base class only, it also
-                                  // has to declare a virtual
-                                  // destructor, which however does
-                                  // nothing. Besides this, it only
-                                  // provides for a little bit of
-                                  // bookkeeping: since we usually
-                                  // want to evaluate solutions on
-                                  // subsequent refinement levels, we
-                                  // store the number of the present
-                                  // refinement cycle, and provide a
-                                  // function to change this number.
-  template <int dim>
-  class EvaluationBase 
+  using namespace dealii;
+
+                                  // @sect3{Evaluation of the solution}
+
+                                  // As for the program itself, we
+                                  // first define classes that evaluate
+                                  // the solutions of a Laplace
+                                  // equation. In fact, they can
+                                  // evaluate every kind of solution,
+                                  // as long as it is described by a
+                                  // <code>DoFHandler</code> object, and a
+                                  // solution vector. We define them
+                                  // here first, even before the
+                                  // classes that actually generate the
+                                  // solution to be evaluated, since we
+                                  // need to declare an abstract base
+                                  // class that the solver classes can
+                                  // refer to.
+                                  //
+                                  // From an abstract point of view, we
+                                  // declare a pure base class
+                                  // that provides an evaluation
+                                  // operator() which will
+                                  // do the evaluation of the solution
+                                  // (whatever derived classes might
+                                  // consider an <code>evaluation</code>). Since
+                                  // this is the only real function of
+                                  // this base class (except for some
+                                  // bookkeeping machinery), one
+                                  // usually terms such a class that
+                                  // only has an <code>operator()</code> a
+                                  // <code>functor</code> in C++ terminology,
+                                  // since it is used just like a
+                                  // function object.
+                                  //
+                                  // Objects of this functor type will
+                                  // then later be passed to the solver
+                                  // object, which applies it to the
+                                  // solution just computed. The
+                                  // evaluation objects may then
+                                  // extract any quantity they like
+                                  // from the solution. The advantage
+                                  // of putting these evaluation
+                                  // functions into a separate
+                                  // hierarchy of classes is that by
+                                  // design they cannot use the
+                                  // internals of the solver object and
+                                  // are therefore independent of
+                                  // changes to the way the solver
+                                  // works. Furthermore, it is trivial
+                                  // to write another evaluation class
+                                  // without modifying the solver
+                                  // class, which speeds up programming
+                                  // (not being able to use internals
+                                  // of another class also means that
+                                  // you do not have to worry about
+                                  // them -- programming evaluators is
+                                  // usually a rather quickly done
+                                  // task), as well as compilation (if
+                                  // solver and evaluation classes are
+                                  // put into different files: the
+                                  // solver only needs to see the
+                                  // declaration of the abstract base
+                                  // class, and therefore does not need
+                                  // to be recompiled upon addition of
+                                  // a new evaluation class, or
+                                  // modification of an old one).
+                                  // On a related note, you can reuse
+                                  // the evaluation classes for other
+                                  // projects, solving different
+                                  // equations.
+                                  //
+                                  // In order to improve separation of
+                                  // code into different modules, we
+                                  // put the evaluation classes into a
+                                  // namespace of their own. This makes
+                                  // it easier to actually solve
+                                  // different equations in the same
+                                  // program, by assembling it from
+                                  // existing building blocks. The
+                                  // reason for this is that classes
+                                  // for similar purposes tend to have
+                                  // the same name, although they were
+                                  // developed in different
+                                  // contexts. In order to be able to
+                                  // use them together in one program,
+                                  // it is necessary that they are
+                                  // placed in different
+                                  // namespaces. This we do here:
+  namespace Evaluation
   {
-    public:
-      virtual ~EvaluationBase ();
-
-      void set_refinement_cycle (const unsigned int refinement_cycle);
-      
-      virtual void operator () (const DoFHandler<dim> &dof_handler,
-                               const Vector<double>  &solution) const = 0;
-    protected:
-      unsigned int refinement_cycle;
-  };
 
+                                    // Now for the abstract base class
+                                    // of evaluation classes: its main
+                                    // purpose is to declare a pure
+                                    // virtual function <code>operator()</code>
+                                    // taking a <code>DoFHandler</code> object,
+                                    // and the solution vector. In
+                                    // order to be able to use pointers
+                                    // to this base class only, it also
+                                    // has to declare a virtual
+                                    // destructor, which however does
+                                    // nothing. Besides this, it only
+                                    // provides for a little bit of
+                                    // bookkeeping: since we usually
+                                    // want to evaluate solutions on
+                                    // subsequent refinement levels, we
+                                    // store the number of the present
+                                    // refinement cycle, and provide a
+                                    // function to change this number.
+    template <int dim>
+    class EvaluationBase
+    {
+      public:
+       virtual ~EvaluationBase ();
 
-                                  // After the declaration has been
-                                  // discussed above, the
-                                  // implementation is rather
-                                  // straightforward:
-  template <int dim>
-  EvaluationBase<dim>::~EvaluationBase ()
-  {}
-  
+       void set_refinement_cycle (const unsigned int refinement_cycle);
 
-  
-  template <int dim>
-  void
-  EvaluationBase<dim>::set_refinement_cycle (const unsigned int step)
-  {
-    refinement_cycle = step;
-  }
+       virtual void operator () (const DoFHandler<dim> &dof_handler,
+                                 const Vector<double>  &solution) const = 0;
+      protected:
+       unsigned int refinement_cycle;
+    };
 
 
-                                  // @sect4{%Point evaluation}
+                                    // After the declaration has been
+                                    // discussed above, the
+                                    // implementation is rather
+                                    // straightforward:
+    template <int dim>
+    EvaluationBase<dim>::~EvaluationBase ()
+    {}
 
-                                  // The next thing is to implement
-                                  // actual evaluation classes. As
-                                  // noted in the introduction, we'd
-                                  // like to extract a point value
-                                  // from the solution, so the first
-                                  // class does this in its
-                                  // <code>operator()</code>. The actual point
-                                  // is given to this class through
-                                  // the constructor, as well as a
-                                  // table object into which it will
-                                  // put its findings.
-                                  //
-                                  // Finding out the value of a
-                                  // finite element field at an
-                                  // arbitrary point is rather
-                                  // difficult, if we cannot rely on
-                                  // knowing the actual finite
-                                  // element used, since then we
-                                  // cannot, for example, interpolate
-                                  // between nodes. For simplicity,
-                                  // we therefore assume here that
-                                  // the point at which we want to
-                                  // evaluate the field is actually a
-                                  // node. If, in the process of
-                                  // evaluating the solution, we find
-                                  // that we did not encounter this
-                                  // point upon looping over all
-                                  // vertices, we then have to throw
-                                  // an exception in order to signal
-                                  // to the calling functions that
-                                  // something has gone wrong, rather
-                                  // than silently ignore this error.
-                                  //
-                                  // In the step-9 example program,
-                                  // we have already seen how such an
-                                  // exception class can be declared,
-                                  // using the <code>DeclExceptionN</code>
-                                  // macros. We use this mechanism
-                                  // here again.
-                                  //
-                                  // From this, the actual
-                                  // declaration of this class should
-                                  // be evident. Note that of course
-                                  // even if we do not list a
-                                  // destructor explicitely, an
-                                  // implicit destructor is generated
-                                  // from the compiler, and it is
-                                  // virtual just as the one of the
-                                  // base class.
-  template <int dim>
-  class PointValueEvaluation : public EvaluationBase<dim>
-  {
-    public:
-      PointValueEvaluation (const Point<dim>   &evaluation_point,
-                           TableHandler       &results_table);
-      
-      virtual void operator () (const DoFHandler<dim> &dof_handler,
-                               const Vector<double>  &solution) const;
-      
-      DeclException1 (ExcEvaluationPointNotFound,
-                     Point<dim>,
-                     << "The evaluation point " << arg1
-                     << " was not found among the vertices of the present grid.");
-    private:
-      const Point<dim>  evaluation_point;
-      TableHandler     &results_table;
-  };
 
 
-                                  // As for the definition, the
-                                  // constructor is trivial, just
-                                  // taking data and storing it in
-                                  // object-local ones:
-  template <int dim>
-  PointValueEvaluation<dim>::
-  PointValueEvaluation (const Point<dim>   &evaluation_point,
-                       TableHandler       &results_table)
-                 :
-                 evaluation_point (evaluation_point),
-                 results_table (results_table)
-  {}
-  
-
-
-                                  // Now for the function that is
-                                  // mainly of interest in this
-                                  // class, the computation of the
-                                  // point value:
-  template <int dim>
-  void
-  PointValueEvaluation<dim>::
-  operator () (const DoFHandler<dim> &dof_handler,
-              const Vector<double>  &solution) const 
-  {
-                                    // First allocate a variable that
-                                    // will hold the point
-                                    // value. Initialize it with a
-                                    // value that is clearly bogus,
-                                    // so that if we fail to set it
-                                    // to a reasonable value, we will
-                                    // note at once. This may not be
-                                    // necessary in a function as
-                                    // small as this one, since we
-                                    // can easily see all possible
-                                    // paths of execution here, but
-                                    // it proved to be helpful for
-                                    // more complex cases, and so we
-                                    // employ this strategy here as
-                                    // well.
-    double point_value = 1e20;
-
-                                    // Then loop over all cells and
-                                    // all their vertices, and check
-                                    // whether a vertex matches the
-                                    // evaluation point. If this is
-                                    // the case, then extract the
-                                    // point value, set a flag that
-                                    // we have found the point of
-                                    // interest, and exit the loop.
-    typename DoFHandler<dim>::active_cell_iterator
-      cell = dof_handler.begin_active(),
-      endc = dof_handler.end();
-    bool evaluation_point_found = false;
-    for (; (cell!=endc) && !evaluation_point_found; ++cell)
-      for (unsigned int vertex=0;
-          vertex<GeometryInfo<dim>::vertices_per_cell;
-          ++vertex)
-       if (cell->vertex(vertex) == evaluation_point)
-         {
-                                            // In order to extract
-                                            // the point value from
-                                            // the global solution
-                                            // vector, pick that
-                                            // component that belongs
-                                            // to the vertex of
-                                            // interest, and, in case
-                                            // the solution is
-                                            // vector-valued, take
-                                            // the first component of
-                                            // it:
-           point_value = solution(cell->vertex_dof_index(vertex,0));
-                                            // Note that by this we
-                                            // have made an
-                                            // assumption that is not
-                                            // valid always and
-                                            // should be documented
-                                            // in the class
-                                            // declaration if this
-                                            // were code for a real
-                                            // application rather
-                                            // than a tutorial
-                                            // program: we assume
-                                            // that the finite
-                                            // element used for the
-                                            // solution we try to
-                                            // evaluate actually has
-                                            // degrees of freedom
-                                            // associated with
-                                            // vertices. This, for
-                                            // example, does not hold
-                                            // for discontinuous
-                                            // elements, were the
-                                            // support points for the
-                                            // shape functions
-                                            // happen to be located
-                                            // at the vertices, but
-                                            // are not associated
-                                            // with the vertices but
-                                            // rather with the cell
-                                            // interior, since
-                                            // association with
-                                            // vertices would imply
-                                            // continuity there. It
-                                            // would also not hold
-                                            // for edge oriented
-                                            // elements, and the
-                                            // like.
-                                            //
-                                            // Ideally, we would
-                                            // check this at the
-                                            // beginning of the
-                                            // function, for example
-                                            // by a statement like
-                                            // <code>Assert
-                                            // (dof_handler.get_fe().dofs_per_vertex
-                                            // @> 0,
-                                            // ExcNotImplemented())</code>,
-                                            // which should make it
-                                            // quite clear what is
-                                            // going wrong when the
-                                            // exception is
-                                            // triggered. In this
-                                            // case, we omit it
-                                            // (which is indeed bad
-                                            // style), but knowing
-                                            // that that does not
-                                            // hurt here, since the
-                                            // statement
-                                            // <code>cell-@>vertex_dof_index(vertex,0)</code>
-                                            // would fail if we asked
-                                            // it to give us the DoF
-                                            // index of a vertex if
-                                            // there were none.
-                                            //
-                                            // We stress again that
-                                            // this restriction on
-                                            // the allowed finite
-                                            // elements should be
-                                            // stated in the class
-                                            // documentation.
-
-                                            // Since we found the
-                                            // right point, we now
-                                            // set the respective
-                                            // flag and exit the
-                                            // innermost loop. The
-                                            // outer loop will the
-                                            // also be terminated due
-                                            // to the set flag.
-           evaluation_point_found = true;
-           break;
-         };
+    template <int dim>
+    void
+    EvaluationBase<dim>::set_refinement_cycle (const unsigned int step)
+    {
+      refinement_cycle = step;
+    }
 
-                                    // Finally, we'd like to make
-                                    // sure that we have indeed found
-                                    // the evaluation point, since if
-                                    // that were not so we could not
-                                    // give a reasonable value of the
-                                    // solution there and the rest of
-                                    // the computations were useless
-                                    // anyway. So make sure through
-                                    // the <code>AssertThrow</code> macro
-                                    // already used in the step-9
-                                    // program that we have indeed
-                                    // found this point. If this is
-                                    // not so, the macro throws an
-                                    // exception of the type that is
-                                    // given to it as second
-                                    // argument, but compared to a
-                                    // straightforward <code>throw</code>
-                                    // statement, it fills the
-                                    // exception object with a set of
-                                    // additional information, for
-                                    // example the source file and
-                                    // line number where the
-                                    // exception was generated, and
-                                    // the condition that failed. If
-                                    // you have a <code>catch</code> clause in
-                                    // your main function (as this
-                                    // program has), you will catch
-                                    // all exceptions that are not
-                                    // caught somewhere in between
-                                    // and thus already handled, and
-                                    // this additional information
-                                    // will help you find out what
-                                    // happened and where it went
-                                    // wrong.
-    AssertThrow (evaluation_point_found,
-                ExcEvaluationPointNotFound(evaluation_point));
-                                    // Note that we have used the
-                                    // <code>Assert</code> macro in other
-                                    // example programs as well. It
-                                    // differed from the
-                                    // <code>AssertThrow</code> macro used
-                                    // here in that it simply aborts
-                                    // the program, rather than
-                                    // throwing an exception, and
-                                    // that it did so only in debug
-                                    // mode. It was the right macro
-                                    // to use to check about the size
-                                    // of vectors passed as arguments
-                                    // to functions, and the like.
+
+                                    // @sect4{%Point evaluation}
+
+                                    // The next thing is to implement
+                                    // actual evaluation classes. As
+                                    // noted in the introduction, we'd
+                                    // like to extract a point value
+                                    // from the solution, so the first
+                                    // class does this in its
+                                    // <code>operator()</code>. The actual point
+                                    // is given to this class through
+                                    // the constructor, as well as a
+                                    // table object into which it will
+                                    // put its findings.
                                     //
-                                    // However, here the situation is
-                                    // different: whether we find the
-                                    // evaluation point or not may
-                                    // change from refinement to
-                                    // refinement (for example, if
-                                    // the four cells around point
-                                    // are coarsened away, then the
-                                    // point may vanish after
-                                    // refinement and
-                                    // coarsening). This is something
-                                    // that cannot be predicted from
-                                    // a few number of runs of the
-                                    // program in debug mode, but
-                                    // should be checked always, also
-                                    // in production runs. Thus the
-                                    // use of the <code>AssertThrow</code>
-                                    // macro here.
-    
-                                    // Now, if we are sure that we
-                                    // have found the evaluation
-                                    // point, we can add the results
-                                    // into the table of results:
-    results_table.add_value ("DoFs", dof_handler.n_dofs());
-    results_table.add_value ("u(x_0)", point_value);
-  }
+                                    // Finding out the value of a
+                                    // finite element field at an
+                                    // arbitrary point is rather
+                                    // difficult, if we cannot rely on
+                                    // knowing the actual finite
+                                    // element used, since then we
+                                    // cannot, for example, interpolate
+                                    // between nodes. For simplicity,
+                                    // we therefore assume here that
+                                    // the point at which we want to
+                                    // evaluate the field is actually a
+                                    // node. If, in the process of
+                                    // evaluating the solution, we find
+                                    // that we did not encounter this
+                                    // point upon looping over all
+                                    // vertices, we then have to throw
+                                    // an exception in order to signal
+                                    // to the calling functions that
+                                    // something has gone wrong, rather
+                                    // than silently ignore this error.
+                                    //
+                                    // In the step-9 example program,
+                                    // we have already seen how such an
+                                    // exception class can be declared,
+                                    // using the <code>DeclExceptionN</code>
+                                    // macros. We use this mechanism
+                                    // here again.
+                                    //
+                                    // From this, the actual
+                                    // declaration of this class should
+                                    // be evident. Note that of course
+                                    // even if we do not list a
+                                    // destructor explicitely, an
+                                    // implicit destructor is generated
+                                    // from the compiler, and it is
+                                    // virtual just as the one of the
+                                    // base class.
+    template <int dim>
+    class PointValueEvaluation : public EvaluationBase<dim>
+    {
+      public:
+       PointValueEvaluation (const Point<dim>   &evaluation_point,
+                             TableHandler       &results_table);
+
+       virtual void operator () (const DoFHandler<dim> &dof_handler,
+                                 const Vector<double>  &solution) const;
+
+       DeclException1 (ExcEvaluationPointNotFound,
+                       Point<dim>,
+                       << "The evaluation point " << arg1
+                       << " was not found among the vertices of the present grid.");
+      private:
+       const Point<dim>  evaluation_point;
+       TableHandler     &results_table;
+    };
 
 
+                                    // As for the definition, the
+                                    // constructor is trivial, just
+                                    // taking data and storing it in
+                                    // object-local ones:
+    template <int dim>
+    PointValueEvaluation<dim>::
+    PointValueEvaluation (const Point<dim>   &evaluation_point,
+                         TableHandler       &results_table)
+                   :
+                   evaluation_point (evaluation_point),
+                   results_table (results_table)
+    {}
+
+
+
+                                    // Now for the function that is
+                                    // mainly of interest in this
+                                    // class, the computation of the
+                                    // point value:
+    template <int dim>
+    void
+    PointValueEvaluation<dim>::
+    operator () (const DoFHandler<dim> &dof_handler,
+                const Vector<double>  &solution) const
+    {
+                                      // First allocate a variable that
+                                      // will hold the point
+                                      // value. Initialize it with a
+                                      // value that is clearly bogus,
+                                      // so that if we fail to set it
+                                      // to a reasonable value, we will
+                                      // note at once. This may not be
+                                      // necessary in a function as
+                                      // small as this one, since we
+                                      // can easily see all possible
+                                      // paths of execution here, but
+                                      // it proved to be helpful for
+                                      // more complex cases, and so we
+                                      // employ this strategy here as
+                                      // well.
+      double point_value = 1e20;
+
+                                      // Then loop over all cells and
+                                      // all their vertices, and check
+                                      // whether a vertex matches the
+                                      // evaluation point. If this is
+                                      // the case, then extract the
+                                      // point value, set a flag that
+                                      // we have found the point of
+                                      // interest, and exit the loop.
+      typename DoFHandler<dim>::active_cell_iterator
+       cell = dof_handler.begin_active(),
+       endc = dof_handler.end();
+      bool evaluation_point_found = false;
+      for (; (cell!=endc) && !evaluation_point_found; ++cell)
+       for (unsigned int vertex=0;
+            vertex<GeometryInfo<dim>::vertices_per_cell;
+            ++vertex)
+         if (cell->vertex(vertex) == evaluation_point)
+           {
+                                              // In order to extract
+                                              // the point value from
+                                              // the global solution
+                                              // vector, pick that
+                                              // component that belongs
+                                              // to the vertex of
+                                              // interest, and, in case
+                                              // the solution is
+                                              // vector-valued, take
+                                              // the first component of
+                                              // it:
+             point_value = solution(cell->vertex_dof_index(vertex,0));
+                                              // Note that by this we
+                                              // have made an
+                                              // assumption that is not
+                                              // valid always and
+                                              // should be documented
+                                              // in the class
+                                              // declaration if this
+                                              // were code for a real
+                                              // application rather
+                                              // than a tutorial
+                                              // program: we assume
+                                              // that the finite
+                                              // element used for the
+                                              // solution we try to
+                                              // evaluate actually has
+                                              // degrees of freedom
+                                              // associated with
+                                              // vertices. This, for
+                                              // example, does not hold
+                                              // for discontinuous
+                                              // elements, were the
+                                              // support points for the
+                                              // shape functions
+                                              // happen to be located
+                                              // at the vertices, but
+                                              // are not associated
+                                              // with the vertices but
+                                              // rather with the cell
+                                              // interior, since
+                                              // association with
+                                              // vertices would imply
+                                              // continuity there. It
+                                              // would also not hold
+                                              // for edge oriented
+                                              // elements, and the
+                                              // like.
+                                              //
+                                              // Ideally, we would
+                                              // check this at the
+                                              // beginning of the
+                                              // function, for example
+                                              // by a statement like
+                                              // <code>Assert
+                                              // (dof_handler.get_fe().dofs_per_vertex
+                                              // @> 0,
+                                              // ExcNotImplemented())</code>,
+                                              // which should make it
+                                              // quite clear what is
+                                              // going wrong when the
+                                              // exception is
+                                              // triggered. In this
+                                              // case, we omit it
+                                              // (which is indeed bad
+                                              // style), but knowing
+                                              // that that does not
+                                              // hurt here, since the
+                                              // statement
+                                              // <code>cell-@>vertex_dof_index(vertex,0)</code>
+                                              // would fail if we asked
+                                              // it to give us the DoF
+                                              // index of a vertex if
+                                              // there were none.
+                                              //
+                                              // We stress again that
+                                              // this restriction on
+                                              // the allowed finite
+                                              // elements should be
+                                              // stated in the class
+                                              // documentation.
+
+                                              // Since we found the
+                                              // right point, we now
+                                              // set the respective
+                                              // flag and exit the
+                                              // innermost loop. The
+                                              // outer loop will the
+                                              // also be terminated due
+                                              // to the set flag.
+             evaluation_point_found = true;
+             break;
+           };
+
+                                      // Finally, we'd like to make
+                                      // sure that we have indeed found
+                                      // the evaluation point, since if
+                                      // that were not so we could not
+                                      // give a reasonable value of the
+                                      // solution there and the rest of
+                                      // the computations were useless
+                                      // anyway. So make sure through
+                                      // the <code>AssertThrow</code> macro
+                                      // already used in the step-9
+                                      // program that we have indeed
+                                      // found this point. If this is
+                                      // not so, the macro throws an
+                                      // exception of the type that is
+                                      // given to it as second
+                                      // argument, but compared to a
+                                      // straightforward <code>throw</code>
+                                      // statement, it fills the
+                                      // exception object with a set of
+                                      // additional information, for
+                                      // example the source file and
+                                      // line number where the
+                                      // exception was generated, and
+                                      // the condition that failed. If
+                                      // you have a <code>catch</code> clause in
+                                      // your main function (as this
+                                      // program has), you will catch
+                                      // all exceptions that are not
+                                      // caught somewhere in between
+                                      // and thus already handled, and
+                                      // this additional information
+                                      // will help you find out what
+                                      // happened and where it went
+                                      // wrong.
+      AssertThrow (evaluation_point_found,
+                  ExcEvaluationPointNotFound(evaluation_point));
+                                      // Note that we have used the
+                                      // <code>Assert</code> macro in other
+                                      // example programs as well. It
+                                      // differed from the
+                                      // <code>AssertThrow</code> macro used
+                                      // here in that it simply aborts
+                                      // the program, rather than
+                                      // throwing an exception, and
+                                      // that it did so only in debug
+                                      // mode. It was the right macro
+                                      // to use to check about the size
+                                      // of vectors passed as arguments
+                                      // to functions, and the like.
+                                      //
+                                      // However, here the situation is
+                                      // different: whether we find the
+                                      // evaluation point or not may
+                                      // change from refinement to
+                                      // refinement (for example, if
+                                      // the four cells around point
+                                      // are coarsened away, then the
+                                      // point may vanish after
+                                      // refinement and
+                                      // coarsening). This is something
+                                      // that cannot be predicted from
+                                      // a few number of runs of the
+                                      // program in debug mode, but
+                                      // should be checked always, also
+                                      // in production runs. Thus the
+                                      // use of the <code>AssertThrow</code>
+                                      // macro here.
+
+                                      // Now, if we are sure that we
+                                      // have found the evaluation
+                                      // point, we can add the results
+                                      // into the table of results:
+      results_table.add_value ("DoFs", dof_handler.n_dofs());
+      results_table.add_value ("u(x_0)", point_value);
+    }
 
 
-                                  // @sect4{Generating output}
-
-                                  // A different, maybe slightly odd
-                                  // kind of <code>evaluation</code> of a
-                                  // solution is to output it to a
-                                  // file in a graphical
-                                  // format. Since in the evaluation
-                                  // functions we are given a
-                                  // <code>DoFHandler</code> object and the
-                                  // solution vector, we have all we
-                                  // need to do this, so we can do it
-                                  // in an evaluation class. The
-                                  // reason for actually doing so
-                                  // instead of putting it into the
-                                  // class that computed the solution
-                                  // is that this way we have more
-                                  // flexibility: if we choose to
-                                  // only output certain aspects of
-                                  // it, or not output it at all. In
-                                  // any case, we do not need to
-                                  // modify the solver class, we just
-                                  // have to modify one of the
-                                  // modules out of which we build
-                                  // this program. This form of
-                                  // encapsulation, as above, helps
-                                  // us to keep each part of the
-                                  // program rather simple as the
-                                  // interfaces are kept simple, and
-                                  // no access to hidden data is
-                                  // possible.
-                                  //
-                                  // Since this class which generates
-                                  // the output is derived from the
-                                  // common <code>EvaluationBase</code> base
-                                  // class, its main interface is the
-                                  // <code>operator()</code>
-                                  // function. Furthermore, it has a
-                                  // constructor taking a string that
-                                  // will be used as the base part of
-                                  // the file name to which output
-                                  // will be sent (we will augment it
-                                  // by a number indicating the
-                                  // number of the refinement cycle
-                                  // -- the base class has this
-                                  // information at hand --, and a
-                                  // suffix), and the constructor
-                                  // also takes a value that
-                                  // indicates which format is
-                                  // requested, i.e. for which
-                                  // graphics program we shall
-                                  // generate output (from this we
-                                  // will then also generate the
-                                  // suffix of the filename to which
-                                  // we write).
-                                  //
-                                  // Regarding the output format, the
-                                  // <code>DataOutInterface</code> class
-                                  // (which is a base class of
-                                  // <code>DataOut</code> through which we
-                                  // will access its fields) provides
-                                  // an enumeration field
-                                  // <code>OutputFormat</code>, which lists
-                                  // names for all supported output
-                                  // formats. At the time of writing
-                                  // of this program, the supported
-                                  // graphics formats are represented
-                                  // by the enum values <code>ucd</code>,
-                                  // <code>gnuplot</code>, <code>povray</code>,
-                                  // <code>eps</code>, <code>gmv</code>, <code>tecplot</code>,
-                                  // <code>tecplot_binary</code>, <code>dx</code>, and
-                                  // <code>vtk</code>, but this list will
-                                  // certainly grow over time. Now,
-                                  // within various functions of that
-                                  // base class, you can use values
-                                  // of this type to get information
-                                  // about these graphics formats
-                                  // (for example the default suffix
-                                  // used for files of each format),
-                                  // and you can call a generic
-                                  // <code>write</code> function, which then
-                                  // branches to the
-                                  // <code>write_gnuplot</code>,
-                                  // <code>write_ucd</code>, etc functions
-                                  // which we have used in previous
-                                  // examples already, based on the
-                                  // value of a second argument given
-                                  // to it denoting the required
-                                  // output format. This mechanism
-                                  // makes it simple to write an
-                                  // extensible program that can
-                                  // decide which output format to
-                                  // use at runtime, and it also
-                                  // makes it rather simple to write
-                                  // the program in a way such that
-                                  // it takes advantage of newly
-                                  // implemented output formats,
-                                  // without the need to change the
-                                  // application program.
-                                  //
-                                  // Of these two fields, the base
-                                  // name and the output format
-                                  // descriptor, the constructor
-                                  // takes values and stores them for
-                                  // later use by the actual
-                                  // evaluation function.
-  template <int dim>
-  class SolutionOutput : public EvaluationBase<dim>
-  {
-    public:
-      SolutionOutput (const std::string                         &output_name_base,
-                     const typename DataOut<dim>::OutputFormat  output_format);
-      
-      virtual void operator () (const DoFHandler<dim> &dof_handler,
-                               const Vector<double>  &solution) const;
-    private:
-      const std::string                         output_name_base;
-      const typename DataOut<dim>::OutputFormat output_format;
-  };
 
 
-  template <int dim>
-  SolutionOutput<dim>::
-  SolutionOutput (const std::string                         &output_name_base,
-                 const typename DataOut<dim>::OutputFormat  output_format)
-                 :
-                 output_name_base (output_name_base),
-                 output_format (output_format)
-  {}
-  
-
-                                  // After the description above, the
-                                  // function generating the actual
-                                  // output is now relatively
-                                  // straightforward. The only
-                                  // particularly interesting feature
-                                  // over previous example programs
-                                  // is the use of the
-                                  // <code>DataOut::default_suffix</code>
-                                  // function, returning the usual
-                                  // suffix for files of a given
-                                  // format (e.g. ".eps" for
-                                  // encapsulated postscript files,
-                                  // ".gnuplot" for Gnuplot files),
-                                  // and of the generic
-                                  // <code>DataOut::write</code> function with
-                                  // a second argument, which
-                                  // branches to the actual output
-                                  // functions for the different
-                                  // graphics formats, based on the
-                                  // value of the format descriptor
-                                  // passed as second argument.
-                                  //
-                                  // Also note that we have to prefix
-                                  // <code>this-@></code> to access a member
-                                  // variable of the template
-                                  // dependent base class. The reason
-                                  // here, and further down in the
-                                  // program is the same as the one
-                                  // described in the step-7 example
-                                  // program (look for <code>two-stage
-                                  // name lookup</code> there).
-  template <int dim>
-  void
-  SolutionOutput<dim>::operator () (const DoFHandler<dim> &dof_handler,
-                                   const Vector<double>  &solution) const
-  {
-    DataOut<dim> data_out;
-    data_out.attach_dof_handler (dof_handler);
-    data_out.add_data_vector (solution, "solution");
-    data_out.build_patches ();
-  
-    std::ostringstream filename;
-    filename << output_name_base << "-"
-            << this->refinement_cycle
-            << data_out.default_suffix (output_format)
-            << std::ends;
-    std::ofstream out (filename.str().c_str());
-    
-    data_out.write (out, output_format);
-  }
+                                    // @sect4{Generating output}
+
+                                    // A different, maybe slightly odd
+                                    // kind of <code>evaluation</code> of a
+                                    // solution is to output it to a
+                                    // file in a graphical
+                                    // format. Since in the evaluation
+                                    // functions we are given a
+                                    // <code>DoFHandler</code> object and the
+                                    // solution vector, we have all we
+                                    // need to do this, so we can do it
+                                    // in an evaluation class. The
+                                    // reason for actually doing so
+                                    // instead of putting it into the
+                                    // class that computed the solution
+                                    // is that this way we have more
+                                    // flexibility: if we choose to
+                                    // only output certain aspects of
+                                    // it, or not output it at all. In
+                                    // any case, we do not need to
+                                    // modify the solver class, we just
+                                    // have to modify one of the
+                                    // modules out of which we build
+                                    // this program. This form of
+                                    // encapsulation, as above, helps
+                                    // us to keep each part of the
+                                    // program rather simple as the
+                                    // interfaces are kept simple, and
+                                    // no access to hidden data is
+                                    // possible.
+                                    //
+                                    // Since this class which generates
+                                    // the output is derived from the
+                                    // common <code>EvaluationBase</code> base
+                                    // class, its main interface is the
+                                    // <code>operator()</code>
+                                    // function. Furthermore, it has a
+                                    // constructor taking a string that
+                                    // will be used as the base part of
+                                    // the file name to which output
+                                    // will be sent (we will augment it
+                                    // by a number indicating the
+                                    // number of the refinement cycle
+                                    // -- the base class has this
+                                    // information at hand --, and a
+                                    // suffix), and the constructor
+                                    // also takes a value that
+                                    // indicates which format is
+                                    // requested, i.e. for which
+                                    // graphics program we shall
+                                    // generate output (from this we
+                                    // will then also generate the
+                                    // suffix of the filename to which
+                                    // we write).
+                                    //
+                                    // Regarding the output format, the
+                                    // <code>DataOutInterface</code> class
+                                    // (which is a base class of
+                                    // <code>DataOut</code> through which we
+                                    // will access its fields) provides
+                                    // an enumeration field
+                                    // <code>OutputFormat</code>, which lists
+                                    // names for all supported output
+                                    // formats. At the time of writing
+                                    // of this program, the supported
+                                    // graphics formats are represented
+                                    // by the enum values <code>ucd</code>,
+                                    // <code>gnuplot</code>, <code>povray</code>,
+                                    // <code>eps</code>, <code>gmv</code>, <code>tecplot</code>,
+                                    // <code>tecplot_binary</code>, <code>dx</code>, and
+                                    // <code>vtk</code>, but this list will
+                                    // certainly grow over time. Now,
+                                    // within various functions of that
+                                    // base class, you can use values
+                                    // of this type to get information
+                                    // about these graphics formats
+                                    // (for example the default suffix
+                                    // used for files of each format),
+                                    // and you can call a generic
+                                    // <code>write</code> function, which then
+                                    // branches to the
+                                    // <code>write_gnuplot</code>,
+                                    // <code>write_ucd</code>, etc functions
+                                    // which we have used in previous
+                                    // examples already, based on the
+                                    // value of a second argument given
+                                    // to it denoting the required
+                                    // output format. This mechanism
+                                    // makes it simple to write an
+                                    // extensible program that can
+                                    // decide which output format to
+                                    // use at runtime, and it also
+                                    // makes it rather simple to write
+                                    // the program in a way such that
+                                    // it takes advantage of newly
+                                    // implemented output formats,
+                                    // without the need to change the
+                                    // application program.
+                                    //
+                                    // Of these two fields, the base
+                                    // name and the output format
+                                    // descriptor, the constructor
+                                    // takes values and stores them for
+                                    // later use by the actual
+                                    // evaluation function.
+    template <int dim>
+    class SolutionOutput : public EvaluationBase<dim>
+    {
+      public:
+       SolutionOutput (const std::string                         &output_name_base,
+                       const typename DataOut<dim>::OutputFormat  output_format);
+
+       virtual void operator () (const DoFHandler<dim> &dof_handler,
+                                 const Vector<double>  &solution) const;
+      private:
+       const std::string                         output_name_base;
+       const typename DataOut<dim>::OutputFormat output_format;
+    };
 
 
+    template <int dim>
+    SolutionOutput<dim>::
+    SolutionOutput (const std::string                         &output_name_base,
+                   const typename DataOut<dim>::OutputFormat  output_format)
+                   :
+                   output_name_base (output_name_base),
+                   output_format (output_format)
+    {}
+
+
+                                    // After the description above, the
+                                    // function generating the actual
+                                    // output is now relatively
+                                    // straightforward. The only
+                                    // particularly interesting feature
+                                    // over previous example programs
+                                    // is the use of the
+                                    // <code>DataOut::default_suffix</code>
+                                    // function, returning the usual
+                                    // suffix for files of a given
+                                    // format (e.g. ".eps" for
+                                    // encapsulated postscript files,
+                                    // ".gnuplot" for Gnuplot files),
+                                    // and of the generic
+                                    // <code>DataOut::write</code> function with
+                                    // a second argument, which
+                                    // branches to the actual output
+                                    // functions for the different
+                                    // graphics formats, based on the
+                                    // value of the format descriptor
+                                    // passed as second argument.
+                                    //
+                                    // Also note that we have to prefix
+                                    // <code>this-@></code> to access a member
+                                    // variable of the template
+                                    // dependent base class. The reason
+                                    // here, and further down in the
+                                    // program is the same as the one
+                                    // described in the step-7 example
+                                    // program (look for <code>two-stage
+                                    // name lookup</code> there).
+    template <int dim>
+    void
+    SolutionOutput<dim>::operator () (const DoFHandler<dim> &dof_handler,
+                                     const Vector<double>  &solution) const
+    {
+      DataOut<dim> data_out;
+      data_out.attach_dof_handler (dof_handler);
+      data_out.add_data_vector (solution, "solution");
+      data_out.build_patches ();
+
+      std::ostringstream filename;
+      filename << output_name_base << "-"
+              << this->refinement_cycle
+              << data_out.default_suffix (output_format)
+              << std::ends;
+      std::ofstream out (filename.str().c_str());
+
+      data_out.write (out, output_format);
+    }
 
-                                  // @sect4{Other evaluations}
-  
-                                  // In practical applications, one
-                                  // would add here a list of other
-                                  // possible evaluation classes,
-                                  // representing quantities that one
-                                  // may be interested in. For this
-                                  // example, that much shall be
-                                  // sufficient, so we close the
-                                  // namespace.
-}
 
-  
-                                // @sect3{The Laplace solver classes}
-
-                                // After defining what we want to
-                                // know of the solution, we should
-                                // now care how to get at it. We will
-                                // pack everything we need into a
-                                // namespace of its own, for much the
-                                // same reasons as for the
-                                // evaluations above.
-                                //
-                                // Since we have discussed Laplace
-                                // solvers already in considerable
-                                // detail in previous examples, there
-                                // is not much new stuff
-                                // following. Rather, we have to a
-                                // great extent cannibalized previous
-                                // examples and put them, in slightly
-                                // different form, into this example
-                                // program. We will therefore mostly
-                                // be concerned with discussing the
-                                // differences to previous examples.
-                                //
-                                // Basically, as already said in the
-                                // introduction, the lack of new
-                                // stuff in this example is
-                                // deliberate, as it is more to
-                                // demonstrate software design
-                                // practices, rather than
-                                // mathematics. The emphasis in
-                                // explanations below will therefore
-                                // be more on the actual
-                                // implementation.
-namespace LaplaceSolver
-{
-                                  // @sect4{An abstract base class}
-
-                                  // In defining a Laplace solver, we
-                                  // start out by declaring an
-                                  // abstract base class, that has no
-                                  // functionality itself except for
-                                  // taking and storing a pointer to
-                                  // the triangulation to be used
-                                  // later.
-                                  //
-                                  // This base class is very general,
-                                  // and could as well be used for
-                                  // any other stationary problem. It
-                                  // provides declarations of
-                                  // functions that shall, in derived
-                                  // classes, solve a problem,
-                                  // postprocess the solution with a
-                                  // list of evaluation objects, and
-                                  // refine the grid,
-                                  // respectively. None of these
-                                  // functions actually does
-                                  // something itself in the base
-                                  // class.
-                                  //
-                                  // Due to the lack of actual
-                                  // functionality, the programming
-                                  // style of declaring very abstract
-                                  // base classes reminds of the
-                                  // style used in Smalltalk or Java
-                                  // programs, where all classes are
-                                  // derived from entirely abstract
-                                  // classes <code>Object</code>, even number
-                                  // representations. The author
-                                  // admits that he does not
-                                  // particularly like the use of
-                                  // such a style in C++, as it puts
-                                  // style over reason. Furthermore,
-                                  // it promotes the use of virtual
-                                  // functions for everything (for
-                                  // example, in Java, all functions
-                                  // are virtual per se), which,
-                                  // however, has proven to be rather
-                                  // inefficient in many applications
-                                  // where functions are often only
-                                  // accessing data, not doing
-                                  // computations, and therefore
-                                  // quickly return; the overhead of
-                                  // virtual functions can then be
-                                  // significant. The opinion of the
-                                  // author is to have abstract base
-                                  // classes wherever at least some
-                                  // part of the code of actual
-                                  // implementations can be shared
-                                  // and thus separated into the base
-                                  // class.
-                                  //
-                                  // Besides all these theoretical
-                                  // questions, we here have a good
-                                  // reason, which will become
-                                  // clearer to the reader
-                                  // below. Basically, we want to be
-                                  // able to have a family of
-                                  // different Laplace solvers that
-                                  // differ so much that no larger
-                                  // common subset of functionality
-                                  // could be found. We therefore
-                                  // just declare such an abstract
-                                  // base class, taking a pointer to
-                                  // a triangulation in the
-                                  // constructor and storing it
-                                  // henceforth. Since this
-                                  // triangulation will be used
-                                  // throughout all computations, we
-                                  // have to make sure that the
-                                  // triangulation exists until the
-                                  // destructor exits. We do this by
-                                  // keeping a <code>SmartPointer</code> to
-                                  // this triangulation, which uses a
-                                  // counter in the triangulation
-                                  // class to denote the fact that
-                                  // there is still an object out
-                                  // there using this triangulation,
-                                  // thus leading to an abort in case
-                                  // the triangulation is attempted
-                                  // to be destructed while this
-                                  // object still uses it.
-                                  //
-                                  // Note that while the pointer
-                                  // itself is declared constant
-                                  // (i.e. throughout the lifetime of
-                                  // this object, the pointer points
-                                  // to the same object), it is not
-                                  // declared as a pointer to a
-                                  // constant triangulation. In fact,
-                                  // by this we allow that derived
-                                  // classes refine or coarsen the
-                                  // triangulation within the
-                                  // <code>refine_grid</code> function.
-                                  //
-                                  // Finally, we have a function
-                                  // <code>n_dofs</code> is only a tool for
-                                  // the driver functions to decide
-                                  // whether we want to go on with
-                                  // mesh refinement or not. It
-                                  // returns the number of degrees of
-                                  // freedom the present simulation
-                                  // has.
-  template <int dim>
-  class Base
-  {
-    public:
-      Base (Triangulation<dim> &coarse_grid);
-      virtual ~Base ();
-
-      virtual void solve_problem () = 0;
-      virtual void postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const = 0;
-      virtual void refine_grid () = 0;
-      virtual unsigned int n_dofs () const = 0;
-      
-    protected:
-      const SmartPointer<Triangulation<dim> > triangulation;
-  };
 
+                                    // @sect4{Other evaluations}
 
-                                  // The implementation of the only
-                                  // two non-abstract functions is
-                                  // then rather boring:
-  template <int dim>
-  Base<dim>::Base (Triangulation<dim> &coarse_grid)
-                 :
-                 triangulation (&coarse_grid)
-  {}
+                                    // In practical applications, one
+                                    // would add here a list of other
+                                    // possible evaluation classes,
+                                    // representing quantities that one
+                                    // may be interested in. For this
+                                    // example, that much shall be
+                                    // sufficient, so we close the
+                                    // namespace.
+  }
 
 
-  template <int dim>
-  Base<dim>::~Base () 
-  {}
-  
-
-                                  // @sect4{A general solver class}
-
-                                  // Following now the main class
-                                  // that implements assembling the
-                                  // matrix of the linear system,
-                                  // solving it, and calling the
-                                  // postprocessor objects on the
-                                  // solution. It implements the
-                                  // <code>solve_problem</code> and
-                                  // <code>postprocess</code> functions
-                                  // declared in the base class. It
-                                  // does not, however, implement the
-                                  // <code>refine_grid</code> method, as mesh
-                                  // refinement will be implemented
-                                  // in a number of derived classes.
-                                  //
-                                  // It also declares a new abstract
-                                  // virtual function,
-                                  // <code>assemble_rhs</code>, that needs to
-                                  // be overloaded in subclasses. The
-                                  // reason is that we will implement
-                                  // two different classes that will
-                                  // implement different methods to
-                                  // assemble the right hand side
-                                  // vector. This function might also
-                                  // be interesting in cases where
-                                  // the right hand side depends not
-                                  // simply on a continuous function,
-                                  // but on something else as well,
-                                  // for example the solution of
-                                  // another discretized problem,
-                                  // etc. The latter happens
-                                  // frequently in non-linear
-                                  // problems.
-                                  //
-                                  // As we mentioned previously, the
-                                  // actual content of this class is
-                                  // not new, but a mixture of
-                                  // various techniques already used
-                                  // in previous examples. We will
-                                  // therefore not discuss them in
-                                  // detail, but refer the reader to
-                                  // these programs.
-                                  //
-                                  // Basically, in a few words, the
-                                  // constructor of this class takes
-                                  // pointers to a triangulation, a
-                                  // finite element, and a function
-                                  // object representing the boundary
-                                  // values. These are either passed
-                                  // down to the base class's
-                                  // constructor, or are stored and
-                                  // used to generate a
-                                  // <code>DoFHandler</code> object
-                                  // later. Since finite elements and
-                                  // quadrature formula should match,
-                                  // it is also passed a quadrature
-                                  // object.
-                                  //
-                                  // The <code>solve_problem</code> sets up
-                                  // the data structures for the
-                                  // actual solution, calls the
-                                  // functions to assemble the linear
-                                  // system, and solves it.
+                                  // @sect3{The Laplace solver classes}
+
+                                  // After defining what we want to
+                                  // know of the solution, we should
+                                  // now care how to get at it. We will
+                                  // pack everything we need into a
+                                  // namespace of its own, for much the
+                                  // same reasons as for the
+                                  // evaluations above.
                                   //
-                                  // The <code>postprocess</code> function
-                                  // finally takes an evaluation
-                                  // object and applies it to the
-                                  // computed solution.
+                                  // Since we have discussed Laplace
+                                  // solvers already in considerable
+                                  // detail in previous examples, there
+                                  // is not much new stuff
+                                  // following. Rather, we have to a
+                                  // great extent cannibalized previous
+                                  // examples and put them, in slightly
+                                  // different form, into this example
+                                  // program. We will therefore mostly
+                                  // be concerned with discussing the
+                                  // differences to previous examples.
                                   //
-                                  // The <code>n_dofs</code> function finally
-                                  // implements the pure virtual
-                                  // function of the base class.
-  template <int dim>
-  class Solver : public virtual Base<dim>
+                                  // Basically, as already said in the
+                                  // introduction, the lack of new
+                                  // stuff in this example is
+                                  // deliberate, as it is more to
+                                  // demonstrate software design
+                                  // practices, rather than
+                                  // mathematics. The emphasis in
+                                  // explanations below will therefore
+                                  // be more on the actual
+                                  // implementation.
+  namespace LaplaceSolver
   {
-    public:
-      Solver (Triangulation<dim>       &triangulation,
-             const FiniteElement<dim> &fe,
-             const Quadrature<dim>    &quadrature,
-             const Function<dim>      &boundary_values);
-      virtual
-      ~Solver ();
-
-      virtual
-      void
-      solve_problem ();
-
-      virtual
-      void
-      postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const;
-
-      virtual
-      unsigned int
-      n_dofs () const;
-      
-                                      // In the protected section of
-                                      // this class, we first have a
-                                      // number of member variables,
-                                      // of which the use should be
-                                      // clear from the previous
-                                      // examples:
-    protected:
-      const SmartPointer<const FiniteElement<dim> >  fe;
-      const SmartPointer<const Quadrature<dim> >     quadrature;
-      DoFHandler<dim>                                dof_handler;
-      Vector<double>                                 solution;
-      const SmartPointer<const Function<dim> >       boundary_values;
-
-                                      // Then we declare an abstract
-                                      // function that will be used
-                                      // to assemble the right hand
-                                      // side. As explained above,
-                                      // there are various cases for
-                                      // which this action differs
-                                      // strongly in what is
-                                      // necessary, so we defer this
-                                      // to derived classes:
-      virtual void assemble_rhs (Vector<double> &rhs) const = 0;
-    
-                                      // Next, in the private
-                                      // section, we have a small
-                                      // class which represents an
-                                      // entire linear system, i.e. a
-                                      // matrix, a right hand side,
-                                      // and a solution vector, as
-                                      // well as the constraints that
-                                      // are applied to it, such as
-                                      // those due to hanging
-                                      // nodes. Its constructor
-                                      // initializes the various
-                                      // subobjects, and there is a
-                                      // function that implements a
-                                      // conjugate gradient method as
-                                      // solver.
-    private:
-      struct LinearSystem
-      {
-         LinearSystem (const DoFHandler<dim> &dof_handler);
-
-         void solve (Vector<double> &solution) const;
-       
-         ConstraintMatrix     hanging_node_constraints;
-         SparsityPattern      sparsity_pattern;
-         SparseMatrix<double> matrix;
-         Vector<double>       rhs;
-      };
+                                    // @sect4{An abstract base class}
+
+                                    // In defining a Laplace solver, we
+                                    // start out by declaring an
+                                    // abstract base class, that has no
+                                    // functionality itself except for
+                                    // taking and storing a pointer to
+                                    // the triangulation to be used
+                                    // later.
+                                    //
+                                    // This base class is very general,
+                                    // and could as well be used for
+                                    // any other stationary problem. It
+                                    // provides declarations of
+                                    // functions that shall, in derived
+                                    // classes, solve a problem,
+                                    // postprocess the solution with a
+                                    // list of evaluation objects, and
+                                    // refine the grid,
+                                    // respectively. None of these
+                                    // functions actually does
+                                    // something itself in the base
+                                    // class.
+                                    //
+                                    // Due to the lack of actual
+                                    // functionality, the programming
+                                    // style of declaring very abstract
+                                    // base classes reminds of the
+                                    // style used in Smalltalk or Java
+                                    // programs, where all classes are
+                                    // derived from entirely abstract
+                                    // classes <code>Object</code>, even number
+                                    // representations. The author
+                                    // admits that he does not
+                                    // particularly like the use of
+                                    // such a style in C++, as it puts
+                                    // style over reason. Furthermore,
+                                    // it promotes the use of virtual
+                                    // functions for everything (for
+                                    // example, in Java, all functions
+                                    // are virtual per se), which,
+                                    // however, has proven to be rather
+                                    // inefficient in many applications
+                                    // where functions are often only
+                                    // accessing data, not doing
+                                    // computations, and therefore
+                                    // quickly return; the overhead of
+                                    // virtual functions can then be
+                                    // significant. The opinion of the
+                                    // author is to have abstract base
+                                    // classes wherever at least some
+                                    // part of the code of actual
+                                    // implementations can be shared
+                                    // and thus separated into the base
+                                    // class.
+                                    //
+                                    // Besides all these theoretical
+                                    // questions, we here have a good
+                                    // reason, which will become
+                                    // clearer to the reader
+                                    // below. Basically, we want to be
+                                    // able to have a family of
+                                    // different Laplace solvers that
+                                    // differ so much that no larger
+                                    // common subset of functionality
+                                    // could be found. We therefore
+                                    // just declare such an abstract
+                                    // base class, taking a pointer to
+                                    // a triangulation in the
+                                    // constructor and storing it
+                                    // henceforth. Since this
+                                    // triangulation will be used
+                                    // throughout all computations, we
+                                    // have to make sure that the
+                                    // triangulation exists until the
+                                    // destructor exits. We do this by
+                                    // keeping a <code>SmartPointer</code> to
+                                    // this triangulation, which uses a
+                                    // counter in the triangulation
+                                    // class to denote the fact that
+                                    // there is still an object out
+                                    // there using this triangulation,
+                                    // thus leading to an abort in case
+                                    // the triangulation is attempted
+                                    // to be destructed while this
+                                    // object still uses it.
+                                    //
+                                    // Note that while the pointer
+                                    // itself is declared constant
+                                    // (i.e. throughout the lifetime of
+                                    // this object, the pointer points
+                                    // to the same object), it is not
+                                    // declared as a pointer to a
+                                    // constant triangulation. In fact,
+                                    // by this we allow that derived
+                                    // classes refine or coarsen the
+                                    // triangulation within the
+                                    // <code>refine_grid</code> function.
+                                    //
+                                    // Finally, we have a function
+                                    // <code>n_dofs</code> is only a tool for
+                                    // the driver functions to decide
+                                    // whether we want to go on with
+                                    // mesh refinement or not. It
+                                    // returns the number of degrees of
+                                    // freedom the present simulation
+                                    // has.
+    template <int dim>
+    class Base
+    {
+      public:
+       Base (Triangulation<dim> &coarse_grid);
+       virtual ~Base ();
 
-                                      // Finally, there is a pair of
-                                      // functions which will be used
-                                      // to assemble the actual
-                                      // system matrix. It calls the
-                                      // virtual function assembling
-                                      // the right hand side, and
-                                      // installs a number threads
-                                      // each running the second
-                                      // function which assembles
-                                      // part of the system
-                                      // matrix. The mechanism for
-                                      // doing so is the same as in
-                                      // the step-9 example program.
-      void
-      assemble_linear_system (LinearSystem &linear_system);
-
-      void
-      assemble_matrix (LinearSystem                                         &linear_system,
-                      const typename DoFHandler<dim>::active_cell_iterator &begin_cell,
-                      const typename DoFHandler<dim>::active_cell_iterator &end_cell,
-                      Threads::ThreadMutex                                 &mutex) const;
-  };
+       virtual void solve_problem () = 0;
+       virtual void postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const = 0;
+       virtual void refine_grid () = 0;
+       virtual unsigned int n_dofs () const = 0;
 
+      protected:
+       const SmartPointer<Triangulation<dim> > triangulation;
+    };
 
 
-                                  // Now here comes the constructor
-                                  // of the class. It does not do
-                                  // much except store pointers to
-                                  // the objects given, and generate
-                                  // <code>DoFHandler</code> object
-                                  // initialized with the given
-                                  // pointer to a triangulation. This
-                                  // causes the DoF handler to store
-                                  // that pointer, but does not
-                                  // already generate a finite
-                                  // element numbering (we only ask
-                                  // for that in the
-                                  // <code>solve_problem</code> function).
-  template <int dim>
-  Solver<dim>::Solver (Triangulation<dim>       &triangulation,
-                      const FiniteElement<dim> &fe,
-                      const Quadrature<dim>    &quadrature,
-                      const Function<dim>      &boundary_values)
-                 :
-                 Base<dim> (triangulation),
-                 fe (&fe),
-                  quadrature (&quadrature),
-                 dof_handler (triangulation),
-                 boundary_values (&boundary_values)
-  {}
-
-
-                                  // The destructor is simple, it
-                                  // only clears the information
-                                  // stored in the DoF handler object
-                                  // to release the memory.
-  template <int dim>
-  Solver<dim>::~Solver () 
-  {
-    dof_handler.clear ();
-  }
+                                    // The implementation of the only
+                                    // two non-abstract functions is
+                                    // then rather boring:
+    template <int dim>
+    Base<dim>::Base (Triangulation<dim> &coarse_grid)
+                   :
+                   triangulation (&coarse_grid)
+    {}
+
+
+    template <int dim>
+    Base<dim>::~Base ()
+    {}
+
+
+                                    // @sect4{A general solver class}
+
+                                    // Following now the main class
+                                    // that implements assembling the
+                                    // matrix of the linear system,
+                                    // solving it, and calling the
+                                    // postprocessor objects on the
+                                    // solution. It implements the
+                                    // <code>solve_problem</code> and
+                                    // <code>postprocess</code> functions
+                                    // declared in the base class. It
+                                    // does not, however, implement the
+                                    // <code>refine_grid</code> method, as mesh
+                                    // refinement will be implemented
+                                    // in a number of derived classes.
+                                    //
+                                    // It also declares a new abstract
+                                    // virtual function,
+                                    // <code>assemble_rhs</code>, that needs to
+                                    // be overloaded in subclasses. The
+                                    // reason is that we will implement
+                                    // two different classes that will
+                                    // implement different methods to
+                                    // assemble the right hand side
+                                    // vector. This function might also
+                                    // be interesting in cases where
+                                    // the right hand side depends not
+                                    // simply on a continuous function,
+                                    // but on something else as well,
+                                    // for example the solution of
+                                    // another discretized problem,
+                                    // etc. The latter happens
+                                    // frequently in non-linear
+                                    // problems.
+                                    //
+                                    // As we mentioned previously, the
+                                    // actual content of this class is
+                                    // not new, but a mixture of
+                                    // various techniques already used
+                                    // in previous examples. We will
+                                    // therefore not discuss them in
+                                    // detail, but refer the reader to
+                                    // these programs.
+                                    //
+                                    // Basically, in a few words, the
+                                    // constructor of this class takes
+                                    // pointers to a triangulation, a
+                                    // finite element, and a function
+                                    // object representing the boundary
+                                    // values. These are either passed
+                                    // down to the base class's
+                                    // constructor, or are stored and
+                                    // used to generate a
+                                    // <code>DoFHandler</code> object
+                                    // later. Since finite elements and
+                                    // quadrature formula should match,
+                                    // it is also passed a quadrature
+                                    // object.
+                                    //
+                                    // The <code>solve_problem</code> sets up
+                                    // the data structures for the
+                                    // actual solution, calls the
+                                    // functions to assemble the linear
+                                    // system, and solves it.
+                                    //
+                                    // The <code>postprocess</code> function
+                                    // finally takes an evaluation
+                                    // object and applies it to the
+                                    // computed solution.
+                                    //
+                                    // The <code>n_dofs</code> function finally
+                                    // implements the pure virtual
+                                    // function of the base class.
+    template <int dim>
+    class Solver : public virtual Base<dim>
+    {
+      public:
+       Solver (Triangulation<dim>       &triangulation,
+               const FiniteElement<dim> &fe,
+               const Quadrature<dim>    &quadrature,
+               const Function<dim>      &boundary_values);
+       virtual
+       ~Solver ();
+
+       virtual
+       void
+       solve_problem ();
+
+       virtual
+       void
+       postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const;
+
+       virtual
+       unsigned int
+       n_dofs () const;
+
+                                        // In the protected section of
+                                        // this class, we first have a
+                                        // number of member variables,
+                                        // of which the use should be
+                                        // clear from the previous
+                                        // examples:
+      protected:
+       const SmartPointer<const FiniteElement<dim> >  fe;
+       const SmartPointer<const Quadrature<dim> >     quadrature;
+       DoFHandler<dim>                                dof_handler;
+       Vector<double>                                 solution;
+       const SmartPointer<const Function<dim> >       boundary_values;
+
+                                        // Then we declare an abstract
+                                        // function that will be used
+                                        // to assemble the right hand
+                                        // side. As explained above,
+                                        // there are various cases for
+                                        // which this action differs
+                                        // strongly in what is
+                                        // necessary, so we defer this
+                                        // to derived classes:
+       virtual void assemble_rhs (Vector<double> &rhs) const = 0;
+
+                                        // Next, in the private
+                                        // section, we have a small
+                                        // class which represents an
+                                        // entire linear system, i.e. a
+                                        // matrix, a right hand side,
+                                        // and a solution vector, as
+                                        // well as the constraints that
+                                        // are applied to it, such as
+                                        // those due to hanging
+                                        // nodes. Its constructor
+                                        // initializes the various
+                                        // subobjects, and there is a
+                                        // function that implements a
+                                        // conjugate gradient method as
+                                        // solver.
+      private:
+       struct LinearSystem
+       {
+           LinearSystem (const DoFHandler<dim> &dof_handler);
 
+           void solve (Vector<double> &solution) const;
 
-                                  // The next function is the one
-                                  // which delegates the main work in
-                                  // solving the problem: it sets up
-                                  // the DoF handler object with the
-                                  // finite element given to the
-                                  // constructor of this object, the
-                                  // creates an object that denotes
-                                  // the linear system (i.e. the
-                                  // matrix, the right hand side
-                                  // vector, and the solution
-                                  // vector), calls the function to
-                                  // assemble it, and finally solves
-                                  // it:
-  template <int dim>
-  void
-  Solver<dim>::solve_problem ()
-  {
-    dof_handler.distribute_dofs (*fe);
-    solution.reinit (dof_handler.n_dofs());
+           ConstraintMatrix     hanging_node_constraints;
+           SparsityPattern      sparsity_pattern;
+           SparseMatrix<double> matrix;
+           Vector<double>       rhs;
+       };
 
-    LinearSystem linear_system (dof_handler);
-    assemble_linear_system (linear_system);
-    linear_system.solve (solution);
-  }
+                                        // Finally, there is a pair of
+                                        // functions which will be used
+                                        // to assemble the actual
+                                        // system matrix. It calls the
+                                        // virtual function assembling
+                                        // the right hand side, and
+                                        // installs a number threads
+                                        // each running the second
+                                        // function which assembles
+                                        // part of the system
+                                        // matrix. The mechanism for
+                                        // doing so is the same as in
+                                        // the step-9 example program.
+       void
+       assemble_linear_system (LinearSystem &linear_system);
+
+       void
+       assemble_matrix (LinearSystem                                         &linear_system,
+                        const typename DoFHandler<dim>::active_cell_iterator &begin_cell,
+                        const typename DoFHandler<dim>::active_cell_iterator &end_cell,
+                        Threads::ThreadMutex                                 &mutex) const;
+    };
 
 
-                                  // As stated above, the
-                                  // <code>postprocess</code> function takes
-                                  // an evaluation object, and
-                                  // applies it to the computed
-                                  // solution. This function may be
-                                  // called multiply, once for each
-                                  // evaluation of the solution which
-                                  // the user required.
-  template <int dim>
-  void
-  Solver<dim>::
-  postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const
-  {
-    postprocessor (dof_handler, solution);
-  }
 
+                                    // Now here comes the constructor
+                                    // of the class. It does not do
+                                    // much except store pointers to
+                                    // the objects given, and generate
+                                    // <code>DoFHandler</code> object
+                                    // initialized with the given
+                                    // pointer to a triangulation. This
+                                    // causes the DoF handler to store
+                                    // that pointer, but does not
+                                    // already generate a finite
+                                    // element numbering (we only ask
+                                    // for that in the
+                                    // <code>solve_problem</code> function).
+    template <int dim>
+    Solver<dim>::Solver (Triangulation<dim>       &triangulation,
+                        const FiniteElement<dim> &fe,
+                        const Quadrature<dim>    &quadrature,
+                        const Function<dim>      &boundary_values)
+                   :
+                   Base<dim> (triangulation),
+                   fe (&fe),
+                   quadrature (&quadrature),
+                   dof_handler (triangulation),
+                   boundary_values (&boundary_values)
+    {}
+
+
+                                    // The destructor is simple, it
+                                    // only clears the information
+                                    // stored in the DoF handler object
+                                    // to release the memory.
+    template <int dim>
+    Solver<dim>::~Solver ()
+    {
+      dof_handler.clear ();
+    }
 
-                                  // The <code>n_dofs</code> function should
-                                  // be self-explanatory:
-  template <int dim>
-  unsigned int
-  Solver<dim>::n_dofs () const
-  {
-    return dof_handler.n_dofs();
-  }
-  
-
-                                  // The following function assembles matrix
-                                  // and right hand side of the linear system
-                                  // to be solved in each step. It goes along
-                                  // the same lines as used in previous
-                                  // examples, so we explain it only
-                                  // briefly. Note that we do a number of
-                                  // things in parallel, a process described
-                                  // in more detail in the @ref threads
-                                  // module.
-  template <int dim>
-  void
-  Solver<dim>::assemble_linear_system (LinearSystem &linear_system)
-  {
-                                    // First define a convenience
-                                    // abbreviation for these lengthy
-                                    // iterator names...
-    typedef
-      typename DoFHandler<dim>::active_cell_iterator
-      active_cell_iterator;
-
-                                    // ... and use it to split up the
-                                    // set of cells into a number of
-                                    // pieces of equal size. The
-                                    // number of blocks is set to the
-                                    // default number of threads to
-                                    // be used, which by default is
-                                    // set to the number of
-                                    // processors found in your
-                                    // computer at startup of the
-                                    // program:
-    const unsigned int n_threads = multithread_info.n_default_threads;
-    std::vector<std::pair<active_cell_iterator,active_cell_iterator> >
-      thread_ranges 
-      = Threads::split_range<active_cell_iterator> (dof_handler.begin_active (),
-                                                   dof_handler.end (),
-                                                   n_threads);
-
-                                    // These ranges are then assigned
-                                    // to a number of threads which
-                                    // we create next. Each will
-                                    // assemble the local cell
-                                    // matrices on the assigned
-                                    // cells, and fill the matrix
-                                    // object with it. Since there is
-                                    // need for synchronization when
-                                    // filling the same matrix from
-                                    // different threads, we need a
-                                    // mutex here:
-    Threads::ThreadMutex mutex;
-    Threads::ThreadGroup<> threads;
-    for (unsigned int thread=0; thread<n_threads; ++thread)
-      threads += Threads::new_thread (&Solver<dim>::assemble_matrix,
-                                     *this,
-                                     linear_system,
-                                     thread_ranges[thread].first,
-                                     thread_ranges[thread].second,
-                                     mutex);
-
-                                    // While the new threads
-                                    // assemble the system matrix, we
-                                    // can already compute the right
-                                    // hand side vector in the main
-                                    // thread, and condense away the
-                                    // constraints due to hanging
-                                    // nodes:
-    assemble_rhs (linear_system.rhs);
-    linear_system.hanging_node_constraints.condense (linear_system.rhs);
-
-                                    // And while we're already
-                                    // computing things in parallel,
-                                    // interpolating boundary values
-                                    // is one more thing that can be
-                                    // done independently, so we do
-                                    // it here:
-    std::map<unsigned int,double> boundary_value_map;
-    VectorTools::interpolate_boundary_values (dof_handler,
-                                             0,
-                                             *boundary_values,
-                                             boundary_value_map);
-    
-    
-                                    // If this is done, wait for the
-                                    // matrix assembling threads, and
-                                    // condense the constraints in
-                                    // the matrix as well:
-    threads.join_all ();
-    linear_system.hanging_node_constraints.condense (linear_system.matrix);
-
-                                    // Now that we have the linear
-                                    // system, we can also treat
-                                    // boundary values, which need to
-                                    // be eliminated from both the
-                                    // matrix and the right hand
-                                    // side:
-    MatrixTools::apply_boundary_values (boundary_value_map,
-                                       linear_system.matrix,
-                                       solution,
-                                       linear_system.rhs);
 
-  }
+                                    // The next function is the one
+                                    // which delegates the main work in
+                                    // solving the problem: it sets up
+                                    // the DoF handler object with the
+                                    // finite element given to the
+                                    // constructor of this object, the
+                                    // creates an object that denotes
+                                    // the linear system (i.e. the
+                                    // matrix, the right hand side
+                                    // vector, and the solution
+                                    // vector), calls the function to
+                                    // assemble it, and finally solves
+                                    // it:
+    template <int dim>
+    void
+    Solver<dim>::solve_problem ()
+    {
+      dof_handler.distribute_dofs (*fe);
+      solution.reinit (dof_handler.n_dofs());
 
+      LinearSystem linear_system (dof_handler);
+      assemble_linear_system (linear_system);
+      linear_system.solve (solution);
+    }
 
-                                  // The second of this pair of
-                                  // functions takes a range of cell
-                                  // iterators, and assembles the
-                                  // system matrix on this part of
-                                  // the domain. Since it's actions
-                                  // have all been explained in
-                                  // previous programs, we do not
-                                  // comment on it any more, except
-                                  // for one pointe below.
-  template <int dim>
-  void
-  Solver<dim>::assemble_matrix (LinearSystem                                         &linear_system,
-                               const typename DoFHandler<dim>::active_cell_iterator &begin_cell,
-                               const typename DoFHandler<dim>::active_cell_iterator &end_cell,
-                               Threads::ThreadMutex                                 &mutex) const
-  {
-    FEValues<dim> fe_values (*fe, *quadrature, 
-                            update_gradients | update_JxW_values);
 
-    const unsigned int   dofs_per_cell = fe->dofs_per_cell;
-    const unsigned int   n_q_points    = quadrature->size();
+                                    // As stated above, the
+                                    // <code>postprocess</code> function takes
+                                    // an evaluation object, and
+                                    // applies it to the computed
+                                    // solution. This function may be
+                                    // called multiply, once for each
+                                    // evaluation of the solution which
+                                    // the user required.
+    template <int dim>
+    void
+    Solver<dim>::
+    postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const
+    {
+      postprocessor (dof_handler, solution);
+    }
+
 
-    FullMatrix<double>   cell_matrix (dofs_per_cell, dofs_per_cell);
+                                    // The <code>n_dofs</code> function should
+                                    // be self-explanatory:
+    template <int dim>
+    unsigned int
+    Solver<dim>::n_dofs () const
+    {
+      return dof_handler.n_dofs();
+    }
 
-    std::vector<unsigned int> local_dof_indices (dofs_per_cell);
 
-    for (typename DoFHandler<dim>::active_cell_iterator cell=begin_cell;
-        cell!=end_cell; ++cell)
-      {
-       cell_matrix = 0;
+                                    // The following function assembles matrix
+                                    // and right hand side of the linear system
+                                    // to be solved in each step. It goes along
+                                    // the same lines as used in previous
+                                    // examples, so we explain it only
+                                    // briefly. Note that we do a number of
+                                    // things in parallel, a process described
+                                    // in more detail in the @ref threads
+                                    // module.
+    template <int dim>
+    void
+    Solver<dim>::assemble_linear_system (LinearSystem &linear_system)
+    {
+                                      // First define a convenience
+                                      // abbreviation for these lengthy
+                                      // iterator names...
+      typedef
+       typename DoFHandler<dim>::active_cell_iterator
+       active_cell_iterator;
+
+                                      // ... and use it to split up the
+                                      // set of cells into a number of
+                                      // pieces of equal size. The
+                                      // number of blocks is set to the
+                                      // default number of threads to
+                                      // be used, which by default is
+                                      // set to the number of
+                                      // processors found in your
+                                      // computer at startup of the
+                                      // program:
+      const unsigned int n_threads = multithread_info.n_default_threads;
+      std::vector<std::pair<active_cell_iterator,active_cell_iterator> >
+       thread_ranges
+       = Threads::split_range<active_cell_iterator> (dof_handler.begin_active (),
+                                                     dof_handler.end (),
+                                                     n_threads);
+
+                                      // These ranges are then assigned
+                                      // to a number of threads which
+                                      // we create next. Each will
+                                      // assemble the local cell
+                                      // matrices on the assigned
+                                      // cells, and fill the matrix
+                                      // object with it. Since there is
+                                      // need for synchronization when
+                                      // filling the same matrix from
+                                      // different threads, we need a
+                                      // mutex here:
+      Threads::ThreadMutex mutex;
+      Threads::ThreadGroup<> threads;
+      for (unsigned int thread=0; thread<n_threads; ++thread)
+       threads += Threads::new_thread (&Solver<dim>::assemble_matrix,
+                                       *this,
+                                       linear_system,
+                                       thread_ranges[thread].first,
+                                       thread_ranges[thread].second,
+                                       mutex);
+
+                                      // While the new threads
+                                      // assemble the system matrix, we
+                                      // can already compute the right
+                                      // hand side vector in the main
+                                      // thread, and condense away the
+                                      // constraints due to hanging
+                                      // nodes:
+      assemble_rhs (linear_system.rhs);
+      linear_system.hanging_node_constraints.condense (linear_system.rhs);
+
+                                      // And while we're already
+                                      // computing things in parallel,
+                                      // interpolating boundary values
+                                      // is one more thing that can be
+                                      // done independently, so we do
+                                      // it here:
+      std::map<unsigned int,double> boundary_value_map;
+      VectorTools::interpolate_boundary_values (dof_handler,
+                                               0,
+                                               *boundary_values,
+                                               boundary_value_map);
+
+
+                                      // If this is done, wait for the
+                                      // matrix assembling threads, and
+                                      // condense the constraints in
+                                      // the matrix as well:
+      threads.join_all ();
+      linear_system.hanging_node_constraints.condense (linear_system.matrix);
+
+                                      // Now that we have the linear
+                                      // system, we can also treat
+                                      // boundary values, which need to
+                                      // be eliminated from both the
+                                      // matrix and the right hand
+                                      // side:
+      MatrixTools::apply_boundary_values (boundary_value_map,
+                                         linear_system.matrix,
+                                         solution,
+                                         linear_system.rhs);
 
-       fe_values.reinit (cell);
+    }
+
+
+                                    // The second of this pair of
+                                    // functions takes a range of cell
+                                    // iterators, and assembles the
+                                    // system matrix on this part of
+                                    // the domain. Since it's actions
+                                    // have all been explained in
+                                    // previous programs, we do not
+                                    // comment on it any more, except
+                                    // for one pointe below.
+    template <int dim>
+    void
+    Solver<dim>::assemble_matrix (LinearSystem                                         &linear_system,
+                                 const typename DoFHandler<dim>::active_cell_iterator &begin_cell,
+                                 const typename DoFHandler<dim>::active_cell_iterator &end_cell,
+                                 Threads::ThreadMutex                                 &mutex) const
+    {
+      FEValues<dim> fe_values (*fe, *quadrature,
+                              update_gradients | update_JxW_values);
 
-       for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
+      const unsigned int   dofs_per_cell = fe->dofs_per_cell;
+      const unsigned int   n_q_points    = quadrature->size();
+
+      FullMatrix<double>   cell_matrix (dofs_per_cell, dofs_per_cell);
+
+      std::vector<unsigned int> local_dof_indices (dofs_per_cell);
+
+      for (typename DoFHandler<dim>::active_cell_iterator cell=begin_cell;
+          cell!=end_cell; ++cell)
+       {
+         cell_matrix = 0;
+
+         fe_values.reinit (cell);
+
+         for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
+           for (unsigned int i=0; i<dofs_per_cell; ++i)
+             for (unsigned int j=0; j<dofs_per_cell; ++j)
+               cell_matrix(i,j) += (fe_values.shape_grad(i,q_point) *
+                                    fe_values.shape_grad(j,q_point) *
+                                    fe_values.JxW(q_point));
+
+
+         cell->get_dof_indices (local_dof_indices);
+
+                                          // In the step-9 program, we
+                                          // have shown that you have
+                                          // to use the mutex to lock
+                                          // the matrix when copying
+                                          // the elements from the
+                                          // local to the global
+                                          // matrix. This was necessary
+                                          // to avoid that two threads
+                                          // access it at the same
+                                          // time, eventually
+                                          // overwriting their
+                                          // respective
+                                          // work. Previously, we have
+                                          // used the <code>acquire</code> and
+                                          // <code>release</code> functions of
+                                          // the mutex to lock and
+                                          // unlock the mutex,
+                                          // respectively. While this
+                                          // is valid, there is one
+                                          // possible catch: if between
+                                          // the locking operation and
+                                          // the unlocking operation an
+                                          // exception is thrown, the
+                                          // mutex remains in the
+                                          // locked state, and in some
+                                          // cases this might lead to
+                                          // deadlocks. A similar
+                                          // situation arises, when one
+                                          // changes the code to have a
+                                          // return statement somewhere
+                                          // in the middle of the
+                                          // locked block, and forgets
+                                          // that before we call
+                                          // <code>return</code>, we also have
+                                          // to unlock the mutex. This
+                                          // all is not be a problem
+                                          // here, but we want to show
+                                          // the general technique to
+                                          // cope with these problems
+                                          // nevertheless: have an
+                                          // object that upon
+                                          // initialization (i.e. in
+                                          // its constructor) locks the
+                                          // mutex, and on running the
+                                          // destructor unlocks it
+                                          // again. This is called the
+                                          // <code>scoped lock</code> pattern
+                                          // (apparently invented by
+                                          // Doug Schmidt originally),
+                                          // and it works because
+                                          // destructors of local
+                                          // objects are also run when
+                                          // we exit the function
+                                          // either through a
+                                          // <code>return</code> statement, or
+                                          // when an exception is
+                                          // raised. Thus, it is
+                                          // guaranteed that the mutex
+                                          // will always be unlocked
+                                          // when we exit this part of
+                                          // the program, whether the
+                                          // operation completed
+                                          // successfully or not,
+                                          // whether the exit path was
+                                          // something we implemented
+                                          // willfully or whether the
+                                          // function was exited by an
+                                          // exception that we did not
+                                          // forsee.
+                                          //
+                                          // deal.II implements the
+                                          // scoped locking pattern in
+                                          // the
+                                          // ThreadMutex::ScopedLock
+                                          // class: it takes the mutex
+                                          // in the constructor and
+                                          // locks it; in its
+                                          // destructor, it unlocks it
+                                          // again. So here is how it
+                                          // is used:
+         Threads::ThreadMutex::ScopedLock lock (mutex);
          for (unsigned int i=0; i<dofs_per_cell; ++i)
            for (unsigned int j=0; j<dofs_per_cell; ++j)
-             cell_matrix(i,j) += (fe_values.shape_grad(i,q_point) *
-                                  fe_values.shape_grad(j,q_point) *
-                                  fe_values.JxW(q_point));
-
-
-       cell->get_dof_indices (local_dof_indices);
-
-                                         // In the step-9 program, we
-                                         // have shown that you have
-                                         // to use the mutex to lock
-                                         // the matrix when copying
-                                         // the elements from the
-                                         // local to the global
-                                         // matrix. This was necessary
-                                         // to avoid that two threads
-                                         // access it at the same
-                                         // time, eventually
-                                         // overwriting their
-                                         // respective
-                                         // work. Previously, we have
-                                         // used the <code>acquire</code> and
-                                         // <code>release</code> functions of
-                                         // the mutex to lock and
-                                         // unlock the mutex,
-                                         // respectively. While this
-                                         // is valid, there is one
-                                         // possible catch: if between
-                                         // the locking operation and
-                                         // the unlocking operation an
-                                         // exception is thrown, the
-                                         // mutex remains in the
-                                         // locked state, and in some
-                                         // cases this might lead to
-                                         // deadlocks. A similar
-                                         // situation arises, when one
-                                         // changes the code to have a
-                                         // return statement somewhere
-                                         // in the middle of the
-                                         // locked block, and forgets
-                                         // that before we call
-                                         // <code>return</code>, we also have
-                                         // to unlock the mutex. This
-                                         // all is not be a problem
-                                         // here, but we want to show
-                                         // the general technique to
-                                         // cope with these problems
-                                         // nevertheless: have an
-                                         // object that upon
-                                         // initialization (i.e. in
-                                         // its constructor) locks the
-                                         // mutex, and on running the
-                                         // destructor unlocks it
-                                         // again. This is called the
-                                         // <code>scoped lock</code> pattern
-                                         // (apparently invented by
-                                         // Doug Schmidt originally),
-                                         // and it works because
-                                         // destructors of local
-                                         // objects are also run when
-                                         // we exit the function
-                                         // either through a
-                                         // <code>return</code> statement, or
-                                         // when an exception is
-                                         // raised. Thus, it is
-                                         // guaranteed that the mutex
-                                         // will always be unlocked
-                                         // when we exit this part of
-                                         // the program, whether the
-                                         // operation completed
-                                         // successfully or not,
-                                         // whether the exit path was
-                                         // something we implemented
-                                         // willfully or whether the
-                                         // function was exited by an
-                                         // exception that we did not
-                                         // forsee.
-                                         //
-                                         // deal.II implements the
-                                         // scoped locking pattern in
-                                         // the
-                                         // ThreadMutex::ScopedLock
-                                         // class: it takes the mutex
-                                         // in the constructor and
-                                         // locks it; in its
-                                         // destructor, it unlocks it
-                                         // again. So here is how it
-                                         // is used:
-        Threads::ThreadMutex::ScopedLock lock (mutex);
-       for (unsigned int i=0; i<dofs_per_cell; ++i)
-         for (unsigned int j=0; j<dofs_per_cell; ++j)
-           linear_system.matrix.add (local_dof_indices[i],
-                                     local_dof_indices[j],
-                                     cell_matrix(i,j));
-                                         // Here, at the brace, the
-                                         // current scope ends, so the
-                                         // <code>lock</code> variable goes out
-                                         // of existence and its
-                                         // destructor the mutex is
-                                         // unlocked.
-      };
-  }
+             linear_system.matrix.add (local_dof_indices[i],
+                                       local_dof_indices[j],
+                                       cell_matrix(i,j));
+                                          // Here, at the brace, the
+                                          // current scope ends, so the
+                                          // <code>lock</code> variable goes out
+                                          // of existence and its
+                                          // destructor the mutex is
+                                          // unlocked.
+       };
+    }
 
 
-                                  // Now for the functions that
-                                  // implement actions in the linear
-                                  // system class. First, the
-                                  // constructor initializes all data
-                                  // elements to their correct sizes,
-                                  // and sets up a number of
-                                  // additional data structures, such
-                                  // as constraints due to hanging
-                                  // nodes. Since setting up the
-                                  // hanging nodes and finding out
-                                  // about the nonzero elements of
-                                  // the matrix is independent, we do
-                                  // that in parallel (if the library
-                                  // was configured to use
-                                  // concurrency, at least;
-                                  // otherwise, the actions are
-                                  // performed sequentially). Note
-                                  // that we start only one thread,
-                                  // and do the second action in the
-                                  // main thread. Since only one
-                                  // thread is generated, we don't
-                                  // use the <code>Threads::ThreadGroup</code>
-                                  // class here, but rather use the
-                                  // one created thread object
-                                  // directly to wait for this
-                                  // particular thread's exit.
-                                  //
-                                  // Note that taking up the address
-                                  // of the
-                                  // <code>DoFTools::make_hanging_node_constraints</code>
-                                  // function is a little tricky,
-                                  // since there are actually three
-                                  // of them, one for each supported
-                                  // space dimension. Taking
-                                  // addresses of overloaded
-                                  // functions is somewhat
-                                  // complicated in C++, since the
-                                  // address-of operator <code>&</code> in
-                                  // that case returns more like a
-                                  // set of values (the addresses of
-                                  // all functions with that name),
-                                  // and selecting the right one is
-                                  // then the next step. If the
-                                  // context dictates which one to
-                                  // take (for example by assigning
-                                  // to a function pointer of known
-                                  // type), then the compiler can do
-                                  // that by itself, but if this set
-                                  // of pointers shall be given as
-                                  // the argument to a function that
-                                  // takes a template, the compiler
-                                  // could choose all without having
-                                  // a preference for one. We
-                                  // therefore have to make it clear
-                                  // to the compiler which one we
-                                  // would like to have; for this, we
-                                  // could use a cast, but for more
-                                  // clarity, we assign it to a
-                                  // temporary <code>mhnc_p</code> (short for
-                                  // <code>pointer to
-                                  // make_hanging_node_constraints</code>)
-                                  // with the right type, and using
-                                  // this pointer instead.
-  template <int dim>
-  Solver<dim>::LinearSystem::
-  LinearSystem (const DoFHandler<dim> &dof_handler)
-  {
-    hanging_node_constraints.clear ();
-
-    void (*mhnc_p) (const DoFHandler<dim> &,
-                   ConstraintMatrix      &)
-      = &DoFTools::make_hanging_node_constraints;
-    
-    Threads::Thread<>
-      mhnc_thread = Threads::new_thread (mhnc_p,
-                                        dof_handler,
-                                        hanging_node_constraints);
-
-    sparsity_pattern.reinit (dof_handler.n_dofs(),
-                            dof_handler.n_dofs(),
-                            dof_handler.max_couplings_between_dofs());
-    DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
-
-                                    // Wait until the
-                                    // <code>hanging_node_constraints</code>
-                                    // object is fully set up, then
-                                    // close it and use it to
-                                    // condense the sparsity pattern:
-    mhnc_thread.join ();
-    hanging_node_constraints.close ();
-    hanging_node_constraints.condense (sparsity_pattern);
-
-                                    // Finally, close the sparsity
-                                    // pattern, initialize the
-                                    // matrix, and set the right hand
-                                    // side vector to the right size.
-    sparsity_pattern.compress();
-    matrix.reinit (sparsity_pattern);
-    rhs.reinit (dof_handler.n_dofs());
-  }
+                                    // Now for the functions that
+                                    // implement actions in the linear
+                                    // system class. First, the
+                                    // constructor initializes all data
+                                    // elements to their correct sizes,
+                                    // and sets up a number of
+                                    // additional data structures, such
+                                    // as constraints due to hanging
+                                    // nodes. Since setting up the
+                                    // hanging nodes and finding out
+                                    // about the nonzero elements of
+                                    // the matrix is independent, we do
+                                    // that in parallel (if the library
+                                    // was configured to use
+                                    // concurrency, at least;
+                                    // otherwise, the actions are
+                                    // performed sequentially). Note
+                                    // that we start only one thread,
+                                    // and do the second action in the
+                                    // main thread. Since only one
+                                    // thread is generated, we don't
+                                    // use the <code>Threads::ThreadGroup</code>
+                                    // class here, but rather use the
+                                    // one created thread object
+                                    // directly to wait for this
+                                    // particular thread's exit.
+                                    //
+                                    // Note that taking up the address
+                                    // of the
+                                    // <code>DoFTools::make_hanging_node_constraints</code>
+                                    // function is a little tricky,
+                                    // since there are actually three
+                                    // of them, one for each supported
+                                    // space dimension. Taking
+                                    // addresses of overloaded
+                                    // functions is somewhat
+                                    // complicated in C++, since the
+                                    // address-of operator <code>&</code> in
+                                    // that case returns more like a
+                                    // set of values (the addresses of
+                                    // all functions with that name),
+                                    // and selecting the right one is
+                                    // then the next step. If the
+                                    // context dictates which one to
+                                    // take (for example by assigning
+                                    // to a function pointer of known
+                                    // type), then the compiler can do
+                                    // that by itself, but if this set
+                                    // of pointers shall be given as
+                                    // the argument to a function that
+                                    // takes a template, the compiler
+                                    // could choose all without having
+                                    // a preference for one. We
+                                    // therefore have to make it clear
+                                    // to the compiler which one we
+                                    // would like to have; for this, we
+                                    // could use a cast, but for more
+                                    // clarity, we assign it to a
+                                    // temporary <code>mhnc_p</code> (short for
+                                    // <code>pointer to
+                                    // make_hanging_node_constraints</code>)
+                                    // with the right type, and using
+                                    // this pointer instead.
+    template <int dim>
+    Solver<dim>::LinearSystem::
+    LinearSystem (const DoFHandler<dim> &dof_handler)
+    {
+      hanging_node_constraints.clear ();
+
+      void (*mhnc_p) (const DoFHandler<dim> &,
+                     ConstraintMatrix      &)
+       = &DoFTools::make_hanging_node_constraints;
+
+      Threads::Thread<>
+       mhnc_thread = Threads::new_thread (mhnc_p,
+                                          dof_handler,
+                                          hanging_node_constraints);
+
+      sparsity_pattern.reinit (dof_handler.n_dofs(),
+                              dof_handler.n_dofs(),
+                              dof_handler.max_couplings_between_dofs());
+      DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
+
+                                      // Wait until the
+                                      // <code>hanging_node_constraints</code>
+                                      // object is fully set up, then
+                                      // close it and use it to
+                                      // condense the sparsity pattern:
+      mhnc_thread.join ();
+      hanging_node_constraints.close ();
+      hanging_node_constraints.condense (sparsity_pattern);
+
+                                      // Finally, close the sparsity
+                                      // pattern, initialize the
+                                      // matrix, and set the right hand
+                                      // side vector to the right size.
+      sparsity_pattern.compress();
+      matrix.reinit (sparsity_pattern);
+      rhs.reinit (dof_handler.n_dofs());
+    }
 
 
 
-                                  // The second function of this
-                                  // class simply solves the linear
-                                  // system by a preconditioned
-                                  // conjugate gradient method. This
-                                  // has been extensively discussed
-                                  // before, so we don't dwell into
-                                  // it any more.
-  template <int dim>
-  void
-  Solver<dim>::LinearSystem::solve (Vector<double> &solution) const
-  {
-    SolverControl           solver_control (1000, 1e-12);
-    SolverCG<>              cg (solver_control);
+                                    // The second function of this
+                                    // class simply solves the linear
+                                    // system by a preconditioned
+                                    // conjugate gradient method. This
+                                    // has been extensively discussed
+                                    // before, so we don't dwell into
+                                    // it any more.
+    template <int dim>
+    void
+    Solver<dim>::LinearSystem::solve (Vector<double> &solution) const
+    {
+      SolverControl           solver_control (1000, 1e-12);
+      SolverCG<>              cg (solver_control);
 
-    PreconditionSSOR<> preconditioner;
-    preconditioner.initialize(matrix, 1.2);
+      PreconditionSSOR<> preconditioner;
+      preconditioner.initialize(matrix, 1.2);
 
-    cg.solve (matrix, solution, rhs, preconditioner);
+      cg.solve (matrix, solution, rhs, preconditioner);
 
-    hanging_node_constraints.distribute (solution);
-  }
+      hanging_node_constraints.distribute (solution);
+    }
 
 
 
 
-                                  // @sect4{A primal solver}
+                                    // @sect4{A primal solver}
 
-                                  // In the previous section, a base
-                                  // class for Laplace solvers was
-                                  // implemented, that lacked the
-                                  // functionality to assemble the
-                                  // right hand side vector, however,
-                                  // for reasons that were explained
-                                  // there. Now we implement a
-                                  // corresponding class that can do
-                                  // this for the case that the right
-                                  // hand side of a problem is given
-                                  // as a function object.
-                                  //
-                                  // The actions of the class are
-                                  // rather what you have seen
-                                  // already in previous examples
-                                  // already, so a brief explanation
-                                  // should suffice: the constructor
-                                  // takes the same data as does that
-                                  // of the underlying class (to
-                                  // which it passes all information)
-                                  // except for one function object
-                                  // that denotes the right hand side
-                                  // of the problem. A pointer to
-                                  // this object is stored (again as
-                                  // a <code>SmartPointer</code>, in order to
-                                  // make sure that the function
-                                  // object is not deleted as long as
-                                  // it is still used by this class).
-                                  //
-                                  // The only functional part of this
-                                  // class is the <code>assemble_rhs</code>
-                                  // method that does what its name
-                                  // suggests.
-  template <int dim>
-  class PrimalSolver : public Solver<dim>
-  {
-    public:
-      PrimalSolver (Triangulation<dim>       &triangulation,
-                   const FiniteElement<dim> &fe,
-                   const Quadrature<dim>    &quadrature,
-                   const Function<dim>      &rhs_function,
-                   const Function<dim>      &boundary_values);
-    protected:
-      const SmartPointer<const Function<dim> > rhs_function;
-      virtual void assemble_rhs (Vector<double> &rhs) const;
-  };
+                                    // In the previous section, a base
+                                    // class for Laplace solvers was
+                                    // implemented, that lacked the
+                                    // functionality to assemble the
+                                    // right hand side vector, however,
+                                    // for reasons that were explained
+                                    // there. Now we implement a
+                                    // corresponding class that can do
+                                    // this for the case that the right
+                                    // hand side of a problem is given
+                                    // as a function object.
+                                    //
+                                    // The actions of the class are
+                                    // rather what you have seen
+                                    // already in previous examples
+                                    // already, so a brief explanation
+                                    // should suffice: the constructor
+                                    // takes the same data as does that
+                                    // of the underlying class (to
+                                    // which it passes all information)
+                                    // except for one function object
+                                    // that denotes the right hand side
+                                    // of the problem. A pointer to
+                                    // this object is stored (again as
+                                    // a <code>SmartPointer</code>, in order to
+                                    // make sure that the function
+                                    // object is not deleted as long as
+                                    // it is still used by this class).
+                                    //
+                                    // The only functional part of this
+                                    // class is the <code>assemble_rhs</code>
+                                    // method that does what its name
+                                    // suggests.
+    template <int dim>
+    class PrimalSolver : public Solver<dim>
+    {
+      public:
+       PrimalSolver (Triangulation<dim>       &triangulation,
+                     const FiniteElement<dim> &fe,
+                     const Quadrature<dim>    &quadrature,
+                     const Function<dim>      &rhs_function,
+                     const Function<dim>      &boundary_values);
+      protected:
+       const SmartPointer<const Function<dim> > rhs_function;
+       virtual void assemble_rhs (Vector<double> &rhs) const;
+    };
 
 
-                                  // The constructor of this class
-                                  // basically does what it is
-                                  // announced to do above...
-  template <int dim>
-  PrimalSolver<dim>::
-  PrimalSolver (Triangulation<dim>       &triangulation,
-               const FiniteElement<dim> &fe,
-               const Quadrature<dim>    &quadrature,
-               const Function<dim>      &rhs_function,
-               const Function<dim>      &boundary_values)
-                 :
-                 Base<dim> (triangulation),
-                 Solver<dim> (triangulation, fe,
-                              quadrature, boundary_values),
-                  rhs_function (&rhs_function)
-  {}
-
-
-
-                                  // ... as does the <code>assemble_rhs</code>
-                                  // function. Since this is
-                                  // explained in several of the
-                                  // previous example programs, we
-                                  // leave it at that.
-  template <int dim>
-  void
-  PrimalSolver<dim>::
-  assemble_rhs (Vector<double> &rhs) const 
-  {
-    FEValues<dim> fe_values (*this->fe, *this->quadrature, 
-                            update_values | update_quadrature_points  |
-                             update_JxW_values);
+                                    // The constructor of this class
+                                    // basically does what it is
+                                    // announced to do above...
+    template <int dim>
+    PrimalSolver<dim>::
+    PrimalSolver (Triangulation<dim>       &triangulation,
+                 const FiniteElement<dim> &fe,
+                 const Quadrature<dim>    &quadrature,
+                 const Function<dim>      &rhs_function,
+                 const Function<dim>      &boundary_values)
+                   :
+                   Base<dim> (triangulation),
+                   Solver<dim> (triangulation, fe,
+                                quadrature, boundary_values),
+                   rhs_function (&rhs_function)
+    {}
+
+
+
+                                    // ... as does the <code>assemble_rhs</code>
+                                    // function. Since this is
+                                    // explained in several of the
+                                    // previous example programs, we
+                                    // leave it at that.
+    template <int dim>
+    void
+    PrimalSolver<dim>::
+    assemble_rhs (Vector<double> &rhs) const
+    {
+      FEValues<dim> fe_values (*this->fe, *this->quadrature,
+                              update_values | update_quadrature_points  |
+                              update_JxW_values);
 
-    const unsigned int   dofs_per_cell = this->fe->dofs_per_cell;
-    const unsigned int   n_q_points    = this->quadrature->size();
+      const unsigned int   dofs_per_cell = this->fe->dofs_per_cell;
+      const unsigned int   n_q_points    = this->quadrature->size();
 
-    Vector<double>       cell_rhs (dofs_per_cell);
-    std::vector<double>  rhs_values (n_q_points);
-    std::vector<unsigned int> local_dof_indices (dofs_per_cell);
+      Vector<double>       cell_rhs (dofs_per_cell);
+      std::vector<double>  rhs_values (n_q_points);
+      std::vector<unsigned int> local_dof_indices (dofs_per_cell);
 
-    typename DoFHandler<dim>::active_cell_iterator
-      cell = this->dof_handler.begin_active(),
-      endc = this->dof_handler.end();
-    for (; cell!=endc; ++cell)
-      {
-       cell_rhs = 0;
-       fe_values.reinit (cell);
-       rhs_function->value_list (fe_values.get_quadrature_points(),
-                                 rhs_values);
-      
-       for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
+      typename DoFHandler<dim>::active_cell_iterator
+       cell = this->dof_handler.begin_active(),
+       endc = this->dof_handler.end();
+      for (; cell!=endc; ++cell)
+       {
+         cell_rhs = 0;
+         fe_values.reinit (cell);
+         rhs_function->value_list (fe_values.get_quadrature_points(),
+                                   rhs_values);
+
+         for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
+           for (unsigned int i=0; i<dofs_per_cell; ++i)
+             cell_rhs(i) += (fe_values.shape_value(i,q_point) *
+                             rhs_values[q_point] *
+                             fe_values.JxW(q_point));
+
+         cell->get_dof_indices (local_dof_indices);
          for (unsigned int i=0; i<dofs_per_cell; ++i)
-           cell_rhs(i) += (fe_values.shape_value(i,q_point) *
-                           rhs_values[q_point] *
-                           fe_values.JxW(q_point));
+           rhs(local_dof_indices[i]) += cell_rhs(i);
+       };
+    }
 
-       cell->get_dof_indices (local_dof_indices);
-       for (unsigned int i=0; i<dofs_per_cell; ++i)
-         rhs(local_dof_indices[i]) += cell_rhs(i);
-      };
-  }
 
+                                    // @sect4{Global refinement}
 
-                                  // @sect4{Global refinement}
+                                    // By now, all functions of the
+                                    // abstract base class except for
+                                    // the <code>refine_grid</code> function
+                                    // have been implemented. We will
+                                    // now have two classes that
+                                    // implement this function for the
+                                    // <code>PrimalSolver</code> class, one
+                                    // doing global refinement, one a
+                                    // form of local refinement.
+                                    //
+                                    // The first, doing global
+                                    // refinement, is rather simple:
+                                    // its main function just calls
+                                    // <code>triangulation-@>refine_global
+                                    // (1);</code>, which does all the work.
+                                    //
+                                    // Note that since the <code>Base</code>
+                                    // base class of the <code>Solver</code>
+                                    // class is virtual, we have to
+                                    // declare a constructor that
+                                    // initializes the immediate base
+                                    // class as well as the abstract
+                                    // virtual one.
+                                    //
+                                    // Apart from this technical
+                                    // complication, the class is
+                                    // probably simple enough to be
+                                    // left without further comments.
+    template <int dim>
+    class RefinementGlobal : public PrimalSolver<dim>
+    {
+      public:
+       RefinementGlobal (Triangulation<dim>       &coarse_grid,
+                         const FiniteElement<dim> &fe,
+                         const Quadrature<dim>    &quadrature,
+                         const Function<dim>      &rhs_function,
+                         const Function<dim>      &boundary_values);
+
+       virtual void refine_grid ();
+    };
 
-                                  // By now, all functions of the
-                                  // abstract base class except for
-                                  // the <code>refine_grid</code> function
-                                  // have been implemented. We will
-                                  // now have two classes that
-                                  // implement this function for the
-                                  // <code>PrimalSolver</code> class, one
-                                  // doing global refinement, one a
-                                  // form of local refinement.
-                                  //
-                                  // The first, doing global
-                                  // refinement, is rather simple:
-                                  // its main function just calls
-                                  // <code>triangulation-@>refine_global
-                                  // (1);</code>, which does all the work.
-                                  //
-                                  // Note that since the <code>Base</code>
-                                  // base class of the <code>Solver</code>
-                                  // class is virtual, we have to
-                                  // declare a constructor that
-                                  // initializes the immediate base
-                                  // class as well as the abstract
-                                  // virtual one.
-                                  //
-                                  // Apart from this technical
-                                  // complication, the class is
-                                  // probably simple enough to be
-                                  // left without further comments.
-  template <int dim>
-  class RefinementGlobal : public PrimalSolver<dim>
-  {
-    public:
-      RefinementGlobal (Triangulation<dim>       &coarse_grid,
-                       const FiniteElement<dim> &fe,
-                       const Quadrature<dim>    &quadrature,
-                       const Function<dim>      &rhs_function,
-                       const Function<dim>      &boundary_values);
 
-      virtual void refine_grid ();
-  };
 
+    template <int dim>
+    RefinementGlobal<dim>::
+    RefinementGlobal (Triangulation<dim>       &coarse_grid,
+                     const FiniteElement<dim> &fe,
+                     const Quadrature<dim>    &quadrature,
+                     const Function<dim>      &rhs_function,
+                     const Function<dim>      &boundary_values)
+                   :
+                   Base<dim> (coarse_grid),
+                   PrimalSolver<dim> (coarse_grid, fe, quadrature,
+                                      rhs_function, boundary_values)
+    {}
 
 
-  template <int dim>
-  RefinementGlobal<dim>::
-  RefinementGlobal (Triangulation<dim>       &coarse_grid,
-                   const FiniteElement<dim> &fe,
-                   const Quadrature<dim>    &quadrature,
-                   const Function<dim>      &rhs_function,
-                   const Function<dim>      &boundary_values)
-                 :
-                 Base<dim> (coarse_grid),
-                  PrimalSolver<dim> (coarse_grid, fe, quadrature,
-                                    rhs_function, boundary_values)
-  {}
 
+    template <int dim>
+    void
+    RefinementGlobal<dim>::refine_grid ()
+    {
+      this->triangulation->refine_global (1);
+    }
 
 
-  template <int dim>
-  void
-  RefinementGlobal<dim>::refine_grid ()
-  {
-    this->triangulation->refine_global (1);
+                                    // @sect4{Local refinement by the Kelly error indicator}
+
+                                    // The second class implementing
+                                    // refinement strategies uses the
+                                    // Kelly refinemet indicator used
+                                    // in various example programs
+                                    // before. Since this indicator is
+                                    // already implemented in a class
+                                    // of its own inside the deal.II
+                                    // library, there is not much t do
+                                    // here except cal the function
+                                    // computing the indicator, then
+                                    // using it to select a number of
+                                    // cells for refinement and
+                                    // coarsening, and refinement the
+                                    // mesh accordingly.
+                                    //
+                                    // Again, this should now be
+                                    // sufficiently standard to allow
+                                    // the omission of further
+                                    // comments.
+    template <int dim>
+    class RefinementKelly : public PrimalSolver<dim>
+    {
+      public:
+       RefinementKelly (Triangulation<dim>       &coarse_grid,
+                        const FiniteElement<dim> &fe,
+                        const Quadrature<dim>    &quadrature,
+                        const Function<dim>      &rhs_function,
+                        const Function<dim>      &boundary_values);
+
+       virtual void refine_grid ();
+    };
+
+
+
+    template <int dim>
+    RefinementKelly<dim>::
+    RefinementKelly (Triangulation<dim>       &coarse_grid,
+                    const FiniteElement<dim> &fe,
+                    const Quadrature<dim>    &quadrature,
+                    const Function<dim>      &rhs_function,
+                    const Function<dim>      &boundary_values)
+                   :
+                   Base<dim> (coarse_grid),
+                   PrimalSolver<dim> (coarse_grid, fe, quadrature,
+                                      rhs_function, boundary_values)
+    {}
+
+
+
+    template <int dim>
+    void
+    RefinementKelly<dim>::refine_grid ()
+    {
+      Vector<float> estimated_error_per_cell (this->triangulation->n_active_cells());
+      KellyErrorEstimator<dim>::estimate (this->dof_handler,
+                                         QGauss<dim-1>(3),
+                                         typename FunctionMap<dim>::type(),
+                                         this->solution,
+                                         estimated_error_per_cell);
+      GridRefinement::refine_and_coarsen_fixed_number (*this->triangulation,
+                                                      estimated_error_per_cell,
+                                                      0.3, 0.03);
+      this->triangulation->execute_coarsening_and_refinement ();
+    }
+
   }
 
 
-                                  // @sect4{Local refinement by the Kelly error indicator}
-
-                                  // The second class implementing
-                                  // refinement strategies uses the
-                                  // Kelly refinemet indicator used
-                                  // in various example programs
-                                  // before. Since this indicator is
-                                  // already implemented in a class
-                                  // of its own inside the deal.II
-                                  // library, there is not much t do
-                                  // here except cal the function
-                                  // computing the indicator, then
-                                  // using it to select a number of
-                                  // cells for refinement and
-                                  // coarsening, and refinement the
-                                  // mesh accordingly.
+
+
+                                  // @sect3{Equation data}
+
+                                  // As this is one more academic
+                                  // example, we'd like to compare
+                                  // exact and computed solution
+                                  // against each other. For this, we
+                                  // need to declare function classes
+                                  // representing the exact solution
+                                  // (for comparison and for the
+                                  // Dirichlet boundary values), as
+                                  // well as a class that denotes the
+                                  // right hand side of the equation
+                                  // (this is simply the Laplace
+                                  // operator applied to the exact
+                                  // solution we'd like to recover).
                                   //
-                                  // Again, this should now be
-                                  // sufficiently standard to allow
-                                  // the omission of further
-                                  // comments.
+                                  // For this example, let us choose as
+                                  // exact solution the function
+                                  // $u(x,y)=exp(x+sin(10y+5x^2))$. In more
+                                  // than two dimensions, simply repeat
+                                  // the sine-factor with <code>y</code>
+                                  // replaced by <code>z</code> and so on. Given
+                                  // this, the following two classes
+                                  // are probably straightforward from
+                                  // the previous examples.
+                                  //
+                                  // As in previous examples, the C++
+                                  // language forces us to declare and
+                                  // define a constructor to the
+                                  // following classes even though they
+                                  // are empty. This is due to the fact
+                                  // that the base class has no default
+                                  // constructor (i.e. one without
+                                  // arguments), even though it has a
+                                  // constructor which has default
+                                  // values for all arguments.
   template <int dim>
-  class RefinementKelly : public PrimalSolver<dim>
+  class Solution : public Function<dim>
   {
     public:
-      RefinementKelly (Triangulation<dim>       &coarse_grid,
-                      const FiniteElement<dim> &fe,
-                      const Quadrature<dim>    &quadrature,
-                      const Function<dim>      &rhs_function,
-                      const Function<dim>      &boundary_values);
+      Solution () : Function<dim> () {}
 
-      virtual void refine_grid ();
+      virtual double value (const Point<dim>   &p,
+                           const unsigned int  component) const;
   };
 
 
-
-  template <int dim>
-  RefinementKelly<dim>::
-  RefinementKelly (Triangulation<dim>       &coarse_grid,
-                  const FiniteElement<dim> &fe,
-                  const Quadrature<dim>    &quadrature,
-                  const Function<dim>      &rhs_function,
-                  const Function<dim>      &boundary_values)
-                 :
-                 Base<dim> (coarse_grid),
-                  PrimalSolver<dim> (coarse_grid, fe, quadrature,
-                                    rhs_function, boundary_values)
-  {}
-
-
-
   template <int dim>
-  void
-  RefinementKelly<dim>::refine_grid ()
+  double
+  Solution<dim>::value (const Point<dim>   &p,
+                       const unsigned int  /*component*/) const
   {
-    Vector<float> estimated_error_per_cell (this->triangulation->n_active_cells());
-    KellyErrorEstimator<dim>::estimate (this->dof_handler,
-                                       QGauss<dim-1>(3),
-                                       typename FunctionMap<dim>::type(),
-                                       this->solution,
-                                       estimated_error_per_cell);
-    GridRefinement::refine_and_coarsen_fixed_number (*this->triangulation,
-                                                    estimated_error_per_cell,
-                                                    0.3, 0.03);
-    this->triangulation->execute_coarsening_and_refinement ();
+    double q = p(0);
+    for (unsigned int i=1; i<dim; ++i)
+      q += std::sin(10*p(i)+5*p(0)*p(0));
+    const double exponential = std::exp(q);
+    return exponential;
   }
 
-}
 
 
+  template <int dim>
+  class RightHandSide : public Function<dim>
+  {
+    public:
+      RightHandSide () : Function<dim> () {}
 
+      virtual double value (const Point<dim>   &p,
+                           const unsigned int  component) const;
+  };
 
-                                // @sect3{Equation data}
-
-                                // As this is one more academic
-                                // example, we'd like to compare
-                                // exact and computed solution
-                                // against each other. For this, we
-                                // need to declare function classes
-                                // representing the exact solution
-                                // (for comparison and for the
-                                // Dirichlet boundary values), as
-                                // well as a class that denotes the
-                                // right hand side of the equation
-                                // (this is simply the Laplace
-                                // operator applied to the exact
-                                // solution we'd like to recover).
-                                //
-                                // For this example, let us choose as
-                                // exact solution the function
-                                // $u(x,y)=exp(x+sin(10y+5x^2))$. In more
-                                // than two dimensions, simply repeat
-                                // the sine-factor with <code>y</code>
-                                // replaced by <code>z</code> and so on. Given
-                                // this, the following two classes
-                                // are probably straightforward from
-                                // the previous examples.
-                                //
-                                // As in previous examples, the C++
-                                // language forces us to declare and
-                                // define a constructor to the
-                                // following classes even though they
-                                // are empty. This is due to the fact
-                                // that the base class has no default
-                                // constructor (i.e. one without
-                                // arguments), even though it has a
-                                // constructor which has default
-                                // values for all arguments.
-template <int dim>
-class Solution : public Function<dim>
-{
-  public:
-    Solution () : Function<dim> () {}
-    
-    virtual double value (const Point<dim>   &p,
-                         const unsigned int  component) const;
-};
-
-
-template <int dim>
-double
-Solution<dim>::value (const Point<dim>   &p,
-                     const unsigned int  /*component*/) const
-{
-  double q = p(0);
-  for (unsigned int i=1; i<dim; ++i)
-    q += std::sin(10*p(i)+5*p(0)*p(0));
-  const double exponential = std::exp(q);
-  return exponential;
-}
 
+  template <int dim>
+  double
+  RightHandSide<dim>::value (const Point<dim>   &p,
+                            const unsigned int  /*component*/) const
+  {
+    double q = p(0);
+    for (unsigned int i=1; i<dim; ++i)
+      q += std::sin(10*p(i)+5*p(0)*p(0));
+    const double u = std::exp(q);
+    double t1 = 1,
+          t2 = 0,
+          t3 = 0;
+    for (unsigned int i=1; i<dim; ++i)
+      {
+       t1 += std::cos(10*p(i)+5*p(0)*p(0)) * 10 * p(0);
+       t2 += 10*std::cos(10*p(i)+5*p(0)*p(0)) -
+             100*std::sin(10*p(i)+5*p(0)*p(0)) * p(0)*p(0);
+       t3 += 100*std::cos(10*p(i)+5*p(0)*p(0))*std::cos(10*p(i)+5*p(0)*p(0)) -
+             100*std::sin(10*p(i)+5*p(0)*p(0));
+      };
+    t1 = t1*t1;
 
+    return -u*(t1+t2+t3);
+  }
 
-template <int dim>
-class RightHandSide : public Function<dim>
-{
-  public:
-    RightHandSide () : Function<dim> () {}
-    
-    virtual double value (const Point<dim>   &p,
-                         const unsigned int  component) const;
-};
-
-
-template <int dim>
-double
-RightHandSide<dim>::value (const Point<dim>   &p,
-                          const unsigned int  /*component*/) const
-{
-  double q = p(0);
-  for (unsigned int i=1; i<dim; ++i)
-    q += std::sin(10*p(i)+5*p(0)*p(0));
-  const double u = std::exp(q);
-  double t1 = 1,
-        t2 = 0,
-        t3 = 0;
-  for (unsigned int i=1; i<dim; ++i)
-    {
-      t1 += std::cos(10*p(i)+5*p(0)*p(0)) * 10 * p(0);
-      t2 += 10*std::cos(10*p(i)+5*p(0)*p(0)) -
-           100*std::sin(10*p(i)+5*p(0)*p(0)) * p(0)*p(0);
-      t3 += 100*std::cos(10*p(i)+5*p(0)*p(0))*std::cos(10*p(i)+5*p(0)*p(0)) -
-           100*std::sin(10*p(i)+5*p(0)*p(0));
-    };
-  t1 = t1*t1;
-  
-  return -u*(t1+t2+t3);
-}
 
 
+                                  // @sect3{The driver routines}
 
-                                // @sect3{The driver routines}
-
-                                // What is now missing are only the
-                                // functions that actually select the
-                                // various options, and run the
-                                // simulation on successively finer
-                                // grids to monitor the progress as
-                                // the mesh is refined.
-                                //
-                                // This we do in the following
-                                // function: it takes a solver
-                                // object, and a list of
-                                // postprocessing (evaluation)
-                                // objects, and runs them with
-                                // intermittent mesh refinement:
-template <int dim>
-void
-run_simulation (LaplaceSolver::Base<dim>                     &solver,
-               const std::list<Evaluation::EvaluationBase<dim> *> &postprocessor_list)
-{
-                                  // We will give an indicator of the
-                                  // step we are presently computing,
-                                  // in order to keep the user
-                                  // informed that something is still
-                                  // happening, and that the program
-                                  // is not in an endless loop. This
-                                  // is the head of this status line:
-  std::cout << "Refinement cycle: ";
-
-                                  // Then start a loop which only
-                                  // terminates once the number of
-                                  // degrees of freedom is larger
-                                  // than 20,000 (you may of course
-                                  // change this limit, if you need
-                                  // more -- or less -- accuracy from
-                                  // your program).
-  for (unsigned int step=0; true; ++step)
-    {
-                                      // Then give the <code>alive</code>
-                                      // indication for this
-                                      // iteration. Note that the
-                                      // <code>std::flush</code> is needed to
-                                      // have the text actually
-                                      // appear on the screen, rather
-                                      // than only in some buffer
-                                      // that is only flushed the
-                                      // next time we issue an
-                                      // end-line.
-      std::cout << step << " " << std::flush;
-
-                                      // Now solve the problem on the
-                                      // present grid, and run the
-                                      // evaluators on it. The long
-                                      // type name of iterators into
-                                      // the list is a little
-                                      // annoying, but could be
-                                      // shortened by a typedef, if
-                                      // so desired.
-      solver.solve_problem ();
-
-      for (typename std::list<Evaluation::EvaluationBase<dim> *>::const_iterator
-            i = postprocessor_list.begin();
-          i != postprocessor_list.end(); ++i)
-       {
-         (*i)->set_refinement_cycle (step);
-         solver.postprocess (**i);
-       };
+                                  // What is now missing are only the
+                                  // functions that actually select the
+                                  // various options, and run the
+                                  // simulation on successively finer
+                                  // grids to monitor the progress as
+                                  // the mesh is refined.
+                                  //
+                                  // This we do in the following
+                                  // function: it takes a solver
+                                  // object, and a list of
+                                  // postprocessing (evaluation)
+                                  // objects, and runs them with
+                                  // intermittent mesh refinement:
+  template <int dim>
+  void
+  run_simulation (LaplaceSolver::Base<dim>                     &solver,
+                 const std::list<Evaluation::EvaluationBase<dim> *> &postprocessor_list)
+  {
+                                    // We will give an indicator of the
+                                    // step we are presently computing,
+                                    // in order to keep the user
+                                    // informed that something is still
+                                    // happening, and that the program
+                                    // is not in an endless loop. This
+                                    // is the head of this status line:
+    std::cout << "Refinement cycle: ";
+
+                                    // Then start a loop which only
+                                    // terminates once the number of
+                                    // degrees of freedom is larger
+                                    // than 20,000 (you may of course
+                                    // change this limit, if you need
+                                    // more -- or less -- accuracy from
+                                    // your program).
+    for (unsigned int step=0; true; ++step)
+      {
+                                        // Then give the <code>alive</code>
+                                        // indication for this
+                                        // iteration. Note that the
+                                        // <code>std::flush</code> is needed to
+                                        // have the text actually
+                                        // appear on the screen, rather
+                                        // than only in some buffer
+                                        // that is only flushed the
+                                        // next time we issue an
+                                        // end-line.
+       std::cout << step << " " << std::flush;
+
+                                        // Now solve the problem on the
+                                        // present grid, and run the
+                                        // evaluators on it. The long
+                                        // type name of iterators into
+                                        // the list is a little
+                                        // annoying, but could be
+                                        // shortened by a typedef, if
+                                        // so desired.
+       solver.solve_problem ();
+
+       for (typename std::list<Evaluation::EvaluationBase<dim> *>::const_iterator
+              i = postprocessor_list.begin();
+            i != postprocessor_list.end(); ++i)
+         {
+           (*i)->set_refinement_cycle (step);
+           solver.postprocess (**i);
+         };
 
 
-                                      // Now check whether more
-                                      // iterations are required, or
-                                      // whether the loop shall be
-                                      // ended:
-      if (solver.n_dofs() < 20000)
-       solver.refine_grid ();
-      else
-       break;
-    };
+                                        // Now check whether more
+                                        // iterations are required, or
+                                        // whether the loop shall be
+                                        // ended:
+       if (solver.n_dofs() < 20000)
+         solver.refine_grid ();
+       else
+         break;
+      };
 
-                                  // Finally end the line in which we
-                                  // displayed status reports:
-  std::cout << std::endl;
-}
+                                    // Finally end the line in which we
+                                    // displayed status reports:
+    std::cout << std::endl;
+  }
 
 
 
-                                // The final function is one which
-                                // takes the name of a solver
-                                // (presently "kelly" and "global"
-                                // are allowed), creates a solver
-                                // object out of it using a coarse
-                                // grid (in this case the ubiquitous
-                                // unit square) and a finite element
-                                // object (here the likewise
-                                // ubiquitous bilinear one), and uses
-                                // that solver to ask for the
-                                // solution of the problem on a
-                                // sequence of successively refined
-                                // grids.
-                                //
-                                // The function also sets up two of
-                                // evaluation functions, one
-                                // evaluating the solution at the
-                                // point (0.5,0.5), the other writing
-                                // out the solution to a file.
-template <int dim>
-void solve_problem (const std::string &solver_name) 
-{
-                                  // First minor task: tell the user
-                                  // what is going to happen. Thus
-                                  // write a header line, and a line
-                                  // with all '-' characters of the
-                                  // same length as the first one
-                                  // right below.
-  const std::string header = "Running tests with \"" + solver_name +
-                            "\" refinement criterion:";
-  std::cout << header << std::endl
-           << std::string (header.size(), '-') << std::endl;
-
-                                  // Then set up triangulation,
-                                  // finite element, etc.
-  Triangulation<dim> triangulation;
-  GridGenerator::hyper_cube (triangulation, -1, 1);
-  triangulation.refine_global (2);
-  const FE_Q<dim>          fe(1);
-  const QGauss<dim>       quadrature(4);
-  const RightHandSide<dim> rhs_function;
-  const Solution<dim>      boundary_values;
-
-                                  // Create a solver object of the
-                                  // kind indicated by the argument
-                                  // to this function. If the name is
-                                  // not recognized, throw an
-                                  // exception!
-  LaplaceSolver::Base<dim> * solver = 0;
-  if (solver_name == "global")
-    solver = new LaplaceSolver::RefinementGlobal<dim> (triangulation, fe,
-                                                      quadrature,
-                                                      rhs_function,
-                                                      boundary_values);
-  else if (solver_name == "kelly")
-    solver = new LaplaceSolver::RefinementKelly<dim> (triangulation, fe,
-                                                     quadrature,
-                                                     rhs_function,
-                                                     boundary_values);
-  else
-    AssertThrow (false, ExcNotImplemented());
-
-                                  // Next create a table object in
-                                  // which the values of the
-                                  // numerical solution at the point
-                                  // (0.5,0.5) will be stored, and
-                                  // create a respective evaluation
-                                  // object:
-  TableHandler results_table;
-  Evaluation::PointValueEvaluation<dim>
-    postprocessor1 (Point<dim>(0.5,0.5), results_table);
-
-                                  // Also generate an evaluator which
-                                  // writes out the solution:
-  Evaluation::SolutionOutput<dim>
-    postprocessor2 (std::string("solution-")+solver_name,
-                   DataOut<dim>::gnuplot);
-
-                                  // Take these two evaluation
-                                  // objects and put them in a
-                                  // list...
-  std::list<Evaluation::EvaluationBase<dim> *> postprocessor_list;
-  postprocessor_list.push_back (&postprocessor1);
-  postprocessor_list.push_back (&postprocessor2);
-
-                                  // ... which we can then pass on to
-                                  // the function that actually runs
-                                  // the simulation on successively
-                                  // refined grids:
-  run_simulation (*solver, postprocessor_list);
-
-                                  // When this all is done, write out
-                                  // the results of the point
-                                  // evaluations, and finally delete
-                                  // the solver object:
-  results_table.write_text (std::cout);
-  delete solver;
-
-                                  // And one blank line after all
-                                  // results:
-  std::cout << std::endl;
+                                  // The final function is one which
+                                  // takes the name of a solver
+                                  // (presently "kelly" and "global"
+                                  // are allowed), creates a solver
+                                  // object out of it using a coarse
+                                  // grid (in this case the ubiquitous
+                                  // unit square) and a finite element
+                                  // object (here the likewise
+                                  // ubiquitous bilinear one), and uses
+                                  // that solver to ask for the
+                                  // solution of the problem on a
+                                  // sequence of successively refined
+                                  // grids.
+                                  //
+                                  // The function also sets up two of
+                                  // evaluation functions, one
+                                  // evaluating the solution at the
+                                  // point (0.5,0.5), the other writing
+                                  // out the solution to a file.
+  template <int dim>
+  void solve_problem (const std::string &solver_name)
+  {
+                                    // First minor task: tell the user
+                                    // what is going to happen. Thus
+                                    // write a header line, and a line
+                                    // with all '-' characters of the
+                                    // same length as the first one
+                                    // right below.
+    const std::string header = "Running tests with \"" + solver_name +
+                              "\" refinement criterion:";
+    std::cout << header << std::endl
+             << std::string (header.size(), '-') << std::endl;
+
+                                    // Then set up triangulation,
+                                    // finite element, etc.
+    Triangulation<dim> triangulation;
+    GridGenerator::hyper_cube (triangulation, -1, 1);
+    triangulation.refine_global (2);
+    const FE_Q<dim>          fe(1);
+    const QGauss<dim>       quadrature(4);
+    const RightHandSide<dim> rhs_function;
+    const Solution<dim>      boundary_values;
+
+                                    // Create a solver object of the
+                                    // kind indicated by the argument
+                                    // to this function. If the name is
+                                    // not recognized, throw an
+                                    // exception!
+    LaplaceSolver::Base<dim> * solver = 0;
+    if (solver_name == "global")
+      solver = new LaplaceSolver::RefinementGlobal<dim> (triangulation, fe,
+                                                        quadrature,
+                                                        rhs_function,
+                                                        boundary_values);
+    else if (solver_name == "kelly")
+      solver = new LaplaceSolver::RefinementKelly<dim> (triangulation, fe,
+                                                       quadrature,
+                                                       rhs_function,
+                                                       boundary_values);
+    else
+      AssertThrow (false, ExcNotImplemented());
+
+                                    // Next create a table object in
+                                    // which the values of the
+                                    // numerical solution at the point
+                                    // (0.5,0.5) will be stored, and
+                                    // create a respective evaluation
+                                    // object:
+    TableHandler results_table;
+    Evaluation::PointValueEvaluation<dim>
+      postprocessor1 (Point<dim>(0.5,0.5), results_table);
+
+                                    // Also generate an evaluator which
+                                    // writes out the solution:
+    Evaluation::SolutionOutput<dim>
+      postprocessor2 (std::string("solution-")+solver_name,
+                     DataOut<dim>::gnuplot);
+
+                                    // Take these two evaluation
+                                    // objects and put them in a
+                                    // list...
+    std::list<Evaluation::EvaluationBase<dim> *> postprocessor_list;
+    postprocessor_list.push_back (&postprocessor1);
+    postprocessor_list.push_back (&postprocessor2);
+
+                                    // ... which we can then pass on to
+                                    // the function that actually runs
+                                    // the simulation on successively
+                                    // refined grids:
+    run_simulation (*solver, postprocessor_list);
+
+                                    // When this all is done, write out
+                                    // the results of the point
+                                    // evaluations, and finally delete
+                                    // the solver object:
+    results_table.write_text (std::cout);
+    delete solver;
+
+                                    // And one blank line after all
+                                    // results:
+    std::cout << std::endl;
+  }
 }
 
 
@@ -2054,14 +2057,14 @@ void solve_problem (const std::string &solver_name)
                                 // as much information as possible if
                                 // we should get some. The rest is
                                 // self-explanatory.
-int main () 
+int main ()
 {
   try
     {
-      deallog.depth_console (0);
+      dealii::deallog.depth_console (0);
 
-      solve_problem<2> ("global");
-      solve_problem<2> ("kelly");      
+      Step13::solve_problem<2> ("global");
+      Step13::solve_problem<2> ("kelly");
     }
   catch (std::exception &exc)
     {
@@ -2075,7 +2078,7 @@ int main ()
                << std::endl;
       return 1;
     }
-  catch (...) 
+  catch (...)
     {
       std::cerr << std::endl << std::endl
                << "----------------------------------------------------"
index 6139079b7dc9ef3208bddbd21d52439d1c1caa8c..b5d21d969fbb060429b036719bd4e81e31c7a828 100644 (file)
@@ -3,7 +3,7 @@
 
 /*    $Id$       */
 /*                                                                */
-/*    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by the deal.II authors */
+/*    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors */
 /*                                                                */
 /*    This file is subject to QPL and may not be  distributed     */
 /*    without copyright and license information. Please refer     */
 
                                 // The last step is as in all
                                 // previous programs:
-using namespace dealii;
-
-                                // @sect3{Evaluating the solution}
-
-                                // As mentioned in the introduction,
-                                // significant parts of the program
-                                // have simply been taken over from
-                                // the step-13 example program. We
-                                // therefore only comment on those
-                                // things that are new.
-                                //
-                                // First, the framework for
-                                // evaluation of solutions is
-                                // unchanged, i.e. the base class is
-                                // the same, and the class to
-                                // evaluate the solution at a grid
-                                // point is unchanged:
-namespace Evaluation
+namespace Step14
 {
-                                  // @sect4{The EvaluationBase class}
-  template <int dim>
-  class EvaluationBase 
-  {
-    public:
-      virtual ~EvaluationBase ();
-
-      void set_refinement_cycle (const unsigned int refinement_cycle);
-      
-      virtual void operator () (const DoFHandler<dim> &dof_handler,
-                               const Vector<double>  &solution) const = 0;
-    protected:
-      unsigned int refinement_cycle;
-  };
+  using namespace dealii;
 
+                                  // @sect3{Evaluating the solution}
 
-  template <int dim>
-  EvaluationBase<dim>::~EvaluationBase ()
-  {}
-  
+                                  // As mentioned in the introduction,
+                                  // significant parts of the program
+                                  // have simply been taken over from
+                                  // the step-13 example program. We
+                                  // therefore only comment on those
+                                  // things that are new.
+                                  //
+                                  // First, the framework for
+                                  // evaluation of solutions is
+                                  // unchanged, i.e. the base class is
+                                  // the same, and the class to
+                                  // evaluate the solution at a grid
+                                  // point is unchanged:
+  namespace Evaluation
+  {
+                                    // @sect4{The EvaluationBase class}
+    template <int dim>
+    class EvaluationBase
+    {
+      public:
+       virtual ~EvaluationBase ();
 
-  
-  template <int dim>
-  void
-  EvaluationBase<dim>::set_refinement_cycle (const unsigned int step)
-  {
-    refinement_cycle = step;
-  }
+       void set_refinement_cycle (const unsigned int refinement_cycle);
 
+       virtual void operator () (const DoFHandler<dim> &dof_handler,
+                                 const Vector<double>  &solution) const = 0;
+      protected:
+       unsigned int refinement_cycle;
+    };
 
-                                  // @sect4{The PointValueEvaluation class}
-  template <int dim>
-  class PointValueEvaluation : public EvaluationBase<dim>
-  {
-    public:
-      PointValueEvaluation (const Point<dim>   &evaluation_point);
-      
-      virtual void operator () (const DoFHandler<dim> &dof_handler,
-                               const Vector<double>  &solution) const;
-      
-      DeclException1 (ExcEvaluationPointNotFound,
-                     Point<dim>,
-                     << "The evaluation point " << arg1
-                     << " was not found among the vertices of the present grid.");
-    private:
-      const Point<dim>  evaluation_point;
-  };
 
+    template <int dim>
+    EvaluationBase<dim>::~EvaluationBase ()
+    {}
 
-  template <int dim>
-  PointValueEvaluation<dim>::
-  PointValueEvaluation (const Point<dim>   &evaluation_point)
-                 :
-                 evaluation_point (evaluation_point)
-  {}
-  
 
 
-  template <int dim>
-  void
-  PointValueEvaluation<dim>::
-  operator () (const DoFHandler<dim> &dof_handler,
-              const Vector<double>  &solution) const 
-  {
-    double point_value = 1e20;
-
-    typename DoFHandler<dim>::active_cell_iterator
-      cell = dof_handler.begin_active(),
-      endc = dof_handler.end();
-    bool evaluation_point_found = false;
-    for (; (cell!=endc) && !evaluation_point_found; ++cell)
-      for (unsigned int vertex=0;
-          vertex<GeometryInfo<dim>::vertices_per_cell;
-          ++vertex)
-       if (cell->vertex(vertex).distance (evaluation_point)
-           <
-           cell->diameter() * 1e-8)
-         {
-           point_value = solution(cell->vertex_dof_index(vertex,0));
+    template <int dim>
+    void
+    EvaluationBase<dim>::set_refinement_cycle (const unsigned int step)
+    {
+      refinement_cycle = step;
+    }
 
-           evaluation_point_found = true;
-           break;
-         }
 
-    AssertThrow (evaluation_point_found,
-                ExcEvaluationPointNotFound(evaluation_point));
+                                    // @sect4{The PointValueEvaluation class}
+    template <int dim>
+    class PointValueEvaluation : public EvaluationBase<dim>
+    {
+      public:
+       PointValueEvaluation (const Point<dim>   &evaluation_point);
+
+       virtual void operator () (const DoFHandler<dim> &dof_handler,
+                                 const Vector<double>  &solution) const;
+
+       DeclException1 (ExcEvaluationPointNotFound,
+                       Point<dim>,
+                       << "The evaluation point " << arg1
+                       << " was not found among the vertices of the present grid.");
+      private:
+       const Point<dim>  evaluation_point;
+    };
 
-    std::cout << "   Point value=" << point_value
-             << std::endl;
-  }
 
+    template <int dim>
+    PointValueEvaluation<dim>::
+    PointValueEvaluation (const Point<dim>   &evaluation_point)
+                   :
+                   evaluation_point (evaluation_point)
+    {}
 
-                                  // @sect4{The PointXDerivativeEvaluation class}
-
-                                  // Besides the class implementing
-                                  // the evaluation of the solution
-                                  // at one point, we here provide
-                                  // one which evaluates the gradient
-                                  // at a grid point. Since in
-                                  // general the gradient of a finite
-                                  // element function is not
-                                  // continuous at a vertex, we have
-                                  // to be a little bit more careful
-                                  // here. What we do is to loop over
-                                  // all cells, even if we have found
-                                  // the point already on one cell,
-                                  // and use the mean value of the
-                                  // gradient at the vertex taken
-                                  // from all adjacent cells.
-                                  //
-                                  // Given the interface of the
-                                  // <code>PointValueEvaluation</code> class,
-                                  // the declaration of this class
-                                  // provides little surprise, and
-                                  // neither does the constructor:
-  template <int dim>
-  class PointXDerivativeEvaluation : public EvaluationBase<dim>
-  {
-    public:
-      PointXDerivativeEvaluation (const Point<dim>   &evaluation_point);
-      
-      virtual void operator () (const DoFHandler<dim> &dof_handler,
-                               const Vector<double>  &solution) const;
-      
-      DeclException1 (ExcEvaluationPointNotFound,
-                     Point<dim>,
-                     << "The evaluation point " << arg1
-                     << " was not found among the vertices of the present grid.");
-    private:
-      const Point<dim>  evaluation_point;
-  };
 
 
-  template <int dim>
-  PointXDerivativeEvaluation<dim>::
-  PointXDerivativeEvaluation (const Point<dim>   &evaluation_point)
-                 :
-                 evaluation_point (evaluation_point)
-  {}
-  
+    template <int dim>
+    void
+    PointValueEvaluation<dim>::
+    operator () (const DoFHandler<dim> &dof_handler,
+                const Vector<double>  &solution) const
+    {
+      double point_value = 1e20;
 
-                                  // The more interesting things
-                                  // happen inside the function doing
-                                  // the actual evaluation:
-  template <int dim>
-  void
-  PointXDerivativeEvaluation<dim>::
-  operator () (const DoFHandler<dim> &dof_handler,
-              const Vector<double>  &solution) const 
-  {
-                                    // This time initialize the
-                                    // return value with something
-                                    // useful, since we will have to
-                                    // add up a number of
-                                    // contributions and take the
-                                    // mean value afterwards...
-    double point_derivative = 0;
-
-                                    // ...then have some objects of
-                                    // which the meaning wil become
-                                    // clear below...
-    QTrapez<dim>  vertex_quadrature;
-    FEValues<dim> fe_values (dof_handler.get_fe(),
-                            vertex_quadrature,
-                            update_gradients | update_quadrature_points);
-    std::vector<Tensor<1,dim> >
-      solution_gradients (vertex_quadrature.size());
-    
-                                    // ...and next loop over all cells
-                                    // and their vertices, and count
-                                    // how often the vertex has been
-                                    // found:
-    typename DoFHandler<dim>::active_cell_iterator
-      cell = dof_handler.begin_active(),
-      endc = dof_handler.end();
-    unsigned int evaluation_point_hits = 0;
-    for (; cell!=endc; ++cell)
-      for (unsigned int vertex=0;
-          vertex<GeometryInfo<dim>::vertices_per_cell;
-          ++vertex)
-       if (cell->vertex(vertex) == evaluation_point)
-         {
-                                            // Things are now no more
-                                            // as simple, since we
-                                            // can't get the gradient
-                                            // of the finite element
-                                            // field as before, where
-                                            // we simply had to pick
-                                            // one degree of freedom
-                                            // at a vertex.
-                                            //
-                                            // Rather, we have to
-                                            // evaluate the finite
-                                            // element field on this
-                                            // cell, and at a certain
-                                            // point. As you know,
-                                            // evaluating finite
-                                            // element fields at
-                                            // certain points is done
-                                            // through the
-                                            // <code>FEValues</code> class, so
-                                            // we use that. The
-                                            // question is: the
-                                            // <code>FEValues</code> object
-                                            // needs to be a given a
-                                            // quadrature formula and
-                                            // can then compute the
-                                            // values of finite
-                                            // element quantities at
-                                            // the quadrature
-                                            // points. Here, we don't
-                                            // want to do quadrature,
-                                            // we simply want to
-                                            // specify some points!
-                                            //
-                                            // Nevertheless, the same
-                                            // way is chosen: use a
-                                            // special quadrature
-                                            // rule with points at
-                                            // the vertices, since
-                                            // these are what we are
-                                            // interested in. The
-                                            // appropriate rule is
-                                            // the trapezoidal rule,
-                                            // so that is the reason
-                                            // why we used that one
-                                            // above.
-                                            //
-                                            // Thus: initialize the
-                                            // <code>FEValues</code> object on
-                                            // this cell,
-           fe_values.reinit (cell);
-                                            // and extract the
-                                            // gradients of the
-                                            // solution vector at the
-                                            // vertices:
-           fe_values.get_function_grads (solution,
-                                         solution_gradients);
-
-                                            // Now we have the
-                                            // gradients at all
-                                            // vertices, so pick out
-                                            // that one which belongs
-                                            // to the evaluation
-                                            // point (note that the
-                                            // order of vertices is
-                                            // not necessarily the
-                                            // same as that of the
-                                            // quadrature points):
-           unsigned int q_point = 0;
-           for (; q_point<solution_gradients.size(); ++q_point)
-             if (fe_values.quadrature_point(q_point) ==
-                 evaluation_point)
-               break;
-
-                                            // Check that the
-                                            // evaluation point was
-                                            // indeed found,
-           Assert (q_point < solution_gradients.size(),
-                   ExcInternalError());
-                                            // and if so take the
-                                            // x-derivative of the
-                                            // gradient there as the
-                                            // value which we are
-                                            // interested in, and
-                                            // increase the counter
-                                            // indicating how often
-                                            // we have added to that
-                                            // variable:
-           point_derivative += solution_gradients[q_point][0];
-           ++evaluation_point_hits;
-
-                                            // Finally break out of
-                                            // the innermost loop
-                                            // iterating over the
-                                            // vertices of the
-                                            // present cell, since if
-                                            // we have found the
-                                            // evaluation point at
-                                            // one vertex it cannot
-                                            // be at a following
-                                            // vertex as well:
-           break;
-         }
+      typename DoFHandler<dim>::active_cell_iterator
+       cell = dof_handler.begin_active(),
+       endc = dof_handler.end();
+      bool evaluation_point_found = false;
+      for (; (cell!=endc) && !evaluation_point_found; ++cell)
+       for (unsigned int vertex=0;
+            vertex<GeometryInfo<dim>::vertices_per_cell;
+            ++vertex)
+         if (cell->vertex(vertex).distance (evaluation_point)
+             <
+             cell->diameter() * 1e-8)
+           {
+             point_value = solution(cell->vertex_dof_index(vertex,0));
 
-                                    // Now we have looped over all
-                                    // cells and vertices, so check
-                                    // whether the point was found:
-    AssertThrow (evaluation_point_hits > 0,
-                ExcEvaluationPointNotFound(evaluation_point));
-
-                                    // We have simply summed up the
-                                    // contributions of all adjacent
-                                    // cells, so we still have to
-                                    // compute the mean value. Once
-                                    // this is done, report the status:
-    point_derivative /= evaluation_point_hits;
-    std::cout << "   Point x-derivative=" << point_derivative
-             << std::endl;
-  }
+             evaluation_point_found = true;
+             break;
+           }
 
+      AssertThrow (evaluation_point_found,
+                  ExcEvaluationPointNotFound(evaluation_point));
 
-  
-                                  // @sect4{The GridOutput class}
-
-                                  // Since this program has a more
-                                  // difficult structure (it computed
-                                  // a dual solution in addition to a
-                                  // primal one), writing out the
-                                  // solution is no more done by an
-                                  // evaluation object since we want
-                                  // to write both solutions at once
-                                  // into one file, and that requires
-                                  // some more information than
-                                  // available to the evaluation
-                                  // classes.
-                                  //
-                                  // However, we also want to look at
-                                  // the grids generated. This again
-                                  // can be done with one such
-                                  // class. Its structure is analog
-                                  // to the <code>SolutionOutput</code> class
-                                  // of the previous example program,
-                                  // so we do not discuss it here in
-                                  // more detail. Furthermore,
-                                  // everything that is used here has
-                                  // already been used in previous
-                                  // example programs.
-  template <int dim>
-  class GridOutput : public EvaluationBase<dim>
-  {
-    public:
-      GridOutput (const std::string &output_name_base);
-      
-      virtual void operator () (const DoFHandler<dim> &dof_handler,
-                               const Vector<double>  &solution) const;
-    private:
-      const std::string output_name_base;
-  };
+      std::cout << "   Point value=" << point_value
+               << std::endl;
+    }
 
 
-  template <int dim>
-  GridOutput<dim>::
-  GridOutput (const std::string &output_name_base)
-                 :
-                 output_name_base (output_name_base)
-  {}
-  
+                                    // @sect4{The PointXDerivativeEvaluation class}
+
+                                    // Besides the class implementing
+                                    // the evaluation of the solution
+                                    // at one point, we here provide
+                                    // one which evaluates the gradient
+                                    // at a grid point. Since in
+                                    // general the gradient of a finite
+                                    // element function is not
+                                    // continuous at a vertex, we have
+                                    // to be a little bit more careful
+                                    // here. What we do is to loop over
+                                    // all cells, even if we have found
+                                    // the point already on one cell,
+                                    // and use the mean value of the
+                                    // gradient at the vertex taken
+                                    // from all adjacent cells.
+                                    //
+                                    // Given the interface of the
+                                    // <code>PointValueEvaluation</code> class,
+                                    // the declaration of this class
+                                    // provides little surprise, and
+                                    // neither does the constructor:
+    template <int dim>
+    class PointXDerivativeEvaluation : public EvaluationBase<dim>
+    {
+      public:
+       PointXDerivativeEvaluation (const Point<dim>   &evaluation_point);
+
+       virtual void operator () (const DoFHandler<dim> &dof_handler,
+                                 const Vector<double>  &solution) const;
+
+       DeclException1 (ExcEvaluationPointNotFound,
+                       Point<dim>,
+                       << "The evaluation point " << arg1
+                       << " was not found among the vertices of the present grid.");
+      private:
+       const Point<dim>  evaluation_point;
+    };
 
-  template <int dim>
-  void
-  GridOutput<dim>::operator () (const DoFHandler<dim> &dof_handler,
-                               const Vector<double>  &/*solution*/) const
-  {
-    std::ostringstream filename;
-    filename << output_name_base << "-"
-            << this->refinement_cycle
-            << ".eps"
-            << std::ends;
-    
-    std::ofstream out (filename.str().c_str());
-    GridOut().write_eps (dof_handler.get_tria(), out);
-  }
-}
 
-  
-                                // @sect3{The Laplace solver classes}
+    template <int dim>
+    PointXDerivativeEvaluation<dim>::
+    PointXDerivativeEvaluation (const Point<dim>   &evaluation_point)
+                   :
+                   evaluation_point (evaluation_point)
+    {}
 
-                                // Next are the actual solver
-                                // classes. Again, we discuss only
-                                // the differences to the previous
-                                // program.
-namespace LaplaceSolver
-{
-                                  // Before everything else,
-                                  // forward-declare one class that
-                                  // we will have later, since we
-                                  // will want to make it a friend of
-                                  // some of the classes that follow,
-                                  // which requires the class to be
-                                  // known:
-  template <int dim> class WeightedResidual;
-  
-  
-                                  // @sect4{The Laplace solver base class}
-
-                                  // This class is almost unchanged,
-                                  // with the exception that it
-                                  // declares two more functions:
-                                  // <code>output_solution</code> will be used
-                                  // to generate output files from
-                                  // the actual solutions computed by
-                                  // derived classes, and the
-                                  // <code>set_refinement_cycle</code>
-                                  // function by which the testing
-                                  // framework sets the number of the
-                                  // refinement cycle to a local
-                                  // variable in this class; this
-                                  // number is later used to generate
-                                  // filenames for the solution
-                                  // output.
-  template <int dim>
-  class Base
-  {
-    public:
-      Base (Triangulation<dim> &coarse_grid);
-      virtual ~Base ();
 
-      virtual void solve_problem () = 0;
-      virtual void postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const = 0;
-      virtual void refine_grid () = 0;
-      virtual unsigned int n_dofs () const = 0;
+                                    // The more interesting things
+                                    // happen inside the function doing
+                                    // the actual evaluation:
+    template <int dim>
+    void
+    PointXDerivativeEvaluation<dim>::
+    operator () (const DoFHandler<dim> &dof_handler,
+                const Vector<double>  &solution) const
+    {
+                                      // This time initialize the
+                                      // return value with something
+                                      // useful, since we will have to
+                                      // add up a number of
+                                      // contributions and take the
+                                      // mean value afterwards...
+      double point_derivative = 0;
+
+                                      // ...then have some objects of
+                                      // which the meaning wil become
+                                      // clear below...
+      QTrapez<dim>  vertex_quadrature;
+      FEValues<dim> fe_values (dof_handler.get_fe(),
+                              vertex_quadrature,
+                              update_gradients | update_quadrature_points);
+      std::vector<Tensor<1,dim> >
+       solution_gradients (vertex_quadrature.size());
+
+                                      // ...and next loop over all cells
+                                      // and their vertices, and count
+                                      // how often the vertex has been
+                                      // found:
+      typename DoFHandler<dim>::active_cell_iterator
+       cell = dof_handler.begin_active(),
+       endc = dof_handler.end();
+      unsigned int evaluation_point_hits = 0;
+      for (; cell!=endc; ++cell)
+       for (unsigned int vertex=0;
+            vertex<GeometryInfo<dim>::vertices_per_cell;
+            ++vertex)
+         if (cell->vertex(vertex) == evaluation_point)
+           {
+                                              // Things are now no more
+                                              // as simple, since we
+                                              // can't get the gradient
+                                              // of the finite element
+                                              // field as before, where
+                                              // we simply had to pick
+                                              // one degree of freedom
+                                              // at a vertex.
+                                              //
+                                              // Rather, we have to
+                                              // evaluate the finite
+                                              // element field on this
+                                              // cell, and at a certain
+                                              // point. As you know,
+                                              // evaluating finite
+                                              // element fields at
+                                              // certain points is done
+                                              // through the
+                                              // <code>FEValues</code> class, so
+                                              // we use that. The
+                                              // question is: the
+                                              // <code>FEValues</code> object
+                                              // needs to be a given a
+                                              // quadrature formula and
+                                              // can then compute the
+                                              // values of finite
+                                              // element quantities at
+                                              // the quadrature
+                                              // points. Here, we don't
+                                              // want to do quadrature,
+                                              // we simply want to
+                                              // specify some points!
+                                              //
+                                              // Nevertheless, the same
+                                              // way is chosen: use a
+                                              // special quadrature
+                                              // rule with points at
+                                              // the vertices, since
+                                              // these are what we are
+                                              // interested in. The
+                                              // appropriate rule is
+                                              // the trapezoidal rule,
+                                              // so that is the reason
+                                              // why we used that one
+                                              // above.
+                                              //
+                                              // Thus: initialize the
+                                              // <code>FEValues</code> object on
+                                              // this cell,
+             fe_values.reinit (cell);
+                                              // and extract the
+                                              // gradients of the
+                                              // solution vector at the
+                                              // vertices:
+             fe_values.get_function_grads (solution,
+                                           solution_gradients);
+
+                                              // Now we have the
+                                              // gradients at all
+                                              // vertices, so pick out
+                                              // that one which belongs
+                                              // to the evaluation
+                                              // point (note that the
+                                              // order of vertices is
+                                              // not necessarily the
+                                              // same as that of the
+                                              // quadrature points):
+             unsigned int q_point = 0;
+             for (; q_point<solution_gradients.size(); ++q_point)
+               if (fe_values.quadrature_point(q_point) ==
+                   evaluation_point)
+                 break;
+
+                                              // Check that the
+                                              // evaluation point was
+                                              // indeed found,
+             Assert (q_point < solution_gradients.size(),
+                     ExcInternalError());
+                                              // and if so take the
+                                              // x-derivative of the
+                                              // gradient there as the
+                                              // value which we are
+                                              // interested in, and
+                                              // increase the counter
+                                              // indicating how often
+                                              // we have added to that
+                                              // variable:
+             point_derivative += solution_gradients[q_point][0];
+             ++evaluation_point_hits;
+
+                                              // Finally break out of
+                                              // the innermost loop
+                                              // iterating over the
+                                              // vertices of the
+                                              // present cell, since if
+                                              // we have found the
+                                              // evaluation point at
+                                              // one vertex it cannot
+                                              // be at a following
+                                              // vertex as well:
+             break;
+           }
 
-      virtual void set_refinement_cycle (const unsigned int cycle);
+                                      // Now we have looped over all
+                                      // cells and vertices, so check
+                                      // whether the point was found:
+      AssertThrow (evaluation_point_hits > 0,
+                  ExcEvaluationPointNotFound(evaluation_point));
+
+                                      // We have simply summed up the
+                                      // contributions of all adjacent
+                                      // cells, so we still have to
+                                      // compute the mean value. Once
+                                      // this is done, report the status:
+      point_derivative /= evaluation_point_hits;
+      std::cout << "   Point x-derivative=" << point_derivative
+               << std::endl;
+    }
 
-      virtual void output_solution () const = 0;
-      
-    protected:
-      const SmartPointer<Triangulation<dim> > triangulation;
 
-      unsigned int refinement_cycle;
-  };
 
+                                    // @sect4{The GridOutput class}
 
-  template <int dim>
-  Base<dim>::Base (Triangulation<dim> &coarse_grid)
-                 :
-                 triangulation (&coarse_grid)
-  {}
+                                    // Since this program has a more
+                                    // difficult structure (it computed
+                                    // a dual solution in addition to a
+                                    // primal one), writing out the
+                                    // solution is no more done by an
+                                    // evaluation object since we want
+                                    // to write both solutions at once
+                                    // into one file, and that requires
+                                    // some more information than
+                                    // available to the evaluation
+                                    // classes.
+                                    //
+                                    // However, we also want to look at
+                                    // the grids generated. This again
+                                    // can be done with one such
+                                    // class. Its structure is analog
+                                    // to the <code>SolutionOutput</code> class
+                                    // of the previous example program,
+                                    // so we do not discuss it here in
+                                    // more detail. Furthermore,
+                                    // everything that is used here has
+                                    // already been used in previous
+                                    // example programs.
+    template <int dim>
+    class GridOutput : public EvaluationBase<dim>
+    {
+      public:
+       GridOutput (const std::string &output_name_base);
 
+       virtual void operator () (const DoFHandler<dim> &dof_handler,
+                                 const Vector<double>  &solution) const;
+      private:
+       const std::string output_name_base;
+    };
 
-  template <int dim>
-  Base<dim>::~Base () 
-  {}
 
+    template <int dim>
+    GridOutput<dim>::
+    GridOutput (const std::string &output_name_base)
+                   :
+                   output_name_base (output_name_base)
+    {}
 
 
-  template <int dim>
-  void
-  Base<dim>::set_refinement_cycle (const unsigned int cycle)
-  {
-    refinement_cycle = cycle;
+    template <int dim>
+    void
+    GridOutput<dim>::operator () (const DoFHandler<dim> &dof_handler,
+                                 const Vector<double>  &/*solution*/) const
+    {
+      std::ostringstream filename;
+      filename << output_name_base << "-"
+              << this->refinement_cycle
+              << ".eps"
+              << std::ends;
+
+      std::ofstream out (filename.str().c_str());
+      GridOut().write_eps (dof_handler.get_tria(), out);
+    }
   }
-  
 
-                                  // @sect4{The Laplace Solver class}
 
-                                  // Likewise, the <code>Solver</code> class
-                                  // is entirely unchanged and will
-                                  // thus not be discussed.
-  template <int dim>
-  class Solver : public virtual Base<dim>
-  {
-    public:
-      Solver (Triangulation<dim>       &triangulation,
-             const FiniteElement<dim> &fe,
-             const Quadrature<dim>    &quadrature,
-             const Quadrature<dim-1>  &face_quadrature,              
-             const Function<dim>      &boundary_values);
-      virtual
-      ~Solver ();
-
-      virtual
-      void
-      solve_problem ();
-
-      virtual
-      void
-      postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const;
-
-      virtual
-      unsigned int
-      n_dofs () const;
-      
-    protected:
-      const SmartPointer<const FiniteElement<dim> >  fe;
-      const SmartPointer<const Quadrature<dim> >     quadrature;
-      const SmartPointer<const Quadrature<dim-1> >   face_quadrature;      
-      DoFHandler<dim>                                dof_handler;
-      Vector<double>                                 solution;
-      const SmartPointer<const Function<dim> >       boundary_values;
-
-      virtual void assemble_rhs (Vector<double> &rhs) const = 0;
-    
-    private:
-      struct LinearSystem
-      {
-         LinearSystem (const DoFHandler<dim> &dof_handler);
-
-         void solve (Vector<double> &solution) const;
-       
-         ConstraintMatrix     hanging_node_constraints;
-         SparsityPattern      sparsity_pattern;
-         SparseMatrix<double> matrix;
-         Vector<double>       rhs;
-      };
+                                  // @sect3{The Laplace solver classes}
+
+                                  // Next are the actual solver
+                                  // classes. Again, we discuss only
+                                  // the differences to the previous
+                                  // program.
+  namespace LaplaceSolver
+  {
+                                    // Before everything else,
+                                    // forward-declare one class that
+                                    // we will have later, since we
+                                    // will want to make it a friend of
+                                    // some of the classes that follow,
+                                    // which requires the class to be
+                                    // known:
+    template <int dim> class WeightedResidual;
+
+
+                                    // @sect4{The Laplace solver base class}
+
+                                    // This class is almost unchanged,
+                                    // with the exception that it
+                                    // declares two more functions:
+                                    // <code>output_solution</code> will be used
+                                    // to generate output files from
+                                    // the actual solutions computed by
+                                    // derived classes, and the
+                                    // <code>set_refinement_cycle</code>
+                                    // function by which the testing
+                                    // framework sets the number of the
+                                    // refinement cycle to a local
+                                    // variable in this class; this
+                                    // number is later used to generate
+                                    // filenames for the solution
+                                    // output.
+    template <int dim>
+    class Base
+    {
+      public:
+       Base (Triangulation<dim> &coarse_grid);
+       virtual ~Base ();
 
-      void
-      assemble_linear_system (LinearSystem &linear_system);
+       virtual void solve_problem () = 0;
+       virtual void postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const = 0;
+       virtual void refine_grid () = 0;
+       virtual unsigned int n_dofs () const = 0;
 
-      void
-      assemble_matrix (LinearSystem                                         &linear_system,
-                      const typename DoFHandler<dim>::active_cell_iterator &begin_cell,
-                      const typename DoFHandler<dim>::active_cell_iterator &end_cell,
-                      Threads::ThreadMutex                                 &mutex) const;
-  };
+       virtual void set_refinement_cycle (const unsigned int cycle);
 
+       virtual void output_solution () const = 0;
 
+      protected:
+       const SmartPointer<Triangulation<dim> > triangulation;
 
-  template <int dim>
-  Solver<dim>::Solver (Triangulation<dim>       &triangulation,
-                      const FiniteElement<dim> &fe,
-                      const Quadrature<dim>    &quadrature,
-                      const Quadrature<dim-1>  &face_quadrature,
-                      const Function<dim>      &boundary_values)
-                 :
-                 Base<dim> (triangulation),
-                 fe (&fe),
-                  quadrature (&quadrature),
-                  face_quadrature (&face_quadrature),    
-                 dof_handler (triangulation),
-                 boundary_values (&boundary_values)
-  {}
+       unsigned int refinement_cycle;
+    };
 
 
-  template <int dim>
-  Solver<dim>::~Solver () 
-  {
-    dof_handler.clear ();
-  }
+    template <int dim>
+    Base<dim>::Base (Triangulation<dim> &coarse_grid)
+                   :
+                   triangulation (&coarse_grid)
+    {}
 
 
-  template <int dim>
-  void
-  Solver<dim>::solve_problem ()
-  {
-    dof_handler.distribute_dofs (*fe);
-    solution.reinit (dof_handler.n_dofs());
+    template <int dim>
+    Base<dim>::~Base ()
+    {}
 
-    LinearSystem linear_system (dof_handler);
-    assemble_linear_system (linear_system);
-    linear_system.solve (solution);
-  }
 
 
-  template <int dim>
-  void
-  Solver<dim>::
-  postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const
-  {
-    postprocessor (dof_handler, solution);
-  }
+    template <int dim>
+    void
+    Base<dim>::set_refinement_cycle (const unsigned int cycle)
+    {
+      refinement_cycle = cycle;
+    }
 
 
-  template <int dim>
-  unsigned int
-  Solver<dim>::n_dofs () const
-  {
-    return dof_handler.n_dofs();
-  }
-  
+                                    // @sect4{The Laplace Solver class}
 
-  template <int dim>
-  void
-  Solver<dim>::assemble_linear_system (LinearSystem &linear_system)
-  {
-    typedef
-      typename DoFHandler<dim>::active_cell_iterator
-      active_cell_iterator;
-
-    const unsigned int n_threads = multithread_info.n_default_threads;
-    std::vector<std::pair<active_cell_iterator,active_cell_iterator> >
-      thread_ranges 
-      = Threads::split_range<active_cell_iterator> (dof_handler.begin_active (),
-                                                   dof_handler.end (),
-                                                   n_threads);
-
-    Threads::ThreadMutex mutex;
-    Threads::ThreadGroup<> threads;
-    for (unsigned int thread=0; thread<n_threads; ++thread)
-      threads += Threads::new_thread (&Solver<dim>::assemble_matrix,
-                                     *this,
-                                     linear_system,
-                                     thread_ranges[thread].first,
-                                     thread_ranges[thread].second,
-                                     mutex);
-
-    assemble_rhs (linear_system.rhs);
-    linear_system.hanging_node_constraints.condense (linear_system.rhs);
-
-    std::map<unsigned int,double> boundary_value_map;
-    VectorTools::interpolate_boundary_values (dof_handler,
-                                             0,
-                                             *boundary_values,
-                                             boundary_value_map);
-    
-    threads.join_all ();
-    linear_system.hanging_node_constraints.condense (linear_system.matrix);
-
-    MatrixTools::apply_boundary_values (boundary_value_map,
-                                       linear_system.matrix,
-                                       solution,
-                                       linear_system.rhs);
-  }
+                                    // Likewise, the <code>Solver</code> class
+                                    // is entirely unchanged and will
+                                    // thus not be discussed.
+    template <int dim>
+    class Solver : public virtual Base<dim>
+    {
+      public:
+       Solver (Triangulation<dim>       &triangulation,
+               const FiniteElement<dim> &fe,
+               const Quadrature<dim>    &quadrature,
+               const Quadrature<dim-1>  &face_quadrature,
+               const Function<dim>      &boundary_values);
+       virtual
+       ~Solver ();
+
+       virtual
+       void
+       solve_problem ();
+
+       virtual
+       void
+       postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const;
+
+       virtual
+       unsigned int
+       n_dofs () const;
+
+      protected:
+       const SmartPointer<const FiniteElement<dim> >  fe;
+       const SmartPointer<const Quadrature<dim> >     quadrature;
+       const SmartPointer<const Quadrature<dim-1> >   face_quadrature;
+       DoFHandler<dim>                                dof_handler;
+       Vector<double>                                 solution;
+       const SmartPointer<const Function<dim> >       boundary_values;
+
+       virtual void assemble_rhs (Vector<double> &rhs) const = 0;
+
+      private:
+       struct LinearSystem
+       {
+           LinearSystem (const DoFHandler<dim> &dof_handler);
 
+           void solve (Vector<double> &solution) const;
 
-  template <int dim>
-  void
-  Solver<dim>::assemble_matrix (LinearSystem                                         &linear_system,
-                               const typename DoFHandler<dim>::active_cell_iterator &begin_cell,
-                               const typename DoFHandler<dim>::active_cell_iterator &end_cell,
-                               Threads::ThreadMutex                                 &mutex) const
-  {
-    FEValues<dim> fe_values (*fe, *quadrature, 
-                            update_gradients | update_JxW_values);
+           ConstraintMatrix     hanging_node_constraints;
+           SparsityPattern      sparsity_pattern;
+           SparseMatrix<double> matrix;
+           Vector<double>       rhs;
+       };
+
+       void
+       assemble_linear_system (LinearSystem &linear_system);
 
-    const unsigned int   dofs_per_cell = fe->dofs_per_cell;
-    const unsigned int   n_q_points    = quadrature->size();
+       void
+       assemble_matrix (LinearSystem                                         &linear_system,
+                        const typename DoFHandler<dim>::active_cell_iterator &begin_cell,
+                        const typename DoFHandler<dim>::active_cell_iterator &end_cell,
+                        Threads::ThreadMutex                                 &mutex) const;
+    };
 
-    FullMatrix<double>   cell_matrix (dofs_per_cell, dofs_per_cell);
 
-    std::vector<unsigned int> local_dof_indices (dofs_per_cell);
 
-    for (typename DoFHandler<dim>::active_cell_iterator cell=begin_cell;
-        cell!=end_cell; ++cell)
-      {
-       cell_matrix = 0;
+    template <int dim>
+    Solver<dim>::Solver (Triangulation<dim>       &triangulation,
+                        const FiniteElement<dim> &fe,
+                        const Quadrature<dim>    &quadrature,
+                        const Quadrature<dim-1>  &face_quadrature,
+                        const Function<dim>      &boundary_values)
+                   :
+                   Base<dim> (triangulation),
+                   fe (&fe),
+                   quadrature (&quadrature),
+                   face_quadrature (&face_quadrature),
+                   dof_handler (triangulation),
+                   boundary_values (&boundary_values)
+    {}
+
+
+    template <int dim>
+    Solver<dim>::~Solver ()
+    {
+      dof_handler.clear ();
+    }
+
+
+    template <int dim>
+    void
+    Solver<dim>::solve_problem ()
+    {
+      dof_handler.distribute_dofs (*fe);
+      solution.reinit (dof_handler.n_dofs());
+
+      LinearSystem linear_system (dof_handler);
+      assemble_linear_system (linear_system);
+      linear_system.solve (solution);
+    }
+
+
+    template <int dim>
+    void
+    Solver<dim>::
+    postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const
+    {
+      postprocessor (dof_handler, solution);
+    }
+
+
+    template <int dim>
+    unsigned int
+    Solver<dim>::n_dofs () const
+    {
+      return dof_handler.n_dofs();
+    }
 
-       fe_values.reinit (cell);
 
-       for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
+    template <int dim>
+    void
+    Solver<dim>::assemble_linear_system (LinearSystem &linear_system)
+    {
+      typedef
+       typename DoFHandler<dim>::active_cell_iterator
+       active_cell_iterator;
+
+      const unsigned int n_threads = multithread_info.n_default_threads;
+      std::vector<std::pair<active_cell_iterator,active_cell_iterator> >
+       thread_ranges
+       = Threads::split_range<active_cell_iterator> (dof_handler.begin_active (),
+                                                     dof_handler.end (),
+                                                     n_threads);
+
+      Threads::ThreadMutex mutex;
+      Threads::ThreadGroup<> threads;
+      for (unsigned int thread=0; thread<n_threads; ++thread)
+       threads += Threads::new_thread (&Solver<dim>::assemble_matrix,
+                                       *this,
+                                       linear_system,
+                                       thread_ranges[thread].first,
+                                       thread_ranges[thread].second,
+                                       mutex);
+
+      assemble_rhs (linear_system.rhs);
+      linear_system.hanging_node_constraints.condense (linear_system.rhs);
+
+      std::map<unsigned int,double> boundary_value_map;
+      VectorTools::interpolate_boundary_values (dof_handler,
+                                               0,
+                                               *boundary_values,
+                                               boundary_value_map);
+
+      threads.join_all ();
+      linear_system.hanging_node_constraints.condense (linear_system.matrix);
+
+      MatrixTools::apply_boundary_values (boundary_value_map,
+                                         linear_system.matrix,
+                                         solution,
+                                         linear_system.rhs);
+    }
+
+
+    template <int dim>
+    void
+    Solver<dim>::assemble_matrix (LinearSystem                                         &linear_system,
+                                 const typename DoFHandler<dim>::active_cell_iterator &begin_cell,
+                                 const typename DoFHandler<dim>::active_cell_iterator &end_cell,
+                                 Threads::ThreadMutex                                 &mutex) const
+    {
+      FEValues<dim> fe_values (*fe, *quadrature,
+                              update_gradients | update_JxW_values);
+
+      const unsigned int   dofs_per_cell = fe->dofs_per_cell;
+      const unsigned int   n_q_points    = quadrature->size();
+
+      FullMatrix<double>   cell_matrix (dofs_per_cell, dofs_per_cell);
+
+      std::vector<unsigned int> local_dof_indices (dofs_per_cell);
+
+      for (typename DoFHandler<dim>::active_cell_iterator cell=begin_cell;
+          cell!=end_cell; ++cell)
+       {
+         cell_matrix = 0;
+
+         fe_values.reinit (cell);
+
+         for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
+           for (unsigned int i=0; i<dofs_per_cell; ++i)
+             for (unsigned int j=0; j<dofs_per_cell; ++j)
+               cell_matrix(i,j) += (fe_values.shape_grad(i,q_point) *
+                                    fe_values.shape_grad(j,q_point) *
+                                    fe_values.JxW(q_point));
+
+
+         cell->get_dof_indices (local_dof_indices);
+         Threads::ThreadMutex::ScopedLock lock (mutex);
          for (unsigned int i=0; i<dofs_per_cell; ++i)
            for (unsigned int j=0; j<dofs_per_cell; ++j)
-             cell_matrix(i,j) += (fe_values.shape_grad(i,q_point) *
-                                  fe_values.shape_grad(j,q_point) *
-                                  fe_values.JxW(q_point));
-
-
-       cell->get_dof_indices (local_dof_indices);
-       Threads::ThreadMutex::ScopedLock lock (mutex);
-       for (unsigned int i=0; i<dofs_per_cell; ++i)
-         for (unsigned int j=0; j<dofs_per_cell; ++j)
-           linear_system.matrix.add (local_dof_indices[i],
-                                     local_dof_indices[j],
-                                     cell_matrix(i,j));
-      }
-  }
+             linear_system.matrix.add (local_dof_indices[i],
+                                       local_dof_indices[j],
+                                       cell_matrix(i,j));
+       }
+    }
 
 
-  template <int dim>
-  Solver<dim>::LinearSystem::
-  LinearSystem (const DoFHandler<dim> &dof_handler)
-  {
-    hanging_node_constraints.clear ();
-
-    void (*mhnc_p) (const DoFHandler<dim> &,
-                   ConstraintMatrix      &)
-      = &DoFTools::make_hanging_node_constraints;
-    
-    Threads::Thread<>
-      mhnc_thread = Threads::new_thread (mhnc_p,
-                                        dof_handler,
-                                        hanging_node_constraints);
-
-    sparsity_pattern.reinit (dof_handler.n_dofs(),
-                            dof_handler.n_dofs(),
-                            dof_handler.max_couplings_between_dofs());
-    DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
-
-    mhnc_thread.join ();
-    hanging_node_constraints.close ();
-    hanging_node_constraints.condense (sparsity_pattern);
-
-    sparsity_pattern.compress();
-    matrix.reinit (sparsity_pattern);
-    rhs.reinit (dof_handler.n_dofs());
-  }
+    template <int dim>
+    Solver<dim>::LinearSystem::
+    LinearSystem (const DoFHandler<dim> &dof_handler)
+    {
+      hanging_node_constraints.clear ();
 
+      void (*mhnc_p) (const DoFHandler<dim> &,
+                     ConstraintMatrix      &)
+       = &DoFTools::make_hanging_node_constraints;
 
+      Threads::Thread<>
+       mhnc_thread = Threads::new_thread (mhnc_p,
+                                          dof_handler,
+                                          hanging_node_constraints);
 
-  template <int dim>
-  void
-  Solver<dim>::LinearSystem::solve (Vector<double> &solution) const
-  {
-    SolverControl           solver_control (5000, 1e-12);
-    SolverCG<>              cg (solver_control);
+      sparsity_pattern.reinit (dof_handler.n_dofs(),
+                              dof_handler.n_dofs(),
+                              dof_handler.max_couplings_between_dofs());
+      DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
 
-    PreconditionSSOR<> preconditioner;
-    preconditioner.initialize(matrix, 1.2);
+      mhnc_thread.join ();
+      hanging_node_constraints.close ();
+      hanging_node_constraints.condense (sparsity_pattern);
 
-    cg.solve (matrix, solution, rhs, preconditioner);
+      sparsity_pattern.compress();
+      matrix.reinit (sparsity_pattern);
+      rhs.reinit (dof_handler.n_dofs());
+    }
 
-    hanging_node_constraints.distribute (solution);
-  }
 
 
+    template <int dim>
+    void
+    Solver<dim>::LinearSystem::solve (Vector<double> &solution) const
+    {
+      SolverControl           solver_control (5000, 1e-12);
+      SolverCG<>              cg (solver_control);
 
+      PreconditionSSOR<> preconditioner;
+      preconditioner.initialize(matrix, 1.2);
 
-                                  // @sect4{The PrimalSolver class}
-
-                                  // The <code>PrimalSolver</code> class is
-                                  // also mostly unchanged except for
-                                  // overloading the functions
-                                  // <code>solve_problem</code>, <code>n_dofs</code>,
-                                  // and <code>postprocess</code> of the base
-                                  // class, and implementing the
-                                  // <code>output_solution</code>
-                                  // function. These overloaded
-                                  // functions do nothing particular
-                                  // besides calling the functions of
-                                  // the base class -- that seems
-                                  // superfluous, but works around a
-                                  // bug in a popular compiler which
-                                  // requires us to write such
-                                  // functions for the following
-                                  // scenario: Besides the
-                                  // <code>PrimalSolver</code> class, we will
-                                  // have a <code>DualSolver</code>, both
-                                  // derived from <code>Solver</code>. We will
-                                  // then have a final classes which
-                                  // derived from these two, which
-                                  // will then have two instances of
-                                  // the <code>Solver</code> class as its base
-                                  // classes. If we want, for
-                                  // example, the number of degrees
-                                  // of freedom of the primal solver,
-                                  // we would have to indicate this
-                                  // like so:
-                                  // <code>PrimalSolver::n_dofs()</code>.
-                                  // However, the compiler does not
-                                  // accept this since the <code>n_dofs</code>
-                                  // function is actually from a base
-                                  // class of the <code>PrimalSolver</code>
-                                  // class, so we have to inject the
-                                  // name from the base to the
-                                  // derived class using these
-                                  // additional functions.
-                                  //
-                                  // Regarding the implementation of
-                                  // the <code>output_solution</code>
-                                  // function, we keep the
-                                  // <code>GlobalRefinement</code> and
-                                  // <code>RefinementKelly</code> classes in
-                                  // this program, and they can then
-                                  // rely on the default
-                                  // implementation of this function
-                                  // which simply outputs the primal
-                                  // solution. The class implementing
-                                  // dual weighted error estimators
-                                  // will overload this function
-                                  // itself, to also output the dual
-                                  // solution.
-                                  //
-                                  // Except for this, the class is
-                                  // unchanged with respect to the
-                                  // previous example.
-  template <int dim>
-  class PrimalSolver : public Solver<dim>
-  {
-    public:
-      PrimalSolver (Triangulation<dim>       &triangulation,
-                   const FiniteElement<dim> &fe,
-                   const Quadrature<dim>    &quadrature,
-                   const Quadrature<dim-1>  &face_quadrature,
-                   const Function<dim>      &rhs_function,
-                   const Function<dim>      &boundary_values);
-
-      virtual
-      void solve_problem ();
-      
-      virtual
-      unsigned int n_dofs () const;
-      
-      virtual
-      void postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const;
-
-      virtual
-      void output_solution () const;
-      
-    protected:
-      const SmartPointer<const Function<dim> > rhs_function;
-      virtual void assemble_rhs (Vector<double> &rhs) const;
-
-                                      // Now, in order to work around
-                                      // some problems in one of the
-                                      // compilers this library can
-                                      // be compiled with, we will
-                                      // have to declare a
-                                      // class that is actually
-                                      // derived from the present
-                                      // one, as a friend (strange as
-                                      // that seems). The full
-                                      // rationale will be explained
-                                      // below.
-      friend class WeightedResidual<dim>;
-  };
+      cg.solve (matrix, solution, rhs, preconditioner);
 
+      hanging_node_constraints.distribute (solution);
+    }
 
-  template <int dim>
-  PrimalSolver<dim>::
-  PrimalSolver (Triangulation<dim>       &triangulation,
-               const FiniteElement<dim> &fe,
-               const Quadrature<dim>    &quadrature,
-               const Quadrature<dim-1>  &face_quadrature,
-               const Function<dim>      &rhs_function,
-               const Function<dim>      &boundary_values)
-                 :
-                 Base<dim> (triangulation),
-                 Solver<dim> (triangulation, fe,
-                              quadrature, face_quadrature,
-                              boundary_values),
-                  rhs_function (&rhs_function)
-  {}
 
 
-  template <int dim>
-  void
-  PrimalSolver<dim>::solve_problem ()
-  {
-    Solver<dim>::solve_problem ();
-  }
 
+                                    // @sect4{The PrimalSolver class}
+
+                                    // The <code>PrimalSolver</code> class is
+                                    // also mostly unchanged except for
+                                    // overloading the functions
+                                    // <code>solve_problem</code>, <code>n_dofs</code>,
+                                    // and <code>postprocess</code> of the base
+                                    // class, and implementing the
+                                    // <code>output_solution</code>
+                                    // function. These overloaded
+                                    // functions do nothing particular
+                                    // besides calling the functions of
+                                    // the base class -- that seems
+                                    // superfluous, but works around a
+                                    // bug in a popular compiler which
+                                    // requires us to write such
+                                    // functions for the following
+                                    // scenario: Besides the
+                                    // <code>PrimalSolver</code> class, we will
+                                    // have a <code>DualSolver</code>, both
+                                    // derived from <code>Solver</code>. We will
+                                    // then have a final classes which
+                                    // derived from these two, which
+                                    // will then have two instances of
+                                    // the <code>Solver</code> class as its base
+                                    // classes. If we want, for
+                                    // example, the number of degrees
+                                    // of freedom of the primal solver,
+                                    // we would have to indicate this
+                                    // like so:
+                                    // <code>PrimalSolver::n_dofs()</code>.
+                                    // However, the compiler does not
+                                    // accept this since the <code>n_dofs</code>
+                                    // function is actually from a base
+                                    // class of the <code>PrimalSolver</code>
+                                    // class, so we have to inject the
+                                    // name from the base to the
+                                    // derived class using these
+                                    // additional functions.
+                                    //
+                                    // Regarding the implementation of
+                                    // the <code>output_solution</code>
+                                    // function, we keep the
+                                    // <code>GlobalRefinement</code> and
+                                    // <code>RefinementKelly</code> classes in
+                                    // this program, and they can then
+                                    // rely on the default
+                                    // implementation of this function
+                                    // which simply outputs the primal
+                                    // solution. The class implementing
+                                    // dual weighted error estimators
+                                    // will overload this function
+                                    // itself, to also output the dual
+                                    // solution.
+                                    //
+                                    // Except for this, the class is
+                                    // unchanged with respect to the
+                                    // previous example.
+    template <int dim>
+    class PrimalSolver : public Solver<dim>
+    {
+      public:
+       PrimalSolver (Triangulation<dim>       &triangulation,
+                     const FiniteElement<dim> &fe,
+                     const Quadrature<dim>    &quadrature,
+                     const Quadrature<dim-1>  &face_quadrature,
+                     const Function<dim>      &rhs_function,
+                     const Function<dim>      &boundary_values);
+
+       virtual
+       void solve_problem ();
+
+       virtual
+       unsigned int n_dofs () const;
+
+       virtual
+       void postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const;
+
+       virtual
+       void output_solution () const;
+
+      protected:
+       const SmartPointer<const Function<dim> > rhs_function;
+       virtual void assemble_rhs (Vector<double> &rhs) const;
+
+                                        // Now, in order to work around
+                                        // some problems in one of the
+                                        // compilers this library can
+                                        // be compiled with, we will
+                                        // have to declare a
+                                        // class that is actually
+                                        // derived from the present
+                                        // one, as a friend (strange as
+                                        // that seems). The full
+                                        // rationale will be explained
+                                        // below.
+       friend class WeightedResidual<dim>;
+    };
 
 
-  template <int dim>
-  unsigned int
-  PrimalSolver<dim>::n_dofs() const
-  {
-    return Solver<dim>::n_dofs();
-  }
+    template <int dim>
+    PrimalSolver<dim>::
+    PrimalSolver (Triangulation<dim>       &triangulation,
+                 const FiniteElement<dim> &fe,
+                 const Quadrature<dim>    &quadrature,
+                 const Quadrature<dim-1>  &face_quadrature,
+                 const Function<dim>      &rhs_function,
+                 const Function<dim>      &boundary_values)
+                   :
+                   Base<dim> (triangulation),
+                   Solver<dim> (triangulation, fe,
+                                quadrature, face_quadrature,
+                                boundary_values),
+                   rhs_function (&rhs_function)
+    {}
+
+
+    template <int dim>
+    void
+    PrimalSolver<dim>::solve_problem ()
+    {
+      Solver<dim>::solve_problem ();
+    }
 
 
-  template <int dim>
-  void
-  PrimalSolver<dim>::
-  postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const
-  {
-    Solver<dim>::postprocess(postprocessor);
-  }
 
+    template <int dim>
+    unsigned int
+    PrimalSolver<dim>::n_dofs() const
+    {
+      return Solver<dim>::n_dofs();
+    }
 
-  template <int dim>
-  void
-  PrimalSolver<dim>::output_solution () const
-  {
-    DataOut<dim> data_out;
-    data_out.attach_dof_handler (this->dof_handler);
-    data_out.add_data_vector (this->solution, "solution");
-    data_out.build_patches ();
-
-    std::ostringstream filename;
-    filename << "solution-"
-            << this->refinement_cycle
-            << ".gnuplot"
-            << std::ends;
-    
-    std::ofstream out (filename.str().c_str());
-    data_out.write (out, DataOut<dim>::gnuplot);
-  }
-  
 
+    template <int dim>
+    void
+    PrimalSolver<dim>::
+    postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const
+    {
+      Solver<dim>::postprocess(postprocessor);
+    }
 
-  template <int dim>
-  void
-  PrimalSolver<dim>::
-  assemble_rhs (Vector<double> &rhs) const 
-  {
-    FEValues<dim> fe_values (*this->fe, *this->quadrature, 
-                            update_values  | update_quadrature_points  |
-                             update_JxW_values);
 
-    const unsigned int   dofs_per_cell = this->fe->dofs_per_cell;
-    const unsigned int   n_q_points    = this->quadrature->size();
+    template <int dim>
+    void
+    PrimalSolver<dim>::output_solution () const
+    {
+      DataOut<dim> data_out;
+      data_out.attach_dof_handler (this->dof_handler);
+      data_out.add_data_vector (this->solution, "solution");
+      data_out.build_patches ();
+
+      std::ostringstream filename;
+      filename << "solution-"
+              << this->refinement_cycle
+              << ".gnuplot"
+              << std::ends;
+
+      std::ofstream out (filename.str().c_str());
+      data_out.write (out, DataOut<dim>::gnuplot);
+    }
 
-    Vector<double>       cell_rhs (dofs_per_cell);
-    std::vector<double>  rhs_values (n_q_points);
-    std::vector<unsigned int> local_dof_indices (dofs_per_cell);
 
-    typename DoFHandler<dim>::active_cell_iterator
-      cell = this->dof_handler.begin_active(),
-      endc = this->dof_handler.end();
-    for (; cell!=endc; ++cell)
-      {
-       cell_rhs = 0;
 
-       fe_values.reinit (cell);
+    template <int dim>
+    void
+    PrimalSolver<dim>::
+    assemble_rhs (Vector<double> &rhs) const
+    {
+      FEValues<dim> fe_values (*this->fe, *this->quadrature,
+                              update_values  | update_quadrature_points  |
+                              update_JxW_values);
+
+      const unsigned int   dofs_per_cell = this->fe->dofs_per_cell;
+      const unsigned int   n_q_points    = this->quadrature->size();
+
+      Vector<double>       cell_rhs (dofs_per_cell);
+      std::vector<double>  rhs_values (n_q_points);
+      std::vector<unsigned int> local_dof_indices (dofs_per_cell);
+
+      typename DoFHandler<dim>::active_cell_iterator
+       cell = this->dof_handler.begin_active(),
+       endc = this->dof_handler.end();
+      for (; cell!=endc; ++cell)
+       {
+         cell_rhs = 0;
+
+         fe_values.reinit (cell);
+
+         rhs_function->value_list (fe_values.get_quadrature_points(),
+                                   rhs_values);
+
+         for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
+           for (unsigned int i=0; i<dofs_per_cell; ++i)
+             cell_rhs(i) += (fe_values.shape_value(i,q_point) *
+                             rhs_values[q_point] *
+                             fe_values.JxW(q_point));
 
-       rhs_function->value_list (fe_values.get_quadrature_points(),
-                                 rhs_values);
-      
-       for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
+         cell->get_dof_indices (local_dof_indices);
          for (unsigned int i=0; i<dofs_per_cell; ++i)
-           cell_rhs(i) += (fe_values.shape_value(i,q_point) *
-                           rhs_values[q_point] *
-                           fe_values.JxW(q_point));
+           rhs(local_dof_indices[i]) += cell_rhs(i);
+       }
+    }
 
-       cell->get_dof_indices (local_dof_indices);
-       for (unsigned int i=0; i<dofs_per_cell; ++i)
-         rhs(local_dof_indices[i]) += cell_rhs(i);
-      }
-  }
 
+                                    // @sect4{The RefinementGlobal and RefinementKelly classes}
 
-                                  // @sect4{The RefinementGlobal and RefinementKelly classes}
+                                    // For the following two classes,
+                                    // the same applies as for most of
+                                    // the above: the class is taken
+                                    // from the previous example as-is:
+    template <int dim>
+    class RefinementGlobal : public PrimalSolver<dim>
+    {
+      public:
+       RefinementGlobal (Triangulation<dim>       &coarse_grid,
+                         const FiniteElement<dim> &fe,
+                         const Quadrature<dim>    &quadrature,
+                         const Quadrature<dim-1>  &face_quadrature,
+                         const Function<dim>      &rhs_function,
+                         const Function<dim>      &boundary_values);
+
+       virtual void refine_grid ();
+    };
 
-                                  // For the following two classes,
-                                  // the same applies as for most of
-                                  // the above: the class is taken
-                                  // from the previous example as-is:
-  template <int dim>
-  class RefinementGlobal : public PrimalSolver<dim>
-  {
-    public:
-      RefinementGlobal (Triangulation<dim>       &coarse_grid,
-                       const FiniteElement<dim> &fe,
-                       const Quadrature<dim>    &quadrature,
-                       const Quadrature<dim-1>  &face_quadrature,
-                       const Function<dim>      &rhs_function,
-                       const Function<dim>      &boundary_values);
-
-      virtual void refine_grid ();
-  };
 
 
+    template <int dim>
+    RefinementGlobal<dim>::
+    RefinementGlobal (Triangulation<dim>       &coarse_grid,
+                     const FiniteElement<dim> &fe,
+                     const Quadrature<dim>    &quadrature,
+                     const Quadrature<dim-1>  &face_quadrature,
+                     const Function<dim>      &rhs_function,
+                     const Function<dim>      &boundary_values)
+                   :
+                   Base<dim> (coarse_grid),
+                   PrimalSolver<dim> (coarse_grid, fe, quadrature,
+                                      face_quadrature, rhs_function,
+                                      boundary_values)
+    {}
 
-  template <int dim>
-  RefinementGlobal<dim>::
-  RefinementGlobal (Triangulation<dim>       &coarse_grid,
-                   const FiniteElement<dim> &fe,
-                   const Quadrature<dim>    &quadrature,
-                   const Quadrature<dim-1>  &face_quadrature,
-                   const Function<dim>      &rhs_function,
-                   const Function<dim>      &boundary_values)
-                 :
-                 Base<dim> (coarse_grid),
-                  PrimalSolver<dim> (coarse_grid, fe, quadrature,
-                                    face_quadrature, rhs_function,
-                                    boundary_values)
-  {}
 
 
+    template <int dim>
+    void
+    RefinementGlobal<dim>::refine_grid ()
+    {
+      this->triangulation->refine_global (1);
+    }
 
-  template <int dim>
-  void
-  RefinementGlobal<dim>::refine_grid ()
-  {
-    this->triangulation->refine_global (1);
-  }
 
 
+    template <int dim>
+    class RefinementKelly : public PrimalSolver<dim>
+    {
+      public:
+       RefinementKelly (Triangulation<dim>       &coarse_grid,
+                        const FiniteElement<dim> &fe,
+                        const Quadrature<dim>    &quadrature,
+                        const Quadrature<dim-1>  &face_quadrature,
+                        const Function<dim>      &rhs_function,
+                        const Function<dim>      &boundary_values);
+
+       virtual void refine_grid ();
+    };
 
-  template <int dim>
-  class RefinementKelly : public PrimalSolver<dim>
-  {
-    public:
-      RefinementKelly (Triangulation<dim>       &coarse_grid,
-                      const FiniteElement<dim> &fe,
-                      const Quadrature<dim>    &quadrature,
-                      const Quadrature<dim-1>  &face_quadrature,
-                      const Function<dim>      &rhs_function,
-                      const Function<dim>      &boundary_values);
-
-      virtual void refine_grid ();
-  };
 
 
+    template <int dim>
+    RefinementKelly<dim>::
+    RefinementKelly (Triangulation<dim>       &coarse_grid,
+                    const FiniteElement<dim> &fe,
+                    const Quadrature<dim>    &quadrature,
+                    const Quadrature<dim-1>  &face_quadrature,
+                    const Function<dim>      &rhs_function,
+                    const Function<dim>      &boundary_values)
+                   :
+                   Base<dim> (coarse_grid),
+                   PrimalSolver<dim> (coarse_grid, fe, quadrature,
+                                      face_quadrature,
+                                      rhs_function, boundary_values)
+    {}
 
-  template <int dim>
-  RefinementKelly<dim>::
-  RefinementKelly (Triangulation<dim>       &coarse_grid,
-                  const FiniteElement<dim> &fe,
-                  const Quadrature<dim>    &quadrature,
-                  const Quadrature<dim-1>  &face_quadrature,
-                  const Function<dim>      &rhs_function,
-                  const Function<dim>      &boundary_values)
-                 :
-                 Base<dim> (coarse_grid),
-                  PrimalSolver<dim> (coarse_grid, fe, quadrature,
-                                    face_quadrature,
-                                    rhs_function, boundary_values)
-  {}
+
+
+    template <int dim>
+    void
+    RefinementKelly<dim>::refine_grid ()
+    {
+      Vector<float> estimated_error_per_cell (this->triangulation->n_active_cells());
+      KellyErrorEstimator<dim>::estimate (this->dof_handler,
+                                         QGauss<dim-1>(3),
+                                         typename FunctionMap<dim>::type(),
+                                         this->solution,
+                                         estimated_error_per_cell);
+      GridRefinement::refine_and_coarsen_fixed_number (*this->triangulation,
+                                                      estimated_error_per_cell,
+                                                      0.3, 0.03);
+      this->triangulation->execute_coarsening_and_refinement ();
+    }
 
 
 
-  template <int dim>
-  void
-  RefinementKelly<dim>::refine_grid ()
-  {
-    Vector<float> estimated_error_per_cell (this->triangulation->n_active_cells());
-    KellyErrorEstimator<dim>::estimate (this->dof_handler,
-                                       QGauss<dim-1>(3),
-                                       typename FunctionMap<dim>::type(),
-                                       this->solution,
-                                       estimated_error_per_cell);
-    GridRefinement::refine_and_coarsen_fixed_number (*this->triangulation,
-                                                    estimated_error_per_cell,
-                                                    0.3, 0.03);
-    this->triangulation->execute_coarsening_and_refinement ();
+                                    // @sect4{The RefinementWeightedKelly class}
+
+                                    // This class is a variant of the
+                                    // previous one, in that it allows
+                                    // to weight the refinement
+                                    // indicators we get from the
+                                    // library's Kelly indicator by
+                                    // some function. We include this
+                                    // class since the goal of this
+                                    // example program is to
+                                    // demonstrate automatic refinement
+                                    // criteria even for complex output
+                                    // quantities such as point values
+                                    // or stresses. If we did not solve
+                                    // a dual problem and compute the
+                                    // weights thereof, we would
+                                    // probably be tempted to give a
+                                    // hand-crafted weighting to the
+                                    // indicators to account for the
+                                    // fact that we are going to
+                                    // evaluate these quantities. This
+                                    // class accepts such a weighting
+                                    // function as argument to its
+                                    // constructor:
+    template <int dim>
+    class RefinementWeightedKelly : public PrimalSolver<dim>
+    {
+      public:
+       RefinementWeightedKelly (Triangulation<dim>       &coarse_grid,
+                                const FiniteElement<dim> &fe,
+                                const Quadrature<dim>    &quadrature,
+                                const Quadrature<dim-1>  &face_quadrature,
+                                const Function<dim>      &rhs_function,
+                                const Function<dim>      &boundary_values,
+                                const Function<dim>      &weighting_function);
+
+       virtual void refine_grid ();
+
+      private:
+       const SmartPointer<const Function<dim> > weighting_function;
+    };
+
+
+
+    template <int dim>
+    RefinementWeightedKelly<dim>::
+    RefinementWeightedKelly (Triangulation<dim>       &coarse_grid,
+                            const FiniteElement<dim> &fe,
+                            const Quadrature<dim>    &quadrature,
+                            const Quadrature<dim-1>  &face_quadrature,
+                            const Function<dim>      &rhs_function,
+                            const Function<dim>      &boundary_values,
+                            const Function<dim>      &weighting_function)
+                   :
+                   Base<dim> (coarse_grid),
+                   PrimalSolver<dim> (coarse_grid, fe, quadrature,
+                                      face_quadrature,
+                                      rhs_function, boundary_values),
+                   weighting_function (&weighting_function)
+    {}
+
+
+
+                                    // Now, here comes the main
+                                    // function, including the
+                                    // weighting:
+    template <int dim>
+    void
+    RefinementWeightedKelly<dim>::refine_grid ()
+    {
+                                      // First compute some residual
+                                      // based error indicators for all
+                                      // cells by a method already
+                                      // implemented in the
+                                      // library. What exactly is
+                                      // computed can be read in the
+                                      // documentation of that class.
+      Vector<float> estimated_error (this->triangulation->n_active_cells());
+      KellyErrorEstimator<dim>::estimate (this->dof_handler,
+                                         *this->face_quadrature,
+                                         typename FunctionMap<dim>::type(),
+                                         this->solution,
+                                         estimated_error);
+
+                                      // Now we are going to weight
+                                      // these indicators by the value
+                                      // of the function given to the
+                                      // constructor:
+      typename DoFHandler<dim>::active_cell_iterator
+       cell = this->dof_handler.begin_active(),
+       endc = this->dof_handler.end();
+      for (unsigned int cell_index=0; cell!=endc; ++cell, ++cell_index)
+       estimated_error(cell_index)
+         *= weighting_function->value (cell->center());
+
+      GridRefinement::refine_and_coarsen_fixed_number (*this->triangulation,
+                                                      estimated_error,
+                                                      0.3, 0.03);
+      this->triangulation->execute_coarsening_and_refinement ();
+    }
+
   }
 
 
+                                  // @sect3{Equation data}
+                                  //
+                                  // In this example program, we work
+                                  // with the same data sets as in the
+                                  // previous one, but as it may so
+                                  // happen that someone wants to run
+                                  // the program with different
+                                  // boundary values and right hand side
+                                  // functions, or on a different grid,
+                                  // we show a simple technique to do
+                                  // exactly that. For more clarity, we
+                                  // furthermore pack everything that
+                                  // has to do with equation data into
+                                  // a namespace of its own.
+                                  //
+                                  // The underlying assumption is that
+                                  // this is a research program, and
+                                  // that there we often have a number
+                                  // of test cases that consist of a
+                                  // domain, a right hand side,
+                                  // boundary values, possibly a
+                                  // specified coefficient, and a
+                                  // number of other parameters. They
+                                  // often vary all at the same time
+                                  // when shifting from one example to
+                                  // another. To make handling such
+                                  // sets of problem description
+                                  // parameters simple is the goal of
+                                  // the following.
+                                  //
+                                  // Basically, the idea is this: let
+                                  // us have a structure for each set
+                                  // of data, in which we pack
+                                  // everything that describes a test
+                                  // case: here, these are two
+                                  // subclasses, one called
+                                  // <code>BoundaryValues</code> for the
+                                  // boundary values of the exact
+                                  // solution, and one called
+                                  // <code>RightHandSide</code>, and then a way
+                                  // to generate the coarse grid. Since
+                                  // the solution of the previous
+                                  // example program looked like curved
+                                  // ridges, we use this name here for
+                                  // the enclosing class. Note that the
+                                  // names of the two inner classes
+                                  // have to be the same for all
+                                  // enclosing test case classes, and
+                                  // also that we have attached the
+                                  // dimension template argument to the
+                                  // enclosing class rather than to the
+                                  // inner ones, to make further
+                                  // processing simpler.  (From a
+                                  // language viewpoint, a namespace
+                                  // would be better to encapsulate
+                                  // these inner classes, rather than a
+                                  // structure. However, namespaces
+                                  // cannot be given as template
+                                  // arguments, so we use a structure
+                                  // to allow a second object to select
+                                  // from within its given
+                                  // argument. The enclosing structure,
+                                  // of course, has no member variables
+                                  // apart from the classes it
+                                  // declares, and a static function to
+                                  // generate the coarse mesh; it will
+                                  // in general never be instantiated.)
+                                  //
+                                  // The idea is then the following
+                                  // (this is the right time to also
+                                  // take a brief look at the code
+                                  // below): we can generate objects
+                                  // for boundary values and
+                                  // right hand side by simply giving
+                                  // the name of the outer class as a
+                                  // template argument to a class which
+                                  // we call here <code>Data::SetUp</code>, and
+                                  // it then creates objects for the
+                                  // inner classes. In this case, to
+                                  // get all that characterizes the
+                                  // curved ridge solution, we would
+                                  // simply generate an instance of
+                                  // <code>Data::SetUp@<Data::CurvedRidge@></code>,
+                                  // and everything we need to know
+                                  // about the solution would be static
+                                  // member variables and functions of
+                                  // that object.
+                                  //
+                                  // This approach might seem like
+                                  // overkill in this case, but will
+                                  // become very handy once a certain
+                                  // set up is not only characterized
+                                  // by Dirichlet boundary values and a
+                                  // right hand side function, but in
+                                  // addition by material properties,
+                                  // Neumann values, different boundary
+                                  // descriptors, etc. In that case,
+                                  // the <code>SetUp</code> class might consist
+                                  // of a dozen or more objects, and
+                                  // each descriptor class (like the
+                                  // <code>CurvedRidges</code> class below)
+                                  // would have to provide them. Then,
+                                  // you will be happy to be able to
+                                  // change from one set of data to
+                                  // another by only changing the
+                                  // template argument to the <code>SetUp</code>
+                                  // class at one place, rather than at
+                                  // many.
+                                  //
+                                  // With this framework for different
+                                  // test cases, we are almost
+                                  // finished, but one thing remains:
+                                  // by now we can select statically,
+                                  // by changing one template argument,
+                                  // which data set to choose. In order
+                                  // to be able to do that dynamically,
+                                  // i.e. at run time, we need a base
+                                  // class. This we provide in the
+                                  // obvious way, see below, with
+                                  // virtual abstract functions. It
+                                  // forces us to introduce a second
+                                  // template parameter <code>dim</code> which
+                                  // we need for the base class (which
+                                  // could be avoided using some
+                                  // template magic, but we omit that),
+                                  // but that's all.
+                                  //
+                                  // Adding new testcases is now
+                                  // simple, you don't have to touch
+                                  // the framework classes, only a
+                                  // structure like the
+                                  // <code>CurvedRidges</code> one is needed.
+  namespace Data
+  {
+                                    // @sect4{The SetUpBase and SetUp classes}
+
+                                    // Based on the above description,
+                                    // the <code>SetUpBase</code> class then
+                                    // looks as follows. To allow using
+                                    // the <code>SmartPointer</code> class with
+                                    // this class, we derived from the
+                                    // <code>Subscriptor</code> class.
+    template <int dim>
+    struct SetUpBase : public Subscriptor
+    {
+       virtual
+       const Function<dim> &  get_boundary_values () const = 0;
 
-                                  // @sect4{The RefinementWeightedKelly class}
-
-                                  // This class is a variant of the
-                                  // previous one, in that it allows
-                                  // to weight the refinement
-                                  // indicators we get from the
-                                  // library's Kelly indicator by
-                                  // some function. We include this
-                                  // class since the goal of this
-                                  // example program is to
-                                  // demonstrate automatic refinement
-                                  // criteria even for complex output
-                                  // quantities such as point values
-                                  // or stresses. If we did not solve
-                                  // a dual problem and compute the
-                                  // weights thereof, we would
-                                  // probably be tempted to give a
-                                  // hand-crafted weighting to the
-                                  // indicators to account for the
-                                  // fact that we are going to
-                                  // evaluate these quantities. This
-                                  // class accepts such a weighting
-                                  // function as argument to its
-                                  // constructor:
-  template <int dim>
-  class RefinementWeightedKelly : public PrimalSolver<dim>
-  {
-    public:
-      RefinementWeightedKelly (Triangulation<dim>       &coarse_grid,
-                              const FiniteElement<dim> &fe,
-                              const Quadrature<dim>    &quadrature,
-                              const Quadrature<dim-1>  &face_quadrature,
-                              const Function<dim>      &rhs_function,
-                              const Function<dim>      &boundary_values,
-                              const Function<dim>      &weighting_function);
-
-      virtual void refine_grid ();
-
-    private:
-      const SmartPointer<const Function<dim> > weighting_function;
-  };
+       virtual
+       const Function<dim> &  get_right_hand_side () const = 0;
 
+       virtual
+       void create_coarse_grid (Triangulation<dim> &coarse_grid) const = 0;
+    };
 
 
-  template <int dim>
-  RefinementWeightedKelly<dim>::
-  RefinementWeightedKelly (Triangulation<dim>       &coarse_grid,
-                          const FiniteElement<dim> &fe,
-                          const Quadrature<dim>    &quadrature,
-                          const Quadrature<dim-1>  &face_quadrature,
-                          const Function<dim>      &rhs_function,
-                          const Function<dim>      &boundary_values,
-                          const Function<dim>      &weighting_function)
-                 :
-                 Base<dim> (coarse_grid),
-                  PrimalSolver<dim> (coarse_grid, fe, quadrature,
-                                    face_quadrature,
-                                    rhs_function, boundary_values),
-                  weighting_function (&weighting_function)
-  {}
+                                    // And now for the derived class
+                                    // that takes the template argument
+                                    // as explained above. For some
+                                    // reason, C++ requires us to
+                                    // define a constructor (which
+                                    // maybe empty), as otherwise a
+                                    // warning is generated that some
+                                    // data is not initialized.
+                                    //
+                                    // Here we pack the data elements
+                                    // into private variables, and
+                                    // allow access to them through the
+                                    // methods of the base class.
+    template <class Traits, int dim>
+    struct SetUp : public SetUpBase<dim>
+    {
+       SetUp () {}
 
+       virtual
+       const Function<dim> &  get_boundary_values () const;
 
+       virtual
+       const Function<dim> &  get_right_hand_side () const;
 
-                                  // Now, here comes the main
-                                  // function, including the
-                                  // weighting:
-  template <int dim>
-  void
-  RefinementWeightedKelly<dim>::refine_grid ()
-  {
-                                    // First compute some residual
-                                    // based error indicators for all
-                                    // cells by a method already
-                                    // implemented in the
-                                    // library. What exactly is
-                                    // computed can be read in the
-                                    // documentation of that class.
-    Vector<float> estimated_error (this->triangulation->n_active_cells());
-    KellyErrorEstimator<dim>::estimate (this->dof_handler,
-                                       *this->face_quadrature,
-                                       typename FunctionMap<dim>::type(),
-                                       this->solution,
-                                       estimated_error);
-
-                                    // Now we are going to weight
-                                    // these indicators by the value
-                                    // of the function given to the
-                                    // constructor:
-    typename DoFHandler<dim>::active_cell_iterator
-      cell = this->dof_handler.begin_active(),
-      endc = this->dof_handler.end();
-    for (unsigned int cell_index=0; cell!=endc; ++cell, ++cell_index)
-      estimated_error(cell_index)
-       *= weighting_function->value (cell->center());
-    
-    GridRefinement::refine_and_coarsen_fixed_number (*this->triangulation,
-                                                    estimated_error,
-                                                    0.3, 0.03);
-    this->triangulation->execute_coarsening_and_refinement ();
-  }
 
-}
+       virtual
+       void create_coarse_grid (Triangulation<dim> &coarse_grid) const;
 
+      private:
+       static const typename Traits::BoundaryValues boundary_values;
+       static const typename Traits::RightHandSide  right_hand_side;
+    };
 
-                                // @sect3{Equation data}
-                                //
-                                // In this example program, we work
-                                // with the same data sets as in the
-                                // previous one, but as it may so
-                                // happen that someone wants to run
-                                // the program with different
-                                // boundary values and right hand side
-                                // functions, or on a different grid,
-                                // we show a simple technique to do
-                                // exactly that. For more clarity, we
-                                // furthermore pack everything that
-                                // has to do with equation data into
-                                // a namespace of its own.
-                                //
-                                // The underlying assumption is that
-                                // this is a research program, and
-                                // that there we often have a number
-                                // of test cases that consist of a
-                                // domain, a right hand side,
-                                // boundary values, possibly a
-                                // specified coefficient, and a
-                                // number of other parameters. They
-                                // often vary all at the same time
-                                // when shifting from one example to
-                                // another. To make handling such
-                                // sets of problem description
-                                // parameters simple is the goal of
-                                // the following.
-                                //
-                                // Basically, the idea is this: let
-                                // us have a structure for each set
-                                // of data, in which we pack
-                                // everything that describes a test
-                                // case: here, these are two
-                                // subclasses, one called
-                                // <code>BoundaryValues</code> for the
-                                // boundary values of the exact
-                                // solution, and one called
-                                // <code>RightHandSide</code>, and then a way
-                                // to generate the coarse grid. Since
-                                // the solution of the previous
-                                // example program looked like curved
-                                // ridges, we use this name here for
-                                // the enclosing class. Note that the
-                                // names of the two inner classes
-                                // have to be the same for all
-                                // enclosing test case classes, and
-                                // also that we have attached the
-                                // dimension template argument to the
-                                // enclosing class rather than to the
-                                // inner ones, to make further
-                                // processing simpler.  (From a
-                                // language viewpoint, a namespace
-                                // would be better to encapsulate
-                                // these inner classes, rather than a
-                                // structure. However, namespaces
-                                // cannot be given as template
-                                // arguments, so we use a structure
-                                // to allow a second object to select
-                                // from within its given
-                                // argument. The enclosing structure,
-                                // of course, has no member variables
-                                // apart from the classes it
-                                // declares, and a static function to
-                                // generate the coarse mesh; it will
-                                // in general never be instantiated.)
-                                //
-                                // The idea is then the following
-                                // (this is the right time to also
-                                // take a brief look at the code
-                                // below): we can generate objects
-                                // for boundary values and
-                                // right hand side by simply giving
-                                // the name of the outer class as a
-                                // template argument to a class which
-                                // we call here <code>Data::SetUp</code>, and
-                                // it then creates objects for the
-                                // inner classes. In this case, to
-                                // get all that characterizes the
-                                // curved ridge solution, we would
-                                // simply generate an instance of
-                                // <code>Data::SetUp@<Data::CurvedRidge@></code>,
-                                // and everything we need to know
-                                // about the solution would be static
-                                // member variables and functions of
-                                // that object.
-                                //
-                                // This approach might seem like
-                                // overkill in this case, but will
-                                // become very handy once a certain
-                                // set up is not only characterized
-                                // by Dirichlet boundary values and a
-                                // right hand side function, but in
-                                // addition by material properties,
-                                // Neumann values, different boundary
-                                // descriptors, etc. In that case,
-                                // the <code>SetUp</code> class might consist
-                                // of a dozen or more objects, and
-                                // each descriptor class (like the
-                                // <code>CurvedRidges</code> class below)
-                                // would have to provide them. Then,
-                                // you will be happy to be able to
-                                // change from one set of data to
-                                // another by only changing the
-                                // template argument to the <code>SetUp</code>
-                                // class at one place, rather than at
-                                // many.
-                                //
-                                // With this framework for different
-                                // test cases, we are almost
-                                // finished, but one thing remains:
-                                // by now we can select statically,
-                                // by changing one template argument,
-                                // which data set to choose. In order
-                                // to be able to do that dynamically,
-                                // i.e. at run time, we need a base
-                                // class. This we provide in the
-                                // obvious way, see below, with
-                                // virtual abstract functions. It
-                                // forces us to introduce a second
-                                // template parameter <code>dim</code> which
-                                // we need for the base class (which
-                                // could be avoided using some
-                                // template magic, but we omit that),
-                                // but that's all.
-                                //
-                                // Adding new testcases is now
-                                // simple, you don't have to touch
-                                // the framework classes, only a
-                                // structure like the
-                                // <code>CurvedRidges</code> one is needed.
-namespace Data
-{
-                                  // @sect4{The SetUpBase and SetUp classes}
-  
-                                  // Based on the above description,
-                                  // the <code>SetUpBase</code> class then
-                                  // looks as follows. To allow using
-                                  // the <code>SmartPointer</code> class with
-                                  // this class, we derived from the
-                                  // <code>Subscriptor</code> class.
-  template <int dim>
-  struct SetUpBase : public Subscriptor
-  {
-      virtual
-      const Function<dim> &  get_boundary_values () const = 0;
+                                    // We have to provide definitions
+                                    // for the static member variables
+                                    // of the above class:
+    template <class Traits, int dim>
+    const typename Traits::BoundaryValues  SetUp<Traits,dim>::boundary_values;
+    template <class Traits, int dim>
+    const typename Traits::RightHandSide   SetUp<Traits,dim>::right_hand_side;
+
+                                    // And definitions of the member
+                                    // functions:
+    template <class Traits, int dim>
+    const Function<dim> &
+    SetUp<Traits,dim>::get_boundary_values () const
+    {
+      return boundary_values;
+    }
 
-      virtual
-      const Function<dim> &  get_right_hand_side () const = 0;
 
-      virtual
-      void create_coarse_grid (Triangulation<dim> &coarse_grid) const = 0;
-  };
+    template <class Traits, int dim>
+    const Function<dim> &
+    SetUp<Traits,dim>::get_right_hand_side () const
+    {
+      return right_hand_side;
+    }
 
 
-                                  // And now for the derived class
-                                  // that takes the template argument
-                                  // as explained above. For some
-                                  // reason, C++ requires us to
-                                  // define a constructor (which
-                                  // maybe empty), as otherwise a
-                                  // warning is generated that some
-                                  // data is not initialized.
-                                  //
-                                  // Here we pack the data elements
-                                  // into private variables, and
-                                  // allow access to them through the
-                                  // methods of the base class.
-  template <class Traits, int dim>
-  struct SetUp : public SetUpBase<dim>
-  {
-      SetUp () {}
+    template <class Traits, int dim>
+    void
+    SetUp<Traits,dim>::
+    create_coarse_grid (Triangulation<dim> &coarse_grid) const
+    {
+      Traits::create_coarse_grid (coarse_grid);
+    }
 
-      virtual
-      const Function<dim> &  get_boundary_values () const;
 
-      virtual
-      const Function<dim> &  get_right_hand_side () const;
-      
+                                    // @sect4{The CurvedRidges class}
 
-      virtual
-      void create_coarse_grid (Triangulation<dim> &coarse_grid) const;
+                                    // The class that is used to
+                                    // describe the boundary values and
+                                    // right hand side of the <code>curved
+                                    // ridge</code> problem already used in
+                                    // the step-13 example program is
+                                    // then like so:
+    template <int dim>
+    struct CurvedRidges
+    {
+       class BoundaryValues : public Function<dim>
+       {
+         public:
+           BoundaryValues () : Function<dim> () {}
 
-    private:
-      static const typename Traits::BoundaryValues boundary_values;
-      static const typename Traits::RightHandSide  right_hand_side;
-  };
+           virtual double value (const Point<dim>   &p,
+                                 const unsigned int  component) const;
+       };
 
-                                  // We have to provide definitions
-                                  // for the static member variables
-                                  // of the above class:
-  template <class Traits, int dim>
-  const typename Traits::BoundaryValues  SetUp<Traits,dim>::boundary_values;
-  template <class Traits, int dim>
-  const typename Traits::RightHandSide   SetUp<Traits,dim>::right_hand_side;
-
-                                  // And definitions of the member
-                                  // functions:
-  template <class Traits, int dim>
-  const Function<dim> &
-  SetUp<Traits,dim>::get_boundary_values () const 
-  {
-    return boundary_values;
-  }
 
+       class RightHandSide : public Function<dim>
+       {
+         public:
+           RightHandSide () : Function<dim> () {}
 
-  template <class Traits, int dim>
-  const Function<dim> &
-  SetUp<Traits,dim>::get_right_hand_side () const 
-  {
-    return right_hand_side;
-  }
+           virtual double value (const Point<dim>   &p,
+                                 const unsigned int  component) const;
+       };
 
+       static
+       void
+       create_coarse_grid (Triangulation<dim> &coarse_grid);
+    };
 
-  template <class Traits, int dim>
-  void
-  SetUp<Traits,dim>::
-  create_coarse_grid (Triangulation<dim> &coarse_grid) const 
-  {
-    Traits::create_coarse_grid (coarse_grid);
-  }
-  
 
-                                  // @sect4{The CurvedRidges class}
+    template <int dim>
+    double
+    CurvedRidges<dim>::BoundaryValues::
+    value (const Point<dim>   &p,
+          const unsigned int  /*component*/) const
+    {
+      double q = p(0);
+      for (unsigned int i=1; i<dim; ++i)
+       q += std::sin(10*p(i)+5*p(0)*p(0));
+      const double exponential = std::exp(q);
+      return exponential;
+    }
 
-                                  // The class that is used to
-                                  // describe the boundary values and
-                                  // right hand side of the <code>curved
-                                  // ridge</code> problem already used in
-                                  // the step-13 example program is
-                                  // then like so:
-  template <int dim>
-  struct CurvedRidges
-  {
-      class BoundaryValues : public Function<dim>
-      {
-       public:
-         BoundaryValues () : Function<dim> () {}
-         
-         virtual double value (const Point<dim>   &p,
-                               const unsigned int  component) const;
-      };
 
 
-      class RightHandSide : public Function<dim>
-      {
-       public:
-         RightHandSide () : Function<dim> () {}
-         
-         virtual double value (const Point<dim>   &p,
-                               const unsigned int  component) const;
-      };
+    template <int dim>
+    double
+    CurvedRidges<dim>::RightHandSide::value (const Point<dim>   &p,
+                                            const unsigned int  /*component*/) const
+    {
+      double q = p(0);
+      for (unsigned int i=1; i<dim; ++i)
+       q += std::sin(10*p(i)+5*p(0)*p(0));
+      const double u = std::exp(q);
+      double t1 = 1,
+            t2 = 0,
+            t3 = 0;
+      for (unsigned int i=1; i<dim; ++i)
+       {
+         t1 += std::cos(10*p(i)+5*p(0)*p(0)) * 10 * p(0);
+         t2 += 10*std::cos(10*p(i)+5*p(0)*p(0)) -
+               100*std::sin(10*p(i)+5*p(0)*p(0)) * p(0)*p(0);
+         t3 += 100*std::cos(10*p(i)+5*p(0)*p(0))*std::cos(10*p(i)+5*p(0)*p(0)) -
+               100*std::sin(10*p(i)+5*p(0)*p(0));
+       }
+      t1 = t1*t1;
 
-      static
-      void
-      create_coarse_grid (Triangulation<dim> &coarse_grid);
-  };
-  
-    
-  template <int dim>
-  double
-  CurvedRidges<dim>::BoundaryValues::
-  value (const Point<dim>   &p,
-        const unsigned int  /*component*/) const
-  {
-    double q = p(0);
-    for (unsigned int i=1; i<dim; ++i)
-      q += std::sin(10*p(i)+5*p(0)*p(0));
-    const double exponential = std::exp(q);
-    return exponential;
-  }
+      return -u*(t1+t2+t3);
+    }
 
 
+    template <int dim>
+    void
+    CurvedRidges<dim>::
+    create_coarse_grid (Triangulation<dim> &coarse_grid)
+    {
+      GridGenerator::hyper_cube (coarse_grid, -1, 1);
+      coarse_grid.refine_global (2);
+    }
 
-  template <int dim>
-  double
-  CurvedRidges<dim>::RightHandSide::value (const Point<dim>   &p,
-                                          const unsigned int  /*component*/) const
-  {
-    double q = p(0);
-    for (unsigned int i=1; i<dim; ++i)
-      q += std::sin(10*p(i)+5*p(0)*p(0));
-    const double u = std::exp(q);
-    double t1 = 1,
-          t2 = 0,
-          t3 = 0;
-    for (unsigned int i=1; i<dim; ++i)
-      {
-       t1 += std::cos(10*p(i)+5*p(0)*p(0)) * 10 * p(0);
-       t2 += 10*std::cos(10*p(i)+5*p(0)*p(0)) -
-             100*std::sin(10*p(i)+5*p(0)*p(0)) * p(0)*p(0);
-       t3 += 100*std::cos(10*p(i)+5*p(0)*p(0))*std::cos(10*p(i)+5*p(0)*p(0)) -
-             100*std::sin(10*p(i)+5*p(0)*p(0));
-      }
-    t1 = t1*t1;
-    
-    return -u*(t1+t2+t3);
-  }
 
+                                    // @sect4{The Exercise_2_3 class}
+
+                                    // This example program was written
+                                    // while giving practical courses
+                                    // for a lecture on adaptive finite
+                                    // element methods and duality
+                                    // based error estimates. For these
+                                    // courses, we had one exercise,
+                                    // which required to solve the
+                                    // Laplace equation with constant
+                                    // right hand side on a square
+                                    // domain with a square hole in the
+                                    // center, and zero boundary
+                                    // values. Since the implementation
+                                    // of the properties of this
+                                    // problem is so particularly
+                                    // simple here, lets do it. As the
+                                    // number of the exercise was 2.3,
+                                    // we take the liberty to retain
+                                    // this name for the class as well.
+    template <int dim>
+    struct Exercise_2_3
+    {
+                                        // We need a class to denote
+                                        // the boundary values of the
+                                        // problem. In this case, this
+                                        // is simple: it's the zero
+                                        // function, so don't even
+                                        // declare a class, just a
+                                        // typedef:
+       typedef ZeroFunction<dim> BoundaryValues;
+
+                                        // Second, a class that denotes
+                                        // the right hand side. Since
+                                        // they are constant, just
+                                        // subclass the corresponding
+                                        // class of the library and be
+                                        // done:
+       class RightHandSide : public ConstantFunction<dim>
+       {
+         public:
+           RightHandSide () : ConstantFunction<dim> (1.) {}
+       };
 
-  template <int dim>
-  void
-  CurvedRidges<dim>::
-  create_coarse_grid (Triangulation<dim> &coarse_grid)
-  {
-    GridGenerator::hyper_cube (coarse_grid, -1, 1);
-    coarse_grid.refine_global (2);
-  }
-  
-
-                                  // @sect4{The Exercise_2_3 class}
-  
-                                  // This example program was written
-                                  // while giving practical courses
-                                  // for a lecture on adaptive finite
-                                  // element methods and duality
-                                  // based error estimates. For these
-                                  // courses, we had one exercise,
-                                  // which required to solve the
-                                  // Laplace equation with constant
-                                  // right hand side on a square
-                                  // domain with a square hole in the
-                                  // center, and zero boundary
-                                  // values. Since the implementation
-                                  // of the properties of this
-                                  // problem is so particularly
-                                  // simple here, lets do it. As the
-                                  // number of the exercise was 2.3,
-                                  // we take the liberty to retain
-                                  // this name for the class as well.
-  template <int dim>
-  struct Exercise_2_3
-  {
-                                      // We need a class to denote
-                                      // the boundary values of the
-                                      // problem. In this case, this
-                                      // is simple: it's the zero
-                                      // function, so don't even
-                                      // declare a class, just a
-                                      // typedef:
-      typedef ZeroFunction<dim> BoundaryValues;
-
-                                      // Second, a class that denotes
-                                      // the right hand side. Since
-                                      // they are constant, just
-                                      // subclass the corresponding
-                                      // class of the library and be
-                                      // done:
-      class RightHandSide : public ConstantFunction<dim>
-      {
-       public:
-         RightHandSide () : ConstantFunction<dim> (1.) {}
-      };
-      
-                                      // Finally a function to
-                                      // generate the coarse
-                                      // grid. This is somewhat more
-                                      // complicated here, see
-                                      // immediately below.
-      static
-      void
-      create_coarse_grid (Triangulation<dim> &coarse_grid);
-  };
+                                        // Finally a function to
+                                        // generate the coarse
+                                        // grid. This is somewhat more
+                                        // complicated here, see
+                                        // immediately below.
+       static
+       void
+       create_coarse_grid (Triangulation<dim> &coarse_grid);
+    };
 
 
-                                  // As stated above, the grid for
-                                  // this example is the square
-                                  // [-1,1]^2 with the square
-                                  // [-1/2,1/2]^2 as hole in it. We
-                                  // create the coarse grid as 4
-                                  // times 4 cells with the middle
-                                  // four ones missing.
-                                  //
-                                  // Of course, the example has an
-                                  // extension to 3d, but since this
-                                  // function cannot be written in a
-                                  // dimension independent way we
-                                  // choose not to implement this
-                                  // here, but rather only specialize
-                                  // the template for dim=2. If you
-                                  // compile the program for 3d,
-                                  // you'll get a message from the
-                                  // linker that this function is not
-                                  // implemented for 3d, and needs to
-                                  // be provided.
-                                  //
-                                  // For the creation of this
-                                  // geometry, the library has no
-                                  // predefined method. In this case,
-                                  // the geometry is still simple
-                                  // enough to do the creation by
-                                  // hand, rather than using a mesh
-                                  // generator.
-  template <>
-  void
-  Exercise_2_3<2>::
-  create_coarse_grid (Triangulation<2> &coarse_grid)
-  {
-                                    // First define the space
-                                    // dimension, to allow those
-                                    // parts of the function that are
-                                    // actually dimension independent
-                                    // to use this variable. That
-                                    // makes it simpler if you later
-                                    // takes this as a starting point
-                                    // to implement the 3d version.
-    const unsigned int dim = 2;
-
-                                    // Then have a list of
-                                    // vertices. Here, they are 24 (5
-                                    // times 5, with the middle one
-                                    // omitted). It is probably best
-                                    // to draw a sketch here. Note
-                                    // that we leave the number of
-                                    // vertices open at first, but
-                                    // then let the compiler compute
-                                    // this number afterwards. This
-                                    // reduces the possibility of
-                                    // having the dimension to large
-                                    // and leaving the last ones
-                                    // uninitialized.
-    static const Point<2> vertices_1[]
-      = {  Point<2> (-1.,   -1.),
+                                    // As stated above, the grid for
+                                    // this example is the square
+                                    // [-1,1]^2 with the square
+                                    // [-1/2,1/2]^2 as hole in it. We
+                                    // create the coarse grid as 4
+                                    // times 4 cells with the middle
+                                    // four ones missing.
+                                    //
+                                    // Of course, the example has an
+                                    // extension to 3d, but since this
+                                    // function cannot be written in a
+                                    // dimension independent way we
+                                    // choose not to implement this
+                                    // here, but rather only specialize
+                                    // the template for dim=2. If you
+                                    // compile the program for 3d,
+                                    // you'll get a message from the
+                                    // linker that this function is not
+                                    // implemented for 3d, and needs to
+                                    // be provided.
+                                    //
+                                    // For the creation of this
+                                    // geometry, the library has no
+                                    // predefined method. In this case,
+                                    // the geometry is still simple
+                                    // enough to do the creation by
+                                    // hand, rather than using a mesh
+                                    // generator.
+    template <>
+    void
+    Exercise_2_3<2>::
+    create_coarse_grid (Triangulation<2> &coarse_grid)
+    {
+                                      // First define the space
+                                      // dimension, to allow those
+                                      // parts of the function that are
+                                      // actually dimension independent
+                                      // to use this variable. That
+                                      // makes it simpler if you later
+                                      // takes this as a starting point
+                                      // to implement the 3d version.
+      const unsigned int dim = 2;
+
+                                      // Then have a list of
+                                      // vertices. Here, they are 24 (5
+                                      // times 5, with the middle one
+                                      // omitted). It is probably best
+                                      // to draw a sketch here. Note
+                                      // that we leave the number of
+                                      // vertices open at first, but
+                                      // then let the compiler compute
+                                      // this number afterwards. This
+                                      // reduces the possibility of
+                                      // having the dimension to large
+                                      // and leaving the last ones
+                                      // uninitialized.
+      static const Point<2> vertices_1[]
+       = {  Point<2> (-1.,   -1.),
             Point<2> (-1./2, -1.),
             Point<2> (0.,    -1.),
             Point<2> (+1./2, -1.),
             Point<2> (+1,    -1.),
-            
+
             Point<2> (-1.,   -1./2.),
             Point<2> (-1./2, -1./2.),
             Point<2> (0.,    -1./2.),
             Point<2> (+1./2, -1./2.),
             Point<2> (+1,    -1./2.),
-            
+
             Point<2> (-1.,   0.),
             Point<2> (-1./2, 0.),
             Point<2> (+1./2, 0.),
             Point<2> (+1,    0.),
-            
+
             Point<2> (-1.,   1./2.),
             Point<2> (-1./2, 1./2.),
             Point<2> (0.,    1./2.),
             Point<2> (+1./2, 1./2.),
             Point<2> (+1,    1./2.),
-            
+
             Point<2> (-1.,   1.),
             Point<2> (-1./2, 1.),
-            Point<2> (0.,    1.),                        
+            Point<2> (0.,    1.),
             Point<2> (+1./2, 1.),
             Point<2> (+1,    1.)    };
-    const unsigned int
-      n_vertices = sizeof(vertices_1) / sizeof(vertices_1[0]);
-
-                                    // From this static list of
-                                    // vertices, we generate an STL
-                                    // vector of the vertices, as
-                                    // this is the data type the
-                                    // library wants to see.
-    const std::vector<Point<dim> > vertices (&vertices_1[0],
-                                            &vertices_1[n_vertices]);
-
-                                    // Next, we have to define the
-                                    // cells and the vertices they
-                                    // contain. Here, we have 8
-                                    // vertices, but leave the number
-                                    // open and let it be computed
-                                    // afterwards:
-    static const int cell_vertices[][GeometryInfo<dim>::vertices_per_cell]
-      = {{0, 1, 5, 6},
-        {1, 2, 6, 7},
-        {2, 3, 7, 8},
-        {3, 4, 8, 9},
-        {5, 6, 10, 11},
-        {8, 9, 12, 13},
-        {10, 11, 14, 15},
-        {12, 13, 17, 18},
-        {14, 15, 19, 20},
-        {15, 16, 20, 21},
-        {16, 17, 21, 22},
-        {17, 18, 22, 23}};
-    const unsigned int
-      n_cells = sizeof(cell_vertices) / sizeof(cell_vertices[0]);
-
-                                    // Again, we generate a C++
-                                    // vector type from this, but
-                                    // this time by looping over the
-                                    // cells (yes, this is
-                                    // boring). Additionally, we set
-                                    // the material indicator to zero
-                                    // for all the cells:
-    std::vector<CellData<dim> > cells (n_cells, CellData<dim>());
-    for (unsigned int i=0; i<n_cells; ++i) 
-      {
-       for (unsigned int j=0;
-            j<GeometryInfo<dim>::vertices_per_cell;
-            ++j)
-         cells[i].vertices[j] = cell_vertices[i][j];
-       cells[i].material_id = 0;
-      }
+      const unsigned int
+       n_vertices = sizeof(vertices_1) / sizeof(vertices_1[0]);
+
+                                      // From this static list of
+                                      // vertices, we generate an STL
+                                      // vector of the vertices, as
+                                      // this is the data type the
+                                      // library wants to see.
+      const std::vector<Point<dim> > vertices (&vertices_1[0],
+                                              &vertices_1[n_vertices]);
+
+                                      // Next, we have to define the
+                                      // cells and the vertices they
+                                      // contain. Here, we have 8
+                                      // vertices, but leave the number
+                                      // open and let it be computed
+                                      // afterwards:
+      static const int cell_vertices[][GeometryInfo<dim>::vertices_per_cell]
+       = {{0, 1, 5, 6},
+          {1, 2, 6, 7},
+          {2, 3, 7, 8},
+          {3, 4, 8, 9},
+          {5, 6, 10, 11},
+          {8, 9, 12, 13},
+          {10, 11, 14, 15},
+          {12, 13, 17, 18},
+          {14, 15, 19, 20},
+          {15, 16, 20, 21},
+          {16, 17, 21, 22},
+          {17, 18, 22, 23}};
+      const unsigned int
+       n_cells = sizeof(cell_vertices) / sizeof(cell_vertices[0]);
+
+                                      // Again, we generate a C++
+                                      // vector type from this, but
+                                      // this time by looping over the
+                                      // cells (yes, this is
+                                      // boring). Additionally, we set
+                                      // the material indicator to zero
+                                      // for all the cells:
+      std::vector<CellData<dim> > cells (n_cells, CellData<dim>());
+      for (unsigned int i=0; i<n_cells; ++i)
+       {
+         for (unsigned int j=0;
+              j<GeometryInfo<dim>::vertices_per_cell;
+              ++j)
+           cells[i].vertices[j] = cell_vertices[i][j];
+         cells[i].material_id = 0;
+       }
 
-                                    // Finally pass all this
-                                    // information to the library to
-                                    // generate a triangulation. The
-                                    // last parameter may be used to
-                                    // pass information about
-                                    // non-zero boundary indicators
-                                    // at certain faces of the
-                                    // triangulation to the library,
-                                    // but we don't want that here,
-                                    // so we give an empty object:
-    coarse_grid.create_triangulation (vertices,
-                                     cells,
-                                     SubCellData());
-    
-                                    // And since we want that the
-                                    // evaluation point (3/4,3/4) in
-                                    // this example is a grid point,
-                                    // we refine once globally:
-    coarse_grid.refine_global (1);
+                                      // Finally pass all this
+                                      // information to the library to
+                                      // generate a triangulation. The
+                                      // last parameter may be used to
+                                      // pass information about
+                                      // non-zero boundary indicators
+                                      // at certain faces of the
+                                      // triangulation to the library,
+                                      // but we don't want that here,
+                                      // so we give an empty object:
+      coarse_grid.create_triangulation (vertices,
+                                       cells,
+                                       SubCellData());
+
+                                      // And since we want that the
+                                      // evaluation point (3/4,3/4) in
+                                      // this example is a grid point,
+                                      // we refine once globally:
+      coarse_grid.refine_global (1);
+    }
   }
-}
 
-                                // @sect4{Discussion}
-                                //
-                                // As you have now read through this
-                                // framework, you may be wondering
-                                // why we have not chosen to
-                                // implement the classes implementing
-                                // a certain setup (like the
-                                // <code>CurvedRidges</code> class) directly
-                                // as classes derived from
-                                // <code>Data::SetUpBase</code>. Indeed, we
-                                // could have done very well so. The
-                                // only reason is that then we would
-                                // have to have member variables for
-                                // the solution and right hand side
-                                // classes in the <code>CurvedRidges</code>
-                                // class, as well as member functions
-                                // overloading the abstract functions
-                                // of the base class giving access to
-                                // these member variables. The
-                                // <code>SetUp</code> class has the sole
-                                // reason to relieve us from the need
-                                // to reiterate these member
-                                // variables and functions that would
-                                // be necessary in all such
-                                // classes. In some way, the template
-                                // mechanism here only provides a way
-                                // to have default implementations
-                                // for a number of functions that
-                                // depend on external quantities and
-                                // can thus not be provided using
-                                // normal virtual functions, at least
-                                // not without the help of templates.
-                                //
-                                // However, there might be good
-                                // reasons to actually implement
-                                // classes derived from
-                                // <code>Data::SetUpBase</code>, for example
-                                // if the solution or right hand side
-                                // classes require constructors that
-                                // take arguments, which the
-                                // <code>Data::SetUpBase</code> class cannot
-                                // provide. In that case, subclassing
-                                // is a worthwhile strategy. Other
-                                // possibilities for special cases
-                                // are to derive from
-                                // <code>Data::SetUp@<SomeSetUp@></code> where
-                                // <code>SomeSetUp</code> denotes a class, or
-                                // even to explicitly specialize
-                                // <code>Data::SetUp@<SomeSetUp@></code>. The
-                                // latter allows to transparently use
-                                // the way the <code>SetUp</code> class is
-                                // used for other set-ups, but with
-                                // special actions taken for special
-                                // arguments.
-                                //
-                                // A final observation favoring the
-                                // approach taken here is the
-                                // following: we have found numerous
-                                // times that when starting a
-                                // project, the number of parameters
-                                // (usually boundary values, right
-                                // hand side, coarse grid, just as
-                                // here) was small, and the number of
-                                // test cases was small as well. One
-                                // then starts out by handcoding them
-                                // into a number of <code>switch</code>
-                                // statements. Over time, projects
-                                // grow, and so does the number of
-                                // test cases. The number of
-                                // <code>switch</code> statements grows with
-                                // that, and their length as well,
-                                // and one starts to find ways to
-                                // consider impossible examples where
-                                // domains, boundary values, and
-                                // right hand sides do not fit
-                                // together any more, and starts
-                                // loosing the overview over the
-                                // whole structure. Encapsulating
-                                // everything belonging to a certain
-                                // test case into a structure of its
-                                // own has proven worthwhile for
-                                // this, as it keeps everything that
-                                // belongs to one test case in one
-                                // place. Furthermore, it allows to
-                                // put these things all in one or
-                                // more files that are only devoted
-                                // to test cases and their data,
-                                // without having to bring their
-                                // actual implementation into contact
-                                // with the rest of the program.
-
-
-                                // @sect3{Dual functionals}
-
-                                // As with the other components of
-                                // the program, we put everything we
-                                // need to describe dual functionals
-                                // into a namespace of its own, and
-                                // define an abstract base class that
-                                // provides the interface the class
-                                // solving the dual problem needs for
-                                // its work.
-                                //
-                                // We will then implement two such
-                                // classes, for the evaluation of a
-                                // point value and of the derivative
-                                // of the solution at that point. For
-                                // these functionals we already have
-                                // the corresponding evaluation
-                                // objects, so they are comlementary.
-namespace DualFunctional
-{
-                                  // @sect4{The DualFunctionalBase class}
-  
-                                  // First start with the base class
-                                  // for dual functionals. Since for
-                                  // linear problems the
-                                  // characteristics of the dual
-                                  // problem play a role only in the
-                                  // right hand side, we only need to
-                                  // provide for a function that
-                                  // assembles the right hand side
-                                  // for a given discretization:
-  template <int dim>
-  class DualFunctionalBase : public Subscriptor
-  {
-    public:
-      virtual
-      void
-      assemble_rhs (const DoFHandler<dim> &dof_handler,
-                   Vector<double>        &rhs) const = 0;
-  };
+                                  // @sect4{Discussion}
+                                  //
+                                  // As you have now read through this
+                                  // framework, you may be wondering
+                                  // why we have not chosen to
+                                  // implement the classes implementing
+                                  // a certain setup (like the
+                                  // <code>CurvedRidges</code> class) directly
+                                  // as classes derived from
+                                  // <code>Data::SetUpBase</code>. Indeed, we
+                                  // could have done very well so. The
+                                  // only reason is that then we would
+                                  // have to have member variables for
+                                  // the solution and right hand side
+                                  // classes in the <code>CurvedRidges</code>
+                                  // class, as well as member functions
+                                  // overloading the abstract functions
+                                  // of the base class giving access to
+                                  // these member variables. The
+                                  // <code>SetUp</code> class has the sole
+                                  // reason to relieve us from the need
+                                  // to reiterate these member
+                                  // variables and functions that would
+                                  // be necessary in all such
+                                  // classes. In some way, the template
+                                  // mechanism here only provides a way
+                                  // to have default implementations
+                                  // for a number of functions that
+                                  // depend on external quantities and
+                                  // can thus not be provided using
+                                  // normal virtual functions, at least
+                                  // not without the help of templates.
+                                  //
+                                  // However, there might be good
+                                  // reasons to actually implement
+                                  // classes derived from
+                                  // <code>Data::SetUpBase</code>, for example
+                                  // if the solution or right hand side
+                                  // classes require constructors that
+                                  // take arguments, which the
+                                  // <code>Data::SetUpBase</code> class cannot
+                                  // provide. In that case, subclassing
+                                  // is a worthwhile strategy. Other
+                                  // possibilities for special cases
+                                  // are to derive from
+                                  // <code>Data::SetUp@<SomeSetUp@></code> where
+                                  // <code>SomeSetUp</code> denotes a class, or
+                                  // even to explicitly specialize
+                                  // <code>Data::SetUp@<SomeSetUp@></code>. The
+                                  // latter allows to transparently use
+                                  // the way the <code>SetUp</code> class is
+                                  // used for other set-ups, but with
+                                  // special actions taken for special
+                                  // arguments.
+                                  //
+                                  // A final observation favoring the
+                                  // approach taken here is the
+                                  // following: we have found numerous
+                                  // times that when starting a
+                                  // project, the number of parameters
+                                  // (usually boundary values, right
+                                  // hand side, coarse grid, just as
+                                  // here) was small, and the number of
+                                  // test cases was small as well. One
+                                  // then starts out by handcoding them
+                                  // into a number of <code>switch</code>
+                                  // statements. Over time, projects
+                                  // grow, and so does the number of
+                                  // test cases. The number of
+                                  // <code>switch</code> statements grows with
+                                  // that, and their length as well,
+                                  // and one starts to find ways to
+                                  // consider impossible examples where
+                                  // domains, boundary values, and
+                                  // right hand sides do not fit
+                                  // together any more, and starts
+                                  // loosing the overview over the
+                                  // whole structure. Encapsulating
+                                  // everything belonging to a certain
+                                  // test case into a structure of its
+                                  // own has proven worthwhile for
+                                  // this, as it keeps everything that
+                                  // belongs to one test case in one
+                                  // place. Furthermore, it allows to
+                                  // put these things all in one or
+                                  // more files that are only devoted
+                                  // to test cases and their data,
+                                  // without having to bring their
+                                  // actual implementation into contact
+                                  // with the rest of the program.
+
+
+                                  // @sect3{Dual functionals}
+
+                                  // As with the other components of
+                                  // the program, we put everything we
+                                  // need to describe dual functionals
+                                  // into a namespace of its own, and
+                                  // define an abstract base class that
+                                  // provides the interface the class
+                                  // solving the dual problem needs for
+                                  // its work.
+                                  //
+                                  // We will then implement two such
+                                  // classes, for the evaluation of a
+                                  // point value and of the derivative
+                                  // of the solution at that point. For
+                                  // these functionals we already have
+                                  // the corresponding evaluation
+                                  // objects, so they are comlementary.
+  namespace DualFunctional
+  {
+                                    // @sect4{The DualFunctionalBase class}
+
+                                    // First start with the base class
+                                    // for dual functionals. Since for
+                                    // linear problems the
+                                    // characteristics of the dual
+                                    // problem play a role only in the
+                                    // right hand side, we only need to
+                                    // provide for a function that
+                                    // assembles the right hand side
+                                    // for a given discretization:
+    template <int dim>
+    class DualFunctionalBase : public Subscriptor
+    {
+      public:
+       virtual
+       void
+       assemble_rhs (const DoFHandler<dim> &dof_handler,
+                     Vector<double>        &rhs) const = 0;
+    };
 
 
-                                  // @sect4{The PointValueEvaluation class}
-  
-                                  // As a first application, we
-                                  // consider the functional
-                                  // corresponding to the evaluation
-                                  // of the solution's value at a
-                                  // given point which again we
-                                  // assume to be a vertex. Apart
-                                  // from the constructor that takes
-                                  // and stores the evaluation point,
-                                  // this class consists only of the
-                                  // function that implements
-                                  // assembling the right hand side.
-  template <int dim>
-  class PointValueEvaluation : public DualFunctionalBase<dim>
-  {
-    public:
-      PointValueEvaluation (const Point<dim> &evaluation_point);
-
-      virtual
-      void
-      assemble_rhs (const DoFHandler<dim> &dof_handler,
-                   Vector<double>        &rhs) const;
-      
-      DeclException1 (ExcEvaluationPointNotFound,
-                     Point<dim>,
-                     << "The evaluation point " << arg1
-                     << " was not found among the vertices of the present grid.");
-
-    protected:
-      const Point<dim> evaluation_point;
-  };
+                                    // @sect4{The PointValueEvaluation class}
+
+                                    // As a first application, we
+                                    // consider the functional
+                                    // corresponding to the evaluation
+                                    // of the solution's value at a
+                                    // given point which again we
+                                    // assume to be a vertex. Apart
+                                    // from the constructor that takes
+                                    // and stores the evaluation point,
+                                    // this class consists only of the
+                                    // function that implements
+                                    // assembling the right hand side.
+    template <int dim>
+    class PointValueEvaluation : public DualFunctionalBase<dim>
+    {
+      public:
+       PointValueEvaluation (const Point<dim> &evaluation_point);
 
+       virtual
+       void
+       assemble_rhs (const DoFHandler<dim> &dof_handler,
+                     Vector<double>        &rhs) const;
 
-  template <int dim>
-  PointValueEvaluation<dim>::
-  PointValueEvaluation (const Point<dim> &evaluation_point)
-                 :
-                 evaluation_point (evaluation_point)
-  {}
-  
-
-                                  // As for doing the main purpose of
-                                  // the class, assembling the right
-                                  // hand side, let us first consider
-                                  // what is necessary: The right
-                                  // hand side of the dual problem is
-                                  // a vector of values J(phi_i),
-                                  // where J is the error functional,
-                                  // and phi_i is the i-th shape
-                                  // function. Here, J is the
-                                  // evaluation at the point x0,
-                                  // i.e. J(phi_i)=phi_i(x0).
-                                  //
-                                  // Now, we have assumed that the
-                                  // evaluation point is a
-                                  // vertex. Thus, for the usual
-                                  // finite elements we might be
-                                  // using in this program, we can
-                                  // take for granted that at such a
-                                  // point exactly one shape function
-                                  // is nonzero, and in particular
-                                  // has the value one. Thus, we set
-                                  // the right hand side vector to
-                                  // all-zeros, then seek for the
-                                  // shape function associated with
-                                  // that point and set the
-                                  // corresponding value of the right
-                                  // hand side vector to one:
-  template <int dim>
-  void
-  PointValueEvaluation<dim>::
-  assemble_rhs (const DoFHandler<dim> &dof_handler,
-               Vector<double>        &rhs) const
-  {
-                                    // So, first set everything to
-                                    // zeros...
-    rhs.reinit (dof_handler.n_dofs());
-
-                                    // ...then loop over cells and
-                                    // find the evaluation point
-                                    // among the vertices (or very
-                                    // close to a vertex, which may
-                                    // happen due to floating point
-                                    // round-off):
-    typename DoFHandler<dim>::active_cell_iterator
-      cell = dof_handler.begin_active(),
-      endc = dof_handler.end();
-    for (; cell!=endc; ++cell)
-      for (unsigned int vertex=0;
-          vertex<GeometryInfo<dim>::vertices_per_cell;
-          ++vertex)
-       if (cell->vertex(vertex).distance(evaluation_point)
-           < cell->diameter()*1e-8)
+       DeclException1 (ExcEvaluationPointNotFound,
+                       Point<dim>,
+                       << "The evaluation point " << arg1
+                       << " was not found among the vertices of the present grid.");
+
+      protected:
+       const Point<dim> evaluation_point;
+    };
+
+
+    template <int dim>
+    PointValueEvaluation<dim>::
+    PointValueEvaluation (const Point<dim> &evaluation_point)
+                   :
+                   evaluation_point (evaluation_point)
+    {}
+
+
+                                    // As for doing the main purpose of
+                                    // the class, assembling the right
+                                    // hand side, let us first consider
+                                    // what is necessary: The right
+                                    // hand side of the dual problem is
+                                    // a vector of values J(phi_i),
+                                    // where J is the error functional,
+                                    // and phi_i is the i-th shape
+                                    // function. Here, J is the
+                                    // evaluation at the point x0,
+                                    // i.e. J(phi_i)=phi_i(x0).
+                                    //
+                                    // Now, we have assumed that the
+                                    // evaluation point is a
+                                    // vertex. Thus, for the usual
+                                    // finite elements we might be
+                                    // using in this program, we can
+                                    // take for granted that at such a
+                                    // point exactly one shape function
+                                    // is nonzero, and in particular
+                                    // has the value one. Thus, we set
+                                    // the right hand side vector to
+                                    // all-zeros, then seek for the
+                                    // shape function associated with
+                                    // that point and set the
+                                    // corresponding value of the right
+                                    // hand side vector to one:
+    template <int dim>
+    void
+    PointValueEvaluation<dim>::
+    assemble_rhs (const DoFHandler<dim> &dof_handler,
+                 Vector<double>        &rhs) const
+    {
+                                      // So, first set everything to
+                                      // zeros...
+      rhs.reinit (dof_handler.n_dofs());
+
+                                      // ...then loop over cells and
+                                      // find the evaluation point
+                                      // among the vertices (or very
+                                      // close to a vertex, which may
+                                      // happen due to floating point
+                                      // round-off):
+      typename DoFHandler<dim>::active_cell_iterator
+       cell = dof_handler.begin_active(),
+       endc = dof_handler.end();
+      for (; cell!=endc; ++cell)
+       for (unsigned int vertex=0;
+            vertex<GeometryInfo<dim>::vertices_per_cell;
+            ++vertex)
+         if (cell->vertex(vertex).distance(evaluation_point)
+             < cell->diameter()*1e-8)
+           {
+                                              // Ok, found, so set
+                                              // corresponding entry,
+                                              // and leave function
+                                              // since we are finished:
+             rhs(cell->vertex_dof_index(vertex,0)) = 1;
+             return;
+           }
+
+                                      // Finally, a sanity check: if we
+                                      // somehow got here, then we must
+                                      // have missed the evaluation
+                                      // point, so raise an exception
+                                      // unconditionally:
+      AssertThrow (false, ExcEvaluationPointNotFound(evaluation_point));
+    }
+
+
+                                    // @sect4{The PointXDerivativeEvaluation class}
+
+                                    // As second application, we again
+                                    // consider the evaluation of the
+                                    // x-derivative of the solution at
+                                    // one point. Again, the
+                                    // declaration of the class, and
+                                    // the implementation of its
+                                    // constructor is not too
+                                    // interesting:
+    template <int dim>
+    class PointXDerivativeEvaluation : public DualFunctionalBase<dim>
+    {
+      public:
+       PointXDerivativeEvaluation (const Point<dim> &evaluation_point);
+
+       virtual
+       void
+       assemble_rhs (const DoFHandler<dim> &dof_handler,
+                     Vector<double>        &rhs) const;
+
+       DeclException1 (ExcEvaluationPointNotFound,
+                       Point<dim>,
+                       << "The evaluation point " << arg1
+                       << " was not found among the vertices of the present grid.");
+
+      protected:
+       const Point<dim> evaluation_point;
+    };
+
+
+    template <int dim>
+    PointXDerivativeEvaluation<dim>::
+    PointXDerivativeEvaluation (const Point<dim> &evaluation_point)
+                   :
+                   evaluation_point (evaluation_point)
+    {}
+
+
+                                    // What is interesting is the
+                                    // implementation of this
+                                    // functional: here,
+                                    // J(phi_i)=d/dx phi_i(x0).
+                                    //
+                                    // We could, as in the
+                                    // implementation of the respective
+                                    // evaluation object take the
+                                    // average of the gradients of each
+                                    // shape function phi_i at this
+                                    // evaluation point. However, we
+                                    // take a slightly different
+                                    // approach: we simply take the
+                                    // average over all cells that
+                                    // surround this point. The
+                                    // question which cells
+                                    // <code>surrounds</code> the evaluation
+                                    // point is made dependent on the
+                                    // mesh width by including those
+                                    // cells for which the distance of
+                                    // the cell's midpoint to the
+                                    // evaluation point is less than
+                                    // the cell's diameter.
+                                    //
+                                    // Taking the average of the
+                                    // gradient over the area/volume of
+                                    // these cells leads to a dual
+                                    // solution which is very close to
+                                    // the one which would result from
+                                    // the point evaluation of the
+                                    // gradient. It is simple to
+                                    // justify theoretically that this
+                                    // does not change the method
+                                    // significantly.
+    template <int dim>
+    void
+    PointXDerivativeEvaluation<dim>::
+    assemble_rhs (const DoFHandler<dim> &dof_handler,
+                 Vector<double>        &rhs) const
+    {
+                                      // Again, first set all entries
+                                      // to zero:
+      rhs.reinit (dof_handler.n_dofs());
+
+                                      // Initialize a <code>FEValues</code>
+                                      // object with a quadrature
+                                      // formula, have abbreviations
+                                      // for the number of quadrature
+                                      // points and shape functions...
+      QGauss<dim> quadrature(4);
+      FEValues<dim>  fe_values (dof_handler.get_fe(), quadrature,
+                               update_gradients |
+                               update_quadrature_points  |
+                               update_JxW_values);
+      const unsigned int n_q_points = fe_values.n_quadrature_points;
+      const unsigned int dofs_per_cell = dof_handler.get_fe().dofs_per_cell;
+
+                                      // ...and have two objects that
+                                      // are used to store the global
+                                      // indices of the degrees of
+                                      // freedom on a cell, and the
+                                      // values of the gradients of the
+                                      // shape functions at the
+                                      // quadrature points:
+      Vector<double> cell_rhs (dofs_per_cell);
+      std::vector<unsigned int> local_dof_indices (dofs_per_cell);
+
+                                      // Finally have a variable in
+                                      // which we will sum up the
+                                      // area/volume of the cells over
+                                      // which we integrate, by
+                                      // integrating the unit functions
+                                      // on these cells:
+      double total_volume = 0;
+
+                                      // Then start the loop over all
+                                      // cells, and select those cells
+                                      // which are close enough to the
+                                      // evaluation point:
+      typename DoFHandler<dim>::active_cell_iterator
+       cell = dof_handler.begin_active(),
+       endc = dof_handler.end();
+      for (; cell!=endc; ++cell)
+       if (cell->center().distance(evaluation_point) <=
+           cell->diameter())
          {
-                                            // Ok, found, so set
-                                            // corresponding entry,
-                                            // and leave function
-                                            // since we are finished:
-           rhs(cell->vertex_dof_index(vertex,0)) = 1;
-           return;
-         }
+                                            // If we have found such a
+                                            // cell, then initialize
+                                            // the <code>FEValues</code> object
+                                            // and integrate the
+                                            // x-component of the
+                                            // gradient of each shape
+                                            // function, as well as the
+                                            // unit function for the
+                                            // total area/volume.
+           fe_values.reinit (cell);
+           cell_rhs = 0;
 
-                                    // Finally, a sanity check: if we
-                                    // somehow got here, then we must
-                                    // have missed the evaluation
-                                    // point, so raise an exception
-                                    // unconditionally:
-    AssertThrow (false, ExcEvaluationPointNotFound(evaluation_point));
-  }
+           for (unsigned int q=0; q<n_q_points; ++q)
+             {
+               for (unsigned int i=0; i<dofs_per_cell; ++i)
+                 cell_rhs(i) += fe_values.shape_grad(i,q)[0] *
+                                fe_values.JxW (q);
+               total_volume += fe_values.JxW (q);
+             }
 
+                                            // If we have the local
+                                            // contributions,
+                                            // distribute them to the
+                                            // global vector:
+           cell->get_dof_indices (local_dof_indices);
+           for (unsigned int i=0; i<dofs_per_cell; ++i)
+             rhs(local_dof_indices[i]) += cell_rhs(i);
+         }
 
-                                  // @sect4{The PointXDerivativeEvaluation class}
-  
-                                  // As second application, we again
-                                  // consider the evaluation of the
-                                  // x-derivative of the solution at
-                                  // one point. Again, the
-                                  // declaration of the class, and
-                                  // the implementation of its
-                                  // constructor is not too
-                                  // interesting:
-  template <int dim>
-  class PointXDerivativeEvaluation : public DualFunctionalBase<dim>
-  {
-    public:
-      PointXDerivativeEvaluation (const Point<dim> &evaluation_point);
-
-      virtual
-      void
-      assemble_rhs (const DoFHandler<dim> &dof_handler,
-                   Vector<double>        &rhs) const;
-      
-      DeclException1 (ExcEvaluationPointNotFound,
-                     Point<dim>,
-                     << "The evaluation point " << arg1
-                     << " was not found among the vertices of the present grid.");
-
-    protected:
-      const Point<dim> evaluation_point;
-  };
+                                      // After we have looped over all
+                                      // cells, check whether we have
+                                      // found any at all, by making
+                                      // sure that their volume is
+                                      // non-zero. If not, then the
+                                      // results will be botched, as
+                                      // the right hand side should
+                                      // then still be zero, so throw
+                                      // an exception:
+      AssertThrow (total_volume > 0,
+                  ExcEvaluationPointNotFound(evaluation_point));
+
+                                      // Finally, we have by now only
+                                      // integrated the gradients of
+                                      // the shape functions, not
+                                      // taking their mean value. We
+                                      // fix this by dividing by the
+                                      // measure of the volume over
+                                      // which we have integrated:
+      rhs.scale (1./total_volume);
+    }
 
 
-  template <int dim>
-  PointXDerivativeEvaluation<dim>::
-  PointXDerivativeEvaluation (const Point<dim> &evaluation_point)
-                 :
-                 evaluation_point (evaluation_point)
-  {}
-  
+  }
 
-                                  // What is interesting is the
-                                  // implementation of this
-                                  // functional: here,
-                                  // J(phi_i)=d/dx phi_i(x0).
-                                  //
-                                  // We could, as in the
-                                  // implementation of the respective
-                                  // evaluation object take the
-                                  // average of the gradients of each
-                                  // shape function phi_i at this
-                                  // evaluation point. However, we
-                                  // take a slightly different
-                                  // approach: we simply take the
-                                  // average over all cells that
-                                  // surround this point. The
-                                  // question which cells
-                                  // <code>surrounds</code> the evaluation
-                                  // point is made dependent on the
-                                  // mesh width by including those
-                                  // cells for which the distance of
-                                  // the cell's midpoint to the
-                                  // evaluation point is less than
-                                  // the cell's diameter.
-                                  //
-                                  // Taking the average of the
-                                  // gradient over the area/volume of
-                                  // these cells leads to a dual
-                                  // solution which is very close to
-                                  // the one which would result from
-                                  // the point evaluation of the
-                                  // gradient. It is simple to
-                                  // justify theoretically that this
-                                  // does not change the method
-                                  // significantly.
-  template <int dim>
-  void
-  PointXDerivativeEvaluation<dim>::
-  assemble_rhs (const DoFHandler<dim> &dof_handler,
-               Vector<double>        &rhs) const
+
+                                  // @sect3{Extending the LaplaceSolver namespace}
+  namespace LaplaceSolver
   {
-                                    // Again, first set all entries
-                                    // to zero:
-    rhs.reinit (dof_handler.n_dofs());
-
-                                    // Initialize a <code>FEValues</code>
-                                    // object with a quadrature
-                                    // formula, have abbreviations
-                                    // for the number of quadrature
-                                    // points and shape functions...
-    QGauss<dim> quadrature(4);
-    FEValues<dim>  fe_values (dof_handler.get_fe(), quadrature,
-                             update_gradients |
-                             update_quadrature_points  |
-                             update_JxW_values);
-    const unsigned int n_q_points = fe_values.n_quadrature_points;
-    const unsigned int dofs_per_cell = dof_handler.get_fe().dofs_per_cell;
-
-                                    // ...and have two objects that
-                                    // are used to store the global
-                                    // indices of the degrees of
-                                    // freedom on a cell, and the
-                                    // values of the gradients of the
-                                    // shape functions at the
-                                    // quadrature points:
-    Vector<double> cell_rhs (dofs_per_cell);
-    std::vector<unsigned int> local_dof_indices (dofs_per_cell);
-
-                                    // Finally have a variable in
-                                    // which we will sum up the
-                                    // area/volume of the cells over
-                                    // which we integrate, by
-                                    // integrating the unit functions
-                                    // on these cells:
-    double total_volume = 0;
-    
-                                    // Then start the loop over all
-                                    // cells, and select those cells
-                                    // which are close enough to the
-                                    // evaluation point:
-    typename DoFHandler<dim>::active_cell_iterator
-      cell = dof_handler.begin_active(),
-      endc = dof_handler.end();
-    for (; cell!=endc; ++cell)
-      if (cell->center().distance(evaluation_point) <=
-         cell->diameter())
-       {
-                                          // If we have found such a
-                                          // cell, then initialize
-                                          // the <code>FEValues</code> object
-                                          // and integrate the
-                                          // x-component of the
-                                          // gradient of each shape
-                                          // function, as well as the
-                                          // unit function for the
-                                          // total area/volume.
-         fe_values.reinit (cell);
-         cell_rhs = 0;
-         
-         for (unsigned int q=0; q<n_q_points; ++q)
-           {
-             for (unsigned int i=0; i<dofs_per_cell; ++i)
-               cell_rhs(i) += fe_values.shape_grad(i,q)[0] *
-                              fe_values.JxW (q);
-             total_volume += fe_values.JxW (q);
-           }
 
-                                          // If we have the local
-                                          // contributions,
-                                          // distribute them to the
-                                          // global vector:
-         cell->get_dof_indices (local_dof_indices);
-         for (unsigned int i=0; i<dofs_per_cell; ++i)
-           rhs(local_dof_indices[i]) += cell_rhs(i);
-       }
+                                    // @sect4{The DualSolver class}
+
+                                    // In the same way as the
+                                    // <code>PrimalSolver</code> class above, we
+                                    // now implement a
+                                    // <code>DualSolver</code>. It has all the
+                                    // same features, the only
+                                    // difference is that it does not
+                                    // take a function object denoting
+                                    // a right hand side object, but
+                                    // now takes a
+                                    // <code>DualFunctionalBase</code> object
+                                    // that will assemble the right
+                                    // hand side vector of the dual
+                                    // problem. The rest of the class
+                                    // is rather trivial.
+                                    //
+                                    // Since both primal and dual
+                                    // solver will use the same
+                                    // triangulation, but different
+                                    // discretizations, it now becomes
+                                    // clear why we have made the
+                                    // <code>Base</code> class a virtual one:
+                                    // since the final class will be
+                                    // derived from both
+                                    // <code>PrimalSolver</code> as well as
+                                    // <code>DualSolver</code>, it would have
+                                    // two <code>Base</code> instances, would we
+                                    // not have marked the inheritance
+                                    // as virtual. Since in many
+                                    // applications the base class
+                                    // would store much more
+                                    // information than just the
+                                    // triangulation which needs to be
+                                    // shared between primal and dual
+                                    // solvers, we do not usually want
+                                    // to use two such base classes.
+    template <int dim>
+    class DualSolver : public Solver<dim>
+    {
+      public:
+       DualSolver (Triangulation<dim>       &triangulation,
+                   const FiniteElement<dim> &fe,
+                   const Quadrature<dim>    &quadrature,
+                   const Quadrature<dim-1>  &face_quadrature,
+                   const DualFunctional::DualFunctionalBase<dim> &dual_functional);
 
-                                    // After we have looped over all
-                                    // cells, check whether we have
-                                    // found any at all, by making
-                                    // sure that their volume is
-                                    // non-zero. If not, then the
-                                    // results will be botched, as
-                                    // the right hand side should
-                                    // then still be zero, so throw
-                                    // an exception:
-    AssertThrow (total_volume > 0,
-                ExcEvaluationPointNotFound(evaluation_point));
-
-                                    // Finally, we have by now only
-                                    // integrated the gradients of
-                                    // the shape functions, not
-                                    // taking their mean value. We
-                                    // fix this by dividing by the
-                                    // measure of the volume over
-                                    // which we have integrated:
-    rhs.scale (1./total_volume);
-  }
-  
+       virtual
+       void
+       solve_problem ();
 
-}
+       virtual
+       unsigned int
+       n_dofs () const;
 
+       virtual
+       void
+       postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const;
 
-                                // @sect3{Extending the LaplaceSolver namespace}
-namespace LaplaceSolver
-{
+      protected:
+       const SmartPointer<const DualFunctional::DualFunctionalBase<dim> > dual_functional;
+       virtual void assemble_rhs (Vector<double> &rhs) const;
 
-                                  // @sect4{The DualSolver class}
-
-                                  // In the same way as the
-                                  // <code>PrimalSolver</code> class above, we
-                                  // now implement a
-                                  // <code>DualSolver</code>. It has all the
-                                  // same features, the only
-                                  // difference is that it does not
-                                  // take a function object denoting
-                                  // a right hand side object, but
-                                  // now takes a
-                                  // <code>DualFunctionalBase</code> object
-                                  // that will assemble the right
-                                  // hand side vector of the dual
-                                  // problem. The rest of the class
-                                  // is rather trivial.
-                                  //
-                                  // Since both primal and dual
-                                  // solver will use the same
-                                  // triangulation, but different
-                                  // discretizations, it now becomes
-                                  // clear why we have made the
-                                  // <code>Base</code> class a virtual one:
-                                  // since the final class will be
-                                  // derived from both
-                                  // <code>PrimalSolver</code> as well as
-                                  // <code>DualSolver</code>, it would have
-                                  // two <code>Base</code> instances, would we
-                                  // not have marked the inheritance
-                                  // as virtual. Since in many
-                                  // applications the base class
-                                  // would store much more
-                                  // information than just the
-                                  // triangulation which needs to be
-                                  // shared between primal and dual
-                                  // solvers, we do not usually want
-                                  // to use two such base classes.
-  template <int dim>
-  class DualSolver : public Solver<dim>
-  {
-    public:
-      DualSolver (Triangulation<dim>       &triangulation,
-                 const FiniteElement<dim> &fe,
-                 const Quadrature<dim>    &quadrature,
-                 const Quadrature<dim-1>  &face_quadrature,
-                 const DualFunctional::DualFunctionalBase<dim> &dual_functional);
-
-      virtual
-      void
-      solve_problem ();
-      
-      virtual
-      unsigned int
-      n_dofs () const;
-
-      virtual
-      void
-      postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const;
-
-    protected:
-      const SmartPointer<const DualFunctional::DualFunctionalBase<dim> > dual_functional;
-      virtual void assemble_rhs (Vector<double> &rhs) const;
-
-      static const ZeroFunction<dim> boundary_values;
-
-                                      // Same as above -- make a
-                                      // derived class a friend of
-                                      // this one:
-      friend class WeightedResidual<dim>;
-  };
+       static const ZeroFunction<dim> boundary_values;
 
-  template <int dim>
-  const ZeroFunction<dim> DualSolver<dim>::boundary_values;
+                                        // Same as above -- make a
+                                        // derived class a friend of
+                                        // this one:
+       friend class WeightedResidual<dim>;
+    };
 
-  template <int dim>
-  DualSolver<dim>::
-  DualSolver (Triangulation<dim>       &triangulation,
-             const FiniteElement<dim> &fe,
-             const Quadrature<dim>    &quadrature,
-             const Quadrature<dim-1>  &face_quadrature,
-             const DualFunctional::DualFunctionalBase<dim> &dual_functional)
-                 :
-                 Base<dim> (triangulation),
-                 Solver<dim> (triangulation, fe,
-                              quadrature, face_quadrature,
-                              boundary_values),
-                  dual_functional (&dual_functional)
-  {}
+    template <int dim>
+    const ZeroFunction<dim> DualSolver<dim>::boundary_values;
 
+    template <int dim>
+    DualSolver<dim>::
+    DualSolver (Triangulation<dim>       &triangulation,
+               const FiniteElement<dim> &fe,
+               const Quadrature<dim>    &quadrature,
+               const Quadrature<dim-1>  &face_quadrature,
+               const DualFunctional::DualFunctionalBase<dim> &dual_functional)
+                   :
+                   Base<dim> (triangulation),
+                   Solver<dim> (triangulation, fe,
+                                quadrature, face_quadrature,
+                                boundary_values),
+                   dual_functional (&dual_functional)
+    {}
+
+
+    template <int dim>
+    void
+    DualSolver<dim>::solve_problem ()
+    {
+      Solver<dim>::solve_problem ();
+    }
 
-  template <int dim>
-  void
-  DualSolver<dim>::solve_problem ()
-  {
-    Solver<dim>::solve_problem ();
-  }
 
 
+    template <int dim>
+    unsigned int
+    DualSolver<dim>::n_dofs() const
+    {
+      return Solver<dim>::n_dofs();
+    }
 
-  template <int dim>
-  unsigned int
-  DualSolver<dim>::n_dofs() const
-  {
-    return Solver<dim>::n_dofs();
-  }
 
+    template <int dim>
+    void
+    DualSolver<dim>::
+    postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const
+    {
+      Solver<dim>::postprocess(postprocessor);
+    }
 
-  template <int dim>
-  void
-  DualSolver<dim>::
-  postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const
-  {
-    Solver<dim>::postprocess(postprocessor);
-  }
-  
 
 
-  template <int dim>
-  void
-  DualSolver<dim>::
-  assemble_rhs (Vector<double> &rhs) const 
-  {
-    dual_functional->assemble_rhs (this->dof_handler, rhs);
-  }
+    template <int dim>
+    void
+    DualSolver<dim>::
+    assemble_rhs (Vector<double> &rhs) const
+    {
+      dual_functional->assemble_rhs (this->dof_handler, rhs);
+    }
 
 
-                                  // @sect4{The WeightedResidual class}
-
-                                  // Here finally comes the main
-                                  // class of this program, the one
-                                  // that implements the dual
-                                  // weighted residual error
-                                  // estimator. It joins the primal
-                                  // and dual solver classes to use
-                                  // them for the computation of
-                                  // primal and dual solutions, and
-                                  // implements the error
-                                  // representation formula for use
-                                  // as error estimate and mesh
-                                  // refinement.
-                                  //
-                                  // The first few of the functions
-                                  // of this class are mostly
-                                  // overriders of the respective
-                                  // functions of the base class:
-  template <int dim>
-  class WeightedResidual : public PrimalSolver<dim>,
-                          public DualSolver<dim>
-  {
-    public:
-      WeightedResidual (Triangulation<dim>       &coarse_grid,
-                       const FiniteElement<dim> &primal_fe,
-                       const FiniteElement<dim> &dual_fe,
-                       const Quadrature<dim>    &quadrature,
-                       const Quadrature<dim-1>  &face_quadrature,
-                       const Function<dim>      &rhs_function,
-                       const Function<dim>      &boundary_values,
-                       const DualFunctional::DualFunctionalBase<dim> &dual_functional);
-
-      virtual
-      void
-      solve_problem ();
-
-      virtual
-      void
-      postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const;
-      
-      virtual
-      unsigned int
-      n_dofs () const;
-
-      virtual void refine_grid ();
-
-      virtual
-      void
-      output_solution () const;
-
-    private:
-                                      // In the private section, we
-                                      // have two functions that are
-                                      // used to call the
-                                      // <code>solve_problem</code> functions
-                                      // of the primal and dual base
-                                      // classes. These two functions
-                                      // will be called in parallel
-                                      // by the <code>solve_problem</code>
-                                      // function of this class.
-      void solve_primal_problem ();
-      void solve_dual_problem ();
-                                      // Then declare abbreviations
-                                      // for active cell iterators,
-                                      // to avoid that we have to
-                                      // write this lengthy name
-                                      // over and over again:
-                                       
-      typedef
-      typename DoFHandler<dim>::active_cell_iterator
-      active_cell_iterator;
-
-                                      // Next, declare a data type
-                                      // that we will us to store the
-                                      // contribution of faces to the
-                                      // error estimator. The idea is
-                                      // that we can compute the face
-                                      // terms from each of the two
-                                      // cells to this face, as they
-                                      // are the same when viewed
-                                      // from both sides. What we
-                                      // will do is to compute them
-                                      // only once, based on some
-                                      // rules explained below which
-                                      // of the two adjacent cells
-                                      // will be in charge to do
-                                      // so. We then store the
-                                      // contribution of each face in
-                                      // a map mapping faces to their
-                                      // values, and only collect the
-                                      // contributions for each cell
-                                      // by looping over the cells a
-                                      // second time and grabbing the
-                                      // values from the map.
-                                      //
-                                      // The data type of this map is
-                                      // declared here:
-      typedef
-      typename std::map<typename DoFHandler<dim>::face_iterator,double>
-      FaceIntegrals;
-
-                                      // In the computation of the
-                                      // error estimates on cells and
-                                      // faces, we need a number of
-                                      // helper objects, such as
-                                      // <code>FEValues</code> and
-                                      // <code>FEFaceValues</code> functions,
-                                      // but also temporary objects
-                                      // storing the values and
-                                      // gradients of primal and dual
-                                      // solutions, for
-                                      // example. These fields are
-                                      // needed in the three
-                                      // functions that do the
-                                      // integration on cells, and
-                                      // regular and irregular faces,
-                                      // respectively.
-                                      //
-                                      // There are three reasonable
-                                      // ways to provide these
-                                      // fields: first, as local
-                                      // variables in the function
-                                      // that needs them; second, as
-                                      // member variables of this
-                                      // class; third, as arguments
-                                      // passed to that function.
-                                      //
-                                      // These three alternatives all
-                                      // have drawbacks: the third
-                                      // that their number is not
-                                      // neglectable and would make
-                                      // calling these functions a
-                                      // lengthy enterprise. The
-                                      // second has the drawback that
-                                      // it disallows
-                                      // parallelization, since the
-                                      // threads that will compute
-                                      // the error estimate have to
-                                      // have their own copies of
-                                      // these variables each, so
-                                      // member variables of the
-                                      // enclosing class will not
-                                      // work. The first approach,
-                                      // although straightforward,
-                                      // has a subtle but important
-                                      // drawback: we will call these
-                                      // functions over and over
-                                      // again, many thousands of times
-                                      // maybe; it has now turned out
-                                      // that allocating vectors and
-                                      // other objects that need
-                                      // memory from the heap is an
-                                      // expensive business in terms
-                                      // of run-time, since memory
-                                      // allocation is expensive when
-                                      // several threads are
-                                      // involved. In our experience,
-                                      // more than 20 per cent of the
-                                      // total run time of error
-                                      // estimation functions are due
-                                      // to memory allocation, if
-                                      // done on a per-call level. It
-                                      // is thus significantly better
-                                      // to allocate the memory only
-                                      // once, and recycle the
-                                      // objects as often as
-                                      // possible.
-                                      //
-                                      // What to do? Our answer is to
-                                      // use a variant of the third
-                                      // strategy, namely generating
-                                      // these variables once in the
-                                      // main function of each
-                                      // thread, and passing them
-                                      // down to the functions that
-                                      // do the actual work. To avoid
-                                      // that we have to give these
-                                      // functions a dozen or so
-                                      // arguments, we pack all these
-                                      // variables into two
-                                      // structures, one which is
-                                      // used for the computations on
-                                      // cells, the other doing them
-                                      // on the faces. Instead of
-                                      // many individual objects, we
-                                      // will then only pass one such
-                                      // object to these functions,
-                                      // making their calling
-                                      // sequence simpler.
-      struct CellData
-      {
-         FEValues<dim>    fe_values;
-         const SmartPointer<const Function<dim> > right_hand_side;
-
-         std::vector<double> cell_residual;
-         std::vector<double> rhs_values;         
-         std::vector<double> dual_weights;       
-         std::vector<double> cell_laplacians;
-         CellData (const FiniteElement<dim> &fe,
-                   const Quadrature<dim>    &quadrature,
-                   const Function<dim>      &right_hand_side);
-      };
+                                    // @sect4{The WeightedResidual class}
+
+                                    // Here finally comes the main
+                                    // class of this program, the one
+                                    // that implements the dual
+                                    // weighted residual error
+                                    // estimator. It joins the primal
+                                    // and dual solver classes to use
+                                    // them for the computation of
+                                    // primal and dual solutions, and
+                                    // implements the error
+                                    // representation formula for use
+                                    // as error estimate and mesh
+                                    // refinement.
+                                    //
+                                    // The first few of the functions
+                                    // of this class are mostly
+                                    // overriders of the respective
+                                    // functions of the base class:
+    template <int dim>
+    class WeightedResidual : public PrimalSolver<dim>,
+                            public DualSolver<dim>
+    {
+      public:
+       WeightedResidual (Triangulation<dim>       &coarse_grid,
+                         const FiniteElement<dim> &primal_fe,
+                         const FiniteElement<dim> &dual_fe,
+                         const Quadrature<dim>    &quadrature,
+                         const Quadrature<dim-1>  &face_quadrature,
+                         const Function<dim>      &rhs_function,
+                         const Function<dim>      &boundary_values,
+                         const DualFunctional::DualFunctionalBase<dim> &dual_functional);
+
+       virtual
+       void
+       solve_problem ();
+
+       virtual
+       void
+       postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const;
+
+       virtual
+       unsigned int
+       n_dofs () const;
+
+       virtual void refine_grid ();
+
+       virtual
+       void
+       output_solution () const;
+
+      private:
+                                        // In the private section, we
+                                        // have two functions that are
+                                        // used to call the
+                                        // <code>solve_problem</code> functions
+                                        // of the primal and dual base
+                                        // classes. These two functions
+                                        // will be called in parallel
+                                        // by the <code>solve_problem</code>
+                                        // function of this class.
+       void solve_primal_problem ();
+       void solve_dual_problem ();
+                                        // Then declare abbreviations
+                                        // for active cell iterators,
+                                        // to avoid that we have to
+                                        // write this lengthy name
+                                        // over and over again:
+
+       typedef
+       typename DoFHandler<dim>::active_cell_iterator
+       active_cell_iterator;
+
+                                        // Next, declare a data type
+                                        // that we will us to store the
+                                        // contribution of faces to the
+                                        // error estimator. The idea is
+                                        // that we can compute the face
+                                        // terms from each of the two
+                                        // cells to this face, as they
+                                        // are the same when viewed
+                                        // from both sides. What we
+                                        // will do is to compute them
+                                        // only once, based on some
+                                        // rules explained below which
+                                        // of the two adjacent cells
+                                        // will be in charge to do
+                                        // so. We then store the
+                                        // contribution of each face in
+                                        // a map mapping faces to their
+                                        // values, and only collect the
+                                        // contributions for each cell
+                                        // by looping over the cells a
+                                        // second time and grabbing the
+                                        // values from the map.
+                                        //
+                                        // The data type of this map is
+                                        // declared here:
+       typedef
+       typename std::map<typename DoFHandler<dim>::face_iterator,double>
+       FaceIntegrals;
+
+                                        // In the computation of the
+                                        // error estimates on cells and
+                                        // faces, we need a number of
+                                        // helper objects, such as
+                                        // <code>FEValues</code> and
+                                        // <code>FEFaceValues</code> functions,
+                                        // but also temporary objects
+                                        // storing the values and
+                                        // gradients of primal and dual
+                                        // solutions, for
+                                        // example. These fields are
+                                        // needed in the three
+                                        // functions that do the
+                                        // integration on cells, and
+                                        // regular and irregular faces,
+                                        // respectively.
+                                        //
+                                        // There are three reasonable
+                                        // ways to provide these
+                                        // fields: first, as local
+                                        // variables in the function
+                                        // that needs them; second, as
+                                        // member variables of this
+                                        // class; third, as arguments
+                                        // passed to that function.
+                                        //
+                                        // These three alternatives all
+                                        // have drawbacks: the third
+                                        // that their number is not
+                                        // neglectable and would make
+                                        // calling these functions a
+                                        // lengthy enterprise. The
+                                        // second has the drawback that
+                                        // it disallows
+                                        // parallelization, since the
+                                        // threads that will compute
+                                        // the error estimate have to
+                                        // have their own copies of
+                                        // these variables each, so
+                                        // member variables of the
+                                        // enclosing class will not
+                                        // work. The first approach,
+                                        // although straightforward,
+                                        // has a subtle but important
+                                        // drawback: we will call these
+                                        // functions over and over
+                                        // again, many thousands of times
+                                        // maybe; it has now turned out
+                                        // that allocating vectors and
+                                        // other objects that need
+                                        // memory from the heap is an
+                                        // expensive business in terms
+                                        // of run-time, since memory
+                                        // allocation is expensive when
+                                        // several threads are
+                                        // involved. In our experience,
+                                        // more than 20 per cent of the
+                                        // total run time of error
+                                        // estimation functions are due
+                                        // to memory allocation, if
+                                        // done on a per-call level. It
+                                        // is thus significantly better
+                                        // to allocate the memory only
+                                        // once, and recycle the
+                                        // objects as often as
+                                        // possible.
+                                        //
+                                        // What to do? Our answer is to
+                                        // use a variant of the third
+                                        // strategy, namely generating
+                                        // these variables once in the
+                                        // main function of each
+                                        // thread, and passing them
+                                        // down to the functions that
+                                        // do the actual work. To avoid
+                                        // that we have to give these
+                                        // functions a dozen or so
+                                        // arguments, we pack all these
+                                        // variables into two
+                                        // structures, one which is
+                                        // used for the computations on
+                                        // cells, the other doing them
+                                        // on the faces. Instead of
+                                        // many individual objects, we
+                                        // will then only pass one such
+                                        // object to these functions,
+                                        // making their calling
+                                        // sequence simpler.
+       struct CellData
+       {
+           FEValues<dim>    fe_values;
+           const SmartPointer<const Function<dim> > right_hand_side;
+
+           std::vector<double> cell_residual;
+           std::vector<double> rhs_values;
+           std::vector<double> dual_weights;
+           std::vector<double> cell_laplacians;
+           CellData (const FiniteElement<dim> &fe,
+                     const Quadrature<dim>    &quadrature,
+                     const Function<dim>      &right_hand_side);
+       };
 
-      struct FaceData
-      {
-         FEFaceValues<dim>    fe_face_values_cell;
-         FEFaceValues<dim>    fe_face_values_neighbor;
-         FESubfaceValues<dim> fe_subface_values_cell;
-
-         std::vector<double> jump_residual;
-         std::vector<double> dual_weights;       
-         typename std::vector<Tensor<1,dim> > cell_grads;
-         typename std::vector<Tensor<1,dim> > neighbor_grads;
-         FaceData (const FiniteElement<dim> &fe,
-                   const Quadrature<dim-1>  &face_quadrature);
-      };
+       struct FaceData
+       {
+           FEFaceValues<dim>    fe_face_values_cell;
+           FEFaceValues<dim>    fe_face_values_neighbor;
+           FESubfaceValues<dim> fe_subface_values_cell;
+
+           std::vector<double> jump_residual;
+           std::vector<double> dual_weights;
+           typename std::vector<Tensor<1,dim> > cell_grads;
+           typename std::vector<Tensor<1,dim> > neighbor_grads;
+           FaceData (const FiniteElement<dim> &fe,
+                     const Quadrature<dim-1>  &face_quadrature);
+       };
 
-      
-
-                                      // Regarding the evaluation of
-                                      // the error estimator, we have
-                                      // two driver functions that do
-                                      // this: the first is called to
-                                      // generate the cell-wise
-                                      // estimates, and splits up the
-                                      // task in a number of threads
-                                      // each of which work on a
-                                      // subset of the cells. The
-                                      // first function will run the
-                                      // second for each of these
-                                      // threads:
-      void estimate_error (Vector<float> &error_indicators) const;
-
-      void estimate_some (const Vector<double> &primal_solution,
-                         const Vector<double> &dual_weights,
-                         const unsigned int    n_threads,
-                         const unsigned int    this_thread,
-                         Vector<float>        &error_indicators,
-                         FaceIntegrals        &face_integrals) const;
-
-                                      // Then we have functions that
-                                      // do the actual integration of
-                                      // the error representation
-                                      // formula. They will treat the
-                                      // terms on the cell interiors,
-                                      // on those faces that have no
-                                      // hanging nodes, and on those
-                                      // faces with hanging nodes,
-                                      // respectively:
-      void
-      integrate_over_cell (const active_cell_iterator &cell,
-                          const unsigned int          cell_index,
-                          const Vector<double>       &primal_solution,
-                          const Vector<double>       &dual_weights,
-                          CellData                   &cell_data,
-                          Vector<float>              &error_indicators) const;
-
-      void
-      integrate_over_regular_face (const active_cell_iterator &cell,
-                                  const unsigned int          face_no,
-                                  const Vector<double>       &primal_solution,
-                                  const Vector<double>       &dual_weights,
-                                  FaceData                   &face_data,
-                                  FaceIntegrals              &face_integrals) const;
-      void
-      integrate_over_irregular_face (const active_cell_iterator &cell,
+
+
+                                        // Regarding the evaluation of
+                                        // the error estimator, we have
+                                        // two driver functions that do
+                                        // this: the first is called to
+                                        // generate the cell-wise
+                                        // estimates, and splits up the
+                                        // task in a number of threads
+                                        // each of which work on a
+                                        // subset of the cells. The
+                                        // first function will run the
+                                        // second for each of these
+                                        // threads:
+       void estimate_error (Vector<float> &error_indicators) const;
+
+       void estimate_some (const Vector<double> &primal_solution,
+                           const Vector<double> &dual_weights,
+                           const unsigned int    n_threads,
+                           const unsigned int    this_thread,
+                           Vector<float>        &error_indicators,
+                           FaceIntegrals        &face_integrals) const;
+
+                                        // Then we have functions that
+                                        // do the actual integration of
+                                        // the error representation
+                                        // formula. They will treat the
+                                        // terms on the cell interiors,
+                                        // on those faces that have no
+                                        // hanging nodes, and on those
+                                        // faces with hanging nodes,
+                                        // respectively:
+       void
+       integrate_over_cell (const active_cell_iterator &cell,
+                            const unsigned int          cell_index,
+                            const Vector<double>       &primal_solution,
+                            const Vector<double>       &dual_weights,
+                            CellData                   &cell_data,
+                            Vector<float>              &error_indicators) const;
+
+       void
+       integrate_over_regular_face (const active_cell_iterator &cell,
                                     const unsigned int          face_no,
                                     const Vector<double>       &primal_solution,
                                     const Vector<double>       &dual_weights,
                                     FaceData                   &face_data,
                                     FaceIntegrals              &face_integrals) const;
-  };
+       void
+       integrate_over_irregular_face (const active_cell_iterator &cell,
+                                      const unsigned int          face_no,
+                                      const Vector<double>       &primal_solution,
+                                      const Vector<double>       &dual_weights,
+                                      FaceData                   &face_data,
+                                      FaceIntegrals              &face_integrals) const;
+    };
 
 
 
-                                  // In the implementation of this
-                                  // class, we first have the
-                                  // constructors of the <code>CellData</code>
-                                  // and <code>FaceData</code> member classes,
-                                  // and the <code>WeightedResidual</code>
-                                  // constructor. They only
-                                  // initialize fields to their
-                                  // correct lengths, so we do not
-                                  // have to discuss them to length.
-  template <int dim>
-  WeightedResidual<dim>::CellData::
-  CellData (const FiniteElement<dim> &fe,
-           const Quadrature<dim>    &quadrature,
-           const Function<dim>      &right_hand_side)
-                 :
-                 fe_values (fe, quadrature,
-                            update_values   |
-                            update_hessians |
-                            update_quadrature_points |
-                            update_JxW_values),
-                 right_hand_side (&right_hand_side),
-                 cell_residual (quadrature.size()),
-                 rhs_values (quadrature.size()),
-                 dual_weights (quadrature.size()),
-                 cell_laplacians (quadrature.size())
-  {}
-  
-  
+                                    // In the implementation of this
+                                    // class, we first have the
+                                    // constructors of the <code>CellData</code>
+                                    // and <code>FaceData</code> member classes,
+                                    // and the <code>WeightedResidual</code>
+                                    // constructor. They only
+                                    // initialize fields to their
+                                    // correct lengths, so we do not
+                                    // have to discuss them to length.
+    template <int dim>
+    WeightedResidual<dim>::CellData::
+    CellData (const FiniteElement<dim> &fe,
+             const Quadrature<dim>    &quadrature,
+             const Function<dim>      &right_hand_side)
+                   :
+                   fe_values (fe, quadrature,
+                              update_values   |
+                              update_hessians |
+                              update_quadrature_points |
+                              update_JxW_values),
+                   right_hand_side (&right_hand_side),
+                   cell_residual (quadrature.size()),
+                   rhs_values (quadrature.size()),
+                   dual_weights (quadrature.size()),
+                   cell_laplacians (quadrature.size())
+    {}
+
+
+
+    template <int dim>
+    WeightedResidual<dim>::FaceData::
+    FaceData (const FiniteElement<dim> &fe,
+             const Quadrature<dim-1>  &face_quadrature)
+                   :
+                   fe_face_values_cell (fe, face_quadrature,
+                                        update_values        |
+                                        update_gradients     |
+                                        update_JxW_values    |
+                                        update_normal_vectors),
+                   fe_face_values_neighbor (fe, face_quadrature,
+                                            update_values     |
+                                            update_gradients  |
+                                            update_JxW_values |
+                                            update_normal_vectors),
+                   fe_subface_values_cell (fe, face_quadrature,
+                                           update_gradients)
+    {
+      const unsigned int n_face_q_points
+       = face_quadrature.size();
 
-  template <int dim>
-  WeightedResidual<dim>::FaceData::
-  FaceData (const FiniteElement<dim> &fe,
-           const Quadrature<dim-1>  &face_quadrature)
-                 :
-                 fe_face_values_cell (fe, face_quadrature,
-                                      update_values        |
-                                      update_gradients     |
-                                      update_JxW_values    |
-                                      update_normal_vectors),
-                 fe_face_values_neighbor (fe, face_quadrature,
-                                          update_values     |
-                                          update_gradients  |
-                                          update_JxW_values |
-                                          update_normal_vectors),
-                 fe_subface_values_cell (fe, face_quadrature,
-                                         update_gradients)
-  {  
-    const unsigned int n_face_q_points
-      = face_quadrature.size();
-  
-    jump_residual.resize(n_face_q_points);
-    dual_weights.resize(n_face_q_points);    
-    cell_grads.resize(n_face_q_points);
-    neighbor_grads.resize(n_face_q_points);
-  }
-  
+      jump_residual.resize(n_face_q_points);
+      dual_weights.resize(n_face_q_points);
+      cell_grads.resize(n_face_q_points);
+      neighbor_grads.resize(n_face_q_points);
+    }
 
 
 
-  template <int dim>
-  WeightedResidual<dim>::
-  WeightedResidual (Triangulation<dim>       &coarse_grid,
-                   const FiniteElement<dim> &primal_fe,
-                   const FiniteElement<dim> &dual_fe,
-                   const Quadrature<dim>    &quadrature,
-                   const Quadrature<dim-1>  &face_quadrature,
-                   const Function<dim>      &rhs_function,
-                   const Function<dim>      &bv,
-                   const DualFunctional::DualFunctionalBase<dim> &dual_functional)
-                 :
-                 Base<dim> (coarse_grid),
-                  PrimalSolver<dim> (coarse_grid, primal_fe,
+
+    template <int dim>
+    WeightedResidual<dim>::
+    WeightedResidual (Triangulation<dim>       &coarse_grid,
+                     const FiniteElement<dim> &primal_fe,
+                     const FiniteElement<dim> &dual_fe,
+                     const Quadrature<dim>    &quadrature,
+                     const Quadrature<dim-1>  &face_quadrature,
+                     const Function<dim>      &rhs_function,
+                     const Function<dim>      &bv,
+                     const DualFunctional::DualFunctionalBase<dim> &dual_functional)
+                   :
+                   Base<dim> (coarse_grid),
+                   PrimalSolver<dim> (coarse_grid, primal_fe,
+                                      quadrature, face_quadrature,
+                                      rhs_function, bv),
+                   DualSolver<dim> (coarse_grid, dual_fe,
                                     quadrature, face_quadrature,
-                                    rhs_function, bv),
-                  DualSolver<dim> (coarse_grid, dual_fe,
-                                  quadrature, face_quadrature,
-                                  dual_functional)
-  {}
+                                    dual_functional)
+    {}
+
+
+                                    // The next five functions are
+                                    // boring, as they simply relay
+                                    // their work to the base
+                                    // classes. The first calls the
+                                    // primal and dual solvers in
+                                    // parallel, while postprocessing
+                                    // the solution and retrieving the
+                                    // number of degrees of freedom is
+                                    // done by the primal class.
+    template <int dim>
+    void
+    WeightedResidual<dim>::solve_problem ()
+    {
+      Threads::ThreadGroup<> threads;
+      threads += Threads::new_thread (&WeightedResidual<dim>::solve_primal_problem,
+                                     *this);
+      threads += Threads::new_thread (&WeightedResidual<dim>::solve_dual_problem,
+                                     *this);
+      threads.join_all ();
+    }
 
 
-                                  // The next five functions are
-                                  // boring, as they simply relay
-                                  // their work to the base
-                                  // classes. The first calls the
-                                  // primal and dual solvers in
-                                  // parallel, while postprocessing
-                                  // the solution and retrieving the
-                                  // number of degrees of freedom is
-                                  // done by the primal class.
-  template <int dim>
-  void
-  WeightedResidual<dim>::solve_problem ()
-  {
-    Threads::ThreadGroup<> threads;
-    threads += Threads::new_thread (&WeightedResidual<dim>::solve_primal_problem,
-                                   *this);
-    threads += Threads::new_thread (&WeightedResidual<dim>::solve_dual_problem,
-                                   *this);
-    threads.join_all ();
-  }
+    template <int dim>
+    void
+    WeightedResidual<dim>::solve_primal_problem ()
+    {
+      PrimalSolver<dim>::solve_problem ();
+    }
 
-  
-  template <int dim>
-  void
-  WeightedResidual<dim>::solve_primal_problem ()
-  {
-    PrimalSolver<dim>::solve_problem ();
-  }
+    template <int dim>
+    void
+    WeightedResidual<dim>::solve_dual_problem ()
+    {
+      DualSolver<dim>::solve_problem ();
+    }
 
-  template <int dim>
-  void
-  WeightedResidual<dim>::solve_dual_problem ()
-  {
-    DualSolver<dim>::solve_problem ();
-  }
-  
 
-  template <int dim>
-  void
-  WeightedResidual<dim>::
-  postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const
-  {
-    PrimalSolver<dim>::postprocess (postprocessor);
-  }
-  
-  
-  template <int dim>
-  unsigned int
-  WeightedResidual<dim>::n_dofs () const
-  {
-    return PrimalSolver<dim>::n_dofs();
-  }
+    template <int dim>
+    void
+    WeightedResidual<dim>::
+    postprocess (const Evaluation::EvaluationBase<dim> &postprocessor) const
+    {
+      PrimalSolver<dim>::postprocess (postprocessor);
+    }
 
 
+    template <int dim>
+    unsigned int
+    WeightedResidual<dim>::n_dofs () const
+    {
+      return PrimalSolver<dim>::n_dofs();
+    }
 
-                                  // Now, it is becoming more
-                                  // interesting: the <code>refine_grid</code>
-                                  // function asks the error
-                                  // estimator to compute the
-                                  // cell-wise error indicators, then
-                                  // uses their absolute values for
-                                  // mesh refinement.
-  template <int dim>
-  void
-  WeightedResidual<dim>::refine_grid ()
-  {
-                                    // First call the function that
-                                    // computes the cell-wise and
-                                    // global error:
-    Vector<float> error_indicators (this->triangulation->n_active_cells());
-    estimate_error (error_indicators);
-
-                                    // Then note that marking cells
-                                    // for refinement or coarsening
-                                    // only works if all indicators
-                                    // are positive, to allow their
-                                    // comparison. Thus, drop the
-                                    // signs on all these indicators:
-    for (Vector<float>::iterator i=error_indicators.begin();
-        i != error_indicators.end(); ++i)
-      *i = std::fabs (*i);
-
-                                    // Finally, we can select between
-                                    // different strategies for
-                                    // refinement. The default here
-                                    // is to refine those cells with
-                                    // the largest error indicators
-                                    // that make up for a total of 80
-                                    // per cent of the error, while
-                                    // we coarsen those with the
-                                    // smallest indicators that make
-                                    // up for the bottom 2 per cent
-                                    // of the error.
-    GridRefinement::refine_and_coarsen_fixed_fraction (*this->triangulation,
-                                                      error_indicators,
-                                                      0.8, 0.02);
-    this->triangulation->execute_coarsening_and_refinement ();
-  }
-  
-
-                                  // Since we want to output both the
-                                  // primal and the dual solution, we
-                                  // overload the <code>output_solution</code>
-                                  // function. The only interesting
-                                  // feature of this function is that
-                                  // the primal and dual solutions
-                                  // are defined on different finite
-                                  // element spaces, which is not the
-                                  // format the <code>DataOut</code> class
-                                  // expects. Thus, we have to
-                                  // transfer them to a common finite
-                                  // element space. Since we want the
-                                  // solutions only to see them
-                                  // qualitatively, we contend
-                                  // ourselves with interpolating the
-                                  // dual solution to the (smaller)
-                                  // primal space. For the
-                                  // interpolation, there is a
-                                  // library function, that takes a
-                                  // <code>ConstraintMatrix</code> object
-                                  // including the hanging node
-                                  // constraints. The rest is
-                                  // standard.
-                                  //
-                                  // There is, however, one
-                                  // work-around worth mentioning: in
-                                  // this function, as in a couple of
-                                  // following ones, we have to
-                                  // access the <code>DoFHandler</code>
-                                  // objects and solutions of both
-                                  // the primal as well as of the
-                                  // dual solver. Since these are
-                                  // members of the <code>Solver</code> base
-                                  // class which exists twice in the
-                                  // class hierarchy leading to the
-                                  // present class (once as base
-                                  // class of the <code>PrimalSolver</code>
-                                  // class, once as base class of the
-                                  // <code>DualSolver</code> class), we have
-                                  // to disambiguate accesses to them
-                                  // by telling the compiler a member
-                                  // of which of these two instances
-                                  // we want to access. The way to do
-                                  // this would be identify the
-                                  // member by pointing a path
-                                  // through the class hierarchy
-                                  // which disambiguates the base
-                                  // class, for example writing
-                                  // <code>PrimalSolver::dof_handler</code> to
-                                  // denote the member variable
-                                  // <code>dof_handler</code> from the
-                                  // <code>Solver</code> base class of the
-                                  // <code>PrimalSolver</code>
-                                  // class. Unfortunately, this
-                                  // confuses gcc's version 2.96 (a
-                                  // version that was intended as a
-                                  // development snapshot, but
-                                  // delivered as system compiler by
-                                  // Red Hat in their 7.x releases)
-                                  // so much that it bails out and
-                                  // refuses to compile the code.
-                                  //
-                                  // Thus, we have to work around
-                                  // this problem. We do this by
-                                  // introducing references to the
-                                  // <code>PrimalSolver</code> and
-                                  // <code>DualSolver</code> components of the
-                                  // <code>WeightedResidual</code> object at
-                                  // the beginning of the
-                                  // function. Since each of these
-                                  // has an unambiguous base class
-                                  // <code>Solver</code>, we can access the
-                                  // member variables we want through
-                                  // these references. However, we
-                                  // are now accessing protected
-                                  // member variables of these
-                                  // classes through a pointer other
-                                  // than the <code>this</code> pointer (in
-                                  // fact, this is of course the
-                                  // <code>this</code> pointer, but not
-                                  // explicitly). This finally is the
-                                  // reason why we had to declare the
-                                  // present class a friend of the
-                                  // classes we so access.
-  template <int dim>
-  void
-  WeightedResidual<dim>::output_solution () const
-  {
-    const PrimalSolver<dim> &primal_solver = *this;
-    const DualSolver<dim>   &dual_solver   = *this;
-    
-    ConstraintMatrix primal_hanging_node_constraints;
-    DoFTools::make_hanging_node_constraints (primal_solver.dof_handler,
-                                            primal_hanging_node_constraints);
-    primal_hanging_node_constraints.close();
-    Vector<double> dual_solution (primal_solver.dof_handler.n_dofs());
-    FETools::interpolate (dual_solver.dof_handler,
-                         dual_solver.solution,
-                         primal_solver.dof_handler,
-                         primal_hanging_node_constraints,
-                         dual_solution);    
-
-    DataOut<dim> data_out;
-    data_out.attach_dof_handler (primal_solver.dof_handler);
-
-                                    // Add the data vectors for which
-                                    // we want output. Add them both,
-                                    // the <code>DataOut</code> functions can
-                                    // handle as many data vectors as
-                                    // you wish to write to output:
-    data_out.add_data_vector (primal_solver.solution,
-                             "primal_solution");
-    data_out.add_data_vector (dual_solution,
-                             "dual_solution");
-    
-    data_out.build_patches ();
-  
-    std::ostringstream filename;
-    filename << "solution-"
-            << this->refinement_cycle
-            << ".gnuplot"
-            << std::ends;
-    
-    std::ofstream out (filename.str().c_str());    
-    data_out.write (out, DataOut<dim>::gnuplot);
-  }
 
 
-                                  // @sect3{Estimating errors}
+                                    // Now, it is becoming more
+                                    // interesting: the <code>refine_grid</code>
+                                    // function asks the error
+                                    // estimator to compute the
+                                    // cell-wise error indicators, then
+                                    // uses their absolute values for
+                                    // mesh refinement.
+    template <int dim>
+    void
+    WeightedResidual<dim>::refine_grid ()
+    {
+                                      // First call the function that
+                                      // computes the cell-wise and
+                                      // global error:
+      Vector<float> error_indicators (this->triangulation->n_active_cells());
+      estimate_error (error_indicators);
+
+                                      // Then note that marking cells
+                                      // for refinement or coarsening
+                                      // only works if all indicators
+                                      // are positive, to allow their
+                                      // comparison. Thus, drop the
+                                      // signs on all these indicators:
+      for (Vector<float>::iterator i=error_indicators.begin();
+          i != error_indicators.end(); ++i)
+       *i = std::fabs (*i);
+
+                                      // Finally, we can select between
+                                      // different strategies for
+                                      // refinement. The default here
+                                      // is to refine those cells with
+                                      // the largest error indicators
+                                      // that make up for a total of 80
+                                      // per cent of the error, while
+                                      // we coarsen those with the
+                                      // smallest indicators that make
+                                      // up for the bottom 2 per cent
+                                      // of the error.
+      GridRefinement::refine_and_coarsen_fixed_fraction (*this->triangulation,
+                                                        error_indicators,
+                                                        0.8, 0.02);
+      this->triangulation->execute_coarsening_and_refinement ();
+    }
+
 
-                                  // @sect4{Error estimation driver functions}
-                                  //
-                                  // As for the actual computation of
-                                  // error estimates, let's start
-                                  // with the function that drives
-                                  // all this, i.e. calls those
-                                  // functions that actually do the
-                                  // work, and finally collects the
-                                  // results.
-  
-  template <int dim>
-  void
-  WeightedResidual<dim>::
-  estimate_error (Vector<float> &error_indicators) const
-  {
-    const PrimalSolver<dim> &primal_solver = *this;
-    const DualSolver<dim>   &dual_solver   = *this;
-
-                                    // The first task in computing
-                                    // the error is to set up vectors
-                                    // that denote the primal
-                                    // solution, and the weights
-                                    // (z-z_h)=(z-I_hz), both in the
-                                    // finite element space for which
-                                    // we have computed the dual
-                                    // solution. For this, we have to
-                                    // interpolate the primal
-                                    // solution to the dual finite
-                                    // element space, and to subtract
-                                    // the interpolation of the
-                                    // computed dual solution to the
-                                    // primal finite element
-                                    // space. Fortunately, the
-                                    // library provides functions for
-                                    // the interpolation into larger
-                                    // or smaller finite element
-                                    // spaces, so this is mostly
-                                    // obvious.
-                                    //
-                                    // First, let's do that for the
-                                    // primal solution: it is
-                                    // cell-wise interpolated into
-                                    // the finite element space in
-                                    // which we have solved the dual
-                                    // problem: But, again as in the
-                                    // <code>WeightedResidual::output_solution</code>
-                                    // function we first need to
-                                    // create a ConstraintMatrix
+                                    // Since we want to output both the
+                                    // primal and the dual solution, we
+                                    // overload the <code>output_solution</code>
+                                    // function. The only interesting
+                                    // feature of this function is that
+                                    // the primal and dual solutions
+                                    // are defined on different finite
+                                    // element spaces, which is not the
+                                    // format the <code>DataOut</code> class
+                                    // expects. Thus, we have to
+                                    // transfer them to a common finite
+                                    // element space. Since we want the
+                                    // solutions only to see them
+                                    // qualitatively, we contend
+                                    // ourselves with interpolating the
+                                    // dual solution to the (smaller)
+                                    // primal space. For the
+                                    // interpolation, there is a
+                                    // library function, that takes a
+                                    // <code>ConstraintMatrix</code> object
                                     // including the hanging node
-                                    // constraints, but this time of
-                                    // the dual finite element space.
-    ConstraintMatrix dual_hanging_node_constraints;
-    DoFTools::make_hanging_node_constraints (dual_solver.dof_handler,
-                                            dual_hanging_node_constraints);
-    dual_hanging_node_constraints.close();
-    Vector<double> primal_solution (dual_solver.dof_handler.n_dofs());
-    FETools::interpolate (primal_solver.dof_handler,
-                         primal_solver.solution,
-                         dual_solver.dof_handler,
-                         dual_hanging_node_constraints,
-                         primal_solution);
-    
-                                    // Then for computing the
-                                    // interpolation of the
-                                    // numerically approximated dual
-                                    // solution z into the finite
-                                    // element space of the primal
-                                    // solution and subtracting it
-                                    // from z: use the
-                                    // <code>interpolate_difference</code>
-                                    // function, that gives (z-I_hz)
-                                    // in the element space of the
-                                    // dual solution.
-    ConstraintMatrix primal_hanging_node_constraints;
-    DoFTools::make_hanging_node_constraints (primal_solver.dof_handler,
-                                            primal_hanging_node_constraints);
-    primal_hanging_node_constraints.close();
-    Vector<double> dual_weights (dual_solver.dof_handler.n_dofs());
-    FETools::interpolation_difference (dual_solver.dof_handler,
-                                      dual_hanging_node_constraints,
-                                      dual_solver.solution,
-                                      primal_solver.dof_handler,
-                                      primal_hanging_node_constraints,
-                                      dual_weights);
-    
-                                    // Note that this could probably
-                                    // have been more efficient since
-                                    // those constraints have been
-                                    // used previously when
-                                    // assembling matrix and right
-                                    // hand side for the primal
-                                    // problem and writing out the
-                                    // dual solution. We leave the
-                                    // optimization of the program in
-                                    // this respect as an exercise.
-    
-                                    // Having computed the dual
-                                    // weights we now proceed with
-                                    // computing the cell and face
-                                    // residuals of the primal
-                                    // solution. First we set up a
-                                    // map between face iterators and
-                                    // their jump term contributions
-                                    // of faces to the error
-                                    // estimator. The reason is that
-                                    // we compute the jump terms only
-                                    // once, from one side of the
-                                    // face, and want to collect them
-                                    // only afterwards when looping
-                                    // over all cells a second time.
+                                    // constraints. The rest is
+                                    // standard.
                                     //
-                                    // We initialize this map already
-                                    // with a value of -1e20 for all
-                                    // faces, since this value will
-                                    // strike in the results if
-                                    // something should go wrong and
-                                    // we fail to compute the value
-                                    // for a face for some
-                                    // reason. Secondly, we
-                                    // initialize the map once before
-                                    // we branch to different threads
-                                    // since this way the map's
-                                    // structure is no more modified
-                                    // by the individual threads,
-                                    // only existing entries are set
-                                    // to new values. This relieves
-                                    // us from the necessity to
-                                    // synchronise the threads
-                                    // through a mutex each time they
-                                    // write to (and modify the
-                                    // structure of) this map.
-    FaceIntegrals face_integrals;
-    for (active_cell_iterator cell=dual_solver.dof_handler.begin_active();
-        cell!=dual_solver.dof_handler.end();
-        ++cell)
-      for (unsigned int face_no=0;
-          face_no<GeometryInfo<dim>::faces_per_cell;
-          ++face_no)
-       face_integrals[cell->face(face_no)] = -1e20;
-
-                                    // Then set up a vector with
-                                    // error indicators.  Reserve one
-                                    // slot for each cell and set it
-                                    // to zero.
-    error_indicators.reinit (dual_solver.dof_handler
-                            .get_tria().n_active_cells());
-
-                                    // Now start a number of threads
-                                    // which compute the error
-                                    // formula on parts of all the
-                                    // cells, and once they are all
-                                    // started wait until they have
-                                    // all finished:
-    const unsigned int n_threads = multithread_info.n_default_threads;
-    Threads::ThreadGroup<> threads;
-    for (unsigned int i=0; i<n_threads; ++i)
-      threads += Threads::new_thread (&WeightedResidual<dim>::estimate_some,
-                                     *this,
-                                     primal_solution,
-                                     dual_weights,
-                                     n_threads, i,
-                                     error_indicators,
-                                     face_integrals);
-    threads.join_all();    
-
-                                    // Once the error contributions
-                                    // are computed, sum them up. For
-                                    // this, note that the cell terms
-                                    // are already set, and that only
-                                    // the edge terms need to be
-                                    // collected. Thus, loop over all
-                                    // cells and their faces, make
-                                    // sure that the contributions of
-                                    // each of the faces are there,
-                                    // and add them up. Only take
-                                    // minus one half of the jump
-                                    // term, since the other half
-                                    // will be taken by the
-                                    // neighboring cell.
-    unsigned int present_cell=0;  
-    for (active_cell_iterator cell=dual_solver.dof_handler.begin_active();
-        cell!=dual_solver.dof_handler.end();
-        ++cell, ++present_cell)
-      for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell;
-          ++face_no)
-       {
-         Assert(face_integrals.find(cell->face(face_no)) !=
-                face_integrals.end(),
-                ExcInternalError());
-         error_indicators(present_cell)
-           -= 0.5*face_integrals[cell->face(face_no)];
-       }
-    std::cout << "   Estimated error="
-             << std::accumulate (error_indicators.begin(),
-                                 error_indicators.end(), 0.)
-             << std::endl;
-  }
+                                    // There is, however, one
+                                    // work-around worth mentioning: in
+                                    // this function, as in a couple of
+                                    // following ones, we have to
+                                    // access the <code>DoFHandler</code>
+                                    // objects and solutions of both
+                                    // the primal as well as of the
+                                    // dual solver. Since these are
+                                    // members of the <code>Solver</code> base
+                                    // class which exists twice in the
+                                    // class hierarchy leading to the
+                                    // present class (once as base
+                                    // class of the <code>PrimalSolver</code>
+                                    // class, once as base class of the
+                                    // <code>DualSolver</code> class), we have
+                                    // to disambiguate accesses to them
+                                    // by telling the compiler a member
+                                    // of which of these two instances
+                                    // we want to access. The way to do
+                                    // this would be identify the
+                                    // member by pointing a path
+                                    // through the class hierarchy
+                                    // which disambiguates the base
+                                    // class, for example writing
+                                    // <code>PrimalSolver::dof_handler</code> to
+                                    // denote the member variable
+                                    // <code>dof_handler</code> from the
+                                    // <code>Solver</code> base class of the
+                                    // <code>PrimalSolver</code>
+                                    // class. Unfortunately, this
+                                    // confuses gcc's version 2.96 (a
+                                    // version that was intended as a
+                                    // development snapshot, but
+                                    // delivered as system compiler by
+                                    // Red Hat in their 7.x releases)
+                                    // so much that it bails out and
+                                    // refuses to compile the code.
+                                    //
+                                    // Thus, we have to work around
+                                    // this problem. We do this by
+                                    // introducing references to the
+                                    // <code>PrimalSolver</code> and
+                                    // <code>DualSolver</code> components of the
+                                    // <code>WeightedResidual</code> object at
+                                    // the beginning of the
+                                    // function. Since each of these
+                                    // has an unambiguous base class
+                                    // <code>Solver</code>, we can access the
+                                    // member variables we want through
+                                    // these references. However, we
+                                    // are now accessing protected
+                                    // member variables of these
+                                    // classes through a pointer other
+                                    // than the <code>this</code> pointer (in
+                                    // fact, this is of course the
+                                    // <code>this</code> pointer, but not
+                                    // explicitly). This finally is the
+                                    // reason why we had to declare the
+                                    // present class a friend of the
+                                    // classes we so access.
+    template <int dim>
+    void
+    WeightedResidual<dim>::output_solution () const
+    {
+      const PrimalSolver<dim> &primal_solver = *this;
+      const DualSolver<dim>   &dual_solver   = *this;
+
+      ConstraintMatrix primal_hanging_node_constraints;
+      DoFTools::make_hanging_node_constraints (primal_solver.dof_handler,
+                                              primal_hanging_node_constraints);
+      primal_hanging_node_constraints.close();
+      Vector<double> dual_solution (primal_solver.dof_handler.n_dofs());
+      FETools::interpolate (dual_solver.dof_handler,
+                           dual_solver.solution,
+                           primal_solver.dof_handler,
+                           primal_hanging_node_constraints,
+                           dual_solution);
+
+      DataOut<dim> data_out;
+      data_out.attach_dof_handler (primal_solver.dof_handler);
+
+                                      // Add the data vectors for which
+                                      // we want output. Add them both,
+                                      // the <code>DataOut</code> functions can
+                                      // handle as many data vectors as
+                                      // you wish to write to output:
+      data_out.add_data_vector (primal_solver.solution,
+                               "primal_solution");
+      data_out.add_data_vector (dual_solution,
+                               "dual_solution");
+
+      data_out.build_patches ();
+
+      std::ostringstream filename;
+      filename << "solution-"
+              << this->refinement_cycle
+              << ".gnuplot"
+              << std::ends;
+
+      std::ofstream out (filename.str().c_str());
+      data_out.write (out, DataOut<dim>::gnuplot);
+    }
 
 
-                                  // @sect4{Estimating on a subset of cells}
+                                    // @sect3{Estimating errors}
 
-                                  // Next we have the function that
-                                  // is called to estimate the error
-                                  // on a subset of cells. The
-                                  // function may be called multiply
-                                  // if the library was configured to
-                                  // use multi-threading. Here it
-                                  // goes:
-  template <int dim>
-  void
-  WeightedResidual<dim>::
-  estimate_some (const Vector<double> &primal_solution,
-                const Vector<double> &dual_weights,
-                const unsigned int    n_threads,
-                const unsigned int    this_thread,
-                Vector<float>        &error_indicators,
-                FaceIntegrals        &face_integrals) const
-  {
-    const PrimalSolver<dim> &primal_solver = *this;
-    const DualSolver<dim>   &dual_solver   = *this;
-
-                                    // At the beginning, we
-                                    // initialize two variables for
-                                    // each thread which may be
-                                    // running this function. The
-                                    // reason for these functions was
-                                    // discussed above, when the
-                                    // respective classes were
-                                    // discussed, so we here only
-                                    // point out that since they are
-                                    // local to the function that is
-                                    // spawned when running more than
-                                    // one thread, the data of these
-                                    // objects exists actually once
-                                    // per thread, so we don't have
-                                    // to take care about
-                                    // synchronising access to them.
-    CellData cell_data (*dual_solver.fe,
-                       *dual_solver.quadrature,
-                       *primal_solver.rhs_function);
-    FaceData face_data (*dual_solver.fe,
-                       *dual_solver.face_quadrature);    
-
-                                    // Then calculate the start cell
-                                    // for this thread. We let the
-                                    // different threads run on
-                                    // interleaved cells, i.e. for
-                                    // example if we have 4 threads,
-                                    // then the first thread treates
-                                    // cells 0, 4, 8, etc, while the
-                                    // second threads works on cells 1,
-                                    // 5, 9, and so on. The reason is
-                                    // that it takes vastly more time
-                                    // to work on cells with hanging
-                                    // nodes than on regular cells, but
-                                    // such cells are not evenly
-                                    // distributed across the range of
-                                    // cell iterators, so in order to
-                                    // have the different threads do
-                                    // approximately the same amount of
-                                    // work, we have to let them work
-                                    // interleaved to the effect of a
-                                    // pseudorandom distribution of the
-                                    // `hard' cells to the different
-                                    // threads.
-    active_cell_iterator cell=dual_solver.dof_handler.begin_active();
-    for (unsigned int t=0;
-        (t<this_thread) && (cell!=dual_solver.dof_handler.end());
-        ++t, ++cell)
-      ;
-
-                                    // If there are no cells for this
-                                    // thread (for example if there
-                                    // are a total of less cells than
-                                    // there are threads), then go
-                                    // back right now
-    if (cell == dual_solver.dof_handler.end())
-      return;
-    
-                                    // Next loop over all cells. The
-                                    // check for loop end is done at
-                                    // the end of the loop, along
-                                    // with incrementing the loop
-                                    // index.
-    for (unsigned int cell_index=this_thread; true; )
-      {
-                                        // First task on each cell is
-                                        // to compute the cell
-                                        // residual contributions of
-                                        // this cell, and put them
-                                        // into the
-                                        // <code>error_indicators</code>
-                                        // variable:
-       integrate_over_cell (cell, cell_index,
-                            primal_solution,
-                            dual_weights,
-                            cell_data,
-                            error_indicators);
-       
-                                        // After computing the cell
-                                        // terms, turn to the face
-                                        // terms. For this, loop over
-                                        // all faces of the present
-                                        // cell, and see whether
-                                        // something needs to be
-                                        // computed on it:
+                                    // @sect4{Error estimation driver functions}
+                                    //
+                                    // As for the actual computation of
+                                    // error estimates, let's start
+                                    // with the function that drives
+                                    // all this, i.e. calls those
+                                    // functions that actually do the
+                                    // work, and finally collects the
+                                    // results.
+
+    template <int dim>
+    void
+    WeightedResidual<dim>::
+    estimate_error (Vector<float> &error_indicators) const
+    {
+      const PrimalSolver<dim> &primal_solver = *this;
+      const DualSolver<dim>   &dual_solver   = *this;
+
+                                      // The first task in computing
+                                      // the error is to set up vectors
+                                      // that denote the primal
+                                      // solution, and the weights
+                                      // (z-z_h)=(z-I_hz), both in the
+                                      // finite element space for which
+                                      // we have computed the dual
+                                      // solution. For this, we have to
+                                      // interpolate the primal
+                                      // solution to the dual finite
+                                      // element space, and to subtract
+                                      // the interpolation of the
+                                      // computed dual solution to the
+                                      // primal finite element
+                                      // space. Fortunately, the
+                                      // library provides functions for
+                                      // the interpolation into larger
+                                      // or smaller finite element
+                                      // spaces, so this is mostly
+                                      // obvious.
+                                      //
+                                      // First, let's do that for the
+                                      // primal solution: it is
+                                      // cell-wise interpolated into
+                                      // the finite element space in
+                                      // which we have solved the dual
+                                      // problem: But, again as in the
+                                      // <code>WeightedResidual::output_solution</code>
+                                      // function we first need to
+                                      // create a ConstraintMatrix
+                                      // including the hanging node
+                                      // constraints, but this time of
+                                      // the dual finite element space.
+      ConstraintMatrix dual_hanging_node_constraints;
+      DoFTools::make_hanging_node_constraints (dual_solver.dof_handler,
+                                              dual_hanging_node_constraints);
+      dual_hanging_node_constraints.close();
+      Vector<double> primal_solution (dual_solver.dof_handler.n_dofs());
+      FETools::interpolate (primal_solver.dof_handler,
+                           primal_solver.solution,
+                           dual_solver.dof_handler,
+                           dual_hanging_node_constraints,
+                           primal_solution);
+
+                                      // Then for computing the
+                                      // interpolation of the
+                                      // numerically approximated dual
+                                      // solution z into the finite
+                                      // element space of the primal
+                                      // solution and subtracting it
+                                      // from z: use the
+                                      // <code>interpolate_difference</code>
+                                      // function, that gives (z-I_hz)
+                                      // in the element space of the
+                                      // dual solution.
+      ConstraintMatrix primal_hanging_node_constraints;
+      DoFTools::make_hanging_node_constraints (primal_solver.dof_handler,
+                                              primal_hanging_node_constraints);
+      primal_hanging_node_constraints.close();
+      Vector<double> dual_weights (dual_solver.dof_handler.n_dofs());
+      FETools::interpolation_difference (dual_solver.dof_handler,
+                                        dual_hanging_node_constraints,
+                                        dual_solver.solution,
+                                        primal_solver.dof_handler,
+                                        primal_hanging_node_constraints,
+                                        dual_weights);
+
+                                      // Note that this could probably
+                                      // have been more efficient since
+                                      // those constraints have been
+                                      // used previously when
+                                      // assembling matrix and right
+                                      // hand side for the primal
+                                      // problem and writing out the
+                                      // dual solution. We leave the
+                                      // optimization of the program in
+                                      // this respect as an exercise.
+
+                                      // Having computed the dual
+                                      // weights we now proceed with
+                                      // computing the cell and face
+                                      // residuals of the primal
+                                      // solution. First we set up a
+                                      // map between face iterators and
+                                      // their jump term contributions
+                                      // of faces to the error
+                                      // estimator. The reason is that
+                                      // we compute the jump terms only
+                                      // once, from one side of the
+                                      // face, and want to collect them
+                                      // only afterwards when looping
+                                      // over all cells a second time.
+                                      //
+                                      // We initialize this map already
+                                      // with a value of -1e20 for all
+                                      // faces, since this value will
+                                      // strike in the results if
+                                      // something should go wrong and
+                                      // we fail to compute the value
+                                      // for a face for some
+                                      // reason. Secondly, we
+                                      // initialize the map once before
+                                      // we branch to different threads
+                                      // since this way the map's
+                                      // structure is no more modified
+                                      // by the individual threads,
+                                      // only existing entries are set
+                                      // to new values. This relieves
+                                      // us from the necessity to
+                                      // synchronise the threads
+                                      // through a mutex each time they
+                                      // write to (and modify the
+                                      // structure of) this map.
+      FaceIntegrals face_integrals;
+      for (active_cell_iterator cell=dual_solver.dof_handler.begin_active();
+          cell!=dual_solver.dof_handler.end();
+          ++cell)
        for (unsigned int face_no=0;
             face_no<GeometryInfo<dim>::faces_per_cell;
             ++face_no)
+         face_integrals[cell->face(face_no)] = -1e20;
+
+                                      // Then set up a vector with
+                                      // error indicators.  Reserve one
+                                      // slot for each cell and set it
+                                      // to zero.
+      error_indicators.reinit (dual_solver.dof_handler
+                              .get_tria().n_active_cells());
+
+                                      // Now start a number of threads
+                                      // which compute the error
+                                      // formula on parts of all the
+                                      // cells, and once they are all
+                                      // started wait until they have
+                                      // all finished:
+      const unsigned int n_threads = multithread_info.n_default_threads;
+      Threads::ThreadGroup<> threads;
+      for (unsigned int i=0; i<n_threads; ++i)
+       threads += Threads::new_thread (&WeightedResidual<dim>::estimate_some,
+                                       *this,
+                                       primal_solution,
+                                       dual_weights,
+                                       n_threads, i,
+                                       error_indicators,
+                                       face_integrals);
+      threads.join_all();
+
+                                      // Once the error contributions
+                                      // are computed, sum them up. For
+                                      // this, note that the cell terms
+                                      // are already set, and that only
+                                      // the edge terms need to be
+                                      // collected. Thus, loop over all
+                                      // cells and their faces, make
+                                      // sure that the contributions of
+                                      // each of the faces are there,
+                                      // and add them up. Only take
+                                      // minus one half of the jump
+                                      // term, since the other half
+                                      // will be taken by the
+                                      // neighboring cell.
+      unsigned int present_cell=0;
+      for (active_cell_iterator cell=dual_solver.dof_handler.begin_active();
+          cell!=dual_solver.dof_handler.end();
+          ++cell, ++present_cell)
+       for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell;
+            ++face_no)
          {
-                                            // First, if this face is
-                                            // part of the boundary,
-                                            // then there is nothing
-                                            // to do. However, to
-                                            // make things easier
-                                            // when summing up the
-                                            // contributions of the
-                                            // faces of cells, we
-                                            // enter this face into
-                                            // the list of faces with
-                                            // a zero contribution to
-                                            // the error.
-           if (cell->face(face_no)->at_boundary()) 
-             {
-               face_integrals[cell->face(face_no)] = 0;
+           Assert(face_integrals.find(cell->face(face_no)) !=
+                  face_integrals.end(),
+                  ExcInternalError());
+           error_indicators(present_cell)
+             -= 0.5*face_integrals[cell->face(face_no)];
+         }
+      std::cout << "   Estimated error="
+               << std::accumulate (error_indicators.begin(),
+                                   error_indicators.end(), 0.)
+               << std::endl;
+    }
+
+
+                                    // @sect4{Estimating on a subset of cells}
+
+                                    // Next we have the function that
+                                    // is called to estimate the error
+                                    // on a subset of cells. The
+                                    // function may be called multiply
+                                    // if the library was configured to
+                                    // use multi-threading. Here it
+                                    // goes:
+    template <int dim>
+    void
+    WeightedResidual<dim>::
+    estimate_some (const Vector<double> &primal_solution,
+                  const Vector<double> &dual_weights,
+                  const unsigned int    n_threads,
+                  const unsigned int    this_thread,
+                  Vector<float>        &error_indicators,
+                  FaceIntegrals        &face_integrals) const
+    {
+      const PrimalSolver<dim> &primal_solver = *this;
+      const DualSolver<dim>   &dual_solver   = *this;
+
+                                      // At the beginning, we
+                                      // initialize two variables for
+                                      // each thread which may be
+                                      // running this function. The
+                                      // reason for these functions was
+                                      // discussed above, when the
+                                      // respective classes were
+                                      // discussed, so we here only
+                                      // point out that since they are
+                                      // local to the function that is
+                                      // spawned when running more than
+                                      // one thread, the data of these
+                                      // objects exists actually once
+                                      // per thread, so we don't have
+                                      // to take care about
+                                      // synchronising access to them.
+      CellData cell_data (*dual_solver.fe,
+                         *dual_solver.quadrature,
+                         *primal_solver.rhs_function);
+      FaceData face_data (*dual_solver.fe,
+                         *dual_solver.face_quadrature);
+
+                                      // Then calculate the start cell
+                                      // for this thread. We let the
+                                      // different threads run on
+                                      // interleaved cells, i.e. for
+                                      // example if we have 4 threads,
+                                      // then the first thread treates
+                                      // cells 0, 4, 8, etc, while the
+                                      // second threads works on cells 1,
+                                      // 5, 9, and so on. The reason is
+                                      // that it takes vastly more time
+                                      // to work on cells with hanging
+                                      // nodes than on regular cells, but
+                                      // such cells are not evenly
+                                      // distributed across the range of
+                                      // cell iterators, so in order to
+                                      // have the different threads do
+                                      // approximately the same amount of
+                                      // work, we have to let them work
+                                      // interleaved to the effect of a
+                                      // pseudorandom distribution of the
+                                      // `hard' cells to the different
+                                      // threads.
+      active_cell_iterator cell=dual_solver.dof_handler.begin_active();
+      for (unsigned int t=0;
+          (t<this_thread) && (cell!=dual_solver.dof_handler.end());
+          ++t, ++cell)
+       ;
+
+                                      // If there are no cells for this
+                                      // thread (for example if there
+                                      // are a total of less cells than
+                                      // there are threads), then go
+                                      // back right now
+      if (cell == dual_solver.dof_handler.end())
+       return;
+
+                                      // Next loop over all cells. The
+                                      // check for loop end is done at
+                                      // the end of the loop, along
+                                      // with incrementing the loop
+                                      // index.
+      for (unsigned int cell_index=this_thread; true; )
+       {
+                                          // First task on each cell is
+                                          // to compute the cell
+                                          // residual contributions of
+                                          // this cell, and put them
+                                          // into the
+                                          // <code>error_indicators</code>
+                                          // variable:
+         integrate_over_cell (cell, cell_index,
+                              primal_solution,
+                              dual_weights,
+                              cell_data,
+                              error_indicators);
+
+                                          // After computing the cell
+                                          // terms, turn to the face
+                                          // terms. For this, loop over
+                                          // all faces of the present
+                                          // cell, and see whether
+                                          // something needs to be
+                                          // computed on it:
+         for (unsigned int face_no=0;
+              face_no<GeometryInfo<dim>::faces_per_cell;
+              ++face_no)
+           {
+                                              // First, if this face is
+                                              // part of the boundary,
+                                              // then there is nothing
+                                              // to do. However, to
+                                              // make things easier
+                                              // when summing up the
+                                              // contributions of the
+                                              // faces of cells, we
+                                              // enter this face into
+                                              // the list of faces with
+                                              // a zero contribution to
+                                              // the error.
+             if (cell->face(face_no)->at_boundary())
+               {
+                 face_integrals[cell->face(face_no)] = 0;
+                 continue;
+               }
+
+                                              // Next, note that since
+                                              // we want to compute the
+                                              // jump terms on each
+                                              // face only once
+                                              // although we access it
+                                              // twice (if it is not at
+                                              // the boundary), we have
+                                              // to define some rules
+                                              // who is responsible for
+                                              // computing on a face:
+                                              //
+                                              // First, if the
+                                              // neighboring cell is on
+                                              // the same level as this
+                                              // one, i.e. neither
+                                              // further refined not
+                                              // coarser, then the one
+                                              // with the lower index
+                                              // within this level does
+                                              // the work. In other
+                                              // words: if the other
+                                              // one has a lower index,
+                                              // then skip work on this
+                                              // face:
+             if ((cell->neighbor(face_no)->has_children() == false) &&
+                 (cell->neighbor(face_no)->level() == cell->level()) &&
+                 (cell->neighbor(face_no)->index() < cell->index()))
                continue;
-             }
-           
-                                            // Next, note that since
-                                            // we want to compute the
-                                            // jump terms on each
-                                            // face only once
-                                            // although we access it
-                                            // twice (if it is not at
-                                            // the boundary), we have
-                                            // to define some rules
-                                            // who is responsible for
-                                            // computing on a face:
-                                            //
-                                            // First, if the
-                                            // neighboring cell is on
-                                            // the same level as this
-                                            // one, i.e. neither
-                                            // further refined not
-                                            // coarser, then the one
-                                            // with the lower index
-                                            // within this level does
-                                            // the work. In other
-                                            // words: if the other
-                                            // one has a lower index,
-                                            // then skip work on this
-                                            // face:
-           if ((cell->neighbor(face_no)->has_children() == false) &&
-               (cell->neighbor(face_no)->level() == cell->level()) &&
-               (cell->neighbor(face_no)->index() < cell->index()))
-             continue;
-
-                                            // Likewise, we always
-                                            // work from the coarser
-                                            // cell if this and its
-                                            // neighbor differ in
-                                            // refinement. Thus, if
-                                            // the neighboring cell
-                                            // is less refined than
-                                            // the present one, then
-                                            // do nothing since we
-                                            // integrate over the
-                                            // subfaces when we visit
-                                            // the coarse cell.
-           if (cell->at_boundary(face_no) == false)
-             if (cell->neighbor(face_no)->level() < cell->level())
-               continue;         
-
-
-                                            // Now we know that we
-                                            // are in charge here, so
-                                            // actually compute the
-                                            // face jump terms. If
-                                            // the face is a regular
-                                            // one, i.e.  the other
-                                            // side's cell is neither
-                                            // coarser not finer than
-                                            // this cell, then call
-                                            // one function, and if
-                                            // the cell on the other
-                                            // side is further
-                                            // refined, then use
-                                            // another function. Note
-                                            // that the case that the
-                                            // cell on the other side
-                                            // is coarser cannot
-                                            // happen since we have
-                                            // decided above that we
-                                            // handle this case when
-                                            // we pass over that
-                                            // other cell.
-           if (cell->face(face_no)->has_children() == false)
-             integrate_over_regular_face (cell, face_no,
-                                          primal_solution,
-                                          dual_weights,
-                                          face_data,
-                                          face_integrals);       
-           else
-             integrate_over_irregular_face (cell, face_no,
+
+                                              // Likewise, we always
+                                              // work from the coarser
+                                              // cell if this and its
+                                              // neighbor differ in
+                                              // refinement. Thus, if
+                                              // the neighboring cell
+                                              // is less refined than
+                                              // the present one, then
+                                              // do nothing since we
+                                              // integrate over the
+                                              // subfaces when we visit
+                                              // the coarse cell.
+             if (cell->at_boundary(face_no) == false)
+               if (cell->neighbor(face_no)->level() < cell->level())
+                 continue;
+
+
+                                              // Now we know that we
+                                              // are in charge here, so
+                                              // actually compute the
+                                              // face jump terms. If
+                                              // the face is a regular
+                                              // one, i.e.  the other
+                                              // side's cell is neither
+                                              // coarser not finer than
+                                              // this cell, then call
+                                              // one function, and if
+                                              // the cell on the other
+                                              // side is further
+                                              // refined, then use
+                                              // another function. Note
+                                              // that the case that the
+                                              // cell on the other side
+                                              // is coarser cannot
+                                              // happen since we have
+                                              // decided above that we
+                                              // handle this case when
+                                              // we pass over that
+                                              // other cell.
+             if (cell->face(face_no)->has_children() == false)
+               integrate_over_regular_face (cell, face_no,
                                             primal_solution,
                                             dual_weights,
                                             face_data,
                                             face_integrals);
-         }
-
-                                        // After computing the cell
-                                        // contributions and looping
-                                        // over the faces, go to the
-                                        // next cell for this
-                                        // thread. Note again that
-                                        // the cells for each of the
-                                        // threads are interleaved.
-                                        // If we are at the end of
-                                        // our workload, jump out
-                                        // of the loop.
-       for (unsigned int t=0;
-            ((t<n_threads) && (cell!=dual_solver.dof_handler.end()));
-            ++t, ++cell, ++cell_index)
-         ;
-       
-       if (cell == dual_solver.dof_handler.end())
-         break;
-      }
-  }
-
+             else
+               integrate_over_irregular_face (cell, face_no,
+                                              primal_solution,
+                                              dual_weights,
+                                              face_data,
+                                              face_integrals);
+           }
 
-                                  // @sect4{Computing cell term error contributions}
+                                          // After computing the cell
+                                          // contributions and looping
+                                          // over the faces, go to the
+                                          // next cell for this
+                                          // thread. Note again that
+                                          // the cells for each of the
+                                          // threads are interleaved.
+                                          // If we are at the end of
+                                          // our workload, jump out
+                                          // of the loop.
+         for (unsigned int t=0;
+              ((t<n_threads) && (cell!=dual_solver.dof_handler.end()));
+              ++t, ++cell, ++cell_index)
+           ;
+
+         if (cell == dual_solver.dof_handler.end())
+           break;
+       }
+    }
 
-                                  // As for the actual computation of
-                                  // the error contributions, first
-                                  // turn to the cell terms:
-  template <int dim>
-  void WeightedResidual<dim>::
-  integrate_over_cell (const active_cell_iterator &cell,
-                      const unsigned int          cell_index,
-                      const Vector<double>       &primal_solution,
-                      const Vector<double>       &dual_weights,
-                      CellData                   &cell_data,
-                      Vector<float>              &error_indicators) const
-  {
-                                    // The tasks to be done are what
-                                    // appears natural from looking
-                                    // at the error estimation
-                                    // formula: first get the
-                                    // right hand side and
-                                    // Laplacian of the numerical
-                                    // solution at the quadrature
-                                    // points for the cell residual,
-    cell_data.fe_values.reinit (cell);
-    cell_data.right_hand_side
-      ->value_list (cell_data.fe_values.get_quadrature_points(),
-                   cell_data.rhs_values);
-    cell_data.fe_values.get_function_laplacians (primal_solution,
-                                                cell_data.cell_laplacians);
-
-                                    // ...then get the dual weights...
-    cell_data.fe_values.get_function_values (dual_weights,
-                                            cell_data.dual_weights);
-
-                                    // ...and finally build the sum
-                                    // over all quadrature points and
-                                    // store it with the present
-                                    // cell:
-    double sum = 0;
-    for (unsigned int p=0; p<cell_data.fe_values.n_quadrature_points; ++p)
-      sum += ((cell_data.rhs_values[p]+cell_data.cell_laplacians[p]) *
-             cell_data.dual_weights[p] *
-             cell_data.fe_values.JxW (p));
-    error_indicators(cell_index) += sum;
-  }
 
+                                    // @sect4{Computing cell term error contributions}
 
-                                  // @sect4{Computing edge term error contributions -- 1}
-  
-                                  // On the other hand, computation
-                                  // of the edge terms for the error
-                                  // estimate is not so
-                                  // simple. First, we have to
-                                  // distinguish between faces with
-                                  // and without hanging
-                                  // nodes. Because it is the simple
-                                  // case, we first consider the case
-                                  // without hanging nodes on a face
-                                  // (let's call this the `regular'
-                                  // case):
-  template <int dim>
-  void WeightedResidual<dim>::
-  integrate_over_regular_face (const active_cell_iterator &cell,
-                              const unsigned int          face_no,
-                              const Vector<double>       &primal_solution,
-                              const Vector<double>       &dual_weights,
-                              FaceData                   &face_data,
-                              FaceIntegrals              &face_integrals) const
-  {
-    const unsigned int
-      n_q_points = face_data.fe_face_values_cell.n_quadrature_points;
-
-                                    // The first step is to get the
-                                    // values of the gradients at the
-                                    // quadrature points of the
-                                    // finite element field on the
-                                    // present cell. For this,
-                                    // initialize the
-                                    // <code>FEFaceValues</code> object
-                                    // corresponding to this side of
-                                    // the face, and extract the
-                                    // gradients using that
-                                    // object.
-    face_data.fe_face_values_cell.reinit (cell, face_no);
-    face_data.fe_face_values_cell.get_function_grads (primal_solution,
-                                                     face_data.cell_grads);
-
-                                    // The second step is then to
-                                    // extract the gradients of the
-                                    // finite element solution at the
-                                    // quadrature points on the other
-                                    // side of the face, i.e. from
-                                    // the neighboring cell.
-                                    //
-                                    // For this, do a sanity check
-                                    // before: make sure that the
-                                    // neigbor actually exists (yes,
-                                    // we should not have come here
-                                    // if the neighbor did not exist,
-                                    // but in complicated software
-                                    // there are bugs, so better
-                                    // check this), and if this is
-                                    // not the case throw an error.
-    Assert (cell->neighbor(face_no).state() == IteratorState::valid,
-           ExcInternalError());
-                                    // If we have that, then we need
-                                    // to find out with which face of
-                                    // the neighboring cell we have
-                                    // to work, i.e. the
-                                    // <code>home-many</code>the neighbor the
-                                    // present cell is of the cell
-                                    // behind the present face. For
-                                    // this, there is a function, and
-                                    // we put the result into a
-                                    // variable with the name
-                                    // <code>neighbor_neighbor</code>:
-    const unsigned int
-      neighbor_neighbor = cell->neighbor_of_neighbor (face_no);
-                                    // Then define an abbreviation
-                                    // for the neigbor cell,
-                                    // initialize the
-                                    // <code>FEFaceValues</code> object on
-                                    // that cell, and extract the
-                                    // gradients on that cell:
-    const active_cell_iterator neighbor = cell->neighbor(face_no);
-    face_data.fe_face_values_neighbor.reinit (neighbor, neighbor_neighbor);      
-    face_data.fe_face_values_neighbor.get_function_grads (primal_solution,
-                                                         face_data.neighbor_grads);
-
-                                    // Now that we have the gradients
-                                    // on this and the neighboring
-                                    // cell, compute the jump
-                                    // residual by multiplying the
-                                    // jump in the gradient with the
-                                    // normal vector:
-    for (unsigned int p=0; p<n_q_points; ++p)
-      face_data.jump_residual[p]
-       = ((face_data.cell_grads[p] - face_data.neighbor_grads[p]) *
-          face_data.fe_face_values_cell.normal_vector(p));
-
-                                    // Next get the dual weights for
-                                    // this face:
-    face_data.fe_face_values_cell.get_function_values (dual_weights,
-                                                      face_data.dual_weights);
-    
-                                    // Finally, we have to compute
-                                    // the sum over jump residuals,
-                                    // dual weights, and quadrature
-                                    // weights, to get the result for
-                                    // this face:
-    double face_integral = 0;
-    for (unsigned int p=0; p<n_q_points; ++p)
-      face_integral += (face_data.jump_residual[p] *
-                       face_data.dual_weights[p]  *
-                       face_data.fe_face_values_cell.JxW(p));
-
-                                    // Double check that the element
-                                    // already exists and that it was
-                                    // not already written to...
-    Assert (face_integrals.find (cell->face(face_no)) != face_integrals.end(),
-           ExcInternalError());
-    Assert (face_integrals[cell->face(face_no)] == -1e20,
-           ExcInternalError());
-
-                                    // ...then store computed value
-                                    // at assigned location. Note
-                                    // that the stored value does not
-                                    // contain the factor 1/2 that
-                                    // appears in the error
-                                    // representation. The reason is
-                                    // that the term actually does
-                                    // not have this factor if we
-                                    // loop over all faces in the
-                                    // triangulation, but only
-                                    // appears if we write it as a
-                                    // sum over all cells and all
-                                    // faces of each cell; we thus
-                                    // visit the same face twice. We
-                                    // take account of this by using
-                                    // this factor -1/2 later, when we
-                                    // sum up the contributions for
-                                    // each cell individually.
-    face_integrals[cell->face(face_no)] = face_integral;
-  }
+                                    // As for the actual computation of
+                                    // the error contributions, first
+                                    // turn to the cell terms:
+    template <int dim>
+    void WeightedResidual<dim>::
+    integrate_over_cell (const active_cell_iterator &cell,
+                        const unsigned int          cell_index,
+                        const Vector<double>       &primal_solution,
+                        const Vector<double>       &dual_weights,
+                        CellData                   &cell_data,
+                        Vector<float>              &error_indicators) const
+    {
+                                      // The tasks to be done are what
+                                      // appears natural from looking
+                                      // at the error estimation
+                                      // formula: first get the
+                                      // right hand side and
+                                      // Laplacian of the numerical
+                                      // solution at the quadrature
+                                      // points for the cell residual,
+      cell_data.fe_values.reinit (cell);
+      cell_data.right_hand_side
+       ->value_list (cell_data.fe_values.get_quadrature_points(),
+                     cell_data.rhs_values);
+      cell_data.fe_values.get_function_laplacians (primal_solution,
+                                                  cell_data.cell_laplacians);
+
+                                      // ...then get the dual weights...
+      cell_data.fe_values.get_function_values (dual_weights,
+                                              cell_data.dual_weights);
+
+                                      // ...and finally build the sum
+                                      // over all quadrature points and
+                                      // store it with the present
+                                      // cell:
+      double sum = 0;
+      for (unsigned int p=0; p<cell_data.fe_values.n_quadrature_points; ++p)
+       sum += ((cell_data.rhs_values[p]+cell_data.cell_laplacians[p]) *
+               cell_data.dual_weights[p] *
+               cell_data.fe_values.JxW (p));
+      error_indicators(cell_index) += sum;
+    }
 
 
-                                  // @sect4{Computing edge term error contributions -- 2}
-  
-                                  // We are still missing the case of
-                                  // faces with hanging nodes. This
-                                  // is what is covered in this
-                                  // function:
-  template <int dim>
-  void WeightedResidual<dim>::
-  integrate_over_irregular_face (const active_cell_iterator &cell,
+                                    // @sect4{Computing edge term error contributions -- 1}
+
+                                    // On the other hand, computation
+                                    // of the edge terms for the error
+                                    // estimate is not so
+                                    // simple. First, we have to
+                                    // distinguish between faces with
+                                    // and without hanging
+                                    // nodes. Because it is the simple
+                                    // case, we first consider the case
+                                    // without hanging nodes on a face
+                                    // (let's call this the `regular'
+                                    // case):
+    template <int dim>
+    void WeightedResidual<dim>::
+    integrate_over_regular_face (const active_cell_iterator &cell,
                                 const unsigned int          face_no,
                                 const Vector<double>       &primal_solution,
                                 const Vector<double>       &dual_weights,
                                 FaceData                   &face_data,
                                 FaceIntegrals              &face_integrals) const
+    {
+      const unsigned int
+       n_q_points = face_data.fe_face_values_cell.n_quadrature_points;
+
+                                      // The first step is to get the
+                                      // values of the gradients at the
+                                      // quadrature points of the
+                                      // finite element field on the
+                                      // present cell. For this,
+                                      // initialize the
+                                      // <code>FEFaceValues</code> object
+                                      // corresponding to this side of
+                                      // the face, and extract the
+                                      // gradients using that
+                                      // object.
+      face_data.fe_face_values_cell.reinit (cell, face_no);
+      face_data.fe_face_values_cell.get_function_grads (primal_solution,
+                                                       face_data.cell_grads);
+
+                                      // The second step is then to
+                                      // extract the gradients of the
+                                      // finite element solution at the
+                                      // quadrature points on the other
+                                      // side of the face, i.e. from
+                                      // the neighboring cell.
+                                      //
+                                      // For this, do a sanity check
+                                      // before: make sure that the
+                                      // neigbor actually exists (yes,
+                                      // we should not have come here
+                                      // if the neighbor did not exist,
+                                      // but in complicated software
+                                      // there are bugs, so better
+                                      // check this), and if this is
+                                      // not the case throw an error.
+      Assert (cell->neighbor(face_no).state() == IteratorState::valid,
+             ExcInternalError());
+                                      // If we have that, then we need
+                                      // to find out with which face of
+                                      // the neighboring cell we have
+                                      // to work, i.e. the
+                                      // <code>home-many</code>the neighbor the
+                                      // present cell is of the cell
+                                      // behind the present face. For
+                                      // this, there is a function, and
+                                      // we put the result into a
+                                      // variable with the name
+                                      // <code>neighbor_neighbor</code>:
+      const unsigned int
+       neighbor_neighbor = cell->neighbor_of_neighbor (face_no);
+                                      // Then define an abbreviation
+                                      // for the neigbor cell,
+                                      // initialize the
+                                      // <code>FEFaceValues</code> object on
+                                      // that cell, and extract the
+                                      // gradients on that cell:
+      const active_cell_iterator neighbor = cell->neighbor(face_no);
+      face_data.fe_face_values_neighbor.reinit (neighbor, neighbor_neighbor);
+      face_data.fe_face_values_neighbor.get_function_grads (primal_solution,
+                                                           face_data.neighbor_grads);
+
+                                      // Now that we have the gradients
+                                      // on this and the neighboring
+                                      // cell, compute the jump
+                                      // residual by multiplying the
+                                      // jump in the gradient with the
+                                      // normal vector:
+      for (unsigned int p=0; p<n_q_points; ++p)
+       face_data.jump_residual[p]
+         = ((face_data.cell_grads[p] - face_data.neighbor_grads[p]) *
+            face_data.fe_face_values_cell.normal_vector(p));
+
+                                      // Next get the dual weights for
+                                      // this face:
+      face_data.fe_face_values_cell.get_function_values (dual_weights,
+                                                        face_data.dual_weights);
+
+                                      // Finally, we have to compute
+                                      // the sum over jump residuals,
+                                      // dual weights, and quadrature
+                                      // weights, to get the result for
+                                      // this face:
+      double face_integral = 0;
+      for (unsigned int p=0; p<n_q_points; ++p)
+       face_integral += (face_data.jump_residual[p] *
+                         face_data.dual_weights[p]  *
+                         face_data.fe_face_values_cell.JxW(p));
+
+                                      // Double check that the element
+                                      // already exists and that it was
+                                      // not already written to...
+      Assert (face_integrals.find (cell->face(face_no)) != face_integrals.end(),
+             ExcInternalError());
+      Assert (face_integrals[cell->face(face_no)] == -1e20,
+             ExcInternalError());
+
+                                      // ...then store computed value
+                                      // at assigned location. Note
+                                      // that the stored value does not
+                                      // contain the factor 1/2 that
+                                      // appears in the error
+                                      // representation. The reason is
+                                      // that the term actually does
+                                      // not have this factor if we
+                                      // loop over all faces in the
+                                      // triangulation, but only
+                                      // appears if we write it as a
+                                      // sum over all cells and all
+                                      // faces of each cell; we thus
+                                      // visit the same face twice. We
+                                      // take account of this by using
+                                      // this factor -1/2 later, when we
+                                      // sum up the contributions for
+                                      // each cell individually.
+      face_integrals[cell->face(face_no)] = face_integral;
+    }
+
+
+                                    // @sect4{Computing edge term error contributions -- 2}
+
+                                    // We are still missing the case of
+                                    // faces with hanging nodes. This
+                                    // is what is covered in this
+                                    // function:
+    template <int dim>
+    void WeightedResidual<dim>::
+    integrate_over_irregular_face (const active_cell_iterator &cell,
+                                  const unsigned int          face_no,
+                                  const Vector<double>       &primal_solution,
+                                  const Vector<double>       &dual_weights,
+                                  FaceData                   &face_data,
+                                  FaceIntegrals              &face_integrals) const
+    {
+                                      // First again two abbreviations,
+                                      // and some consistency checks
+                                      // whether the function is called
+                                      // only on faces for which it is
+                                      // supposed to be called:
+      const unsigned int
+       n_q_points = face_data.fe_face_values_cell.n_quadrature_points;
+
+      const typename DoFHandler<dim>::face_iterator
+       face = cell->face(face_no);
+      const typename DoFHandler<dim>::cell_iterator
+       neighbor = cell->neighbor(face_no);
+      Assert (neighbor.state() == IteratorState::valid,
+             ExcInternalError());
+      Assert (neighbor->has_children(),
+             ExcInternalError());
+
+                                      // Then find out which neighbor
+                                      // the present cell is of the
+                                      // adjacent cell. Note that we
+                                      // will operator on the children
+                                      // of this adjacent cell, but
+                                      // that their orientation is the
+                                      // same as that of their mother,
+                                      // i.e. the neigbor direction is
+                                      // the same.
+      const unsigned int
+       neighbor_neighbor = cell->neighbor_of_neighbor (face_no);
+
+                                      // Then simply do everything we
+                                      // did in the previous function
+                                      // for one face for all the
+                                      // sub-faces now:
+      for (unsigned int subface_no=0;
+          subface_no<face->n_children(); ++subface_no)
+       {
+                                          // Start with some checks
+                                          // again: get an iterator
+                                          // pointing to the cell
+                                          // behind the present subface
+                                          // and check whether its face
+                                          // is a subface of the one we
+                                          // are considering. If that
+                                          // were not the case, then
+                                          // there would be either a
+                                          // bug in the
+                                          // <code>neighbor_neighbor</code>
+                                          // function called above, or
+                                          // -- worse -- some function
+                                          // in the library did not
+                                          // keep to some underlying
+                                          // assumptions about cells,
+                                          // their children, and their
+                                          // faces. In any case, even
+                                          // though this assertion
+                                          // should not be triggered,
+                                          // it does not harm to be
+                                          // cautious, and in optimized
+                                          // mode computations the
+                                          // assertion will be removed
+                                          // anyway.
+         const active_cell_iterator neighbor_child
+           = cell->neighbor_child_on_subface (face_no, subface_no);
+         Assert (neighbor_child->face(neighbor_neighbor) ==
+                 cell->face(face_no)->child(subface_no),
+                 ExcInternalError());
+
+                                          // Now start the work by
+                                          // again getting the gradient
+                                          // of the solution first at
+                                          // this side of the
+                                          // interface,
+         face_data.fe_subface_values_cell.reinit (cell, face_no, subface_no);
+         face_data.fe_subface_values_cell.get_function_grads (primal_solution,
+                                                              face_data.cell_grads);
+                                          // then at the other side,
+         face_data.fe_face_values_neighbor.reinit (neighbor_child,
+                                                   neighbor_neighbor);
+         face_data.fe_face_values_neighbor.get_function_grads (primal_solution,
+                                                               face_data.neighbor_grads);
+
+                                          // and finally building the
+                                          // jump residuals. Since we
+                                          // take the normal vector
+                                          // from the other cell this
+                                          // time, revert the sign of
+                                          // the first term compared to
+                                          // the other function:
+         for (unsigned int p=0; p<n_q_points; ++p)
+           face_data.jump_residual[p]
+             = ((face_data.neighbor_grads[p] - face_data.cell_grads[p]) *
+                face_data.fe_face_values_neighbor.normal_vector(p));
+
+                                          // Then get dual weights:
+         face_data.fe_face_values_neighbor.get_function_values (dual_weights,
+                                                                face_data.dual_weights);
+
+                                          // At last, sum up the
+                                          // contribution of this
+                                          // sub-face, and set it in
+                                          // the global map:
+         double face_integral = 0;
+         for (unsigned int p=0; p<n_q_points; ++p)
+           face_integral += (face_data.jump_residual[p] *
+                             face_data.dual_weights[p] *
+                             face_data.fe_face_values_neighbor.JxW(p));
+         face_integrals[neighbor_child->face(neighbor_neighbor)]
+           = face_integral;
+       }
+
+                                      // Once the contributions of all
+                                      // sub-faces are computed, loop
+                                      // over all sub-faces to collect
+                                      // and store them with the mother
+                                      // face for simple use when later
+                                      // collecting the error terms of
+                                      // cells. Again make safety
+                                      // checks that the entries for
+                                      // the sub-faces have been
+                                      // computed and do not carry an
+                                      // invalid value.
+      double sum = 0;
+      for (unsigned int subface_no=0;
+          subface_no<face->n_children(); ++subface_no)
+       {
+         Assert (face_integrals.find(face->child(subface_no)) !=
+                 face_integrals.end(),
+                 ExcInternalError());
+         Assert (face_integrals[face->child(subface_no)] != -1e20,
+                 ExcInternalError());
+
+         sum += face_integrals[face->child(subface_no)];
+       }
+                                      // Finally store the value with
+                                      // the parent face.
+      face_integrals[face] = sum;
+    }
+
+  }
+
+
+                                  // @sect3{A simulation framework}
+
+                                  // In the previous example program,
+                                  // we have had two functions that
+                                  // were used to drive the process of
+                                  // solving on subsequently finer
+                                  // grids. We extend this here to
+                                  // allow for a number of parameters
+                                  // to be passed to these functions,
+                                  // and put all of that into framework
+                                  // class.
+                                  //
+                                  // You will have noted that this
+                                  // program is built up of a number of
+                                  // small parts (evaluation functions,
+                                  // solver classes implementing
+                                  // various refinement methods,
+                                  // different dual functionals,
+                                  // different problem and data
+                                  // descriptions), which makes the
+                                  // program relatively simple to
+                                  // extend, but also allows to solve a
+                                  // large number of different problems
+                                  // by replacing one part by
+                                  // another. We reflect this
+                                  // flexibility by declaring a
+                                  // structure in the following
+                                  // framework class that holds a
+                                  // number of parameters that may be
+                                  // set to test various combinations
+                                  // of the parts of this program, and
+                                  // which can be used to test it at
+                                  // various problems and
+                                  // discretizations in a simple way.
+  template <int dim>
+  struct Framework
   {
-                                    // First again two abbreviations,
-                                    // and some consistency checks
-                                    // whether the function is called
-                                    // only on faces for which it is
-                                    // supposed to be called:
-    const unsigned int
-      n_q_points = face_data.fe_face_values_cell.n_quadrature_points;
-
-    const typename DoFHandler<dim>::face_iterator
-      face = cell->face(face_no);    
-    const typename DoFHandler<dim>::cell_iterator
-      neighbor = cell->neighbor(face_no);    
-    Assert (neighbor.state() == IteratorState::valid,
-           ExcInternalError());
-    Assert (neighbor->has_children(),
-           ExcInternalError());
-
-                                    // Then find out which neighbor
-                                    // the present cell is of the
-                                    // adjacent cell. Note that we
-                                    // will operator on the children
-                                    // of this adjacent cell, but
-                                    // that their orientation is the
-                                    // same as that of their mother,
-                                    // i.e. the neigbor direction is
-                                    // the same.
-    const unsigned int
-      neighbor_neighbor = cell->neighbor_of_neighbor (face_no);
-  
-                                    // Then simply do everything we
-                                    // did in the previous function
-                                    // for one face for all the
-                                    // sub-faces now:
-    for (unsigned int subface_no=0;
-        subface_no<face->n_children(); ++subface_no)
+    public:
+                                      // First, we declare two
+                                      // abbreviations for simple use
+                                      // of the respective data types:
+      typedef Evaluation::EvaluationBase<dim> Evaluator;
+      typedef std::list<Evaluator*>           EvaluatorList;
+
+
+                                      // Then we have the structure
+                                      // which declares all the
+                                      // parameters that may be set. In
+                                      // the default constructor of the
+                                      // structure, these values are
+                                      // all set to default values, for
+                                      // simple use.
+      struct ProblemDescription
       {
-                                        // Start with some checks
-                                        // again: get an iterator
-                                        // pointing to the cell
-                                        // behind the present subface
-                                        // and check whether its face
-                                        // is a subface of the one we
-                                        // are considering. If that
-                                        // were not the case, then
-                                        // there would be either a
-                                        // bug in the
-                                        // <code>neighbor_neighbor</code>
-                                        // function called above, or
-                                        // -- worse -- some function
-                                        // in the library did not
-                                        // keep to some underlying
-                                        // assumptions about cells,
-                                        // their children, and their
-                                        // faces. In any case, even
-                                        // though this assertion
-                                        // should not be triggered,
-                                        // it does not harm to be
-                                        // cautious, and in optimized
-                                        // mode computations the
-                                        // assertion will be removed
-                                        // anyway.
-       const active_cell_iterator neighbor_child
-          = cell->neighbor_child_on_subface (face_no, subface_no);
-       Assert (neighbor_child->face(neighbor_neighbor) ==
-               cell->face(face_no)->child(subface_no),
-               ExcInternalError());
-
-                                        // Now start the work by
-                                        // again getting the gradient
-                                        // of the solution first at
-                                        // this side of the
-                                        // interface,
-       face_data.fe_subface_values_cell.reinit (cell, face_no, subface_no);
-       face_data.fe_subface_values_cell.get_function_grads (primal_solution,
-                                                            face_data.cell_grads);
-                                        // then at the other side,
-       face_data.fe_face_values_neighbor.reinit (neighbor_child,
-                                            neighbor_neighbor);
-       face_data.fe_face_values_neighbor.get_function_grads (primal_solution,
-                                                             face_data.neighbor_grads);
-      
-                                        // and finally building the
-                                        // jump residuals. Since we
-                                        // take the normal vector
-                                        // from the other cell this
-                                        // time, revert the sign of
-                                        // the first term compared to
-                                        // the other function:
-       for (unsigned int p=0; p<n_q_points; ++p)
-         face_data.jump_residual[p]
-            = ((face_data.neighbor_grads[p] - face_data.cell_grads[p]) *
-               face_data.fe_face_values_neighbor.normal_vector(p));
-
-                                        // Then get dual weights:
-       face_data.fe_face_values_neighbor.get_function_values (dual_weights,
-                                                              face_data.dual_weights);
-       
-                                        // At last, sum up the
-                                        // contribution of this
-                                        // sub-face, and set it in
-                                        // the global map:
-       double face_integral = 0;
-       for (unsigned int p=0; p<n_q_points; ++p)
-         face_integral += (face_data.jump_residual[p] *
-                           face_data.dual_weights[p] *
-                           face_data.fe_face_values_neighbor.JxW(p));
-       face_integrals[neighbor_child->face(neighbor_neighbor)]
-         = face_integral;
-      }
+                                          // First allow for the
+                                          // degrees of the piecewise
+                                          // polynomials by which the
+                                          // primal and dual problems
+                                          // will be discretized. They
+                                          // default to (bi-,
+                                          // tri-)linear ansatz
+                                          // functions for the primal,
+                                          // and (bi-, tri-)quadratic
+                                          // ones for the dual
+                                          // problem. If a refinement
+                                          // criterion is chosen that
+                                          // does not need the solution
+                                          // of a dual problem, the
+                                          // value of the dual finite
+                                          // element degree is of
+                                          // course ignored.
+         unsigned int primal_fe_degree;
+         unsigned int dual_fe_degree;
+
+                                          // Then have an object that
+                                          // describes the problem
+                                          // type, i.e. right hand
+                                          // side, domain, boundary
+                                          // values, etc. The pointer
+                                          // needed here defaults to
+                                          // the Null pointer, i.e. you
+                                          // will have to set it in
+                                          // actual instances of this
+                                          // object to make it useful.
+         SmartPointer<const Data::SetUpBase<dim> > data;
+
+                                          // Since we allow to use
+                                          // different refinement
+                                          // criteria (global
+                                          // refinement, refinement by
+                                          // the Kelly error indicator,
+                                          // possibly with a weight,
+                                          // and using the dual
+                                          // estimator), define a
+                                          // number of enumeration
+                                          // values, and subsequently a
+                                          // variable of that type. It
+                                          // will default to
+                                          // <code>dual_weighted_error_estimator</code>.
+         enum RefinementCriterion {
+               dual_weighted_error_estimator,
+               global_refinement,
+               kelly_indicator,
+               weighted_kelly_indicator
+         };
+
+         RefinementCriterion refinement_criterion;
+
+                                          // Next, an object that
+                                          // describes the dual
+                                          // functional. It is only
+                                          // needed if the dual
+                                          // weighted residual
+                                          // refinement is chosen, and
+                                          // also defaults to a Null
+                                          // pointer.
+         SmartPointer<const DualFunctional::DualFunctionalBase<dim> > dual_functional;
+
+                                          // Then a list of evaluation
+                                          // objects. Its default value
+                                          // is empty, i.e. no
+                                          // evaluation objects.
+         EvaluatorList evaluator_list;
+
+                                          // Next to last, a function
+                                          // that is used as a weight
+                                          // to the
+                                          // <code>RefinementWeightedKelly</code>
+                                          // class. The default value
+                                          // of this pointer is zero,
+                                          // but you have to set it to
+                                          // some other value if you
+                                          // want to use the
+                                          // <code>weighted_kelly_indicator</code>
+                                          // refinement criterion.
+         SmartPointer<const Function<dim> > kelly_weight;
+
+                                          // Finally, we have a
+                                          // variable that denotes the
+                                          // maximum number of degrees
+                                          // of freedom we allow for
+                                          // the (primal)
+                                          // discretization. If it is
+                                          // exceeded, we stop the
+                                          // process of solving and
+                                          // intermittend mesh
+                                          // refinement. Its default
+                                          // value is 20,000.
+         unsigned int max_degrees_of_freedom;
+
+                                          // Finally the default
+                                          // constructor of this class:
+         ProblemDescription ();
+      };
 
-                                    // Once the contributions of all
-                                    // sub-faces are computed, loop
-                                    // over all sub-faces to collect
-                                    // and store them with the mother
-                                    // face for simple use when later
-                                    // collecting the error terms of
-                                    // cells. Again make safety
-                                    // checks that the entries for
-                                    // the sub-faces have been
-                                    // computed and do not carry an
-                                    // invalid value.
-    double sum = 0;
-    for (unsigned int subface_no=0;
-        subface_no<face->n_children(); ++subface_no) 
-      {
-       Assert (face_integrals.find(face->child(subface_no)) !=
-               face_integrals.end(),
-               ExcInternalError());
-       Assert (face_integrals[face->child(subface_no)] != -1e20,
-               ExcInternalError());
-      
-       sum += face_integrals[face->child(subface_no)];
-      }
-                                    // Finally store the value with
-                                    // the parent face.
-    face_integrals[face] = sum;
-  }
-  
-}
+                                      // The driver framework class
+                                      // only has one method which
+                                      // calls solver and mesh
+                                      // refinement intermittently, and
+                                      // does some other small tasks in
+                                      // between. Since it does not
+                                      // need data besides the
+                                      // parameters given to it, we
+                                      // make it static:
+      static void run (const ProblemDescription &descriptor);
+  };
 
 
-                                // @sect3{A simulation framework}
-
-                                // In the previous example program,
-                                // we have had two functions that
-                                // were used to drive the process of
-                                // solving on subsequently finer
-                                // grids. We extend this here to
-                                // allow for a number of parameters
-                                // to be passed to these functions,
-                                // and put all of that into framework
-                                // class.
-                                //
-                                // You will have noted that this
-                                // program is built up of a number of
-                                // small parts (evaluation functions,
-                                // solver classes implementing
-                                // various refinement methods,
-                                // different dual functionals,
-                                // different problem and data
-                                // descriptions), which makes the
-                                // program relatively simple to
-                                // extend, but also allows to solve a
-                                // large number of different problems
-                                // by replacing one part by
-                                // another. We reflect this
-                                // flexibility by declaring a
-                                // structure in the following
-                                // framework class that holds a
-                                // number of parameters that may be
-                                // set to test various combinations
-                                // of the parts of this program, and
-                                // which can be used to test it at
-                                // various problems and
-                                // discretizations in a simple way.
-template <int dim>
-struct Framework
-{
-  public:
-                                    // First, we declare two
-                                    // abbreviations for simple use
-                                    // of the respective data types:
-    typedef Evaluation::EvaluationBase<dim> Evaluator;
-    typedef std::list<Evaluator*>           EvaluatorList;
-
-
-                                    // Then we have the structure
-                                    // which declares all the
-                                    // parameters that may be set. In
-                                    // the default constructor of the
-                                    // structure, these values are
-                                    // all set to default values, for
-                                    // simple use.
-    struct ProblemDescription 
-    {
-                                        // First allow for the
-                                        // degrees of the piecewise
-                                        // polynomials by which the
-                                        // primal and dual problems
-                                        // will be discretized. They
-                                        // default to (bi-,
-                                        // tri-)linear ansatz
-                                        // functions for the primal,
-                                        // and (bi-, tri-)quadratic
-                                        // ones for the dual
-                                        // problem. If a refinement
-                                        // criterion is chosen that
-                                        // does not need the solution
-                                        // of a dual problem, the
-                                        // value of the dual finite
-                                        // element degree is of
-                                        // course ignored.
-       unsigned int primal_fe_degree;
-       unsigned int dual_fe_degree;
-
-                                        // Then have an object that
-                                        // describes the problem
-                                        // type, i.e. right hand
-                                        // side, domain, boundary
-                                        // values, etc. The pointer
-                                        // needed here defaults to
-                                        // the Null pointer, i.e. you
-                                        // will have to set it in
-                                        // actual instances of this
-                                        // object to make it useful.
-       SmartPointer<const Data::SetUpBase<dim> > data;
-
-                                        // Since we allow to use
-                                        // different refinement
-                                        // criteria (global
-                                        // refinement, refinement by
-                                        // the Kelly error indicator,
-                                        // possibly with a weight,
-                                        // and using the dual
-                                        // estimator), define a
-                                        // number of enumeration
-                                        // values, and subsequently a
-                                        // variable of that type. It
-                                        // will default to
-                                        // <code>dual_weighted_error_estimator</code>.
-       enum RefinementCriterion {
-             dual_weighted_error_estimator,
-             global_refinement,
-             kelly_indicator,
-             weighted_kelly_indicator
-       };
+                                  // As for the implementation, first
+                                  // the constructor of the parameter
+                                  // object, setting all values to
+                                  // their defaults:
+  template <int dim>
+  Framework<dim>::ProblemDescription::ProblemDescription ()
+                 :
+                 primal_fe_degree (1),
+                 dual_fe_degree (2),
+                 refinement_criterion (dual_weighted_error_estimator),
+                 max_degrees_of_freedom (20000)
+  {}
 
-       RefinementCriterion refinement_criterion;
-
-                                        // Next, an object that
-                                        // describes the dual
-                                        // functional. It is only
-                                        // needed if the dual
-                                        // weighted residual
-                                        // refinement is chosen, and
-                                        // also defaults to a Null
-                                        // pointer.
-       SmartPointer<const DualFunctional::DualFunctionalBase<dim> > dual_functional;
-
-                                        // Then a list of evaluation
-                                        // objects. Its default value
-                                        // is empty, i.e. no
-                                        // evaluation objects.
-       EvaluatorList evaluator_list;
-
-                                        // Next to last, a function
-                                        // that is used as a weight
-                                        // to the
-                                        // <code>RefinementWeightedKelly</code>
-                                        // class. The default value
-                                        // of this pointer is zero,
-                                        // but you have to set it to
-                                        // some other value if you
-                                        // want to use the
-                                        // <code>weighted_kelly_indicator</code>
-                                        // refinement criterion.
-       SmartPointer<const Function<dim> > kelly_weight;
-
-                                        // Finally, we have a
-                                        // variable that denotes the
-                                        // maximum number of degrees
-                                        // of freedom we allow for
-                                        // the (primal)
-                                        // discretization. If it is
-                                        // exceeded, we stop the
-                                        // process of solving and
-                                        // intermittend mesh
-                                        // refinement. Its default
-                                        // value is 20,000.
-       unsigned int max_degrees_of_freedom;
-
-                                        // Finally the default
-                                        // constructor of this class:
-       ProblemDescription ();
-    };
 
-                                    // The driver framework class
-                                    // only has one method which
-                                    // calls solver and mesh
-                                    // refinement intermittently, and
-                                    // does some other small tasks in
-                                    // between. Since it does not
-                                    // need data besides the
-                                    // parameters given to it, we
-                                    // make it static:
-    static void run (const ProblemDescription &descriptor);
-};
-
-
-                                // As for the implementation, first
-                                // the constructor of the parameter
-                                // object, setting all values to
-                                // their defaults:
-template <int dim>
-Framework<dim>::ProblemDescription::ProblemDescription ()
-               :
-               primal_fe_degree (1),
-               dual_fe_degree (2),
-               refinement_criterion (dual_weighted_error_estimator),
-               max_degrees_of_freedom (20000)
-{}
-
-
-
-                                // Then the function which drives the
-                                // whole process:
-template <int dim>
-void Framework<dim>::run (const ProblemDescription &descriptor)
-{
-                                  // First create a triangulation
-                                  // from the given data object,
-  Triangulation<dim>
-    triangulation (Triangulation<dim>::smoothing_on_refinement);
-  descriptor.data->create_coarse_grid (triangulation);
-
-                                  // then a set of finite elements
-                                  // and appropriate quadrature
-                                  // formula:
-  const FE_Q<dim>     primal_fe(descriptor.primal_fe_degree);
-  const FE_Q<dim>     dual_fe(descriptor.dual_fe_degree);
-  const QGauss<dim>   quadrature(descriptor.dual_fe_degree+1);
-  const QGauss<dim-1> face_quadrature(descriptor.dual_fe_degree+1);
-
-                                  // Next, select one of the classes
-                                  // implementing different
-                                  // refinement criteria.
-  LaplaceSolver::Base<dim> * solver = 0;
-  switch (descriptor.refinement_criterion)
-    {
-      case ProblemDescription::dual_weighted_error_estimator:
-      {
-       solver
-         = new LaplaceSolver::WeightedResidual<dim> (triangulation,
-                                                     primal_fe,
-                                                     dual_fe,
-                                                     quadrature,
-                                                     face_quadrature,
-                                                     descriptor.data->get_right_hand_side(),
-                                                     descriptor.data->get_boundary_values(),
-                                                     *descriptor.dual_functional);
-       break;
-      }
-       
-      case ProblemDescription::global_refinement:
-      {
-       solver
-         = new LaplaceSolver::RefinementGlobal<dim> (triangulation,
-                                                     primal_fe,
-                                                     quadrature,
-                                                     face_quadrature,
-                                                     descriptor.data->get_right_hand_side(),
-                                                     descriptor.data->get_boundary_values());
-       break;
-      }
-       
-      case ProblemDescription::kelly_indicator:
+
+                                  // Then the function which drives the
+                                  // whole process:
+  template <int dim>
+  void Framework<dim>::run (const ProblemDescription &descriptor)
+  {
+                                    // First create a triangulation
+                                    // from the given data object,
+    Triangulation<dim>
+      triangulation (Triangulation<dim>::smoothing_on_refinement);
+    descriptor.data->create_coarse_grid (triangulation);
+
+                                    // then a set of finite elements
+                                    // and appropriate quadrature
+                                    // formula:
+    const FE_Q<dim>     primal_fe(descriptor.primal_fe_degree);
+    const FE_Q<dim>     dual_fe(descriptor.dual_fe_degree);
+    const QGauss<dim>   quadrature(descriptor.dual_fe_degree+1);
+    const QGauss<dim-1> face_quadrature(descriptor.dual_fe_degree+1);
+
+                                    // Next, select one of the classes
+                                    // implementing different
+                                    // refinement criteria.
+    LaplaceSolver::Base<dim> * solver = 0;
+    switch (descriptor.refinement_criterion)
       {
-       solver
-         = new LaplaceSolver::RefinementKelly<dim> (triangulation,
-                                                    primal_fe,
-                                                    quadrature,
-                                                    face_quadrature,
-                                                    descriptor.data->get_right_hand_side(),
-                                                    descriptor.data->get_boundary_values());
-       break;
+       case ProblemDescription::dual_weighted_error_estimator:
+       {
+         solver
+           = new LaplaceSolver::WeightedResidual<dim> (triangulation,
+                                                       primal_fe,
+                                                       dual_fe,
+                                                       quadrature,
+                                                       face_quadrature,
+                                                       descriptor.data->get_right_hand_side(),
+                                                       descriptor.data->get_boundary_values(),
+                                                       *descriptor.dual_functional);
+         break;
+       }
+
+       case ProblemDescription::global_refinement:
+       {
+         solver
+           = new LaplaceSolver::RefinementGlobal<dim> (triangulation,
+                                                       primal_fe,
+                                                       quadrature,
+                                                       face_quadrature,
+                                                       descriptor.data->get_right_hand_side(),
+                                                       descriptor.data->get_boundary_values());
+         break;
+       }
+
+       case ProblemDescription::kelly_indicator:
+       {
+         solver
+           = new LaplaceSolver::RefinementKelly<dim> (triangulation,
+                                                      primal_fe,
+                                                      quadrature,
+                                                      face_quadrature,
+                                                      descriptor.data->get_right_hand_side(),
+                                                      descriptor.data->get_boundary_values());
+         break;
+       }
+
+       case ProblemDescription::weighted_kelly_indicator:
+       {
+         solver
+           = new LaplaceSolver::RefinementWeightedKelly<dim> (triangulation,
+                                                              primal_fe,
+                                                              quadrature,
+                                                              face_quadrature,
+                                                              descriptor.data->get_right_hand_side(),
+                                                              descriptor.data->get_boundary_values(),
+                                                              *descriptor.kelly_weight);
+         break;
+       }
+
+       default:
+             AssertThrow (false, ExcInternalError());
       }
 
-      case ProblemDescription::weighted_kelly_indicator:
+                                    // Now that all objects are in
+                                    // place, run the main loop. The
+                                    // stopping criterion is
+                                    // implemented at the bottom of the
+                                    // loop.
+                                    //
+                                    // In the loop, first set the new
+                                    // cycle number, then solve the
+                                    // problem, output its solution(s),
+                                    // apply the evaluation objects to
+                                    // it, then decide whether we want
+                                    // to refine the mesh further and
+                                    // solve again on this mesh, or
+                                    // jump out of the loop.
+    for (unsigned int step=0; true; ++step)
       {
-       solver
-         = new LaplaceSolver::RefinementWeightedKelly<dim> (triangulation,
-                                                            primal_fe,
-                                                            quadrature,
-                                                            face_quadrature,
-                                                            descriptor.data->get_right_hand_side(),
-                                                            descriptor.data->get_boundary_values(),
-                                                            *descriptor.kelly_weight);
-       break;
+       std::cout << "Refinement cycle: "       << step
+                 << std::endl;
+
+       solver->set_refinement_cycle (step);
+       solver->solve_problem ();
+       solver->output_solution ();
+
+       std::cout << "   Number of degrees of freedom="
+                 << solver->n_dofs() << std::endl;
+
+       for (typename EvaluatorList::const_iterator
+              e = descriptor.evaluator_list.begin();
+            e != descriptor.evaluator_list.end(); ++e)
+         {
+           (*e)->set_refinement_cycle (step);
+           solver->postprocess (**e);
+         }
+
+
+       if (solver->n_dofs() < descriptor.max_degrees_of_freedom)
+         solver->refine_grid ();
+       else
+         break;
       }
-           
-      default:
-           AssertThrow (false, ExcInternalError());
-    }
-  
-                                  // Now that all objects are in
-                                  // place, run the main loop. The
-                                  // stopping criterion is
-                                  // implemented at the bottom of the
-                                  // loop.
-                                  //
-                                  // In the loop, first set the new
-                                  // cycle number, then solve the
-                                  // problem, output its solution(s),
-                                  // apply the evaluation objects to
-                                  // it, then decide whether we want
-                                  // to refine the mesh further and
-                                  // solve again on this mesh, or
-                                  // jump out of the loop.
-  for (unsigned int step=0; true; ++step)
-    {
-      std::cout << "Refinement cycle: "        << step
-               << std::endl;
-           
-      solver->set_refinement_cycle (step);
-      solver->solve_problem ();
-      solver->output_solution ();
-
-      std::cout << "   Number of degrees of freedom="
-               << solver->n_dofs() << std::endl;
-      
-      for (typename EvaluatorList::const_iterator
-            e = descriptor.evaluator_list.begin();
-          e != descriptor.evaluator_list.end(); ++e)
-       {
-         (*e)->set_refinement_cycle (step);
-         solver->postprocess (**e);
-       }
 
-           
-      if (solver->n_dofs() < descriptor.max_degrees_of_freedom)
-       solver->refine_grid ();
-      else
-       break;
-    }
+                                    // After the loop has run, clean up
+                                    // the screen, and delete objects
+                                    // no more needed:
+    std::cout << std::endl;
+    delete solver;
+    solver = 0;
+  }
 
-                                  // After the loop has run, clean up
-                                  // the screen, and delete objects
-                                  // no more needed:
-  std::cout << std::endl;
-  delete solver;
-  solver = 0;
 }
 
 
 
-
                                 // @sect3{The main function}
 
                                 // Here finally comes the main
@@ -3936,11 +3939,14 @@ void Framework<dim>::run (const ProblemDescription &descriptor)
                                 // etc), and passes them packed into
                                 // a structure to the frame work
                                 // class above.
-int main () 
+int main ()
 {
-  deallog.depth_console (0);
   try
     {
+      using namespace dealii;
+      using namespace Step14;
+
+      deallog.depth_console (0);
                                       // Describe the problem we want
                                       // to solve here by passing a
                                       // descriptor object to the
@@ -3983,7 +3989,7 @@ int main ()
                                       // can also use
                                       // <code>CurvedRidges@<dim@></code>:
       descriptor.data = new Data::SetUp<Data::Exercise_2_3<dim>,dim> ();
-      
+
                                       // Next set first a dual
                                       // functional, then a list of
                                       // evaluation objects. We
@@ -4016,12 +4022,12 @@ int main ()
       const Point<dim> evaluation_point (0.75, 0.75);
       descriptor.dual_functional
        = new DualFunctional::PointValueEvaluation<dim> (evaluation_point);
-      
+
       Evaluation::PointValueEvaluation<dim>
        postprocessor1 (evaluation_point);
       Evaluation::GridOutput<dim>
        postprocessor2 ("grid");
-      
+
       descriptor.evaluator_list.push_back (&postprocessor1);
       descriptor.evaluator_list.push_back (&postprocessor2);
 
@@ -4031,7 +4037,7 @@ int main ()
                                       // stop refining the mesh
                                       // further:
       descriptor.max_degrees_of_freedom = 20000;
-      
+
                                       // Finally pass the descriptor
                                       // object to a function that
                                       // runs the entire solution
@@ -4054,7 +4060,7 @@ int main ()
                << std::endl;
       return 1;
     }
-  catch (...) 
+  catch (...)
     {
       std::cerr << std::endl << std::endl
                << "----------------------------------------------------"

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.