From: Wolfgang Bangerth Date: Wed, 30 Apr 2025 17:09:48 +0000 (-0600) Subject: Add some thoughts to step-93. X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9fd56cbd48bfc92f09c916e69c95f9222b76f8e5;p=dealii.git Add some thoughts to step-93. --- diff --git a/doc/doxygen/references.bib b/doc/doxygen/references.bib index 8e43ce46e9..a55bc59367 100644 --- a/doc/doxygen/references.bib +++ b/doc/doxygen/references.bib @@ -2000,6 +2000,22 @@ } +%------------------------------------------------------------------------------- +% Step 93 +%------------------------------------------------------------------------------- + +@inbook{Battermann_1998, + title={Preconditioners for Karush-Kuhn-Tucker Matrices Arising in the Optimal Control of Distributed Systems}, + url={http://dx.doi.org/10.1007/978-3-0348-8849-3_2}, + DOI={10.1007/978-3-0348-8849-3_2}, + booktitle={Control and Estimation of Distributed Parameter Systems}, + publisher={Birkh{\"a}user Basel}, + author={Battermann, A. and Heinkenschloss, M.}, + year={1998}, + pages={15-32} +} + + %------------------------------------------------------------------------------- % References used elsewhere %------------------------------------------------------------------------------- diff --git a/examples/step-93/doc/intro.dox b/examples/step-93/doc/intro.dox index 03a121ced6..38d959bcd2 100644 --- a/examples/step-93/doc/intro.dox +++ b/examples/step-93/doc/intro.dox @@ -149,7 +149,7 @@ idealized system to solve: 0 & \mathcal{F} & 0 \end{array}\right) \left(\begin{array}{c} - U\\\Lambda\\ C + U\\ \Lambda \\ C \end{array}\right) = \left(\begin{array}{c} \overline{\mathcal{U}}\\0\\0 diff --git a/examples/step-93/doc/results.dox b/examples/step-93/doc/results.dox index 0f3af8f0ee..4c89af0500 100644 --- a/examples/step-93/doc/results.dox +++ b/examples/step-93/doc/results.dox @@ -159,7 +159,24 @@ note that since the block matrix we use has many zeros on the diagonal, preconditioners like PreconditionJacobi will not work because they divide by diagonal entries. Instead, block preconditioners such as those discussed in step-20 or step-22 (among -many others) will likely be useful. +many others) will likely be useful. For block preconditioners, the +key realizations is that the blocks of the system matrix +@f{align*}{ + \left(\begin{array}{c c c} + \mathcal{M} & -\mathcal{N}^T & 0\\ + -\mathcal{N} & 0 & \mathcal{F}^T\\ + 0 & \mathcal{F} & 0 + \end{array}\right) +@f} +can often individually be solved with quite efficiently; for example, +$\mathcal{M}$ is a mass matrix that is easily solved with using a CG +iteration, and $\mathcal N$ is a Laplace matrix for which CG with +a geometric or algebraic multigrid preconditioner is very effective. +Using the ideas of step-20 and step-22, we should then create a +$3\times 3$ block preconditioner in which some blocks correspond to the +inverses of $\mathcal{M}$ or $\mathcal{N}$, or some kind of Schur +complement. A starting point for this kind of consideration is +@cite Battermann_1998 . 2. To validate the optimization problem is working correctly, we could try to match a target function which is itself a solution to the diff --git a/examples/step-93/step-93.cc b/examples/step-93/step-93.cc index 5057f4fd55..bcb2d5a2e4 100644 --- a/examples/step-93/step-93.cc +++ b/examples/step-93/step-93.cc @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -635,24 +634,25 @@ namespace Step93 // solver. For smaller problems, one can also use a direct solver // (see step-29) for which you would just replace the main part of // this function by the following three lines of code: - // - // `SparseDirectUMFPACK direct_solver;` - // - // `direct_solver.initialize(system_matrix);` - // - // `direct_solver.vmult(solution, system_rhs);` + // @code + // SparseDirectUMFPACK direct_solver; + // direct_solver.initialize(system_matrix); + // direct_solver.vmult(solution, system_rhs); + // @endcode template void Step93::solve() { std::cout << "Beginning solve..." << std::endl; - Timer timer; + { + Timer timer; - SolverControl solver_control(1'000'000, 1e-6 * system_rhs.l2_norm()); - SolverMinRes> solver(solver_control); + SolverControl solver_control(1'000'000, 1e-6 * system_rhs.l2_norm()); + SolverMinRes> solver(solver_control); - solver.solve(system_matrix, solution, system_rhs, PreconditionIdentity()); + solver.solve(system_matrix, solution, system_rhs, PreconditionIdentity()); - timer.stop(); + timer.stop(); + } std::cout << "Wall time: " << timer.wall_time() << "s" << std::endl; std::cout << "Solved in " << solver_control.last_step() << " MINRES iterations." << std::endl;