76 subroutine cg_cpld_init(this, n, max_iter, M, rel_tol, abs_tol, monitor)
77 class(
cg_cpld_t),
target,
intent(inout) :: this
78 integer,
intent(in) :: max_iter
79 class(
pc_t),
optional,
intent(in),
target :: M
80 integer,
intent(in) :: n
81 real(kind=
rp),
optional,
intent(in) :: rel_tol
82 real(kind=
rp),
optional,
intent(in) :: abs_tol
83 logical,
optional,
intent(in) :: monitor
105 if (
present(rel_tol) .and.
present(abs_tol) .and.
present(monitor))
then
106 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
107 else if (
present(rel_tol) .and.
present(abs_tol))
then
108 call this%ksp_init(max_iter, rel_tol, abs_tol)
109 else if (
present(monitor) .and.
present(abs_tol))
then
110 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
111 else if (
present(rel_tol) .and.
present(monitor))
then
112 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
113 else if (
present(rel_tol))
then
114 call this%ksp_init(max_iter, rel_tol = rel_tol)
115 else if (
present(abs_tol))
then
116 call this%ksp_init(max_iter, abs_tol = abs_tol)
117 else if (
present(monitor))
then
118 call this%ksp_init(max_iter, monitor = monitor)
120 call this%ksp_init(max_iter)
209 n, coef, blstx, blsty, blstz, gs_h, niter)
result(ksp_results)
211 class(
ax_t),
intent(in) :: ax
212 type(
field_t),
intent(inout) :: x
213 type(
field_t),
intent(inout) :: y
214 type(
field_t),
intent(inout) :: z
215 integer,
intent(in) :: n
216 real(kind=
rp),
dimension(n),
intent(in) :: fx
217 real(kind=
rp),
dimension(n),
intent(in) :: fy
218 real(kind=
rp),
dimension(n),
intent(in) :: fz
219 type(
coef_t),
intent(inout) :: coef
223 type(
gs_t),
intent(inout) :: gs_h
225 integer,
optional,
intent(in) :: niter
226 integer :: i, iter, max_iter, ierr
227 real(kind=
rp) :: rnorm, rtr, rtr0, rtz2, rtz1
228 real(kind=
rp) :: beta, pap, alpha, norm_fac
229 real(kind=
xp) :: tmp_xp, r1_xp, r2_xp, r3_xp, mult_xp
231 if (
present(niter))
then
234 max_iter = this%max_iter
236 norm_fac = 1.0_rp / sqrt(coef%volume)
238 associate(p1 => this%p1, p2 => this%p2, p3 => this%p3, z1 => this%z1, &
239 z2 => this%z2, z3 => this%z3, r1 => this%r1, r2 => this%r2, &
240 r3 => this%r3, tmp => this%tmp, w1 => this%w1, w2 => this%w2, &
244 do concurrent(i = 1:n)
245 x%x(i,1,1,1) = 0.0_rp
246 y%x(i,1,1,1) = 0.0_rp
247 z%x(i,1,1,1) = 0.0_rp
257 tmp(i) = r1(i)**2 + r2(i)**2 + r3(i)**2
260 rtr =
glsc2(tmp, coef%mult, n)
261 rnorm = sqrt(rtr)*norm_fac
262 ksp_results%res_start = rnorm
263 ksp_results%res_final = rnorm
265 if (
abscmp(rnorm, 0.0_rp))
then
266 ksp_results%converged = .true.
270 call this%monitor_start(
'cpldCG')
271 do iter = 1, max_iter
272 call this%M%solve(z1, this%r1, n)
273 call this%M%solve(z2, this%r2, n)
274 call this%M%solve(z3, this%r3, n)
277 do concurrent(i = 1:n)
278 this%tmp(i) = z1(i) * r1(i) &
283 rtz1 =
glsc2(tmp, coef%mult, n)
286 if (iter .eq. 1) beta = 0.0_rp
287 do concurrent(i = 1:n)
288 p1(i) = p1(i) * beta + z1(i)
289 p2(i) = p2(i) * beta + z2(i)
290 p3(i) = p3(i) * beta + z3(i)
293 call ax%compute_vector(w1, w2, w3, p1, p2, p3, coef, x%msh, x%Xh)
296 call gs_h%op(w1, n, gs_op_add)
297 call gs_h%op(w2, n, gs_op_add)
298 call gs_h%op(w3, n, gs_op_add)
301 call blstx%apply_scalar(w1, n)
302 call blsty%apply_scalar(w2, n)
303 call blstz%apply_scalar(w3, n)
305 do concurrent(i = 1:n)
306 tmp(i) = w1(i) * p1(i) &
311 pap =
glsc2(tmp, coef%mult, n)
314 do concurrent(i = 1:n)
315 x%x(i,1,1,1) = x%x(i,1,1,1) + alpha * p1(i)
316 y%x(i,1,1,1) = y%x(i,1,1,1) + alpha * p2(i)
317 z%x(i,1,1,1) = z%x(i,1,1,1) + alpha * p3(i)
324 r1(i) = r1(i) - alpha * w1(i)
325 r2(i) = r2(i) - alpha * w2(i)
326 r3(i) = r3(i) - alpha * w3(i)
327 r1_xp =
real(r1(i), kind=
xp)
328 r2_xp =
real(r2(i), kind=
xp)
329 r3_xp =
real(r3(i), kind=
xp)
330 mult_xp =
real(coef%mult(i,1,1,1), kind=
xp)
332 (r1_xp * r1_xp + r2_xp * r2_xp + r3_xp * r3_xp) * mult_xp
340 if (iter .eq. 1) rtr0 = rtr
341 rnorm = sqrt(rtr) * norm_fac
342 call this%monitor_iter(iter, rnorm)
343 if (rnorm .lt. this%abs_tol)
then
348 call this%monitor_stop()
349 ksp_results%res_final = rnorm
350 ksp_results%iter = iter
351 ksp_results%converged = this%is_converged(iter, rnorm)