@@ -2,37 +2,88 @@ const CKSP = Ptr{Cvoid}
22const CKSPType = Cstring
33
44abstract type AbstractKSP{PetscLib, PetscScalar} <: Factorization{PetscScalar} end
5-
6- Base. @kwdef mutable struct KSP{PetscLib, PetscScalar} <: AbstractKSP{PetscLib, PetscScalar}
5+
6+ Base. @kwdef mutable struct KSP{PetscLib, PetscScalar} < :
7+ AbstractKSP{PetscLib, PetscScalar}
78 ptr:: CKSP = C_NULL
89 opts:: Options{PetscLib} = Options (PetscLib)
910 A:: Union{AbstractMat, Nothing} = nothing
11+ P:: Union{AbstractMat, Nothing} = nothing
1012end
1113
12- function KSP (A:: AbstractMat{PetscLib} ; kwargs... ) where PetscLib
14+ function KSP (
15+ A:: AbstractMat{PetscLib} ,
16+ P:: AbstractMat{PetscLib} = A;
17+ kwargs... ,
18+ ) where {PetscLib}
1319 @assert initialized (PetscLib)
1420 opts = Options (PetscLib; kwargs... )
1521 PetscScalar = PetscLib. PetscScalar
16- ksp = KSP {PetscLib, PetscScalar} (opts= opts, A = A)
17- #=
22+ ksp = KSP {PetscLib, PetscScalar} (opts = opts)
23+ comm = getcomm (A)
24+
1825 with (ksp. opts) do
19- @chk ccall((: KSPCreate, $libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CKSP}) , comm, ksp)
26+ LibPETSc . KSPCreate (PetscLib , comm, ksp)
2027 end
21- if comm == MPI.COMM_SELF
28+
29+ setoperators! (ksp, A, P)
30+ setfromoptions! (ksp)
31+
32+ # If there is only one rank we can finalize the KSP with GC
33+ if MPI. Comm_size (comm) == 1
2234 finalizer (destroy, ksp)
2335 end
24- =#
36+
37+ return ksp
38+ end
39+
40+ function setoperators! (
41+ ksp:: AbstractKSP{PetscLib} ,
42+ A:: AbstractMat{PetscLib} ,
43+ P:: AbstractMat{PetscLib} = A,
44+ ) where {PetscLib}
45+ LibPETSc. KSPSetOperators (PetscLib, ksp, A, P)
46+ ksp. A = A
47+ ksp. P = P
2548 return ksp
2649end
2750
51+ function setfromoptions! (ksp:: AbstractKSP{PetscLib} ) where {PetscLib}
52+ with (ksp. opts) do
53+ LibPETSc. KSPSetFromOptions (PetscLib, ksp)
54+ end
55+ end
56+
57+ function destroy (ksp:: AbstractKSP{PetscLib} ) where {PetscLib}
58+ finalized (PetscLib) || LibPETSc. MatDestroy (PetscLib, ksp)
59+ return nothing
60+ end
61+
62+ function solve! (
63+ x:: AbstractVec{PetscLib} ,
64+ ksp:: AbstractKSP{PetscLib} ,
65+ b:: AbstractVec{PetscLib} ,
66+ ) where {PetscLib}
67+ with (ksp. opts) do
68+ LibPETSc. KSPSolve (PetscLib, ksp, b, x)
69+ end
70+ return x
71+ end
72+
73+ function LinearAlgebra. ldiv! (x:: AbstractVec , ksp:: AbstractKSP , b:: AbstractVec )
74+ solve! (x, ksp, b)
75+ end
76+ #=
77+ function Base.:\(ksp::AbstractKSP, b::AbstractVec)
78+ ldiv!(similar(b), ksp, b)
79+ end
80+ =#
81+
2882#=
2983struct WrappedKSP{T, PetscLib} <: AbstractKSP{T, PetscLib}
3084 ptr::CKSP
3185end
3286
33- scalartype(::KSP{T}) where {T} = T
34- Base.eltype(::KSP{T}) where {T} = T
35-
3687LinearAlgebra.transpose(ksp) = LinearAlgebra.Transpose(ksp)
3788LinearAlgebra.adjoint(ksp) = LinearAlgebra.Adjoint(ksp)
3889
@@ -80,32 +131,6 @@ struct Fn_KSPComputeOperators{T} end
80131
81132@for_libpetsc begin
82133
83- function KSP{$PetscScalar}(comm::MPI.Comm; kwargs...)
84- @assert initialized($petsclib)
85- opts = Options($petsclib, kwargs...)
86- ksp = KSP{$PetscScalar, $PetscLib}(opts=opts)
87- with(ksp.opts) do
88- @chk ccall((:KSPCreate, $libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CKSP}), comm, ksp)
89- end
90- if comm == MPI.COMM_SELF
91- finalizer(destroy, ksp)
92- end
93- return ksp
94- end
95-
96- function destroy(ksp::KSP{$PetscScalar})
97- finalized($petsclib) ||
98- @chk ccall((:KSPDestroy, $libpetsc), PetscErrorCode, (Ptr{CKSP},), ksp)
99- return nothing
100- end
101-
102- function setoperators!(ksp::KSP{$PetscScalar}, A::AbstractMat{$PetscScalar}, P::AbstractMat{$PetscScalar})
103- @chk ccall((:KSPSetOperators, $libpetsc), PetscErrorCode, (CKSP, CMat, CMat), ksp, A, P)
104- ksp._A = A
105- ksp._P = P
106- return nothing
107- end
108-
109134 function (::Fn_KSPComputeRHS{$PetscScalar})(
110135 new_ksp_ptr::CKSP,
111136 cb::CVec,
@@ -194,12 +219,6 @@ struct Fn_KSPComputeOperators{T} end
194219 return nothing
195220 end
196221
197- function setfromoptions!(ksp::KSP{$PetscScalar})
198- with(ksp.opts) do
199- @chk ccall((:KSPSetFromOptions, $libpetsc), PetscErrorCode, (CKSP,), ksp)
200- end
201- end
202-
203222 function gettype(ksp::KSP{$PetscScalar})
204223 t_r = Ref{CKSPType}()
205224 @chk ccall((:KSPGetType, $libpetsc), PetscErrorCode, (CKSP, Ptr{CKSPType}), ksp, t_r)
@@ -227,14 +246,6 @@ struct Fn_KSPComputeOperators{T} end
227246 return r_rnorm[]
228247 end
229248
230- function solve!(x::AbstractVec{$PetscScalar}, ksp::KSP{$PetscScalar}, b::AbstractVec{$PetscScalar})
231- with(ksp.opts) do
232- @chk ccall((:KSPSolve, $libpetsc), PetscErrorCode,
233- (CKSP, CVec, CVec), ksp, b, x)
234- end
235- return x
236- end
237-
238249 function solve!(ksp::KSP{$PetscScalar})
239250 with(ksp.opts) do
240251 @chk ccall((:KSPSolve, $libpetsc), PetscErrorCode,
@@ -266,21 +277,6 @@ function LinearAlgebra.ldiv!(x::AbstractVector{T}, ksp::KSPAT{T, LT}, b::Abstrac
266277end
267278Base.:\(ksp::KSPAT{T, LT}, b::AbstractVector{T}) where {T, LT} = ldiv!(similar(b), ksp, b)
268279
269-
270- """
271- KSP(A, P; options...)
272-
273- Construct a PETSc Krylov subspace solver.
274-
275- Any PETSc options prefixed with `ksp_` and `pc_` can be passed as keywords.
276- """
277- function KSP(A::AbstractMat{T}, P::AbstractMat{T}=A; kwargs...) where {T}
278- ksp = KSP{T}(getcomm(A); kwargs...)
279- setoperators!(ksp, A, P)
280- setfromoptions!(ksp)
281- return ksp
282- end
283-
284280"""
285281 KSP(da::AbstractDM; options...)
286282
300296
301297Base.show(io::IO, ksp::KSP) = _show(io, ksp)
302298
303-
304299"""
305300 iters(ksp::KSP)
306301
@@ -311,7 +306,6 @@ $(_doc_external("KSP/KSPGetIterationNumber"))
311306"""
312307iters
313308
314-
315309"""
316310 resnorm(ksp::KSP)
317311
0 commit comments