123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- *DECK DLSOD
- SUBROUTINE DLSOD (DF, NEQ, T, Y, TOUT, RTOL, ATOL, IDID, YPOUT,
- + YH, YH1, EWT, SAVF, ACOR, WM, IWM, DJAC, INTOUT, TSTOP, TOLFAC,
- + DELSGN, RPAR, IPAR)
- C***BEGIN PROLOGUE DLSOD
- C***SUBSIDIARY
- C***PURPOSE Subsidiary to DDEBDF
- C***LIBRARY SLATEC
- C***TYPE DOUBLE PRECISION (LSOD-S, DLSOD-D)
- C***AUTHOR (UNKNOWN)
- C***DESCRIPTION
- C
- C DDEBDF merely allocates storage for DLSOD to relieve the user of
- C the inconvenience of a long call list. Consequently DLSOD is used
- C as described in the comments for DDEBDF .
- C
- C***SEE ALSO DDEBDF
- C***ROUTINES CALLED D1MACH, DHSTRT, DINTYD, DSTOD, DVNRMS, XERMSG
- C***COMMON BLOCKS DDEBD1
- C***REVISION HISTORY (YYMMDD)
- C 820301 DATE WRITTEN
- C 890531 Changed all specific intrinsics to generic. (WRB)
- C 890831 Modified array declarations. (WRB)
- C 891214 Prologue converted to Version 4.0 format. (BAB)
- C 900328 Added TYPE section. (WRB)
- C 900510 Convert XERRWV calls to XERMSG calls. (RWC)
- C***END PROLOGUE DLSOD
- C
- INTEGER IBAND, IBEGIN, IDID, IER, IINTEG, IJAC, INIT, INTFLG,
- 1 IOWNS, IPAR, IQUIT, ITOL, ITSTOP, IWM, JSTART, K, KFLAG,
- 2 KSTEPS, L, LACOR, LDUM, LEWT, LSAVF, LTOL, LWM, LYH, MAXNUM,
- 3 MAXORD, METH, MITER, N, NATOLP, NEQ, NFE, NJE, NQ, NQU,
- 4 NRTOLP, NST
- DOUBLE PRECISION ABSDEL, ACOR, ATOL, BIG, D1MACH, DEL,
- 1 DELSGN, DT, DVNRMS, EL0, EWT,
- 2 H, HA, HMIN, HMXI, HU, ROWNS, RPAR, RTOL, SAVF, T, TOL,
- 3 TOLD, TOLFAC, TOUT, TSTOP, U, WM, X, Y, YH, YH1, YPOUT
- LOGICAL INTOUT
- CHARACTER*8 XERN1
- CHARACTER*16 XERN3, XERN4
- C
- DIMENSION Y(*),YPOUT(*),YH(NEQ,6),YH1(*),EWT(*),SAVF(*),
- 1 ACOR(*),WM(*),IWM(*),RTOL(*),ATOL(*),RPAR(*),IPAR(*)
- C
- C
- COMMON /DDEBD1/ TOLD,ROWNS(210),EL0,H,HMIN,HMXI,HU,X,U,IQUIT,INIT,
- 1 LYH,LEWT,LACOR,LSAVF,LWM,KSTEPS,IBEGIN,ITOL,
- 2 IINTEG,ITSTOP,IJAC,IBAND,IOWNS(6),IER,JSTART,
- 3 KFLAG,LDUM,METH,MITER,MAXORD,N,NQ,NST,NFE,NJE,NQU
- C
- EXTERNAL DF, DJAC
- C
- C ..................................................................
- C
- C THE EXPENSE OF SOLVING THE PROBLEM IS MONITORED BY COUNTING THE
- C NUMBER OF STEPS ATTEMPTED. WHEN THIS EXCEEDS MAXNUM, THE
- C COUNTER IS RESET TO ZERO AND THE USER IS INFORMED ABOUT POSSIBLE
- C EXCESSIVE WORK.
- SAVE MAXNUM
- C
- DATA MAXNUM /500/
- C
- C ..................................................................
- C
- C***FIRST EXECUTABLE STATEMENT DLSOD
- IF (IBEGIN .EQ. 0) THEN
- C
- C ON THE FIRST CALL , PERFORM INITIALIZATION --
- C DEFINE THE MACHINE UNIT ROUNDOFF QUANTITY U BY CALLING THE
- C FUNCTION ROUTINE D1MACH. THE USER MUST MAKE SURE THAT THE
- C VALUES SET IN D1MACH ARE RELEVANT TO THE COMPUTER BEING USED.
- C
- U = D1MACH(4)
- C -- SET ASSOCIATED MACHINE DEPENDENT PARAMETER
- WM(1) = SQRT(U)
- C -- SET TERMINATION FLAG
- IQUIT = 0
- C -- SET INITIALIZATION INDICATOR
- INIT = 0
- C -- SET COUNTER FOR ATTEMPTED STEPS
- KSTEPS = 0
- C -- SET INDICATOR FOR INTERMEDIATE-OUTPUT
- INTOUT = .FALSE.
- C -- SET START INDICATOR FOR DSTOD CODE
- JSTART = 0
- C -- SET BDF METHOD INDICATOR
- METH = 2
- C -- SET MAXIMUM ORDER FOR BDF METHOD
- MAXORD = 5
- C -- SET ITERATION MATRIX INDICATOR
- C
- IF (IJAC .EQ. 0 .AND. IBAND .EQ. 0) MITER = 2
- IF (IJAC .EQ. 1 .AND. IBAND .EQ. 0) MITER = 1
- IF (IJAC .EQ. 0 .AND. IBAND .EQ. 1) MITER = 5
- IF (IJAC .EQ. 1 .AND. IBAND .EQ. 1) MITER = 4
- C
- C -- SET OTHER NECESSARY ITEMS IN COMMON BLOCK
- N = NEQ
- NST = 0
- NJE = 0
- HMXI = 0.0D0
- NQ = 1
- H = 1.0D0
- C -- RESET IBEGIN FOR SUBSEQUENT CALLS
- IBEGIN = 1
- ENDIF
- C
- C ..................................................................
- C
- C CHECK VALIDITY OF INPUT PARAMETERS ON EACH ENTRY
- C
- IF (NEQ .LT. 1) THEN
- WRITE (XERN1, '(I8)') NEQ
- CALL XERMSG ('SLATEC', 'DLSOD',
- * 'IN DDEBDF, THE NUMBER OF EQUATIONS MUST BE A ' //
- * 'POSITIVE INTEGER.$$YOU HAVE CALLED THE CODE WITH NEQ = ' //
- * XERN1, 6, 1)
- IDID=-33
- ENDIF
- C
- NRTOLP = 0
- NATOLP = 0
- DO 60 K = 1, NEQ
- IF (NRTOLP .LE. 0) THEN
- IF (RTOL(K) .LT. 0.) THEN
- WRITE (XERN1, '(I8)') K
- WRITE (XERN3, '(1PE15.6)') RTOL(K)
- CALL XERMSG ('SLATEC', 'DLSOD',
- * 'IN DDEBDF, THE RELATIVE ERROR TOLERANCES MUST ' //
- * 'BE NON-NEGATIVE.$$YOU HAVE CALLED THE CODE WITH ' //
- * 'RTOL(' // XERN1 // ') = ' // XERN3 // '$$IN THE ' //
- * 'CASE OF VECTOR ERROR TOLERANCES, NO FURTHER ' //
- * 'CHECKING OF RTOL COMPONENTS IS DONE.', 7, 1)
- IDID = -33
- IF (NATOLP .GT. 0) GO TO 70
- NRTOLP = 1
- ELSEIF (NATOLP .GT. 0) THEN
- GO TO 50
- ENDIF
- ENDIF
- C
- IF (ATOL(K) .LT. 0.) THEN
- WRITE (XERN1, '(I8)') K
- WRITE (XERN3, '(1PE15.6)') ATOL(K)
- CALL XERMSG ('SLATEC', 'DLSOD',
- * 'IN DDEBDF, THE ABSOLUTE ERROR ' //
- * 'TOLERANCES MUST BE NON-NEGATIVE.$$YOU HAVE CALLED ' //
- * 'THE CODE WITH ATOL(' // XERN1 // ') = ' // XERN3 //
- * '$$IN THE CASE OF VECTOR ERROR TOLERANCES, NO FURTHER '
- * // 'CHECKING OF ATOL COMPONENTS IS DONE.', 8, 1)
- IDID=-33
- IF (NRTOLP .GT. 0) GO TO 70
- NATOLP=1
- ENDIF
- 50 IF (ITOL .EQ. 0) GO TO 70
- 60 CONTINUE
- C
- 70 IF (ITSTOP .EQ. 1) THEN
- IF (SIGN(1.0D0,TOUT-T) .NE. SIGN(1.0D0,TSTOP-T) .OR.
- 1 ABS(TOUT-T) .GT. ABS(TSTOP-T)) THEN
- WRITE (XERN3, '(1PE15.6)') TOUT
- WRITE (XERN4, '(1PE15.6)') TSTOP
- CALL XERMSG ('SLATEC', 'DLSOD',
- * 'IN DDEBDF, YOU HAVE CALLED THE ' //
- * 'CODE WITH TOUT = ' // XERN3 // '$$BUT YOU HAVE ' //
- * 'ALSO TOLD THE CODE NOT TO INTEGRATE PAST THE POINT ' //
- * 'TSTOP = ' // XERN4 // ' BY SETTING INFO(4) = 1.$$' //
- * 'THESE INSTRUCTIONS CONFLICT.', 14, 1)
- IDID=-33
- ENDIF
- ENDIF
- C
- C CHECK SOME CONTINUATION POSSIBILITIES
- C
- IF (INIT .NE. 0) THEN
- IF (T .EQ. TOUT) THEN
- WRITE (XERN3, '(1PE15.6)') T
- CALL XERMSG ('SLATEC', 'DLSOD',
- * 'IN DDEBDF, YOU HAVE CALLED THE CODE WITH T = TOUT = ' //
- * XERN3 // '$$THIS IS NOT ALLOWED ON CONTINUATION CALLS.',
- * 9, 1)
- IDID=-33
- ENDIF
- C
- IF (T .NE. TOLD) THEN
- WRITE (XERN3, '(1PE15.6)') TOLD
- WRITE (XERN4, '(1PE15.6)') T
- CALL XERMSG ('SLATEC', 'DLSOD',
- * 'IN DDEBDF, YOU HAVE CHANGED THE VALUE OF T FROM ' //
- * XERN3 // ' TO ' // XERN4 //
- * ' THIS IS NOT ALLOWED ON CONTINUATION CALLS.', 10, 1)
- IDID=-33
- ENDIF
- C
- IF (INIT .NE. 1) THEN
- IF (DELSGN*(TOUT-T) .LT. 0.0D0) THEN
- WRITE (XERN3, '(1PE15.6)') TOUT
- CALL XERMSG ('SLATEC', 'DLSOD',
- * 'IN DDEBDF, BY CALLING THE CODE WITH TOUT = ' //
- * XERN3 // ' YOU ARE ATTEMPTING TO CHANGE THE ' //
- * 'DIRECTION OF INTEGRATION.$$THIS IS NOT ALLOWED ' //
- * 'WITHOUT RESTARTING.', 11, 1)
- IDID=-33
- ENDIF
- ENDIF
- ENDIF
- C
- IF (IDID .EQ. (-33)) THEN
- IF (IQUIT .NE. (-33)) THEN
- C INVALID INPUT DETECTED
- IQUIT=-33
- IBEGIN=-1
- ELSE
- CALL XERMSG ('SLATEC', 'DLSOD',
- * 'IN DDEBDF, INVALID INPUT WAS DETECTED ON ' //
- * 'SUCCESSIVE ENTRIES. IT IS IMPOSSIBLE TO PROCEED ' //
- * 'BECAUSE YOU HAVE NOT CORRECTED THE PROBLEM, ' //
- * 'SO EXECUTION IS BEING TERMINATED.', 12, 2)
- ENDIF
- RETURN
- ENDIF
- C
- C ...............................................................
- C
- C RTOL = ATOL = 0. IS ALLOWED AS VALID INPUT AND INTERPRETED
- C AS ASKING FOR THE MOST ACCURATE SOLUTION POSSIBLE. IN THIS
- C CASE, THE RELATIVE ERROR TOLERANCE RTOL IS RESET TO THE
- C SMALLEST VALUE 100*U WHICH IS LIKELY TO BE REASONABLE FOR
- C THIS METHOD AND MACHINE
- C
- DO 180 K = 1, NEQ
- IF (RTOL(K) + ATOL(K) .GT. 0.0D0) GO TO 170
- RTOL(K) = 100.0D0*U
- IDID = -2
- 170 CONTINUE
- C ...EXIT
- IF (ITOL .EQ. 0) GO TO 190
- 180 CONTINUE
- 190 CONTINUE
- C
- IF (IDID .NE. (-2)) GO TO 200
- C RTOL=ATOL=0 ON INPUT, SO RTOL IS CHANGED TO A
- C SMALL POSITIVE VALUE
- IBEGIN = -1
- GO TO 460
- 200 CONTINUE
- C BEGIN BLOCK PERMITTING ...EXITS TO 450
- C BEGIN BLOCK PERMITTING ...EXITS TO 430
- C BEGIN BLOCK PERMITTING ...EXITS TO 260
- C BEGIN BLOCK PERMITTING ...EXITS TO 230
- C
- C BRANCH ON STATUS OF INITIALIZATION INDICATOR
- C INIT=0 MEANS INITIAL DERIVATIVES AND
- C NOMINAL STEP SIZE
- C AND DIRECTION NOT YET SET
- C INIT=1 MEANS NOMINAL STEP SIZE AND
- C DIRECTION NOT YET SET INIT=2 MEANS NO
- C FURTHER INITIALIZATION REQUIRED
- C
- IF (INIT .EQ. 0) GO TO 210
- C ......EXIT
- IF (INIT .EQ. 1) GO TO 230
- C .........EXIT
- GO TO 260
- 210 CONTINUE
- C
- C ................................................
- C
- C MORE INITIALIZATION --
- C -- EVALUATE INITIAL
- C DERIVATIVES
- C
- INIT = 1
- CALL DF(T,Y,YH(1,2),RPAR,IPAR)
- NFE = 1
- C ...EXIT
- IF (T .NE. TOUT) GO TO 230
- IDID = 2
- DO 220 L = 1, NEQ
- YPOUT(L) = YH(L,2)
- 220 CONTINUE
- TOLD = T
- C ............EXIT
- GO TO 450
- 230 CONTINUE
- C
- C -- COMPUTE INITIAL STEP SIZE
- C -- SAVE SIGN OF INTEGRATION DIRECTION
- C -- SET INDEPENDENT AND DEPENDENT VARIABLES
- C X AND YH(*) FOR DSTOD
- C
- LTOL = 1
- DO 240 L = 1, NEQ
- IF (ITOL .EQ. 1) LTOL = L
- TOL = RTOL(LTOL)*ABS(Y(L)) + ATOL(LTOL)
- IF (TOL .EQ. 0.0D0) GO TO 390
- EWT(L) = TOL
- 240 CONTINUE
- C
- BIG = SQRT(D1MACH(2))
- CALL DHSTRT(DF,NEQ,T,TOUT,Y,YH(1,2),EWT,1,U,BIG,
- 1 YH(1,3),YH(1,4),YH(1,5),YH(1,6),RPAR,
- 2 IPAR,H)
- C
- DELSGN = SIGN(1.0D0,TOUT-T)
- X = T
- DO 250 L = 1, NEQ
- YH(L,1) = Y(L)
- YH(L,2) = H*YH(L,2)
- 250 CONTINUE
- INIT = 2
- 260 CONTINUE
- C
- C ......................................................
- C
- C ON EACH CALL SET INFORMATION WHICH DETERMINES THE
- C ALLOWED INTERVAL OF INTEGRATION BEFORE RETURNING
- C WITH AN ANSWER AT TOUT
- C
- DEL = TOUT - T
- ABSDEL = ABS(DEL)
- C
- C ......................................................
- C
- C IF ALREADY PAST OUTPUT POINT, INTERPOLATE AND
- C RETURN
- C
- 270 CONTINUE
- C BEGIN BLOCK PERMITTING ...EXITS TO 400
- C BEGIN BLOCK PERMITTING ...EXITS TO 380
- IF (ABS(X-T) .LT. ABSDEL) GO TO 290
- CALL DINTYD(TOUT,0,YH,NEQ,Y,INTFLG)
- CALL DINTYD(TOUT,1,YH,NEQ,YPOUT,INTFLG)
- IDID = 3
- IF (X .NE. TOUT) GO TO 280
- IDID = 2
- INTOUT = .FALSE.
- 280 CONTINUE
- T = TOUT
- TOLD = T
- C ..................EXIT
- GO TO 450
- 290 CONTINUE
- C
- C IF CANNOT GO PAST TSTOP AND SUFFICIENTLY
- C CLOSE, EXTRAPOLATE AND RETURN
- C
- IF (ITSTOP .NE. 1) GO TO 310
- IF (ABS(TSTOP-X) .GE. 100.0D0*U*ABS(X))
- 1 GO TO 310
- DT = TOUT - X
- DO 300 L = 1, NEQ
- Y(L) = YH(L,1) + (DT/H)*YH(L,2)
- 300 CONTINUE
- CALL DF(TOUT,Y,YPOUT,RPAR,IPAR)
- NFE = NFE + 1
- IDID = 3
- T = TOUT
- TOLD = T
- C ..................EXIT
- GO TO 450
- 310 CONTINUE
- C
- IF (IINTEG .EQ. 0 .OR. .NOT.INTOUT) GO TO 320
- C
- C INTERMEDIATE-OUTPUT MODE
- C
- IDID = 1
- GO TO 370
- 320 CONTINUE
- C
- C .............................................
- C
- C MONITOR NUMBER OF STEPS ATTEMPTED
- C
- IF (KSTEPS .LE. MAXNUM) GO TO 330
- C
- C A SIGNIFICANT AMOUNT OF WORK HAS BEEN
- C EXPENDED
- IDID = -1
- KSTEPS = 0
- IBEGIN = -1
- GO TO 370
- 330 CONTINUE
- C
- C ..........................................
- C
- C LIMIT STEP SIZE AND SET WEIGHT VECTOR
- C
- HMIN = 100.0D0*U*ABS(X)
- HA = MAX(ABS(H),HMIN)
- IF (ITSTOP .EQ. 1)
- 1 HA = MIN(HA,ABS(TSTOP-X))
- H = SIGN(HA,H)
- LTOL = 1
- DO 340 L = 1, NEQ
- IF (ITOL .EQ. 1) LTOL = L
- EWT(L) = RTOL(LTOL)*ABS(YH(L,1))
- 1 + ATOL(LTOL)
- C .........EXIT
- IF (EWT(L) .LE. 0.0D0) GO TO 380
- 340 CONTINUE
- TOLFAC = U*DVNRMS(NEQ,YH,EWT)
- C .........EXIT
- IF (TOLFAC .LE. 1.0D0) GO TO 400
- C
- C TOLERANCES TOO SMALL
- IDID = -2
- TOLFAC = 2.0D0*TOLFAC
- RTOL(1) = TOLFAC*RTOL(1)
- ATOL(1) = TOLFAC*ATOL(1)
- IF (ITOL .EQ. 0) GO TO 360
- DO 350 L = 2, NEQ
- RTOL(L) = TOLFAC*RTOL(L)
- ATOL(L) = TOLFAC*ATOL(L)
- 350 CONTINUE
- 360 CONTINUE
- IBEGIN = -1
- 370 CONTINUE
- C ............EXIT
- GO TO 430
- 380 CONTINUE
- C
- C RELATIVE ERROR CRITERION INAPPROPRIATE
- 390 CONTINUE
- IDID = -3
- IBEGIN = -1
- C .........EXIT
- GO TO 430
- 400 CONTINUE
- C
- C ...................................................
- C
- C TAKE A STEP
- C
- CALL DSTOD(NEQ,Y,YH,NEQ,YH1,EWT,SAVF,ACOR,WM,IWM,
- 1 DF,DJAC,RPAR,IPAR)
- C
- JSTART = -2
- INTOUT = .TRUE.
- IF (KFLAG .EQ. 0) GO TO 270
- C
- C ......................................................
- C
- IF (KFLAG .EQ. -1) GO TO 410
- C
- C REPEATED CORRECTOR CONVERGENCE FAILURES
- IDID = -6
- IBEGIN = -1
- GO TO 420
- 410 CONTINUE
- C
- C REPEATED ERROR TEST FAILURES
- IDID = -7
- IBEGIN = -1
- 420 CONTINUE
- 430 CONTINUE
- C
- C .........................................................
- C
- C STORE VALUES BEFORE RETURNING TO
- C DDEBDF
- DO 440 L = 1, NEQ
- Y(L) = YH(L,1)
- YPOUT(L) = YH(L,2)/H
- 440 CONTINUE
- T = X
- TOLD = T
- INTOUT = .FALSE.
- 450 CONTINUE
- 460 CONTINUE
- RETURN
- END
|