2 #include <petsc/finclude/petscksp.h>
15 public :: kspsetconvergencetest
25 integer(I4B) :: icnvg_ims
26 integer(I4B) :: icnvgopt
31 integer(I4B) :: max_its
32 real(dp) :: rnorm_l2_init
34 real(dp) :: t_convergence_check
43 subroutine cnvgcheckfunc(ksp, n, rnorm, flag, context, ierr)
48 kspconvergedreason :: flag
50 petscerrorcode :: ierr
53 subroutine cnvgdestroyfunc(context, ierr)
56 petscerrorcode :: ierr
59 subroutine kspsetconvergencetest(ksp, check_convergence, context, &
63 procedure(cnvgcheckfunc) :: check_convergence
65 procedure(cnvgdestroyfunc) :: destroy
66 petscerrorcode :: ierr
72 subroutine create(this, mat, settings, summary)
78 petscerrorcode :: ierr
81 this%icnvgopt = settings%icnvgopt
82 this%dvclose = settings%dvclose
83 this%rclose = settings%rclose
84 this%max_its = settings%iter1
85 this%cnvg_summary => summary
86 call matcreatevecs(mat, this%x_old, petsc_null_vec, ierr)
88 call matcreatevecs(mat, this%delta_x, petsc_null_vec, ierr)
90 call matcreatevecs(mat, this%residual, petsc_null_vec, ierr)
100 petscreal :: rnorm_l2
101 kspconvergedreason :: flag
103 petscerrorcode :: ierr
105 petscreal,
parameter :: min_one = -1.0
106 petscreal :: xnorm_inf, rnorm0, rnorm_inf_ims, rnorm_l2_ims
110 summary => context%cnvg_summary
114 call kspbuildsolution(ksp, petsc_null_vec, x, ierr)
119 call kspbuildresidual(ksp, petsc_null_vec, petsc_null_vec, res, ierr)
122 rnorm0 = huge(rnorm0)
123 if (context%icnvgopt == 2 .or. &
124 context%icnvgopt == 3 .or. &
125 context%icnvgopt == 4)
then
126 call vecnorm(res, norm_2, rnorm_l2_ims, ierr)
127 rnorm0 = rnorm_l2_ims
129 else if (context%icnvgopt == 100)
then
135 context%rnorm_L2_init = rnorm0
138 flag = ksp_converged_happy_breakdown
140 call veccopy(x, context%x_old, ierr)
142 flag = ksp_converged_iterating
145 call vecdestroy(res, ierr)
150 call vecwaxpy(context%delta_x, min_one, context%x_old, x, ierr)
153 call vecnorm(context%delta_x, norm_infinity, xnorm_inf, ierr)
156 rnorm_inf_ims = huge(rnorm_inf_ims)
157 if (context%icnvgopt == 0 .or. context%icnvgopt == 1)
then
158 call vecnorm(res, norm_infinity, rnorm_inf_ims, ierr)
162 call veccopy(x, context%x_old, ierr)
170 flag = ksp_converged_happy_breakdown
171 else if (context%icnvgopt < 100)
then
173 flag =
apply_check(context, n, xnorm_inf, rnorm_inf_ims, rnorm_l2_ims)
174 else if (context%icnvgopt == 100)
then
176 flag = ksp_converged_iterating
177 if (xnorm_inf < context%dvclose .and. rnorm_l2 < context%rclose)
then
178 flag = ksp_converged_happy_breakdown
182 write (
errmsg,
'(a,i0)')
"Invalid convergence option: ", context%icnvgopt
186 if (flag == ksp_converged_iterating)
then
188 if (n == context%max_its)
then
189 flag = ksp_diverged_its
193 call vecdestroy(res, ierr)
200 function apply_check(ctx, nit, dvmax, rnorm_inf, rnorm_L2)
result(flag)
206 real(dp) :: rnorm_inf
208 kspconvergedreason :: flag
214 flag = ksp_converged_iterating
219 if (ctx%icnvgopt == 2 .or. &
220 ctx%icnvgopt == 3 .or. &
221 ctx%icnvgopt == 4)
then
227 dvmax, rcnvg, ctx%rnorm_L2_init, &
228 epfact, ctx%dvclose, ctx%rclose)
230 if (ctx%icnvg_ims /= 0)
then
232 flag = ksp_converged_happy_breakdown
245 petscreal,
dimension(:),
pointer :: local_dx, local_res
246 petscreal :: dvmax_model, rmax_model
247 petscerrorcode :: ierr
248 petscint :: idx_dv, idx_r
249 petscint :: i, j, istart, iend
253 summary%iter_cnt = summary%iter_cnt + 1
254 iter_cnt = summary%iter_cnt
256 if (summary%nitermax > 1)
then
257 summary%itinner(iter_cnt) = n
258 do i = 1, summary%convnmod
259 summary%convdvmax(i, iter_cnt) =
dzero
260 summary%convlocdv(i, iter_cnt) = 0
261 summary%convrmax(i, iter_cnt) =
dzero
262 summary%convlocr(i, iter_cnt) = 0
267 call vecgetarrayreadf90(dx, local_dx, ierr)
269 call vecgetarrayreadf90(res, local_res, ierr)
271 do i = 1, summary%convnmod
278 istart = summary%model_bounds(i)
279 iend = summary%model_bounds(i + 1) - 1
281 if (abs(local_dx(j)) > abs(dvmax_model))
then
282 dvmax_model = local_dx(j)
285 if (abs(local_res(j)) > abs(rmax_model))
then
286 rmax_model = local_res(j)
290 if (summary%nitermax > 1)
then
291 summary%convdvmax(i, iter_cnt) = dvmax_model
292 summary%convlocdv(i, iter_cnt) = idx_dv
293 summary%convrmax(i, iter_cnt) = rmax_model
294 summary%convlocr(i, iter_cnt) = idx_r
297 call vecrestorearrayf90(dx, local_dx, ierr)
299 call vecrestorearrayf90(res, local_res, ierr)
309 call vecdestroy(this%x_old, ierr)
311 call vecdestroy(this%delta_x, ierr)
313 call vecdestroy(this%residual, ierr)
This module contains simulation constants.
real(dp), parameter dzero
real constant zero
real(dp), parameter dprec
real constant machine precision
subroutine destroy(this)
Cleanup.
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.
This module defines variable data types.
real(dp), parameter, private rnorm_l2_tol
function apply_check(ctx, nit, dvmax, rnorm_inf, rnorm_L2)
Apply the IMS convergence check.
subroutine create(this, mat, settings, summary)
subroutine fill_cnvg_summary(summary, dx, res, n)
Fill the convergence summary from the context.
subroutine, public petsc_cnvg_check(ksp, n, rnorm_L2, flag, context, ierr)
Routine to check the convergence following the configuration.
This module contains simulation methods.
subroutine, public store_error(msg, terminate)
Store an error message.
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
integer(i4b), pointer, public kstp
current time step number
This structure stores the generic convergence info for a solution.
x vector from the previous iteration