49 use json_module,
only : json_file
62 character(len=18) :: name =
""
66 real(kind=
rp) :: res_start
68 real(kind=
rp) :: res_final
70 logical :: converged = .false.
78 class(
pc_t),
pointer :: m => null()
79 real(kind=
rp) :: rel_tol
80 real(kind=
rp) :: abs_tol
82 class(
pc_t),
allocatable :: m_ident
125 class(
ksp_t),
target,
intent(inout) :: this
126 integer,
intent(in) :: max_iter
127 class(
pc_t),
optional,
intent(in),
target :: M
128 integer,
intent(in) :: n
129 real(kind=
rp),
optional,
intent(in) :: rel_tol
130 real(kind=
rp),
optional,
intent(in) :: abs_tol
131 logical,
optional,
intent(in) :: monitor
145 function ksp_method(this, Ax, x, f, n, coef, bc_projector, gs_h, niter) &
156 class(
ksp_t),
intent(inout) :: this
157 class(
ax_t),
intent(in) :: ax
158 type(
field_t),
intent(inout) :: x
159 integer,
intent(in) :: n
160 real(kind=
rp),
dimension(n),
intent(in) :: f
161 type(
coef_t),
intent(inout) :: coef
163 type(
gs_t),
intent(inout) :: gs_h
164 integer,
optional,
intent(in) :: niter
184 n, coef, bc_projector, gs_h, niter)
result(ksp_results)
194 class(
ksp_t),
intent(inout) :: this
195 class(
ax_t),
intent(in) :: ax
196 type(
field_t),
intent(inout) :: x
197 type(
field_t),
intent(inout) :: y
198 type(
field_t),
intent(inout) :: z
199 integer,
intent(in) :: n
200 real(kind=
rp),
dimension(n),
intent(in) :: fx
201 real(kind=
rp),
dimension(n),
intent(in) :: fy
202 real(kind=
rp),
dimension(n),
intent(in) :: fz
203 type(
coef_t),
intent(inout) :: coef
205 type(
gs_t),
intent(inout) :: gs_h
206 integer,
optional,
intent(in) :: niter
215 class(
ksp_t),
intent(inout) :: this
230 module subroutine krylov_solver_factory_components(object, n, type_name, &
231 max_iter, abstol, m, monitor)
232 class(ksp_t),
allocatable,
intent(inout) :: object
233 integer,
intent(in),
value :: n
234 character(len=*),
intent(in) :: type_name
235 integer,
intent(in) :: max_iter
236 real(kind=
rp),
optional :: abstol
237 class(pc_t),
optional,
intent(in),
target :: M
238 logical,
optional,
intent(in) :: monitor
239 end subroutine krylov_solver_factory_components
247 module subroutine krylov_solver_factory_json(object, n, json, m)
248 class(ksp_t),
allocatable,
intent(inout) :: object
249 integer,
intent(in),
value :: n
250 type(json_file),
intent(inout) :: json
251 class(pc_t),
optional,
intent(in),
target :: M
252 end subroutine krylov_solver_factory_json
253 end interface krylov_solver_factory
259 module subroutine krylov_solver_allocator(object, type_name)
260 class(ksp_t),
allocatable,
intent(inout) :: object
261 character(len=*),
intent(in) :: type_name
262 end subroutine krylov_solver_allocator
273 subroutine krylov_allocate(obj)
275 class(ksp_t),
allocatable,
intent(inout) :: obj
276 end subroutine krylov_allocate
281 module subroutine register_krylov(type_name, allocator)
282 character(len=*),
intent(in) :: type_name
283 procedure(krylov_allocate),
pointer,
intent(in) :: allocator
284 end subroutine register_krylov
288 type krylov_allocator_entry
289 character(len=NEKO_TYPENAME_LEN) :: type_name
290 procedure(krylov_allocate),
pointer,
nopass :: allocator
291 end type krylov_allocator_entry
294 type(krylov_allocator_entry),
allocatable :: krylov_registry(:)
297 integer :: krylov_registry_size = 0
299 public :: krylov_solver_factory, krylov_solver_allocator, register_krylov, &
308 subroutine krylov_init(this, max_iter, rel_tol, abs_tol, M, monitor)
309 class(ksp_t),
target,
intent(inout) :: this
310 integer,
intent(in) :: max_iter
311 real(kind=
rp),
optional,
intent(in) :: rel_tol
312 real(kind=
rp),
optional,
intent(in) :: abs_tol
313 class(
pc_t),
optional,
target,
intent(in) :: m
314 logical,
optional,
intent(in) :: monitor
316 call krylov_free(this)
318 if (
present(rel_tol))
then
319 this%rel_tol = rel_tol
321 this%rel_tol = ksp_rel_tol
324 if (
present(abs_tol))
then
325 this%abs_tol = abs_tol
327 this%abs_tol = ksp_abs_tol
330 this%max_iter = max_iter
335 if (.not.
associated(this%M))
then
339 allocate(
ident_t::this%M_ident)
341 this%M => this%M_ident
345 if (
present(monitor))
then
346 this%monitor = monitor
348 this%monitor = .false.
351 end subroutine krylov_init
360 subroutine krylov_init_from_json(this, n, json, M)
361 class(ksp_t),
target,
intent(inout) :: this
362 integer,
intent(in) :: n
363 type(json_file),
intent(inout) :: json
364 class(
pc_t),
optional,
intent(in),
target :: M
366 real(kind=
rp) :: abs_tol
374 call this%init(n, max_iter, m = m, abs_tol = abs_tol, monitor = monitor)
376 end subroutine krylov_init_from_json
379 subroutine krylov_free(this)
380 class(ksp_t),
intent(inout) :: this
384 end subroutine krylov_free
388 subroutine krylov_set_pc(this, M)
389 class(ksp_t),
intent(inout) :: this
390 class(
pc_t),
target,
intent(in) :: M
392 if (
associated(this%M))
then
393 select type (pc => this%M)
397 call neko_error(
'Preconditioner already defined')
403 end subroutine krylov_set_pc
406 subroutine krylov_monitor_start(this, name)
407 class(ksp_t),
intent(in) :: this
408 character(len=*) :: name
409 character(len=LOG_SIZE) :: log_buf
411 if (this%monitor)
then
412 write(log_buf,
'(A)')
'Krylov monitor (' // trim(name) //
')'
413 call neko_log%section(trim(log_buf))
416 write(log_buf,
'(A)')
' Iter. Residual'
418 write(log_buf,
'(A)')
'-------------------------'
421 end subroutine krylov_monitor_start
424 subroutine krylov_monitor_stop(this)
425 class(ksp_t),
intent(in) :: this
427 if (this%monitor)
then
432 end subroutine krylov_monitor_stop
436 subroutine krylov_monitor_iter(this, iter, rnorm)
437 class(ksp_t),
intent(in) :: this
438 integer,
intent(in) :: iter
439 real(kind=
rp),
intent(in) :: rnorm
440 character(len=LOG_SIZE) :: log_buf
442 if (this%monitor)
then
443 write(log_buf,
'(I6,E18.9)') iter, rnorm
447 end subroutine krylov_monitor_iter
457 pure function krylov_is_converged(this, iter, residual)
result(converged)
458 class(ksp_t),
intent(in) :: this
459 integer,
intent(in) :: iter
460 real(kind=
rp),
intent(in) :: residual
464 if (iter .ge. this%max_iter) converged = .false.
465 if (residual .gt. this%abs_tol) converged = .false.
467 end function krylov_is_converged
470 subroutine krylov_monitor_print_header(this)
471 class(ksp_monitor_t),
intent(in) :: this
472 character(len=LOG_SIZE) :: log_buf
474 write(log_buf,
'(A10,2x,A3,(A5,13x),1x,A6,3x,A15,3x,A15)') &
475 'KSP solver',
' | ',
'Field:',
'Iters:', &
476 'Start residual:',
'Final residual:'
479 end subroutine krylov_monitor_print_header
482 subroutine krylov_monitor_print_result(this, step)
483 class(ksp_monitor_t),
intent(in) :: this
484 integer,
intent(in) :: step
485 character(len=LOG_SIZE) :: log_buf
486 character(len=12) :: step_str
487 character(len=:),
allocatable :: output_format
489 if (this%name .eq.
"")
call neko_error(
'Krylov solver name is not set')
492 output_format =
'(A12,A3,A18,1x,I6,3x,E15.9,3x,E15.9)'
493 write(step_str,
'(I12)') step
494 step_str = adjustl(step_str)
496 write(log_buf, output_format) &
497 step_str,
' | ' , adjustl(this%name), this%iter, &
498 this%res_start, this%res_final
501 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)
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Factory for Krylov solvers. Both creates and initializes the object, either from its parameters or fr...
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)
Utilities for retrieving parameters from the case files.
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.
subroutine krylov_init_from_json(this, n, json, m)
Constructor from a JSON solver block. Reads max_iterations (default KSP_MAX_ITER),...
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.
integer, parameter, public neko_typename_len
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.