123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- *DECK DPIGMR
- SUBROUTINE DPIGMR (N, R0, SR, SZ, JSCAL, MAXL, MAXLP1, KMP, NRSTS,
- + JPRE, MATVEC, MSOLVE, NMSL, Z, V, HES, Q, LGMR, RPAR, IPAR, WK,
- + DL, RHOL, NRMAX, B, BNRM, X, XL, ITOL, TOL, NELT, IA, JA, A,
- + ISYM, IUNIT, IFLAG, ERR)
- C***BEGIN PROLOGUE DPIGMR
- C***SUBSIDIARY
- C***PURPOSE Internal routine for DGMRES.
- C***LIBRARY SLATEC (SLAP)
- C***CATEGORY D2A4, D2B4
- C***TYPE DOUBLE PRECISION (SPIGMR-S, DPIGMR-D)
- C***KEYWORDS GENERALIZED MINIMUM RESIDUAL, ITERATIVE PRECONDITION,
- C NON-SYMMETRIC LINEAR SYSTEM, SLAP, SPARSE
- C***AUTHOR Brown, Peter, (LLNL), pnbrown@llnl.gov
- C Hindmarsh, Alan, (LLNL), alanh@llnl.gov
- C Seager, Mark K., (LLNL), seager@llnl.gov
- C Lawrence Livermore National Laboratory
- C PO Box 808, L-60
- C Livermore, CA 94550 (510) 423-3141
- C***DESCRIPTION
- C This routine solves the linear system A * Z = R0 using a
- C scaled preconditioned version of the generalized minimum
- C residual method. An initial guess of Z = 0 is assumed.
- C
- C *Usage:
- C INTEGER N, JSCAL, MAXL, MAXLP1, KMP, NRSTS, JPRE, NMSL, LGMR
- C INTEGER IPAR(USER DEFINED), NRMAX, ITOL, NELT, IA(NELT), JA(NELT)
- C INTEGER ISYM, IUNIT, IFLAG
- C DOUBLE PRECISION R0(N), SR(N), SZ(N), Z(N), V(N,MAXLP1),
- C $ HES(MAXLP1,MAXL), Q(2*MAXL), RPAR(USER DEFINED),
- C $ WK(N), DL(N), RHOL, B(N), BNRM, X(N), XL(N),
- C $ TOL, A(NELT), ERR
- C EXTERNAL MATVEC, MSOLVE
- C
- C CALL DPIGMR(N, R0, SR, SZ, JSCAL, MAXL, MAXLP1, KMP,
- C $ NRSTS, JPRE, MATVEC, MSOLVE, NMSL, Z, V, HES, Q, LGMR,
- C $ RPAR, IPAR, WK, DL, RHOL, NRMAX, B, BNRM, X, XL,
- C $ ITOL, TOL, NELT, IA, JA, A, ISYM, IUNIT, IFLAG, ERR)
- C
- C *Arguments:
- C N :IN Integer
- C The order of the matrix A, and the lengths
- C of the vectors SR, SZ, R0 and Z.
- C R0 :IN Double Precision R0(N)
- C R0 = the right hand side of the system A*Z = R0.
- C R0 is also used as workspace when computing
- C the final approximation.
- C (R0 is the same as V(*,MAXL+1) in the call to DPIGMR.)
- C SR :IN Double Precision SR(N)
- C SR is a vector of length N containing the non-zero
- C elements of the diagonal scaling matrix for R0.
- C SZ :IN Double Precision SZ(N)
- C SZ is a vector of length N containing the non-zero
- C elements of the diagonal scaling matrix for Z.
- C JSCAL :IN Integer
- C A flag indicating whether arrays SR and SZ are used.
- C JSCAL=0 means SR and SZ are not used and the
- C algorithm will perform as if all
- C SR(i) = 1 and SZ(i) = 1.
- C JSCAL=1 means only SZ is used, and the algorithm
- C performs as if all SR(i) = 1.
- C JSCAL=2 means only SR is used, and the algorithm
- C performs as if all SZ(i) = 1.
- C JSCAL=3 means both SR and SZ are used.
- C MAXL :IN Integer
- C The maximum allowable order of the matrix H.
- C MAXLP1 :IN Integer
- C MAXPL1 = MAXL + 1, used for dynamic dimensioning of HES.
- C KMP :IN Integer
- C The number of previous vectors the new vector VNEW
- C must be made orthogonal to. (KMP .le. MAXL)
- C NRSTS :IN Integer
- C Counter for the number of restarts on the current
- C call to DGMRES. If NRSTS .gt. 0, then the residual
- C R0 is already scaled, and so scaling of it is
- C not necessary.
- C JPRE :IN Integer
- C Preconditioner type flag.
- C MATVEC :EXT External.
- C Name of a routine which performs the matrix vector multiply
- C Y = A*X given A and X. The name of the MATVEC routine must
- C be declared external in the calling program. The calling
- C sequence to MATVEC is:
- C CALL MATVEC(N, X, Y, NELT, IA, JA, A, ISYM)
- C where N is the number of unknowns, Y is the product A*X
- C upon return, X is an input vector, and NELT is the number of
- C non-zeros in the SLAP IA, JA, A storage for the matrix A.
- C ISYM is a flag which, if non-zero, denotes that A is
- C symmetric and only the lower or upper triangle is stored.
- C MSOLVE :EXT External.
- C Name of the routine which solves a linear system Mz = r for
- C z given r with the preconditioning matrix M (M is supplied via
- C RPAR and IPAR arrays. The name of the MSOLVE routine must
- C be declared external in the calling program. The calling
- C sequence to MSOLVE is:
- C CALL MSOLVE(N, R, Z, NELT, IA, JA, A, ISYM, RPAR, IPAR)
- C Where N is the number of unknowns, R is the right-hand side
- C vector and Z is the solution upon return. NELT, IA, JA, A and
- C ISYM are defined as below. RPAR is a double precision array
- C that can be used to pass necessary preconditioning information
- C and/or workspace to MSOLVE. IPAR is an integer work array
- C for the same purpose as RPAR.
- C NMSL :OUT Integer
- C The number of calls to MSOLVE.
- C Z :OUT Double Precision Z(N)
- C The final computed approximation to the solution
- C of the system A*Z = R0.
- C V :OUT Double Precision V(N,MAXLP1)
- C The N by (LGMR+1) array containing the LGMR
- C orthogonal vectors V(*,1) to V(*,LGMR).
- C HES :OUT Double Precision HES(MAXLP1,MAXL)
- C The upper triangular factor of the QR decomposition
- C of the (LGMR+1) by LGMR upper Hessenberg matrix whose
- C entries are the scaled inner-products of A*V(*,I)
- C and V(*,K).
- C Q :OUT Double Precision Q(2*MAXL)
- C A double precision array of length 2*MAXL containing the
- C components of the Givens rotations used in the QR
- C decomposition of HES. It is loaded in DHEQR and used in
- C DHELS.
- C LGMR :OUT Integer
- C The number of iterations performed and
- C the current order of the upper Hessenberg
- C matrix HES.
- C RPAR :IN Double Precision RPAR(USER DEFINED)
- C Double Precision workspace passed directly to the MSOLVE
- C routine.
- C IPAR :IN Integer IPAR(USER DEFINED)
- C Integer workspace passed directly to the MSOLVE routine.
- C WK :IN Double Precision WK(N)
- C A double precision work array of length N used by routines
- C MATVEC and MSOLVE.
- C DL :INOUT Double Precision DL(N)
- C On input, a double precision work array of length N used for
- C calculation of the residual norm RHO when the method is
- C incomplete (KMP.lt.MAXL), and/or when using restarting.
- C On output, the scaled residual vector RL. It is only loaded
- C when performing restarts of the Krylov iteration.
- C RHOL :OUT Double Precision
- C A double precision scalar containing the norm of the final
- C residual.
- C NRMAX :IN Integer
- C The maximum number of restarts of the Krylov iteration.
- C NRMAX .gt. 0 means restarting is active, while
- C NRMAX = 0 means restarting is not being used.
- C B :IN Double Precision B(N)
- C The right hand side of the linear system A*X = b.
- C BNRM :IN Double Precision
- C The scaled norm of b.
- C X :IN Double Precision X(N)
- C The current approximate solution as of the last
- C restart.
- C XL :IN Double Precision XL(N)
- C An array of length N used to hold the approximate
- C solution X(L) when ITOL=11.
- C ITOL :IN Integer
- C A flag to indicate the type of convergence criterion
- C used. See the driver for its description.
- C TOL :IN Double Precision
- C The tolerance on residuals R0-A*Z in scaled norm.
- C NELT :IN Integer
- C The length of arrays IA, JA and A.
- C IA :IN Integer IA(NELT)
- C An integer array of length NELT containing matrix data.
- C It is passed directly to the MATVEC and MSOLVE routines.
- C JA :IN Integer JA(NELT)
- C An integer array of length NELT containing matrix data.
- C It is passed directly to the MATVEC and MSOLVE routines.
- C A :IN Double Precision A(NELT)
- C A double precision array of length NELT containing matrix
- C data. It is passed directly to the MATVEC and MSOLVE routines.
- C ISYM :IN Integer
- C A flag to indicate symmetric matrix storage.
- C If ISYM=0, all non-zero entries of the matrix are
- C stored. If ISYM=1, the matrix is symmetric and
- C only the upper or lower triangular part is stored.
- C IUNIT :IN Integer
- C The i/o unit number for writing intermediate residual
- C norm values.
- C IFLAG :OUT Integer
- C An integer error flag..
- C 0 means convergence in LGMR iterations, LGMR.le.MAXL.
- C 1 means the convergence test did not pass in MAXL
- C iterations, but the residual norm is .lt. norm(R0),
- C and so Z is computed.
- C 2 means the convergence test did not pass in MAXL
- C iterations, residual .ge. norm(R0), and Z = 0.
- C ERR :OUT Double Precision.
- C Error estimate of error in final approximate solution, as
- C defined by ITOL.
- C
- C *Cautions:
- C This routine will attempt to write to the Fortran logical output
- C unit IUNIT, if IUNIT .ne. 0. Thus, the user must make sure that
- C this logical unit is attached to a file or terminal before calling
- C this routine with a non-zero value for IUNIT. This routine does
- C not check for the validity of a non-zero IUNIT unit number.
- C
- C***SEE ALSO DGMRES
- C***ROUTINES CALLED DAXPY, DCOPY, DHELS, DHEQR, DNRM2, DORTH, DRLCAL,
- C DSCAL, ISDGMR
- C***REVISION HISTORY (YYMMDD)
- C 890404 DATE WRITTEN
- C 890404 Previous REVISION DATE
- C 890915 Made changes requested at July 1989 CML Meeting. (MKS)
- C 890922 Numerous changes to prologue to make closer to SLATEC
- C standard. (FNF)
- C 890929 Numerous changes to reduce SP/DP differences. (FNF)
- C 910411 Prologue converted to Version 4.0 format. (BAB)
- C 910502 Removed MATVEC and MSOLVE from ROUTINES CALLED list. (FNF)
- C 910506 Made subsidiary to DGMRES. (FNF)
- C 920511 Added complete declaration section. (WRB)
- C***END PROLOGUE DPIGMR
- C The following is for optimized compilation on LLNL/LTSS Crays.
- CLLL. OPTIMIZE
- C .. Scalar Arguments ..
- DOUBLE PRECISION BNRM, ERR, RHOL, TOL
- INTEGER IFLAG, ISYM, ITOL, IUNIT, JPRE, JSCAL, KMP, LGMR, MAXL,
- + MAXLP1, N, NELT, NMSL, NRMAX, NRSTS
- C .. Array Arguments ..
- DOUBLE PRECISION A(NELT), B(*), DL(*), HES(MAXLP1,*), Q(*), R0(*),
- + RPAR(*), SR(*), SZ(*), V(N,*), WK(*), X(*),
- + XL(*), Z(*)
- INTEGER IA(NELT), IPAR(*), JA(NELT)
- C .. Subroutine Arguments ..
- EXTERNAL MATVEC, MSOLVE
- C .. Local Scalars ..
- DOUBLE PRECISION C, DLNRM, PROD, R0NRM, RHO, S, SNORMW, TEM
- INTEGER I, I2, INFO, IP1, ITER, ITMAX, J, K, LL, LLP1
- C .. External Functions ..
- DOUBLE PRECISION DNRM2
- INTEGER ISDGMR
- EXTERNAL DNRM2, ISDGMR
- C .. External Subroutines ..
- EXTERNAL DAXPY, DCOPY, DHELS, DHEQR, DORTH, DRLCAL, DSCAL
- C .. Intrinsic Functions ..
- INTRINSIC ABS
- C***FIRST EXECUTABLE STATEMENT DPIGMR
- C
- C Zero out the Z array.
- C
- DO 5 I = 1,N
- Z(I) = 0
- 5 CONTINUE
- C
- IFLAG = 0
- LGMR = 0
- NMSL = 0
- C Load ITMAX, the maximum number of iterations.
- ITMAX =(NRMAX+1)*MAXL
- C -------------------------------------------------------------------
- C The initial residual is the vector R0.
- C Apply left precon. if JPRE < 0 and this is not a restart.
- C Apply scaling to R0 if JSCAL = 2 or 3.
- C -------------------------------------------------------------------
- IF ((JPRE .LT. 0) .AND.(NRSTS .EQ. 0)) THEN
- CALL DCOPY(N, R0, 1, WK, 1)
- CALL MSOLVE(N, WK, R0, NELT, IA, JA, A, ISYM, RPAR, IPAR)
- NMSL = NMSL + 1
- ENDIF
- IF (((JSCAL.EQ.2) .OR.(JSCAL.EQ.3)) .AND.(NRSTS.EQ.0)) THEN
- DO 10 I = 1,N
- V(I,1) = R0(I)*SR(I)
- 10 CONTINUE
- ELSE
- DO 20 I = 1,N
- V(I,1) = R0(I)
- 20 CONTINUE
- ENDIF
- R0NRM = DNRM2(N, V, 1)
- ITER = NRSTS*MAXL
- C
- C Call stopping routine ISDGMR.
- C
- IF (ISDGMR(N, B, X, XL, NELT, IA, JA, A, ISYM, MSOLVE,
- $ NMSL, ITOL, TOL, ITMAX, ITER, ERR, IUNIT, V(1,1), Z, WK,
- $ RPAR, IPAR, R0NRM, BNRM, SR, SZ, JSCAL,
- $ KMP, LGMR, MAXL, MAXLP1, V, Q, SNORMW, PROD, R0NRM,
- $ HES, JPRE) .NE. 0) RETURN
- TEM = 1.0D0/R0NRM
- CALL DSCAL(N, TEM, V(1,1), 1)
- C
- C Zero out the HES array.
- C
- DO 50 J = 1,MAXL
- DO 40 I = 1,MAXLP1
- HES(I,J) = 0
- 40 CONTINUE
- 50 CONTINUE
- C -------------------------------------------------------------------
- C Main loop to compute the vectors V(*,2) to V(*,MAXL).
- C The running product PROD is needed for the convergence test.
- C -------------------------------------------------------------------
- PROD = 1
- DO 90 LL = 1,MAXL
- LGMR = LL
- C -------------------------------------------------------------------
- C Unscale the current V(LL) and store in WK. Call routine
- C MSOLVE to compute(M-inverse)*WK, where M is the
- C preconditioner matrix. Save the answer in Z. Call routine
- C MATVEC to compute VNEW = A*Z, where A is the the system
- C matrix. save the answer in V(LL+1). Scale V(LL+1). Call
- C routine DORTH to orthogonalize the new vector VNEW =
- C V(*,LL+1). Call routine DHEQR to update the factors of HES.
- C -------------------------------------------------------------------
- IF ((JSCAL .EQ. 1) .OR.(JSCAL .EQ. 3)) THEN
- DO 60 I = 1,N
- WK(I) = V(I,LL)/SZ(I)
- 60 CONTINUE
- ELSE
- CALL DCOPY(N, V(1,LL), 1, WK, 1)
- ENDIF
- IF (JPRE .GT. 0) THEN
- CALL MSOLVE(N, WK, Z, NELT, IA, JA, A, ISYM, RPAR, IPAR)
- NMSL = NMSL + 1
- CALL MATVEC(N, Z, V(1,LL+1), NELT, IA, JA, A, ISYM)
- ELSE
- CALL MATVEC(N, WK, V(1,LL+1), NELT, IA, JA, A, ISYM)
- ENDIF
- IF (JPRE .LT. 0) THEN
- CALL DCOPY(N, V(1,LL+1), 1, WK, 1)
- CALL MSOLVE(N,WK,V(1,LL+1),NELT,IA,JA,A,ISYM,RPAR,IPAR)
- NMSL = NMSL + 1
- ENDIF
- IF ((JSCAL .EQ. 2) .OR.(JSCAL .EQ. 3)) THEN
- DO 65 I = 1,N
- V(I,LL+1) = V(I,LL+1)*SR(I)
- 65 CONTINUE
- ENDIF
- CALL DORTH(V(1,LL+1), V, HES, N, LL, MAXLP1, KMP, SNORMW)
- HES(LL+1,LL) = SNORMW
- CALL DHEQR(HES, MAXLP1, LL, Q, INFO, LL)
- IF (INFO .EQ. LL) GO TO 120
- C -------------------------------------------------------------------
- C Update RHO, the estimate of the norm of the residual R0-A*ZL.
- C If KMP < MAXL, then the vectors V(*,1),...,V(*,LL+1) are not
- C necessarily orthogonal for LL > KMP. The vector DL must then
- C be computed, and its norm used in the calculation of RHO.
- C -------------------------------------------------------------------
- PROD = PROD*Q(2*LL)
- RHO = ABS(PROD*R0NRM)
- IF ((LL.GT.KMP) .AND.(KMP.LT.MAXL)) THEN
- IF (LL .EQ. KMP+1) THEN
- CALL DCOPY(N, V(1,1), 1, DL, 1)
- DO 75 I = 1,KMP
- IP1 = I + 1
- I2 = I*2
- S = Q(I2)
- C = Q(I2-1)
- DO 70 K = 1,N
- DL(K) = S*DL(K) + C*V(K,IP1)
- 70 CONTINUE
- 75 CONTINUE
- ENDIF
- S = Q(2*LL)
- C = Q(2*LL-1)/SNORMW
- LLP1 = LL + 1
- DO 80 K = 1,N
- DL(K) = S*DL(K) + C*V(K,LLP1)
- 80 CONTINUE
- DLNRM = DNRM2(N, DL, 1)
- RHO = RHO*DLNRM
- ENDIF
- RHOL = RHO
- C -------------------------------------------------------------------
- C Test for convergence. If passed, compute approximation ZL.
- C If failed and LL < MAXL, then continue iterating.
- C -------------------------------------------------------------------
- ITER = NRSTS*MAXL + LGMR
- IF (ISDGMR(N, B, X, XL, NELT, IA, JA, A, ISYM, MSOLVE,
- $ NMSL, ITOL, TOL, ITMAX, ITER, ERR, IUNIT, DL, Z, WK,
- $ RPAR, IPAR, RHOL, BNRM, SR, SZ, JSCAL,
- $ KMP, LGMR, MAXL, MAXLP1, V, Q, SNORMW, PROD, R0NRM,
- $ HES, JPRE) .NE. 0) GO TO 200
- IF (LL .EQ. MAXL) GO TO 100
- C -------------------------------------------------------------------
- C Rescale so that the norm of V(1,LL+1) is one.
- C -------------------------------------------------------------------
- TEM = 1.0D0/SNORMW
- CALL DSCAL(N, TEM, V(1,LL+1), 1)
- 90 CONTINUE
- 100 CONTINUE
- IF (RHO .LT. R0NRM) GO TO 150
- 120 CONTINUE
- IFLAG = 2
- C
- C Load approximate solution with zero.
- C
- DO 130 I = 1,N
- Z(I) = 0
- 130 CONTINUE
- RETURN
- 150 IFLAG = 1
- C
- C Tolerance not met, but residual norm reduced.
- C
- IF (NRMAX .GT. 0) THEN
- C
- C If performing restarting (NRMAX > 0) calculate the residual
- C vector RL and store it in the DL array. If the incomplete
- C version is being used (KMP < MAXL) then DL has already been
- C calculated up to a scaling factor. Use DRLCAL to calculate
- C the scaled residual vector.
- C
- CALL DRLCAL(N, KMP, MAXL, MAXL, V, Q, DL, SNORMW, PROD,
- $ R0NRM)
- ENDIF
- C -------------------------------------------------------------------
- C Compute the approximation ZL to the solution. Since the
- C vector Z was used as workspace, and the initial guess
- C of the linear iteration is zero, Z must be reset to zero.
- C -------------------------------------------------------------------
- 200 CONTINUE
- LL = LGMR
- LLP1 = LL + 1
- DO 210 K = 1,LLP1
- R0(K) = 0
- 210 CONTINUE
- R0(1) = R0NRM
- CALL DHELS(HES, MAXLP1, LL, Q, R0)
- DO 220 K = 1,N
- Z(K) = 0
- 220 CONTINUE
- DO 230 I = 1,LL
- CALL DAXPY(N, R0(I), V(1,I), 1, Z, 1)
- 230 CONTINUE
- IF ((JSCAL .EQ. 1) .OR.(JSCAL .EQ. 3)) THEN
- DO 240 I = 1,N
- Z(I) = Z(I)/SZ(I)
- 240 CONTINUE
- ENDIF
- IF (JPRE .GT. 0) THEN
- CALL DCOPY(N, Z, 1, WK, 1)
- CALL MSOLVE(N, WK, Z, NELT, IA, JA, A, ISYM, RPAR, IPAR)
- NMSL = NMSL + 1
- ENDIF
- RETURN
- C------------- LAST LINE OF DPIGMR FOLLOWS ----------------------------
- END
|