1
1
2
- # TODO : composed preconditioners, preconditioner setter for cache,
3
- # detailed tests for wrappers
4
-
5
2
# # Preconditioners
6
3
7
- struct ScaleVector{T}
8
- s:: T
9
- isleft:: Bool
4
+ scaling_preconditioner (s) = I * s , I * (1 / s)
5
+
6
+ struct ComposePreconditioner{Ti,To}
7
+ inner:: Ti
8
+ outer:: To
10
9
end
11
10
12
- function LinearAlgebra. ldiv! (v:: ScaleVector , x)
11
+ Base. eltype (A:: ComposePreconditioner ) = promote_type (eltype (A. inner), eltype (A. outer))
12
+ Base. adjoint (A:: ComposePreconditioner ) = ComposePreconditioner (A. outer' , A. inner' )
13
+ Base. inv (A:: ComposePreconditioner ) = InvComposePreconditioner (A)
14
+
15
+ function LinearAlgebra. ldiv! (A:: ComposePreconditioner , x)
16
+ @unpack inner, outer = A
17
+
18
+ ldiv! (inner, x)
19
+ ldiv! (outer, x)
13
20
end
14
21
15
- function LinearAlgebra. ldiv! (y, v:: ScaleVector , x)
22
+ function LinearAlgebra. ldiv! (y, A:: ComposePreconditioner , x)
23
+ @unpack inner, outer = A
24
+
25
+ ldiv! (y, inner, x)
26
+ ldiv! (outer, y)
16
27
end
17
28
18
- struct ComposePreconditioner{Ti,To}
19
- inner:: Ti
20
- outer:: To
21
- isleft:: Bool
29
+ struct InvComposePreconditioner{Tp <: ComposePreconditioner }
30
+ P:: Tp
22
31
end
23
32
24
- function LinearAlgebra. ldiv! (v:: ComposePreconditioner , x)
25
- @unpack inner, outer, isleft = v
33
+ InvComposePreconditioner (inner, outer) = InvComposePreconditioner (ComposePreconditioner (inner, outer))
34
+
35
+ Base. eltype (A:: InvComposePreconditioner ) = Base. eltype (A. P)
36
+ Base. adjoint (A:: InvComposePreconditioner ) = InvComposePreconditioner (A. P' )
37
+ Base. inv (A:: InvComposePreconditioner ) = deepcopy (A. P)
38
+
39
+ function LinearAlgebra. mul! (y, A:: InvComposePreconditioner , x)
40
+ @unpack P = A
41
+ ldiv! (y, P, x)
26
42
end
27
43
28
- function LinearAlgebra. ldiv! (y, v:: ComposePreconditioner , x)
29
- @unpack inner, outer, isleft = v
44
+ function get_preconditioner (Pi, Po)
45
+
46
+ ifPi = Pi != = Identity ()
47
+ ifPo = Po != = Identity ()
48
+
49
+ P =
50
+ if ifPi & ifPo
51
+ ComposePreconditioner (Pi, Po)
52
+ elseif ifPi | ifPo
53
+ ifPi ? Pi : Po
54
+ else
55
+ Identity ()
56
+ end
57
+
58
+ return P
30
59
end
31
60
32
61
# # Krylov.jl
@@ -41,10 +70,14 @@ struct KrylovJL{F,Tl,Tr,I,A,K} <: AbstractKrylovSubspaceMethod
41
70
kwargs:: K
42
71
end
43
72
44
- function KrylovJL (args... ; KrylovAlg = Krylov. gmres!, Pl= I, Pr= I,
73
+ function KrylovJL (args... ; KrylovAlg = Krylov. gmres!,
74
+ Pl= nothing , Pr= nothing ,
45
75
gmres_restart= 0 , window= 0 ,
46
76
kwargs... )
47
77
78
+ Pl = (Pl === nothing ) ? Identity () : Pl
79
+ Pr = (Pr === nothing ) ? Identity () : Pr
80
+
48
81
return KrylovJL (KrylovAlg, Pl, Pr, gmres_restart, window,
49
82
args, kwargs)
50
83
end
@@ -132,6 +165,12 @@ function SciMLBase.solve(cache::LinearCache, alg::KrylovJL; kwargs...)
132
165
cache = set_cacheval (cache, solver)
133
166
end
134
167
168
+ M = get_preconditioner (alg. Pl, cache. Pl)
169
+ N = get_preconditioner (alg. Pr, cache. Pr)
170
+
171
+ M = (M === Identity ()) ? I : inv (M)
172
+ N = (N === Identity ()) ? I : inv (N)
173
+
135
174
atol = cache. abstol
136
175
rtol = cache. reltol
137
176
itmax = cache. maxiters
@@ -142,20 +181,20 @@ function SciMLBase.solve(cache::LinearCache, alg::KrylovJL; kwargs...)
142
181
alg. kwargs... )
143
182
144
183
if cache. cacheval isa Krylov. CgSolver
145
- alg . Pr != LinearAlgebra . I &&
184
+ N != = I &&
146
185
@warn " $(alg. KrylovAlg) doesn't support right preconditioning."
147
- Krylov. solve! (args... ; M= alg . Pl ,
186
+ Krylov. solve! (args... ; M= M ,
148
187
kwargs... )
149
188
elseif cache. cacheval isa Krylov. GmresSolver
150
- Krylov. solve! (args... ; M= alg . Pl , N= alg . Pr ,
189
+ Krylov. solve! (args... ; M= M , N= N ,
151
190
kwargs... )
152
191
elseif cache. cacheval isa Krylov. BicgstabSolver
153
- Krylov. solve! (args... ; M= alg . Pl , N= alg . Pr ,
192
+ Krylov. solve! (args... ; M= M , N= N ,
154
193
kwargs... )
155
194
elseif cache. cacheval isa Krylov. MinresSolver
156
- alg . Pr != LinearAlgebra . I &&
195
+ N != = I &&
157
196
@warn " $(alg. KrylovAlg) doesn't support right preconditioning."
158
- Krylov. solve! (args... ; M= alg . Pl ,
197
+ Krylov. solve! (args... ; M= M ,
159
198
kwargs... )
160
199
else
161
200
Krylov. solve! (args... ; kwargs... )
177
216
178
217
function IterativeSolversJL (args... ;
179
218
generate_iterator = IterativeSolvers. gmres_iterable!,
180
- Pl= IterativeSolvers. Identity (),
181
- Pr= IterativeSolvers. Identity (),
219
+ Pl= nothing , Pr= nothing ,
182
220
gmres_restart= 0 , kwargs... )
221
+
222
+ Pl = (Pl === nothing ) ? Identity () : Pl
223
+ Pr = (Pr === nothing ) ? Identity () : Pr
224
+
183
225
return IterativeSolversJL (generate_iterator, Pl, Pr, gmres_restart,
184
226
args, kwargs)
185
227
end
@@ -204,8 +246,8 @@ IterativeSolversJL_MINRES(args...;kwargs...) =
204
246
function init_cacheval (alg:: IterativeSolversJL , cache:: LinearCache )
205
247
@unpack A, b, u = cache
206
248
207
- Pl = (alg. Pl == LinearAlgebra . I) ? IterativeSolvers . Identity () : alg . Pl
208
- Pr = (alg. Pr == LinearAlgebra . I) ? IterativeSolvers . Identity () : alg . Pr
249
+ Pl = get_preconditioner (alg. Pl, cache . Pl)
250
+ Pr = get_preconditioner (alg. Pr, cache . Pr)
209
251
210
252
abstol = cache. abstol
211
253
reltol = cache. reltol
@@ -218,15 +260,15 @@ function init_cacheval(alg::IterativeSolversJL, cache::LinearCache)
218
260
alg. kwargs... )
219
261
220
262
iterable = if alg. generate_iterator === IterativeSolvers. cg_iterator!
221
- Pr != IterativeSolvers . Identity () &&
263
+ Pr != = Identity () &&
222
264
@warn " $(alg. generate_iterator) doesn't support right preconditioning"
223
265
alg. generate_iterator (u, A, b, Pl;
224
266
kwargs... )
225
267
elseif alg. generate_iterator === IterativeSolvers. gmres_iterable!
226
268
alg. generate_iterator (u, A, b; Pl= Pl, Pr= Pr, restart= restart,
227
269
kwargs... )
228
270
elseif alg. generate_iterator === IterativeSolvers. bicgstabl_iterator!
229
- Pr != IterativeSolvers . Identity () &&
271
+ Pr != = Identity () &&
230
272
@warn " $(alg. generate_iterator) doesn't support right preconditioning"
231
273
alg. generate_iterator (u, A, b, alg. args... ; Pl= Pl,
232
274
abstol= abstol, reltol= reltol,
0 commit comments