2 #include <petsc/finclude/petscksp.h>
27 class(petscmatrixtype),
pointer :: matrix => null()
28 mat,
pointer :: mat_petsc => null()
31 logical(LGP) :: use_ims_pc
32 logical(LGP) :: use_ims_cnvgopt
61 character(len=LENSOLUTIONNAME) :: sln_name
64 character(len=LINELENGTH) :: errmsg
66 allocate (petsc_solver)
67 allocate (petsc_solver%petsc_ctx)
69 solver => petsc_solver
70 solver%name = sln_name
73 write (errmsg,
'(a,a)')
'PETSc solver not supported for run mode: ', &
88 this%linear_settings => linear_settings
90 call this%print_petsc_version()
92 this%mat_petsc => null()
93 select type (pm => matrix)
94 class is (petscmatrixtype)
96 this%mat_petsc => pm%mat
99 call this%petsc_check_settings(linear_settings)
101 this%use_ims_cnvgopt = .true.
102 this%use_ims_pc = .true.
103 allocate (this%pc_context)
104 call this%pc_context%create(this%matrix, linear_settings)
106 if (linear_settings%ilinmeth ==
cg_method)
then
107 this%ksp_type = kspcg
109 this%ksp_type = kspbcgs
113 call this%get_options_mf6()
116 call this%create_ksp()
119 call this%create_convergence_check(convergence_summary)
127 character(len=LINELENGTH) :: warnmsg, errmsg
130 if (linear_settings%ilinmeth /=
cg_method .and. &
132 write (errmsg,
'(a,a)')
'PETSc: unknown linear solver method in ', &
138 if (linear_settings%iord > 0)
then
139 linear_settings%iord = 0
140 write (warnmsg,
'(a)')
'PETSc: IMS reordering not supported'
143 if (linear_settings%iscl > 0)
then
144 linear_settings%iscl = 0
145 write (warnmsg,
'(a)')
'PETSc: IMS matrix scaling not supported'
148 if (linear_settings%north > 0)
then
149 linear_settings%north = 0
150 write (warnmsg,
'(a)')
'PETSc: IMS orthogonalization not supported'
161 petscerrorcode :: ierr
162 petscint :: major, minor, subminor, release
163 character(len=128) :: petsc_version, release_str
165 call petscgetversionnumber(major, minor, subminor, release, ierr)
168 if (release == 1)
then
169 release_str =
"(release)"
171 release_str =
"(unofficial)"
173 write (petsc_version,
'(i0,a,i0,a,i0,a,a)') &
174 major,
".", minor,
".", subminor,
" ", trim(release_str)
175 write (
iout,
'(/,1x,4a,/)')
"PETSc Linear Solver will be used for ", &
176 trim(this%name),
": version ", petsc_version
185 petscerrorcode :: ierr
186 logical(LGP) :: found
187 logical(LGP) :: use_petsc_pc, use_petsc_cnvg
189 use_petsc_pc = .false.
190 call petscoptionsgetbool(petsc_null_options, petsc_null_character, &
191 '-use_petsc_pc', use_petsc_pc, found, ierr)
193 this%use_ims_pc = .not. use_petsc_pc
195 use_petsc_cnvg = .false.
196 call petscoptionsgetbool(petsc_null_options, petsc_null_character, &
197 '-use_petsc_cnvg', use_petsc_cnvg, found, ierr)
199 this%use_ims_cnvgopt = .not. use_petsc_cnvg
208 petscerrorcode :: ierr
211 call kspcreate(petsc_comm_world, this%ksp_petsc, ierr)
214 call kspsetoperators(this%ksp_petsc, this%mat_petsc, this%mat_petsc, ierr)
217 call kspsetinitialguessnonzero(this%ksp_petsc, .true., ierr)
220 call kspsettype(this%ksp_petsc, this%ksp_type, ierr)
223 if (this%use_ims_pc)
then
224 call this%set_ims_pc()
226 call dev_feature(
'PETSc preconditioning is under development, install the &
227 &nightly build or compile from source with IDEVELOPMODE = 1.')
230 call kspgetpc(this%ksp_petsc, pc, ierr)
232 call pcsetfromoptions(pc, ierr)
236 call kspseterrorifnotconverged(this%ksp_petsc, .false., ierr)
241 call kspsetfromoptions(this%ksp_petsc, ierr)
244 call kspsetup(this%ksp_petsc, ierr)
255 ksp,
dimension(1) :: sub_ksp
256 petscint :: n_local, n_first
257 petscerrorcode :: ierr
259 call kspgetpc(this%ksp_petsc, pc, ierr)
261 call pcsettype(pc, pcbjacobi, ierr)
263 call pcsetup(pc, ierr)
265 call pcbjacobigetsubksp(pc, n_local, n_first, sub_ksp, ierr)
267 call kspgetpc(sub_ksp(1), sub_pc, ierr)
269 call pcsettype(sub_pc, pcshell, ierr)
275 call pcshellsetcontext(sub_pc, this%pc_context, ierr)
287 petscerrorcode :: ierr
289 call this%petsc_ctx%create(this%mat_petsc, this%linear_settings, &
291 if (.not. this%use_ims_cnvgopt)
then
293 call dev_feature(
'Using PETSc convergence is under development, install &
294 &the nightly build or compile from source with IDEVELOPMODE = 1.')
295 this%petsc_ctx%icnvgopt = 100
299 this%petsc_ctx, petsc_null_function, ierr)
306 integer(I4B) :: kiter
311 petscerrorcode :: ierr
313 kspconvergedreason :: cnvg_reason
315 character(len=LINELENGTH) :: errmsg
329 this%iteration_number = 0
330 this%is_converged = 0
332 this%petsc_ctx%cnvg_summary%iter_cnt = 0
336 call this%matrix%update()
337 call kspsolve(this%ksp_petsc, rhs_petsc%vec_impl, x_petsc%vec_impl, ierr)
340 call kspgetiterationnumber(this%ksp_petsc, it_number, ierr)
342 this%iteration_number = it_number
344 call kspgetconvergedreason(this%ksp_petsc, cnvg_reason, ierr)
346 if (cnvg_reason > 0)
then
347 if (this%petsc_ctx%icnvg_ims == -1)
then
349 this%is_converged = 0
352 this%is_converged = 1
356 if (cnvg_reason < 0 .and. cnvg_reason /= ksp_diverged_its)
then
357 write (errmsg,
'(1x,3a,i0)')
"PETSc convergence failure in ", &
358 trim(this%name),
": ", cnvg_reason
367 character(len=128) :: ksp_str, pc_str, subpc_str, &
368 dvclose_str, rclose_str, relax_str, dtol_str
369 character(len=128) :: ksp_logfile
372 petscviewer :: ksp_viewer
374 if (this%use_ims_pc)
then
375 call kspgettype(this%ksp_petsc, ksp_str, ierr)
377 call kspgetpc(this%ksp_petsc, pc, ierr)
379 call pcgettype(pc, pc_str, ierr)
381 subpc_str = this%pc_context%ims_pc_type
383 write (dvclose_str,
'(e15.5)') this%linear_settings%dvclose
384 write (rclose_str,
'(e15.5)') this%linear_settings%rclose
385 write (relax_str,
'(e15.5)') this%linear_settings%relax
386 write (dtol_str,
'(e15.5)') this%linear_settings%droptol
388 write (
iout,
'(/,1x,a)')
"PETSc linear solver settings: "
389 write (
iout,
'(1x,a)') repeat(
'-', 66)
390 write (
iout,
'(1x,a,a)')
"Linear acceleration method: ", trim(ksp_str)
391 write (
iout,
'(1x,a,a)')
"Preconditioner type: ", trim(pc_str)
392 write (
iout,
'(1x,a,a)')
"Sub-preconditioner type: ", trim(subpc_str)
393 write (
iout,
'(1x,a,i0)')
"Maximum nr. of iterations: ", &
394 this%linear_settings%iter1
395 write (
iout,
'(1x,a,a)') &
396 "Dep. var. closure criterion: ", trim(adjustl(dvclose_str))
397 write (
iout,
'(1x,a,a)') &
398 "Residual closure criterion: ", trim(adjustl(rclose_str))
399 if (this%use_ims_cnvgopt)
then
400 write (
iout,
'(1x,a,i0)') &
401 "Residual convergence option: ", this%linear_settings%icnvgopt
403 write (
iout,
'(1x,a)') &
404 "Residual convergence option: PETSc L2 norm"
406 write (
iout,
'(1x,a,a)') &
407 "Relaxation factor MILU(T): ", trim(adjustl(relax_str))
408 write (
iout,
'(1x,a,i0)') &
409 "Fill level in factorization: ", this%linear_settings%level
410 write (
iout,
'(1x,a,a,/)') &
411 "Drop tolerance level fill: ", trim(adjustl(dtol_str))
413 ksp_logfile =
"ksp_logview.txt"
414 write (
iout,
'(/,1x,a)')
"PETSc linear solver settings from .petscrc: "
415 write (
iout,
'(1x,a)') repeat(
'-', 66)
416 write (
iout,
'(1x,2a)')
"see ", trim(ksp_logfile)
419 call petscviewerasciiopen(petsc_comm_world, ksp_logfile, ksp_viewer, ierr);
421 call petscviewerpushformat(ksp_viewer, petsc_viewer_ascii_info_detail, ierr)
423 call kspview(this%ksp_petsc, ksp_viewer, ierr)
425 call petscviewerdestroy(ksp_viewer, ierr)
434 petscerrorcode :: ierr
436 call kspdestroy(this%ksp_petsc, ierr)
440 call this%petsc_ctx%destroy()
441 deallocate (this%petsc_ctx)
443 call this%pc_context%destroy()
444 deallocate (this%pc_context)
452 class(petscmatrixtype),
pointer :: petsc_matrix
454 allocate (petsc_matrix)
455 matrix => petsc_matrix
463 character(len=*) :: vec_name
464 integer(I4B) :: kiter
466 petscviewer :: viewer
467 character(len=24) :: filename
468 petscerrorcode :: ierr
470 write (filename,
'(2a,i0,a,i0,a,i0,a)') vec_name,
'_',
nper, &
471 '_',
kstp,
'_', kiter,
'.txt'
472 call petscviewerasciiopen(petsc_comm_world, filename, viewer, ierr)
474 call vecview(vec%vec_impl, viewer, ierr)
476 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.
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