On 9/11/19 7:04 AM, Konrad wrote:
>
> The system that needs to be solved formally reads
> *(P) A sigma + B^T u = 0
> *
> * B sigma + C u = f*
>
> *A* is sort of a mass matrix so it is positive (corresponds to
> *<tau,sigma>* in *H(curl)*) and *C* is positive semi-definite
> (corresponds to *<div v, div u>* in *H(div)*).
>
> First thing that crossed my mind was a Schur complement solver. Now one
> a priori has two options:
>
> 1.) Solve first for u and then for sigma, i.e. invert *A* and use the
> Schur complement *S = -B*A^{-1}*B^T + C*
> 2.) The other way around *S = -B^T*C^{-1}*B + A*. My gut feeling tells
> me that this could actually turn out to be not an option since either
> *C* is very ill-conditioned or not invertible at all. It is symmetric
> and contains at least one zero eigenvalue. Thinking of it: it formally
> corresponds to *C~(grad div)^{-1}* (and I am of course having
> convergence issues)
Correct, your approach 2 will not work precisely because C has a kernal
(all divergence free vector fields) and is consequently not invertible.
> Using approach 1.) I get timing results like that:
> (using MPI with Petsc, AMG preconditioning for *A* on one machine with
> four cores, no preconditioning for the Schur complement *S =
> -B*A^{-1}*B^T + C* from 1.)
>
> Running using PETSc.
> Number of active cells: 32768
> Total number of cells: 21449 (on 6 levels)
> Number of degrees of freedom: 205920 (104544+101376)
> Iterative Schur complement solver converged in 177 iterations.
> Outer solver completed.
>
>
> +---------------------------------------------+------------+------------+
> | Total wallclock time elapsed since start | 37s | |
> | | | |
> | Section | no. calls | wall time | % of total |
> +---------------------------------+-----------+------------+------------+
> | Schur complement solver (for u) | 1 | 27.2s | 74% |
> | assembly | 1 | 6.61s | 18% |
That's actually an acceptable time: My rule of thumb, maybe a bit
outdated, is that it takes a minute to solve for 100,000 unknowns for
non-trivial problems. You've got twice that many unknowns and solve it
in half the time.
> You will notice that the time for the Schur complement solver is
> dominating. So either I did something wrong in the implementation
> conceptually (see class for Schur complement below) or I need to do a
> better job in solving/preconditioning the system. Note that the Schur
> complement is usually not definite in contrast to Stokes or Darcy systems.
Really? Is this an issue related to boundary conditions? Your matrix
corresponds to the operator
curl I curl + grad div
I thought there are no vector fields that are both divergence-free and
curl-free.
> Does anyone have an idea of how to attack systems like *(P)*? Are there
> optimal preconditioners? Any hint would be appreciated.
Take a look at step-20 and step-22. The idea of preconditioning a Schur
complement is to use some sort of approximation of the Schur complement
that is easier to solve for. I suspect that in your case, a simple
Laplace matrix would make for a nice approximation of S, and so using
one SSOR step with the Laplace matrix might be a good preconditioner for
S. Alternatively, an algebraic multigrid initialized with the Laplace
matrix might work.
step-20 plays with these ideas, solving for the Schur complement
directly. step-22 (in particular the code in the "Possibilities for
extensions" section) expands on this: If you have a preconditioner for
the Schur complement, then you can just use that as part of the
preconditioner for the overall system. It's the best approach we have
for the Stokes equation (used successfully on systems with billions of
unknowns) and worth understanding!
Best
W.
--
------------------------------------------------------------------------
Wolfgang Bangerth email:
bang...@colostate.edu
www:
http://www.math.colostate.edu/~bangerth/