@@ -205,4 +205,44 @@ function scale_rows!(ret, S, v)
205205 end
206206 ret
207207end
208- scale_rows (S, v) = scale_rows! (deepcopy (S), S, v)
208+ scale_rows (S, v) = scale_rows! (deepcopy (S), S, v)
209+
210+ struct SOR{S} <: Smoother
211+ ω:: Float64
212+ sweep:: S
213+ iter:: Int
214+ end
215+
216+ SOR (ω; iter = 1 ) = SOR (ω, SymmetricSweep (), iter)
217+ SOR (ω, f:: ForwardSweep ) = SOR (ω, f, 1 )
218+ SOR (ω, b:: BackwardSweep ) = SOR (ω, b, 1 )
219+ SOR (ω, s:: SymmetricSweep ) = SOR (ω, s, 1 )
220+
221+ function (sor:: SOR{S} )(A, x, b) where {S<: Sweep }
222+ for i in 1 : sor. iter
223+ if S === ForwardSweep || S === SymmetricSweep
224+ sor_step! (A, b, x, sor. ω, 1 , 1 , size (A, 1 ))
225+ end
226+ if S === BackwardSweep || S === SymmetricSweep
227+ sor_step! (A, b, x, sor. ω, size (A, 1 ), - 1 , 1 )
228+ end
229+ end
230+ end
231+
232+ function sor_step! (A, b, x, ω, start, step, stop)
233+ n = size (A, 1 )
234+ z = zero (eltype (A))
235+ @inbounds for col in 1 : size (x, 2 )
236+ for i in start: step: stop
237+ rsum = z
238+ d = z
239+ for j in nzrange (A, i)
240+ row = A. rowval[j]
241+ val = A. nzval[j]
242+ d = ifelse (i == row, val, d)
243+ rsum += ifelse (i == row, z, val * x[row, col])
244+ end
245+ x[i, col] = ifelse (d == 0 , x[i, col], (1 - ω) * x[i, col] + (ω / d) * (b[i, col] - rsum))
246+ end
247+ end
248+ end
0 commit comments