58 character(len=18) :: name =
""
62 real(kind=
rp) :: res_start
64 real(kind=
rp) :: res_final
66 logical :: converged = .false.
74 class(
pc_t),
pointer :: m => null()
75 real(kind=
rp) :: rel_tol
76 real(kind=
rp) :: abs_tol
78 class(
pc_t),
allocatable :: m_ident
116 class(
ksp_t),
target,
intent(inout) :: this
117 integer,
intent(in) :: max_iter
118 class(
pc_t),
optional,
intent(in),
target :: M
119 integer,
intent(in) :: n
120 real(kind=
rp),
optional,
intent(in) :: rel_tol
121 real(kind=
rp),
optional,
intent(in) :: abs_tol
122 logical,
optional,
intent(in) :: monitor
136 function ksp_method(this, Ax, x, f, n, coef, blst, gs_h, niter) &
147 class(
ksp_t),
intent(inout) :: this
148 class(
ax_t),
intent(in) :: ax
149 type(
field_t),
intent(inout) :: x
150 integer,
intent(in) :: n
151 real(kind=
rp),
dimension(n),
intent(in) :: f
152 type(
coef_t),
intent(inout) :: coef
154 type(
gs_t),
intent(inout) :: gs_h
155 integer,
optional,
intent(in) :: niter
175 n, coef, blstx, blsty, blstz, gs_h, niter)
result(ksp_results)
185 class(
ksp_t),
intent(inout) :: this
186 class(
ax_t),
intent(in) :: ax
187 type(
field_t),
intent(inout) :: x
188 type(
field_t),
intent(inout) :: y
189 type(
field_t),
intent(inout) :: z
190 integer,
intent(in) :: n
191 real(kind=
rp),
dimension(n),
intent(in) :: fx
192 real(kind=
rp),
dimension(n),
intent(in) :: fy
193 real(kind=
rp),
dimension(n),
intent(in) :: fz
194 type(
coef_t),
intent(inout) :: coef
198 type(
gs_t),
intent(inout) :: gs_h
199 integer,
optional,
intent(in) :: niter
208 class(
ksp_t),
intent(inout) :: this
221 module subroutine krylov_solver_factory(object, n, type_name, &
222 max_iter, abstol, m, monitor)
223 class(ksp_t),
allocatable,
intent(inout) :: object
224 integer,
intent(in),
value :: n
225 character(len=*),
intent(in) :: type_name
226 integer,
intent(in) :: max_iter
227 real(kind=
rp),
optional :: abstol
228 class(
pc_t),
optional,
intent(in),
target :: m
229 logical,
optional,
intent(in) :: monitor
230 end subroutine krylov_solver_factory
238 module subroutine krylov_solver_allocator(object, type_name)
239 class(ksp_t),
allocatable,
intent(inout) :: object
240 character(len=*),
intent(in) :: type_name
241 end subroutine krylov_solver_allocator
252 subroutine krylov_allocate(obj)
254 class(ksp_t),
allocatable,
intent(inout) :: obj
255 end subroutine krylov_allocate
260 module subroutine register_krylov(type_name, allocator)
261 character(len=*),
intent(in) :: type_name
262 procedure(krylov_allocate),
pointer,
intent(in) :: allocator
263 end subroutine register_krylov
267 type krylov_allocator_entry
268 character(len=20) :: type_name
269 procedure(krylov_allocate),
pointer,
nopass :: allocator
270 end type krylov_allocator_entry
273 type(krylov_allocator_entry),
allocatable :: krylov_registry(:)
276 integer :: krylov_registry_size = 0
278 public :: krylov_solver_factory, krylov_solver_allocator, register_krylov, &
287 subroutine krylov_init(this, max_iter, rel_tol, abs_tol, M, monitor)
288 class(ksp_t),
target,
intent(inout) :: this
289 integer,
intent(in) :: max_iter
290 real(kind=
rp),
optional,
intent(in) :: rel_tol
291 real(kind=
rp),
optional,
intent(in) :: abs_tol
292 class(
pc_t),
optional,
target,
intent(in) :: m
293 logical,
optional,
intent(in) :: monitor
295 call krylov_free(this)
297 if (
present(rel_tol))
then
298 this%rel_tol = rel_tol
300 this%rel_tol = ksp_rel_tol
303 if (
present(abs_tol))
then
304 this%abs_tol = abs_tol
306 this%abs_tol = ksp_abs_tol
309 this%max_iter = max_iter
314 if (.not.
associated(this%M))
then
318 allocate(
ident_t::this%M_ident)
320 this%M => this%M_ident
324 if (
present(monitor))
then
325 this%monitor = monitor
327 this%monitor = .false.
330 end subroutine krylov_init
333 subroutine krylov_free(this)
334 class(ksp_t),
intent(inout) :: this
338 end subroutine krylov_free
342 subroutine krylov_set_pc(this, M)
343 class(ksp_t),
intent(inout) :: this
344 class(
pc_t),
target,
intent(in) :: M
346 if (
associated(this%M))
then
347 select type (pc => this%M)
351 call neko_error(
'Preconditioner already defined')
357 end subroutine krylov_set_pc
360 subroutine krylov_monitor_start(this, name)
361 class(ksp_t),
intent(in) :: this
362 character(len=*) :: name
363 character(len=LOG_SIZE) :: log_buf
365 if (this%monitor)
then
366 write(log_buf,
'(A)')
'Krylov monitor (' // trim(name) //
')'
367 call neko_log%section(trim(log_buf))
370 write(log_buf,
'(A)')
' Iter. Residual'
372 write(log_buf,
'(A)')
'-------------------------'
375 end subroutine krylov_monitor_start
378 subroutine krylov_monitor_stop(this)
379 class(ksp_t),
intent(in) :: this
381 if (this%monitor)
then
386 end subroutine krylov_monitor_stop
390 subroutine krylov_monitor_iter(this, iter, rnorm)
391 class(ksp_t),
intent(in) :: this
392 integer,
intent(in) :: iter
393 real(kind=
rp),
intent(in) :: rnorm
394 character(len=LOG_SIZE) :: log_buf
396 if (this%monitor)
then
397 write(log_buf,
'(I6,E18.9)') iter, rnorm
401 end subroutine krylov_monitor_iter
411 pure function krylov_is_converged(this, iter, residual)
result(converged)
412 class(ksp_t),
intent(in) :: this
413 integer,
intent(in) :: iter
414 real(kind=
rp),
intent(in) :: residual
418 if (iter .ge. this%max_iter) converged = .false.
419 if (residual .gt. this%abs_tol) converged = .false.
421 end function krylov_is_converged
424 subroutine krylov_monitor_print_header(this)
425 class(ksp_monitor_t),
intent(in) :: this
426 character(len=LOG_SIZE) :: log_buf
428 write(log_buf,
'(A10,2x,A3,(A5,13x),1x,A6,3x,A15,3x,A15)') &
429 'KSP solver',
' | ',
'Field:',
'Iters:', &
430 'Start residual:',
'Final residual:'
433 end subroutine krylov_monitor_print_header
436 subroutine krylov_monitor_print_result(this, step)
437 class(ksp_monitor_t),
intent(in) :: this
438 integer,
intent(in) :: step
439 character(len=LOG_SIZE) :: log_buf
440 character(len=12) :: step_str
441 character(len=:),
allocatable :: output_format
443 if (this%name .eq.
"")
call neko_error(
'Krylov solver name is not set')
446 output_format =
'(A12,A3,A18,1x,I6,3x,E15.9,3x,E15.9)'
447 write(step_str,
'(I12)') step
448 step_str = adjustl(step_str)
450 write(log_buf, output_format) &
451 step_str,
' | ' , adjustl(this%name), this%iter, &
452 this%res_start, this%res_final
455 end subroutine krylov_monitor_print_result
__device__ T solve(const T u, const T y, const T guess, const T nu, const T kappa, const T B)
Abstract interface for a Krylov method's constructor.
Abstract interface for a Krylov method's coupled solve routine.
Abstract interface for a Krylov method's solve routine.
Abstract interface for deallocating a Krylov method.
Defines a Matrix-vector product.
Identity Krylov preconditioner for accelerators.
Krylov preconditioner (identity)
Implements the base abstract type for Krylov solvers plus helper types.
real(kind=rp), parameter, public ksp_rel_tol
Relative tolerance.
real(kind=rp), parameter, public ksp_abs_tol
Absolut tolerance.
subroutine krylov_free(this)
Deallocate a Krylov solver.
integer, parameter, public ksp_max_iter
Maximum number of iters.
subroutine krylov_monitor_iter(this, iter, rnorm)
Monitor iteration.
subroutine krylov_init(this, max_iter, rel_tol, abs_tol, m, monitor)
Constructor for the base type.
subroutine krylov_monitor_print_header(this)
Print the Krylov solver's result header.
subroutine krylov_monitor_start(this, name)
Monitor start.
pure logical function krylov_is_converged(this, iter, residual)
Check for convergence.
subroutine krylov_set_pc(this, m)
Setup a Krylov solver's preconditioner.
subroutine krylov_monitor_stop(this)
Monitor stop.
subroutine krylov_monitor_print_result(this, step)
Print the Krylov solver's result.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
integer, parameter neko_bcknd_device
integer, parameter, public c_rp
integer, parameter, public rp
Global precision used in computations.
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
Base type for a matrix-vector product providing .
A list of allocatable `bc_t`. Follows the standard interface of lists.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Defines a canonical Krylov preconditioner for accelerators.
Defines a canonical Krylov preconditioner.
Type for storing initial and final residuals in a Krylov solver.
Base abstract type for a canonical Krylov method, solving .
Defines a canonical Krylov preconditioner.