Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
bicgstab_coupled.f90
Go to the documentation of this file.
1! Copyright (c) 2026, 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, xp
36 use krylov, only : ksp_t, ksp_monitor_t
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
46 use mpi_f08, only : mpi_allreduce, mpi_in_place, mpi_sum
47 use operators, only : rotate_cyc
48 use math, only : neko_eps
49 use utils, only : neko_error
50 use, intrinsic :: ieee_arithmetic, only : ieee_is_finite
51 implicit none
52 private
53
59 type, public, extends(ksp_t) :: bicgstab_cpld_t
61 real(kind=rp), pointer :: p(:, :) => null()
63 real(kind=rp), pointer :: p_hat(:, :) => null()
65 real(kind=rp), pointer :: r(:, :) => null()
67 real(kind=rp), pointer :: s_hat(:, :) => null()
69 real(kind=rp), pointer :: t(:, :) => null()
71 real(kind=rp), pointer :: v(:, :) => null()
72 contains
74 procedure, pass(this) :: init => bicgstab_cpld_init
76 procedure, pass(this) :: free => bicgstab_cpld_free
78 procedure, pass(this) :: solve => bicgstab_cpld_solve_scalar
80 procedure, pass(this) :: solve_coupled => bicgstab_cpld_solve
81 end type bicgstab_cpld_t
82
83contains
84
93 subroutine bicgstab_cpld_init(this, n, max_iter, M, rel_tol, abs_tol, &
94 monitor)
95 class(bicgstab_cpld_t), target, intent(inout) :: this
96 integer, intent(in) :: n
97 integer, intent(in) :: max_iter
98 class(pc_t), optional, intent(in), target :: M
99 real(kind=rp), optional, intent(in) :: rel_tol
100 real(kind=rp), optional, intent(in) :: abs_tol
101 logical, optional, intent(in) :: monitor
102
103 call this%free()
104
105 if (present(m)) then
106 this%M => m
107 end if
108
109 if (present(rel_tol) .and. present(abs_tol) .and. present(monitor)) then
110 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
111 else if (present(rel_tol) .and. present(abs_tol)) then
112 call this%ksp_init(max_iter, rel_tol, abs_tol)
113 else if (present(monitor) .and. present(abs_tol)) then
114 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
115 else if (present(rel_tol) .and. present(monitor)) then
116 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
117 else if (present(rel_tol)) then
118 call this%ksp_init(max_iter, rel_tol = rel_tol)
119 else if (present(abs_tol)) then
120 call this%ksp_init(max_iter, abs_tol = abs_tol)
121 else if (present(monitor)) then
122 call this%ksp_init(max_iter, monitor = monitor)
123 else
124 call this%ksp_init(max_iter)
125 end if
126
127 end subroutine bicgstab_cpld_init
128
130 subroutine bicgstab_cpld_free(this)
131 class(bicgstab_cpld_t), intent(inout) :: this
132
133 call this%ksp_free()
134
135 nullify(this%M)
136 nullify(this%p, this%p_hat, this%r, this%s_hat, this%t, this%v)
137
138 end subroutine bicgstab_cpld_free
139
150 function bicgstab_cpld_solve_scalar(this, Ax, x, f, n, coef, &
151 bc_projector, gs_h, niter) result(ksp_results)
152 class(bicgstab_cpld_t), intent(inout) :: this
153 class(ax_t), intent(in) :: ax
154 type(field_t), intent(inout) :: x
155 integer, intent(in) :: n
156 real(kind=rp), dimension(n), intent(in) :: f
157 type(coef_t), intent(inout) :: coef
158 class(scalar_bc_projector_t), intent(inout) :: bc_projector
159 type(gs_t), intent(inout) :: gs_h
160 integer, optional, intent(in) :: niter
161 type(ksp_monitor_t) :: ksp_results
162
163 call neko_error('Coupled BiCGStab is only defined for coupled solves')
164
165 ksp_results%res_start = 0.0_rp
166 ksp_results%res_final = 0.0_rp
167 ksp_results%iter = 0
168 ksp_results%converged = .false.
169
170 end function bicgstab_cpld_solve_scalar
171
191 function bicgstab_cpld_solve(this, Ax, x, y, z, fx, fy, fz, n, coef, &
192 bc_projector, gs_h, niter) result(ksp_results)
193 class(bicgstab_cpld_t), intent(inout) :: this
194 class(ax_t), intent(in) :: ax
195 type(field_t), intent(inout) :: x
196 type(field_t), intent(inout) :: y
197 type(field_t), intent(inout) :: z
198 integer, intent(in) :: n
199 real(kind=rp), dimension(n), intent(in) :: fx
200 real(kind=rp), dimension(n), intent(in) :: fy
201 real(kind=rp), dimension(n), intent(in) :: fz
202 type(coef_t), intent(inout) :: coef
203 class(vector_bc_projector_t), intent(inout) :: bc_projector
204 type(gs_t), intent(inout) :: gs_h
205 integer, optional, intent(in) :: niter
206 type(ksp_monitor_t), dimension(3) :: ksp_results
207 integer :: i, iter, max_iter, ierr
208 real(kind=rp) :: alpha, beta, omega, rho_1, rho_2
209 real(kind=rp) :: rnorm, norm_fac, gamma
210 real(kind=rp) :: r_norm, s_norm, shadow_norm, t_norm, v_norm
211 ! r^T r, s^T s, f^T v, v^T v, s^T t, t^T t
212 real(kind=rp) :: rtr, sts, ftv, vtv, stt, ttt
213 real(kind=xp) :: norm_sum
214 real(kind=rp), pointer, dimension(:) :: p_tmp, p_hat_tmp, r_tmp
215 real(kind=rp), pointer, dimension(:) :: s_hat_tmp, t_tmp, v_tmp
216 integer :: temp_indices(6)
217
218 if (present(niter)) then
219 max_iter = niter
220 else
221 max_iter = this%max_iter
222 end if
223 norm_fac = 1.0_rp / sqrt(coef%volume)
224
225 call neko_scratch_registry%request(p_tmp, temp_indices(1), 3 * n, .false.)
226 call neko_scratch_registry%request(p_hat_tmp, temp_indices(2), 3 * n, .false.)
227 call neko_scratch_registry%request(r_tmp, temp_indices(3), 3 * n, .false.)
228 call neko_scratch_registry%request(s_hat_tmp, temp_indices(4), 3 * n, .false.)
229 call neko_scratch_registry%request(t_tmp, temp_indices(5), 3 * n, .false.)
230 call neko_scratch_registry%request(v_tmp, temp_indices(6), 3 * n, .false.)
231
232 this%p(1:n, 1:3) => p_tmp
233 this%p_hat(1:n, 1:3) => p_hat_tmp
234 this%r(1:n, 1:3) => r_tmp
235 this%s_hat(1:n, 1:3) => s_hat_tmp
236 this%t(1:n, 1:3) => t_tmp
237 this%v(1:n, 1:3) => v_tmp
238
239 associate(p => this%p, p_hat => this%p_hat, r => this%r, &
240 s_hat => this%s_hat, t => this%t, v => this%v)
241
242 ! BiCGStab starts from zero. The right-hand side is consequently both
243 ! the initial residual and the fixed shadow residual.
244 norm_sum = 0.0_xp
245 !$omp parallel do reduction(+:norm_sum)
246 do i = 1, n
247 x%x(i, 1, 1, 1) = 0.0_rp
248 y%x(i, 1, 1, 1) = 0.0_rp
249 z%x(i, 1, 1, 1) = 0.0_rp
250 r(i, 1) = fx(i)
251 r(i, 2) = fy(i)
252 r(i, 3) = fz(i)
253 norm_sum = norm_sum + coef%mult(i, 1, 1, 1) * &
254 (r(i, 1)**2 + r(i, 2)**2 + r(i, 3)**2)
255 end do
256 !$omp end parallel do
257 call mpi_allreduce(mpi_in_place, norm_sum, 1, mpi_extra_precision, &
258 mpi_sum, neko_comm, ierr)
259
260 rtr = norm_sum
261 r_norm = bicgstab_cpld_sqrt(rtr, 'initial residual')
262 shadow_norm = r_norm
263 rnorm = r_norm * norm_fac
264 gamma = rnorm * this%rel_tol
265 ksp_results%res_start = rnorm
266 ksp_results%res_final = rnorm
267 ksp_results%iter = 0
268
269 ! Besides saving an iteration, the early check prevents a converged
270 ! right-hand side from being reported as a rho breakdown.
271 if (r_norm .le. 0.0_rp .or. rnorm .lt. this%abs_tol .or. &
272 rnorm .lt. gamma) then
273 ksp_results%converged = .true.
274 nullify(this%p, this%p_hat, this%r, this%s_hat, this%t, this%v)
275 call neko_scratch_registry%relinquish_host_array(temp_indices)
276 return
277 end if
278
279 call this%monitor_start('Coupled BiCGStab')
280 do iter = 1, max_iter
281 call bicgstab_cpld_product(rho_1, fx, fy, fz, r(:, 1), r(:, 2), &
282 r(:, 3), coef%mult, n)
283
284 ! The combined product-space norms make the breakdown decision
285 ! invariant under a uniform scaling of the complete vector system.
286 call bicgstab_cpld_check_inner_product(rho_1, shadow_norm, r_norm, &
287 'rho inner product')
288
289 if (iter .eq. 1) then
290 !$omp parallel do
291 do i = 1, n
292 p(i, 1) = r(i, 1)
293 p(i, 2) = r(i, 2)
294 p(i, 3) = r(i, 3)
295 end do
296 !$omp end parallel do
297 else
298 beta = (rho_1 / rho_2) * (alpha / omega)
299 if (.not. ieee_is_finite(beta)) then
300 call neko_error('Coupled BiCGStab failure: non-finite beta')
301 end if
302
303 !$omp parallel do
304 do i = 1, n
305 p(i, 1) = r(i, 1) + &
306 beta * (p(i, 1) - omega * v(i, 1))
307 p(i, 2) = r(i, 2) + &
308 beta * (p(i, 2) - omega * v(i, 2))
309 p(i, 3) = r(i, 3) + &
310 beta * (p(i, 3) - omega * v(i, 3))
311 end do
312 !$omp end parallel do
313 end if
314
315 ! The preconditioner interface is scalar, so apply the same
316 ! preconditioner separately to all three components.
317 call this%M%solve(p_hat(:, 1), p(:, 1), n)
318 call this%M%solve(p_hat(:, 2), p(:, 2), n)
319 call this%M%solve(p_hat(:, 3), p(:, 3), n)
320
321 call ax%compute_vector(v(:, 1), v(:, 2), v(:, 3), p_hat(:, 1), &
322 p_hat(:, 2), p_hat(:, 3), coef, x%msh, x%Xh)
323 call bicgstab_cpld_assemble(v, n, coef, bc_projector, gs_h)
324
325 ! Compute f^T v and v^T v in a single global reduction. The latter
326 ! supplies the scale for the alpha-denominator breakdown check.
327 call bicgstab_cpld_product_and_norm(ftv, vtv, fx, fy, fz, &
328 v(:, 1), v(:, 2), v(:, 3), coef%mult, n)
329 v_norm = bicgstab_cpld_sqrt(vtv, 'operator result v')
330 call bicgstab_cpld_check_inner_product(ftv, shadow_norm, v_norm, &
331 'alpha denominator')
332 alpha = rho_1 / ftv
333 if (.not. ieee_is_finite(alpha)) then
334 call neko_error('Coupled BiCGStab failure: non-finite alpha')
335 end if
336
337 ! Store the intermediate residual in r and compute its combined norm
338 ! in the same pass. The previous residual is no longer needed after
339 ! p has been formed.
340 norm_sum = 0.0_xp
341 !$omp parallel do reduction(+:norm_sum)
342 do i = 1, n
343 r(i, 1) = r(i, 1) - alpha * v(i, 1)
344 r(i, 2) = r(i, 2) - alpha * v(i, 2)
345 r(i, 3) = r(i, 3) - alpha * v(i, 3)
346 norm_sum = norm_sum + coef%mult(i, 1, 1, 1) * &
347 (r(i, 1)**2 + r(i, 2)**2 + r(i, 3)**2)
348 end do
349 !$omp end parallel do
350 call mpi_allreduce(mpi_in_place, norm_sum, 1, mpi_extra_precision, &
351 mpi_sum, neko_comm, ierr)
352
353 sts = norm_sum
354 s_norm = bicgstab_cpld_sqrt(sts, 'intermediate residual')
355 rnorm = s_norm * norm_fac
356 if (rnorm .lt. this%abs_tol .or. rnorm .lt. gamma) then
357 !$omp parallel do
358 do i = 1, n
359 x%x(i, 1, 1, 1) = x%x(i, 1, 1, 1) + alpha * p_hat(i, 1)
360 y%x(i, 1, 1, 1) = y%x(i, 1, 1, 1) + alpha * p_hat(i, 2)
361 z%x(i, 1, 1, 1) = z%x(i, 1, 1, 1) + alpha * p_hat(i, 3)
362 end do
363 !$omp end parallel do
364 call this%monitor_iter(iter, rnorm)
365 exit
366 end if
367
368 call this%M%solve(s_hat(:, 1), r(:, 1), n)
369 call this%M%solve(s_hat(:, 2), r(:, 2), n)
370 call this%M%solve(s_hat(:, 3), r(:, 3), n)
371
372 call ax%compute_vector(t(:, 1), t(:, 2), t(:, 3), s_hat(:, 1), &
373 s_hat(:, 2), s_hat(:, 3), coef, x%msh, x%Xh)
374 call bicgstab_cpld_assemble(t, n, coef, bc_projector, gs_h)
375
376 ! The numerator and denominator of omega share one reduction.
377 call bicgstab_cpld_product_and_norm(stt, ttt, r(:, 1), r(:, 2), &
378 r(:, 3), t(:, 1), t(:, 2), t(:, 3), coef%mult, n)
379 t_norm = bicgstab_cpld_sqrt(ttt, 'operator result t')
380 if (t_norm .le. 0.0_rp) then
381 call neko_error(&
382 'Coupled BiCGStab breakdown: zero omega denominator')
383 end if
384 if (.not. ieee_is_finite(stt)) then
385 call neko_error(&
386 'Coupled BiCGStab failure: non-finite omega numerator')
387 end if
388 omega = stt / ttt
389 if (.not. ieee_is_finite(omega)) then
390 call neko_error('Coupled BiCGStab failure: non-finite omega')
391 end if
392
393 ! Update the solution, recursive residual, and residual norm together
394 ! to avoid another traversal of all three component vectors.
395 norm_sum = 0.0_xp
396 !$omp parallel do reduction(+:norm_sum)
397 do i = 1, n
398 x%x(i, 1, 1, 1) = x%x(i, 1, 1, 1) + alpha * p_hat(i, 1) + &
399 omega * s_hat(i, 1)
400 y%x(i, 1, 1, 1) = y%x(i, 1, 1, 1) + alpha * p_hat(i, 2) + &
401 omega * s_hat(i, 2)
402 z%x(i, 1, 1, 1) = z%x(i, 1, 1, 1) + alpha * p_hat(i, 3) + &
403 omega * s_hat(i, 3)
404 r(i, 1) = r(i, 1) - omega * t(i, 1)
405 r(i, 2) = r(i, 2) - omega * t(i, 2)
406 r(i, 3) = r(i, 3) - omega * t(i, 3)
407 norm_sum = norm_sum + coef%mult(i, 1, 1, 1) * &
408 (r(i, 1)**2 + r(i, 2)**2 + r(i, 3)**2)
409 end do
410 !$omp end parallel do
411 call mpi_allreduce(mpi_in_place, norm_sum, 1, mpi_extra_precision, &
412 mpi_sum, neko_comm, ierr)
413
414 rtr = norm_sum
415 r_norm = bicgstab_cpld_sqrt(rtr, 'recursive residual')
416 rnorm = r_norm * norm_fac
417 call this%monitor_iter(iter, rnorm)
418 if (rnorm .lt. this%abs_tol .or. rnorm .lt. gamma) then
419 exit
420 end if
421
422 ! A negative omega is valid. Only numerical orthogonality between s
423 ! and t constitutes a breakdown of the minimal-residual step.
424 call bicgstab_cpld_check_inner_product(stt, s_norm, t_norm, &
425 'omega numerator')
426 rho_2 = rho_1
427 end do
428
429 call this%monitor_stop()
430 ksp_results%res_final = rnorm
431 ksp_results%iter = iter
432 ksp_results%converged = this%is_converged(iter, rnorm)
433 end associate
434 nullify(this%p, this%p_hat, this%r, this%s_hat, this%t, this%v)
435 call neko_scratch_registry%relinquish_host_array(temp_indices)
436
437 end function bicgstab_cpld_solve
438
444 subroutine bicgstab_cpld_check_inner_product(inner_product, norm_a, norm_b, &
445 quantity)
446 real(kind=rp), intent(in) :: inner_product
447 real(kind=rp), intent(in) :: norm_a
448 real(kind=rp), intent(in) :: norm_b
449 character(len=*), intent(in) :: quantity
450 real(kind=rp) :: large_norm, small_norm
451
452 if (.not. ieee_is_finite(inner_product)) then
453 call neko_error('Coupled BiCGStab failure: non-finite ' // &
454 trim(quantity))
455 end if
456
457 ! Divide by the larger norm first to avoid overflow in their product.
458 large_norm = max(norm_a, norm_b)
459 small_norm = min(norm_a, norm_b)
460 if (large_norm .le. 0.0_rp .or. &
461 abs(inner_product) / large_norm .le. neko_eps * small_norm) then
462 call neko_error('Coupled BiCGStab breakdown: near-zero ' // &
463 trim(quantity))
464 end if
465
467
472 function bicgstab_cpld_sqrt(value, quantity) result(root)
473 real(kind=rp), intent(in) :: value
474 character(len=*), intent(in) :: quantity
475 real(kind=rp) :: root
476
477 if (.not. ieee_is_finite(value) .or. value .lt. 0.0_rp) then
478 call neko_error('Coupled BiCGStab failure: invalid ' // &
479 trim(quantity) // ' norm')
480 end if
481 root = sqrt(value)
482
483 end function bicgstab_cpld_sqrt
484
491 subroutine bicgstab_cpld_assemble(vector, n, coef, bc_projector, gs_h)
492 integer, intent(in) :: n
493 real(kind=rp), dimension(n, 3), intent(inout) :: vector
494 type(coef_t), intent(inout) :: coef
495 class(vector_bc_projector_t), intent(inout) :: bc_projector
496 type(gs_t), intent(inout) :: gs_h
497
498 ! Cyclic faces must be expressed in their common coordinate system while
499 ! the three components are gathered, then rotated back to physical space.
500 call rotate_cyc(vector(:, 1), vector(:, 2), vector(:, 3), 1, coef)
501 call gs_h%op(vector(:, 1), vector(:, 2), vector(:, 3), n, gs_op_add)
502 call rotate_cyc(vector(:, 1), vector(:, 2), vector(:, 3), 0, coef)
503
504 call bc_projector%apply(vector(:, 1), vector(:, 2), vector(:, 3), n)
505
506 end subroutine bicgstab_cpld_assemble
507
518 subroutine bicgstab_cpld_product(product, ax, ay, az, bx, by, bz, mult, n)
519 integer, intent(in) :: n
520 real(kind=rp), intent(out) :: product
521 real(kind=rp), dimension(n), intent(in) :: ax, ay, az
522 real(kind=rp), dimension(n), intent(in) :: bx, by, bz
523 real(kind=rp), dimension(n), intent(in) :: mult
524 real(kind=xp) :: product_sum
525 integer :: i, ierr
526
527 product_sum = 0.0_xp
528 !$omp parallel do reduction(+:product_sum)
529 do i = 1, n
530 product_sum = product_sum + mult(i) * &
531 (ax(i) * bx(i) + ay(i) * by(i) + az(i) * bz(i))
532 end do
533 !$omp end parallel do
534
535 call mpi_allreduce(mpi_in_place, product_sum, 1, mpi_extra_precision, &
536 mpi_sum, neko_comm, ierr)
537 product = product_sum
538
539 end subroutine bicgstab_cpld_product
540
552 subroutine bicgstab_cpld_product_and_norm(product, norm_squared, ax, ay, &
553 az, bx, by, bz, mult, n)
554 integer, intent(in) :: n
555 real(kind=rp), intent(out) :: product
556 real(kind=rp), intent(out) :: norm_squared
557 real(kind=rp), dimension(n), intent(in) :: ax, ay, az
558 real(kind=rp), dimension(n), intent(in) :: bx, by, bz
559 real(kind=rp), dimension(n), intent(in) :: mult
560 real(kind=xp) :: product_sum, norm_sum
561 real(kind=xp) :: reductions(2)
562 integer :: i, ierr
563
564 product_sum = 0.0_xp
565 norm_sum = 0.0_xp
566 !$omp parallel do reduction(+:product_sum,norm_sum)
567 do i = 1, n
568 product_sum = product_sum + mult(i) * &
569 (ax(i) * bx(i) + ay(i) * by(i) + az(i) * bz(i))
570 norm_sum = norm_sum + mult(i) * &
571 (bx(i)**2 + by(i)**2 + bz(i)**2)
572 end do
573 !$omp end parallel do
574
575 reductions(1) = product_sum
576 reductions(2) = norm_sum
577 call mpi_allreduce(mpi_in_place, reductions, 2, mpi_extra_precision, &
578 mpi_sum, neko_comm, ierr)
579 product = reductions(1)
580 norm_squared = reductions(2)
581
582 end subroutine bicgstab_cpld_product_and_norm
583
584end module bicgstab_cpld
__device__ T solve(const T u, const T y, const T guess, const T nu, const T kappa, const T B)
Apply cyclic boundary condition to a vector field.
Defines a Matrix-vector product.
Definition ax.f90:34
Provides a coupled CPU implementation of the BiCGStab method.
subroutine bicgstab_cpld_free(this)
Free a coupled CPU BiCGStab solver.
subroutine bicgstab_cpld_check_inner_product(inner_product, norm_a, norm_b, quantity)
Check an inner product for a coupled BiCGStab breakdown.
type(ksp_monitor_t) function bicgstab_cpld_solve_scalar(this, ax, x, f, n, coef, bc_projector, gs_h, niter)
Reject a scalar solve with a coupled BiCGStab solver.
subroutine bicgstab_cpld_product_and_norm(product, norm_squared, ax, ay, az, bx, by, bz, mult, n)
Compute a coupled inner product and squared norm in one reduction.
real(kind=rp) function bicgstab_cpld_sqrt(value, quantity)
Return the square root of a valid combined squared norm.
subroutine bicgstab_cpld_init(this, n, max_iter, m, rel_tol, abs_tol, monitor)
Initialise a coupled CPU BiCGStab solver.
subroutine bicgstab_cpld_assemble(vector, n, coef, bc_projector, gs_h)
Assemble a coupled operator result and project its boundary data.
subroutine bicgstab_cpld_product(product, ax, ay, az, bx, by, bz, mult, n)
Compute a coupled weighted inner product in one global reduction.
type(ksp_monitor_t) function, dimension(3) bicgstab_cpld_solve(this, ax, x, y, z, fx, fy, fz, n, coef, bc_projector, gs_h, niter)
Solve a three-component coupled system with the CPU BiCGStab method.
Coefficients.
Definition coef.f90:34
Definition comm.F90:1
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:46
type(mpi_datatype), public mpi_extra_precision
Definition comm.F90:55
Defines a field.
Definition field.f90:34
Gather-scatter.
Implements the base abstract type for Krylov solvers plus helper types.
Definition krylov.f90:34
Definition math.f90:60
real(kind=rp), parameter, public neko_eps
Machine epsilon .
Definition math.f90:70
integer, parameter, public xp
Definition num_types.f90:16
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Operators.
Definition operators.f90:34
Krylov preconditioner.
Definition precon.f90:34
Implements scalar_projector_t.
Defines a registry for storing and requesting temporary objects This can be used when you have a func...
type(scratch_registry_t), target, public neko_scratch_registry
Global scratch registry.
Utilities.
Definition utils.f90:35
Implements boundary condition projectors for vector fields. Two types concrete types are provided: se...
Defines a vector.
Definition vector.f90:34
Base type for a matrix-vector product providing .
Definition ax.f90:43
Coupled right-preconditioned CPU BiCGStab method.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:135
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.
#define max(a, b)
Definition tensor.cu:40