162 function pipecg_solve(this, Ax, x, f, n, coef, blst, gs_h, niter)
result(ksp_results)
163 class(
pipecg_t),
intent(inout) :: this
164 class(
ax_t),
intent(in) :: ax
165 type(
field_t),
intent(inout) :: x
166 integer,
intent(in) :: n
167 real(kind=
rp),
dimension(n),
intent(in) :: f
168 type(
coef_t),
intent(inout) :: coef
170 type(
gs_t),
intent(inout) :: gs_h
172 integer,
optional,
intent(in) :: niter
173 integer :: iter, max_iter, i, j, k, ierr, p_cur, p_prev, u_prev
174 real(kind=
rp) :: rnorm, rtr, reduction(3), norm_fac
176 real(kind=
rp) :: gamma1, gamma2, delta
178 type(mpi_request) :: request
179 type(mpi_status) :: status
181 if (
present(niter))
then
184 max_iter = this%max_iter
186 norm_fac = 1.0_rp / sqrt(coef%volume)
188 associate(p => this%p, q => this%q, r => this%r, s => this%s, &
189 u => this%u, w => this%w, z => this%z, mi => this%mi, ni => this%ni)
196 x%x(i,1,1,1) = 0.0_rp
204 call this%M%solve(u(1,u_prev), r, n)
205 call ax%compute(w, u(1,u_prev), coef, x%msh, x%Xh)
206 call gs_h%op(w, n, gs_op_add)
207 call blst%apply(w, n)
209 rtr =
glsc3(r, coef%mult, r, n)
210 rnorm = sqrt(rtr)*norm_fac
211 ksp_results%res_start = rnorm
212 ksp_results%res_final = rnorm
215 if(
abscmp(rnorm, 0.0_rp))
then
216 ksp_results%converged = .true.
226 tmp1 = tmp1 + r(i) * coef%mult(i,1,1,1) * u(i,u_prev)
227 tmp2 = tmp2 + w(i) * coef%mult(i,1,1,1) * u(i,u_prev)
228 tmp3 = tmp3 + r(i) * coef%mult(i,1,1,1) * r(i)
235 call this%monitor_start(
'PipeCG')
236 do iter = 1, max_iter
237 call mpi_iallreduce(mpi_in_place, reduction, 3, &
240 call this%M%solve(mi, w, n)
241 call ax%compute(ni, mi, coef, x%msh, x%Xh)
242 call gs_h%op(ni, n, gs_op_add)
243 call blst%apply(ni, n)
245 call mpi_wait(request, status, ierr)
247 gamma1 = reduction(1)
251 rnorm = sqrt(rtr)*norm_fac
252 call this%monitor_iter(iter, rnorm)
253 if (rnorm .lt. this%abs_tol)
exit
255 if (iter .gt. 1)
then
256 beta(p_cur) = gamma1 / gamma2
257 alpha(p_cur) = gamma1 / (delta - (beta(p_cur) * gamma1/alpha(p_prev)))
260 alpha(p_cur) = gamma1/delta
271 z(i+k) = beta(p_cur) * z(i+k) + ni(i+k)
272 q(i+k) = beta(p_cur) * q(i+k) + mi(i+k)
273 s(i+k) = beta(p_cur) * s(i+k) + w(i+k)
274 r(i+k) = r(i+k) - alpha(p_cur) * s(i+k)
275 u(i+k,p_cur) = u(i+k,u_prev) - alpha(p_cur) * q(i+k)
276 w(i+k) = w(i+k) - alpha(p_cur) * z(i+k)
277 tmp1 = tmp1 + r(i+k) * coef%mult(i+k,1,1,1) * u(i+k,p_cur)
278 tmp2 = tmp2 + w(i+k) * coef%mult(i+k,1,1,1) * u(i+k,p_cur)
279 tmp3 = tmp3 + r(i+k) * coef%mult(i+k,1,1,1) * r(i+k)
283 z(i+k) = beta(p_cur) * z(i+k) + ni(i+k)
284 q(i+k) = beta(p_cur) * q(i+k) + mi(i+k)
285 s(i+k) = beta(p_cur) * s(i+k) + w(i+k)
286 r(i+k) = r(i+k) - alpha(p_cur) * s(i+k)
287 u(i+k,p_cur) = u(i+k,u_prev) - alpha(p_cur) * q(i+k)
288 w(i+k) = w(i+k) - alpha(p_cur) * z(i+k)
289 tmp1 = tmp1 + r(i+k) * coef%mult(i+k,1,1,1) * u(i+k,p_cur)
290 tmp2 = tmp2 + w(i+k) * coef%mult(i+k,1,1,1) * u(i+k,p_cur)
291 tmp3 = tmp3 + r(i+k) * coef%mult(i+k,1,1,1) * r(i+k)
312 p(i+k) = beta(j) * p(i+k) + u(i+k,p_prev)
313 x_plus(k) = x_plus(k) + alpha(j) * p(i+k)
319 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + x_plus(k)
329 p(i+k) = beta(j) * p(i+k) + u(i+k,p_prev)
330 x_plus(k) = x_plus(k) + alpha(j) * p(i+k)
335 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + x_plus(k)
343 alpha(1) = alpha(p_cur)
344 beta(1) = beta(p_cur)
353 if ( p_cur .ne. 1)
then
365 p(i+k) = beta(j) * p(i+k) + u(i+k,p_prev)
366 x_plus(k) = x_plus(k) + alpha(j) * p(i+k)
372 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + x_plus(k)
382 p(i+k) = beta(j) * p(i+k) + u(i+k,p_prev)
383 x_plus(k) = x_plus(k) + alpha(j) * p(i+k)
388 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + x_plus(k)
395 call this%monitor_stop()
396 ksp_results%res_final = rnorm
397 ksp_results%iter = iter
398 ksp_results%converged = this%is_converged(iter, rnorm)
406 n, coef, blstx, blsty, blstz, gs_h, niter)
result(ksp_results)
407 class(
pipecg_t),
intent(inout) :: this
408 class(ax_t),
intent(in) :: ax
409 type(field_t),
intent(inout) :: x
410 type(field_t),
intent(inout) :: y
411 type(field_t),
intent(inout) :: z
412 integer,
intent(in) :: n
413 real(kind=rp),
dimension(n),
intent(in) :: fx
414 real(kind=rp),
dimension(n),
intent(in) :: fy
415 real(kind=rp),
dimension(n),
intent(in) :: fz
416 type(coef_t),
intent(inout) :: coef
417 type(bc_list_t),
intent(inout) :: blstx
418 type(bc_list_t),
intent(inout) :: blsty
419 type(bc_list_t),
intent(inout) :: blstz
420 type(gs_t),
intent(inout) :: gs_h
421 type(ksp_monitor_t),
dimension(3) :: ksp_results
422 integer,
optional,
intent(in) :: niter
424 ksp_results(1) = this%solve(ax, x, fx, n, coef, blstx, gs_h, niter)
425 ksp_results(2) = this%solve(ax, y, fy, n, coef, blsty, gs_h, niter)
426 ksp_results(3) = this%solve(ax, z, fz, n, coef, blstz, gs_h, niter)