dslvk Subroutine

subroutine dslvk(neq, y, t, ydot, savr, x, ewt, rwm, iwm, res, ires, psol, iersl, cj, epslin, sqrtn, rsqrtn, rhok, rpar, ipar)

Uses

  • proc~~dslvk~~UsesGraph proc~dslvk dslvk module~blas_interfaces blas_interfaces proc~dslvk->module~blas_interfaces module~daskr daskr proc~dslvk->module~daskr module~daskr_kinds daskr_kinds proc~dslvk->module~daskr_kinds module~blas_interfaces->module~daskr_kinds module~daskr->module~daskr_kinds iso_fortran_env iso_fortran_env module~daskr_kinds->iso_fortran_env

This routine uses a restart algorithm and interfaces to dspigm for the solution of the linear system arising from a Newton iteration.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: neq

Problem size.

real(kind=rk), intent(in) :: y(neq)

Current dependent variables.

real(kind=rk), intent(in) :: t

Current independent variable.

real(kind=rk), intent(in) :: ydot(neq)

Current derivatives of dependent variables.

real(kind=rk), intent(in) :: savr(neq)

Current residual evaluated at (t, y, ydot).

real(kind=rk), intent(inout) :: x(neq)

On entry, the right-hand side vector of the linear system to be solved, and, on exit, the solution vector.

real(kind=rk), intent(inout) :: ewt(neq)

Nonzero elements of the diagonal scaling matrix.

real(kind=rk), intent(inout) :: rwm(*)

Real work space containing data for the algorithm (Krylov basis vectors, Hessenberg matrix, etc.).

integer, intent(inout) :: iwm(*)

Integer work space containing data for the algorithm.

procedure(res_t) :: res

User-defined residuals routine.

integer, intent(out) :: ires

Error flag from res.

procedure(psol_t) :: psol

User-defined preconditioner routine.

integer, intent(out) :: iersl

Error flag. 0: no trouble occurred (or user res routine returned ires < 0). 1: iterative method failed to converge (dspigm returned iflag > 0). -1: nonrecoverable error in the iterative solver, and an error exit will occur.

real(kind=rk), intent(in) :: cj

Scalar used in forming the system Jacobian.

real(kind=rk), intent(in) :: epslin

Tolerance for linear system solver.

real(kind=rk), intent(in) :: sqrtn

Square root of neq.

real(kind=rk), intent(in) :: rsqrtn

Reciprocal of square root of neq.

real(kind=rk), intent(out) :: rhok

Weighted norm of the final preconditioned residual.

real(kind=rk), intent(inout) :: rpar(*)

User real workspace.

integer, intent(inout) :: ipar(*)

User integer workspace.


Calls

proc~~dslvk~~CallsGraph proc~dslvk dslvk dspigm dspigm proc~dslvk->dspigm interface~dcopy dcopy proc~dslvk->interface~dcopy interface~dscal dscal proc~dslvk->interface~dscal

Variables

Type Visibility Attributes Name Initial
integer, public, save :: irst = 1
integer, public :: i
integer, public :: iflag
integer, public :: kmp
integer, public :: ldl
integer, public :: lhes
integer, public :: lgmr
integer, public :: liwp
integer, public :: lq
integer, public :: lr
integer, public :: lv
integer, public :: lwk
integer, public :: lrwp
integer, public :: lz
integer, public :: maxl
integer, public :: maxlp1
integer, public :: miter
integer, public :: ncfl
integer, public :: nli
integer, public :: nps
integer, public :: npsol
integer, public :: nre
integer, public :: nres
integer, public :: nrmax
integer, public :: nrsts

Source Code

subroutine dslvk( &
   neq, y, t, ydot, savr, x, ewt, rwm, iwm, res, ires, psol, &
   iersl, cj, epslin, sqrtn, rsqrtn, rhok, rpar, ipar)
