Skip to content

Commit ebf1d33

Browse files
committed
Add symmetric smoothing to improve CG convergence
1 parent b636e5f commit ebf1d33

File tree

4 files changed

+30
-18
lines changed

4 files changed

+30
-18
lines changed

src/AMG.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ include("gallery.jl")
1212
export poisson
1313

1414
include("smoother.jl")
15+
export GaussSeidel, SymmetricSweep, ForwardSweep, BackwardSweep
1516

1617
include("multilevel.jl")
1718
export solve

src/classical.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ function ruge_stuben{Ti,Tv}(A::SparseMatrixCSC{Ti,Tv};
2020

2121
levels = Vector{Level{Ti,Tv}}()
2222

23-
while length(levels) < max_levels
23+
while length(levels) < max_levels #&& size(A, 1) < max_coarse
2424
A = extend_heirarchy!(levels, strength, CF, A)
25-
if size(A, 1) < max_coarse
25+
if size(A, 1) <= max_coarse
2626
break
2727
end
2828
end

src/multilevel.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,20 @@ end
6161
function solve{T}(ml::MultiLevel, b::Vector{T},
6262
maxiter = 100,
6363
cycle = V(),
64-
tol = 1e-5)
64+
tol = 1e-5;
65+
verbose = false)
6566
x = zeros(T, size(b))
6667
residuals = Vector{T}()
6768
A = ml.levels[1].A
6869
normb = norm(b)
6970
if normb != 0
7071
tol *= normb
7172
end
72-
push!(residuals, T(norm(b - A*x)))
73+
push!(residuals, normb)
7374

7475
lvl = 1
7576
while length(residuals) <= maxiter && residuals[end] > tol
76-
if length(ml.levels) == 1
77+
if length(ml) == 1
7778
x = coarse_solver(ml.coarse_solver, A, b)
7879
else
7980
x = __solve(cycle, ml, x, b, lvl)

src/smoother.jl

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,46 @@ struct SymmetricSweep <: Sweep
44
end
55
struct ForwardSweep <: Sweep
66
end
7+
struct BackwardSweep <: Sweep
8+
end
79
struct GaussSeidel{S} <: Smoother
810
sweep::S
911
end
10-
GaussSeidel() = GaussSeidel(ForwardSweep())
12+
GaussSeidel() = GaussSeidel(SymmetricSweep())
13+
14+
presmoother!(s, A, x, b) = smoother!(s, s.sweep, A, x, b)
15+
postsmoother!(s, A, x, b) = smoother!(s, s.sweep, A, x, b)
1116

12-
presmoother!(s, A, x, b) = smoother(s, s.sweep, A, x, b)
13-
postsmoother!(s, A, x, b) = smoother(s, s.sweep, A, x, b)
17+
smoother!(s::GaussSeidel, ::ForwardSweep, A, x, b) =
18+
gs!(A, b, x, 1, 1, size(A, 1))
19+
# gauss_seidel!(x, A, b, maxiter = 1)
20+
function smoother!(s::GaussSeidel, ::SymmetricSweep, A, x, b)
21+
smoother!(s, ForwardSweep(), A, x, b)
22+
smoother!(s, BackwardSweep(), A, x, b)
23+
end
1424

15-
smoother(s::GaussSeidel, ::ForwardSweep, A, x, b) =
16-
gs!(A, b, x)
17-
#gauss_seidel!(x, A, b, maxiter = 1)
25+
smoother!(s::GaussSeidel, ::BackwardSweep, A, x, b) =
26+
gs!(A, b, x, size(A,1), -1, 1)
1827

19-
function gs!{T,Ti}(A::SparseMatrixCSC{T,Ti}, b::Vector{T}, x::Vector{T})
28+
29+
function gs!{T,Ti}(A::SparseMatrixCSC{T,Ti}, b::Vector{T}, x::Vector{T}, start, step, stop)
2030
n = size(A, 1)
2131
z = zero(eltype(A))
22-
for i = 1:n
23-
# rsum = calc_weighted_sum(A, x)
32+
for i = start:step:stop
2433
rsum = z
25-
diag = z
34+
d = z
2635
for j in nzrange(A, i)
2736
row = A.rowval[j]
2837
val = A.nzval[j]
2938
if i == row
30-
diag = val
39+
d = val
3140
else
3241
rsum += val * x[row]
3342
end
3443
end
35-
if diag != 0
36-
x[i] = (b[i] - rsum) / diag
44+
45+
if d != 0
46+
x[i] = (b[i] - rsum) / d
3747
end
3848
end
3949
end

0 commit comments

Comments
 (0)