73 class(
pc_t),
optional,
intent(in),
target :: M
74 integer,
intent(in) :: n
75 integer,
intent(in) :: max_iter
76 real(kind=
rp),
optional,
intent(in) :: rel_tol
77 real(kind=
rp),
optional,
intent(in) :: abs_tol
78 logical,
optional,
intent(in) :: monitor
95 if (
present(rel_tol) .and.
present(abs_tol) .and.
present(monitor))
then
96 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
97 else if (
present(rel_tol) .and.
present(abs_tol))
then
98 call this%ksp_init(max_iter, rel_tol, abs_tol)
99 else if (
present(monitor) .and.
present(abs_tol))
then
100 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
101 else if (
present(rel_tol) .and.
present(monitor))
then
102 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
103 else if (
present(rel_tol))
then
104 call this%ksp_init(max_iter, rel_tol = rel_tol)
105 else if (
present(abs_tol))
then
106 call this%ksp_init(max_iter, abs_tol = abs_tol)
107 else if (
present(monitor))
then
108 call this%ksp_init(max_iter, monitor = monitor)
110 call this%ksp_init(max_iter)
155 function sx_pipecg_solve(this, Ax, x, f, n, coef, blst, gs_h, niter)
result(ksp_results)
157 class(
ax_t),
intent(in) :: ax
158 type(
field_t),
intent(inout) :: x
159 integer,
intent(in) :: n
160 real(kind=
rp),
dimension(n),
intent(in) :: f
161 type(
coef_t),
intent(inout) :: coef
163 type(
gs_t),
intent(inout) :: gs_h
165 integer,
optional,
intent(in) :: niter
166 integer :: iter, max_iter, i, ierr
167 real(kind=
rp) :: rnorm, rtr, reduction(3), norm_fac
168 real(kind=
rp) :: alpha, beta, gamma1, gamma2, delta
169 real(kind=
rp) :: tmp1, tmp2, tmp3
170 type(mpi_request) :: request
171 type(mpi_status) :: status
173 if (
present(niter))
then
176 max_iter = this%max_iter
178 norm_fac = 1.0_rp / sqrt(coef%volume)
181 x%x(i,1,1,1) = 0.0_rp
189 call this%M%solve(this%u, this%r, n)
190 call ax%compute(this%w, this%u, coef, x%msh, x%Xh)
191 call gs_h%op(this%w, n, gs_op_add)
192 call blst%apply_scalar(this%w, n)
194 rtr =
glsc3(this%r, coef%mult, this%r, n)
195 rnorm = sqrt(rtr)*norm_fac
196 ksp_results%res_start = rnorm
197 ksp_results%res_final = rnorm
199 if(
abscmp(rnorm, 0.0_rp))
then
200 ksp_results%converged = .true.
206 call this%monitor_start(
'PipeCG')
207 do iter = 1, max_iter
213 tmp1 = tmp1 + this%r(i) * coef%mult(i,1,1,1) * this%u(i)
214 tmp2 = tmp2 + this%w(i) * coef%mult(i,1,1,1) * this%u(i)
215 tmp3 = tmp3 + this%r(i) * coef%mult(i,1,1,1) * this%r(i)
221 call mpi_iallreduce(mpi_in_place, reduction, 3, &
224 call this%M%solve(this%mi, this%w, n)
225 call ax%compute(this%ni, this%mi, coef, x%msh, x%Xh)
226 call gs_h%op(this%ni, n, gs_op_add)
227 call blst%apply(this%ni, n)
229 call mpi_wait(request, status, ierr)
231 gamma1 = reduction(1)
235 rnorm = sqrt(rtr)*norm_fac
236 call this%monitor_iter(iter, rnorm)
237 if (rnorm .lt. this%abs_tol)
then
241 if (iter .gt. 1)
then
242 beta = gamma1 / gamma2
243 alpha = gamma1 / (delta - (beta * gamma1/alpha))
250 this%z(i) = beta * this%z(i) + this%ni(i)
251 this%q(i) = beta * this%q(i) + this%mi(i)
252 this%s(i) = beta * this%s(i) + this%w(i)
253 this%p(i) = beta * this%p(i) + this%u(i)
257 x%x(i,1,1,1) = x%x(i,1,1,1) + alpha * this%p(i)
258 this%r(i) = this%r(i) - alpha * this%s(i)
259 this%u(i) = this%u(i) - alpha * this%q(i)
260 this%w(i) = this%w(i) - alpha * this%z(i)
264 call this%monitor_stop()
265 ksp_results%res_final = rnorm
266 ksp_results%iter = iter
272 n, coef, blstx, blsty, blstz, gs_h, niter)
result(ksp_results)
274 class(
ax_t),
intent(in) :: ax
275 type(
field_t),
intent(inout) :: x
276 type(
field_t),
intent(inout) :: y
277 type(
field_t),
intent(inout) :: z
278 integer,
intent(in) :: n
279 real(kind=
rp),
dimension(n),
intent(in) :: fx
280 real(kind=
rp),
dimension(n),
intent(in) :: fy
281 real(kind=
rp),
dimension(n),
intent(in) :: fz
282 type(
coef_t),
intent(inout) :: coef
286 type(
gs_t),
intent(inout) :: gs_h
288 integer,
optional,
intent(in) :: niter
290 ksp_results(1) = this%solve(ax, x, fx, n, coef, blstx, gs_h, niter)
291 ksp_results(2) = this%solve(ax, y, fy, n, coef, blsty, gs_h, niter)
292 ksp_results(3) = this%solve(ax, z, fz, n, coef, blstz, gs_h, niter)
type(ksp_monitor_t) function, dimension(3) sx_pipecg_solve_coupled(this, ax, x, y, z, fx, fy, fz, n, coef, blstx, blsty, blstz, gs_h, niter)
Pipelined PCG coupled solve.