]> https://gitweb.dealii.org/ - dealii.git/commitdiff
examples/step-20: Change preconditioner to a fixed number of iterations 7709/head
authorMatthias Maier <tamiko@43-1.org>
Tue, 12 Feb 2019 06:19:47 +0000 (00:19 -0600)
committerMatthias Maier <tamiko@43-1.org>
Tue, 12 Feb 2019 06:21:34 +0000 (00:21 -0600)
This improves the total runtime performance with preconditioner
significantly! (Even though the total number of iterations increases
significantly.)

examples/step-20/doc/intro.dox
examples/step-20/step-20.cc

index 844507e93f30ffe99cecf12762f7e94639ca66b8..773141dfcc73dc7e865b5e75dc396df62f74b4df 100644 (file)
@@ -654,12 +654,21 @@ with $M$ is defined: it is the multiplication with the inverse of the
 diagonal of $M$; in other words, the operation $({\textrm{diag}\ }M)^{-1}x$
 on a vector $x$ is exactly what PreconditionJacobi does.)
 
-With all this, we nearly already have the preconditioner: it should be the
-inverse of the approximate Schur complement. We implement this again with
-the inverse_operator() function
+With all this we almost have the preconditioner completed: it should be the
+inverse of the approximate Schur complement. We implement this again by
+creating a linear operator with inverse_operator() function. This time
+however we would like to choose a relatively modest tolerance for the CG
+solver (that inverts <code>op_aS</code>). The reasoning is that
+<code>op_aS</code> is only coarse approximation to <code>op_S</code>, so we
+actually do not need to invert it exactly. This, however creates a subtle
+problem: <code>preconditioner_S</code> will be used in the final outer CG
+iteration to create an orthogonal basis. But for this to work, it must be
+precisely the same linear operation for every invocation. We ensure this by
+using an IterationNumberControl that allows us to fix the number of CG
+iterations that are performed to a fixed small number (in our case 30):
 @code
-    ReductionControl     reduction_control_aS(2000, 1.e-18, 1.0e-6);
-    SolverCG<>           solver_aS(reduction_control_aS);
+    IterationNumberControl iteration_number_control_aS(30, 1.e-18);
+    SolverCG<>           solver_aS(iteration_number_control_aS);
     PreconditionIdentity preconditioner_aS;
     const auto preconditioner_S =
       inverse_operator(op_aS, solver_aS, preconditioner_aS);
@@ -672,15 +681,15 @@ expensive preconditioner, almost as expensive as inverting the Schur
 complement itself. We can expect it to significantly reduce the number of
 outer iterations required for the Schur complement. In fact it does: in a
 typical run on 7 times refined meshes using elements of order 0, the number of
-outer iterations drops from 592 to 25. On the other hand, we now have to apply
+outer iterations drops from 592 to 39. On the other hand, we now have to apply
 a very expensive preconditioner 25 times. A better measure is therefore simply
 the run-time of the program: on a current laptop (as of January 2019), it
-drops from 3.57 to 2.48 seconds for this test case. That doesn't seem too
+drops from 3.57 to 2.05 seconds for this test case. That doesn't seem too
 impressive, but the savings become more pronounced on finer meshes and with
 elements of higher order. For example, an seven times refined mesh and
 using elements of order 2 (which amounts to about 0.4 million degrees of
-freedom) yields an improvement of 1134 to 28 outer iterations, at a runtime
-of 168 seconds to 78 seconds. Not earth shattering, but significant.
+freedom) yields an improvement of 1134 to 83 outer iterations, at a runtime
+of 168 seconds to 40 seconds. Not earth shattering, but significant.
 
 
 <h3>Definition of the test case</h3>
index 5879d3b6a1f94264c40009ca0c0baa4c4953a465..f1b12f6e185dc0331ba7cefa0a33000c15d511fe 100644 (file)
@@ -610,11 +610,10 @@ namespace Step20
       transpose_operator(op_B) * linear_operator(preconditioner_M) * op_B;
 
     // We now create a preconditioner out of <code>op_aS</code> that
-    // applies a small number of CG iterations (until a very modest
-    // relative reduction of $10^{-3}$ is reached):
-    ReductionControl     reduction_control_aS(2000, 1.e-18, 1.0e-3);
-    SolverCG<>           solver_aS(reduction_control_aS);
-    PreconditionIdentity preconditioner_aS;
+    // applies a fixed number of 30 (inexpensive) CG iterations:
+    IterationNumberControl iteration_number_control_aS(30, 1.e-18);
+    SolverCG<>             solver_aS(iteration_number_control_aS);
+    PreconditionIdentity   preconditioner_aS;
 
     const auto preconditioner_S =
       inverse_operator(op_aS, solver_aS, preconditioner_aS);

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.