50 real(kind=
rp),
allocatable :: p(:)
51 real(kind=
rp),
allocatable :: q(:)
52 real(kind=
rp),
allocatable :: r(:)
53 real(kind=
rp),
allocatable :: s(:)
54 real(kind=
rp),
allocatable :: u(:)
55 real(kind=
rp),
allocatable :: w(:)
56 real(kind=
rp),
allocatable :: z(:)
57 real(kind=
rp),
allocatable :: mi(:)
58 real(kind=
rp),
allocatable :: ni(:)
71 class(
pc_t),
optional,
intent(in),
target :: M
72 integer,
intent(in) :: n
73 integer,
intent(in) :: max_iter
74 real(kind=
rp),
optional,
intent(in) :: rel_tol
75 real(kind=
rp),
optional,
intent(in) :: abs_tol
76 logical,
optional,
intent(in) :: monitor
93 if (
present(rel_tol) .and.
present(abs_tol) .and.
present(monitor))
then
94 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
95 else if (
present(rel_tol) .and.
present(abs_tol))
then
96 call this%ksp_init(max_iter, rel_tol, abs_tol)
97 else if (
present(monitor) .and.
present(abs_tol))
then
98 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
99 else if (
present(rel_tol) .and.
present(monitor))
then
100 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
101 else if (
present(rel_tol))
then
102 call this%ksp_init(max_iter, rel_tol = rel_tol)
103 else if (
present(abs_tol))
then
104 call this%ksp_init(max_iter, abs_tol = abs_tol)
105 else if (
present(monitor))
then
106 call this%ksp_init(max_iter, monitor = monitor)
108 call this%ksp_init(max_iter)
119 if (
allocated(this%p))
then
122 if (
allocated(this%q))
then
125 if (
allocated(this%r))
then
128 if (
allocated(this%s))
then
131 if (
allocated(this%u))
then
134 if (
allocated(this%w))
then
137 if (
allocated(this%z))
then
140 if (
allocated(this%mi))
then
143 if (
allocated(this%ni))
then
153 function sx_pipecg_solve(this, Ax, x, f, n, coef, blst, gs_h, niter)
result(ksp_results)
155 class(
ax_t),
intent(in) :: ax
156 type(
field_t),
intent(inout) :: x
157 integer,
intent(in) :: n
158 real(kind=
rp),
dimension(n),
intent(in) :: f
159 type(
coef_t),
intent(inout) :: coef
161 type(
gs_t),
intent(inout) :: gs_h
163 integer,
optional,
intent(in) :: niter
164 integer :: iter, max_iter, i, ierr
165 real(kind=
rp) :: rnorm, rtr, reduction(3), norm_fac
166 real(kind=
rp) :: alpha, beta, gamma1, gamma2, delta
167 real(kind=
rp) :: tmp1, tmp2, tmp3
168 type(mpi_request) :: request
169 type(mpi_status) :: status
171 if (
present(niter))
then
174 max_iter = this%max_iter
176 norm_fac = 1.0_rp / sqrt(coef%volume)
179 x%x(i,1,1,1) = 0.0_rp
187 call this%M%solve(this%u, this%r, n)
188 call ax%compute(this%w, this%u, coef, x%msh, x%Xh)
189 call gs_h%op(this%w, n, gs_op_add)
192 rtr =
glsc3(this%r, coef%mult, this%r, n)
193 rnorm = sqrt(rtr)*norm_fac
194 ksp_results%res_start = rnorm
195 ksp_results%res_final = rnorm
197 if(
abscmp(rnorm, 0.0_rp))
return
201 call this%monitor_start(
'PipeCG')
202 do iter = 1, max_iter
208 tmp1 = tmp1 + this%r(i) * coef%mult(i,1,1,1) * this%u(i)
209 tmp2 = tmp2 + this%w(i) * coef%mult(i,1,1,1) * this%u(i)
210 tmp3 = tmp3 + this%r(i) * coef%mult(i,1,1,1) * this%r(i)
216 call mpi_iallreduce(mpi_in_place, reduction, 3, &
219 call this%M%solve(this%mi, this%w, n)
220 call ax%compute(this%ni, this%mi, coef, x%msh, x%Xh)
221 call gs_h%op(this%ni, n, gs_op_add)
224 call mpi_wait(request, status, ierr)
226 gamma1 = reduction(1)
230 rnorm = sqrt(rtr)*norm_fac
231 call this%monitor_iter(iter, rnorm)
232 if (rnorm .lt. this%abs_tol)
then
236 if (iter .gt. 1)
then
237 beta = gamma1 / gamma2
238 alpha = gamma1 / (delta - (beta * gamma1/alpha))
245 this%z(i) = beta * this%z(i) + this%ni(i)
246 this%q(i) = beta * this%q(i) + this%mi(i)
247 this%s(i) = beta * this%s(i) + this%w(i)
248 this%p(i) = beta * this%p(i) + this%u(i)
252 x%x(i,1,1,1) = x%x(i,1,1,1) + alpha * this%p(i)
253 this%r(i) = this%r(i) - alpha * this%s(i)
254 this%u(i) = this%u(i) - alpha * this%q(i)
255 this%w(i) = this%w(i) - alpha * this%z(i)
259 call this%monitor_stop()
260 ksp_results%res_final = rnorm
261 ksp_results%iter = iter
267 n, coef, blstx, blsty, blstz, gs_h, niter)
result(ksp_results)
269 class(
ax_t),
intent(in) :: ax
270 type(
field_t),
intent(inout) :: x
271 type(
field_t),
intent(inout) :: y
272 type(
field_t),
intent(inout) :: z
273 integer,
intent(in) :: n
274 real(kind=
rp),
dimension(n),
intent(in) :: fx
275 real(kind=
rp),
dimension(n),
intent(in) :: fy
276 real(kind=
rp),
dimension(n),
intent(in) :: fz
277 type(
coef_t),
intent(inout) :: coef
281 type(
gs_t),
intent(inout) :: gs_h
283 integer,
optional,
intent(in) :: niter
285 ksp_results(1) = this%solve(ax, x, fx, n, coef, blstx, gs_h, niter)
286 ksp_results(2) = this%solve(ax, y, fy, n, coef, blsty, gs_h, niter)
287 ksp_results(3) = this%solve(ax, z, fz, n, coef, blstz, gs_h, niter)
Defines a Matrix-vector product.
Defines a boundary condition.
type(mpi_comm) neko_comm
MPI communicator.
type(mpi_datatype) mpi_real_precision
MPI type for working precision of REAL types.
Implements the base abstract type for Krylov solvers plus helper types.
integer, parameter, public ksp_max_iter
Maximum number of iters.
real(kind=rp) function, public glsc3(a, b, c, n)
Weighted inner product .
integer, parameter, public rp
Global precision used in computations.
Defines a pipelined Conjugate Gradient methods SX-Aurora backend.
subroutine sx_pipecg_free(this)
Deallocate a pipelined PCG solver.
subroutine sx_pipecg_init(this, n, max_iter, M, rel_tol, abs_tol, monitor)
Initialise a pipelined PCG solver.
type(ksp_monitor_t) function, dimension(3) sx_pipecg_solve_coupled(this, Ax, x, y, z, fx, fy, fz, n, coef, blstx, blsty, blstz, gs_h, niter)
Pipelined PCG coupled solve.
type(ksp_monitor_t) function sx_pipecg_solve(this, Ax, x, f, n, coef, blst, gs_h, niter)
Pipelined PCG solve.
Base type for a matrix-vector product providing .
A list of boundary conditions.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Type for storing initial and final residuals in a Krylov solver.
Base abstract type for a canonical Krylov method, solving .
Pipelined preconditioned conjugate gradient method for SX-Aurora.
Defines a canonical Krylov preconditioner.