69 subroutine cg_init(this, n, max_iter, M, rel_tol, abs_tol, monitor)
70 class(
cg_t),
intent(inout),
target :: this
71 integer,
intent(in) :: max_iter
72 class(
pc_t),
optional,
intent(in),
target :: M
73 integer,
intent(in) :: n
74 real(kind=
rp),
optional,
intent(in) :: rel_tol
75 real(kind=
rp),
optional,
intent(in) :: abs_tol
76 logical,
optional,
intent(in) :: monitor
89 if (
present(rel_tol) .and.
present(abs_tol) .and.
present(monitor))
then
90 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
91 else if (
present(rel_tol) .and.
present(abs_tol))
then
92 call this%ksp_init(max_iter, rel_tol, abs_tol)
93 else if (
present(monitor) .and.
present(abs_tol))
then
94 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
95 else if (
present(rel_tol) .and.
present(monitor))
then
96 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
97 else if (
present(rel_tol))
then
98 call this%ksp_init(max_iter, rel_tol = rel_tol)
99 else if (
present(abs_tol))
then
100 call this%ksp_init(max_iter, abs_tol = abs_tol)
101 else if (
present(monitor))
then
102 call this%ksp_init(max_iter, monitor = monitor)
104 call this%ksp_init(max_iter)
140 function cg_solve(this, Ax, x, f, n, coef, blst, gs_h, niter)
result(ksp_results)
141 class(
cg_t),
intent(inout) :: this
142 class(
ax_t),
intent(in) :: ax
143 type(
field_t),
intent(inout) :: x
144 integer,
intent(in) :: n
145 real(kind=
rp),
dimension(n),
intent(in) :: f
146 type(
coef_t),
intent(inout) :: coef
148 type(
gs_t),
intent(inout) :: gs_h
150 integer,
optional,
intent(in) :: niter
151 integer :: iter, max_iter, i, j, k, p_cur, p_prev, ierr
153 real(kind=
rp) :: beta, pap, norm_fac, tmp
155 if (
present(niter))
then
158 max_iter = this%max_iter
160 norm_fac = 1.0_rp / sqrt(coef%volume)
162 associate(w => this%w, r => this%r, p => this%p, &
163 z => this%z, alpha => this%alpha)
169 x%x(i,1,1,1) = 0.0_rp
172 rtr = rtr + (r(i) * coef%mult(i,1,1,1) * r(i))
176 call mpi_allreduce(mpi_in_place, rtr, 1, &
179 rnorm = sqrt(rtr) * norm_fac
180 ksp_results%res_start = rnorm
181 ksp_results%res_final = rnorm
183 if(
abscmp(rnorm, 0.0_rp))
then
184 ksp_results%converged = .true.
190 call this%monitor_start(
'CG')
191 do iter = 1, max_iter
192 call this%M%solve(z, r, n)
194 rtz1 =
glsc3(r, coef%mult, z, n)
197 if (iter .eq. 1) beta = 0.0_rp
200 p(i,p_cur) = z(i) + beta * p(i,p_prev)
204 call ax%compute(w, p(1,p_cur), coef, x%msh, x%Xh)
205 call gs_h%op(w, n, gs_op_add)
206 call blst%apply(w, n)
208 pap =
glsc3(w, coef%mult, p(1,p_cur), n)
210 alpha(p_cur) = rtz1 / pap
212 rnorm = sqrt(rtr) * norm_fac
213 call this%monitor_iter(iter, rnorm)
216 (rnorm .lt. this%abs_tol) .or. iter .eq. max_iter)
then
227 x_plus(k) = x_plus(k) + alpha(j) * p(i+k,j)
232 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + x_plus(k)
238 tmp = tmp + alpha(j) * p(i+k,j)
240 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + tmp
247 if (rnorm .lt. this%abs_tol)
exit
254 call this%monitor_stop()
255 ksp_results%res_final = rnorm
256 ksp_results%iter = iter
257 ksp_results%converged = this%is_converged(iter, rnorm)
261 integer,
intent(in) :: n
262 real(kind=rp),
intent(inout) :: r(n), rtr
264 real(kind=rp),
intent(in) ::mult(n), w(n), alpha
270 r(i) = r(i) - alpha*w(i)
271 tmp = tmp + r(i) * r(i) * mult(i)
274 call mpi_allreduce(mpi_in_place, tmp, 1, &
275 mpi_extra_precision, mpi_sum, neko_comm, ierr)
282 n, coef, blstx, blsty, blstz, gs_h, niter)
result(ksp_results)
283 class(
cg_t),
intent(inout) :: this
284 class(ax_t),
intent(in) :: ax
285 type(field_t),
intent(inout) :: x
286 type(field_t),
intent(inout) :: y
287 type(field_t),
intent(inout) :: z
288 integer,
intent(in) :: n
289 real(kind=rp),
dimension(n),
intent(in) :: fx
290 real(kind=rp),
dimension(n),
intent(in) :: fy
291 real(kind=rp),
dimension(n),
intent(in) :: fz
292 type(coef_t),
intent(inout) :: coef
293 type(bc_list_t),
intent(inout) :: blstx
294 type(bc_list_t),
intent(inout) :: blsty
295 type(bc_list_t),
intent(inout) :: blstz
296 type(gs_t),
intent(inout) :: gs_h
297 type(ksp_monitor_t),
dimension(3) :: ksp_results
298 integer,
optional,
intent(in) :: niter
300 ksp_results(1) = this%solve(ax, x, fx, n, coef, blstx, gs_h, niter)
301 ksp_results(2) = this%solve(ax, y, fy, n, coef, blsty, gs_h, niter)
302 ksp_results(3) = this%solve(ax, z, fz, n, coef, blstz, gs_h, niter)
type(ksp_monitor_t) function, dimension(3) cg_solve_coupled(this, ax, x, y, z, fx, fy, fz, n, coef, blstx, blsty, blstz, gs_h, niter)
Standard PCG coupled solve.
subroutine cg_init(this, n, max_iter, m, rel_tol, abs_tol, monitor)
Initialise a standard PCG solver.
type(ksp_monitor_t) function cg_solve(this, ax, x, f, n, coef, blst, gs_h, niter)
Standard PCG solve.