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
.
Type | Intent | Optional | 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 |
||
real(kind=rk), | intent(in) | :: | v(neq) |
Orthonormal vector (can be the same as |
||
real(kind=rk), | intent(in) | :: | wght(neq) |
Scaling factors. |
||
real(kind=rk), | intent(out) | :: | ydottemp(neq) |
Work array used to store the incremented value of |
||
procedure(res_t) | :: | res |
User-defined residuals routine. |
|||
integer, | intent(out) | :: | ires |
Error flag from |
||
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 |
||
real(kind=rk), | intent(inout) | :: | rwp(*) |
Real work array used by preconditioner |
||
integer, | intent(inout) | :: | iwp(*) |
Integer work array used by preconditioner |
||
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 |
||
integer, | intent(inout) | :: | nres |
Number of calls to |
||
integer, | intent(inout) | :: | npsol |
Number of calls to |
||
real(kind=rk), | intent(inout) | :: | rpar(*) |
User real workspace. |
||
integer, | intent(inout) | :: | ipar(*) |
User integer workspace. |
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