dnedk.f

Go to the documentation of this file.
00001 C Work performed under the auspices of the U.S. Department of Energy
00002 C by Lawrence Livermore National Laboratory under contract number 
00003 C W-7405-Eng-48.
00004 C
00005       SUBROUTINE DNEDK(X,Y,YPRIME,NEQ,RES,JACK,PSOL,
00006      *   H,WT,JSTART,IDID,RPAR,IPAR,PHI,GAMMA,SAVR,DELTA,E,
00007      *   WM,IWM,CJ,CJOLD,CJLAST,S,UROUND,EPLI,SQRTN,RSQRTN,
00008      *   EPCON,JCALC,JFLG,KP1,NONNEG,NTYPE,IERNLS)
00009 C
00010 C***BEGIN PROLOGUE  DNEDK
00011 C***REFER TO  DDASPK
00012 C***DATE WRITTEN   891219   (YYMMDD)
00013 C***REVISION DATE  900926   (YYMMDD)
00014 C***REVISION DATE  940701   (YYMMDD)
00015 C
00016 C
00017 C-----------------------------------------------------------------------
00018 C***DESCRIPTION
00019 C
00020 C     DNEDK solves a nonlinear system of
00021 C     algebraic equations of the form
00022 C     G(X,Y,YPRIME) = 0 for the unknown Y.
00023 C
00024 C     The method used is a matrix-free Newton scheme.
00025 C
00026 C     The parameters represent
00027 C     X         -- Independent variable.
00028 C     Y         -- Solution vector at x.
00029 C     YPRIME    -- Derivative of solution vector
00030 C                  after successful step.
00031 C     NEQ       -- Number of equations to be integrated.
00032 C     RES       -- External user-supplied subroutine
00033 C                  to evaluate the residual.  See RES description
00034 C                  in DDASPK prologue.
00035 C     JACK     --  External user-supplied routine to update
00036 C                  the preconditioner.  (This is optional).
00037 C                  See JAC description for the case
00038 C                  INFO(12) = 1 in the DDASPK prologue.
00039 C     PSOL      -- External user-supplied routine to solve
00040 C                  a linear system using preconditioning. 
00041 C                  (This is optional).  See explanation inside DDASPK.
00042 C     H         -- Appropriate step size for this step.
00043 C     WT        -- Vector of weights for error criterion.
00044 C     JSTART    -- Indicates first call to this routine.
00045 C                  If JSTART = 0, then this is the first call,
00046 C                  otherwise it is not.
00047 C     IDID      -- Completion flag, output by DNEDK.
00048 C                  See IDID description in DDASPK prologue.
00049 C     RPAR,IPAR -- Real and integer arrays used for communication
00050 C                  between the calling program and external user
00051 C                  routines.  They are not altered within DASPK.
00052 C     PHI       -- Array of divided differences used by
00053 C                  DNEDK.  The length is NEQ*(K+1), where
00054 C                  K is the maximum order.
00055 C     GAMMA     -- Array used to predict Y and YPRIME.  The length
00056 C                  is K+1, where K is the maximum order.
00057 C     SAVR      -- Work vector for DNEDK of length NEQ.
00058 C     DELTA     -- Work vector for DNEDK of length NEQ.
00059 C     E         -- Error accumulation vector for DNEDK of length NEQ.
00060 C     WM,IWM    -- Real and integer arrays storing
00061 C                  matrix information for linear system
00062 C                  solvers, and various other information.
00063 C     CJ        -- Parameter always proportional to 1/H.
00064 C     CJOLD     -- Saves the value of CJ as of the last call to DITMD.
00065 C                  Accounts for changes in CJ needed to
00066 C                  decide whether to call DITMD.
00067 C     CJLAST    -- Previous value of CJ.
00068 C     S         -- A scalar determined by the approximate rate
00069 C                  of convergence of the Newton iteration and used
00070 C                  in the convergence test for the Newton iteration.
00071 C
00072 C                  If RATE is defined to be an estimate of the
00073 C                  rate of convergence of the Newton iteration,
00074 C                  then S = RATE/(1.D0-RATE).
00075 C
00076 C                  The closer RATE is to 0., the faster the Newton
00077 C                  iteration is converging; the closer RATE is to 1.,
00078 C                  the slower the Newton iteration is converging.
00079 C
00080 C                  On the first Newton iteration with an up-dated
00081 C                  preconditioner S = 100.D0, Thus the initial
00082 C                  RATE of convergence is approximately 1.
00083 C
00084 C                  S is preserved from call to call so that the rate
00085 C                  estimate from a previous step can be applied to
00086 C                  the current step.
00087 C     UROUND    -- Unit roundoff.
00088 C     EPLI      -- convergence test constant.
00089 C                  See DDASPK prologue for more details.
00090 C     SQRTN     -- Square root of NEQ.
00091 C     RSQRTN    -- reciprical of square root of NEQ.
00092 C     EPCON     -- Tolerance to test for convergence of the Newton
00093 C                  iteration.
00094 C     JCALC     -- Flag used to determine when to update
00095 C                  the Jacobian matrix.  In general:
00096 C
00097 C                  JCALC = -1 ==> Call the DITMD routine to update
00098 C                                 the Jacobian matrix.
00099 C                  JCALC =  0 ==> Jacobian matrix is up-to-date.
00100 C                  JCALC =  1 ==> Jacobian matrix is out-dated,
00101 C                                 but DITMD will not be called unless
00102 C                                 JCALC is set to -1.
00103 C     JFLG      -- Flag showing whether a Jacobian routine is supplied.
00104 C     KP1       -- The current order + 1;  updated across calls.
00105 C     NONNEG    -- Flag to determine nonnegativity constraints.
00106 C     NTYPE     -- Identification code for the DNEDK routine.
00107 C                   1 ==> modified Newton; iterative linear solver.
00108 C                   2 ==> modified Newton; user-supplied linear solver.
00109 C     IERNLS    -- Error flag for nonlinear solver.
00110 C                   0 ==> nonlinear solver converged.
00111 C                   1 ==> recoverable error inside non-linear solver.
00112 C                  -1 ==> unrecoverable error inside non-linear solver.
00113 C
00114 C     The following group of variables are passed as arguments to
00115 C     the Newton iteration solver.  They are explained in greater detail
00116 C     in DNSK:
00117 C        TOLNEW, MULDEL, MAXIT, IERNEW
00118 C
00119 C     IERTYP -- Flag which tells whether this subroutine is correct.
00120 C               0 ==> correct subroutine.
00121 C               1 ==> incorrect subroutine.
00122 C
00123 C-----------------------------------------------------------------------
00124 C***ROUTINES CALLED
00125 C   RES, JACK, DDWNRM, DNSK
00126 C
00127 C***END PROLOGUE  DNEDK
00128 C
00129 C
00130       IMPLICIT DOUBLE PRECISION(A-H,O-Z)
00131       DIMENSION Y(*),YPRIME(*),WT(*)
00132       DIMENSION PHI(NEQ,*),SAVR(*),DELTA(*),E(*)
00133       DIMENSION WM(*),IWM(*)
00134       DIMENSION GAMMA(*),RPAR(*),IPAR(*)
00135       EXTERNAL  RES, JACK, PSOL
00136 C
00137       PARAMETER (LNRE=12, LNJE=13, LLOCWP=29, LLCIWP=30)
00138 C
00139       SAVE MULDEL, MAXIT, XRATE
00140       DATA MULDEL/0/, MAXIT/4/, XRATE/0.25D0/
00141 C
00142 C     Verify that this is the correct subroutine.
00143 C
00144       IERTYP = 0
00145       IF (NTYPE .NE. 1) THEN
00146          IERTYP = 1
00147          GO TO 380
00148          ENDIF
00149 C
00150 C     If this is the first step, perform initializations.
00151 C
00152       IF (JSTART .EQ. 0) THEN
00153          CJOLD = CJ
00154          JCALC = -1
00155          S = 100.D0
00156          ENDIF
00157 C
00158 C     Perform all other initializations.
00159 C
00160       IERNLS = 0
00161       LWP = IWM(LLOCWP)
00162       LIWP = IWM(LLCIWP)
00163 C
00164 C     Decide whether to update the preconditioner.
00165 C
00166       IF (JFLG .NE. 0) THEN
00167          TEMP1 = (1.0D0 - XRATE)/(1.0D0 + XRATE)
00168          TEMP2 = 1.0D0/TEMP1
00169          IF (CJ/CJOLD .LT. TEMP1 .OR. CJ/CJOLD .GT. TEMP2) JCALC = -1
00170          IF (CJ .NE. CJLAST) S = 100.D0
00171       ELSE
00172          JCALC = 0
00173          ENDIF
00174 C
00175 C     Looping point for updating preconditioner with current stepsize.
00176 C
00177 300   CONTINUE
00178 C
00179 C     Initialize all error flags to zero.
00180 C
00181       IERPJ = 0
00182       IRES = 0
00183       IERSL = 0
00184       IERNEW = 0
00185 C
00186 C     Predict the solution and derivative and compute the tolerance
00187 C     for the Newton iteration.
00188 C
00189       DO 310 I=1,NEQ
00190          Y(I)=PHI(I,1)
00191 310      YPRIME(I)=0.0D0
00192       DO 330 J=2,KP1
00193          DO 320 I=1,NEQ
00194             Y(I)=Y(I)+PHI(I,J)
00195 320         YPRIME(I)=YPRIME(I)+GAMMA(J)*PHI(I,J)
00196 330   CONTINUE
00197       EPLIN = EPLI*EPCON
00198       TOLNEW = EPLIN
00199 C
00200 C     Call RES to initialize DELTA.
00201 C
00202       IWM(LNRE)=IWM(LNRE)+1
00203       CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
00204       IF (IRES .LT. 0) GO TO 380
00205 C
00206 C
00207 C     If indicated, update the preconditioner.
00208 C     Set JCALC to 0 as an indicator that this has been done.
00209 C
00210       IF(JCALC .EQ. -1)THEN
00211          IWM(LNJE) = IWM(LNJE) + 1
00212          JCALC=0
00213          CALL JACK (RES, IRES, NEQ, X, Y, YPRIME, WT, DELTA, E, H, CJ,
00214      *      WM(LWP), IWM(LIWP), IERPJ, RPAR, IPAR)
00215          CJOLD=CJ
00216          S = 100.D0
00217          IF (IRES .LT. 0)  GO TO 380
00218          IF (IERPJ .NE. 0) GO TO 380
00219       ENDIF
00220 C
00221 C     Call the nonlinear Newton solver.
00222 C
00223       CALL DNSK(X,Y,YPRIME,NEQ,RES,PSOL,WT,RPAR,IPAR,SAVR,
00224      *   DELTA,E,WM,IWM,CJ,SQRTN,RSQRTN,EPLIN,EPCON,
00225      *   S,TEMP1,TOLNEW,MULDEL,MAXIT,IRES,IERSL,IERNEW)
00226 C
00227       IF (IERNEW .GT. 0 .AND. JCALC .NE. 0) THEN
00228 C
00229 C     The Newton iteration had a recoverable failure with an old
00230 C     preconditioner.  Retry the step with a new preconditioner.
00231 C
00232          JCALC = -1
00233          GO TO 300
00234       ENDIF
00235 C
00236       IF (IERNEW .NE. 0) GO TO 380
00237 C
00238 C     The Newton iteration has converged.  If nonnegativity of
00239 C     solution is required, set the solution nonnegative, if the
00240 C     perturbation to do it is small enough.  If the change is too
00241 C     large, then consider the corrector iteration to have failed.
00242 C
00243       IF(NONNEG .EQ. 0) GO TO 390
00244       DO 360 I = 1,NEQ
00245  360    DELTA(I) = MIN(Y(I),0.0D0)
00246       DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
00247       IF(DELNRM .GT. EPCON) GO TO 380
00248       DO 370 I = 1,NEQ
00249  370    E(I) = E(I) - DELTA(I)
00250       GO TO 390
00251 C
00252 C
00253 C     Exits from nonlinear solver.
00254 C     No convergence with current preconditioner.
00255 C     Compute IERNLS and IDID accordingly.
00256 C
00257 380   CONTINUE
00258       IF (IRES .LE. -2 .OR. IERSL .LT. 0 .OR. IERTYP .NE. 0) THEN
00259          IERNLS = -1
00260          IF (IRES .LE. -2) IDID = -11
00261          IF (IERSL .LT. 0) IDID = -13
00262          IF (IERTYP .NE. 0) IDID = -15
00263       ELSE
00264          IERNLS =  1
00265          IF (IRES .EQ. -1) IDID = -10
00266          IF (IERPJ .NE. 0) IDID = -5
00267          IF (IERSL .GT. 0) IDID = -14
00268       ENDIF
00269 C
00270 C
00271 390   JCALC = 1
00272       RETURN
00273 C
00274 C------END OF SUBROUTINE DNEDK------------------------------------------
00275       END
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines