85 subroutine cg_init(this, n, max_iter, M, rel_tol, abs_tol, monitor)
86 class(
cg_t),
intent(inout),
target :: this
87 integer,
intent(in) :: max_iter
88 class(
pc_t),
optional,
intent(in),
target :: M
89 integer,
intent(in) :: n
90 real(kind=
rp),
optional,
intent(in) :: rel_tol
91 real(kind=
rp),
optional,
intent(in) :: abs_tol
92 logical,
optional,
intent(in) :: monitor
99 if (
present(rel_tol) .and.
present(abs_tol) .and.
present(monitor))
then
100 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
101 else if (
present(rel_tol) .and.
present(abs_tol))
then
102 call this%ksp_init(max_iter, rel_tol, abs_tol)
103 else if (
present(monitor) .and.
present(abs_tol))
then
104 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
105 else if (
present(rel_tol) .and.
present(monitor))
then
106 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
107 else if (
present(rel_tol))
then
108 call this%ksp_init(max_iter, rel_tol = rel_tol)
109 else if (
present(abs_tol))
then
110 call this%ksp_init(max_iter, abs_tol = abs_tol)
111 else if (
present(monitor))
then
112 call this%ksp_init(max_iter, monitor = monitor)
114 call this%ksp_init(max_iter)
136 function cg_solve(this, Ax, x, f, n, coef, bc_projector, gs_h, niter) &
138 class(
cg_t),
intent(inout) :: this
139 class(
ax_t),
intent(in) :: ax
140 type(
field_t),
intent(inout) :: x
141 integer,
intent(in) :: n
142 real(kind=
rp),
dimension(n),
intent(in) :: f
143 type(
coef_t),
intent(inout) :: coef
145 type(
gs_t),
intent(inout) :: gs_h
147 integer,
optional,
intent(in) :: niter
148 integer :: iter, max_iter, i, j, k, p_cur, p_prev, ierr
150 real(kind=
rp) :: beta, pap, norm_fac, tmp
151 integer :: temp_indices(5)
153 if (
present(niter))
then
156 max_iter = this%max_iter
158 norm_fac = 1.0_rp / sqrt(coef%volume)
168 associate(w => this%w, r => this%r, p => this%p%x, &
169 z => this%z, alpha => this%alpha)
175 x%x(i,1,1,1) = 0.0_rp
178 rtr = rtr + (r(i) * coef%mult(i,1,1,1) * r(i))
182 call mpi_allreduce(mpi_in_place, rtr, 1, &
185 rnorm = sqrt(rtr) * norm_fac
186 ksp_results%res_start = rnorm
187 ksp_results%res_final = rnorm
189 if (
abscmp(rnorm, 0.0_rp))
then
190 ksp_results%converged = .true.
191 nullify(this%w, this%r, this%p, this%z, this%alpha)
198 call this%monitor_start(
'CG')
199 do iter = 1, max_iter
200 call this%M%solve(z, r, n)
202 rtz1 =
glsc3(r, coef%mult, z, n)
205 if (iter .eq. 1) beta = 0.0_rp
208 p(i, p_cur) = z(i) + beta * p(i, p_prev)
212 call ax%compute(w, p(1, p_cur), coef, x%msh, x%Xh)
213 call gs_h%op(w, n, gs_op_add)
214 call bc_projector%apply(w, n)
216 pap =
glsc3(w, coef%mult, p(1, p_cur), n)
218 alpha(p_cur) = rtz1 / pap
220 rnorm = sqrt(rtr) * norm_fac
221 call this%monitor_iter(iter, rnorm)
224 (rnorm .lt. this%abs_tol) .or. iter .eq. max_iter)
then
235 x_plus(k) = x_plus(k) + alpha(j) * p(i+k,j)
240 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + x_plus(k)
246 tmp = tmp + alpha(j) * p(i+k,j)
248 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + tmp
255 if (rnorm .lt. this%abs_tol)
exit
262 nullify(this%w, this%r, this%p, this%z, this%alpha)
264 call this%monitor_stop()
265 ksp_results%res_final = rnorm
266 ksp_results%iter = iter
267 ksp_results%converged = this%is_converged(iter, rnorm)
292 n, coef, bc_projector, gs_h, niter)
result(ksp_results)
293 class(
cg_t),
intent(inout) :: this
294 class(ax_t),
intent(in) :: ax
295 type(field_t),
intent(inout) :: x
296 type(field_t),
intent(inout) :: y
297 type(field_t),
intent(inout) :: z
298 integer,
intent(in) :: n
299 real(kind=rp),
dimension(n),
intent(in) :: fx
300 real(kind=rp),
dimension(n),
intent(in) :: fy
301 real(kind=rp),
dimension(n),
intent(in) :: fz
302 type(coef_t),
intent(inout) :: coef
303 class(vector_bc_projector_t),
intent(inout) :: bc_projector
304 type(gs_t),
intent(inout) :: gs_h
305 type(ksp_monitor_t),
dimension(3) :: ksp_results
306 integer,
optional,
intent(in) :: niter
307 type(scalar_bc_projector_t),
pointer :: bc_x, bc_y, bc_z
309 call vector_bc_projector_components(bc_projector, bc_x, bc_y, bc_z)
310 ksp_results(1) = this%solve(ax, x, fx, n, coef, bc_x, gs_h, niter)
311 ksp_results(2) = this%solve(ax, y, fy, n, coef, bc_y, gs_h, niter)
312 ksp_results(3) = this%solve(ax, z, fz, n, coef, bc_z, gs_h, niter)
type(ksp_monitor_t) function, dimension(3) cg_solve_coupled(this, ax, x, y, z, fx, fy, fz, n, coef, bc_projector, gs_h, niter)
Solve three independent systems with the standard PCG method.