@@ -13,82 +13,119 @@ function smoothed_aggregation(A::TA,
1313 diagonal_dominance = false ,
1414 keep = false ,
1515 coarse_solver = Pinv, kwargs... ) where {T,V,bs,TA<: SparseMatrixCSC{T,V} }
16+
17+ @timeit_debug " prologue" begin
18+
1619 n = size (A, 1 )
1720 B = isnothing (B) ? ones (T,n) : copy (B)
1821 @assert size (A, 1 ) == size (B, 1 )
1922
20- #= max_levels, max_coarse, strength =
21- levelize_strength_or_aggregation(max_levels, max_coarse, strength)
22- max_levels, max_coarse, aggregate =
23- levelize_strength_or_aggregation(max_levels, max_coarse, aggregate)
24-
25- improve_candidates =
26- levelize_smooth_or_improve_candidates(improve_candidates, max_levels)=#
27- # str = [stength for _ in 1:max_levels - 1]
28- # agg = [aggregate for _ in 1:max_levels - 1]
29- # sm = [smooth for _ in 1:max_levels]
30-
3123 levels = Vector {Level{TA, TA, Adjoint{T, TA}}} ()
3224 bsr_flag = false
3325 w = MultiLevelWorkspace (Val{bs}, eltype (A))
3426 residual! (w, size (A, 1 ))
3527
28+ end
29+
3630 while length (levels) + 1 < max_levels && size (A, 1 ) > max_coarse
37- A, B, bsr_flag = extend_hierarchy ! (levels, strength, aggregate, smooth,
31+ @timeit_debug " extend_hierarchy! " A, B, bsr_flag = extend_hierarchy_sa ! (levels, strength, aggregate, smooth,
3832 improve_candidates, diagonal_dominance,
3933 keep, A, B, symmetry, bsr_flag)
34+ size (A, 1 ) == 0 && break
4035 coarse_x! (w, size (A, 1 ))
4136 coarse_b! (w, size (A, 1 ))
42- #= if size(A, 1) <= max_coarse
43- break
44- end=#
4537 residual! (w, size (A, 1 ))
4638 end
47- #= A, B = extend_hierarchy!(levels, strength, aggregate, smooth,
48- improve_candidates, diagonal_dominance,
49- keep, A, B, symmetry) =#
50- MultiLevel (levels, A, coarse_solver (A), presmoother, postsmoother, w)
39+
40+ @timeit_debug " coarse solver setup " cs = coarse_solver (A)
41+ @timeit_debug " ml setup " ml = MultiLevel (levels, A, cs, presmoother, postsmoother, w)
42+ return ml
5143end
5244
5345struct HermitianSymmetry
5446end
5547
56- function extend_hierarchy ! (levels, strength, aggregate, smooth,
48+ function extend_hierarchy_sa ! (levels, strength, aggregate, smooth,
5749 improve_candidates, diagonal_dominance, keep,
5850 A, B,
5951 symmetry, bsr_flag)
6052
6153 # Calculate strength of connection matrix
62- if symmetry isa HermitianSymmetry
54+ @timeit_debug " strength " if symmetry isa HermitianSymmetry
6355 S, _T = strength (A, bsr_flag)
6456 else
6557 S, _T = strength (adjoint (A), bsr_flag)
6658 end
6759
6860 # Aggregation operator
69- AggOp = aggregate (S)
61+ @timeit_debug " aggregation " AggOp = aggregate (S)
7062 # b = zeros(eltype(A), size(A, 1))
7163
7264 # Improve candidates
7365 b = zeros (size (A,1 ),size (B,2 ))
74- improve_candidates (A, B, b)
75- T, B = fit_candidates (AggOp, B)
66+ @timeit_debug " improve candidates " improve_candidates (A, B, b)
67+ @timeit_debug " fit candidates " T, B = fit_candidates (AggOp, B)
7668
77- P = smooth (A, T, S, B)
78- R = construct_R (symmetry, P)
79- push! (levels, Level (A, P, R))
69+ @timeit_debug " restriction setup" begin
70+ P = smooth (A, T, S, B)
71+ R = construct_R (symmetry, P)
72+ end
8073
81- A = R * A * P
74+ @timeit_debug " RAP " RAP = R * A * P
8275
83- dropzeros! (A )
76+ push! (levels, Level (A, P, R) )
8477
8578 bsr_flag = true
8679
87- A , B, bsr_flag
80+ RAP , B, bsr_flag
8881end
8982construct_R (:: HermitianSymmetry , P) = P'
9083
91- function fit_candidates (AggOp, B; tol= 1e-10 )
84+ function fit_candidates (AggOp, B:: AbstractVector ; tol= 1e-10 )
85+
86+ A = adjoint (AggOp)
87+ n_fine, n_coarse = size (A)
88+ n_col = n_coarse
89+
90+ R = zeros (eltype (B), n_coarse)
91+ Qx = zeros (eltype (B), nnz (A))
92+ # copy!(Qx, B)
93+ for i = 1 : size (Qx, 1 )
94+ Qx[i] = B[i]
95+ end
96+ # copy!(A.nzval, B)
97+ for i = 1 : n_col
98+ for j in nzrange (A,i)
99+ row = A. rowval[j]
100+ A. nzval[j] = B[row]
101+ end
102+ end
103+ k = 1
104+ for i = 1 : n_col
105+ norm_i = norm_col (A, Qx, i)
106+ threshold_i = tol * norm_i
107+ if norm_i > threshold_i
108+ scale = 1 / norm_i
109+ R[i] = norm_i
110+ else
111+ scale = 0
112+ R[i] = 0
113+ end
114+ for j in nzrange (A, i)
115+ row = A. rowval[j]
116+ # Qx[row] *= scale
117+ # @show k
118+ # Qx[k] *= scale
119+ # k += 1
120+ A. nzval[j] *= scale
121+ end
122+ end
123+
124+ # SparseMatrixCSC(size(A)..., A.colptr, A.rowval, Qx), R
125+ A, R
126+ end
127+
128+ function fit_candidates (AggOp, B:: AbstractMatrix ; tol= 1e-10 )
92129 A = adjoint (AggOp)
93130 n_fine, m = ndims (B) == 1 ? (length (B), 1 ) : size (B)
94131 n_fine2, n_agg = size (A)
@@ -102,7 +139,7 @@ function fit_candidates(AggOp, B; tol=1e-10)
102139 rows = A. rowval[A. colptr[agg]: A. colptr[agg+ 1 ]- 1 ]
103140 M = @view B[rows, :] # size(rows) × m
104141
105-
142+ # TODO the code below can be optimized
106143 F = qr (M)
107144 r = min (length (rows), m)
108145 Qfull = Matrix (F. Q)
@@ -124,3 +161,17 @@ function fit_candidates(AggOp, B; tol=1e-10)
124161
125162 return Qs, R
126163end
164+
165+ function norm_col (A, Qx, i)
166+ s = zero (eltype (A))
167+ for j in nzrange (A, i)
168+ if A. rowval[j] > length (Qx)
169+ val = 1
170+ else
171+ val = Qx[A. rowval[j]]
172+ end
173+ # val = A.nzval[A.rowval[j]]
174+ s += val* val
175+ end
176+ sqrt (s)
177+ end
0 commit comments