MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
petscconvergencemodule Module Reference

Data Types

type  petsccnvgctxtype
 x vector from the previous iteration More...
 
interface  CnvgCheckFunc
 
interface  CnvgDestroyFunc
 
interface  KSPSetConvergenceTest
 

Functions/Subroutines

subroutine create (this, mat, settings, summary)
 
subroutine, public petsc_check_convergence (ksp, n, rnorm_L2, flag, context, ierr)
 Routine to check the convergence. This is called. More...
 
function apply_check (ctx, nit, dvmax, rnorm_inf, rnorm_L2)
 Apply the IMS convergence check. More...
 
subroutine destroy (this)
 

Variables

real(dp), parameter, private rnorm_l2_tol = DPREC
 Context for the custom convergence check. More...
 

Function/Subroutine Documentation

◆ apply_check()

function petscconvergencemodule::apply_check ( class(petsccnvgctxtype ctx,
integer(i4b)  nit,
real(dp)  dvmax,
real(dp)  rnorm_inf,
real(dp)  rnorm_L2 
)
private
Parameters
nititeration number
dvmaxinfinity norm of dep. var. change
rnorm_infinfinity norm of residual change
rnorm_l2L2-norm of residual change
rnorm_l2the convergence status

Definition at line 234 of file PetscConvergence.F90.

235  use tdismodule, only: kstp
237  class(PetscCnvgCtxType) :: ctx
238  integer(I4B) :: nit !< iteration number
239  real(DP) :: dvmax !< infinity norm of dep. var. change
240  real(DP) :: rnorm_inf !< infinity norm of residual change
241  real(DP) :: rnorm_L2 !< L2-norm of residual change
242  kspconvergedreason :: flag !< the convergence status
243  ! local
244  real(DP) :: epfact
245  real(DP) :: rcnvg
246 
247  ! Set to 'not converged'
248  flag = ksp_converged_iterating
249  ctx%icnvg_ims = 0
250 
251  epfact = ims_base_epfact(ctx%icnvgopt, kstp)
252 
253  if (ctx%icnvgopt == 2 .or. &
254  ctx%icnvgopt == 3 .or. &
255  ctx%icnvgopt == 4) then
256  rcnvg = rnorm_l2
257  else
258  rcnvg = rnorm_inf
259  end if
260  call ims_base_testcnvg(ctx%icnvgopt, ctx%icnvg_ims, nit, &
261  dvmax, rcnvg, ctx%rnorm_L2_init, &
262  epfact, ctx%dvclose, ctx%rclose)
263 
264  if (ctx%icnvg_ims /= 0) then
265  ! Set to 'converged'
266  flag = ksp_converged_happy_breakdown
267  end if
268 
This module contains the IMS linear accelerator subroutines.
subroutine ims_base_testcnvg(Icnvgopt, Icnvg, Iiter, Dvmax, Rmax, Rmax0, Epfact, Dvclose, Rclose)
@ brief Test for solver convergence
real(dp) function ims_base_epfact(icnvgopt, kstp)
Function returning EPFACT.
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create()

subroutine petscconvergencemodule::create ( class(petsccnvgctxtype this,
pointer  mat,
type(imslinearsettingstype), pointer  settings,
type(convergencesummarytype), pointer  summary 
)
private

Definition at line 68 of file PetscConvergence.F90.

69  class(PetscCnvgCtxType) :: this
70  mat, pointer :: mat
71  type(ImsLinearSettingsType), pointer :: settings
72  type(ConvergenceSummaryType), pointer :: summary
73  ! local
74  petscerrorcode :: ierr
75 
76  this%icnvg_ims = 0
77  this%icnvgopt = settings%icnvgopt
78  this%dvclose = settings%dvclose
79  this%rclose = settings%rclose
80  this%max_its = settings%iter1
81  this%cnvg_summary => summary
82  call matcreatevecs(mat, this%x_old, petsc_null_vec, ierr)
83  chkerrq(ierr)
84  call matcreatevecs(mat, this%delta_x, petsc_null_vec, ierr)
85  chkerrq(ierr)
86  call matcreatevecs(mat, this%residual, petsc_null_vec, ierr)
87  chkerrq(ierr)
88 

◆ destroy()

subroutine petscconvergencemodule::destroy ( class(petsccnvgctxtype this)

Definition at line 271 of file PetscConvergence.F90.

272  class(PetscCnvgCtxType) :: this
273  ! local
274  integer(I4B) :: ierr
275 
276  call vecdestroy(this%x_old, ierr)
277  chkerrq(ierr)
278  call vecdestroy(this%delta_x, ierr)
279  chkerrq(ierr)
280  call vecdestroy(this%residual, ierr)
281  chkerrq(ierr)
282 

◆ petsc_check_convergence()

subroutine, public petscconvergencemodule::petsc_check_convergence (   ksp,
  n,
  rnorm_L2,
  flag,
class(petsccnvgctxtype), pointer  context,
  ierr 
)
Parameters
contexterror

Definition at line 93 of file PetscConvergence.F90.

94  ksp :: ksp !< Iterative context
95  petscint :: n !< Iteration number
96  petscreal :: rnorm_l2 !< 2-norm (preconditioned) residual value
97  kspconvergedreason :: flag !< Converged reason
98  class(PetscCnvgCtxType), pointer :: context !< context
99  petscerrorcode :: ierr !< error
100  ! local
101  petscreal, parameter :: min_one = -1.0
102  petscreal, dimension(:), pointer :: local_dx, local_res
103  petscreal :: xnorm_inf_ims, rnorm_inf_ims, rnorm_l2_ims
104  petscreal :: dvmax_model, rmax_model
105  petscint :: idx_dv, idx_r
106  vec :: x, rhs
107  mat :: amat
108  type(ConvergenceSummaryType), pointer :: summary
109  petscint :: iter_cnt
110  petscint :: i, j, istart, iend
111 
112  summary => context%cnvg_summary
113 
114  ! NB: KSPBuildResidual needs to have its vector destroyed
115  ! to avoid a memory leak, KSPBuildSolution doesn't...
116  call kspbuildsolution(ksp, petsc_null_vec, x, ierr)
117  chkerrq(ierr)
118 
119  call kspgetrhs(ksp, rhs, ierr)
120  chkerrq(ierr)
121 
122  call kspgetoperators(ksp, amat, petsc_null_mat, ierr)
123  chkerrq(ierr)
124 
125  call matmult(amat, x, context%residual, ierr)
126  chkerrq(ierr)
127 
128  ! y = x + beta y (i.e. r = b - A*x)
129  call vecaypx(context%residual, -1.0_dp, rhs, ierr)
130  chkerrq(ierr)
131 
132  call vecnorm(context%residual, norm_2, rnorm_l2_ims, ierr)
133  chkerrq(ierr)
134 
135  ! n == 0 is before the iteration starts
136  if (n == 0) then
137  context%rnorm_L2_init = rnorm_l2_ims
138  if (rnorm_l2 < rnorm_l2_tol) then
139  ! exact solution found
140  flag = ksp_converged_happy_breakdown
141  else
142  call veccopy(x, context%x_old, ierr)
143  chkerrq(ierr)
144  flag = ksp_converged_iterating
145  end if
146  ! early return
147  return
148  end if
149 
150  ! increment iteration counter
151  summary%iter_cnt = summary%iter_cnt + 1
152  iter_cnt = summary%iter_cnt
153 
154  if (summary%nitermax > 1) then
155  summary%itinner(iter_cnt) = n
156  do i = 1, summary%convnmod
157  summary%convdvmax(i, iter_cnt) = dzero
158  summary%convlocdv(i, iter_cnt) = 0
159  summary%convrmax(i, iter_cnt) = dzero
160  summary%convlocr(i, iter_cnt) = 0
161  end do
162  end if
163 
164  call vecwaxpy(context%delta_x, min_one, context%x_old, x, ierr)
165  chkerrq(ierr)
166 
167  call vecnorm(context%delta_x, norm_infinity, xnorm_inf_ims, ierr)
168  chkerrq(ierr)
169 
170  rnorm_inf_ims = 0.0
171  if (context%icnvgopt == 0 .or. context%icnvgopt == 1) then
172  call vecnorm(context%residual, norm_infinity, rnorm_inf_ims, ierr)
173  chkerrq(ierr)
174  end if
175 
176  call veccopy(x, context%x_old, ierr)
177  chkerrq(ierr)
178 
179  ! get dv and dr per local model (readonly!)
180  call vecgetarrayreadf90(context%delta_x, local_dx, ierr)
181  chkerrq(ierr)
182  call vecgetarrayreadf90(context%residual, local_res, ierr)
183  chkerrq(ierr)
184  do i = 1, summary%convnmod
185  ! reset
186  dvmax_model = dzero
187  idx_dv = 0
188  rmax_model = dzero
189  idx_r = 0
190  ! get first and last model index
191  istart = summary%model_bounds(i)
192  iend = summary%model_bounds(i + 1) - 1
193  do j = istart, iend
194  if (abs(local_dx(j)) > abs(dvmax_model)) then
195  dvmax_model = local_dx(j)
196  idx_dv = j
197  end if
198  if (abs(local_res(j)) > abs(rmax_model)) then
199  rmax_model = local_res(j)
200  idx_r = j
201  end if
202  end do
203  if (summary%nitermax > 1) then
204  summary%convdvmax(i, iter_cnt) = dvmax_model
205  summary%convlocdv(i, iter_cnt) = idx_dv
206  summary%convrmax(i, iter_cnt) = rmax_model
207  summary%convlocr(i, iter_cnt) = idx_r
208  end if
209  end do
210  call vecrestorearrayf90(context%delta_x, local_dx, ierr)
211  chkerrq(ierr)
212  call vecrestorearrayf90(context%residual, local_res, ierr)
213  chkerrq(ierr)
214 
215  if (rnorm_l2 < rnorm_l2_tol) then
216  ! exact solution, set to 'converged'
217  flag = ksp_converged_happy_breakdown
218  else
219  ! IMS check on convergence
220  flag = apply_check(context, n, xnorm_inf_ims, rnorm_inf_ims, rnorm_l2_ims)
221  end if
222 
223  if (flag == ksp_converged_iterating) then
224  ! not yet converged, max. iters reached? Then stop.
225  if (n == context%max_its) then
226  flag = ksp_diverged_its
227  end if
228  end if
229 
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ rnorm_l2_tol

real(dp), parameter, private petscconvergencemodule::rnorm_l2_tol = DPREC
private

Definition at line 16 of file PetscConvergence.F90.

16  real(DP), private, parameter :: RNORM_L2_TOL = dprec