123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726 |
- *DECK DRKFS
- SUBROUTINE DRKFS (DF, NEQ, T, Y, TOUT, INFO, RTOL, ATOL, IDID, H,
- + TOLFAC, YP, F1, F2, F3, F4, F5, YS, TOLD, DTSIGN, U26, RER,
- + INIT, KSTEPS, KOP, IQUIT, STIFF, NONSTF, NTSTEP, NSTIFS, RPAR,
- + IPAR)
- C***BEGIN PROLOGUE DRKFS
- C***SUBSIDIARY
- C***PURPOSE Subsidiary to DDERKF
- C***LIBRARY SLATEC
- C***TYPE DOUBLE PRECISION (DERKFS-S, DRKFS-D)
- C***AUTHOR Watts, H. A., (SNLA)
- C***DESCRIPTION
- C
- C Fehlberg Fourth-Fifth Order Runge-Kutta Method
- C **********************************************************************
- C
- C DRKFS integrates a system of first order ordinary differential
- C equations as described in the comments for DDERKF .
- C
- C The arrays YP,F1,F2,F3,F4,F5,and YS (of length at least NEQ)
- C appear in the call list for variable dimensioning purposes.
- C
- C The variables H,TOLFAC,TOLD,DTSIGN,U26,RER,INIT,KSTEPS,KOP,IQUIT,
- C STIFF,NONSTF,NTSTEP, and NSTIFS are used internally by the code
- C and appear in the call list to eliminate local retention of
- C variables between calls. Accordingly, these variables and the
- C array YP should not be altered.
- C Items of possible interest are
- C H - An appropriate step size to be used for the next step
- C TOLFAC - Factor of change in the tolerances
- C YP - Derivative of solution vector at T
- C KSTEPS - Counter on the number of steps attempted
- C
- C **********************************************************************
- C
- C***SEE ALSO DDERKF
- C***ROUTINES CALLED D1MACH, DFEHL, DHSTRT, DHVNRM, XERMSG
- C***REVISION HISTORY (YYMMDD)
- C 820301 DATE WRITTEN
- C 890531 Changed all specific intrinsics to generic. (WRB)
- C 890831 Modified array declarations. (WRB)
- C 891024 Changed references from DVNORM to DHVNRM. (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, change GOTOs to
- C IF-THEN-ELSEs. (RWC)
- C 910722 Updated AUTHOR section. (ALS)
- C***END PROLOGUE DRKFS
- C
- INTEGER IDID, INFO, INIT, IPAR, IQUIT, K, KOP, KSTEPS, KTOL,
- 1 MXKOP, MXSTEP, NATOLP, NEQ, NRTOLP, NSTIFS, NTSTEP
- DOUBLE PRECISION A, ATOL, BIG, D1MACH,
- 1 DT, DTSIGN, DHVNRM, DY, EE, EEOET, ES, ESTIFF,
- 2 ESTTOL, ET, F1, F2, F3, F4, F5, H, HMIN, REMIN, RER, RPAR,
- 3 RTOL, S, T, TOL, TOLD, TOLFAC, TOUT, U, U26, UTE, Y, YAVG,
- 4 YP, YS
- LOGICAL HFAILD,OUTPUT,STIFF,NONSTF
- CHARACTER*8 XERN1
- CHARACTER*16 XERN3, XERN4
- C
- DIMENSION Y(*),YP(*),F1(*),F2(*),F3(*),F4(*),F5(*),
- 1 YS(*),INFO(15),RTOL(*),ATOL(*),RPAR(*),IPAR(*)
- C
- EXTERNAL DF
- C
- C ..................................................................
- C
- C A FIFTH ORDER METHOD WILL GENERALLY NOT BE CAPABLE OF DELIVERING
- C ACCURACIES NEAR LIMITING PRECISION ON COMPUTERS WITH LONG
- C WORDLENGTHS. TO PROTECT AGAINST LIMITING PRECISION DIFFICULTIES
- C ARISING FROM UNREASONABLE ACCURACY REQUESTS, AN APPROPRIATE
- C TOLERANCE THRESHOLD REMIN IS ASSIGNED FOR THIS METHOD. THIS
- C VALUE SHOULD NOT BE CHANGED ACROSS DIFFERENT MACHINES.
- C
- SAVE REMIN, MXSTEP, MXKOP
- DATA REMIN /1.0D-12/
- C
- C ..................................................................
- C
- C THE EXPENSE OF SOLVING THE PROBLEM IS MONITORED BY COUNTING THE
- C NUMBER OF STEPS ATTEMPTED. WHEN THIS EXCEEDS MXSTEP, THE
- C COUNTER IS RESET TO ZERO AND THE USER IS INFORMED ABOUT POSSIBLE
- C EXCESSIVE WORK.
- C
- DATA MXSTEP /500/
- C
- C ..................................................................
- C
- C INEFFICIENCY CAUSED BY TOO FREQUENT OUTPUT IS MONITORED BY
- C COUNTING THE NUMBER OF STEP SIZES WHICH ARE SEVERELY SHORTENED
- C DUE SOLELY TO THE CHOICE OF OUTPUT POINTS. WHEN THE NUMBER OF
- C ABUSES EXCEED MXKOP, THE COUNTER IS RESET TO ZERO AND THE USER
- C IS INFORMED ABOUT POSSIBLE MISUSE OF THE CODE.
- C
- DATA MXKOP /100/
- C
- C ..................................................................
- C
- C***FIRST EXECUTABLE STATEMENT DRKFS
- IF (INFO(1) .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 PARAMETERS
- U26 = 26.0D0*U
- RER = 2.0D0*U + REMIN
- C -- SET TERMINATION FLAG
- IQUIT = 0
- C -- SET INITIALIZATION INDICATOR
- INIT = 0
- C -- SET COUNTER FOR IMPACT OF OUTPUT POINTS
- KOP = 0
- C -- SET COUNTER FOR ATTEMPTED STEPS
- KSTEPS = 0
- C -- SET INDICATORS FOR STIFFNESS DETECTION
- STIFF = .FALSE.
- NONSTF = .FALSE.
- C -- SET STEP COUNTERS FOR STIFFNESS DETECTION
- NTSTEP = 0
- NSTIFS = 0
- C -- RESET INFO(1) FOR SUBSEQUENT CALLS
- INFO(1) = 1
- ENDIF
- C
- C.......................................................................
- C
- C CHECK VALIDITY OF INPUT PARAMETERS ON EACH ENTRY
- C
- IF (INFO(1) .NE. 0 .AND. INFO(1) .NE. 1) THEN
- WRITE (XERN1, '(I8)') INFO(1)
- CALL XERMSG ('SLATEC', 'DRKFS',
- * 'IN DDERKF, INFO(1) MUST BE SET TO 0 ' //
- * 'FOR THE START OF A NEW PROBLEM, AND MUST BE SET TO 1 ' //
- * 'FOLLOWING AN INTERRUPTED TASK. YOU ARE ATTEMPTING TO ' //
- * 'CONTINUE THE INTEGRATION ILLEGALLY BY CALLING THE CODE ' //
- * 'WITH INFO(1) = ' // XERN1, 3, 1)
- IDID = -33
- ENDIF
- C
- IF (INFO(2) .NE. 0 .AND. INFO(2) .NE. 1) THEN
- WRITE (XERN1, '(I8)') INFO(2)
- CALL XERMSG ('SLATEC', 'DRKFS',
- * 'IN DDERKF, INFO(2) MUST BE 0 OR 1 ' //
- * 'INDICATING SCALAR AND VECTOR ERROR TOLERANCES, ' //
- * 'RESPECTIVELY. YOU HAVE CALLED THE CODE WITH INFO(2) = ' //
- * XERN1, 4, 1)
- IDID = -33
- ENDIF
- C
- IF (INFO(3) .NE. 0 .AND. INFO(3) .NE. 1) THEN
- WRITE (XERN1, '(I8)') INFO(3)
- CALL XERMSG ('SLATEC', 'DRKFS',
- * 'IN DDERKF, INFO(3) MUST BE 0 OR 1 ' //
- * 'INDICATING THE INTERVAL OR INTERMEDIATE-OUTPUT MODE OF ' //
- * 'INTEGRATION, RESPECTIVELY. YOU HAVE CALLED THE CODE ' //
- * 'WITH INFO(3) = ' // XERN1, 5, 1)
- IDID = -33
- ENDIF
- C
- IF (NEQ .LT. 1) THEN
- WRITE (XERN1, '(I8)') NEQ
- CALL XERMSG ('SLATEC', 'DRKFS',
- * 'IN DDERKF, THE NUMBER OF EQUATIONS ' //
- * 'NEQ MUST BE A POSITIVE INTEGER. YOU HAVE CALLED THE ' //
- * 'CODE WITH NEQ = ' // XERN1, 6, 1)
- IDID = -33
- ENDIF
- C
- NRTOLP = 0
- NATOLP = 0
- DO 10 K=1,NEQ
- IF (NRTOLP .EQ. 0 .AND. RTOL(K) .LT. 0.D0) THEN
- WRITE (XERN1, '(I8)') K
- WRITE (XERN3, '(1PE15.6)') RTOL(K)
- CALL XERMSG ('SLATEC', 'DRKFS',
- * 'IN DDERKF, THE RELATIVE ERROR ' //
- * 'TOLERANCES RTOL 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
- NRTOLP = 1
- ENDIF
- C
- IF (NATOLP .EQ. 0 .AND. ATOL(K) .LT. 0.D0) THEN
- WRITE (XERN1, '(I8)') K
- WRITE (XERN3, '(1PE15.6)') ATOL(K)
- CALL XERMSG ('SLATEC', 'DRKFS',
- * 'IN DDERKF, THE ABSOLUTE ERROR ' //
- * 'TOLERANCES ATOL 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
- NATOLP = 1
- ENDIF
- C
- IF (INFO(2) .EQ. 0) GO TO 20
- IF (NATOLP.GT.0 .AND. NRTOLP.GT.0) GO TO 20
- 10 CONTINUE
- C
- C
- C CHECK SOME CONTINUATION POSSIBILITIES
- C
- 20 IF (INIT .NE. 0) THEN
- IF (T .EQ. TOUT) THEN
- WRITE (XERN3, '(1PE15.6)') T
- CALL XERMSG ('SLATEC', 'DRKFS',
- * 'IN DDERKF, 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', 'DRKFS',
- * 'IN DDERKF, 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 (DTSIGN*(TOUT-T) .LT. 0.D0) THEN
- WRITE (XERN3, '(1PE15.6)') TOUT
- CALL XERMSG ('SLATEC', 'DRKFS',
- * 'IN DDERKF, 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
- C INVALID INPUT DETECTED
- C
- IF (IDID .EQ. (-33)) THEN
- IF (IQUIT .NE. (-33)) THEN
- IQUIT = -33
- GOTO 540
- ELSE
- CALL XERMSG ('SLATEC', 'DRKFS',
- * 'IN DDERKF, 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)
- RETURN
- ENDIF
- ENDIF
- C
- C ............................................................
- C
- C RTOL = ATOL = 0. IS ALLOWED AS VALID INPUT AND
- C INTERPRETED AS ASKING FOR THE MOST ACCURATE SOLUTION
- C POSSIBLE. IN THIS CASE, THE RELATIVE ERROR TOLERANCE
- C RTOL IS RESET TO THE SMALLEST VALUE RER WHICH IS LIKELY
- C TO BE REASONABLE FOR THIS METHOD AND MACHINE.
- C
- DO 190 K = 1, NEQ
- IF (RTOL(K) + ATOL(K) .GT. 0.0D0) GO TO 180
- RTOL(K) = RER
- IDID = -2
- 180 CONTINUE
- C ...EXIT
- IF (INFO(2) .EQ. 0) GO TO 200
- 190 CONTINUE
- 200 CONTINUE
- C
- IF (IDID .NE. (-2)) GO TO 210
- C
- C RTOL=ATOL=0 ON INPUT, SO RTOL WAS CHANGED TO A
- C SMALL POSITIVE VALUE
- TOLFAC = 1.0D0
- GO TO 530
- 210 CONTINUE
- C
- C BRANCH ON STATUS OF INITIALIZATION INDICATOR
- C INIT=0 MEANS INITIAL DERIVATIVES AND
- C STARTING STEP SIZE
- C NOT YET COMPUTED
- C INIT=1 MEANS STARTING STEP SIZE NOT YET
- C COMPUTED INIT=2 MEANS NO FURTHER
- C INITIALIZATION REQUIRED
- C
- IF (INIT .EQ. 0) GO TO 220
- C ......EXIT
- IF (INIT .EQ. 1) GO TO 240
- C .........EXIT
- GO TO 260
- 220 CONTINUE
- C
- C ................................................
- C
- C MORE INITIALIZATION --
- C -- EVALUATE INITIAL
- C DERIVATIVES
- C
- INIT = 1
- A = T
- CALL DF(A,Y,YP,RPAR,IPAR)
- IF (T .NE. TOUT) GO TO 230
- C
- C INTERVAL MODE
- IDID = 2
- T = TOUT
- TOLD = T
- C .....................EXIT
- GO TO 560
- 230 CONTINUE
- 240 CONTINUE
- C
- C -- SET SIGN OF INTEGRATION DIRECTION AND
- C -- ESTIMATE STARTING STEP SIZE
- C
- INIT = 2
- DTSIGN = SIGN(1.0D0,TOUT-T)
- U = D1MACH(4)
- BIG = SQRT(D1MACH(2))
- UTE = U**0.375D0
- DY = UTE*DHVNRM(Y,NEQ)
- IF (DY .EQ. 0.0D0) DY = UTE
- KTOL = 1
- DO 250 K = 1, NEQ
- IF (INFO(2) .EQ. 1) KTOL = K
- TOL = RTOL(KTOL)*ABS(Y(K)) + ATOL(KTOL)
- IF (TOL .EQ. 0.0D0) TOL = DY*RTOL(KTOL)
- F1(K) = TOL
- 250 CONTINUE
- C
- CALL DHSTRT(DF,NEQ,T,TOUT,Y,YP,F1,4,U,BIG,F2,F3,F4,
- 1 F5,RPAR,IPAR,H)
- 260 CONTINUE
- C
- C ......................................................
- C
- C SET STEP SIZE FOR INTEGRATION IN THE DIRECTION
- C FROM T TO TOUT AND SET OUTPUT POINT INDICATOR
- C
- DT = TOUT - T
- H = SIGN(H,DT)
- OUTPUT = .FALSE.
- C
- C TEST TO SEE IF DDERKF IS BEING SEVERELY IMPACTED BY
- C TOO MANY OUTPUT POINTS
- C
- IF (ABS(H) .GE. 2.0D0*ABS(DT)) KOP = KOP + 1
- IF (KOP .LE. MXKOP) GO TO 270
- C
- C UNNECESSARY FREQUENCY OF OUTPUT IS RESTRICTING
- C THE STEP SIZE CHOICE
- IDID = -5
- KOP = 0
- GO TO 510
- 270 CONTINUE
- C
- IF (ABS(DT) .GT. U26*ABS(T)) GO TO 290
- C
- C IF TOO CLOSE TO OUTPUT POINT,EXTRAPOLATE AND
- C RETURN
- C
- DO 280 K = 1, NEQ
- Y(K) = Y(K) + DT*YP(K)
- 280 CONTINUE
- A = TOUT
- CALL DF(A,Y,YP,RPAR,IPAR)
- KSTEPS = KSTEPS + 1
- GO TO 500
- 290 CONTINUE
- C BEGIN BLOCK PERMITTING ...EXITS TO 490
- C
- C *********************************************
- C *********************************************
- C STEP BY STEP INTEGRATION
- C
- 300 CONTINUE
- C BEGIN BLOCK PERMITTING ...EXITS TO 480
- HFAILD = .FALSE.
- C
- C TO PROTECT AGAINST IMPOSSIBLE ACCURACY
- C REQUESTS, COMPUTE A TOLERANCE FACTOR
- C BASED ON THE REQUESTED ERROR TOLERANCE
- C AND A LEVEL OF ACCURACY ACHIEVABLE AT
- C LIMITING PRECISION
- C
- TOLFAC = 0.0D0
- KTOL = 1
- DO 330 K = 1, NEQ
- IF (INFO(2) .EQ. 1) KTOL = K
- ET = RTOL(KTOL)*ABS(Y(K))
- 1 + ATOL(KTOL)
- IF (ET .GT. 0.0D0) GO TO 310
- TOLFAC = MAX(TOLFAC,
- 1 RER/RTOL(KTOL))
- GO TO 320
- 310 CONTINUE
- TOLFAC = MAX(TOLFAC,
- 1 ABS(Y(K))
- 2 *(RER/ET))
- 320 CONTINUE
- 330 CONTINUE
- IF (TOLFAC .LE. 1.0D0) GO TO 340
- C
- C REQUESTED ERROR UNATTAINABLE DUE TO LIMITED
- C PRECISION AVAILABLE
- TOLFAC = 2.0D0*TOLFAC
- IDID = -2
- C .....................EXIT
- GO TO 520
- 340 CONTINUE
- C
- C SET SMALLEST ALLOWABLE STEP SIZE
- C
- HMIN = U26*ABS(T)
- C
- C ADJUST STEP SIZE IF NECESSARY TO HIT
- C THE OUTPUT POINT -- LOOK AHEAD TWO
- C STEPS TO AVOID DRASTIC CHANGES IN THE
- C STEP SIZE AND THUS LESSEN THE IMPACT OF
- C OUTPUT POINTS ON THE CODE. STRETCH THE
- C STEP SIZE BY, AT MOST, AN AMOUNT EQUAL
- C TO THE SAFETY FACTOR OF 9/10.
- C
- DT = TOUT - T
- IF (ABS(DT) .GE. 2.0D0*ABS(H))
- 1 GO TO 370
- IF (ABS(DT) .GT. ABS(H)/0.9D0)
- 1 GO TO 350
- C
- C THE NEXT STEP, IF SUCCESSFUL,
- C WILL COMPLETE THE INTEGRATION TO
- C THE OUTPUT POINT
- C
- OUTPUT = .TRUE.
- H = DT
- GO TO 360
- 350 CONTINUE
- C
- H = 0.5D0*DT
- 360 CONTINUE
- 370 CONTINUE
- C
- C
- C ***************************************
- C CORE INTEGRATOR FOR TAKING A
- C SINGLE STEP
- C ***************************************
- C TO AVOID PROBLEMS WITH ZERO
- C CROSSINGS, RELATIVE ERROR IS
- C MEASURED USING THE AVERAGE OF THE
- C MAGNITUDES OF THE SOLUTION AT THE
- C BEGINNING AND END OF A STEP.
- C THE ERROR ESTIMATE FORMULA HAS
- C BEEN GROUPED TO CONTROL LOSS OF
- C SIGNIFICANCE.
- C LOCAL ERROR ESTIMATES FOR A FIRST
- C ORDER METHOD USING THE SAME
- C STEP SIZE AS THE FEHLBERG METHOD
- C ARE CALCULATED AS PART OF THE
- C TEST FOR STIFFNESS.
- C TO DISTINGUISH THE VARIOUS
- C ARGUMENTS, H IS NOT PERMITTED
- C TO BECOME SMALLER THAN 26 UNITS OF
- C ROUNDOFF IN T. PRACTICAL LIMITS
- C ON THE CHANGE IN THE STEP SIZE ARE
- C ENFORCED TO SMOOTH THE STEP SIZE
- C SELECTION PROCESS AND TO AVOID
- C EXCESSIVE CHATTERING ON PROBLEMS
- C HAVING DISCONTINUITIES. TO
- C PREVENT UNNECESSARY FAILURES, THE
- C CODE USES 9/10 THE STEP SIZE
- C IT ESTIMATES WILL SUCCEED.
- C AFTER A STEP FAILURE, THE STEP
- C SIZE IS NOT ALLOWED TO INCREASE
- C FOR THE NEXT ATTEMPTED STEP. THIS
- C MAKES THE CODE MORE EFFICIENT ON
- C PROBLEMS HAVING DISCONTINUITIES
- C AND MORE EFFECTIVE IN GENERAL
- C SINCE LOCAL EXTRAPOLATION IS BEING
- C USED AND EXTRA CAUTION SEEMS
- C WARRANTED.
- C .......................................
- C
- C MONITOR NUMBER OF STEPS ATTEMPTED
- C
- 380 CONTINUE
- IF (KSTEPS .LE. MXSTEP) GO TO 390
- C
- C A SIGNIFICANT AMOUNT OF WORK HAS
- C BEEN EXPENDED
- IDID = -1
- KSTEPS = 0
- C ........................EXIT
- IF (.NOT.STIFF) GO TO 520
- C
- C PROBLEM APPEARS TO BE STIFF
- IDID = -4
- STIFF = .FALSE.
- NONSTF = .FALSE.
- NTSTEP = 0
- NSTIFS = 0
- C ........................EXIT
- GO TO 520
- 390 CONTINUE
- C
- C ADVANCE AN APPROXIMATE SOLUTION OVER
- C ONE STEP OF LENGTH H
- C
- CALL DFEHL(DF,NEQ,T,Y,H,YP,F1,F2,F3,
- 1 F4,F5,YS,RPAR,IPAR)
- KSTEPS = KSTEPS + 1
- C
- C ....................................
- C
- C COMPUTE AND TEST ALLOWABLE
- C TOLERANCES VERSUS LOCAL ERROR
- C ESTIMATES. NOTE THAT RELATIVE
- C ERROR IS MEASURED WITH RESPECT
- C TO THE AVERAGE OF THE
- C MAGNITUDES OF THE SOLUTION AT
- C THE BEGINNING AND END OF THE
- C STEP. LOCAL ERROR ESTIMATES
- C FOR A SPECIAL FIRST ORDER
- C METHOD ARE CALCULATED ONLY WHEN
- C THE STIFFNESS DETECTION IS
- C TURNED ON.
- C
- EEOET = 0.0D0
- ESTIFF = 0.0D0
- KTOL = 1
- DO 420 K = 1, NEQ
- YAVG = 0.5D0
- 1 *(ABS(Y(K))
- 2 + ABS(YS(K)))
- IF (INFO(2) .EQ. 1) KTOL = K
- ET = RTOL(KTOL)*YAVG + ATOL(KTOL)
- IF (ET .GT. 0.0D0) GO TO 400
- C
- C PURE RELATIVE ERROR INAPPROPRIATE WHEN SOLUTION
- C VANISHES
- IDID = -3
- C ...........................EXIT
- GO TO 520
- 400 CONTINUE
- C
- EE = ABS((-2090.0D0*YP(K)
- 1 +(21970.0D0*F3(K)
- 2 -15048.0D0*F4(K)))
- 3 +(22528.0D0*F2(K)
- 4 -27360.0D0*F5(K)))
- IF (STIFF .OR. NONSTF) GO TO 410
- ES = ABS(H
- 1 *(0.055455D0*YP(K)
- 2 -0.035493D0*F1(K)
- 3 -0.036571D0*F2(K)
- 4 +0.023107D0*F3(K)
- 5 -0.009515D0*F4(K)
- 6 +0.003017D0*F5(K))
- 7 )
- ESTIFF = MAX(ESTIFF,ES/ET)
- 410 CONTINUE
- EEOET = MAX(EEOET,EE/ET)
- 420 CONTINUE
- C
- ESTTOL = ABS(H)*EEOET/752400.0D0
- C
- C ...EXIT
- IF (ESTTOL .LE. 1.0D0) GO TO 440
- C
- C ....................................
- C
- C UNSUCCESSFUL STEP
- C
- IF (ABS(H) .GT. HMIN) GO TO 430
- C
- C REQUESTED ERROR UNATTAINABLE AT SMALLEST
- C ALLOWABLE STEP SIZE
- TOLFAC = 1.69D0*ESTTOL
- IDID = -2
- C ........................EXIT
- GO TO 520
- 430 CONTINUE
- C
- C REDUCE THE STEP SIZE , TRY AGAIN
- C THE DECREASE IS LIMITED TO A FACTOR
- C OF 1/10
- C
- HFAILD = .TRUE.
- OUTPUT = .FALSE.
- S = 0.1D0
- IF (ESTTOL .LT. 59049.0D0)
- 1 S = 0.9D0/ESTTOL**0.2D0
- H = SIGN(MAX(S*ABS(H),HMIN),H)
- GO TO 380
- 440 CONTINUE
- C
- C .......................................
- C
- C SUCCESSFUL STEP
- C STORE SOLUTION AT T+H
- C AND EVALUATE
- C DERIVATIVES THERE
- C
- T = T + H
- DO 450 K = 1, NEQ
- Y(K) = YS(K)
- 450 CONTINUE
- A = T
- CALL DF(A,Y,YP,RPAR,IPAR)
- C
- C CHOOSE NEXT STEP SIZE
- C THE INCREASE IS LIMITED TO A FACTOR OF
- C 5 IF STEP FAILURE HAS JUST OCCURRED,
- C NEXT
- C STEP SIZE IS NOT ALLOWED TO INCREASE
- C
- S = 5.0D0
- IF (ESTTOL .GT. 1.889568D-4)
- 1 S = 0.9D0/ESTTOL**0.2D0
- IF (HFAILD) S = MIN(S,1.0D0)
- H = SIGN(MAX(S*ABS(H),HMIN),H)
- C
- C .......................................
- C
- C CHECK FOR STIFFNESS (IF NOT
- C ALREADY DETECTED)
- C
- C IN A SEQUENCE OF 50 SUCCESSFUL
- C STEPS BY THE FEHLBERG METHOD, 25
- C SUCCESSFUL STEPS BY THE FIRST
- C ORDER METHOD INDICATES STIFFNESS
- C AND TURNS THE TEST OFF. IF 26
- C FAILURES BY THE FIRST ORDER METHOD
- C OCCUR, THE TEST IS TURNED OFF
- C UNTIL THIS SEQUENCE OF 50 STEPS BY
- C THE FEHLBERG METHOD IS COMPLETED.
- C
- C ...EXIT
- IF (STIFF) GO TO 480
- NTSTEP = MOD(NTSTEP+1,50)
- IF (NTSTEP .EQ. 1) NONSTF = .FALSE.
- C ...EXIT
- IF (NONSTF) GO TO 480
- IF (ESTIFF .GT. 1.0D0) GO TO 460
- C
- C SUCCESSFUL STEP WITH FIRST ORDER
- C METHOD
- NSTIFS = NSTIFS + 1
- C TURN TEST OFF AFTER 25 INDICATIONS
- C OF STIFFNESS
- IF (NSTIFS .EQ. 25) STIFF = .TRUE.
- GO TO 470
- 460 CONTINUE
- C
- C UNSUCCESSFUL STEP WITH FIRST ORDER
- C METHOD
- IF (NTSTEP - NSTIFS .LE. 25) GO TO 470
- C TURN STIFFNESS DETECTION OFF FOR THIS BLOCK OF
- C FIFTY STEPS
- NONSTF = .TRUE.
- C RESET STIFF STEP COUNTER
- NSTIFS = 0
- 470 CONTINUE
- 480 CONTINUE
- C
- C ******************************************
- C END OF CORE INTEGRATOR
- C ******************************************
- C
- C
- C SHOULD WE TAKE ANOTHER STEP
- C
- C ......EXIT
- IF (OUTPUT) GO TO 490
- IF (INFO(3) .EQ. 0) GO TO 300
- C
- C *********************************************
- C *********************************************
- C
- C INTEGRATION SUCCESSFULLY COMPLETED
- C
- C ONE-STEP MODE
- IDID = 1
- TOLD = T
- C .....................EXIT
- GO TO 560
- 490 CONTINUE
- 500 CONTINUE
- C
- C INTERVAL MODE
- IDID = 2
- T = TOUT
- TOLD = T
- C ...............EXIT
- GO TO 560
- 510 CONTINUE
- 520 CONTINUE
- 530 CONTINUE
- 540 CONTINUE
- C
- C INTEGRATION TASK INTERRUPTED
- C
- INFO(1) = -1
- TOLD = T
- C ...EXIT
- IF (IDID .NE. (-2)) GO TO 560
- C
- C THE ERROR TOLERANCES ARE INCREASED TO VALUES
- C WHICH ARE APPROPRIATE FOR CONTINUING
- RTOL(1) = TOLFAC*RTOL(1)
- ATOL(1) = TOLFAC*ATOL(1)
- C ...EXIT
- IF (INFO(2) .EQ. 0) GO TO 560
- DO 550 K = 2, NEQ
- RTOL(K) = TOLFAC*RTOL(K)
- ATOL(K) = TOLFAC*ATOL(K)
- 550 CONTINUE
- 560 CONTINUE
- RETURN
- END
|