<br>

<i>This program has evolved from a version originally written by Guido
Kanschat in 2003. It has undergone significant revisions by B&auml;rbel
Janssen, Guido Kanschat and Wolfgang Bangerth in 2009 and 2010 to demonstrate
multigrid algorithms on adaptively refined meshes.
</i>


<a name="Intro"></a>
<h1>Introduction</h1>


This example shows the basic usage of the multilevel functions in
deal.II. It solves the same problem as used in step-6,
but demonstrating the things one has to provide when using multigrid
as a preconditioner. In particular, this requires that we define a
hierarchy of levels, provide transfer operators from one level to the
next and back, and provide representations of the Laplace operator on
each level.

In order to allow sufficient flexibility in conjunction with systems of
differential equations and block preconditioners, quite a few different objects
have to be created before starting the multilevel method, although
most of what needs to be done is provided by deal.II itself. These are
<ul>
<li>An the object handling transfer between grids; we use the
    MGTransferPrebuilt class for this that does almost all of the work
    inside the library.
<li>The solver on the coarsest level; here, we use MGCoarseGridHouseholder.
<li>The smoother on all other levels, which in our case will be the
    MGSmootherRelaxation class using SOR as the underlying method
<li>And MGMatrix, a class having a special level multiplication, i.e. we
    basically store one matrix per grid level and allow multiplication
    with it.
</ul>
Most of these objects will only be needed inside the function that
actually solves the linear system. There, these objects are combined
in an object of type Multigrid, containing the implementation of the
V-cycle, which is in turn used by the preconditioner PreconditionMG,
ready for plug-in into a linear solver of the LAC library.

The multilevel method in deal.II follows in many respects the outlines
of the various publications by James Bramble, Joseph Pasciak and
Jinchao Xu (i.e. the "BPX" framework). In order to understand many of
the options, a rough familiarity with their work is quite helpful.

However, in comparison to this framework, the implementation in
deal.II has to take into account the fact that we want to solve linear
systems on adaptively refined meshes. This leads to the complication
that it isn't quite as clear any more what exactly a "level" in a
multilevel hierarchy of a mesh is. The following image shows what we
consider to be a "level":

<p align="center">
  @image html "hanging_nodes.png" ""
</p>

In other words, the fine level in this mesh consists only of the
degrees of freedom that are defined on the refined cells, but does not
extend to that part of the domain that is not refined. While this
guarantees that the overall effort grows as ${\cal O}(N)$ as necessary
for optimal multigrid complexity, it leads to problems when defining
where to smooth and what boundary conditions to pose for the operators
defined on individual levels if the level boundary is not an external
boundary. These questions are discussed in detail in the
@ref mg_paper "Multigrid paper by Janssen and Kanschat" that describes
the implementation in deal.II.



<h3>The testcase</h3>

The problem we solve here is exactly the same as in
step-6, the only difference being the solver we use
here. You may want to look there for a definition of what we solve,
right hand side and boundary conditions. Obviously, the program would
also work if we changed the geometry and other pieces of data that
defines this particular problem.

The things that are new are all those parts that concern the
multigrid. In particular, this includes the following members of the
main class:
- <code>LaplaceProblem::mg_dof_handler</code>
- <code>LaplaceProblem::mg_sparsity</code>
- <code>LaplaceProblem::mg_matrices</code>
- <code>LaplaceProblem::mg_interface_matrices_up</code>
- <code>LaplaceProblem::assemble_multigrid ()</code>
- <code>LaplaceProblem::solve ()</code>
Take a look at these functions.