!! This routine uses a restart algorithm and interfaces to [[dspigm]] for the solution of
!! the linear system arising from a Newton iteration.

   use daskr_kinds, only: rk, zero
   use daskr
   use blas_interfaces, only: dscal, dcopy
   implicit none

   integer, intent(in) :: neq
      !! Problem size.
   real(rk), intent(in) :: y(neq)
      !! Current dependent variables.
   real(rk), intent(in) :: t
      !! Current independent variable.
   real(rk), intent(in) :: ydot(neq)
      !! Current derivatives of dependent variables.
   real(rk), intent(in) :: savr(neq)
      !! Current residual evaluated at `(t, y, ydot)`.
   real(rk), intent(inout) :: x(neq)
      !! On entry, the right-hand side vector of the linear system to be solved,
      !! and, on exit, the solution vector.
   real(rk), intent(inout) :: ewt(neq)
      !! Nonzero elements of the diagonal scaling matrix.
   real(rk), intent(inout) :: rwm(*)
      !! Real work space containing data for the algorithm (Krylov basis vectors,
      !! Hessenberg matrix, etc.).
   integer, intent(inout) :: iwm(*)
      !! Integer work space containing data for the algorithm.
   procedure(res_t) :: res
      !! User-defined residuals routine.
   integer, intent(out) :: ires
      !! Error flag from `res`.
   procedure(psol_t) :: psol
      !! User-defined preconditioner routine.
   integer, intent(out) :: iersl
      !! Error flag.
      !!  `0`: no trouble occurred (or user `res` routine returned `ires < 0`).
      !!  `1`: iterative method failed to converge ([[dspigm]] returned `iflag > 0`).
      !! `-1`: nonrecoverable error in the iterative solver, and an error exit will occur.
   real(rk), intent(in) :: cj
      !! Scalar used in forming the system Jacobian.
   real(rk), intent(in) :: epslin
      !! Tolerance for linear system solver.
   real(rk), intent(in) :: sqrtn
      !! Square root of `neq`.
   real(rk), intent(in) :: rsqrtn
      !! Reciprocal of square root of `neq`.
   real(rk), intent(out) :: rhok
      !! Weighted norm of the final preconditioned residual.
   real(rk), intent(inout) :: rpar(*)
      !! User real workspace.
   integer, intent(inout) :: ipar(*)
      !! User integer workspace.

   integer, save :: irst = 1 ! @todo: move this to iwork, to get rid of save
   integer :: i, iflag, kmp, ldl, lhes, lgmr, liwp, lq, lr, lv, lwk, lrwp, lz, &
              maxl, maxlp1, miter, ncfl, nli, nps, npsol, nre, nres, nrmax, nrsts

   liwp = iwm(iwloc_liwp)
   nli = iwm(iwloc_nli)
   nps = iwm(iwloc_nps)
   ncfl = iwm(iwloc_ncfl)
   nre = iwm(iwloc_nre)
   lrwp = iwm(iwloc_lrwp)
   maxl = iwm(iwloc_maxl)
   kmp = iwm(iwloc_kmp)
   nrmax = iwm(iwloc_nrmax)
   miter = iwm(iwloc_miter)
   iersl = 0
   ires = 0

   ! Use a restarting strategy to solve the linear system P*X = -F. Parse the work vector,
   ! and perform initializations. Note that zero is the initial guess for X.
   maxlp1 = maxl + 1
   lv = 1
   lr = lv + neq*maxl
   lhes = lr + neq + 1
   lq = lhes + maxl*maxlp1
   lwk = lq + 2*maxl
   ldl = lwk + min(1, maxl - kmp)*neq
   lz = ldl + neq
   call dscal(neq, rsqrtn, ewt, 1)
   call dcopy(neq, x, 1, rwm(lr), 1)
   x = zero

   ! Top of loop for the restart algorithm. Initial pass approximates X and sets up a
   ! transformed system to perform subsequent restarts to update X. NRSTS is initialized
   ! to -1, because restarting does not occur until after the first pass.
   ! Update NRSTS; conditionally copy DL to R; call the DSPIGM algorithm to solve A*Z = R;
   ! updated counters; update X with the residual solution.
   ! Note: if convergence is not achieved after NRMAX restarts, then the linear solver is
   ! considered to have failed.
   iflag = 1
   nrsts = -1
   do while ((iflag == 1) .and. (nrsts < nrmax) .and. (ires == 0))
      nrsts = nrsts + 1
      if (nrsts > 0) call dcopy(neq, rwm(ldl), 1, rwm(lr), 1)
      call dspigm(neq, t, y, ydot, savr, rwm(lr), ewt, maxl, &
                  kmp, epslin, cj, res, ires, nres, psol, npsol, rwm(lz), rwm(lv), &
                  rwm(lhes), rwm(lq), lgmr, rwm(lrwp), iwm(liwp), rwm(lwk), &
                  rwm(ldl), rhok, iflag, irst, nrsts, rpar, ipar)
      nli = nli + lgmr
      nps = nps + npsol
      nre = nre + nres
      do i = 1, neq
         x(i) = x(i) + rwm(lz + i - 1)
      end do
   end do

   ! The restart scheme is finished. Test IRES and IFLAG to see if convergence was not
   ! achieved, and set flags accordingly.
   if (ires < 0) then
      ncfl = ncfl + 1
   elseif (iflag /= 0) then
      ncfl = ncfl + 1
      if (iflag > 0) iersl = 1
      if (iflag < 0) iersl = -1
   end if

   ! Update IWM with counters, rescale EWT, and return.
   iwm(iwloc_nli) = nli
   iwm(iwloc_nps) = nps
   iwm(iwloc_ncfl) = ncfl
   iwm(iwloc_nre) = nre
   call dscal(neq, sqrtn, ewt, 1)

end subroutine dslvk