Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
cg_sx.f90
Go to the documentation of this file.
1! Copyright (c) 2021, 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!
34module cg_sx
35 use num_types, only : rp
37 use precon, only : pc_t
38 use ax_product, only : ax_t
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, add2s1, abscmp
46 implicit none
47 private
48
50 type, public, extends(ksp_t) :: sx_cg_t
51 real(kind=rp), allocatable :: w(:)
52 real(kind=rp), allocatable :: r(:)
53 real(kind=rp), allocatable :: p(:)
54 real(kind=rp), allocatable :: z(:)
55 contains
56 procedure, pass(this) :: init => sx_cg_init
57 procedure, pass(this) :: free => sx_cg_free
58 procedure, pass(this) :: solve => sx_cg_solve
59 procedure, pass(this) :: solve_coupled => sx_cg_solve_coupled
60 end type sx_cg_t
61
62contains
63
65 subroutine sx_cg_init(this, n, max_iter, M, rel_tol, abs_tol, monitor)
66 class(sx_cg_t), target, intent(inout) :: this
67 class(pc_t), optional, intent(in), target :: M
68 integer, intent(in) :: n
69 integer, intent(in) :: max_iter
70 real(kind=rp), optional, intent(in) :: rel_tol
71 real(kind=rp), optional, intent(in) :: abs_tol
72 logical, optional, intent(in) :: monitor
73
74 call this%free()
75
76 allocate(this%w(n))
77 allocate(this%r(n))
78 allocate(this%p(n))
79 allocate(this%z(n))
80
81 if (present(m)) then
82 this%M => m
83 end if
84
85 if (present(rel_tol) .and. present(abs_tol) .and. present(monitor)) then
86 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
87 else if (present(rel_tol) .and. present(abs_tol)) then
88 call this%ksp_init(max_iter, rel_tol, abs_tol)
89 else if (present(monitor) .and. present(abs_tol)) then
90 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
91 else if (present(rel_tol) .and. present(monitor)) then
92 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
93 else if (present(rel_tol)) then
94 call this%ksp_init(max_iter, rel_tol = rel_tol)
95 else if (present(abs_tol)) then
96 call this%ksp_init(max_iter, abs_tol = abs_tol)
97 else if (present(monitor)) then
98 call this%ksp_init(max_iter, monitor = monitor)
99 else
100 call this%ksp_init(max_iter)
101 end if
102
103 end subroutine sx_cg_init
104
106 subroutine sx_cg_free(this)
107 class(sx_cg_t), intent(inout) :: this
108
109 call this%ksp_free()
110
111 if (allocated(this%w)) then
112 deallocate(this%w)
113 end if
114
115 if (allocated(this%r)) then
116 deallocate(this%r)
117 end if
118
119 if (allocated(this%p)) then
120 deallocate(this%p)
121 end if
122
123 if (allocated(this%z)) then
124 deallocate(this%z)
125 end if
126
127 nullify(this%M)
128
129 end subroutine sx_cg_free
130
132 function sx_cg_solve(this, Ax, x, f, n, coef, bc_projector, gs_h, niter) &
133 result(ksp_results)
134 class(sx_cg_t), intent(inout) :: this
135 class(ax_t), intent(in) :: ax
136 type(field_t), intent(inout) :: x
137 integer, intent(in) :: n
138 real(kind=rp), dimension(n), intent(in) :: f
139 type(coef_t), intent(inout) :: coef
140 class(scalar_bc_projector_t), intent(inout) :: bc_projector
141 type(gs_t), intent(inout) :: gs_h
142 type(ksp_monitor_t) :: ksp_results
143 integer, optional, intent(in) :: niter
144 real(kind=rp), parameter :: one = 1.0
145 real(kind=rp), parameter :: zero = 0.0
146 integer :: i, iter, max_iter
147 real(kind=rp) :: rnorm, rtr, rtr0, rtz2, rtz1
148 real(kind=rp) :: beta, pap, alpha, alphm, norm_fac
149
150 if (present(niter)) then
151 max_iter = niter
152 else
153 max_iter = this%max_iter
154 end if
155 norm_fac = one / sqrt(coef%volume)
156
157 rtz1 = one
158 do i = 1, n
159 x%x(i,1,1,1) = 0.0_rp
160 this%p(i) = 0.0_rp
161 this%r(i) = f(i)
162 end do
163
164 rtr = glsc3(this%r, coef%mult, this%r, n)
165 rnorm = sqrt(rtr)*norm_fac
166 ksp_results%res_start = rnorm
167 ksp_results%res_final = rnorm
168 ksp_results%iter = 0
169 if (abscmp(rnorm, zero)) then
170 ksp_results%converged = .true.
171 return
172 end if
173
174 call this%monitor_start('CG')
175 do iter = 1, max_iter
176 call this%M%solve(this%z, this%r, n)
177 rtz2 = rtz1
178 rtz1 = glsc3(this%r, coef%mult, this%z, n)
179
180 beta = rtz1 / rtz2
181 if (iter .eq. 1) beta = zero
182 call add2s1(this%p, this%z, beta, n)
183
184 call ax%compute(this%w, this%p, coef, x%msh, x%Xh)
185 call gs_h%op(this%w, n, gs_op_add)
186 call bc_projector%apply(this%w, n)
187
188 pap = glsc3(this%w, coef%mult, this%p, n)
189
190 alpha = rtz1 / pap
191 alphm = -alpha
192 do i = 1, n
193 x%x(i,1,1,1) = x%x(i,1,1,1) + alpha * this%p(i)
194 this%r(i) = this%r(i) + alphm * this%w(i)
195 end do
196
197 rtr = glsc3(this%r, coef%mult, this%r, n)
198 if (iter .eq. 1) rtr0 = rtr
199 rnorm = sqrt(rtr) * norm_fac
200 call this%monitor_iter(iter, rnorm)
201 if (rnorm .lt. this%abs_tol) then
202 exit
203 end if
204 end do
205 call this%monitor_stop()
206 ksp_results%res_final = rnorm
207 ksp_results%iter = iter
208 ksp_results%converged = this%is_converged(iter, rnorm)
209 end function sx_cg_solve
210
212 function sx_cg_solve_coupled(this, Ax, x, y, z, fx, fy, fz, &
213 n, coef, bc_projector, gs_h, niter) result(ksp_results)
214 class(sx_cg_t), intent(inout) :: this
215 class(ax_t), intent(in) :: ax
216 type(field_t), intent(inout) :: x
217 type(field_t), intent(inout) :: y
218 type(field_t), intent(inout) :: z
219 integer, intent(in) :: n
220 real(kind=rp), dimension(n), intent(in) :: fx
221 real(kind=rp), dimension(n), intent(in) :: fy
222 real(kind=rp), dimension(n), intent(in) :: fz
223 type(coef_t), intent(inout) :: coef
224 class(vector_bc_projector_t), intent(inout) :: bc_projector
225 type(gs_t), intent(inout) :: gs_h
226 type(ksp_monitor_t), dimension(3) :: ksp_results
227 integer, optional, intent(in) :: niter
228 type(scalar_bc_projector_t), pointer :: bc_x, bc_y, bc_z
229
230 call vector_bc_projector_components(bc_projector, bc_x, bc_y, bc_z)
231 ksp_results(1) = this%solve(ax, x, fx, n, coef, bc_x, gs_h, niter)
232 ksp_results(2) = this%solve(ax, y, fy, n, coef, bc_y, gs_h, niter)
233 ksp_results(3) = this%solve(ax, z, fz, n, coef, bc_z, gs_h, niter)
234
235 end function sx_cg_solve_coupled
236
237end module cg_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
Defines various Conjugate Gradient methods.
Definition cg_sx.f90:34
type(ksp_monitor_t) function, dimension(3) sx_cg_solve_coupled(this, ax, x, y, z, fx, fy, fz, n, coef, bc_projector, gs_h, niter)
Standard PCG coupled solve.
Definition cg_sx.f90:214
subroutine sx_cg_free(this)
Deallocate a standard PCG solver.
Definition cg_sx.f90:107
type(ksp_monitor_t) function sx_cg_solve(this, ax, x, f, n, coef, bc_projector, gs_h, niter)
Standard PCG solve.
Definition cg_sx.f90:134
subroutine sx_cg_init(this, n, max_iter, m, rel_tol, abs_tol, monitor)
Initialise a standard PCG solver.
Definition cg_sx.f90:66
Coefficients.
Definition coef.f90:34
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
subroutine, public add2s1(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on first argument)
Definition math.f90:984
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
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
Standard preconditioned conjugate gradient method (SX version)
Definition cg_sx.f90:50
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
Defines a canonical Krylov preconditioner.
Definition precon.f90:40
Projector for scalar boundary conditions.
Abstract type for resolving vector boundary conditions.