2021-10-22 Preconditioners¶
Last time¶
Limitations of stationary iterative methods
Preconditioning as a concept
Krylov methods (GMRES)
Today¶
Experiments with preconditioners and diagnostics in PETSc
Basic preconditioners
Incomplete factorization and fill
using Plots
using LinearAlgebra
using SparseArrays
default(linewidth=4)
function advdiff_matrix(n; kappa=1, wind=[0, 0])
"Advection-diffusion with Dirichlet boundary conditions eliminated"
h = 2 / (n + 1)
rows = Vector{Int64}()
cols = Vector{Int64}()
vals = Vector{Float64}()
idx((i, j),) = (i-1)*n + j
in_domain((i, j),) = 1 <= i <= n && 1 <= j <= n
stencil_advect = [-wind[1], -wind[2], 0, wind[1], wind[2]] / h
stencil_diffuse = [-1, -1, 4, -1, -1] * kappa / h^2
stencil = stencil_advect + stencil_diffuse
for i in 1:n
for j in 1:n
neighbors = [(i-1, j), (i, j-1), (i, j), (i+1, j), (i, j+1)]
mask = in_domain.(neighbors)
append!(rows, idx.(repeat([(i,j)], 5))[mask])
append!(cols, idx.(neighbors)[mask])
append!(vals, stencil[mask])
end
end
sparse(rows, cols, vals)
end
function my_spy(A)
cmax = norm(vec(A), Inf)
s = max(1, ceil(120 / size(A, 1)))
spy(A, marker=(:square, s), c=:diverging_rainbow_bgymr_45_85_c67_n256, clims=(-cmax, cmax))
end
grad_descent (generic function with 1 method)
Experiments in PETSc¶
PETSc = Portable Extensible Toolkit for Scientific computing
./configure
,make
Depends on BLAS and LAPACK (default system or package manager)
or
./configure --download-f2cblaslapack --download-blis
Depends on MPI for parallelism (package manager)
or
./configure --download-mpich
(or--download-openmpi
)
docker run -it --rm jedbrown/petsc
Lots of examples (mostly C and Fortran, some Python)
Experimental bindings in Rust, Julia
We’ll use
src/snes/tutorials/ex15.c
“p-Bratu”: combines p-Laplacian with Bratu nonlinearity
\[ -\nabla\cdot\big(\kappa(\nabla u) \nabla u\big) - \lambda e^u = f \]Newton solver with Krylov on each iteration
Simple preconditioners¶
Gauss-Seidel -pc_type sor
¶
where \(L\) is the (strictly) lower triangular part of \(A\). The upper triangular part may be used instead, or a symmetric form
Over-relaxation¶
-pc_sor_omega 1.
is default (Gauss-Seidel)
Run p-Laplacian example¶
$ cd src/snes/tutorials
$ make ex15
$ ./ex15 -da_refine 2 -dm_view
$ ./ex15 -ksp_monitor -pc_type jacobi
$ ./ex15 -snes_view
Experiments¶
How does iteration count vary under grid refinement?
How sensitive is it to parameters
p-Laplacian
-p
\(> 1\) and-epsilon
\(> 0\)Bratu
-lambda
\(< 6.8\)
How sensitive to
-ksp_gmres_restart
?-ksp_monitor_true_residual
Symmetric problems¶
Lanczos iteration: like GMRES for symmetric problems¶
If \(A\) is symmetric, then \(H = Q^T A Q\) is also symmetric. Since \(H\) is Hessenberg, this means \(H\) is tridiagonal. Instead of storing \(Q_n\), it is sufficient to store only the last two columns since the iteration satisfies a 3-term recurrence. The analog of GMRES for the symmetric case is called MINRES and is also useful for solving symmetric indefinite problems.
Conjugate Gradients: changing the norm¶
Instead of minimizing the \(A^T A\) norm of the error, the Conjugate Gradient method minimizes the \(A\) norm of the error. For \(A\) to induce a norm, it must be symmetric positive definite. Jeremy Shewchuck’s guide to CG is an excellent resource.
Incomplete factorization¶
Start factoring like in a sparse direct solver
ILU(0) Discard fill outside the sparsity pattern of \(A\)
ILU(\(k\)): only allow \(k\) levels of fill
ILUT(\(\epsilon\)): only keep fill values larger than \(\epsilon\)
Experiments¶
Try
-pc_factor_levels 2
Impact on cost (check
-log_view
)Impact on scalability (
-da_refine 6
)
Kershaw (1978) matrix¶
Incomplete Cholesky can break down for SPD matrices.
K = [3 -2 0 2; -2 3 -2 0; 0 -2 3 -2; 2 0 -2 3]
eigvals(K)
4-element Vector{Float64}:
0.17157287525380904
0.17157287525381085
5.828427124746186
5.82842712474619