<h1>Results</h1>

On the finest mesh, the solution looks like this:

<p align="center">
  <img src="https://www.dealii.org/images/steps/developer/step-16.solution.png" alt="">
</p>

More importantly, we would like to see if the multigrid method really
improved the solver performance. Therefore, here is the textual
output:

<pre>
DEAL::Cycle 0
DEAL::   Number of active cells:       20
DEAL::   Number of degrees of freedom: 25 (by level: 8, 25)
DEAL:cg::Starting value 0.510691
DEAL:cg::Convergence step 6 value 4.59193e-14
DEAL::Cycle 1
DEAL::   Number of active cells:       41
DEAL::   Number of degrees of freedom: 52 (by level: 8, 25, 41)
DEAL:cg::Starting value 0.455356
DEAL:cg::Convergence step 8 value 3.09682e-13
DEAL::Cycle 2
DEAL::   Number of active cells:       80
DEAL::   Number of degrees of freedom: 100 (by level: 8, 25, 61, 52)
DEAL:cg::Starting value 0.394469
DEAL:cg::Convergence step 9 value 1.96993e-13
DEAL::Cycle 3
DEAL::   Number of active cells:       161
DEAL::   Number of degrees of freedom: 190 (by level: 8, 25, 77, 160)
DEAL:cg::Starting value 0.322156
DEAL:cg::Convergence step 9 value 2.94418e-13
DEAL::Cycle 4
DEAL::   Number of active cells:       311
DEAL::   Number of degrees of freedom: 364 (by level: 8, 25, 86, 227, 174)
DEAL:cg::Starting value 0.279667
DEAL:cg::Convergence step 10 value 3.45746e-13
DEAL::Cycle 5
DEAL::   Number of active cells:       593
DEAL::   Number of degrees of freedom: 667 (by level: 8, 25, 89, 231, 490, 96)
DEAL:cg::Starting value 0.215917
DEAL:cg::Convergence step 10 value 1.03758e-13
DEAL::Cycle 6
DEAL::   Number of active cells:       1127
DEAL::   Number of degrees of freedom: 1251 (by level: 8, 25, 89, 274, 760, 417, 178)
DEAL:cg::Starting value 0.185906
DEAL:cg::Convergence step 10 value 3.40351e-13
DEAL::Cycle 7
DEAL::   Number of active cells:       2144
DEAL::   Number of degrees of freedom: 2359 (by level: 8, 25, 89, 308, 779, 1262, 817)
DEAL:cg::Starting value 0.141519
DEAL:cg::Convergence step 10 value 5.74965e-13
</pre>

That's almost perfect multigrid performance: 12 orders of magnitude in
10 iteration steps, and almost independent of the mesh size. That's
obviously in part due to the simple nature of the problem solved, but
it shows the power of multigrid methods.


<h3> Possible extensions </h3>

We encourage you to switch on timing output by calling the function
LogStream::log_execution_time() of the deallog object and compare to
step 6. You will see that the multigrid method has quite an overhead
on coarse meshes, but that it always beats other methods on fine
meshes because of its optimal complexity.

A close inspection of this program's performance shows that it is mostly
dominated by matrix-vector operations. step-37 shows one way
how this can be avoided by working with matrix-free methods.

Another avenue would be to use algebraic multigrid methods. The
geometric multigrid method used here can at times be a bit awkward to
implement because it needs all those additional data structures, and
it becomes even more difficult if the program is to run in %parallel on
machines coupled through MPI, for example. In that case, it would be
simpler if one could use a black-box preconditioner that uses some
sort of multigrid hierarchy for good performance but can figure out
level matrices and similar things by itself. Algebraic multigrid
methods do exactly this, and we will use them in
step-31 for the solution of a Stokes problemm and in step-32 and
step-40 for a parallel variation.

Finally, one may want to think how to use geometric multigrid for
other kinds of problems, specifically 
@ref vector_valued "vector valued problems". This is the topic of
step-56 where we use the techniques shown here for the Stokes
equation.
