@@ -7,6 +7,10 @@ struct Solver{S,T,P,PS}
7
7
max_coarse:: Int64
8
8
end
9
9
10
+ struct Level{T}
11
+ A:: T
12
+ end
13
+
10
14
function ruge_stuben (A:: SparseMatrixCSC ;
11
15
strength = Classical (),
12
16
CF = RS (),
@@ -26,8 +30,137 @@ function ruge_stuben(A::SparseMatrixCSC;
26
30
end
27
31
28
32
function extend_heirarchy! (levels:: Vector{Level} , strength, CF, A)
29
-
30
33
S = strength_of_connection (strength, A)
31
34
splitting = split_nodes (CF, S)
32
- P = direct_interpolation (A, S, splitting)
35
+ P, R = direct_interpolation (A, S, splitting)
36
+ end
37
+
38
+ function direct_interpolation {T,V} (A:: T , S:: T , splitting:: Vector{V} )
39
+
40
+ fill! (S. nzval, 1. )
41
+ S = A .* S
42
+ Pp = rs_direct_interpolation_pass1 (S, A, splitting)
43
+ Pp .= Pp .+ 1
44
+
45
+ Px, Pj = rs_direct_interpolation_pass2 (A, S, splitting, Pp)
46
+
47
+ Px .= abs .(Px)
48
+ Pj .= Pj .+ 1
49
+
50
+ R = SparseMatrixCSC (maximum (Pj), size (A, 1 ), Pp, Pj, Px)
51
+ P = R'
52
+
53
+ P, R
54
+ end
55
+
56
+
57
+ function rs_direct_interpolation_pass1 (S, A, splitting)
58
+
59
+ Bp = zeros (Int, size (A. colptr))
60
+ Sp = S. colptr
61
+ Sj = S. rowval
62
+ n_nodes = size (A, 1 )
63
+ nnz = 0
64
+ for i = 1 : n_nodes
65
+ if splitting[i] == C_NODE
66
+ nnz += 1
67
+ else
68
+ for jj = Sp[i]: Sp[i+ 1 ]- 1
69
+ if splitting[Sj[jj]] == C_NODE && Sj[jj] != i
70
+ nnz += 1
71
+ end
72
+ end
73
+ end
74
+ Bp[i+ 1 ] = nnz
75
+ end
76
+ Bp
77
+ end
78
+
79
+
80
+ function rs_direct_interpolation_pass2 {Tv, Ti} (A:: SparseMatrixCSC{Tv,Ti} ,
81
+ S:: SparseMatrixCSC{Tv,Ti} ,
82
+ splitting:: Vector{Ti} ,
83
+ Bp:: Vector{Ti} )
84
+
85
+
86
+ Ap = A. colptr
87
+ Aj = A. rowval
88
+ Ax = A. nzval
89
+ Sp = S. colptr
90
+ Sj = S. rowval
91
+ Sx = S. nzval
92
+ Bj = zeros (Ti, Bp[end ])
93
+ Bx = zeros (Float64, Bp[end ])
94
+ n_nodes = size (A, 1 )
95
+ # Bp += 1
96
+
97
+ for i = 1 : n_nodes
98
+ if splitting[i] == C_NODE
99
+ Bj[Bp[i]] = i
100
+ Bx[Bp[i]] = 1
101
+ else
102
+ sum_strong_pos = 0
103
+ sum_strong_neg = 0
104
+ for jj = Sp[i]: Sp[i+ 1 ]- 1
105
+ if splitting[Sj[jj]] == C_NODE && Sj[jj] != i
106
+ if Sx[jj] < 0
107
+ sum_strong_neg += Sx[jj]
108
+ else
109
+ sum_strong_pos += Sx[jj]
110
+ end
111
+ end
112
+ end
113
+
114
+ sum_all_pos = 0
115
+ sum_all_neg = 0
116
+ diag = 0 ;
117
+ for jj = Ap[i]: Ap[i+ 1 ]
118
+ if Aj[jj] == i
119
+ diag += Ax[jj]
120
+ else
121
+ if Ax[jj] < 0
122
+ sum_all_neg += Ax[jj];
123
+ else
124
+ sum_all_pos += Ax[jj];
125
+ end
126
+ end
127
+ end
128
+
129
+ alpha = sum_all_neg / sum_strong_neg
130
+ beta = sum_all_pos / sum_strong_pos
131
+
132
+ if sum_strong_pos == 0
133
+ diag += sum_all_pos
134
+ beta = 0
135
+ end
136
+
137
+ neg_coeff = - alpha/ diag;
138
+ pos_coeff = - beta/ diag;
139
+
140
+ nnz = Bp[i]
141
+ for jj = Sp[i]: Sp[i+ 1 ]
142
+ if splitting[Sj[jj]] == C_NODE && Sj[jj] != i
143
+ Bj[nnz] = Sj[jj]
144
+ if Sx[jj] < 0
145
+ Bx[nnz] = neg_coeff * Sx[jj]
146
+ else
147
+ Bx[nnz] = pos_coeff * Sx[jj]
148
+ nnz += 1
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ m = zeros (Ti, n_nodes)
156
+ sum = 0
157
+ for i = 1 : n_nodes
158
+ m[i] = sum
159
+ sum += splitting[i]
160
+ end
161
+ for i = 1 : Bp[n_nodes]
162
+ Bj[i] = m[Bj[i]]
163
+ end
164
+
165
+ Bx, Bj, Bp
33
166
end
0 commit comments