-
Notifications
You must be signed in to change notification settings - Fork 24
Open
Description
To reproduce
Download this FEMLAB/poisson3Db file and run:
using MatrixMarket
import AlgebraicMultigrid as AMG
A = MatrixMarket.mmread("poisson3Db.mtx")
b = MatrixMarket.mmread("poisson3Db_b.mtx") |> vec
ml = AMG.ruge_stuben(A)
x_amg = AMG._solve(ml, b, verbose=true, maxiter=20)
The residual diverges:
Norm of residual at iteration 1 is 1.8735e+06
Norm of residual at iteration 2 is 2.1074e+06
Norm of residual at iteration 3 is 3.6537e+06
Norm of residual at iteration 4 is 5.8408e+06
Norm of residual at iteration 5 is 9.5234e+06
Norm of residual at iteration 6 is 1.6343e+07
Norm of residual at iteration 7 is 2.9776e+07
Norm of residual at iteration 8 is 5.7516e+07
Norm of residual at iteration 9 is 1.1839e+08
Norm of residual at iteration 10 is 2.7924e+08
Norm of residual at iteration 11 is 9.3488e+08
Norm of residual at iteration 12 is 4.4738e+09
Norm of residual at iteration 13 is 2.4183e+10
Norm of residual at iteration 14 is 1.3371e+11
Norm of residual at iteration 15 is 7.4188e+11
Norm of residual at iteration 16 is 4.1185e+12
Norm of residual at iteration 17 is 2.2864e+13
Norm of residual at iteration 18 is 1.2693e+14
Norm of residual at iteration 19 is 7.0469e+14
Norm of residual at iteration 20 is 3.9122e+15
For a good coarse grid transfer, the column sum of restriction operator R
(or equivalently the row sum of prolongation P
) should be approximately equal to 1. However, the resulting operator contains sum as large as 6.
R_sum = vec(sum(ml.levels[1].R, dims=1))
maximum(R_sum) # 6.5, way too big
sum(R_sum .> 1.5) # 9174
using Plots
plot(R_sum) # show all sums
Compare with PyAMG default
PyAMG with default settings is able to converge:
import pyamg
from scipy.io import mmread
A = mmread("poisson3Db.mtx").tocsr()
b = mmread("poisson3Db_b.mtx").flatten()
ml = pyamg.ruge_stuben_solver(A)
residuals = []
x_amg = ml.solve(b, residuals=residuals, maxiter=20)
print(residuals)
[1873512.4673384393,
233255.5159887513,
109241.08890436463,
70342.75287986077,
51906.30512772909,
41392.049922233826,
34744.68012516487,
30219.93538009633,
26944.726717410056,
24444.551602043706,
22448.232978979628,
20794.899486606348,
19385.86164700615,
18158.491431757277,
17071.605472539315,
16097.097721476017,
15215.053123024978,
14410.837321621537,
13673.326931758267,
12993.808948353657,
12365.279421869809]
The interpolation operators also looks good:
import numpy as np
import matplotlib.pyplot as plt
R_sum = np.squeeze(np.asarray(ml.levels[0].R.sum(axis=0)))
R_sum.max() # 1.26
np.sum(R_sum > 1.5) # 0
plt.plot(R_sum, marker='.', linewidth=0, alpha=0.2) # all nicely bounded
By default, both PyAMG and AMG.jl use theta=0.25
for strength of connection, and symmetric Gauss-Seidel as smoother, so their behaviors should have been similar. Maybe some subtle problems in the interpolation code. Haven't fully figured it out yet.
Metadata
Metadata
Assignees
Labels
No labels