@@ -14,8 +14,9 @@ submodule(stdlib_linalg_iterative_solvers) stdlib_linalg_iterative_pccg
14
14
contains
15
15
16
16
#:for k, t, s in R_KINDS_TYPES
17
- module subroutine solve_pccg_generic_${s}$(A,b,x,di,tol,maxiter,restart,workspace)
17
+ module subroutine solve_pccg_generic_${s}$(A,M, b,x,di,tol,maxiter,restart,workspace)
18
18
class(linop_${s}$), intent(in) :: A
19
+ class(linop_${s}$), intent(in) :: M !> preconditionner
19
20
${t}$, intent(in) :: b(:), tol
20
21
${t}$, intent(inout) :: x(:)
21
22
logical(1), intent(in) :: di(:)
@@ -41,7 +42,7 @@ contains
41
42
call A%matvec(X, R)
42
43
R = merge( zero_${s}$, B - R , di ) !> R = B - A*X
43
44
44
- call A%preconditionner (R,P) !> P = M^{-1}*R
45
+ call M%matvec (R,P) !> P = M^{-1}*R
45
46
P = merge( zero_${s}$, P, di )
46
47
47
48
tolsq = tol*tol
@@ -50,7 +51,7 @@ contains
50
51
zr2 = one_${s}$
51
52
do while ( (iter < maxiter) .AND. (norm_sq > tolsq * norm_sq0) )
52
53
53
- call A%preconditionner (R,S) !> S = M^{-1}*R
54
+ call M%matvec (R,S) !> S = M^{-1}*R
54
55
S = merge( zero_${s}$, S, di )
55
56
zr2 = A%inner_product( R, S )
56
57
@@ -80,7 +81,7 @@ contains
80
81
81
82
#:for matrix in MATRIX_TYPES
82
83
#:for k, t, s in R_KINDS_TYPES
83
- module subroutine solve_pccg_${matrix}$_${s}$(A,b,x,di,tol,maxiter,restart,workspace)
84
+ module subroutine solve_pccg_${matrix}$_${s}$(A,b,x,di,tol,maxiter,restart,M, workspace)
84
85
#:if matrix == "dense"
85
86
${t}$, intent(in) :: A(:,:)
86
87
#:else
@@ -92,9 +93,11 @@ contains
92
93
logical(1), intent(in), optional, target :: di(:)
93
94
integer, intent(in), optional :: maxiter
94
95
logical, intent(in), optional :: restart
96
+ class(linop_${s}$), optional , intent(in), target :: M !> preconditionner
95
97
type(solver_workspace_${s}$), optional, intent(inout), target :: workspace
96
98
!-------------------------
97
99
type(linop_${s}$) :: op
100
+ type(linop_${s}$), pointer :: M_ => null()
98
101
type(solver_workspace_${s}$), pointer :: workspace_
99
102
integer :: n, maxiter_
100
103
${t}$ :: tol_
@@ -109,8 +112,12 @@ contains
109
112
!-------------------------
110
113
! internal memory setup
111
114
op%matvec => default_matvec
112
- ! op%inner_product => default_dot
113
- op%preconditionner => default_preconditionner
115
+ if(present(M)) then
116
+ M_ => M
117
+ else
118
+ allocate( M_ )
119
+ M_%matvec => default_preconditionner
120
+ end if
114
121
if(present(di))then
115
122
di_ => di
116
123
else
@@ -125,7 +132,7 @@ contains
125
132
if(.not.allocated(workspace_%tmp)) allocate( workspace_%tmp(n,size_wksp_pccg) , source = zero_${s}$ )
126
133
!-------------------------
127
134
! main call to the solver
128
- call solve_pccg_generic(op,b,x,di_,tol_,maxiter_,restart_,workspace_)
135
+ call solve_pccg_generic(op,M_, b,x,di_,tol_,maxiter_,restart_,workspace_)
129
136
130
137
!-------------------------
131
138
! internal memory cleanup
@@ -136,6 +143,7 @@ contains
136
143
deallocate( workspace_%tmp )
137
144
deallocate( workspace_ )
138
145
end if
146
+ M_ => null()
139
147
workspace_ => null()
140
148
contains
141
149
0 commit comments