2 #include <petsc/finclude/petscksp.h>
26 class(petscmatrixtype),
pointer :: matrix => null()
27 mat,
pointer :: mat_petsc => null()
30 logical(LGP) :: use_ims_pc
62 character(len=LENSOLUTIONNAME) :: sln_name
65 character(len=LINELENGTH) :: errmsg
67 allocate (petsc_solver)
68 allocate (petsc_solver%petsc_ctx)
70 solver => petsc_solver
71 solver%name = sln_name
74 write (errmsg,
'(a,a)')
'PETSc solver not supported for run mode: ', &
89 this%linear_settings => linear_settings
91 call this%print_petsc_version()
93 this%mat_petsc => null()
94 select type (pm => matrix)
95 class is (petscmatrixtype)
97 this%mat_petsc => pm%mat
100 call this%petsc_check_settings(linear_settings)
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
112 this%pc_type = pcbjacobi
113 this%sub_pc_type = pcilu
116 call this%get_options_mf6()
119 call this%create_ksp()
122 call this%create_convergence_check(convergence_summary)
130 character(len=LINELENGTH) :: warnmsg, errmsg
133 if (linear_settings%ilinmeth /=
cg_method .and. &
135 write (errmsg,
'(a,a)')
'PETSc: unknown linear solver method in ', &
141 if (linear_settings%iord > 0)
then
142 linear_settings%iord = 0
143 write (warnmsg,
'(a)')
'PETSc: IMS reordering not supported'
146 if (linear_settings%iscl > 0)
then
147 linear_settings%iscl = 0
148 write (warnmsg,
'(a)')
'PETSc: IMS matrix scaling not supported'
151 if (linear_settings%north > 0)
then
152 linear_settings%north = 0
153 write (warnmsg,
'(a)')
'PETSc: IMS orthogonalization not supported'
164 petscerrorcode :: ierr
165 petscint :: major, minor, subminor, release
166 character(len=128) :: petsc_version, release_str
168 call petscgetversionnumber(major, minor, subminor, release, ierr)
171 if (release == 1)
then
172 release_str =
"(release)"
174 release_str =
"(unofficial)"
176 write (petsc_version,
'(i0,a,i0,a,i0,a,a)') &
177 major,
".", minor,
".", subminor,
" ", trim(release_str)
178 write (
iout,
'(/,1x,4a,/)')
"PETSc Linear Solver will be used for ", &
179 trim(this%name),
": version ", petsc_version
188 petscerrorcode :: ierr
189 logical(LGP) :: found
191 call petscoptionsgetbool(petsc_null_options, petsc_null_character, &
192 '-ims_pc', this%use_ims_pc, found, ierr)
202 petscerrorcode :: ierr
204 call kspcreate(petsc_comm_world, this%ksp_petsc, ierr)
207 call kspsetoperators(this%ksp_petsc, this%mat_petsc, this%mat_petsc, ierr)
210 call kspsetinitialguessnonzero(this%ksp_petsc, .true., ierr)
213 call kspsettype(this%ksp_petsc, this%ksp_type, ierr)
216 if (this%use_ims_pc)
then
217 call this%set_ims_pc()
219 call this%set_petsc_pc()
222 call kspseterrorifnotconverged(this%ksp_petsc, .false., ierr)
227 call kspsetfromoptions(this%ksp_petsc, ierr)
238 ksp,
dimension(1) :: sub_ksp
239 petscint :: n_local, n_first
240 petscerrorcode :: ierr
242 call kspgetpc(this%ksp_petsc, pc, ierr)
244 call pcsettype(pc, this%pc_type, ierr)
246 call pcsetup(pc, ierr)
248 call pcbjacobigetsubksp(pc, n_local, n_first, sub_ksp, ierr)
250 call kspgetpc(sub_ksp(1), sub_pc, ierr)
252 call pcsettype(sub_pc, this%sub_pc_type, ierr)
254 call pcsetfromoptions(sub_pc, ierr)
256 call pcfactorsetlevels(sub_pc, this%linear_settings%level, ierr)
267 ksp,
dimension(1) :: sub_ksp
268 petscint :: n_local, n_first
269 petscerrorcode :: ierr
271 this%sub_pc_type = pcshell
273 call kspgetpc(this%ksp_petsc, pc, ierr)
275 call pcsettype(pc, this%pc_type, ierr)
277 call pcsetup(pc, ierr)
279 call pcbjacobigetsubksp(pc, n_local, n_first, sub_ksp, ierr)
281 call kspgetpc(sub_ksp(1), sub_pc, ierr)
283 call pcsettype(sub_pc, this%sub_pc_type, ierr)
289 call pcshellsetcontext(sub_pc, this%pc_context, ierr)
301 petscerrorcode :: ierr
303 call this%petsc_ctx%create(this%mat_petsc, this%linear_settings, &
307 this%petsc_ctx, petsc_null_function, ierr)
314 integer(I4B) :: kiter
319 petscerrorcode :: ierr
321 kspconvergedreason :: cnvg_reason
323 character(len=LINELENGTH) :: errmsg
337 this%iteration_number = 0
338 this%is_converged = 0
340 this%petsc_ctx%cnvg_summary%iter_cnt = 0
344 call this%matrix%update()
345 call kspsolve(this%ksp_petsc, rhs_petsc%vec_impl, x_petsc%vec_impl, ierr)
348 call kspgetiterationnumber(this%ksp_petsc, it_number, ierr)
350 this%iteration_number = it_number
352 call kspgetconvergedreason(this%ksp_petsc, cnvg_reason, ierr)
354 if (cnvg_reason > 0)
then
355 if (this%petsc_ctx%icnvg_ims == -1)
then
357 this%is_converged = 0
360 this%is_converged = 1
364 if (cnvg_reason < 0 .and. cnvg_reason /= ksp_diverged_its)
then
365 write (errmsg,
'(1x,3a,i0)')
"PETSc convergence failure in ", &
366 trim(this%name),
": ", cnvg_reason
375 character(len=128) :: ksp_str, pc_str, subpc_str, &
376 dvclose_str, rclose_str, relax_str, dtol_str
380 call kspgettype(this%ksp_petsc, ksp_str, ierr)
382 call kspgetpc(this%ksp_petsc, pc, ierr)
384 call pcgettype(pc, pc_str, ierr)
386 if (this%use_ims_pc)
then
387 subpc_str = this%pc_context%ims_pc_type
389 subpc_str = this%sub_pc_type
392 write (dvclose_str,
'(e15.5)') this%linear_settings%dvclose
393 write (rclose_str,
'(e15.5)') this%linear_settings%rclose
394 write (relax_str,
'(e15.5)') this%linear_settings%relax
395 write (dtol_str,
'(e15.5)') this%linear_settings%droptol
397 write (
iout,
'(/,7x,a)')
"PETSc linear solver settings: "
398 write (
iout,
'(1x,a)') repeat(
'-', 66)
399 write (
iout,
'(1x,a,a)')
"Linear acceleration method: ", trim(ksp_str)
400 write (
iout,
'(1x,a,a)')
"Preconditioner type: ", trim(pc_str)
401 write (
iout,
'(1x,a,a)')
"Sub-preconditioner type: ", trim(subpc_str)
402 write (
iout,
'(1x,a,i0)')
"Maximum nr. of iterations: ", &
403 this%linear_settings%iter1
404 write (
iout,
'(1x,a,a)') &
405 "Dep. var. closure criterion: ", trim(adjustl(dvclose_str))
406 write (
iout,
'(1x,a,a)') &
407 "Residual closure criterion: ", trim(adjustl(rclose_str))
408 write (
iout,
'(1x,a,i0)') &
409 "Residual convergence option: ", this%linear_settings%icnvgopt
410 write (
iout,
'(1x,a,a)') &
411 "Relaxation factor MILU(T): ", trim(adjustl(relax_str))
412 write (
iout,
'(1x,a,i0)') &
413 "Fill level in factorization: ", this%linear_settings%level
414 write (
iout,
'(1x,a,a,/)') &
415 "Drop tolerance level fill: ", trim(adjustl(dtol_str))
422 petscerrorcode :: ierr
424 call kspdestroy(this%ksp_petsc, ierr)
428 call this%petsc_ctx%destroy()
429 deallocate (this%petsc_ctx)
431 call this%pc_context%destroy()
432 deallocate (this%pc_context)
440 class(petscmatrixtype),
pointer :: petsc_matrix
442 allocate (petsc_matrix)
443 matrix => petsc_matrix
451 character(len=*) :: vec_name
452 integer(I4B) :: kiter
454 petscviewer :: viewer
455 character(len=24) :: filename
456 petscerrorcode :: ierr
458 write (filename,
'(2a,i0,a,i0,a,i0,a)') vec_name,
'_',
nper, &
459 '_',
kstp,
'_', kiter,
'.txt'
460 call petscviewerasciiopen(petsc_comm_world, filename, viewer, ierr)
462 call vecview(vec%vec_impl, viewer, ierr)
464 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.
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_check_convergence(ksp, n, rnorm_L2, flag, context, ierr)
Routine to check the convergence. This is called.
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.
subroutine set_petsc_pc(this)
Set up a standard PETSc preconditioner from.
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