123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- *DECK SDAINI
- SUBROUTINE SDAINI (X, Y, YPRIME, NEQ, RES, JAC, H, WT, IDID, RPAR,
- * IPAR, PHI, DELTA, E, WM, IWM, HMIN, UROUND, NONNEG, NTEMP)
- C***BEGIN PROLOGUE SDAINI
- C***SUBSIDIARY
- C***PURPOSE Initialization routine for SDASSL.
- C***LIBRARY SLATEC (DASSL)
- C***TYPE SINGLE PRECISION (SDAINI-S, DDAINI-D)
- C***AUTHOR Petzold, Linda R., (LLNL)
- C***DESCRIPTION
- C-----------------------------------------------------------------
- C SDAINI TAKES ONE STEP OF SIZE H OR SMALLER
- C WITH THE BACKWARD EULER METHOD, TO
- C FIND YPRIME. X AND Y ARE UPDATED TO BE CONSISTENT WITH THE
- C NEW STEP. A MODIFIED DAMPED NEWTON ITERATION IS USED TO
- C SOLVE THE CORRECTOR ITERATION.
- C
- C THE INITIAL GUESS FOR YPRIME IS USED IN THE
- C PREDICTION, AND IN FORMING THE ITERATION
- C MATRIX, BUT IS NOT INVOLVED IN THE
- C ERROR TEST. THIS MAY HAVE TROUBLE
- C CONVERGING IF THE INITIAL GUESS IS NO
- C GOOD, OR IF G(X,Y,YPRIME) DEPENDS
- C NONLINEARLY ON YPRIME.
- C
- C THE PARAMETERS REPRESENT:
- C X -- INDEPENDENT VARIABLE
- C Y -- SOLUTION VECTOR AT X
- C YPRIME -- DERIVATIVE OF SOLUTION VECTOR
- C NEQ -- NUMBER OF EQUATIONS
- C H -- STEPSIZE. IMDER MAY USE A STEPSIZE
- C SMALLER THAN H.
- C WT -- VECTOR OF WEIGHTS FOR ERROR
- C CRITERION
- C IDID -- COMPLETION CODE WITH THE FOLLOWING MEANINGS
- C IDID= 1 -- YPRIME WAS FOUND SUCCESSFULLY
- C IDID=-12 -- SDAINI FAILED TO FIND YPRIME
- C RPAR,IPAR -- REAL AND INTEGER PARAMETER ARRAYS
- C THAT ARE NOT ALTERED BY SDAINI
- C PHI -- WORK SPACE FOR SDAINI
- C DELTA,E -- WORK SPACE FOR SDAINI
- C WM,IWM -- REAL AND INTEGER ARRAYS STORING
- C MATRIX INFORMATION
- C
- C-----------------------------------------------------------------
- C***ROUTINES CALLED SDAJAC, SDANRM, SDASLV
- C***REVISION HISTORY (YYMMDD)
- C 830315 DATE WRITTEN
- C 901009 Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
- C 901019 Merged changes made by C. Ulrich with SLATEC 4.0 format.
- C 901026 Added explicit declarations for all variables and minor
- C cosmetic changes to prologue. (FNF)
- C 901030 Minor corrections to declarations. (FNF)
- C***END PROLOGUE SDAINI
- C
- INTEGER NEQ, IDID, IPAR(*), IWM(*), NONNEG, NTEMP
- REAL X, Y(*), YPRIME(*), H, WT(*), RPAR(*), PHI(NEQ,*), DELTA(*),
- * E(*), WM(*), HMIN, UROUND
- EXTERNAL RES, JAC
- C
- EXTERNAL SDAJAC, SDANRM, SDASLV
- REAL SDANRM
- C
- INTEGER I, IER, IRES, JCALC, LNJE, LNRE, M, MAXIT, MJAC, NCF,
- * NEF, NSF
- REAL CJ, DAMP, DELNRM, ERR, OLDNRM, R, RATE, S, XOLD, YNORM
- LOGICAL CONVGD
- C
- PARAMETER (LNRE=12)
- PARAMETER (LNJE=13)
- C
- DATA MAXIT/10/,MJAC/5/
- DATA DAMP/0.75E0/
- C
- C
- C---------------------------------------------------
- C BLOCK 1.
- C INITIALIZATIONS.
- C---------------------------------------------------
- C
- C***FIRST EXECUTABLE STATEMENT SDAINI
- IDID=1
- NEF=0
- NCF=0
- NSF=0
- XOLD=X
- YNORM=SDANRM(NEQ,Y,WT,RPAR,IPAR)
- C
- C SAVE Y AND YPRIME IN PHI
- DO 100 I=1,NEQ
- PHI(I,1)=Y(I)
- 100 PHI(I,2)=YPRIME(I)
- C
- C
- C----------------------------------------------------
- C BLOCK 2.
- C DO ONE BACKWARD EULER STEP.
- C----------------------------------------------------
- C
- C SET UP FOR START OF CORRECTOR ITERATION
- 200 CJ=1.0E0/H
- X=X+H
- C
- C PREDICT SOLUTION AND DERIVATIVE
- DO 250 I=1,NEQ
- 250 Y(I)=Y(I)+H*YPRIME(I)
- C
- JCALC=-1
- M=0
- CONVGD=.TRUE.
- C
- C
- C CORRECTOR LOOP.
- 300 IWM(LNRE)=IWM(LNRE)+1
- IRES=0
- C
- CALL RES(X,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
- IF (IRES.LT.0) GO TO 430
- C
- C
- C EVALUATE THE ITERATION MATRIX
- IF (JCALC.NE.-1) GO TO 310
- IWM(LNJE)=IWM(LNJE)+1
- JCALC=0
- CALL SDAJAC(NEQ,X,Y,YPRIME,DELTA,CJ,H,
- * IER,WT,E,WM,IWM,RES,IRES,
- * UROUND,JAC,RPAR,IPAR,NTEMP)
- C
- S=1000000.E0
- IF (IRES.LT.0) GO TO 430
- IF (IER.NE.0) GO TO 430
- NSF=0
- C
- C
- C
- C MULTIPLY RESIDUAL BY DAMPING FACTOR
- 310 CONTINUE
- DO 320 I=1,NEQ
- 320 DELTA(I)=DELTA(I)*DAMP
- C
- C COMPUTE A NEW ITERATE (BACK SUBSTITUTION)
- C STORE THE CORRECTION IN DELTA
- C
- CALL SDASLV(NEQ,DELTA,WM,IWM)
- C
- C UPDATE Y AND YPRIME
- DO 330 I=1,NEQ
- Y(I)=Y(I)-DELTA(I)
- 330 YPRIME(I)=YPRIME(I)-CJ*DELTA(I)
- C
- C TEST FOR CONVERGENCE OF THE ITERATION.
- C
- DELNRM=SDANRM(NEQ,DELTA,WT,RPAR,IPAR)
- IF (DELNRM.LE.100.E0*UROUND*YNORM)
- * GO TO 400
- C
- IF (M.GT.0) GO TO 340
- OLDNRM=DELNRM
- GO TO 350
- C
- 340 RATE=(DELNRM/OLDNRM)**(1.0E0/M)
- IF (RATE.GT.0.90E0) GO TO 430
- S=RATE/(1.0E0-RATE)
- C
- 350 IF (S*DELNRM .LE. 0.33E0) GO TO 400
- C
- C
- C THE CORRECTOR HAS NOT YET CONVERGED. UPDATE
- C M AND AND TEST WHETHER THE MAXIMUM
- C NUMBER OF ITERATIONS HAVE BEEN TRIED.
- C EVERY MJAC ITERATIONS, GET A NEW
- C ITERATION MATRIX.
- C
- M=M+1
- IF (M.GE.MAXIT) GO TO 430
- C
- IF ((M/MJAC)*MJAC.EQ.M) JCALC=-1
- GO TO 300
- C
- C
- C THE ITERATION HAS CONVERGED.
- C CHECK NONNEGATIVITY CONSTRAINTS
- 400 IF (NONNEG.EQ.0) GO TO 450
- DO 410 I=1,NEQ
- 410 DELTA(I)=MIN(Y(I),0.0E0)
- C
- DELNRM=SDANRM(NEQ,DELTA,WT,RPAR,IPAR)
- IF (DELNRM.GT.0.33E0) GO TO 430
- C
- DO 420 I=1,NEQ
- Y(I)=Y(I)-DELTA(I)
- 420 YPRIME(I)=YPRIME(I)-CJ*DELTA(I)
- GO TO 450
- C
- C
- C EXITS FROM CORRECTOR LOOP.
- 430 CONVGD=.FALSE.
- 450 IF (.NOT.CONVGD) GO TO 600
- C
- C
- C
- C-----------------------------------------------------
- C BLOCK 3.
- C THE CORRECTOR ITERATION CONVERGED.
- C DO ERROR TEST.
- C-----------------------------------------------------
- C
- DO 510 I=1,NEQ
- 510 E(I)=Y(I)-PHI(I,1)
- ERR=SDANRM(NEQ,E,WT,RPAR,IPAR)
- C
- IF (ERR.LE.1.0E0) RETURN
- C
- C
- C
- C--------------------------------------------------------
- C BLOCK 4.
- C THE BACKWARD EULER STEP FAILED. RESTORE X, Y
- C AND YPRIME TO THEIR ORIGINAL VALUES.
- C REDUCE STEPSIZE AND TRY AGAIN, IF
- C POSSIBLE.
- C---------------------------------------------------------
- C
- 600 CONTINUE
- X = XOLD
- DO 610 I=1,NEQ
- Y(I)=PHI(I,1)
- 610 YPRIME(I)=PHI(I,2)
- C
- IF (CONVGD) GO TO 640
- IF (IER.EQ.0) GO TO 620
- NSF=NSF+1
- H=H*0.25E0
- IF (NSF.LT.3.AND.ABS(H).GE.HMIN) GO TO 690
- IDID=-12
- RETURN
- 620 IF (IRES.GT.-2) GO TO 630
- IDID=-12
- RETURN
- 630 NCF=NCF+1
- H=H*0.25E0
- IF (NCF.LT.10.AND.ABS(H).GE.HMIN) GO TO 690
- IDID=-12
- RETURN
- C
- 640 NEF=NEF+1
- R=0.90E0/(2.0E0*ERR+0.0001E0)
- R=MAX(0.1E0,MIN(0.5E0,R))
- H=H*R
- IF (ABS(H).GE.HMIN.AND.NEF.LT.10) GO TO 690
- IDID=-12
- RETURN
- 690 GO TO 200
- C
- C-------------END OF SUBROUTINE SDAINI----------------------
- END
|