59 character(len=18) :: name =
""
63 real(kind=
rp) :: res_start
65 real(kind=
rp) :: res_final
67 logical :: converged = .false.
75 class(
pc_t),
pointer :: m => null()
76 real(kind=
rp) :: rel_tol
77 real(kind=
rp) :: abs_tol
79 class(
pc_t),
allocatable :: m_ident
117 class(
ksp_t),
target,
intent(inout) :: this
118 integer,
intent(in) :: max_iter
119 class(
pc_t),
optional,
intent(in),
target :: M
120 integer,
intent(in) :: n
121 real(kind=
rp),
optional,
intent(in) :: rel_tol
122 real(kind=
rp),
optional,
intent(in) :: abs_tol
123 logical,
optional,
intent(in) :: monitor
137 function ksp_method(this, Ax, x, f, n, coef, bc_projector, gs_h, niter) &
148 class(
ksp_t),
intent(inout) :: this
149 class(
ax_t),
intent(in) :: ax
150 type(
field_t),
intent(inout) :: x
151 integer,
intent(in) :: n
152 real(kind=
rp),
dimension(n),
intent(in) :: f
153 type(
coef_t),
intent(inout) :: coef
155 type(
gs_t),
intent(inout) :: gs_h
156 integer,
optional,
intent(in) :: niter
176 n, coef, bc_projector, gs_h, niter)
result(ksp_results)
186 class(
ksp_t),
intent(inout) :: this
187 class(
ax_t),
intent(in) :: ax
188 type(
field_t),
intent(inout) :: x
189 type(
field_t),
intent(inout) :: y
190 type(
field_t),
intent(inout) :: z
191 integer,
intent(in) :: n
192 real(kind=
rp),
dimension(n),
intent(in) :: fx
193 real(kind=
rp),
dimension(n),
intent(in) :: fy
194 real(kind=
rp),
dimension(n),
intent(in) :: fz
195 type(
coef_t),
intent(inout) :: coef
197 type(
gs_t),
intent(inout) :: gs_h
198 integer,
optional,
intent(in) :: niter
207 class(
ksp_t),
intent(inout) :: this
220 module subroutine krylov_solver_factory(object, n, type_name, &
221 max_iter, abstol, m, monitor)
222 class(ksp_t),
allocatable,
intent(inout) :: object
223 integer,
intent(in),
value :: n
224 character(len=*),
intent(in) :: type_name
225 integer,
intent(in) :: max_iter
226 real(kind=
rp),
optional :: abstol
227 class(
pc_t),
optional,
intent(in),
target :: m
228 logical,
optional,
intent(in) :: monitor
229 end subroutine krylov_solver_factory
237 module subroutine krylov_solver_allocator(object, type_name)
238 class(ksp_t),
allocatable,
intent(inout) :: object
239 character(len=*),
intent(in) :: type_name
240 end subroutine krylov_solver_allocator
251 subroutine krylov_allocate(obj)
253 class(ksp_t),
allocatable,
intent(inout) :: obj
254 end subroutine krylov_allocate
259 module subroutine register_krylov(type_name, allocator)
260 character(len=*),
intent(in) :: type_name
261 procedure(krylov_allocate),
pointer,
intent(in) :: allocator
262 end subroutine register_krylov
266 type krylov_allocator_entry
267 character(len=20) :: type_name
268 procedure(krylov_allocate),
pointer,
nopass :: allocator
269 end type krylov_allocator_entry
272 type(krylov_allocator_entry),
allocatable :: krylov_registry(:)
275 integer :: krylov_registry_size = 0
277 public :: krylov_solver_factory, krylov_solver_allocator, register_krylov, &
286 subroutine krylov_init(this, max_iter, rel_tol, abs_tol, M, monitor)
287 class(ksp_t),
target,
intent(inout) :: this
288 integer,
intent(in) :: max_iter
289 real(kind=
rp),
optional,
intent(in) :: rel_tol
290 real(kind=
rp),
optional,
intent(in) :: abs_tol
291 class(
pc_t),
optional,
target,
intent(in) :: m
292 logical,
optional,
intent(in) :: monitor
294 call krylov_free(this)
296 if (
present(rel_tol))
then
297 this%rel_tol = rel_tol
299 this%rel_tol = ksp_rel_tol
302 if (
present(abs_tol))
then
303 this%abs_tol = abs_tol
305 this%abs_tol = ksp_abs_tol
308 this%max_iter = max_iter
313 if (.not.
associated(this%M))
then
317 allocate(
ident_t::this%M_ident)
319 this%M => this%M_ident
323 if (
present(monitor))
then
324 this%monitor = monitor
326 this%monitor = .false.
329 end subroutine krylov_init
332 subroutine krylov_free(this)
333 class(ksp_t),
intent(inout) :: this
337 end subroutine krylov_free
341 subroutine krylov_set_pc(this, M)
342 class(ksp_t),
intent(inout) :: this
343 class(
pc_t),
target,
intent(in) :: M
345 if (
associated(this%M))
then
346 select type (pc => this%M)
350 call neko_error(
'Preconditioner already defined')
356 end subroutine krylov_set_pc
359 subroutine krylov_monitor_start(this, name)
360 class(ksp_t),
intent(in) :: this
361 character(len=*) :: name
362 character(len=LOG_SIZE) :: log_buf
364 if (this%monitor)
then
365 write(log_buf,
'(A)')
'Krylov monitor (' // trim(name) //
')'
366 call neko_log%section(trim(log_buf))
369 write(log_buf,
'(A)')
' Iter. Residual'
371 write(log_buf,
'(A)')
'-------------------------'
374 end subroutine krylov_monitor_start
377 subroutine krylov_monitor_stop(this)
378 class(ksp_t),
intent(in) :: this
380 if (this%monitor)
then
385 end subroutine krylov_monitor_stop
389 subroutine krylov_monitor_iter(this, iter, rnorm)
390 class(ksp_t),
intent(in) :: this
391 integer,
intent(in) :: iter
392 real(kind=
rp),
intent(in) :: rnorm
393 character(len=LOG_SIZE) :: log_buf
395 if (this%monitor)
then
396 write(log_buf,
'(I6,E18.9)') iter, rnorm
400 end subroutine krylov_monitor_iter
410 pure function krylov_is_converged(this, iter, residual)
result(converged)
411 class(ksp_t),
intent(in) :: this
412 integer,
intent(in) :: iter
413 real(kind=
rp),
intent(in) :: residual
417 if (iter .ge. this%max_iter) converged = .false.
418 if (residual .gt. this%abs_tol) converged = .false.
420 end function krylov_is_converged
423 subroutine krylov_monitor_print_header(this)
424 class(ksp_monitor_t),
intent(in) :: this
425 character(len=LOG_SIZE) :: log_buf
427 write(log_buf,
'(A10,2x,A3,(A5,13x),1x,A6,3x,A15,3x,A15)') &
428 'KSP solver',
' | ',
'Field:',
'Iters:', &
429 'Start residual:',
'Final residual:'
432 end subroutine krylov_monitor_print_header
435 subroutine krylov_monitor_print_result(this, step)
436 class(ksp_monitor_t),
intent(in) :: this
437 integer,
intent(in) :: step
438 character(len=LOG_SIZE) :: log_buf
439 character(len=12) :: step_str
440 character(len=:),
allocatable :: output_format
442 if (this%name .eq.
"")
call neko_error(
'Krylov solver name is not set')
445 output_format =
'(A12,A3,A18,1x,I6,3x,E15.9,3x,E15.9)'
446 write(step_str,
'(I12)') step
447 step_str = adjustl(step_str)
449 write(log_buf, output_format) &
450 step_str,
' | ' , adjustl(this%name), this%iter, &
451 this%res_start, this%res_final
454 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.
Implements scalar_projector_t.
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
Implements boundary condition projectors for vector fields. Two types concrete types are provided: se...
Base type for a matrix-vector product providing .
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.
Projector for scalar boundary conditions.
Abstract type for resolving vector boundary conditions.