2 #include <petsc/finclude/petscksp.h>
15 public :: kspsetconvergencetest
25 integer(I4B) :: icnvg_ims
26 integer(I4B) :: icnvgopt
30 integer(I4B) :: max_its
31 real(dp) :: rnorm_l2_init
33 real(dp) :: t_convergence_check
42 subroutine cnvgcheckfunc(ksp, n, rnorm, flag, context, ierr)
47 kspconvergedreason :: flag
49 petscerrorcode :: ierr
52 subroutine cnvgdestroyfunc(context, ierr)
55 petscerrorcode :: ierr
58 subroutine kspsetconvergencetest(ksp, check_convergence, context, &
62 procedure(cnvgcheckfunc) :: check_convergence
64 procedure(cnvgdestroyfunc) :: destroy
65 petscerrorcode :: ierr
71 subroutine create(this, mat, settings, summary)
77 petscerrorcode :: ierr
80 this%icnvgopt = settings%icnvgopt
81 this%dvclose = settings%dvclose
82 this%rclose = settings%rclose
83 this%max_its = settings%iter1
84 this%cnvg_summary => summary
85 call matcreatevecs(mat, this%x_old, petsc_null_vec, ierr)
87 call matcreatevecs(mat, this%delta_x, petsc_null_vec, ierr)
89 call matcreatevecs(mat, this%residual, petsc_null_vec, ierr)
100 kspconvergedreason :: flag
102 petscerrorcode :: ierr
104 petscreal,
parameter :: min_one = -1.0
105 petscreal :: xnorm_inf, rnorm0, rnorm_inf_ims, rnorm_l2_ims
109 summary => context%cnvg_summary
113 call kspbuildsolution(ksp, petsc_null_vec, x, ierr)
118 call kspbuildresidual(ksp, petsc_null_vec, petsc_null_vec, res, ierr)
121 rnorm0 = huge(rnorm0)
122 if (context%icnvgopt == 2 .or. &
123 context%icnvgopt == 3 .or. &
124 context%icnvgopt == 4)
then
125 call vecnorm(res, norm_2, rnorm_l2_ims, ierr)
126 rnorm0 = rnorm_l2_ims
132 context%rnorm_L2_init = rnorm0
135 flag = ksp_converged_happy_breakdown
137 call veccopy(x, context%x_old, ierr)
139 flag = ksp_converged_iterating
142 call vecdestroy(res, ierr)
147 call vecwaxpy(context%delta_x, min_one, context%x_old, x, ierr)
150 call vecnorm(context%delta_x, norm_infinity, xnorm_inf, ierr)
153 rnorm_inf_ims = huge(rnorm_inf_ims)
154 if (context%icnvgopt == 0 .or. context%icnvgopt == 1)
then
155 call vecnorm(res, norm_infinity, rnorm_inf_ims, ierr)
159 call veccopy(x, context%x_old, ierr)
167 flag = ksp_converged_happy_breakdown
168 context%icnvg_ims = 1
170 if (n > 1 .and. context%icnvgopt == 1)
then
171 context%icnvg_ims = -1
175 flag =
apply_check(context, n, xnorm_inf, rnorm_inf_ims, rnorm_l2_ims)
178 if (flag == ksp_converged_iterating)
then
180 if (n == context%max_its)
then
181 flag = ksp_diverged_its
185 call vecdestroy(res, ierr)
192 function apply_check(ctx, nit, dvmax, rnorm_inf, rnorm_L2)
result(flag)
198 real(dp) :: rnorm_inf
200 kspconvergedreason :: flag
206 flag = ksp_converged_iterating
211 if (ctx%icnvgopt == 2 .or. &
212 ctx%icnvgopt == 3 .or. &
213 ctx%icnvgopt == 4)
then
219 dvmax, rcnvg, ctx%rnorm_L2_init, &
220 epfact, ctx%dvclose, ctx%rclose)
222 if (ctx%icnvg_ims /= 0)
then
224 flag = ksp_converged_happy_breakdown
234 petscreal :: rnorm_l2
235 kspconvergedreason :: flag
237 petscerrorcode :: ierr
239 petscreal,
parameter :: min_one = -1.0
240 petscreal :: xnorm_inf, rnorm0
244 summary => context%cnvg_summary
248 call kspbuildsolution(ksp, petsc_null_vec, x, ierr)
255 context%rnorm_L2_init = rnorm0
258 flag = ksp_converged_happy_breakdown
259 context%icnvg_ims = 1
261 call veccopy(x, context%x_old, ierr)
263 flag = ksp_converged_iterating
269 call vecwaxpy(context%delta_x, min_one, context%x_old, x, ierr)
272 call vecnorm(context%delta_x, norm_infinity, xnorm_inf, ierr)
275 call veccopy(x, context%x_old, ierr)
281 context%icnvg_ims = 0
284 flag = ksp_converged_happy_breakdown
285 context%icnvg_ims = 1
287 if (n > 1 .and. context%icnvgopt == 1) context%icnvg_ims = -1
290 if (xnorm_inf <= context%dvclose .and. rnorm_l2 <= context%rclose)
then
291 flag = ksp_converged_happy_breakdown
292 context%icnvg_ims = 1
294 if (n > 1 .and. context%icnvgopt == 1) context%icnvg_ims = -1
298 if (flag == ksp_converged_iterating)
then
300 if (n == context%max_its)
then
301 flag = ksp_diverged_its
305 call vecdestroy(res, ierr)
318 petscreal,
dimension(:),
pointer :: local_dx, local_res
319 petscreal :: dvmax_model, rmax_model
320 petscerrorcode :: ierr
321 petscint :: idx_dv, idx_r
322 petscint :: i, j, istart, iend
326 summary%iter_cnt = summary%iter_cnt + 1
327 iter_cnt = summary%iter_cnt
329 if (summary%nitermax > 1)
then
330 summary%itinner(iter_cnt) = n
331 do i = 1, summary%convnmod
332 summary%convdvmax(i, iter_cnt) =
dzero
333 summary%convlocdv(i, iter_cnt) = 0
334 summary%convrmax(i, iter_cnt) =
dzero
335 summary%convlocr(i, iter_cnt) = 0
340 call vecgetarrayreadf90(dx, local_dx, ierr)
342 call vecgetarrayreadf90(res, local_res, ierr)
344 do i = 1, summary%convnmod
351 istart = summary%model_bounds(i)
352 iend = summary%model_bounds(i + 1) - 1
354 if (abs(local_dx(j)) > abs(dvmax_model))
then
355 dvmax_model = local_dx(j)
358 if (abs(local_res(j)) > abs(rmax_model))
then
359 rmax_model = local_res(j)
363 if (summary%nitermax > 1)
then
364 summary%convdvmax(i, iter_cnt) = dvmax_model
365 summary%convlocdv(i, iter_cnt) = idx_dv
366 summary%convrmax(i, iter_cnt) = rmax_model
367 summary%convlocr(i, iter_cnt) = idx_r
370 call vecrestorearrayf90(dx, local_dx, ierr)
372 call vecrestorearrayf90(res, local_res, ierr)
384 petscreal,
dimension(:),
pointer :: local_dx
385 petscreal :: dvmax_model
386 petscerrorcode :: ierr
388 petscint :: i, j, istart, iend
392 summary%iter_cnt = summary%iter_cnt + 1
393 iter_cnt = summary%iter_cnt
395 if (summary%nitermax > 1)
then
396 summary%itinner(iter_cnt) = n
397 do i = 1, summary%convnmod
398 summary%convdvmax(i, iter_cnt) =
dzero
399 summary%convlocdv(i, iter_cnt) = 0
400 summary%convrmax(i, iter_cnt) =
dzero
401 summary%convlocr(i, iter_cnt) = 0
406 call vecgetarrayreadf90(dx, local_dx, ierr)
408 do i = 1, summary%convnmod
413 istart = summary%model_bounds(i)
414 iend = summary%model_bounds(i + 1) - 1
416 if (abs(local_dx(j)) > abs(dvmax_model))
then
417 dvmax_model = local_dx(j)
421 if (summary%nitermax > 1)
then
422 summary%convdvmax(i, iter_cnt) = dvmax_model
423 summary%convlocdv(i, iter_cnt) = idx_dv
426 call vecrestorearrayf90(dx, local_dx, ierr)
436 call vecdestroy(this%x_old, ierr)
438 call vecdestroy(this%delta_x, ierr)
440 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 fill_cnvg_summary_internal(summary, dx, n)
Fill the convergence summary from the context.
subroutine, public petsc_cnvg_check_internal(ksp, n, rnorm_L2, flag, context, ierr)
Routine to check the convergence following the configuration.
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