2 #include <petsc/finclude/petscksp.h>
28 class(petscmatrixtype),
pointer :: matrix => null()
29 mat,
pointer :: mat_petsc => null()
32 logical(LGP) :: use_ims_pc
33 logical(LGP) :: use_ims_cnvgopt
38 character(len=LENSOLUTIONNAME + 1) :: option_prefix
62 character(len=LENSOLUTIONNAME) :: sln_name
65 character(len=LINELENGTH) :: errmsg
67 allocate (petsc_solver)
68 allocate (petsc_solver%petsc_ctx)
69 petsc_solver%option_prefix =
""
71 petsc_solver%option_prefix = trim(sln_name)//
"_"
74 solver => petsc_solver
75 solver%name = sln_name
78 write (errmsg,
'(a,a)')
'PETSc solver not supported for run mode: ', &
93 this%linear_settings => linear_settings
95 call this%print_petsc_version()
97 this%mat_petsc => null()
98 select type (pm => matrix)
99 class is (petscmatrixtype)
101 this%mat_petsc => pm%mat
104 call this%petsc_check_settings(linear_settings)
106 this%use_ims_cnvgopt = .true.
107 this%use_ims_pc = .true.
108 allocate (this%pc_context)
109 call this%pc_context%create(this%matrix, linear_settings)
111 if (linear_settings%ilinmeth ==
cg_method)
then
112 this%ksp_type = kspcg
114 this%ksp_type = kspbcgs
118 call this%get_options_mf6()
121 call this%create_ksp()
124 call this%create_convergence_check(convergence_summary)
132 character(len=LINELENGTH) :: warnmsg, errmsg
135 if (linear_settings%ilinmeth /=
cg_method .and. &
137 write (errmsg,
'(a,a)')
'PETSc: unknown linear solver method in ', &
143 if (linear_settings%iord > 0)
then
144 linear_settings%iord = 0
145 write (warnmsg,
'(a)')
'PETSc: IMS reordering not supported'
148 if (linear_settings%iscl > 0)
then
149 linear_settings%iscl = 0
150 write (warnmsg,
'(a)')
'PETSc: IMS matrix scaling not supported'
153 if (linear_settings%north > 0)
then
154 linear_settings%north = 0
155 write (warnmsg,
'(a)')
'PETSc: IMS orthogonalization not supported'
166 petscerrorcode :: ierr
167 petscint :: major, minor, subminor, release
168 character(len=128) :: petsc_version, release_str
170 call petscgetversionnumber(major, minor, subminor, release, ierr)
173 if (release == 1)
then
174 release_str =
"(release)"
176 release_str =
"(unofficial)"
178 write (petsc_version,
'(i0,a,i0,a,i0,a,a)') &
179 major,
".", minor,
".", subminor,
" ", trim(release_str)
180 write (
iout,
'(/,1x,4a,/)')
"PETSc Linear Solver will be used for ", &
181 trim(this%name),
": version ", petsc_version
190 petscerrorcode :: ierr
191 logical(LGP) :: found
192 logical(LGP) :: use_petsc_pc, use_petsc_cnvg
194 use_petsc_pc = .false.
195 call petscoptionsgetbool(petsc_null_options, trim(this%option_prefix), &
196 '-use_petsc_pc', use_petsc_pc, found, ierr)
198 this%use_ims_pc = .not. use_petsc_pc
200 use_petsc_cnvg = .false.
201 call petscoptionsgetbool(petsc_null_options, trim(this%option_prefix), &
202 '-use_petsc_cnvg', use_petsc_cnvg, found, ierr)
204 this%use_ims_cnvgopt = .not. use_petsc_cnvg
213 petscerrorcode :: ierr
216 call kspcreate(petsc_comm_world, this%ksp_petsc, ierr)
220 call kspsetoptionsprefix(this%ksp_petsc, trim(this%option_prefix), ierr)
223 call kspsetoperators(this%ksp_petsc, this%mat_petsc, this%mat_petsc, ierr)
226 call kspsetinitialguessnonzero(this%ksp_petsc, .true., ierr)
229 call kspsettype(this%ksp_petsc, this%ksp_type, ierr)
232 if (this%use_ims_pc)
then
233 call this%set_ims_pc()
235 call dev_feature(
'PETSc preconditioning is under development, install the &
236 &nightly build or compile from source with IDEVELOPMODE = 1.')
239 call kspgetpc(this%ksp_petsc, pc, ierr)
241 call pcsetfromoptions(pc, ierr)
245 call kspseterrorifnotconverged(this%ksp_petsc, .false., ierr)
250 call kspsetfromoptions(this%ksp_petsc, ierr)
253 call kspsetup(this%ksp_petsc, ierr)
264 ksp,
dimension(1) :: sub_ksp
265 petscint :: n_local, n_first
266 petscerrorcode :: ierr
268 call kspgetpc(this%ksp_petsc, pc, ierr)
270 call pcsettype(pc, pcbjacobi, ierr)
272 call pcsetup(pc, ierr)
274 call pcbjacobigetsubksp(pc, n_local, n_first, sub_ksp, ierr)
276 call kspgetpc(sub_ksp(1), sub_pc, ierr)
278 call pcsettype(sub_pc, pcshell, ierr)
284 call pcshellsetcontext(sub_pc, this%pc_context, ierr)
296 petscerrorcode :: ierr
298 call this%petsc_ctx%create(this%mat_petsc, this%linear_settings, &
301 if (.not. this%use_ims_cnvgopt)
then
303 call dev_feature(
'Using PETSc convergence is under development, install &
304 &the nightly build or compile from source with IDEVELOPMODE = 1.')
306 this%petsc_ctx, petsc_null_function, ierr)
310 this%petsc_ctx, petsc_null_function, ierr)
318 integer(I4B) :: kiter
323 petscerrorcode :: ierr
325 kspconvergedreason :: cnvg_reason
327 character(len=LINELENGTH) :: errmsg
341 this%iteration_number = 0
342 this%is_converged = 0
344 this%petsc_ctx%cnvg_summary%iter_cnt = 0
348 call this%matrix%update()
349 call kspsolve(this%ksp_petsc, rhs_petsc%vec_impl, x_petsc%vec_impl, ierr)
352 call kspgetiterationnumber(this%ksp_petsc, it_number, ierr)
354 this%iteration_number = it_number
356 call kspgetconvergedreason(this%ksp_petsc, cnvg_reason, ierr)
358 if (cnvg_reason > 0)
then
359 if (this%petsc_ctx%icnvg_ims == -1)
then
361 this%is_converged = 0
364 this%is_converged = 1
368 if (cnvg_reason < 0 .and. cnvg_reason /= ksp_diverged_its)
then
369 write (errmsg,
'(1x,3a,i0)')
"PETSc convergence failure in ", &
370 trim(this%name),
": ", cnvg_reason
379 character(len=128) :: ksp_str, pc_str, subpc_str, &
380 dvclose_str, rclose_str, relax_str, dtol_str
381 character(len=128) :: ksp_logfile
384 petscviewer :: ksp_viewer
386 if (this%use_ims_pc)
then
387 call kspgettype(this%ksp_petsc, ksp_str, ierr)
389 call kspgetpc(this%ksp_petsc, pc, ierr)
391 call pcgettype(pc, pc_str, ierr)
393 subpc_str = this%pc_context%ims_pc_type
395 write (dvclose_str,
'(e15.5)') this%linear_settings%dvclose
396 write (rclose_str,
'(e15.5)') this%linear_settings%rclose
397 write (relax_str,
'(e15.5)') this%linear_settings%relax
398 write (dtol_str,
'(e15.5)') this%linear_settings%droptol
400 write (
iout,
'(/,1x,a)')
"PETSc linear solver settings: "
401 write (
iout,
'(1x,a)') repeat(
'-', 66)
402 write (
iout,
'(1x,a,a)')
"Linear acceleration method: ", trim(ksp_str)
403 write (
iout,
'(1x,a,a)')
"Preconditioner type: ", trim(pc_str)
404 write (
iout,
'(1x,a,a)')
"Sub-preconditioner type: ", trim(subpc_str)
405 write (
iout,
'(1x,a,i0)')
"Maximum nr. of iterations: ", &
406 this%linear_settings%iter1
407 write (
iout,
'(1x,a,a)') &
408 "Dep. var. closure criterion: ", trim(adjustl(dvclose_str))
409 write (
iout,
'(1x,a,a)') &
410 "Residual closure criterion: ", trim(adjustl(rclose_str))
411 if (this%use_ims_cnvgopt)
then
412 write (
iout,
'(1x,a,i0)') &
413 "Residual convergence option: ", this%linear_settings%icnvgopt
415 write (
iout,
'(1x,a)') &
416 "Residual convergence option: PETSc L2 norm"
418 write (
iout,
'(1x,a,a)') &
419 "Relaxation factor MILU(T): ", trim(adjustl(relax_str))
420 write (
iout,
'(1x,a,i0)') &
421 "Fill level in factorization: ", this%linear_settings%level
422 write (
iout,
'(1x,a,a,/)') &
423 "Drop tolerance level fill: ", trim(adjustl(dtol_str))
425 ksp_logfile = trim(this%option_prefix)//
"ksp_logview.txt"
426 write (
iout,
'(/,1x,a)')
"PETSc linear solver settings from .petscrc: "
427 write (
iout,
'(1x,a)') repeat(
'-', 66)
428 write (
iout,
'(1x,2a)')
"see ", trim(ksp_logfile)
431 call petscviewerasciiopen(petsc_comm_world, ksp_logfile, ksp_viewer, ierr);
433 call petscviewerpushformat(ksp_viewer, petsc_viewer_ascii_info_detail, ierr)
435 call kspview(this%ksp_petsc, ksp_viewer, ierr)
437 call petscviewerdestroy(ksp_viewer, ierr)
446 petscerrorcode :: ierr
448 call kspdestroy(this%ksp_petsc, ierr)
452 call this%petsc_ctx%destroy()
453 deallocate (this%petsc_ctx)
455 call this%pc_context%destroy()
456 deallocate (this%pc_context)
464 class(petscmatrixtype),
pointer :: petsc_matrix
466 allocate (petsc_matrix)
467 matrix => petsc_matrix
475 character(len=*) :: vec_name
476 integer(I4B) :: kiter
478 petscviewer :: viewer
479 character(len=24) :: filename
480 petscerrorcode :: ierr
482 write (filename,
'(2a,i0,a,i0,a,i0,a)') vec_name,
'_',
nper, &
483 '_',
kstp,
'_', kiter,
'.txt'
484 call petscviewerasciiopen(petsc_comm_world, filename, viewer, ierr)
486 call vecview(vec%vec_impl, viewer, ierr)
488 call petscviewerdestroy(viewer, ierr)
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
integer(i4b), parameter lensolutionname
maximum length of the solution name
real(dp), parameter dzero
real constant zero
subroutine destroy(this)
Cleanup.
Disable development features in release mode.
subroutine, public dev_feature(errmsg, iunit)
Terminate if in release mode (guard development features)
This module contains the IMS linear accelerator subroutines.
real(dp) function ims_base_epfact(icnvgopt, kstp)
Function returning EPFACT.
integer(i4b), parameter, public cg_method
integer(i4b), parameter, public bcgs_method
This module defines variable data types.
type(listtype), public basesolutionlist
subroutine, public petsc_cnvg_check_internal(ksp, n, rnorm_L2, flag, context, ierr)
Routine to check the convergence following the configuration.
subroutine, public petsc_cnvg_check(ksp, n, rnorm_L2, flag, context, ierr)
Routine to check the convergence following the configuration.
subroutine, public pcshell_setup(pc, ierr)
Set up the custom preconditioner.
subroutine, public pcshell_apply(pc, x, y, ierr)
Apply shell preconditioner.
class(linearsolverbasetype) function, pointer, public create_petsc_solver(sln_name)
Create a PETSc solver object.
subroutine print_vec(this, vec, vec_name, kiter)
subroutine petsc_check_settings(this, linear_settings)
subroutine petsc_solve(this, kiter, rhs, x, cnvg_summary)
subroutine petsc_initialize(this, matrix, linear_settings, convergence_summary)
Initialize PETSc KSP solver with.
subroutine set_ims_pc(this)
Set up a custom preconditioner following the ones.
subroutine print_petsc_version(this)
Print PETSc version string from shared lib.
class(matrixbasetype) function, pointer petsc_create_matrix(this)
subroutine get_options_mf6(this)
Get the MODFLOW specific options from the PETSc database.
subroutine create_convergence_check(this, convergence_summary)
Create and assign a custom convergence.
subroutine petsc_destroy(this)
subroutine petsc_print_summary(this)
subroutine create_ksp(this)
Create the PETSc KSP object.
This module contains simulation methods.
subroutine, public store_warning(msg, substring)
Store warning message.
subroutine, public store_error(msg, terminate)
Store an error message.
This module contains simulation variables.
character(len=linelength) simulation_mode
integer(i4b) iout
file unit number for simulation output
integer(i4b), pointer, public kstp
current time step number
integer(i4b), pointer, public nper
number of stress period
This structure stores the generic convergence info for a solution.
Abstract type for linear solver.
x vector from the previous iteration