159 function pipecg_solve(this, Ax, x, f, n, coef, blst, gs_h, niter)
result(ksp_results)
160 class(
pipecg_t),
intent(inout) :: this
161 class(
ax_t),
intent(in) :: ax
162 type(
field_t),
intent(inout) :: x
163 integer,
intent(in) :: n
164 real(kind=
rp),
dimension(n),
intent(in) :: f
165 type(
coef_t),
intent(inout) :: coef
167 type(
gs_t),
intent(inout) :: gs_h
169 integer,
optional,
intent(in) :: niter
170 integer :: iter, max_iter, i, j, k, ierr, p_cur, p_prev, u_prev
171 real(kind=
rp) :: rnorm, rtr, reduction(3), norm_fac
173 real(kind=
rp) :: gamma1, gamma2, delta
174 real(kind=
rp) :: tmp1, tmp2, tmp3, x_plus(neko_blk_size)
175 type(mpi_request) :: request
176 type(mpi_status) :: status
178 if (
present(niter))
then
181 max_iter = this%max_iter
183 norm_fac = 1.0_rp / sqrt(coef%volume)
185 associate(p => this%p, q => this%q, r => this%r, s => this%s, &
186 u => this%u, w => this%w, z => this%z, mi => this%mi, ni => this%ni)
197 call this%M%solve(u(1,u_prev), r, n)
198 call ax%compute(w, u(1,u_prev), coef, x%msh, x%Xh)
199 call gs_h%op(w, n, gs_op_add)
200 call blst%apply(w, n)
202 rtr =
glsc3(r, coef%mult, r, n)
203 rnorm = sqrt(rtr)*norm_fac
204 ksp_results%res_start = rnorm
205 ksp_results%res_final = rnorm
207 if(
abscmp(rnorm, 0.0_rp))
return
214 tmp1 = tmp1 + r(i) * coef%mult(i,1,1,1) * u(i,u_prev)
215 tmp2 = tmp2 + w(i) * coef%mult(i,1,1,1) * u(i,u_prev)
216 tmp3 = tmp3 + r(i) * coef%mult(i,1,1,1) * r(i)
222 call this%monitor_start(
'PipeCG')
223 do iter = 1, max_iter
224 call mpi_iallreduce(mpi_in_place, reduction, 3, &
227 call this%M%solve(mi, w, n)
228 call ax%compute(ni, mi, coef, x%msh, x%Xh)
229 call gs_h%op(ni, n, gs_op_add)
230 call blst%apply(ni, n)
232 call mpi_wait(request, status, ierr)
234 gamma1 = reduction(1)
238 rnorm = sqrt(rtr)*norm_fac
239 call this%monitor_iter(iter, rnorm)
240 if (rnorm .lt. this%abs_tol)
exit
242 if (iter .gt. 1)
then
243 beta(p_cur) = gamma1 / gamma2
244 alpha(p_cur) = gamma1 / (delta - (beta(p_cur) * gamma1/alpha(p_prev)))
247 alpha(p_cur) = gamma1/delta
253 do i = 0, n, neko_blk_size
254 if (i + neko_blk_size .le. n)
then
255 do k = 1, neko_blk_size
256 z(i+k) = beta(p_cur) * z(i+k) + ni(i+k)
257 q(i+k) = beta(p_cur) * q(i+k) + mi(i+k)
258 s(i+k) = beta(p_cur) * s(i+k) + w(i+k)
259 r(i+k) = r(i+k) - alpha(p_cur) * s(i+k)
260 u(i+k,p_cur) = u(i+k,u_prev) - alpha(p_cur) * q(i+k)
261 w(i+k) = w(i+k) - alpha(p_cur) * z(i+k)
262 tmp1 = tmp1 + r(i+k) * coef%mult(i+k,1,1,1) * u(i+k,p_cur)
263 tmp2 = tmp2 + w(i+k) * coef%mult(i+k,1,1,1) * u(i+k,p_cur)
264 tmp3 = tmp3 + r(i+k) * coef%mult(i+k,1,1,1) * r(i+k)
268 z(i+k) = beta(p_cur) * z(i+k) + ni(i+k)
269 q(i+k) = beta(p_cur) * q(i+k) + mi(i+k)
270 s(i+k) = beta(p_cur) * s(i+k) + w(i+k)
271 r(i+k) = r(i+k) - alpha(p_cur) * s(i+k)
272 u(i+k,p_cur) = u(i+k,u_prev) - alpha(p_cur) * q(i+k)
273 w(i+k) = w(i+k) - alpha(p_cur) * z(i+k)
274 tmp1 = tmp1 + r(i+k) * coef%mult(i+k,1,1,1) * u(i+k,p_cur)
275 tmp2 = tmp2 + w(i+k) * coef%mult(i+k,1,1,1) * u(i+k,p_cur)
276 tmp3 = tmp3 + r(i+k) * coef%mult(i+k,1,1,1) * r(i+k)
286 do i = 0, n, neko_blk_size
287 if (i + neko_blk_size .le. n)
then
288 do k = 1, neko_blk_size
293 do k = 1, neko_blk_size
294 p(i+k) = beta(j) * p(i+k) + u(i+k,p_prev)
295 x_plus(k) = x_plus(k) + alpha(j) * p(i+k)
299 do k = 1, neko_blk_size
300 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + x_plus(k)
308 p(i+k) = beta(j) * p(i+k) + u(i+k,p_prev)
309 x_plus(1) = x_plus(1) + alpha(j) * p(i+k)
312 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + x_plus(1)
319 alpha(1) = alpha(p_cur)
320 beta(1) = beta(p_cur)
329 if ( p_cur .ne. 1)
then
330 do i = 0, n, neko_blk_size
331 if (i + neko_blk_size .le. n)
then
332 do k = 1, neko_blk_size
337 do k = 1, neko_blk_size
338 p(i+k) = beta(j) * p(i+k) + u(i+k,p_prev)
339 x_plus(k) = x_plus(k) + alpha(j) * p(i+k)
343 do k = 1, neko_blk_size
344 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + x_plus(k)
352 p(i+k) = beta(j) * p(i+k) + u(i+k,p_prev)
353 x_plus(1) = x_plus(1) + alpha(j) * p(i+k)
356 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + x_plus(1)
362 call this%monitor_stop()
363 ksp_results%res_final = rnorm
364 ksp_results%iter = iter
365 ksp_results%converged = this%is_converged(iter, rnorm)
373 n, coef, blstx, blsty, blstz, gs_h, niter)
result(ksp_results)
374 class(
pipecg_t),
intent(inout) :: this
375 class(ax_t),
intent(in) :: ax
376 type(field_t),
intent(inout) :: x
377 type(field_t),
intent(inout) :: y
378 type(field_t),
intent(inout) :: z
379 integer,
intent(in) :: n
380 real(kind=rp),
dimension(n),
intent(in) :: fx
381 real(kind=rp),
dimension(n),
intent(in) :: fy
382 real(kind=rp),
dimension(n),
intent(in) :: fz
383 type(coef_t),
intent(inout) :: coef
384 type(bc_list_t),
intent(inout) :: blstx
385 type(bc_list_t),
intent(inout) :: blsty
386 type(bc_list_t),
intent(inout) :: blstz
387 type(gs_t),
intent(inout) :: gs_h
388 type(ksp_monitor_t),
dimension(3) :: ksp_results
389 integer,
optional,
intent(in) :: niter
391 ksp_results(1) = this%solve(ax, x, fx, n, coef, blstx, gs_h, niter)
392 ksp_results(2) = this%solve(ax, y, fy, n, coef, blsty, gs_h, niter)
393 ksp_results(3) = this%solve(ax, z, fz, n, coef, blstz, gs_h, niter)