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) &
142 class(
cg_t),
intent(inout) :: this
143 class(
ax_t),
intent(in) :: ax
144 type(
field_t),
intent(inout) :: x
145 integer,
intent(in) :: n
146 real(kind=
rp),
dimension(n),
intent(in) :: f
147 type(
coef_t),
intent(inout) :: coef
149 type(
gs_t),
intent(inout) :: gs_h
151 integer,
optional,
intent(in) :: niter
152 integer :: iter, max_iter, i, j, k, p_cur, p_prev, ierr
154 real(kind=
rp) :: beta, pap, norm_fac, tmp
156 if (
present(niter))
then
159 max_iter = this%max_iter
161 norm_fac = 1.0_rp / sqrt(coef%volume)
163 associate(w => this%w, r => this%r, p => this%p, &
164 z => this%z, alpha => this%alpha)
170 x%x(i,1,1,1) = 0.0_rp
173 rtr = rtr + (r(i) * coef%mult(i,1,1,1) * r(i))
177 call mpi_allreduce(mpi_in_place, rtr, 1, &
180 rnorm = sqrt(rtr) * norm_fac
181 ksp_results%res_start = rnorm
182 ksp_results%res_final = rnorm
184 if(
abscmp(rnorm, 0.0_rp))
then
185 ksp_results%converged = .true.
191 call this%monitor_start(
'CG')
192 do iter = 1, max_iter
193 call this%M%solve(z, r, n)
195 rtz1 =
glsc3(r, coef%mult, z, n)
198 if (iter .eq. 1) beta = 0.0_rp
201 p(i,p_cur) = z(i) + beta * p(i,p_prev)
205 call ax%compute(w, p(1,p_cur), coef, x%msh, x%Xh)
206 call gs_h%op(w, n, gs_op_add)
207 call blst%apply(w, n)
209 pap =
glsc3(w, coef%mult, p(1,p_cur), n)
211 alpha(p_cur) = rtz1 / pap
213 rnorm = sqrt(rtr) * norm_fac
214 call this%monitor_iter(iter, rnorm)
217 (rnorm .lt. this%abs_tol) .or. iter .eq. max_iter)
then
228 x_plus(k) = x_plus(k) + alpha(j) * p(i+k,j)
233 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + x_plus(k)
239 tmp = tmp + alpha(j) * p(i+k,j)
241 x%x(i+k,1,1,1) = x%x(i+k,1,1,1) + tmp
248 if (rnorm .lt. this%abs_tol)
exit
255 call this%monitor_stop()
256 ksp_results%res_final = rnorm
257 ksp_results%iter = iter
258 ksp_results%converged = this%is_converged(iter, rnorm)
262 integer,
intent(in) :: n
263 real(kind=rp),
intent(inout) :: r(n), rtr
265 real(kind=rp),
intent(in) ::mult(n), w(n), alpha
271 r(i) = r(i) - alpha*w(i)
272 tmp = tmp + r(i) * r(i) * mult(i)
275 call mpi_allreduce(mpi_in_place, tmp, 1, &
276 mpi_extra_precision, mpi_sum, neko_comm, ierr)
283 n, coef, blstx, blsty, blstz, gs_h, niter)
result(ksp_results)
284 class(
cg_t),
intent(inout) :: this
285 class(ax_t),
intent(in) :: ax
286 type(field_t),
intent(inout) :: x
287 type(field_t),
intent(inout) :: y
288 type(field_t),
intent(inout) :: z
289 integer,
intent(in) :: n
290 real(kind=rp),
dimension(n),
intent(in) :: fx
291 real(kind=rp),
dimension(n),
intent(in) :: fy
292 real(kind=rp),
dimension(n),
intent(in) :: fz
293 type(coef_t),
intent(inout) :: coef
294 type(bc_list_t),
intent(inout) :: blstx
295 type(bc_list_t),
intent(inout) :: blsty
296 type(bc_list_t),
intent(inout) :: blstz
297 type(gs_t),
intent(inout) :: gs_h
298 type(ksp_monitor_t),
dimension(3) :: ksp_results
299 integer,
optional,
intent(in) :: niter
301 ksp_results(1) = this%solve(ax, x, fx, n, coef, blstx, gs_h, niter)
302 ksp_results(2) = this%solve(ax, y, fy, n, coef, blsty, gs_h, niter)
303 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.