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)
then
369 if (cnvg_reason == ksp_diverged_breakdown .or. &
370 cnvg_reason == ksp_diverged_its)
then
373 this%is_converged = 0
376 write (errmsg,
'(1x,3a,i0)')
"PETSc convergence failure in ", &
377 trim(this%name),
": ", cnvg_reason
387 character(len=128) :: ksp_str, pc_str, subpc_str, &
388 dvclose_str, rclose_str, relax_str, dtol_str
389 character(len=128) :: ksp_logfile
392 petscviewer :: ksp_viewer
394 if (this%use_ims_pc)
then
395 call kspgettype(this%ksp_petsc, ksp_str, ierr)
397 call kspgetpc(this%ksp_petsc, pc, ierr)
399 call pcgettype(pc, pc_str, ierr)
401 subpc_str = this%pc_context%ims_pc_type
403 write (dvclose_str,
'(e15.5)') this%linear_settings%dvclose
404 write (rclose_str,
'(e15.5)') this%linear_settings%rclose
405 write (relax_str,
'(e15.5)') this%linear_settings%relax
406 write (dtol_str,
'(e15.5)') this%linear_settings%droptol
408 write (
iout,
'(/,1x,a)')
"PETSc linear solver settings: "
409 write (
iout,
'(1x,a)') repeat(
'-', 66)
410 write (
iout,
'(1x,a,a)')
"Linear acceleration method: ", trim(ksp_str)
411 write (
iout,
'(1x,a,a)')
"Preconditioner type: ", trim(pc_str)
412 write (
iout,
'(1x,a,a)')
"Sub-preconditioner type: ", trim(subpc_str)
413 write (
iout,
'(1x,a,i0)')
"Maximum nr. of iterations: ", &
414 this%linear_settings%iter1
415 write (
iout,
'(1x,a,a)') &
416 "Dep. var. closure criterion: ", trim(adjustl(dvclose_str))
417 write (
iout,
'(1x,a,a)') &
418 "Residual closure criterion: ", trim(adjustl(rclose_str))
419 if (this%use_ims_cnvgopt)
then
420 write (
iout,
'(1x,a,i0)') &
421 "Residual convergence option: ", this%linear_settings%icnvgopt
423 write (
iout,
'(1x,a)') &
424 "Residual convergence option: PETSc L2 norm"
426 write (
iout,
'(1x,a,a)') &
427 "Relaxation factor MILU(T): ", trim(adjustl(relax_str))
428 write (
iout,
'(1x,a,i0)') &
429 "Fill level in factorization: ", this%linear_settings%level
430 write (
iout,
'(1x,a,a,/)') &
431 "Drop tolerance level fill: ", trim(adjustl(dtol_str))
433 ksp_logfile = trim(this%option_prefix)//
"ksp_logview.txt"
434 write (
iout,
'(/,1x,a)')
"PETSc linear solver settings from .petscrc: "
435 write (
iout,
'(1x,a)') repeat(
'-', 66)
436 write (
iout,
'(1x,2a)')
"see ", trim(ksp_logfile)
439 call petscviewerasciiopen(petsc_comm_world, ksp_logfile, ksp_viewer, ierr);
441 call petscviewerpushformat(ksp_viewer, petsc_viewer_ascii_info_detail, ierr)
443 call kspview(this%ksp_petsc, ksp_viewer, ierr)
445 call petscviewerdestroy(ksp_viewer, ierr)
454 petscerrorcode :: ierr
456 call kspdestroy(this%ksp_petsc, ierr)
460 call this%petsc_ctx%destroy()
461 deallocate (this%petsc_ctx)
463 call this%pc_context%destroy()
464 deallocate (this%pc_context)
472 class(petscmatrixtype),
pointer :: petsc_matrix
474 allocate (petsc_matrix)
475 matrix => petsc_matrix
483 character(len=*) :: vec_name
484 integer(I4B) :: kiter
486 petscviewer :: viewer
487 character(len=24) :: filename
488 petscerrorcode :: ierr
490 write (filename,
'(2a,i0,a,i0,a,i0,a)') vec_name,
'_',
nper, &
491 '_',
kstp,
'_', kiter,
'.txt'
492 call petscviewerasciiopen(petsc_comm_world, filename, viewer, ierr)
494 call vecview(vec%vec_impl, viewer, ierr)
496 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