Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
pipecg_sx.f90
Go to the documentation of this file.
1! Copyright (c) 2021-2025, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
36 use precon, only : pc_t
37 use ax_product, only : ax_t
38 use num_types, only : rp
39 use field, only : field_t
40 use coefs, only : coef_t
41 use gather_scatter, only : gs_t, gs_op_add
45 use math, only : glsc3, abscmp
47 use mpi_f08, only : mpi_iallreduce, mpi_in_place, mpi_sum, mpi_wait, &
48 mpi_request, mpi_status
49 implicit none
50 private
51
53 type, public, extends(ksp_t) :: sx_pipecg_t
54 real(kind=rp), allocatable :: p(:)
55 real(kind=rp), allocatable :: q(:)
56 real(kind=rp), allocatable :: r(:)
57 real(kind=rp), allocatable :: s(:)
58 real(kind=rp), allocatable :: u(:)
59 real(kind=rp), allocatable :: w(:)
60 real(kind=rp), allocatable :: z(:)
61 real(kind=rp), allocatable :: mi(:)
62 real(kind=rp), allocatable :: ni(:)
63 contains
64 procedure, pass(this) :: init => sx_pipecg_init
65 procedure, pass(this) :: free => sx_pipecg_free
66 procedure, pass(this) :: solve => sx_pipecg_solve
67 procedure, pass(this) :: solve_coupled => sx_pipecg_solve_coupled
68 end type sx_pipecg_t
69
70contains
71
73 subroutine sx_pipecg_init(this, n, max_iter, M, rel_tol, abs_tol, monitor)
74 class(sx_pipecg_t), target, intent(inout) :: this
75 class(pc_t), optional, intent(in), target :: M
76 integer, intent(in) :: n
77 integer, intent(in) :: max_iter
78 real(kind=rp), optional, intent(in) :: rel_tol
79 real(kind=rp), optional, intent(in) :: abs_tol
80 logical, optional, intent(in) :: monitor
81
82 call this%free()
83
84 allocate(this%p(n))
85 allocate(this%q(n))
86 allocate(this%r(n))
87 allocate(this%s(n))
88 allocate(this%u(n))
89 allocate(this%w(n))
90 allocate(this%z(n))
91 allocate(this%mi(n))
92 allocate(this%ni(n))
93 if (present(m)) then
94 this%M => m
95 end if
96
97 if (present(rel_tol) .and. present(abs_tol) .and. present(monitor)) then
98 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
99 else if (present(rel_tol) .and. present(abs_tol)) then
100 call this%ksp_init(max_iter, rel_tol, abs_tol)
101 else if (present(monitor) .and. present(abs_tol)) then
102 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
103 else if (present(rel_tol) .and. present(monitor)) then
104 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
105 else if (present(rel_tol)) then
106 call this%ksp_init(max_iter, rel_tol = rel_tol)
107 else if (present(abs_tol)) then
108 call this%ksp_init(max_iter, abs_tol = abs_tol)
109 else if (present(monitor)) then
110 call this%ksp_init(max_iter, monitor = monitor)
111 else
112 call this%ksp_init(max_iter)
113 end if
114
115 end subroutine sx_pipecg_init
116
118 subroutine sx_pipecg_free(this)
119 class(sx_pipecg_t), intent(inout) :: this
120
121 call this%ksp_free()
122
123 if (allocated(this%p)) then
124 deallocate(this%p)
125 end if
126 if (allocated(this%q)) then
127 deallocate(this%q)
128 end if
129 if (allocated(this%r)) then
130 deallocate(this%r)
131 end if
132 if (allocated(this%s)) then
133 deallocate(this%s)
134 end if
135 if (allocated(this%u)) then
136 deallocate(this%u)
137 end if
138 if (allocated(this%w)) then
139 deallocate(this%w)
140 end if
141 if (allocated(this%z)) then
142 deallocate(this%z)
143 end if
144 if (allocated(this%mi)) then
145 deallocate(this%mi)
146 end if
147 if (allocated(this%ni)) then
148 deallocate(this%ni)
149 end if
150
151 nullify(this%M)
152
153
154 end subroutine sx_pipecg_free
155
157 function sx_pipecg_solve(this, Ax, x, f, n, coef, bc_projector, gs_h, niter) &
158 result(ksp_results)
159 class(sx_pipecg_t), intent(inout) :: this
160 class(ax_t), intent(in) :: ax
161 type(field_t), intent(inout) :: x
162 integer, intent(in) :: n
163 real(kind=rp), dimension(n), intent(in) :: f
164 type(coef_t), intent(inout) :: coef
165 class(scalar_bc_projector_t), intent(inout) :: bc_projector
166 type(gs_t), intent(inout) :: gs_h
167 type(ksp_monitor_t) :: ksp_results
168 integer, optional, intent(in) :: niter
169 integer :: iter, max_iter, i, ierr
170 real(kind=rp) :: rnorm, rtr, reduction(3), norm_fac
171 real(kind=rp) :: alpha, beta, gamma1, gamma2, delta
172 real(kind=rp) :: tmp1, tmp2, tmp3
173 type(mpi_request) :: request
174 type(mpi_status) :: status
175
176 if (present(niter)) then
177 max_iter = niter
178 else
179 max_iter = this%max_iter
180 end if
181 norm_fac = 1.0_rp / sqrt(coef%volume)
182
183 do i = 1, n
184 x%x(i,1,1,1) = 0.0_rp
185 this%z(i) = 0.0_rp
186 this%q(i) = 0.0_rp
187 this%p(i) = 0.0_rp
188 this%s(i) = 0.0_rp
189 this%r(i) = f(i)
190 end do
191
192 call this%M%solve(this%u, this%r, n)
193 call ax%compute(this%w, this%u, coef, x%msh, x%Xh)
194 call gs_h%op(this%w, n, gs_op_add)
195 call bc_projector%apply(this%w, n)
196
197 rtr = glsc3(this%r, coef%mult, this%r, n)
198 rnorm = sqrt(rtr)*norm_fac
199 ksp_results%res_start = rnorm
200 ksp_results%res_final = rnorm
201 ksp_results%iter = 0
202 if (abscmp(rnorm, 0.0_rp)) then
203 ksp_results%converged = .true.
204 return
205 end if
206
207 gamma1 = 0.0_rp
208
209 call this%monitor_start('PipeCG')
210 do iter = 1, max_iter
211
212 tmp1 = 0.0_rp
213 tmp2 = 0.0_rp
214 tmp3 = 0.0_rp
215 do i = 1, n
216 tmp1 = tmp1 + this%r(i) * coef%mult(i,1,1,1) * this%u(i)
217 tmp2 = tmp2 + this%w(i) * coef%mult(i,1,1,1) * this%u(i)
218 tmp3 = tmp3 + this%r(i) * coef%mult(i,1,1,1) * this%r(i)
219 end do
220 reduction(1) = tmp1
221 reduction(2) = tmp2
222 reduction(3) = tmp3
223
224 call mpi_iallreduce(mpi_in_place, reduction, 3, &
225 mpi_real_precision, mpi_sum, neko_comm, request, ierr)
226
227 call this%M%solve(this%mi, this%w, n)
228 call ax%compute(this%ni, this%mi, coef, x%msh, x%Xh)
229 call gs_h%op(this%ni, n, gs_op_add)
230 call bc_projector%apply(this%ni, n)
231
232 call mpi_wait(request, status, ierr)
233 gamma2 = gamma1
234 gamma1 = reduction(1)
235 delta = reduction(2)
236 rtr = reduction(3)
237
238 rnorm = sqrt(rtr)*norm_fac
239 call this%monitor_iter(iter, rnorm)
240 if (rnorm .lt. this%abs_tol) then
241 exit
242 end if
243
244 if (iter .gt. 1) then
245 beta = gamma1 / gamma2
246 alpha = gamma1 / (delta - (beta * gamma1/alpha))
247 else
248 beta = 0.0_rp
249 alpha = gamma1/delta
250 end if
251
252 do i = 1, n
253 this%z(i) = beta * this%z(i) + this%ni(i)
254 this%q(i) = beta * this%q(i) + this%mi(i)
255 this%s(i) = beta * this%s(i) + this%w(i)
256 this%p(i) = beta * this%p(i) + this%u(i)
257 end do
258
259 do i = 1, n
260 x%x(i,1,1,1) = x%x(i,1,1,1) + alpha * this%p(i)
261 this%r(i) = this%r(i) - alpha * this%s(i)
262 this%u(i) = this%u(i) - alpha * this%q(i)
263 this%w(i) = this%w(i) - alpha * this%z(i)
264 end do
265
266 end do
267 call this%monitor_stop()
268 ksp_results%res_final = rnorm
269 ksp_results%iter = iter
270
271 end function sx_pipecg_solve
272
274 function sx_pipecg_solve_coupled(this, Ax, x, y, z, fx, fy, fz, &
275 n, coef, bc_projector, gs_h, niter) result(ksp_results)
276 class(sx_pipecg_t), intent(inout) :: this
277 class(ax_t), intent(in) :: ax
278 type(field_t), intent(inout) :: x
279 type(field_t), intent(inout) :: y
280 type(field_t), intent(inout) :: z
281 integer, intent(in) :: n
282 real(kind=rp), dimension(n), intent(in) :: fx
283 real(kind=rp), dimension(n), intent(in) :: fy
284 real(kind=rp), dimension(n), intent(in) :: fz
285 type(coef_t), intent(inout) :: coef
286 class(vector_bc_projector_t), intent(inout) :: bc_projector
287 type(gs_t), intent(inout) :: gs_h
288 type(ksp_monitor_t), dimension(3) :: ksp_results
289 integer, optional, intent(in) :: niter
290 type(scalar_bc_projector_t), pointer :: bc_x, bc_y, bc_z
291
292 call vector_bc_projector_components(bc_projector, bc_x, bc_y, bc_z)
293 ksp_results(1) = this%solve(ax, x, fx, n, coef, bc_x, gs_h, niter)
294 ksp_results(2) = this%solve(ax, y, fy, n, coef, bc_y, gs_h, niter)
295 ksp_results(3) = this%solve(ax, z, fz, n, coef, bc_z, gs_h, niter)
296
297 end function sx_pipecg_solve_coupled
298
299end module pipecg_sx
__device__ T solve(const T u, const T y, const T guess, const T nu, const T kappa, const T B)
Defines a Matrix-vector product.
Definition ax.f90:34
Coefficients.
Definition coef.f90:34
Definition comm.F90:1
type(mpi_datatype), public mpi_real_precision
MPI type for working precision of REAL types.
Definition comm.F90:54
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:46
Defines a field.
Definition field.f90:34
Gather-scatter.
Implements the base abstract type for Krylov solvers plus helper types.
Definition krylov.f90:34
integer, parameter, public ksp_max_iter
Maximum number of iters.
Definition krylov.f90:52
Definition math.f90:60
real(kind=rp) function, public glsc3(a, b, c, n)
Weighted inner product .
Definition math.f90:1290
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Defines a pipelined Conjugate Gradient methods SX-Aurora backend.
Definition pipecg_sx.f90:34
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.
Definition pipecg_sx.f90:74
type(ksp_monitor_t) function, dimension(3) sx_pipecg_solve_coupled(this, ax, x, y, z, fx, fy, fz, n, coef, bc_projector, gs_h, niter)
Pipelined PCG coupled solve.
type(ksp_monitor_t) function sx_pipecg_solve(this, ax, x, f, n, coef, bc_projector, gs_h, niter)
Pipelined PCG solve.
Krylov preconditioner.
Definition precon.f90:34
Implements scalar_projector_t.
Implements boundary condition projectors for vector fields. Two types concrete types are provided: se...
subroutine, public vector_bc_projector_components(this, x, y, z)
Access the component scalar projectors from a segregated vector projector.
Base type for a matrix-vector product providing .
Definition ax.f90:43
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:93
Gather-scatter kernel.
Type for storing initial and final residuals in a Krylov solver.
Definition krylov.f90:57
Base abstract type for a canonical Krylov method, solving .
Definition krylov.f90:74
Pipelined preconditioned conjugate gradient method for SX-Aurora.
Definition pipecg_sx.f90:53
Defines a canonical Krylov preconditioner.
Definition precon.f90:40
Projector for scalar boundary conditions.
Abstract type for resolving vector boundary conditions.