11
2- # TODO : composed preconditioners, preconditioner setter for cache,
3- # detailed tests for wrappers
4-
52# # Preconditioners
63
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
109end
1110
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)
1320end
1421
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)
1627end
1728
18- struct ComposePreconditioner{Ti,To}
19- inner:: Ti
20- outer:: To
21- isleft:: Bool
29+ struct InvComposePreconditioner{Tp <: ComposePreconditioner }
30+ P:: Tp
2231end
2332
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)
2642end
2743
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
3059end
3160
3261# # Krylov.jl
@@ -41,10 +70,14 @@ struct KrylovJL{F,Tl,Tr,I,A,K} <: AbstractKrylovSubspaceMethod
4170 kwargs:: K
4271end
4372
44- function KrylovJL (args... ; KrylovAlg = Krylov. gmres!, Pl= I, Pr= I,
73+ function KrylovJL (args... ; KrylovAlg = Krylov. gmres!,
74+ Pl= nothing , Pr= nothing ,
4575 gmres_restart= 0 , window= 0 ,
4676 kwargs... )
4777
78+ Pl = (Pl === nothing ) ? Identity () : Pl
79+ Pr = (Pr === nothing ) ? Identity () : Pr
80+
4881 return KrylovJL (KrylovAlg, Pl, Pr, gmres_restart, window,
4982 args, kwargs)
5083end
@@ -132,6 +165,12 @@ function SciMLBase.solve(cache::LinearCache, alg::KrylovJL; kwargs...)
132165 cache = set_cacheval (cache, solver)
133166 end
134167
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+
135174 atol = cache. abstol
136175 rtol = cache. reltol
137176 itmax = cache. maxiters
@@ -142,20 +181,20 @@ function SciMLBase.solve(cache::LinearCache, alg::KrylovJL; kwargs...)
142181 alg. kwargs... )
143182
144183 if cache. cacheval isa Krylov. CgSolver
145- alg . Pr != LinearAlgebra . I &&
184+ N != = I &&
146185 @warn " $(alg. KrylovAlg) doesn't support right preconditioning."
147- Krylov. solve! (args... ; M= alg . Pl ,
186+ Krylov. solve! (args... ; M= M ,
148187 kwargs... )
149188 elseif cache. cacheval isa Krylov. GmresSolver
150- Krylov. solve! (args... ; M= alg . Pl , N= alg . Pr ,
189+ Krylov. solve! (args... ; M= M , N= N ,
151190 kwargs... )
152191 elseif cache. cacheval isa Krylov. BicgstabSolver
153- Krylov. solve! (args... ; M= alg . Pl , N= alg . Pr ,
192+ Krylov. solve! (args... ; M= M , N= N ,
154193 kwargs... )
155194 elseif cache. cacheval isa Krylov. MinresSolver
156- alg . Pr != LinearAlgebra . I &&
195+ N != = I &&
157196 @warn " $(alg. KrylovAlg) doesn't support right preconditioning."
158- Krylov. solve! (args... ; M= alg . Pl ,
197+ Krylov. solve! (args... ; M= M ,
159198 kwargs... )
160199 else
161200 Krylov. solve! (args... ; kwargs... )
177216
178217function IterativeSolversJL (args... ;
179218 generate_iterator = IterativeSolvers. gmres_iterable!,
180- Pl= IterativeSolvers. Identity (),
181- Pr= IterativeSolvers. Identity (),
219+ Pl= nothing , Pr= nothing ,
182220 gmres_restart= 0 , kwargs... )
221+
222+ Pl = (Pl === nothing ) ? Identity () : Pl
223+ Pr = (Pr === nothing ) ? Identity () : Pr
224+
183225 return IterativeSolversJL (generate_iterator, Pl, Pr, gmres_restart,
184226 args, kwargs)
185227end
@@ -204,8 +246,8 @@ IterativeSolversJL_MINRES(args...;kwargs...) =
204246function init_cacheval (alg:: IterativeSolversJL , cache:: LinearCache )
205247 @unpack A, b, u = cache
206248
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)
209251
210252 abstol = cache. abstol
211253 reltol = cache. reltol
@@ -218,15 +260,15 @@ function init_cacheval(alg::IterativeSolversJL, cache::LinearCache)
218260 alg. kwargs... )
219261
220262 iterable = if alg. generate_iterator === IterativeSolvers. cg_iterator!
221- Pr != IterativeSolvers . Identity () &&
263+ Pr != = Identity () &&
222264 @warn " $(alg. generate_iterator) doesn't support right preconditioning"
223265 alg. generate_iterator (u, A, b, Pl;
224266 kwargs... )
225267 elseif alg. generate_iterator === IterativeSolvers. gmres_iterable!
226268 alg. generate_iterator (u, A, b; Pl= Pl, Pr= Pr, restart= restart,
227269 kwargs... )
228270 elseif alg. generate_iterator === IterativeSolvers. bicgstabl_iterator!
229- Pr != IterativeSolvers . Identity () &&
271+ Pr != = Identity () &&
230272 @warn " $(alg. generate_iterator) doesn't support right preconditioning"
231273 alg. generate_iterator (u, A, b, alg. args... ; Pl= Pl,
232274 abstol= abstol, reltol= reltol,
0 commit comments