datv Subroutine

subroutine datv(neq, y, t, ydot, savr, v, wght, ydottemp, res, ires, psol, z, vtemp, rwp, iwp, cj, epslin, ierr, nres, npsol, rpar, ipar)

Uses

  • proc~~datv~~UsesGraph proc~datv datv module~daskr daskr proc~datv->module~daskr module~daskr_kinds daskr_kinds proc~datv->module~daskr_kinds module~daskr->module~daskr_kinds iso_fortran_env iso_fortran_env module~daskr_kinds->iso_fortran_env

This routine computes the matrix-vector product:

where , is a scalar proportional to , and involves the past history of . The quantity is an approximation to the first derivative of and is stored in .

is a diagonal scaling matrix, and is the left preconditioning matrix. is assumed to have L-2 norm equal to 1. The product is stored in and is computed by means of a difference quotient, a call to res, and one call to psol.

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(in) :: v(neq)

Orthonormal vector (can be the same as z).

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

Scaling factors. 1/wght(i) are the diagonal elements of the matrix .

real(kind=rk), intent(out) :: ydottemp(neq)

Work array used to store the incremented value of ydot.

procedure(res_t) :: res

User-defined residuals routine.

integer, intent(out) :: ires

Error flag from res.

procedure(psol_t) :: psol

User-defined preconditioner routine.

real(kind=rk), intent(out) :: z(neq)

Desired scaled matrix-vector product.

real(kind=rk), intent(out) :: vtemp(neq)

Work array used to store the unscaled version of v.

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

Real work array used by preconditioner psol.

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

Integer work array used by preconditioner psol.

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

Scalar used in forming the system Jacobian.

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

Tolerance for linear system.

integer, intent(out) :: ierr

Error flag from psol.

integer, intent(inout) :: nres

Number of calls to res.

integer, intent(inout) :: npsol

Number of calls to psol.

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

User real workspace.

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

User integer workspace.


Source Code

subroutine datv( &
   neq, y, t, ydot, savr, v, wght, ydottemp, res, &
   ires, psol, z, vtemp, rwp, iwp, cj, epslin, ierr, nres, npsol, rpar, ipar)
!! This routine computes the matrix-vector product:
!!
!! $$ z = D^{-1} P^{-1} (\partial F / \partial y) D v $$
!!
!! where \(F = G(t, y, c_J(y - a))\), \(c_J\) is a scalar proportional to \(1/h\), and \(a\)
!! involves the past history of \(y\). The quantity \(c_J(y - a)\) is an approximation to
!! the first derivative of \(y\) and is stored in \(\dot{y}\).
!!
!! \(D\) is a diagonal scaling matrix, and \(P\) is the left preconditioning matrix. \(v\)
!! is assumed to have L-2 norm equal to 1. The product is stored in \(z\) and is computed by
!! means of a difference quotient, a call to `res`, and one call to `psol`.

   use daskr_kinds, only: rk
   use daskr

   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(in) :: v(neq)
      !! Orthonormal vector (can be the same as `z`).
   real(rk), intent(in) :: wght(neq)
      !! Scaling factors. `1/wght(i)` are the diagonal elements of the matrix \(D\).
   real(rk), intent(out) :: ydottemp(neq)
      !! Work array used to store the incremented value of `ydot`.
   procedure(res_t) :: res
      !! User-defined residuals routine.
   integer, intent(out) :: ires
      !! Error flag from `res`.
   procedure(psol_t) :: psol
      !! User-defined preconditioner routine.
   real(rk), intent(out) :: z(neq)
      !! Desired scaled matrix-vector product.
   real(rk), intent(out) :: vtemp(neq)
      !! Work array used to store the unscaled version of `v`.
   real(rk), intent(inout) :: rwp(*)
      !! Real work array used by preconditioner `psol`.
   integer, intent(inout) :: iwp(*)
      !! Integer work array used by preconditioner `psol`.
   real(rk), intent(in) :: cj
      !! Scalar used in forming the system Jacobian.
   real(rk), intent(in) :: epslin
      !! Tolerance for linear system.
   integer, intent(out) :: ierr
      !! Error flag from `psol`.
   integer, intent(inout) :: nres
      !! Number of calls to `res`.
   integer, intent(inout) :: npsol
      !! Number of calls to `psol`.
   real(rk), intent(inout) :: rpar(*)
      !! User real workspace.
   integer, intent(inout) :: ipar(*)
      !! User integer workspace.

   ! Set VTEMP = D * V.
   vtemp = v/wght

   ! Store Y in Z and increment Z by VTEMP.
   ! Store YDOT in YDOTTEMP and increment YDOTTEMP by VTEM*CJ.
   ydottemp = ydot + vtemp*cj
   z = y + vtemp

   ! Call RES with incremented Y, YDOT arguments
   ! stored in Z, YDOTTEMP. VTEMP is overwritten with new residual.
   ires = 0
   call res(t, z, ydottemp, cj, vtemp, ires, rpar, ipar)
   nres = nres + 1
   if (ires < 0) return

   ! Set Z = (dF/dY) * VBAR using difference quotient.
   ! (VBAR is old value of VTEMP before calling RES)
   z = vtemp - savr

   ! Apply inverse of left preconditioner to Z.
   ierr = 0
   call psol(neq, t, y, ydot, savr, ydottemp, cj, wght, rwp, iwp, z, epslin, ierr, rpar, ipar)
   npsol = npsol + 1
   if (ierr /= 0) return

   ! Apply D-inverse to Z
   z = z*wght

end subroutine datv