1
+ """
2
+ struct RichardsonLinearSolver <: LinearSolver
3
+ ...
4
+ end
5
+
6
+ RichardsonLinearSolver(ω,maxiter;Pl=nothing,rtol=1e-10,atol=1e-6,verbose=true,name = "RichardsonLinearSolver")
7
+
8
+ Richardson Iteration, with an optional left preconditioners `Pl`.
9
+
10
+ The relaxation parameter (ω) can either be of type Float64 or Vector{Float64}.
11
+ This gives flexiblity in relaxation.
12
+ """
13
+ struct RichardsonLinearSolver<: Gridap.Algebra.LinearSolver
14
+ ω:: Union{Vector{Float64},Float64}
15
+ Pl:: Union{Gridap.Algebra.LinearSolver,Nothing}
16
+ log:: ConvergenceLog{Float64}
17
+ end
18
+
19
+ function RichardsonLinearSolver (ω,maxiter;Pl= nothing ,rtol= 1e-10 ,atol= 1e-6 ,verbose= true ,name = " RichardsonLinearSolver" )
20
+ tols = SolverTolerances {Float64} (maxiter= maxiter,atol= atol,rtol= rtol)
21
+ log = ConvergenceLog (name,tols,verbose= verbose)
22
+ return RichardsonLinearSolver (ω,Pl,log)
23
+ end
24
+
25
+ struct RichardsonLinearSymbolicSetup<: Gridap.Algebra.SymbolicSetup
26
+ solver
27
+ end
28
+
29
+ function Gridap. Algebra. symbolic_setup (solver:: RichardsonLinearSolver ,A:: AbstractMatrix )
30
+ return RichardsonLinearSymbolicSetup (solver)
31
+ end
32
+
33
+ function get_solver_caches (solver:: RichardsonLinearSolver , A:: AbstractMatrix )
34
+ ω = solver. ω
35
+ z = allocate_in_domain (A)
36
+ r = allocate_in_domain (A)
37
+ α = allocate_in_domain (A)
38
+ fill! (z,0.0 )
39
+ fill! (r,0.0 )
40
+ fill! (α,1.0 )
41
+ return ω, z, r, α
42
+ end
43
+
44
+ mutable struct RichardsonLinearNumericalSetup<: Gridap.Algebra.NumericalSetup
45
+ solver
46
+ A
47
+ Pl_ns
48
+ caches
49
+ end
50
+
51
+ function Gridap. Algebra. numerical_setup (ss:: RichardsonLinearSymbolicSetup , A:: AbstractMatrix )
52
+ solver = ss. solver
53
+ Pl_ns = ! isnothing (solver. Pl) ? numerical_setup (symbolic_setup (solver. Pl,A),A) : nothing
54
+ caches = get_solver_caches (solver,A)
55
+ return RichardsonLinearNumericalSetup (solver,A,Pl_ns,caches)
56
+ end
57
+
58
+ function Gridap. Algebra. numerical_setup (ss:: RichardsonLinearSymbolicSetup , A:: AbstractMatrix , x:: AbstractVector )
59
+ solver = ss. solver
60
+ Pl_ns = ! isnothing (solver. Pl) ? numerical_setup (symbolic_setup (solver. Pl,A,x),A,x) : nothing
61
+ caches = get_solver_caches (solver,A)
62
+ return RichardsonLinearNumericalSetup (solver,A,Pl_ns,caches)
63
+ end
64
+
65
+ function Gridap. Algebra. numerical_setup! (ns:: RichardsonLinearNumericalSetup , A:: AbstractMatrix )
66
+ if ! isa (ns. Pl_ns,Nothing)
67
+ numerical_setup! (ns. Pl_ns,A)
68
+ end
69
+ ns. A = A
70
+ return ns
71
+ end
72
+
73
+ function Gridap. Algebra. numerical_setup! (ns:: RichardsonLinearNumericalSetup , A:: AbstractMatrix , x:: AbstractVector )
74
+ if ! isa (ns. Pl_ns,Nothing)
75
+ numerical_setup! (ns. Pl_ns,A,x)
76
+ end
77
+ ns. A = A
78
+ return ns
79
+ end
80
+
81
+ function Gridap. Algebra. solve! (x:: AbstractVector , ns:: RichardsonLinearNumericalSetup , b:: AbstractVector )
82
+ solver,A,Pl,caches = ns. solver,ns. A,ns. Pl_ns,ns. caches
83
+ ω, z, r, α = caches
84
+ log = solver. log
85
+ # Relaxation parameters
86
+ α .*= ω
87
+ # residual
88
+ r .= b
89
+ mul! (r, A, x, - 1 , 1 )
90
+ done = init! (log,norm (r))
91
+ if ! isa (ns. Pl_ns,Nothing) # Case when a preconditioner is applied
92
+ while ! done
93
+ solve! (z, Pl, r) # Apply preconditioner r = PZ
94
+ x .+ = α.* z
95
+ r .= b
96
+ mul! (r, A, x, - 1 , 1 )
97
+ done = update! (log,norm (r))
98
+ end
99
+ finalize! (log,norm (r))
100
+ else # Case when no preconditioner is applied
101
+ while ! done
102
+ x .+ = α.* r
103
+ r .= b
104
+ mul! (r, A, x, - 1 , 1 )
105
+ done = update! (log,norm (r))
106
+ end
107
+ finalize! (log,norm (r))
108
+ end
109
+ return x
110
+ end
0 commit comments