Neko 1.99.5
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
bicgstab.f90
Go to the documentation of this file.
1! Copyright (c) 2021-2024, 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!
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
42 use bc_list, only : bc_list_t
43 use math, only : glsc3, rzero, copy, neko_eps, add2s2, x_update, &
45 use utils, only : neko_error
46 implicit none
47 private
48
50 type, public, extends(ksp_t) :: bicgstab_t
51 real(kind=rp), allocatable :: p(:)
52 real(kind=rp), allocatable :: p_hat(:)
53 real(kind=rp), allocatable :: r(:)
54 real(kind=rp), allocatable :: s(:)
55 real(kind=rp), allocatable :: s_hat(:)
56 real(kind=rp), allocatable :: t(:)
57 real(kind=rp), allocatable :: v(:)
58 contains
60 procedure, pass(this) :: init => bicgstab_init
62 procedure, pass(this) :: free => bicgstab_free
64 procedure, pass(this) :: solve => bicgstab_solve
66 procedure, pass(this) :: solve_coupled => bicgstab_solve_coupled
67 end type bicgstab_t
68
69contains
70
72 subroutine bicgstab_init(this, n, max_iter, M, rel_tol, abs_tol, monitor)
73 class(bicgstab_t), target, intent(inout) :: this
74 class(pc_t), optional, intent(in), target :: M
75 integer, intent(in) :: n
76 integer, intent(in) :: max_iter
77 real(kind=rp), optional, intent(in) :: rel_tol
78 real(kind=rp), optional, intent(in) :: abs_tol
79 logical, optional, intent(in) :: monitor
80
81
82 call this%free()
83
84 allocate(this%p(n))
85 allocate(this%p_hat(n))
86 allocate(this%r(n))
87 allocate(this%s(n))
88 allocate(this%s_hat(n))
89 allocate(this%t(n))
90 allocate(this%v(n))
91 if (present(m)) then
92 this%M => m
93 end if
94
95 if (present(rel_tol) .and. present(abs_tol) .and. present(monitor)) then
96 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
97 else if (present(rel_tol) .and. present(abs_tol)) then
98 call this%ksp_init(max_iter, rel_tol, abs_tol)
99 else if (present(monitor) .and. present(abs_tol)) then
100 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
101 else if (present(rel_tol) .and. present(monitor)) then
102 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
103 else if (present(rel_tol)) then
104 call this%ksp_init(max_iter, rel_tol = rel_tol)
105 else if (present(abs_tol)) then
106 call this%ksp_init(max_iter, abs_tol = abs_tol)
107 else if (present(monitor)) then
108 call this%ksp_init(max_iter, monitor = monitor)
109 else
110 call this%ksp_init(max_iter)
111 end if
112
113 end subroutine bicgstab_init
114
116 subroutine bicgstab_free(this)
117 class(bicgstab_t), intent(inout) :: this
118
119 call this%ksp_free()
120
121 if (allocated(this%v)) then
122 deallocate(this%v)
123 end if
124
125 if (allocated(this%r)) then
126 deallocate(this%r)
127 end if
128
129 if (allocated(this%t)) then
130 deallocate(this%t)
131 end if
132
133 if (allocated(this%p)) then
134 deallocate(this%p)
135 end if
136
137 if (allocated(this%p_hat)) then
138 deallocate(this%p_hat)
139 end if
140
141 if (allocated(this%s)) then
142 deallocate(this%s)
143 end if
144
145 if (allocated(this%s_hat)) then
146 deallocate(this%s_hat)
147 end if
148
149 nullify(this%M)
150
151
152 end subroutine bicgstab_free
153
155 function bicgstab_solve(this, Ax, x, f, n, coef, blst, gs_h, niter) &
156 result(ksp_results)
157 class(bicgstab_t), intent(inout) :: this
158 class(ax_t), intent(in) :: ax
159 type(field_t), intent(inout) :: x
160 integer, intent(in) :: n
161 real(kind=rp), dimension(n), intent(in) :: f
162 type(coef_t), intent(inout) :: coef
163 type(bc_list_t), intent(inout) :: blst
164 type(gs_t), intent(inout) :: gs_h
165 type(ksp_monitor_t) :: ksp_results
166 integer, optional, intent(in) :: niter
167 integer :: iter, max_iter
168 real(kind=rp) :: rnorm, rtr, norm_fac, gamma
169 real(kind=rp) :: beta, alpha, omega, rho_1, rho_2
170
171 if (present(niter)) then
172 max_iter = niter
173 else
174 max_iter = this%max_iter
175 end if
176 norm_fac = 1.0_rp / sqrt(coef%volume)
177
178 associate(r => this%r, t => this%t, s => this%s, v => this%v, p => this%p, &
179 s_hat => this%s_hat, p_hat => this%p_hat)
180
181 call rzero(x%x, n)
182 call copy(r, f, n)
183
184 rtr = sqrt(glsc3(r, coef%mult, r, n))
185 rnorm = rtr * norm_fac
186 gamma = rnorm * this%rel_tol
187 ksp_results%res_start = rnorm
188 ksp_results%res_final = rnorm
189 ksp_results%iter = 0
190 if(abscmp(rnorm, 0.0_rp)) then
191 ksp_results%converged = .true.
192 return
193 end if
194 call this%monitor_start('BiCGStab')
195 do iter = 1, max_iter
196
197 rho_1 = glsc3(r, coef%mult, f ,n)
198
199 if (abs(rho_1) .lt. neko_eps) then
200 call neko_error('Bi-CGStab rho failure')
201 end if
202
203 if (iter .eq. 1) then
204 call copy(p, r, n)
205 else
206 beta = (rho_1 / rho_2) * (alpha / omega)
207 call p_update(p, r, v, beta, omega, n)
208 end if
209
210 call this%M%solve(p_hat, p, n)
211 call ax%compute(v, p_hat, coef, x%msh, x%Xh)
212 call gs_h%op(v, n, gs_op_add)
213 call blst%apply(v, n)
214 alpha = rho_1 / glsc3(f, coef%mult, v, n)
215 call copy(s, r, n)
216 call add2s2(s, v, -alpha, n)
217 rtr = glsc3(s, coef%mult, s, n)
218 rnorm = sqrt(rtr) * norm_fac
219 if (rnorm .lt. this%abs_tol .or. rnorm .lt. gamma) then
220 call add2s2(x%x, p_hat, alpha,n)
221 exit
222 end if
223
224 call this%M%solve(s_hat, s, n)
225 call ax%compute(t, s_hat, coef, x%msh, x%Xh)
226 call gs_h%op(t, n, gs_op_add)
227 call blst%apply(t, n)
228 omega = glsc3(t, coef%mult, s, n) &
229 / glsc3(t, coef%mult, t, n)
230 call x_update(x%x, p_hat, s_hat, alpha, omega, n)
231 call copy(r, s, n)
232 call add2s2(r, t, -omega, n)
233
234 rtr = glsc3(r, coef%mult, r, n)
235 rnorm = sqrt(rtr) * norm_fac
236 call this%monitor_iter(iter, rnorm)
237 if (rnorm .lt. this%abs_tol .or. rnorm .lt. gamma) then
238 exit
239 end if
240
241 if (omega .lt. neko_eps) then
242 call neko_error('Bi-CGstab omega failure')
243 end if
244 rho_2 = rho_1
245
246 end do
247 end associate
248 call this%monitor_stop()
249 ksp_results%res_final = rnorm
250 ksp_results%iter = iter
251 ksp_results%converged = this%is_converged(iter, rnorm)
252 end function bicgstab_solve
253
255 function bicgstab_solve_coupled(this, Ax, x, y, z, fx, fy, fz, &
256 n, coef, blstx, blsty, blstz, gs_h, niter) result(ksp_results)
257 class(bicgstab_t), intent(inout) :: this
258 class(ax_t), intent(in) :: ax
259 type(field_t), intent(inout) :: x
260 type(field_t), intent(inout) :: y
261 type(field_t), intent(inout) :: z
262 integer, intent(in) :: n
263 real(kind=rp), dimension(n), intent(in) :: fx
264 real(kind=rp), dimension(n), intent(in) :: fy
265 real(kind=rp), dimension(n), intent(in) :: fz
266 type(coef_t), intent(inout) :: coef
267 type(bc_list_t), intent(inout) :: blstx
268 type(bc_list_t), intent(inout) :: blsty
269 type(bc_list_t), intent(inout) :: blstz
270 type(gs_t), intent(inout) :: gs_h
271 type(ksp_monitor_t), dimension(3) :: ksp_results
272 integer, optional, intent(in) :: niter
273
274 ksp_results(1) = this%solve(ax, x, fx, n, coef, blstx, gs_h, niter)
275 ksp_results(2) = this%solve(ax, y, fy, n, coef, blsty, gs_h, niter)
276 ksp_results(3) = this%solve(ax, z, fz, n, coef, blstz, gs_h, niter)
277
278 end function bicgstab_solve_coupled
279
280end module bicgstab
281
__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 a list of bc_t.
Definition bc_list.f90:34
Defines various Bi-Conjugate Gradient Stabilized methods.
Definition bicgstab.f90:34
subroutine bicgstab_init(this, n, max_iter, m, rel_tol, abs_tol, monitor)
Constructor.
Definition bicgstab.f90:73
subroutine bicgstab_free(this)
Deallocate a standard BiCGSTAB solver.
Definition bicgstab.f90:117
type(ksp_monitor_t) function bicgstab_solve(this, ax, x, f, n, coef, blst, gs_h, niter)
Bi-Conjugate Gradient Stabilized method solve.
Definition bicgstab.f90:157
type(ksp_monitor_t) function, dimension(3) bicgstab_solve_coupled(this, ax, x, y, z, fx, fy, fz, n, coef, blstx, blsty, blstz, gs_h, niter)
Standard BiCGSTAB coupled solve.
Definition bicgstab.f90:257
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:51
Definition math.f90:60
real(kind=rp) function, public glsc3(a, b, c, n)
Weighted inner product .
Definition math.f90:1287
subroutine, public x_update(a, b, c, c1, c2, n)
Returns .
Definition math.f90:1249
subroutine, public copy(a, b, n)
Copy a vector .
Definition math.f90:291
real(kind=rp), parameter, public neko_eps
Machine epsilon .
Definition math.f90:70
subroutine, public rzero(a, n)
Zero a real vector.
Definition math.f90:235
subroutine, public add2s2(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on second argument)
Definition math.f90:998
subroutine, public p_update(a, b, c, c1, c2, n)
Returns .
Definition math.f90:1232
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Krylov preconditioner.
Definition precon.f90:34
Utilities.
Definition utils.f90:35
Base type for a matrix-vector product providing .
Definition ax.f90:43
A list of allocatable `bc_t`. Follows the standard interface of lists.
Definition bc_list.f90:49
Standard preconditioned Bi-Conjugate Gradient Stabilized method.
Definition bicgstab.f90:50
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:62
Type for storing initial and final residuals in a Krylov solver.
Definition krylov.f90:56
Base abstract type for a canonical Krylov method, solving .
Definition krylov.f90:73
Defines a canonical Krylov preconditioner.
Definition precon.f90:40