191 function bicgstab_cpld_solve(this, Ax, x, y, z, fx, fy, fz, n, coef, &
192 bc_projector, gs_h, niter)
result(ksp_results)
194 class(
ax_t),
intent(in) :: ax
195 type(
field_t),
intent(inout) :: x
196 type(
field_t),
intent(inout) :: y
197 type(
field_t),
intent(inout) :: z
198 integer,
intent(in) :: n
199 real(kind=
rp),
dimension(n),
intent(in) :: fx
200 real(kind=
rp),
dimension(n),
intent(in) :: fy
201 real(kind=
rp),
dimension(n),
intent(in) :: fz
202 type(
coef_t),
intent(inout) :: coef
204 type(
gs_t),
intent(inout) :: gs_h
205 integer,
optional,
intent(in) :: niter
207 integer :: i, iter, max_iter, ierr
208 real(kind=
rp) :: alpha, beta, omega, rho_1, rho_2
209 real(kind=
rp) :: rnorm, norm_fac, gamma
210 real(kind=
rp) :: r_norm, s_norm, shadow_norm, t_norm, v_norm
212 real(kind=
rp) :: rtr, sts, ftv, vtv, stt, ttt
213 real(kind=
xp) :: norm_sum
214 real(kind=
rp),
pointer,
dimension(:) :: p_tmp, p_hat_tmp, r_tmp
215 real(kind=
rp),
pointer,
dimension(:) :: s_hat_tmp, t_tmp, v_tmp
216 integer :: temp_indices(6)
218 if (
present(niter))
then
221 max_iter = this%max_iter
223 norm_fac = 1.0_rp / sqrt(coef%volume)
232 this%p(1:n, 1:3) => p_tmp
233 this%p_hat(1:n, 1:3) => p_hat_tmp
234 this%r(1:n, 1:3) => r_tmp
235 this%s_hat(1:n, 1:3) => s_hat_tmp
236 this%t(1:n, 1:3) => t_tmp
237 this%v(1:n, 1:3) => v_tmp
239 associate(p => this%p, p_hat => this%p_hat, r => this%r, &
240 s_hat => this%s_hat, t => this%t, v => this%v)
247 x%x(i, 1, 1, 1) = 0.0_rp
248 y%x(i, 1, 1, 1) = 0.0_rp
249 z%x(i, 1, 1, 1) = 0.0_rp
253 norm_sum = norm_sum + coef%mult(i, 1, 1, 1) * &
254 (r(i, 1)**2 + r(i, 2)**2 + r(i, 3)**2)
263 rnorm = r_norm * norm_fac
264 gamma = rnorm * this%rel_tol
265 ksp_results%res_start = rnorm
266 ksp_results%res_final = rnorm
271 if (r_norm .le. 0.0_rp .or. rnorm .lt. this%abs_tol .or. &
272 rnorm .lt. gamma)
then
273 ksp_results%converged = .true.
274 nullify(this%p, this%p_hat, this%r, this%s_hat, this%t, this%v)
279 call this%monitor_start(
'Coupled BiCGStab')
280 do iter = 1, max_iter
282 r(:, 3), coef%mult, n)
289 if (iter .eq. 1)
then
298 beta = (rho_1 / rho_2) * (alpha / omega)
299 if (.not. ieee_is_finite(beta))
then
300 call neko_error(
'Coupled BiCGStab failure: non-finite beta')
305 p(i, 1) = r(i, 1) + &
306 beta * (p(i, 1) - omega * v(i, 1))
307 p(i, 2) = r(i, 2) + &
308 beta * (p(i, 2) - omega * v(i, 2))
309 p(i, 3) = r(i, 3) + &
310 beta * (p(i, 3) - omega * v(i, 3))
317 call this%M%solve(p_hat(:, 1), p(:, 1), n)
318 call this%M%solve(p_hat(:, 2), p(:, 2), n)
319 call this%M%solve(p_hat(:, 3), p(:, 3), n)
321 call ax%compute_vector(v(:, 1), v(:, 2), v(:, 3), p_hat(:, 1), &
322 p_hat(:, 2), p_hat(:, 3), coef, x%msh, x%Xh)
328 v(:, 1), v(:, 2), v(:, 3), coef%mult, n)
333 if (.not. ieee_is_finite(alpha))
then
334 call neko_error(
'Coupled BiCGStab failure: non-finite alpha')
343 r(i, 1) = r(i, 1) - alpha * v(i, 1)
344 r(i, 2) = r(i, 2) - alpha * v(i, 2)
345 r(i, 3) = r(i, 3) - alpha * v(i, 3)
346 norm_sum = norm_sum + coef%mult(i, 1, 1, 1) * &
347 (r(i, 1)**2 + r(i, 2)**2 + r(i, 3)**2)
355 rnorm = s_norm * norm_fac
356 if (rnorm .lt. this%abs_tol .or. rnorm .lt. gamma)
then
359 x%x(i, 1, 1, 1) = x%x(i, 1, 1, 1) + alpha * p_hat(i, 1)
360 y%x(i, 1, 1, 1) = y%x(i, 1, 1, 1) + alpha * p_hat(i, 2)
361 z%x(i, 1, 1, 1) = z%x(i, 1, 1, 1) + alpha * p_hat(i, 3)
364 call this%monitor_iter(iter, rnorm)
368 call this%M%solve(s_hat(:, 1), r(:, 1), n)
369 call this%M%solve(s_hat(:, 2), r(:, 2), n)
370 call this%M%solve(s_hat(:, 3), r(:, 3), n)
372 call ax%compute_vector(t(:, 1), t(:, 2), t(:, 3), s_hat(:, 1), &
373 s_hat(:, 2), s_hat(:, 3), coef, x%msh, x%Xh)
378 r(:, 3), t(:, 1), t(:, 2), t(:, 3), coef%mult, n)
380 if (t_norm .le. 0.0_rp)
then
382 'Coupled BiCGStab breakdown: zero omega denominator')
384 if (.not. ieee_is_finite(stt))
then
386 'Coupled BiCGStab failure: non-finite omega numerator')
389 if (.not. ieee_is_finite(omega))
then
390 call neko_error(
'Coupled BiCGStab failure: non-finite omega')
398 x%x(i, 1, 1, 1) = x%x(i, 1, 1, 1) + alpha * p_hat(i, 1) + &
400 y%x(i, 1, 1, 1) = y%x(i, 1, 1, 1) + alpha * p_hat(i, 2) + &
402 z%x(i, 1, 1, 1) = z%x(i, 1, 1, 1) + alpha * p_hat(i, 3) + &
404 r(i, 1) = r(i, 1) - omega * t(i, 1)
405 r(i, 2) = r(i, 2) - omega * t(i, 2)
406 r(i, 3) = r(i, 3) - omega * t(i, 3)
407 norm_sum = norm_sum + coef%mult(i, 1, 1, 1) * &
408 (r(i, 1)**2 + r(i, 2)**2 + r(i, 3)**2)
416 rnorm = r_norm * norm_fac
417 call this%monitor_iter(iter, rnorm)
418 if (rnorm .lt. this%abs_tol .or. rnorm .lt. gamma)
then
429 call this%monitor_stop()
430 ksp_results%res_final = rnorm
431 ksp_results%iter = iter
432 ksp_results%converged = this%is_converged(iter, rnorm)
434 nullify(this%p, this%p_hat, this%r, this%s_hat, this%t, this%v)