1 SUBROUTINE DDAINI (X, Y, YPRIME, NEQ, RES, JAC, H, WT, IDID, RPAR,
2 + IPAR, PHI, DELTA, E, WM, IWM, HMIN, UROUND, NONNEG, NTEMP)
5 C***BEGIN PROLOGUE DDAINI
7 C***PURPOSE Initialization routine for DDASSL.
8 C***LIBRARY SLATEC (DASSL)
9 C***TYPE DOUBLE PRECISION (SDAINI-S, DDAINI-D)
10 C***AUTHOR PETZOLD, LINDA R., (LLNL)
12 C-----------------------------------------------------------------
13 C DDAINI TAKES ONE STEP OF SIZE H OR SMALLER
14 C WITH THE BACKWARD EULER METHOD, TO
15 C FIND YPRIME. X AND Y ARE UPDATED TO BE CONSISTENT WITH THE
16 C NEW STEP. A MODIFIED DAMPED NEWTON ITERATION IS USED TO
17 C SOLVE THE CORRECTOR ITERATION.
19 C THE INITIAL GUESS FOR YPRIME IS USED IN THE
20 C PREDICTION, AND IN FORMING THE ITERATION
21 C MATRIX, BUT IS NOT INVOLVED IN THE
22 C ERROR TEST. THIS MAY HAVE TROUBLE
23 C CONVERGING IF THE INITIAL GUESS IS NO
24 C GOOD, OR IF G(X,Y,YPRIME) DEPENDS
25 C NONLINEARLY ON YPRIME.
27 C THE PARAMETERS REPRESENT:
28 C X -- INDEPENDENT VARIABLE
29 C Y -- SOLUTION VECTOR AT X
30 C YPRIME -- DERIVATIVE OF SOLUTION VECTOR
31 C NEQ -- NUMBER OF EQUATIONS
32 C H -- STEPSIZE. IMDER MAY USE A STEPSIZE
34 C WT -- VECTOR OF WEIGHTS FOR ERROR
36 C IDID -- COMPLETION CODE WITH THE FOLLOWING MEANINGS
37 C IDID= 1 -- YPRIME WAS FOUND SUCCESSFULLY
38 C IDID=-12 -- DDAINI FAILED TO FIND YPRIME
39 C RPAR,IPAR -- REAL AND INTEGER PARAMETER ARRAYS
40 C THAT ARE NOT ALTERED BY DDAINI
41 C PHI -- WORK SPACE FOR DDAINI
42 C DELTA,E -- WORK SPACE FOR DDAINI
43 C WM,IWM -- REAL AND INTEGER ARRAYS STORING
46 C-----------------------------------------------------------------
47 C***ROUTINES CALLED DDAJAC, DDANRM, DDASLV
48 C***REVISION HISTORY (YYMMDD)
50 C 901009 Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
51 C 901019 Merged changes made by C. Ulrich with SLATEC 4.0 format.
52 C 901026 Added explicit declarations for all variables and minor
53 C cosmetic changes to prologue. (FNF)
54 C 901030 Minor corrections to declarations. (FNF)
55 C***END PROLOGUE DDAINI
57 INTEGER NEQ, IDID, IPAR(*), IWM(*), NONNEG, NTEMP
59 * X, Y(*), YPRIME(*), H, WT(*), RPAR(*), PHI(NEQ,*), DELTA(*),
60 * E(*), WM(*), HMIN, UROUND
63 EXTERNAL DDAJAC, DDANRM, DDASLV
64 DOUBLE PRECISION DDANRM
66 INTEGER I, IER, IRES, JCALC, LNJE, LNRE, M, MAXIT, MJAC, NCF,
69 * CJ, DAMP, DELNRM, IERR, OLDNRM, R, RATE, S, XOLD, YNORM
75 DATA MAXIT/10/,MJAC/5/
79 C---------------------------------------------------
82 C---------------------------------------------------
84 C***FIRST EXECUTABLE STATEMENT DDAINI
90 YNORM=DDANRM(NEQ,Y,WT,RPAR,IPAR)
92 C SAVE Y AND YPRIME IN PHI
95 100 PHI(I,2)=YPRIME(I)
98 C----------------------------------------------------
100 C DO ONE BACKWARD EULER STEP.
101 C----------------------------------------------------
103 C SET UP FOR START OF CORRECTOR ITERATION
107 C PREDICT SOLUTION AND DERIVATIVE
109 250 Y(I)=Y(I)+H*YPRIME(I)
117 300 IWM(LNRE)=IWM(LNRE)+1
121 CALL RES(X,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
123 C IERROR indicates if RES had the right prototype
128 IF (IRES.LT.0) GO TO 430
131 C EVALUATE THE ITERATION MATRIX
132 IF (JCALC.NE.-1) GO TO 310
133 IWM(LNJE)=IWM(LNJE)+1
135 CALL DDAJAC(NEQ,X,Y,YPRIME,DELTA,CJ,H,
136 * IER,WT,E,WM,IWM,RES,IRES,
137 * UROUND,JAC,RPAR,IPAR,NTEMP)
141 IF (IRES.LT.0) GO TO 430
142 IF (IER.NE.0) GO TO 430
147 C MULTIPLY RESIDUAL BY DAMPING FACTOR
150 320 DELTA(I)=DELTA(I)*DAMP
152 C COMPUTE A NEW ITERATE (BACK SUBSTITUTION)
153 C STORE THE CORRECTION IN DELTA
155 CALL DDASLV(NEQ,DELTA,WM,IWM)
157 C UPDATE Y AND YPRIME
160 330 YPRIME(I)=YPRIME(I)-CJ*DELTA(I)
162 C TEST FOR CONVERGENCE OF THE ITERATION.
164 DELNRM=DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
165 IF (DELNRM.LE.100.D0*UROUND*YNORM)
168 IF (M.GT.0) GO TO 340
172 340 RATE=(DELNRM/OLDNRM)**(1.0D0/M)
173 IF (RATE.GT.0.90D0) GO TO 430
176 350 IF (S*DELNRM .LE. 0.33D0) GO TO 400
179 C THE CORRECTOR HAS NOT YET CONVERGED. UPDATE
180 C M AND AND TEST WHETHER THE MAXIMUM
181 C NUMBER OF ITERATIONS HAVE BEEN TRIED.
182 C EVERY MJAC ITERATIONS, GET A NEW
186 IF (M.GE.MAXIT) GO TO 430
188 IF ((M/MJAC)*MJAC.EQ.M) JCALC=-1
192 C THE ITERATION HAS CONVERGED.
193 C CHECK NONNEGATIVITY CONSTRAINTS
194 400 IF (NONNEG.EQ.0) GO TO 450
196 410 DELTA(I)=MIN(Y(I),0.0D0)
198 DELNRM=DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
199 IF (DELNRM.GT.0.33D0) GO TO 430
203 420 YPRIME(I)=YPRIME(I)-CJ*DELTA(I)
207 C EXITS FROM CORRECTOR LOOP.
209 450 IF (.NOT.CONVGD) GO TO 600
213 C-----------------------------------------------------
215 C THE CORRECTOR ITERATION CONVERGED.
217 C-----------------------------------------------------
220 510 E(I)=Y(I)-PHI(I,1)
221 IERR=DDANRM(NEQ,E,WT,RPAR,IPAR)
223 IF (IERR.LE.1.0D0) RETURN
227 C--------------------------------------------------------
229 C THE BACKWARD EULER STEP FAILED. RESTORE X, Y
230 C AND YPRIME TO THEIR ORIGINAL VALUES.
231 C REDUCE STEPSIZE AND TRY AGAIN, IF
233 C---------------------------------------------------------
239 610 YPRIME(I)=PHI(I,2)
241 IF (CONVGD) GO TO 640
242 IF (IER.EQ.0) GO TO 620
245 IF (NSF.LT.3.AND.ABS(H).GE.HMIN) GO TO 690
248 620 IF (IRES.GT.-2) GO TO 630
253 IF (NCF.LT.10.AND.ABS(H).GE.HMIN) GO TO 690
258 R=0.90D0/(2.0D0*IERR+0.0001D0)
259 R=MAX(0.1D0,MIN(0.5D0,R))
261 IF (ABS(H).GE.HMIN.AND.NEF.LT.10) GO TO 690
266 C-------------END OF SUBROUTINE DDAINI----------------------
268 SUBROUTINE DDAJAC (NEQ, X, Y, YPRIME, DELTA, CJ, H,
269 + IER, WT, E, WM, IWM, RES, IRES, UROUND, JAC, RPAR,
273 C***BEGIN PROLOGUE DDAJAC
275 C***PURPOSE Compute the iteration matrix for DDASSL and form the
277 C***LIBRARY SLATEC (DASSL)
278 C***TYPE DOUBLE PRECISION (SDAJAC-S, DDAJAC-D)
279 C***AUTHOR PETZOLD, LINDA R., (LLNL)
281 C-----------------------------------------------------------------------
282 C THIS ROUTINE COMPUTES THE ITERATION MATRIX
283 C PD=DG/DY+CJ*DG/DYPRIME (WHERE G(X,Y,YPRIME)=0).
284 C HERE PD IS COMPUTED BY THE USER-SUPPLIED
285 C ROUTINE JAC IF IWM(MTYPE) IS 1 OR 4, AND
286 C IT IS COMPUTED BY NUMERICAL FINITE DIFFERENCING
287 C IF IWM(MTYPE)IS 2 OR 5
288 C THE PARAMETERS HAVE THE FOLLOWING MEANINGS.
289 C Y = ARRAY CONTAINING PREDICTED VALUES
290 C YPRIME = ARRAY CONTAINING PREDICTED DERIVATIVES
291 C DELTA = RESIDUAL EVALUATED AT (X,Y,YPRIME)
292 C (USED ONLY IF IWM(MTYPE)=2 OR 5)
293 C CJ = SCALAR PARAMETER DEFINING ITERATION MATRIX
294 C H = CURRENT STEPSIZE IN INTEGRATION
295 C IER = VARIABLE WHICH IS .NE. 0
296 C IF ITERATION MATRIX IS SINGULAR,
298 C WT = VECTOR OF WEIGHTS FOR COMPUTING NORMS
299 C E = WORK SPACE (TEMPORARY) OF LENGTH NEQ
300 C WM = REAL WORK SPACE FOR MATRICES. ON
301 C OUTPUT IT CONTAINS THE LU DECOMPOSITION
302 C OF THE ITERATION MATRIX.
303 C IWM = INTEGER WORK SPACE CONTAINING
305 C RES = NAME OF THE EXTERNAL USER-SUPPLIED ROUTINE
306 C TO EVALUATE THE RESIDUAL FUNCTION G(X,Y,YPRIME)
307 C IRES = FLAG WHICH IS EQUAL TO ZERO IF NO ILLEGAL VALUES
308 C IN RES, AND LESS THAN ZERO OTHERWISE. (IF IRES
309 C IS LESS THAN ZERO, THE MATRIX WAS NOT COMPLETED)
310 C IN THIS CASE (IF IRES .LT. 0), THEN IER = 0.
311 C UROUND = THE UNIT ROUNDOFF ERROR OF THE MACHINE BEING USED.
312 C JAC = NAME OF THE EXTERNAL USER-SUPPLIED ROUTINE
313 C TO EVALUATE THE ITERATION MATRIX (THIS ROUTINE
314 C IS ONLY USED IF IWM(MTYPE) IS 1 OR 4)
315 C-----------------------------------------------------------------------
316 C***ROUTINES CALLED DGBFA, DGEFA
317 C***REVISION HISTORY (YYMMDD)
318 C 830315 DATE WRITTEN
319 C 901009 Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
320 C 901010 Modified three MAX calls to be all on one line. (FNF)
321 C 901019 Merged changes made by C. Ulrich with SLATEC 4.0 format.
322 C 901026 Added explicit declarations for all variables and minor
323 C cosmetic changes to prologue. (FNF)
324 C 901101 Corrected PURPOSE. (FNF)
325 C***END PROLOGUE DDAJAC
327 INTEGER NEQ, IER, IWM(*), IRES, IPAR(*), NTEMP
329 * X, Y(*), YPRIME(*), DELTA(*), CJ, H, WT(*), E(*), WM(*),
333 EXTERNAL DGBFA, DGEFA
335 INTEGER I, I1, I2, II, IPSAVE, ISAVE, J, K, L, LENPD, LIPVT,
336 * LML, LMTYPE, LMU, MBA, MBAND, MEB1, MEBAND, MSAVE, MTYPE, N,
338 DOUBLE PRECISION DEL, DELINV, SQUR, YPSAVE, YSAVE
346 C***FIRST EXECUTABLE STATEMENT DDAJAC
350 GO TO (100,200,300,400,500),MTYPE
353 C DENSE USER-SUPPLIED MATRIX
356 110 WM(NPDM1+I)=0.0D0
357 CALL JAC(X,Y,YPRIME,WM(NPD),CJ,RPAR,IPAR)
362 C DENSE FINITE-DIFFERENCE-GENERATED MATRIX
367 DEL=SQUR*MAX(ABS(Y(I)),ABS(H*YPRIME(I)),ABS(WT(I)))
368 DEL=SIGN(DEL,H*YPRIME(I))
373 YPRIME(I)=YPRIME(I)+CJ*DEL
374 CALL RES(X,Y,YPRIME,E,IRES,RPAR,IPAR)
376 IF (IRES .LT. 0) RETURN
379 220 WM(NROW+L)=(E(L)-DELTA(L))*DELINV
386 C DO DENSE-MATRIX LU DECOMPOSITION ON PD
387 230 CALL DGEFA(WM(NPD),NEQ,NEQ,IWM(LIPVT),IER)
391 C DUMMY SECTION FOR IWM(MTYPE)=3
395 C BANDED USER-SUPPLIED MATRIX
396 400 LENPD=(2*IWM(LML)+IWM(LMU)+1)*NEQ
398 410 WM(NPDM1+I)=0.0D0
399 CALL JAC(X,Y,YPRIME,WM(NPD),CJ,RPAR,IPAR)
401 MEBAND=2*IWM(LML)+IWM(LMU)+1
405 C BANDED FINITE-DIFFERENCE-GENERATED MATRIX
406 500 MBAND=IWM(LML)+IWM(LMU)+1
408 MEBAND=MBAND+IWM(LML)
419 WM(IPSAVE+K)=YPRIME(N)
420 DEL=SQUR*MAX(ABS(Y(N)),ABS(H*YPRIME(N)),ABS(WT(N)))
421 DEL=SIGN(DEL,H*YPRIME(N))
424 510 YPRIME(N)=YPRIME(N)+CJ*DEL
425 CALL RES(X,Y,YPRIME,E,IRES,RPAR,IPAR)
427 IF (IRES .LT. 0) RETURN
431 YPRIME(N)=WM(IPSAVE+K)
432 DEL=SQUR*MAX(ABS(Y(N)),ABS(H*YPRIME(N)),ABS(WT(N)))
433 DEL=SIGN(DEL,H*YPRIME(N))
436 I1=MAX(1,(N-IWM(LMU)))
437 I2=MIN(NEQ,(N+IWM(LML)))
438 II=N*MEB1-IWM(LML)+NPDM1
440 520 WM(II+I)=(E(I)-DELTA(I))*DELINV
445 C DO LU DECOMPOSITION OF BANDED PD
446 550 CALL DGBFA(WM(NPD),MEBAND,NEQ,
447 * IWM(LML),IWM(LMU),IWM(LIPVT),IER)
449 C------END OF SUBROUTINE DDAJAC------
451 DOUBLE PRECISION FUNCTION DDANRM (NEQ, V, WT, RPAR, IPAR)
452 C***BEGIN PROLOGUE DDANRM
454 C***PURPOSE Compute vector norm for DDASSL.
455 C***LIBRARY SLATEC (DASSL)
456 C***TYPE DOUBLE PRECISION (SDANRM-S, DDANRM-D)
457 C***AUTHOR PETZOLD, LINDA R., (LLNL)
459 C-----------------------------------------------------------------------
460 C THIS FUNCTION ROUTINE COMPUTES THE WEIGHTED
461 C ROOT-MEAN-SQUARE NORM OF THE VECTOR OF LENGTH
462 C NEQ CONTAINED IN THE ARRAY V,WITH WEIGHTS
463 C CONTAINED IN THE ARRAY WT OF LENGTH NEQ.
464 C DDANRM=SQRT((1/NEQ)*SUM(V(I)/WT(I))**2)
465 C-----------------------------------------------------------------------
466 C***ROUTINES CALLED (NONE)
467 C***REVISION HISTORY (YYMMDD)
468 C 830315 DATE WRITTEN
469 C 901009 Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
470 C 901019 Merged changes made by C. Ulrich with SLATEC 4.0 format.
471 C 901026 Added explicit declarations for all variables and minor
472 C cosmetic changes to prologue. (FNF)
473 C***END PROLOGUE DDANRM
476 DOUBLE PRECISION V(NEQ), WT(NEQ), RPAR(*)
479 DOUBLE PRECISION SUM, VMAX
481 C***FIRST EXECUTABLE STATEMENT DDANRM
485 IF(ABS(V(I)/WT(I)) .GT. VMAX) VMAX = ABS(V(I)/WT(I))
487 IF(VMAX .LE. 0.0D0) GO TO 30
490 20 SUM = SUM + ((V(I)/WT(I))/VMAX)**2
491 DDANRM = VMAX*SQRT(SUM/NEQ)
494 C------END OF FUNCTION DDANRM------
496 SUBROUTINE DDASLV (NEQ, DELTA, WM, IWM)
497 C***BEGIN PROLOGUE DDASLV
499 C***PURPOSE Linear system solver for DDASSL.
500 C***LIBRARY SLATEC (DASSL)
501 C***TYPE DOUBLE PRECISION (SDASLV-S, DDASLV-D)
502 C***AUTHOR PETZOLD, LINDA R., (LLNL)
504 C-----------------------------------------------------------------------
505 C THIS ROUTINE MANAGES THE SOLUTION OF THE LINEAR
506 C SYSTEM ARISING IN THE NEWTON ITERATION.
507 C MATRICES AND REAL TEMPORARY STORAGE AND
508 C REAL INFORMATION ARE STORED IN THE ARRAY WM.
509 C INTEGER MATRIX INFORMATION IS STORED IN
511 C FOR A DENSE MATRIX, THE LINPACK ROUTINE
513 C FOR A BANDED MATRIX,THE LINPACK ROUTINE
515 C-----------------------------------------------------------------------
516 C***ROUTINES CALLED DGBSL, DGESL
517 C***REVISION HISTORY (YYMMDD)
518 C 830315 DATE WRITTEN
519 C 901009 Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
520 C 901019 Merged changes made by C. Ulrich with SLATEC 4.0 format.
521 C 901026 Added explicit declarations for all variables and minor
522 C cosmetic changes to prologue. (FNF)
523 C***END PROLOGUE DDASLV
526 DOUBLE PRECISION DELTA(*), WM(*)
528 EXTERNAL DGBSL, DGESL
530 INTEGER LIPVT, LML, LMU, LMTYPE, MEBAND, MTYPE, NPD
537 C***FIRST EXECUTABLE STATEMENT DDASLV
539 GO TO(100,100,300,400,400),MTYPE
542 100 CALL DGESL(WM(NPD),NEQ,NEQ,IWM(LIPVT),DELTA,0)
545 C DUMMY SECTION FOR MTYPE=3
550 400 MEBAND=2*IWM(LML)+IWM(LMU)+1
551 CALL DGBSL(WM(NPD),MEBAND,NEQ,IWM(LML),
552 * IWM(LMU),IWM(LIPVT),DELTA,0)
554 C------END OF SUBROUTINE DDASLV------
556 SUBROUTINE DDASSL (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
557 + IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC)
559 C***BEGIN PROLOGUE DDASSL
560 C***PURPOSE This code solves a system of differential/algebraic
561 C equations of the form G(T,Y,YPRIME) = 0.
562 C***LIBRARY SLATEC (DASSL)
564 C***TYPE DOUBLE PRECISION (SDASSL-S, DDASSL-D)
565 C***KEYWORDS DIFFERENTIAL/ALGEBRAIC, BACKWARD DIFFERENTIATION FORMULAS,
566 C IMPLICIT DIFFERENTIAL SYSTEMS
567 C***AUTHOR PETZOLD, LINDA R., (LLNL)
568 C COMPUTING AND MATHEMATICS RESEARCH DIVISION
569 C LAWRENCE LIVERMORE NATIONAL LABORATORY
570 C L - 316, P.O. BOX 808,
571 C LIVERMORE, CA. 94550
577 C INTEGER NEQ, INFO(N), IDID, LRW, LIW, IWORK(LIW), IPAR
578 C DOUBLE PRECISION T, Y(NEQ), YPRIME(NEQ), TOUT, RTOL, ATOL,
581 C CALL DDASSL (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
582 C * IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC)
586 C (In the following, all real arrays should be type DOUBLE PRECISION.)
588 C RES:EXT This is a subroutine which you provide to define the
589 C differential/algebraic system.
591 C NEQ:IN This is the number of equations to be solved.
593 C T:INOUT This is the current value of the independent variable.
595 C Y(*):INOUT This array contains the solution components at T.
597 C YPRIME(*):INOUT This array contains the derivatives of the solution
600 C TOUT:IN This is a point at which a solution is desired.
602 C INFO(N):IN The basic task of the code is to solve the system from T
603 C to TOUT and return an answer at TOUT. INFO is an integer
604 C array which is used to communicate exactly how you want
605 C this task to be carried out. (See below for details.)
606 C N must be greater than or equal to 15.
608 C RTOL,ATOL:INOUT These quantities represent relative and absolute
609 C error tolerances which you provide to indicate how
610 C accurately you wish the solution to be computed. You
611 C may choose them to be both scalars or else both vectors.
612 C Caution: In Fortran 77, a scalar is not the same as an
613 C array of length 1. Some compilers may object
614 C to using scalars for RTOL,ATOL.
616 C IDID:OUT This scalar quantity is an indicator reporting what the
617 C code did. You must monitor this integer variable to
618 C decide what action to take next.
620 C RWORK:WORK A real work array of length LRW which provides the
621 C code with needed storage space.
623 C LRW:IN The length of RWORK. (See below for required length.)
625 C IWORK:WORK An integer work array of length LIW which probides the
626 C code with needed storage space.
628 C LIW:IN The length of IWORK. (See below for required length.)
630 C RPAR,IPAR:IN These are real and integer parameter arrays which
631 C you can use for communication between your calling
632 C program and the RES subroutine (and the JAC subroutine)
634 C JAC:EXT This is the name of a subroutine which you may choose
635 C to provide for defining a matrix of partial derivatives
638 C Quantities which may be altered by DDASSL are:
639 C T, Y(*), YPRIME(*), INFO(1), RTOL, ATOL,
640 C IDID, RWORK(*) AND IWORK(*)
644 C Subroutine DDASSL uses the backward differentiation formulas of
645 C orders one through five to solve a system of the above form for Y and
646 C YPRIME. Values for Y and YPRIME at the initial time must be given as
647 C input. These values must be consistent, (that is, if T,Y,YPRIME are
648 C the given initial values, they must satisfy G(T,Y,YPRIME) = 0.). The
649 C subroutine solves the system from T to TOUT. It is easy to continue
650 C the solution to get results at additional TOUT. This is the interval
651 C mode of operation. Intermediate results can also be obtained easily
652 C by using the intermediate-output capability.
654 C The following detailed description is divided into subsections:
655 C 1. Input required for the first call to DDASSL.
656 C 2. Output after any return from DDASSL.
657 C 3. What to do to continue the integration.
661 C -------- INPUT -- WHAT TO DO ON THE FIRST CALL TO DDASSL ------------
663 C The first call of the code is defined to be the start of each new
664 C problem. Read through the descriptions of all the following items,
665 C provide sufficient storage space for designated arrays, set
666 C appropriate variables for the initialization of the problem, and
667 C give information about how you want the problem to be solved.
670 C RES -- Provide a subroutine of the form
671 C SUBROUTINE RES(T,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
672 C to define the system of differential/algebraic
673 C equations which is to be solved. For the given values
674 C of T,Y and YPRIME, the subroutine should
675 C return the residual of the defferential/algebraic
677 C DELTA = G(T,Y,YPRIME)
678 C (DELTA(*) is a vector of length NEQ which is
681 C Subroutine RES must not alter T,Y or YPRIME.
682 C You must declare the name RES in an external
683 C statement in your program that calls DDASSL.
684 C You must dimension Y,YPRIME and DELTA in RES.
686 C IRES is an integer flag which is always equal to
687 C zero on input. Subroutine RES should alter IRES
688 C only if it encounters an illegal value of Y or
689 C a stop condition. Set IRES = -1 if an input value
690 C is illegal, and DDASSL will try to solve the problem
691 C without getting IRES = -1. If IRES = -2, DDASSL
692 C will return control to the calling program
695 C RPAR and IPAR are real and integer parameter arrays which
696 C you can use for communication between your calling program
697 C and subroutine RES. They are not altered by DDASSL. If you
698 C do not need RPAR or IPAR, ignore these parameters by treat-
699 C ing them as dummy arguments. If you do choose to use them,
700 C dimension them in your calling program and in RES as arrays
701 C of appropriate length.
703 C NEQ -- Set it to the number of differential equations.
706 C T -- Set it to the initial point of the integration.
707 C T must be defined as a variable.
709 C Y(*) -- Set this vector to the initial values of the NEQ solution
710 C components at the initial point. You must dimension Y of
711 C length at least NEQ in your calling program.
713 C YPRIME(*) -- Set this vector to the initial values of the NEQ
714 C first derivatives of the solution components at the initial
715 C point. You must dimension YPRIME at least NEQ in your
716 C calling program. If you do not know initial values of some
717 C of the solution components, see the explanation of INFO(11).
719 C TOUT -- Set it to the first point at which a solution
720 C is desired. You can not take TOUT = T.
721 C integration either forward in T (TOUT .GT. T) or
722 C backward in T (TOUT .LT. T) is permitted.
724 C The code advances the solution from T to TOUT using
725 C step sizes which are automatically selected so as to
726 C achieve the desired accuracy. If you wish, the code will
727 C return with the solution and its derivative at
728 C intermediate steps (intermediate-output mode) so that
729 C you can monitor them, but you still must provide TOUT in
730 C accord with the basic aim of the code.
732 C The first step taken by the code is a critical one
733 C because it must reflect how fast the solution changes near
734 C the initial point. The code automatically selects an
735 C initial step size which is practically always suitable for
736 C the problem. By using the fact that the code will not step
737 C past TOUT in the first step, you could, if necessary,
738 C restrict the length of the initial step size.
740 C For some problems it may not be permissible to integrate
741 C past a point TSTOP because a discontinuity occurs there
742 C or the solution or its derivative is not defined beyond
743 C TSTOP. When you have declared a TSTOP point (SEE INFO(4)
744 C and RWORK(1)), you have told the code not to integrate
745 C past TSTOP. In this case any TOUT beyond TSTOP is invalid
748 C INFO(*) -- Use the INFO array to give the code more details about
749 C how you want your problem solved. This array should be
750 C dimensioned of length 15, though DDASSL uses only the first
751 C eleven entries. You must respond to all of the following
752 C items, which are arranged as questions. The simplest use
753 C of the code corresponds to answering all questions as yes,
754 C i.e. setting all entries of INFO to 0.
756 C INFO(1) - This parameter enables the code to initialize
757 C itself. You must set it to indicate the start of every
760 C **** Is this the first call for this problem ...
761 C Yes - Set INFO(1) = 0
762 C No - Not applicable here.
763 C See below for continuation calls. ****
765 C INFO(2) - How much accuracy you want of your solution
766 C is specified by the error tolerances RTOL and ATOL.
767 C The simplest use is to take them both to be scalars.
768 C To obtain more flexibility, they can both be vectors.
769 C The code must be told your choice.
771 C **** Are both error tolerances RTOL, ATOL scalars ...
772 C Yes - Set INFO(2) = 0
773 C and input scalars for both RTOL and ATOL
774 C No - Set INFO(2) = 1
775 C and input arrays for both RTOL and ATOL ****
777 C INFO(3) - The code integrates from T in the direction
778 C of TOUT by steps. If you wish, it will return the
779 C computed solution and derivative at the next
780 C intermediate step (the intermediate-output mode) or
781 C TOUT, whichever comes first. This is a good way to
782 C proceed if you want to see the behavior of the solution.
783 C If you must have solutions at a great many specific
784 C TOUT points, this code will compute them efficiently.
786 C **** Do you want the solution only at
787 C TOUT (and not at the next intermediate step) ...
788 C Yes - Set INFO(3) = 0
789 C No - Set INFO(3) = 1 ****
791 C INFO(4) - To handle solutions at a great many specific
792 C values TOUT efficiently, this code may integrate past
793 C TOUT and interpolate to obtain the result at TOUT.
794 C Sometimes it is not possible to integrate beyond some
795 C point TSTOP because the equation changes there or it is
796 C not defined past TSTOP. Then you must tell the code
799 C **** Can the integration be carried out without any
800 C restrictions on the independent variable T ...
801 C Yes - Set INFO(4)=0
803 C and define the stopping point TSTOP by
804 C setting RWORK(1)=TSTOP ****
806 C INFO(5) - To solve differential/algebraic problems it is
807 C necessary to use a matrix of partial derivatives of the
808 C system of differential equations. If you do not
809 C provide a subroutine to evaluate it analytically (see
810 C description of the item JAC in the call list), it will
811 C be approximated by numerical differencing in this code.
812 C although it is less trouble for you to have the code
813 C compute partial derivatives by numerical differencing,
814 C the solution will be more reliable if you provide the
815 C derivatives via JAC. Sometimes numerical differencing
816 C is cheaper than evaluating derivatives in JAC and
817 C sometimes it is not - this depends on your problem.
819 C **** Do you want the code to evaluate the partial
820 C derivatives automatically by numerical differences ...
821 C Yes - Set INFO(5)=0
823 C and provide subroutine JAC for evaluating the
824 C matrix of partial derivatives ****
826 C INFO(6) - DDASSL will perform much better if the matrix of
827 C partial derivatives, DG/DY + CJ*DG/DYPRIME,
828 C (here CJ is a scalar determined by DDASSL)
829 C is banded and the code is told this. In this
830 C case, the storage needed will be greatly reduced,
831 C numerical differencing will be performed much cheaper,
832 C and a number of important algorithms will execute much
833 C faster. The differential equation is said to have
834 C half-bandwidths ML (lower) and MU (upper) if equation i
835 C involves only unknowns Y(J) with
836 C I-ML .LE. J .LE. I+MU
837 C for all I=1,2,...,NEQ. Thus, ML and MU are the widths
838 C of the lower and upper parts of the band, respectively,
839 C with the main diagonal being excluded. If you do not
840 C indicate that the equation has a banded matrix of partial
841 C derivatives, the code works with a full matrix of NEQ**2
842 C elements (stored in the conventional way). Computations
843 C with banded matrices cost less time and storage than with
844 C full matrices if 2*ML+MU .LT. NEQ. If you tell the
845 C code that the matrix of partial derivatives has a banded
846 C structure and you want to provide subroutine JAC to
847 C compute the partial derivatives, then you must be careful
848 C to store the elements of the matrix in the special form
849 C indicated in the description of JAC.
851 C **** Do you want to solve the problem using a full
852 C (dense) matrix (and not a special banded
854 C Yes - Set INFO(6)=0
856 C and provide the lower (ML) and upper (MU)
857 C bandwidths by setting
862 C INFO(7) -- You can specify a maximum (absolute value of)
863 C stepsize, so that the code
864 C will avoid passing over very
867 C **** Do you want the code to decide
868 C on its own maximum stepsize?
869 C Yes - Set INFO(7)=0
871 C and define HMAX by setting
874 C INFO(8) -- Differential/algebraic problems
875 C may occaisionally suffer from
876 C severe scaling difficulties on the
877 C first step. If you know a great deal
878 C about the scaling of your problem, you can
879 C help to alleviate this problem by
880 C specifying an initial stepsize HO.
882 C **** Do you want the code to define
883 C its own initial stepsize?
884 C Yes - Set INFO(8)=0
886 C and define HO by setting
889 C INFO(9) -- If storage is a severe problem,
890 C you can save some locations by
891 C restricting the maximum order MAXORD.
892 C the default value is 5. for each
893 C order decrease below 5, the code
894 C requires NEQ fewer locations, however
895 C it is likely to be slower. In any
896 C case, you must have 1 .LE. MAXORD .LE. 5
897 C **** Do you want the maximum order to
899 C Yes - Set INFO(9)=0
901 C and define MAXORD by setting
902 C IWORK(3)=MAXORD ****
904 C INFO(10) --If you know that the solutions to your equations
905 C will always be nonnegative, it may help to set this
906 C parameter. However, it is probably best to
907 C try the code without using this option first,
908 C and only to use this option if that doesn't
910 C **** Do you want the code to solve the problem without
911 C invoking any special nonnegativity constraints?
912 C Yes - Set INFO(10)=0
913 C No - Set INFO(10)=1
915 C INFO(11) --DDASSL normally requires the initial T,
916 C Y, and YPRIME to be consistent. That is,
917 C you must have G(T,Y,YPRIME) = 0 at the initial
918 C time. If you do not know the initial
919 C derivative precisely, you can let DDASSL try
921 C **** Are the initialHE INITIAL T, Y, YPRIME consistent?
922 C Yes - Set INFO(11) = 0
923 C No - Set INFO(11) = 1,
924 C and set YPRIME to an initial approximation
925 C to YPRIME. (If you have no idea what
926 C YPRIME should be, set it to zero. Note
927 C that the initial Y should be such
928 C that there must exist a YPRIME so that
929 C G(T,Y,YPRIME) = 0.)
931 C RTOL, ATOL -- You must assign relative (RTOL) and absolute (ATOL
932 C error tolerances to tell the code how accurately you
933 C want the solution to be computed. They must be defined
934 C as variables because the code may change them. You
935 C have two choices --
936 C Both RTOL and ATOL are scalars. (INFO(2)=0)
937 C Both RTOL and ATOL are vectors. (INFO(2)=1)
938 C in either case all components must be non-negative.
940 C The tolerances are used by the code in a local error
941 C test at each step which requires roughly that
942 C ABS(LOCAL ERROR) .LE. RTOL*ABS(Y)+ATOL
943 C for each vector component.
944 C (More specifically, a root-mean-square norm is used to
945 C measure the size of vectors, and the error test uses the
946 C magnitude of the solution at the beginning of the step.)
948 C The true (global) error is the difference between the
949 C true solution of the initial value problem and the
950 C computed approximation. Practically all present day
951 C codes, including this one, control the local error at
952 C each step and do not even attempt to control the global
954 C Usually, but not always, the true accuracy of the
955 C computed Y is comparable to the error tolerances. This
956 C code will usually, but not always, deliver a more
957 C accurate solution if you reduce the tolerances and
958 C integrate again. By comparing two such solutions you
959 C can get a fairly reliable idea of the true error in the
960 C solution at the bigger tolerances.
962 C Setting ATOL=0. results in a pure relative error test on
963 C that component. Setting RTOL=0. results in a pure
964 C absolute error test on that component. A mixed test
965 C with non-zero RTOL and ATOL corresponds roughly to a
966 C relative error test when the solution component is much
967 C bigger than ATOL and to an absolute error test when the
968 C solution component is smaller than the threshhold ATOL.
970 C The code will not attempt to compute a solution at an
971 C accuracy unreasonable for the machine being used. It will
972 C advise you if you ask for too much accuracy and inform
973 C you as to the maximum accuracy it believes possible.
975 C RWORK(*) -- Dimension this real work array of length LRW in your
978 C LRW -- Set it to the declared length of the RWORK array.
980 C LRW .GE. 40+(MAXORD+4)*NEQ+NEQ**2
981 C for the full (dense) JACOBIAN case (when INFO(6)=0), or
982 C LRW .GE. 40+(MAXORfD+4)*NEQ+(2*ML+MU+1)*NEQ
983 C for the banded user-defined JACOBIAN case
984 C (when INFO(5)=1 and INFO(6)=1), or
985 C LRW .GE. 40+(MAXORD+4)*NEQ+(2*ML+MU+1)*NEQ
986 C +2*(NEQ/(ML+MU+1)+1)
987 C for the banded finite-difference-generated JACOBIAN case
988 C (when INFO(5)=0 and INFO(6)=1)
990 C IWORK(*) -- Dimension this integer work array of length LIW in
991 C your calling program.
993 C LIW -- Set it to the declared length of the IWORK array.
994 C You must have LIW .GE. 20+NEQ
996 C RPAR, IPAR -- These are parameter arrays, of real and integer
997 C type, respectively. You can use them for communication
998 C between your program that calls DDASSL and the
999 C RES subroutine (and the JAC subroutine). They are not
1000 C altered by DDASSL. If you do not need RPAR or IPAR,
1001 C ignore these parameters by treating them as dummy
1002 C arguments. If you do choose to use them, dimension
1003 C them in your calling program and in RES (and in JAC)
1004 C as arrays of appropriate length.
1006 C JAC -- If you have set INFO(5)=0, you can ignore this parameter
1007 C by treating it as a dummy argument. Otherwise, you must
1008 C provide a subroutine of the form
1009 C SUBROUTINE JAC(T,Y,YPRIME,PD,CJ,RPAR,IPAR)
1010 C to define the matrix of partial derivatives
1011 C PD=DG/DY+CJ*DG/DYPRIME
1012 C CJ is a scalar which is input to JAC.
1013 C For the given values of T,Y,YPRIME, the
1014 C subroutine must evaluate the non-zero partial
1015 C derivatives for each equation and each solution
1016 C component, and store these values in the
1017 C matrix PD. The elements of PD are set to zero
1018 C before each call to JAC so only non-zero elements
1019 C need to be defined.
1021 C Subroutine JAC must not alter T,Y,(*),YPRIME(*), or CJ.
1022 C You must declare the name JAC in an EXTERNAL statement in
1023 C your program that calls DDASSL. You must dimension Y,
1024 C YPRIME and PD in JAC.
1026 C The way you must store the elements into the PD matrix
1027 C depends on the structure of the matrix which you
1028 C indicated by INFO(6).
1029 C *** INFO(6)=0 -- Full (dense) matrix ***
1030 C Give PD a first dimension of NEQ.
1031 C When you evaluate the (non-zero) partial derivative
1032 C of equation I with respect to variable J, you must
1033 C store it in PD according to
1034 C PD(I,J) = "DG(I)/DY(J)+CJ*DG(I)/DYPRIME(J)"
1035 C *** INFO(6)=1 -- Banded JACOBIAN with ML lower and MU
1036 C upper diagonal bands (refer to INFO(6) description
1038 C Give PD a first dimension of 2*ML+MU+1.
1039 C when you evaluate the (non-zero) partial derivative
1040 C of equation I with respect to variable J, you must
1041 C store it in PD according to
1042 C IROW = I - J + ML + MU + 1
1043 C PD(IROW,J) = "DG(I)/DY(J)+CJ*DG(I)/DYPRIME(J)"
1045 C RPAR and IPAR are real and integer parameter arrays
1046 C which you can use for communication between your calling
1047 C program and your JACOBIAN subroutine JAC. They are not
1048 C altered by DDASSL. If you do not need RPAR or IPAR,
1049 C ignore these parameters by treating them as dummy
1050 C arguments. If you do choose to use them, dimension
1051 C them in your calling program and in JAC as arrays of
1052 C appropriate length.
1055 C OPTIONALLY REPLACEABLE NORM ROUTINE:
1057 C DDASSL uses a weighted norm DDANRM to measure the size
1058 C of vectors such as the estimated error in each step.
1059 C A FUNCTION subprogram
1060 C DOUBLE PRECISION FUNCTION DDANRM(NEQ,V,WT,RPAR,IPAR)
1061 C DIMENSION V(NEQ),WT(NEQ)
1062 C is used to define this norm. Here, V is the vector
1063 C whose norm is to be computed, and WT is a vector of
1064 C weights. A DDANRM routine has been included with DDASSL
1065 C which computes the weighted root-mean-square norm
1067 C DDANRM=SQRT((1/NEQ)*SUM(V(I)/WT(I))**2)
1068 C this norm is suitable for most problems. In some
1069 C special cases, it may be more convenient and/or
1070 C efficient to define your own norm by writing a function
1071 C subprogram to be called instead of DDANRM. This should,
1072 C however, be attempted only after careful thought and
1076 C -------- OUTPUT -- AFTER ANY RETURN FROM DDASSL ---------------------
1078 C The principal aim of the code is to return a computed solution at
1079 C TOUT, although it is also possible to obtain intermediate results
1080 C along the way. To find out whether the code achieved its goal
1081 C or if the integration process was interrupted before the task was
1082 C completed, you must check the IDID parameter.
1085 C T -- The solution was successfully advanced to the
1086 C output value of T.
1088 C Y(*) -- Contains the computed solution approximation at T.
1090 C YPRIME(*) -- Contains the computed derivative
1091 C approximation at T.
1093 C IDID -- Reports what the code did.
1095 C *** Task completed ***
1096 C Reported by positive values of IDID
1098 C IDID = 1 -- A step was successfully taken in the
1099 C intermediate-output mode. The code has not
1102 C IDID = 2 -- The integration to TSTOP was successfully
1103 C completed (T=TSTOP) by stepping exactly to TSTOP.
1105 C IDID = 3 -- The integration to TOUT was successfully
1106 C completed (T=TOUT) by stepping past TOUT.
1107 C Y(*) is obtained by interpolation.
1108 C YPRIME(*) is obtained by interpolation.
1110 C *** Task interrupted ***
1111 C Reported by negative values of IDID
1113 C IDID = -1 -- A large amount of work has been expended.
1116 C IDID = -2 -- The error tolerances are too stringent.
1118 C IDID = -3 -- The local error test cannot be satisfied
1119 C because you specified a zero component in ATOL
1120 C and the corresponding computed solution
1121 C component is zero. Thus, a pure relative error
1122 C test is impossible for this component.
1124 C IDID = -6 -- DDASSL had repeated error test
1125 C failures on the last attempted step.
1127 C IDID = -7 -- The corrector could not converge.
1129 C IDID = -8 -- The matrix of partial derivatives
1132 C IDID = -9 -- The corrector could not converge.
1133 C there were repeated error test failures
1136 C IDID =-10 -- The corrector could not converge
1137 C because IRES was equal to minus one.
1139 C IDID =-11 -- IRES equal to -2 was encountered
1140 C and control is being returned to the
1143 C IDID =-12 -- DDASSL failed to compute the initial
1148 C IDID = -13,..,-32 -- Not applicable for this code
1150 C *** Task terminated ***
1151 C Reported by the value of IDID=-33
1153 C IDID = -33 -- The code has encountered trouble from which
1154 C it cannot recover. A message is printed
1155 C explaining the trouble and control is returned
1156 C to the calling program. For example, this occurs
1157 C when invalid input is detected.
1159 C RTOL, ATOL -- These quantities remain unchanged except when
1160 C IDID = -2. In this case, the error tolerances have been
1161 C increased by the code to values which are estimated to
1162 C be appropriate for continuing the integration. However,
1163 C the reported solution at T was obtained using the input
1164 C values of RTOL and ATOL.
1166 C RWORK, IWORK -- Contain information which is usually of no
1167 C interest to the user but necessary for subsequent calls.
1168 C However, you may find use for
1170 C RWORK(3)--Which contains the step size H to be
1171 C attempted on the next step.
1173 C RWORK(4)--Which contains the current value of the
1174 C independent variable, i.e., the farthest point
1175 C integration has reached. This will be different
1176 C from T only when interpolation has been
1177 C performed (IDID=3).
1179 C RWORK(7)--Which contains the stepsize used
1180 C on the last successful step.
1182 C IWORK(7)--Which contains the order of the method to
1183 C be attempted on the next step.
1185 C IWORK(8)--Which contains the order of the method used
1188 C IWORK(11)--Which contains the number of steps taken so
1191 C IWORK(12)--Which contains the number of calls to RES
1194 C IWORK(13)--Which contains the number of evaluations of
1195 C the matrix of partial derivatives needed so
1198 C IWORK(14)--Which contains the total number
1199 C of error test failures so far.
1201 C IWORK(15)--Which contains the total number
1202 C of convergence test failures so far.
1203 C (includes singular iteration matrix
1207 C -------- INPUT -- WHAT TO DO TO CONTINUE THE INTEGRATION ------------
1208 C (CALLS AFTER THE FIRST)
1210 C This code is organized so that subsequent calls to continue the
1211 C integration involve little (if any) additional effort on your
1212 C part. You must monitor the IDID parameter in order to determine
1215 C Recalling that the principal task of the code is to integrate
1216 C from T to TOUT (the interval mode), usually all you will need
1217 C to do is specify a new TOUT upon reaching the current TOUT.
1219 C Do not alter any quantity not specifically permitted below,
1220 C in particular do not alter NEQ,T,Y(*),YPRIME(*),RWORK(*),IWORK(*)
1221 C or the differential equation in subroutine RES. Any such
1222 C alteration constitutes a new problem and must be treated as such,
1223 C i.e., you must start afresh.
1225 C You cannot change from vector to scalar error control or vice
1226 C versa (INFO(2)), but you can change the size of the entries of
1227 C RTOL, ATOL. Increasing a tolerance makes the equation easier
1228 C to integrate. Decreasing a tolerance will make the equation
1229 C harder to integrate and should generally be avoided.
1231 C You can switch from the intermediate-output mode to the
1232 C interval mode (INFO(3)) or vice versa at any time.
1234 C If it has been necessary to prevent the integration from going
1235 C past a point TSTOP (INFO(4), RWORK(1)), keep in mind that the
1236 C code will not integrate to any TOUT beyond the currently
1237 C specified TSTOP. Once TSTOP has been reached you must change
1238 C the value of TSTOP or set INFO(4)=0. You may change INFO(4)
1239 C or TSTOP at any time but you must supply the value of TSTOP in
1240 C RWORK(1) whenever you set INFO(4)=1.
1242 C Do not change INFO(5), INFO(6), IWORK(1), or IWORK(2)
1243 C unless you are going to restart the code.
1245 C *** Following a completed task ***
1247 C IDID = 1, call the code again to continue the integration
1248 C another step in the direction of TOUT.
1250 C IDID = 2 or 3, define a new TOUT and call the code again.
1251 C TOUT must be different from T. You cannot change
1252 C the direction of integration without restarting.
1254 C *** Following an interrupted task ***
1255 C To show the code that you realize the task was
1256 C interrupted and that you want to continue, you
1257 C must take appropriate action and set INFO(1) = 1
1259 C IDID = -1, The code has taken about 500 steps.
1260 C If you want to continue, set INFO(1) = 1 and
1261 C call the code again. An additional 500 steps
1264 C IDID = -2, The error tolerances RTOL, ATOL have been
1265 C increased to values the code estimates appropriate
1266 C for continuing. You may want to change them
1267 C yourself. If you are sure you want to continue
1268 C with relaxed error tolerances, set INFO(1)=1 and
1269 C call the code again.
1271 C IDID = -3, A solution component is zero and you set the
1272 C corresponding component of ATOL to zero. If you
1273 C are sure you want to continue, you must first
1274 C alter the error criterion to use positive values
1275 C for those components of ATOL corresponding to zero
1276 C solution components, then set INFO(1)=1 and call
1279 C IDID = -4,-5 --- Cannot occur with this code.
1281 C IDID = -6, Repeated error test failures occurred on the
1282 C last attempted step in DDASSL. A singularity in the
1283 C solution may be present. If you are absolutely
1284 C certain you want to continue, you should restart
1285 C the integration. (Provide initial values of Y and
1286 C YPRIME which are consistent)
1288 C IDID = -7, Repeated convergence test failures occurred
1289 C on the last attempted step in DDASSL. An inaccurate
1290 C or ill-conditioned JACOBIAN may be the problem. If
1291 C you are absolutely certain you want to continue, you
1292 C should restart the integration.
1294 C IDID = -8, The matrix of partial derivatives is singular.
1295 C Some of your equations may be redundant.
1296 C DDASSL cannot solve the problem as stated.
1297 C It is possible that the redundant equations
1298 C could be removed, and then DDASSL could
1299 C solve the problem. It is also possible
1300 C that a solution to your problem either
1301 C does not exist or is not unique.
1303 C IDID = -9, DDASSL had multiple convergence test
1304 C failures, preceeded by multiple error
1305 C test failures, on the last attempted step.
1306 C It is possible that your problem
1307 C is ill-posed, and cannot be solved
1308 C using this code. Or, there may be a
1309 C discontinuity or a singularity in the
1310 C solution. If you are absolutely certain
1311 C you want to continue, you should restart
1314 C IDID =-10, DDASSL had multiple convergence test failures
1315 C because IRES was equal to minus one.
1316 C If you are absolutely certain you want
1317 C to continue, you should restart the
1320 C IDID =-11, IRES=-2 was encountered, and control is being
1321 C returned to the calling program.
1323 C IDID =-12, DDASSL failed to compute the initial YPRIME.
1324 C This could happen because the initial
1325 C approximation to YPRIME was not very good, or
1326 C if a YPRIME consistent with the initial Y
1327 C does not exist. The problem could also be caused
1328 C by an inaccurate or singular iteration matrix.
1330 C IDID = -13,..,-32 --- Cannot occur with this code.
1333 C *** Following a terminated task ***
1335 C If IDID= -33, you cannot continue the solution of this problem.
1336 C An attempt to do so will result in your
1337 C run being terminated.
1340 C -------- ERROR MESSAGES ---------------------------------------------
1342 C The SLATEC error print routine XERMSG is called in the event of
1343 C unsuccessful completion of a task. Most of these are treated as
1344 C "recoverable errors", which means that (unless the user has directed
1345 C otherwise) control will be returned to the calling program for
1346 C possible action after the message has been printed.
1348 C In the event of a negative value of IDID other than -33, an appro-
1349 C priate message is printed and the "error number" printed by XERMSG
1350 C is the value of IDID. There are quite a number of illegal input
1351 C errors that can lead to a returned value IDID=-33. The conditions
1352 C and their printed "error numbers" are as follows:
1354 C Error number Condition
1356 C 1 Some element of INFO vector is not zero or one.
1358 C 3 MAXORD not in range.
1359 C 4 LRW is less than the required length for RWORK.
1360 C 5 LIW is less than the required length for IWORK.
1361 C 6 Some element of RTOL is .lt. 0
1362 C 7 Some element of ATOL is .lt. 0
1363 C 8 All elements of RTOL and ATOL are zero.
1364 C 9 INFO(4)=1 and TSTOP is behind TOUT.
1366 C 11 TOUT is behind T.
1367 C 12 INFO(8)=1 and H0=0.0
1368 C 13 Some element of WT is .le. 0.0
1369 C 14 TOUT is too close to T to start integration.
1370 C 15 INFO(4)=1 and TSTOP is behind T.
1371 C 16 --( Not used in this version )--
1372 C 17 ML illegal. Either .lt. 0 or .gt. NEQ
1373 C 18 MU illegal. Either .lt. 0 or .gt. NEQ
1376 C If DDASSL is called again without any action taken to remove the
1377 C cause of an unsuccessful return, XERMSG will be called with a fatal
1378 C error flag, which will cause unconditional termination of the
1379 C program. There are two such fatal errors:
1381 C Error number -998: The last step was terminated with a negative
1382 C value of IDID other than -33, and no appropriate action was
1385 C Error number -999: The previous call was terminated because of
1386 C illegal input (IDID=-33) and there is illegal input in the
1387 C present call, as well. (Suspect infinite loop.)
1389 C ---------------------------------------------------------------------
1391 C***REFERENCES A DESCRIPTION OF DASSL: A DIFFERENTIAL/ALGEBRAIC
1392 C SYSTEM SOLVER, L. R. PETZOLD, SAND82-8637,
1393 C SANDIA NATIONAL LABORATORIES, SEPTEMBER 1982.
1394 C***ROUTINES CALLED DLAMCH, DDAINI, DDANRM, DDASTP, DDATRP, DDAWTS,
1396 C***REVISION HISTORY (YYMMDD)
1397 C 830315 DATE WRITTEN
1398 C 880387 Code changes made. All common statements have been
1399 C replaced by a DATA statement, which defines pointers into
1400 C RWORK, and PARAMETER statements which define pointers
1401 C into IWORK. As well the documentation has gone through
1402 C grammatical changes.
1403 C 881005 The prologue has been changed to mixed case.
1404 C The subordinate routines had revision dates changed to
1405 C this date, although the documentation for these routines
1406 C is all upper case. No code changes.
1407 C 890511 Code changes made. The DATA statement in the declaration
1408 C section of DDASSL was replaced with a PARAMETER
1409 C statement. Also the statement S = 100.D0 was removed
1410 C from the top of the Newton iteration in DDASTP.
1411 C The subordinate routines had revision dates changed to
1413 C 890517 The revision date syntax was replaced with the revision
1414 C history syntax. Also the "DECK" comment was added to
1415 C the top of all subroutines. These changes are consistent
1416 C with new SLATEC guidelines.
1417 C The subordinate routines had revision dates changed to
1418 C this date. No code changes.
1419 C 891013 Code changes made.
1420 C Removed all occurrances of FLOAT or DBLE. All operations
1421 C are now performed with "mixed-mode" arithmetic.
1422 C Also, specific function names were replaced with generic
1423 C function names to be consistent with new SLATEC guidelines.
1425 C Replaced DSQRT with SQRT everywhere.
1426 C Replaced DABS with ABS everywhere.
1427 C Replaced DMIN1 with MIN everywhere.
1428 C Replaced MIN0 with MIN everywhere.
1429 C Replaced DMAX1 with MAX everywhere.
1430 C Replaced MAX0 with MAX everywhere.
1431 C Replaced DSIGN with SIGN everywhere.
1432 C Also replaced REVISION DATE with REVISION HISTORY in all
1433 C subordinate routines.
1434 C 901004 Miscellaneous changes to prologue to complete conversion
1435 C to SLATEC 4.0 format. No code changes. (F.N.Fritsch)
1436 C 901009 Corrected GAMS classification code and converted subsidiary
1437 C routines to 4.0 format. No code changes. (F.N.Fritsch)
1438 C 901010 Converted XERRWV calls to XERMSG calls. (R.Clemens,AFWL)
1439 C 901019 Code changes made.
1440 C Merged SLATEC 4.0 changes with previous changes made
1441 C by C. Ulrich. Below is a history of the changes made by
1442 C C. Ulrich. (Changes in subsidiary routines are implied
1444 C 891228 Bug was found and repaired inside the DDASSL
1445 C and DDAINI routines. DDAINI was incorrectly
1446 C returning the initial T with Y and YPRIME
1447 C computed at T+H. The routine now returns T+H
1448 C rather than the initial T.
1449 C Cosmetic changes made to DDASTP.
1450 C 900904 Three modifications were made to fix a bug (inside
1451 C DDASSL) re interpolation for continuation calls and
1452 C cases where TN is very close to TSTOP:
1454 C 1) In testing for whether H is too large, just
1455 C compare H to (TSTOP - TN), rather than
1456 C (TSTOP - TN) * (1-4*UROUND), and set H to
1457 C TSTOP - TN. This will force DDASTP to step
1458 C exactly to TSTOP under certain situations
1459 C (i.e. when H returned from DDASTP would otherwise
1460 C take TN beyond TSTOP).
1462 C 2) Inside the DDASTP loop, interpolate exactly to
1463 C TSTOP if TN is very close to TSTOP (rather than
1464 C interpolating to within roundoff of TSTOP).
1466 C 3) Modified IDID description for IDID = 2 to say that
1467 C the solution is returned by stepping exactly to
1468 C TSTOP, rather than TOUT. (In some cases the
1469 C solution is actually obtained by extrapolating
1470 C over a distance near unit roundoff to TSTOP,
1471 C but this small distance is deemed acceptable in
1472 C these circumstances.)
1473 C 901026 Added explicit declarations for all variables and minor
1474 C cosmetic changes to prologue, removed unreferenced labels,
1475 C and improved XERMSG calls. (FNF)
1476 C 901030 Added ERROR MESSAGES section and reworked other sections to
1477 C be of more uniform format. (FNF)
1478 C 910624 Fixed minor bug related to HMAX (five lines ending in
1479 C statement 526 in DDASSL). (LRP)
1481 C***END PROLOGUE DDASSL
1485 C Declare arguments.
1487 INTEGER NEQ, INFO(15), IDID, LRW, IWORK(*), LIW, IPAR(*)
1489 * T, Y(*), YPRIME(*), TOUT, RTOL(*), ATOL(*), RWORK(*),
1493 C Declare externals.
1495 EXTERNAL DLAMCH, DDAINI, DDANRM, DDASTP, DDATRP, DDAWTS, XERMSG
1496 DOUBLE PRECISION DLAMCH, DDANRM
1498 C Declare local variables.
1500 INTEGER I, ITEMP, LALPHA, LBETA, LCJ, LCJOLD, LCTF, LDELTA,
1501 * LENIW, LENPD, LENRW, LE, LETF, LGAMMA, LH, LHMAX, LHOLD, LIPVT,
1502 * LJCALC, LK, LKOLD, LIWM, LML, LMTYPE, LMU, LMXORD, LNJE, LNPD,
1503 * LNRE, LNS, LNST, LNSTL, LPD, LPHASE, LPHI, LPSI, LROUND, LS,
1504 * LSIGMA, LTN, LTSTOP, LWM, LWT, MBAND, MSAVE, MXORD, NPD, NTEMP,
1507 * ATOLI, H, HMAX, HMIN, HO, R, RH, RTOLI, TDIST, TN, TNEXT,
1508 * TSTOP, UROUND, YPNORM
1510 C Auxiliary variables for conversion of values to be included in
1512 CHARACTER*8 XERN1, XERN2
1513 CHARACTER*16 XERN3, XERN4
1515 C SET POINTERS INTO IWORK
1516 PARAMETER (LML=1, LMU=2, LMXORD=3, LMTYPE=4, LNST=11,
1517 * LNRE=12, LNJE=13, LETF=14, LCTF=15, LNPD=16,
1518 * LIPVT=21, LJCALC=5, LPHASE=6, LK=7, LKOLD=8,
1519 * LNS=9, LNSTL=10, LIWM=1)
1521 C SET RELATIVE OFFSET INTO RWORK
1524 C SET POINTERS INTO RWORK
1525 PARAMETER (LTSTOP=1, LHMAX=2, LH=3, LTN=4,
1526 * LCJ=5, LCJOLD=6, LHOLD=7, LS=8, LROUND=9,
1527 * LALPHA=11, LBETA=17, LGAMMA=23,
1528 * LPSI=29, LSIGMA=35, LDELTA=41)
1530 C***FIRST EXECUTABLE STATEMENT DDASSL
1531 IF(INFO(1).NE.0)GO TO 100
1533 C-----------------------------------------------------------------------
1534 C THIS BLOCK IS EXECUTED FOR THE INITIAL CALL ONLY.
1535 C IT CONTAINS CHECKING OF INPUTS AND INITIALIZATIONS.
1536 C-----------------------------------------------------------------------
1538 C FIRST CHECK INFO ARRAY TO MAKE SURE ALL ELEMENTS OF INFO
1539 C ARE EITHER ZERO OR ONE.
1541 IF(INFO(I).NE.0.AND.INFO(I).NE.1)GO TO 701
1544 IF(NEQ.LE.0)GO TO 702
1546 C CHECK AND COMPUTE MAXIMUM ORDER
1548 IF(INFO(9).EQ.0)GO TO 20
1550 IF(MXORD.LT.1.OR.MXORD.GT.5)GO TO 703
1551 20 IWORK(LMXORD)=MXORD
1553 C COMPUTE MTYPE,LENPD,LENRW.CHECK ML AND MU.
1554 IF(INFO(6).NE.0)GO TO 40
1556 LENRW=40+(IWORK(LMXORD)+4)*NEQ+LENPD
1557 IF(INFO(5).NE.0)GO TO 30
1562 40 IF(IWORK(LML).LT.0.OR.IWORK(LML).GE.NEQ)GO TO 717
1563 IF(IWORK(LMU).LT.0.OR.IWORK(LMU).GE.NEQ)GO TO 718
1564 LENPD=(2*IWORK(LML)+IWORK(LMU)+1)*NEQ
1565 IF(INFO(5).NE.0)GO TO 50
1567 MBAND=IWORK(LML)+IWORK(LMU)+1
1569 LENRW=40+(IWORK(LMXORD)+4)*NEQ+LENPD+2*MSAVE
1572 LENRW=40+(IWORK(LMXORD)+4)*NEQ+LENPD
1574 C CHECK LENGTHS OF RWORK AND IWORK
1577 IF(LRW.LT.LENRW)GO TO 704
1578 IF(LIW.LT.LENIW)GO TO 705
1580 C CHECK TO SEE THAT TOUT IS DIFFERENT FROM T
1581 IF(TOUT .EQ. T)GO TO 719
1584 IF(INFO(7).EQ.0)GO TO 70
1586 IF(HMAX.LE.0.0D0)GO TO 710
1589 C INITIALIZE COUNTERS
1598 C-----------------------------------------------------------------------
1599 C THIS BLOCK IS FOR CONTINUATION CALLS
1600 C ONLY. HERE WE CHECK INFO(1),AND IF THE
1601 C LAST STEP WAS INTERRUPTED WE CHECK WHETHER
1602 C APPROPRIATE ACTION WAS TAKEN.
1603 C-----------------------------------------------------------------------
1606 IF(INFO(1).EQ.1)GO TO 110
1607 IF(INFO(1).NE.-1)GO TO 701
1609 C IF WE ARE HERE, THE LAST STEP WAS INTERRUPTED
1610 C BY AN ERROR CONDITION FROM DDASTP,AND
1611 C APPROPRIATE ACTION WAS NOT TAKEN. THIS
1613 WRITE (XERN1, '(I8)') IDID
1614 CALL XERMSG ('SLATEC', 'DDASSL',
1615 * 'THE LAST STEP TERMINATED WITH A NEGATIVE VALUE OF IDID = ' //
1616 * XERN1 // ' AND NO APPROPRIATE ACTION WAS TAKEN. ' //
1617 * 'RUN TERMINATED', -998, 2)
1620 IWORK(LNSTL)=IWORK(LNST)
1622 C-----------------------------------------------------------------------
1623 C THIS BLOCK IS EXECUTED ON ALL CALLS.
1624 C THE ERROR TOLERANCE PARAMETERS ARE
1625 C CHECKED, AND THE WORK ARRAY POINTERS
1627 C-----------------------------------------------------------------------
1635 IF(INFO(2).EQ.1)RTOLI=RTOL(I)
1636 IF(INFO(2).EQ.1)ATOLI=ATOL(I)
1637 IF(RTOLI.GT.0.0D0.OR.ATOLI.GT.0.0D0)NZFLG=1
1638 IF(RTOLI.LT.0.0D0)GO TO 706
1639 IF(ATOLI.LT.0.0D0)GO TO 707
1641 IF(NZFLG.EQ.0)GO TO 708
1643 C SET UP RWORK STORAGE.IWORK STORAGE IS FIXED
1644 C IN DATA STATEMENT.
1648 LPD=LPHI+(IWORK(LMXORD)+1)*NEQ
1650 NTEMP=NPD+IWORK(LNPD)
1651 IF(INFO(1).EQ.1)GO TO 400
1653 C-----------------------------------------------------------------------
1654 C THIS BLOCK IS EXECUTED ON THE INITIAL CALL
1655 C ONLY. SET THE INITIAL STEP SIZE, AND
1656 C THE ERROR WEIGHT VECTOR, AND PHI.
1657 C COMPUTE INITIAL YPRIME, IF NECESSARY.
1658 C-----------------------------------------------------------------------
1663 C SET ERROR WEIGHT VECTOR WT
1664 CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR)
1666 IF(RWORK(LWT+I-1).LE.0.0D0) GO TO 713
1669 C COMPUTE UNIT ROUNDOFF AND HMIN
1670 UROUND = DLAMCH('P')
1671 RWORK(LROUND) = UROUND
1672 HMIN = 4.0D0*UROUND*MAX(ABS(T),ABS(TOUT))
1674 C CHECK INITIAL INTERVAL TO SEE THAT IT IS LONG ENOUGH
1675 TDIST = ABS(TOUT - T)
1676 IF(TDIST .LT. HMIN) GO TO 714
1678 C CHECK HO, IF THIS WAS INPUT
1679 IF (INFO(8) .EQ. 0) GO TO 310
1681 IF ((TOUT - T)*HO .LT. 0.0D0) GO TO 711
1682 IF (HO .EQ. 0.0D0) GO TO 712
1686 C COMPUTE INITIAL STEPSIZE, TO BE USED BY EITHER
1687 C DDASTP OR DDAINI, DEPENDING ON INFO(11)
1689 YPNORM = DDANRM(NEQ,YPRIME,RWORK(LWT),RPAR,IPAR)
1690 IF (YPNORM .GT. 0.5D0/HO) HO = 0.5D0/YPNORM
1691 HO = SIGN(HO,TOUT-T)
1692 C ADJUST HO IF NECESSARY TO MEET HMAX BOUND
1693 320 IF (INFO(7) .EQ. 0) GO TO 330
1694 RH = ABS(HO)/RWORK(LHMAX)
1695 IF (RH .GT. 1.0D0) HO = HO/RH
1696 C COMPUTE TSTOP, IF APPLICABLE
1697 330 IF (INFO(4) .EQ. 0) GO TO 340
1698 TSTOP = RWORK(LTSTOP)
1699 IF ((TSTOP - T)*HO .LT. 0.0D0) GO TO 715
1700 IF ((T + HO - TSTOP)*HO .GT. 0.0D0) HO = TSTOP - T
1701 IF ((TSTOP - TOUT)*HO .LT. 0.0D0) GO TO 709
1703 C COMPUTE INITIAL DERIVATIVE, UPDATING TN AND Y, IF APPLICABLE
1704 340 IF (INFO(11) .EQ. 0) GO TO 350
1706 CALL DDAINI(TN,Y,YPRIME,NEQ,
1707 * RES,JAC,HO,RWORK(LWT),IDID,RPAR,IPAR,
1708 * RWORK(LPHI),RWORK(LDELTA),RWORK(LE),
1709 * RWORK(LWM),IWORK(LIWM),HMIN,RWORK(LROUND),
1711 if(iero.ne.0) return
1712 IF (IDID .LT. 0) GO TO 390
1714 C LOAD H WITH HO. STORE H IN RWORK(LH)
1718 C LOAD Y AND H*YPRIME INTO PHI(*,1) AND PHI(*,2)
1721 RWORK(LPHI + I - 1) = Y(I)
1722 370 RWORK(ITEMP + I - 1) = H*YPRIME(I)
1726 C-------------------------------------------------------
1727 C THIS BLOCK IS FOR CONTINUATION CALLS ONLY. ITS
1728 C PURPOSE IS TO CHECK STOP CONDITIONS BEFORE
1730 C ADJUST H IF NECESSARY TO MEET HMAX BOUND
1731 C-------------------------------------------------------
1734 UROUND=RWORK(LROUND)
1738 IF(INFO(7) .EQ. 0) GO TO 410
1739 RH = ABS(H)/RWORK(LHMAX)
1740 IF(RH .GT. 1.0D0) H = H/RH
1742 IF(T .EQ. TOUT) GO TO 719
1743 IF((T - TOUT)*H .GT. 0.0D0) GO TO 711
1744 IF(INFO(4) .EQ. 1) GO TO 430
1745 IF(INFO(3) .EQ. 1) GO TO 420
1746 IF((TN-TOUT)*H.LT.0.0D0)GO TO 490
1747 CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
1748 * RWORK(LPHI),RWORK(LPSI))
1753 420 IF((TN-T)*H .LE. 0.0D0) GO TO 490
1754 IF((TN - TOUT)*H .GT. 0.0D0) GO TO 425
1755 CALL DDATRP(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD),
1756 * RWORK(LPHI),RWORK(LPSI))
1762 CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
1763 * RWORK(LPHI),RWORK(LPSI))
1768 430 IF(INFO(3) .EQ. 1) GO TO 440
1770 IF((TN-TSTOP)*H.GT.0.0D0) GO TO 715
1771 IF((TSTOP-TOUT)*H.LT.0.0D0)GO TO 709
1772 IF((TN-TOUT)*H.LT.0.0D0)GO TO 450
1773 CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
1774 * RWORK(LPHI),RWORK(LPSI))
1779 440 TSTOP = RWORK(LTSTOP)
1780 IF((TN-TSTOP)*H .GT. 0.0D0) GO TO 715
1781 IF((TSTOP-TOUT)*H .LT. 0.0D0) GO TO 709
1782 IF((TN-T)*H .LE. 0.0D0) GO TO 450
1783 IF((TN - TOUT)*H .GT. 0.0D0) GO TO 445
1784 CALL DDATRP(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD),
1785 * RWORK(LPHI),RWORK(LPSI))
1791 CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
1792 * RWORK(LPHI),RWORK(LPSI))
1798 C CHECK WHETHER WE ARE WITHIN ROUNDOFF OF TSTOP
1799 IF(ABS(TN-TSTOP).GT.100.0D0*UROUND*
1800 * (ABS(TN)+ABS(H)))GO TO 460
1801 CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,IWORK(LKOLD),
1802 * RWORK(LPHI),RWORK(LPSI))
1808 IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 490
1812 490 IF (DONE) GO TO 580
1814 C-------------------------------------------------------
1815 C THE NEXT BLOCK CONTAINS THE CALL TO THE
1816 C ONE-STEP INTEGRATOR DDASTP.
1817 C THIS IS A LOOPING POINT FOR THE INTEGRATION STEPS.
1818 C CHECK FOR TOO MANY STEPS.
1820 C CHECK FOR TOO MUCH ACCURACY REQUESTED.
1821 C COMPUTE MINIMUM STEPSIZE.
1822 C-------------------------------------------------------
1825 C CHECK FOR FAILURE TO COMPUTE INITIAL YPRIME
1826 IF (IDID .EQ. -12) GO TO 527
1828 C CHECK FOR TOO MANY STEPS
1829 IF((IWORK(LNST)-IWORK(LNSTL)).LT.500)
1835 510 CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,RWORK(LPHI),
1836 * RWORK(LWT),RPAR,IPAR)
1838 IF(RWORK(I+LWT-1).GT.0.0D0)GO TO 520
1843 C TEST FOR TOO MUCH ACCURACY REQUESTED.
1844 R=DDANRM(NEQ,RWORK(LPHI),RWORK(LWT),RPAR,IPAR)*
1846 IF(R.LE.1.0D0)GO TO 525
1847 C MULTIPLY RTOL AND ATOL BY R AND RETURN
1848 IF(INFO(2).EQ.1)GO TO 523
1855 524 ATOL(I)=R*ATOL(I)
1860 C COMPUTE MINIMUM STEPSIZE
1861 HMIN=4.0D0*UROUND*MAX(ABS(TN),ABS(TOUT))
1864 IF (INFO(7) .EQ. 0) GO TO 526
1865 RH = ABS(H)/RWORK(LHMAX)
1866 IF (RH .GT. 1.0D0) H = H/RH
1870 CALL DDASTP(TN,Y,YPRIME,NEQ,
1871 * RES,JAC,H,RWORK(LWT),INFO(1),IDID,RPAR,IPAR,
1872 * RWORK(LPHI),RWORK(LDELTA),RWORK(LE),
1873 * RWORK(LWM),IWORK(LIWM),
1874 * RWORK(LALPHA),RWORK(LBETA),RWORK(LGAMMA),
1875 * RWORK(LPSI),RWORK(LSIGMA),
1876 * RWORK(LCJ),RWORK(LCJOLD),RWORK(LHOLD),
1877 * RWORK(LS),HMIN,RWORK(LROUND),
1878 * IWORK(LPHASE),IWORK(LJCALC),IWORK(LK),
1879 * IWORK(LKOLD),IWORK(LNS),INFO(10),NTEMP)
1880 if(iero.ne.0) return
1881 527 IF(IDID.LT.0)GO TO 600
1883 C--------------------------------------------------------
1884 C THIS BLOCK HANDLES THE CASE OF A SUCCESSFUL RETURN
1885 C FROM DDASTP (IDID=1). TEST FOR STOP CONDITIONS.
1886 C--------------------------------------------------------
1888 IF(INFO(4).NE.0)GO TO 540
1889 IF(INFO(3).NE.0)GO TO 530
1890 IF((TN-TOUT)*H.LT.0.0D0)GO TO 500
1891 CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
1892 * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
1896 530 IF((TN-TOUT)*H.GE.0.0D0)GO TO 535
1900 535 CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
1901 * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
1905 540 IF(INFO(3).NE.0)GO TO 550
1906 IF((TN-TOUT)*H.LT.0.0D0)GO TO 542
1907 CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
1908 * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
1912 542 IF(ABS(TN-TSTOP).LE.100.0D0*UROUND*
1913 * (ABS(TN)+ABS(H)))GO TO 545
1915 IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 500
1918 545 CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,
1919 * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
1923 550 IF((TN-TOUT)*H.GE.0.0D0)GO TO 555
1924 IF(ABS(TN-TSTOP).LE.100.0D0*UROUND*(ABS(TN)+ABS(H)))GO TO 552
1928 552 CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,
1929 * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
1933 555 CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,
1934 * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
1939 C--------------------------------------------------------
1940 C ALL SUCCESSFUL RETURNS FROM DDASSL ARE MADE FROM
1942 C--------------------------------------------------------
1949 C-----------------------------------------------------------------------
1950 C THIS BLOCK HANDLES ALL UNSUCCESSFUL
1951 C RETURNS OTHER THAN FOR ILLEGAL INPUT.
1952 C-----------------------------------------------------------------------
1956 GO TO (610,620,630,690,690,640,650,660,670,675,
1959 C THE MAXIMUM NUMBER OF STEPS WAS TAKEN BEFORE
1961 610 WRITE (XERN3, '(1P,D15.6)') TN
1962 CALL XERMSG ('SLATEC', 'DDASSL',
1963 * 'AT CURRENT T = ' // XERN3 // ' 500 STEPS TAKEN ON THIS ' //
1964 * 'CALL BEFORE REACHING TOUT', IDID, 1)
1967 C TOO MUCH ACCURACY FOR MACHINE PRECISION
1968 620 WRITE (XERN3, '(1P,D15.6)') TN
1969 CALL XERMSG ('SLATEC', 'DDASSL',
1970 * 'AT T = ' // XERN3 // ' TOO MUCH ACCURACY REQUESTED FOR ' //
1971 * 'PRECISION OF MACHINE. RTOL AND ATOL WERE INCREASED TO ' //
1972 * 'APPROPRIATE VALUES', IDID, 1)
1975 C WT(I) .LE. 0.0 FOR SOME I (NOT AT START OF PROBLEM)
1976 630 WRITE (XERN3, '(1P,D15.6)') TN
1977 CALL XERMSG ('SLATEC', 'DDASSL',
1978 * 'AT T = ' // XERN3 // ' SOME ELEMENT OF WT HAS BECOME .LE. ' //
1982 C ERROR TEST FAILED REPEATEDLY OR WITH H=HMIN
1983 640 WRITE (XERN3, '(1P,D15.6)') TN
1984 WRITE (XERN4, '(1P,D15.6)') H
1985 CALL XERMSG ('SLATEC', 'DDASSL',
1986 * 'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
1987 * ' THE ERROR TEST FAILED REPEATEDLY OR WITH ABS(H)=HMIN',
1991 C CORRECTOR CONVERGENCE FAILED REPEATEDLY OR WITH H=HMIN
1992 650 WRITE (XERN3, '(1P,D15.6)') TN
1993 WRITE (XERN4, '(1P,D15.6)') H
1994 CALL XERMSG ('SLATEC', 'DDASSL',
1995 * 'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
1996 * ' THE CORRECTOR FAILED TO CONVERGE REPEATEDLY OR WITH ' //
1997 * 'ABS(H)=HMIN', IDID, 1)
2000 C THE ITERATION MATRIX IS SINGULAR
2001 660 WRITE (XERN3, '(1P,D15.6)') TN
2002 WRITE (XERN4, '(1P,D15.6)') H
2003 CALL XERMSG ('SLATEC', 'DDASSL',
2004 * 'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
2005 * ' THE ITERATION MATRIX IS SINGULAR', IDID, 1)
2008 C CORRECTOR FAILURE PRECEEDED BY ERROR TEST FAILURES.
2009 670 WRITE (XERN3, '(1P,D15.6)') TN
2010 WRITE (XERN4, '(1P,D15.6)') H
2011 CALL XERMSG ('SLATEC', 'DDASSL',
2012 * 'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
2013 * ' THE CORRECTOR COULD NOT CONVERGE. ALSO, THE ERROR TEST ' //
2014 * 'FAILED REPEATEDLY.', IDID, 1)
2017 C CORRECTOR FAILURE BECAUSE IRES = -1
2018 675 WRITE (XERN3, '(1P,D15.6)') TN
2019 WRITE (XERN4, '(1P,D15.6)') H
2020 CALL XERMSG ('SLATEC', 'DDASSL',
2021 * 'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
2022 * ' THE CORRECTOR COULD NOT CONVERGE BECAUSE IRES WAS EQUAL ' //
2023 * 'TO MINUS ONE', IDID, 1)
2026 C FAILURE BECAUSE IRES = -2
2027 680 WRITE (XERN3, '(1P,D15.6)') TN
2028 WRITE (XERN4, '(1P,D15.6)') H
2029 CALL XERMSG ('SLATEC', 'DDASSL',
2030 * 'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
2031 * ' IRES WAS EQUAL TO MINUS TWO', IDID, 1)
2034 C FAILED TO COMPUTE INITIAL YPRIME
2035 685 WRITE (XERN3, '(1P,D15.6)') TN
2036 WRITE (XERN4, '(1P,D15.6)') HO
2037 CALL XERMSG ('SLATEC', 'DDASSL',
2038 * 'AT T = ' // XERN3 // ' AND STEPSIZE H = ' // XERN4 //
2039 * ' THE INITIAL YPRIME COULD NOT BE COMPUTED', IDID, 1)
2049 C-----------------------------------------------------------------------
2050 C THIS BLOCK HANDLES ALL ERROR RETURNS DUE
2051 C TO ILLEGAL INPUT, AS DETECTED BEFORE CALLING
2052 C DDASTP. FIRST THE ERROR MESSAGE ROUTINE IS
2053 C CALLED. IF THIS HAPPENS TWICE IN
2054 C SUCCESSION, EXECUTION IS TERMINATED
2056 C-----------------------------------------------------------------------
2057 701 CALL XERMSG ('SLATEC', 'DDASSL',
2058 * 'SOME ELEMENT OF INFO VECTOR IS NOT ZERO OR ONE', 1, 1)
2061 702 WRITE (XERN1, '(I8)') NEQ
2062 CALL XERMSG ('SLATEC', 'DDASSL',
2063 * 'NEQ = ' // XERN1 // ' .LE. 0', 2, 1)
2066 703 WRITE (XERN1, '(I8)') MXORD
2067 CALL XERMSG ('SLATEC', 'DDASSL',
2068 * 'MAXORD = ' // XERN1 // ' NOT IN RANGE', 3, 1)
2071 704 WRITE (XERN1, '(I8)') LENRW
2072 WRITE (XERN2, '(I8)') LRW
2073 CALL XERMSG ('SLATEC', 'DDASSL',
2074 * 'RWORK LENGTH NEEDED, LENRW = ' // XERN1 //
2075 * ', EXCEEDS LRW = ' // XERN2, 4, 1)
2078 705 WRITE (XERN1, '(I8)') LENIW
2079 WRITE (XERN2, '(I8)') LIW
2080 CALL XERMSG ('SLATEC', 'DDASSL',
2081 * 'IWORK LENGTH NEEDED, LENIW = ' // XERN1 //
2082 * ', EXCEEDS LIW = ' // XERN2, 5, 1)
2085 706 CALL XERMSG ('SLATEC', 'DDASSL',
2086 * 'SOME ELEMENT OF RTOL IS .LT. 0', 6, 1)
2089 707 CALL XERMSG ('SLATEC', 'DDASSL',
2090 * 'SOME ELEMENT OF ATOL IS .LT. 0', 7, 1)
2093 708 CALL XERMSG ('SLATEC', 'DDASSL',
2094 * 'ALL ELEMENTS OF RTOL AND ATOL ARE ZERO', 8, 1)
2097 709 WRITE (XERN3, '(1P,D15.6)') TSTOP
2098 WRITE (XERN4, '(1P,D15.6)') TOUT
2099 CALL XERMSG ('SLATEC', 'DDASSL',
2100 * 'INFO(4) = 1 AND TSTOP = ' // XERN3 // ' BEHIND TOUT = ' //
2104 710 WRITE (XERN3, '(1P,D15.6)') HMAX
2105 CALL XERMSG ('SLATEC', 'DDASSL',
2106 * 'HMAX = ' // XERN3 // ' .LT. 0.0', 10, 1)
2109 711 WRITE (XERN3, '(1P,D15.6)') TOUT
2110 WRITE (XERN4, '(1P,D15.6)') T
2111 CALL XERMSG ('SLATEC', 'DDASSL',
2112 * 'TOUT = ' // XERN3 // ' BEHIND T = ' // XERN4, 11, 1)
2115 712 CALL XERMSG ('SLATEC', 'DDASSL',
2116 * 'INFO(8)=1 AND H0=0.0', 12, 1)
2119 713 CALL XERMSG ('SLATEC', 'DDASSL',
2120 * 'SOME ELEMENT OF WT IS .LE. 0.0', 13, 1)
2123 714 WRITE (XERN3, '(1P,D15.6)') TOUT
2124 WRITE (XERN4, '(1P,D15.6)') T
2125 CALL XERMSG ('SLATEC', 'DDASSL',
2126 * 'TOUT = ' // XERN3 // ' TOO CLOSE TO T = ' // XERN4 //
2127 * ' TO START INTEGRATION', 14, 1)
2130 715 WRITE (XERN3, '(1P,D15.6)') TSTOP
2131 WRITE (XERN4, '(1P,D15.6)') T
2132 CALL XERMSG ('SLATEC', 'DDASSL',
2133 * 'INFO(4)=1 AND TSTOP = ' // XERN3 // ' BEHIND T = ' // XERN4,
2137 717 WRITE (XERN1, '(I8)') IWORK(LML)
2138 CALL XERMSG ('SLATEC', 'DDASSL',
2139 * 'ML = ' // XERN1 // ' ILLEGAL. EITHER .LT. 0 OR .GT. NEQ',
2143 718 WRITE (XERN1, '(I8)') IWORK(LMU)
2144 CALL XERMSG ('SLATEC', 'DDASSL',
2145 * 'MU = ' // XERN1 // ' ILLEGAL. EITHER .LT. 0 OR .GT. NEQ',
2149 719 WRITE (XERN3, '(1P,D15.6)') TOUT
2150 CALL XERMSG ('SLATEC', 'DDASSL',
2151 * 'TOUT = T = ' // XERN3, 19, 1)
2155 IF(INFO(1).EQ.-1) THEN
2156 CALL XERMSG ('SLATEC', 'DDASSL',
2157 * 'REPEATED OCCURRENCES OF ILLEGAL INPUT$$' //
2158 * 'RUN TERMINATED. APPARENT INFINITE LOOP', -999, 2)
2163 C-----------END OF SUBROUTINE DDASSL------------------------------------
2166 SUBROUTINE DDASTP (X, Y, YPRIME, NEQ, RES, JAC, H, WT, JSTART,
2167 + IDID, RPAR, IPAR, PHI, DELTA, E, WM, IWM, ALPHA, BETA, GAMMA,
2168 + PSI, SIGMA, CJ, CJOLD, HOLD, S, HMIN, UROUND, IPHASE, JCALC,
2169 + K, KOLD, NS, NONNEG, NTEMP)
2173 C***BEGIN PROLOGUE DDASTP
2175 C***PURPOSE Perform one step of the DDASSL integration.
2176 C***LIBRARY SLATEC (DASSL)
2177 C***TYPE DOUBLE PRECISION (SDASTP-S, DDASTP-D)
2178 C***AUTHOR PETZOLD, LINDA R., (LLNL)
2180 C-----------------------------------------------------------------------
2181 C DDASTP SOLVES A SYSTEM OF DIFFERENTIAL/
2182 C ALGEBRAIC EQUATIONS OF THE FORM
2183 C G(X,Y,YPRIME) = 0, FOR ONE STEP (NORMALLY
2186 C THE METHODS USED ARE MODIFIED DIVIDED
2187 C DIFFERENCE,FIXED LEADING COEFFICIENT
2188 C FORMS OF BACKWARD DIFFERENTIATION
2189 C FORMULAS. THE CODE ADJUSTS THE STEPSIZE
2190 C AND ORDER TO CONTROL THE LOCAL ERROR PER
2194 C THE PARAMETERS REPRESENT
2195 C X -- INDEPENDENT VARIABLE
2196 C Y -- SOLUTION VECTOR AT X
2197 C YPRIME -- DERIVATIVE OF SOLUTION VECTOR
2198 C AFTER SUCCESSFUL STEP
2199 C NEQ -- NUMBER OF EQUATIONS TO BE INTEGRATED
2200 C RES -- EXTERNAL USER-SUPPLIED SUBROUTINE
2201 C TO EVALUATE THE RESIDUAL. THE CALL IS
2202 C CALL RES(X,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
2203 C X,Y,YPRIME ARE INPUT. DELTA IS OUTPUT.
2204 C ON INPUT, IRES=0. RES SHOULD ALTER IRES ONLY
2205 C IF IT ENCOUNTERS AN ILLEGAL VALUE OF Y OR A
2206 C STOP CONDITION. SET IRES=-1 IF AN INPUT VALUE
2207 C OF Y IS ILLEGAL, AND DDASTP WILL TRY TO SOLVE
2208 C THE PROBLEM WITHOUT GETTING IRES = -1. IF
2209 C IRES=-2, DDASTP RETURNS CONTROL TO THE CALLING
2210 C PROGRAM WITH IDID = -11.
2211 C JAC -- EXTERNAL USER-SUPPLIED ROUTINE TO EVALUATE
2212 C THE ITERATION MATRIX (THIS IS OPTIONAL)
2213 C THE CALL IS OF THE FORM
2214 C CALL JAC(X,Y,YPRIME,PD,CJ,RPAR,IPAR)
2215 C PD IS THE MATRIX OF PARTIAL DERIVATIVES,
2216 C PD=DG/DY+CJ*DG/DYPRIME
2217 C H -- APPROPRIATE STEP SIZE FOR NEXT STEP.
2218 C NORMALLY DETERMINED BY THE CODE
2219 C WT -- VECTOR OF WEIGHTS FOR ERROR CRITERION.
2220 C JSTART -- INTEGER VARIABLE SET 0 FOR
2221 C FIRST STEP, 1 OTHERWISE.
2222 C IDID -- COMPLETION CODE WITH THE FOLLOWING MEANINGS:
2223 C IDID= 1 -- THE STEP WAS COMPLETED SUCCESSFULLY
2224 C IDID=-6 -- THE ERROR TEST FAILED REPEATEDLY
2225 C IDID=-7 -- THE CORRECTOR COULD NOT CONVERGE
2226 C IDID=-8 -- THE ITERATION MATRIX IS SINGULAR
2227 C IDID=-9 -- THE CORRECTOR COULD NOT CONVERGE.
2228 C THERE WERE REPEATED ERROR TEST
2229 C FAILURES ON THIS STEP.
2230 C IDID=-10-- THE CORRECTOR COULD NOT CONVERGE
2231 C BECAUSE IRES WAS EQUAL TO MINUS ONE
2232 C IDID=-11-- IRES EQUAL TO -2 WAS ENCOUNTERED,
2233 C AND CONTROL IS BEING RETURNED TO
2234 C THE CALLING PROGRAM
2235 C RPAR,IPAR -- REAL AND INTEGER PARAMETER ARRAYS THAT
2236 C ARE USED FOR COMMUNICATION BETWEEN THE
2237 C CALLING PROGRAM AND EXTERNAL USER ROUTINES
2238 C THEY ARE NOT ALTERED BY DDASTP
2239 C PHI -- ARRAY OF DIVIDED DIFFERENCES USED BY
2240 C DDASTP. THE LENGTH IS NEQ*(K+1),WHERE
2241 C K IS THE MAXIMUM ORDER
2242 C DELTA,E -- WORK VECTORS FOR DDASTP OF LENGTH NEQ
2243 C WM,IWM -- REAL AND INTEGER ARRAYS STORING
2244 C MATRIX INFORMATION SUCH AS THE MATRIX
2245 C OF PARTIAL DERIVATIVES,PERMUTATION
2246 C VECTOR,AND VARIOUS OTHER INFORMATION.
2248 C THE OTHER PARAMETERS ARE INFORMATION
2249 C WHICH IS NEEDED INTERNALLY BY DDASTP TO
2250 C CONTINUE FROM STEP TO STEP.
2252 C-----------------------------------------------------------------------
2253 C***ROUTINES CALLED DDAJAC, DDANRM, DDASLV, DDATRP
2254 C***REVISION HISTORY (YYMMDD)
2255 C 830315 DATE WRITTEN
2256 C 901009 Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
2257 C 901019 Merged changes made by C. Ulrich with SLATEC 4.0 format.
2258 C 901026 Added explicit declarations for all variables and minor
2259 C cosmetic changes to prologue. (FNF)
2260 C***END PROLOGUE DDASTP
2262 INTEGER NEQ, JSTART, IDID, IPAR(*), IWM(*), IPHASE, JCALC, K,
2263 * KOLD, NS, NONNEG, NTEMP
2265 * X, Y(*), YPRIME(*), H, WT(*), RPAR(*), PHI(NEQ,*), DELTA(*),
2266 * E(*), WM(*), ALPHA(*), BETA(*), GAMMA(*), PSI(*), SIGMA(*), CJ,
2267 * CJOLD, HOLD, S, HMIN, UROUND
2270 EXTERNAL DDAJAC, DDANRM, DDASLV, DDATRP
2271 DOUBLE PRECISION DDANRM
2273 INTEGER I, IER, IRES, J, J1, KDIFF, KM1, KNEW, KP1, KP2, LCTF,
2274 * LETF, LMXORD, LNJE, LNRE, LNST, M, MAXIT, NCF, NEF, NSF, NSP1
2276 * ALPHA0, ALPHAS, CJLAST, CK, DELNRM, ENORM, ERK, ERKM1,
2277 * ERKM2, ERKP1, IERR, EST, HNEW, OLDNRM, PNORM, R, RATE, TEMP1,
2278 * TEMP2, TERK, TERKM1, TERKM2, TERKP1, XOLD, XRATE
2281 PARAMETER (LMXORD=3)
2295 C-----------------------------------------------------------------------
2297 C INITIALIZE. ON THE FIRST CALL,SET
2298 C THE ORDER TO 1 AND INITIALIZE
2300 C-----------------------------------------------------------------------
2302 C INITIALIZATIONS FOR ALL CALLS
2303 C***FIRST EXECUTABLE STATEMENT DDASTP
2309 IF(JSTART .NE. 0) GO TO 120
2311 C IF THIS IS THE FIRST STEP,PERFORM
2312 C OTHER INITIALIZATIONS
2333 C-----------------------------------------------------------------------
2335 C COMPUTE COEFFICIENTS OF FORMULAS FOR
2337 C-----------------------------------------------------------------------
2343 IF(H.NE.HOLD.OR.K .NE. KOLD) NS = 0
2346 IF(KP1 .LT. NS)GO TO 230
2356 BETA(I)=BETA(I-1)*PSI(I-1)/TEMP2
2359 SIGMA(I)=(I-1)*SIGMA(I-1)*ALPHA(I)
2360 GAMMA(I)=GAMMA(I-1)+ALPHA(I-1)/H
2365 C COMPUTE ALPHAS, ALPHA0
2369 ALPHAS = ALPHAS - 1.0D0/I
2370 ALPHA0 = ALPHA0 - ALPHA(I)
2373 C COMPUTE LEADING COEFFICIENT CJ
2377 C COMPUTE VARIABLE STEPSIZE ERROR COEFFICIENT CK
2378 CK = ABS(ALPHA(KP1) + ALPHAS - ALPHA0)
2379 CK = MAX(CK,ALPHA(KP1))
2381 C DECIDE WHETHER NEW JACOBIAN IS NEEDED
2382 TEMP1 = (1.0D0 - XRATE)/(1.0D0 + XRATE)
2384 IF (CJ/CJOLD .LT. TEMP1 .OR. CJ/CJOLD .GT. TEMP2) JCALC = -1
2385 IF (CJ .NE. CJLAST) S = 100.D0
2387 C CHANGE PHI TO PHI STAR
2388 IF(KP1 .LT. NSP1) GO TO 280
2391 260 PHI(I,J)=BETA(J)*PHI(I,J)
2402 C-----------------------------------------------------------------------
2404 C PREDICT THE SOLUTION AND DERIVATIVE,
2405 C AND SOLVE THE CORRECTOR EQUATION
2406 C-----------------------------------------------------------------------
2408 C FIRST,PREDICT THE SOLUTION AND DERIVATIVE
2416 320 YPRIME(I)=YPRIME(I)+GAMMA(J)*PHI(I,J)
2418 PNORM = DDANRM (NEQ,Y,WT,RPAR,IPAR)
2422 C SOLVE THE CORRECTOR EQUATION USING A
2423 C MODIFIED NEWTON SCHEME.
2426 IWM(LNRE)=IWM(LNRE)+1
2429 CALL RES(X,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
2430 C IERROR indicates if RES had the right prototype
2431 if(IERROR.ne.0) then
2435 if(iero.ne.0) return
2436 IF (IRES .LT. 0) GO TO 380
2439 C IF INDICATED,REEVALUATE THE
2440 C ITERATION MATRIX PD = DG/DY + CJ*DG/DYPRIME
2441 C (WHERE G(X,Y,YPRIME)=0). SET
2442 C JCALC TO 0 AS AN INDICATOR THAT
2443 C THIS HAS BEEN DONE.
2444 IF(JCALC .NE. -1)GO TO 340
2445 IWM(LNJE)=IWM(LNJE)+1
2447 CALL DDAJAC(NEQ,X,Y,YPRIME,DELTA,CJ,H,
2448 * IER,WT,E,WM,IWM,RES,IRES,UROUND,JAC,RPAR,
2450 if(iero.ne.0) return
2453 IF (IRES .LT. 0) GO TO 380
2454 IF(IER .NE. 0)GO TO 380
2458 C INITIALIZE THE ERROR ACCUMULATION VECTOR E.
2467 C MULTIPLY RESIDUAL BY TEMP1 TO ACCELERATE CONVERGENCE
2468 TEMP1 = 2.0D0/(1.0D0 + CJ/CJOLD)
2470 355 DELTA(I) = DELTA(I) * TEMP1
2472 C COMPUTE A NEW ITERATE (BACK-SUBSTITUTION).
2473 C STORE THE CORRECTION IN DELTA.
2474 CALL DDASLV(NEQ,DELTA,WM,IWM)
2476 C UPDATE Y,E,AND YPRIME
2480 360 YPRIME(I)=YPRIME(I)-CJ*DELTA(I)
2482 C TEST FOR CONVERGENCE OF THE ITERATION
2483 DELNRM=DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
2484 IF (DELNRM .LE. 100.D0*UROUND*PNORM) GO TO 375
2485 IF (M .GT. 0) GO TO 365
2488 365 RATE = (DELNRM/OLDNRM)**(1.0D0/M)
2489 IF (RATE .GT. 0.90D0) GO TO 370
2490 S = RATE/(1.0D0 - RATE)
2491 367 IF (S*DELNRM .LE. 0.33D0) GO TO 375
2493 C THE CORRECTOR HAS NOT YET CONVERGED.
2494 C UPDATE M AND TEST WHETHER THE
2495 C MAXIMUM NUMBER OF ITERATIONS HAVE
2498 IF(M.GE.MAXIT)GO TO 370
2500 C EVALUATE THE RESIDUAL
2501 C AND GO BACK TO DO ANOTHER ITERATION
2502 IWM(LNRE)=IWM(LNRE)+1
2504 CALL RES(X,Y,YPRIME,DELTA,IRES,
2506 if(iero.ne.0) return
2507 IF (IRES .LT. 0) GO TO 380
2511 C THE CORRECTOR FAILED TO CONVERGE IN MAXIT
2512 C ITERATIONS. IF THE ITERATION MATRIX
2513 C IS NOT CURRENT,RE-DO THE STEP WITH
2514 C A NEW ITERATION MATRIX.
2516 IF(JCALC.EQ.0)GO TO 380
2521 C THE ITERATION HAS CONVERGED. IF NONNEGATIVITY OF SOLUTION IS
2522 C REQUIRED, SET THE SOLUTION NONNEGATIVE, IF THE PERTURBATION
2523 C TO DO IT IS SMALL ENOUGH. IF THE CHANGE IS TOO LARGE, THEN
2524 C CONSIDER THE CORRECTOR ITERATION TO HAVE FAILED.
2525 375 IF(NONNEG .EQ. 0) GO TO 390
2527 377 DELTA(I) = MIN(Y(I),0.0D0)
2528 DELNRM = DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
2529 IF(DELNRM .GT. 0.33D0) GO TO 380
2531 378 E(I) = E(I) - DELTA(I)
2535 C EXITS FROM BLOCK 3
2536 C NO CONVERGENCE WITH CURRENT ITERATION
2537 C MATRIX,OR SINGULAR ITERATION MATRIX
2540 IF(.NOT.CONVGD)GO TO 600
2546 C-----------------------------------------------------------------------
2548 C ESTIMATE THE ERRORS AT ORDERS K,K-1,K-2
2549 C AS IF CONSTANT STEPSIZE WAS USED. ESTIMATE
2550 C THE LOCAL ERROR AT ORDER K AND TEST
2551 C WHETHER THE CURRENT STEP IS SUCCESSFUL.
2552 C-----------------------------------------------------------------------
2554 C ESTIMATE ERRORS AT ORDERS K,K-1,K-2
2555 ENORM = DDANRM(NEQ,E,WT,RPAR,IPAR)
2556 ERK = SIGMA(K+1)*ENORM
2560 IF(K .EQ. 1)GO TO 430
2562 405 DELTA(I) = PHI(I,KP1) + E(I)
2563 ERKM1=SIGMA(K)*DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
2565 IF(K .GT. 2)GO TO 410
2566 IF(TERKM1 .LE. 0.5D0*TERK)GO TO 420
2570 415 DELTA(I) = PHI(I,K) + DELTA(I)
2571 ERKM2=SIGMA(K-1)*DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
2572 TERKM2 = (K-1)*ERKM2
2573 IF(MAX(TERKM1,TERKM2).GT.TERK)GO TO 430
2580 C CALCULATE THE LOCAL ERROR FOR THE CURRENT STEP
2581 C TO SEE IF THE STEP WAS SUCCESSFUL
2584 IF(IERR .GT. 1.0D0)GO TO 600
2590 C-----------------------------------------------------------------------
2592 C THE STEP IS SUCCESSFUL. DETERMINE
2593 C THE BEST ORDER AND STEPSIZE FOR
2594 C THE NEXT STEP. UPDATE THE DIFFERENCES
2595 C FOR THE NEXT STEP.
2596 C-----------------------------------------------------------------------
2598 IWM(LNST)=IWM(LNST)+1
2604 C ESTIMATE THE ERROR AT ORDER K+1 UNLESS:
2605 C ALREADY DECIDED TO LOWER ORDER, OR
2606 C ALREADY USING MAXIMUM ORDER, OR
2607 C STEPSIZE NOT CONSTANT, OR
2608 C ORDER RAISED IN PREVIOUS STEP
2609 IF(KNEW.EQ.KM1.OR.K.EQ.IWM(LMXORD))IPHASE=1
2610 IF(IPHASE .EQ. 0)GO TO 545
2611 IF(KNEW.EQ.KM1)GO TO 540
2612 IF(K.EQ.IWM(LMXORD)) GO TO 550
2613 IF(KP1.GE.NS.OR.KDIFF.EQ.1)GO TO 550
2615 510 DELTA(I)=E(I)-PHI(I,KP2)
2616 ERKP1 = (1.0D0/(K+2))*DDANRM(NEQ,DELTA,WT,RPAR,IPAR)
2617 TERKP1 = (K+2)*ERKP1
2619 IF(TERKP1.GE.0.5D0*TERK)GO TO 550
2621 520 IF(TERKM1.LE.MIN(TERK,TERKP1))GO TO 540
2622 IF(TERKP1.GE.TERK.OR.K.EQ.IWM(LMXORD))GO TO 550
2634 C IF IPHASE = 0, INCREASE ORDER BY ONE AND MULTIPLY STEPSIZE BY
2642 C DETERMINE THE APPROPRIATE STEPSIZE FOR
2646 R=(2.0D0*EST+0.0001D0)**(-1.0D0/TEMP2)
2647 IF(R .LT. 2.0D0) GO TO 555
2650 555 IF(R .GT. 1.0D0) GO TO 560
2651 R = MAX(0.5D0,MIN(0.9D0,R))
2656 C UPDATE DIFFERENCES FOR NEXT STEP
2658 IF(KOLD.EQ.IWM(LMXORD))GO TO 585
2663 590 PHI(I,KP1)=PHI(I,KP1)+E(I)
2667 595 PHI(I,J)=PHI(I,J)+PHI(I,J+1)
2674 C-----------------------------------------------------------------------
2676 C THE STEP IS UNSUCCESSFUL. RESTORE X,PSI,PHI
2677 C DETERMINE APPROPRIATE STEPSIZE FOR
2678 C CONTINUING THE INTEGRATION, OR EXIT WITH
2679 C AN ERROR FLAG IF THERE HAVE BEEN MANY
2681 C-----------------------------------------------------------------------
2686 IF(KP1.LT.NSP1)GO TO 630
2690 610 PHI(I,J)=TEMP1*PHI(I,J)
2694 640 PSI(I-1)=PSI(I)-H
2697 C TEST WHETHER FAILURE IS DUE TO CORRECTOR ITERATION
2700 IWM(LCTF)=IWM(LCTF)+1
2703 C THE NEWTON ITERATION FAILED TO CONVERGE WITH
2704 C A CURRENT ITERATION MATRIX. DETERMINE THE CAUSE
2705 C OF THE FAILURE AND TAKE APPROPRIATE ACTION.
2706 IF(IER.EQ.0)GO TO 650
2708 C THE ITERATION MATRIX IS SINGULAR. REDUCE
2709 C THE STEPSIZE BY A FACTOR OF 4. IF
2710 C THIS HAPPENS THREE TIMES IN A ROW ON
2711 C THE SAME STEP, RETURN WITH AN ERROR FLAG
2715 IF (NSF .LT. 3 .AND. ABS(H) .GE. HMIN) GO TO 690
2720 C THE NEWTON ITERATION FAILED TO CONVERGE FOR A REASON
2721 C OTHER THAN A SINGULAR ITERATION MATRIX. IF IRES = -2, THEN
2722 C RETURN. OTHERWISE, REDUCE THE STEPSIZE AND TRY AGAIN, UNLESS
2723 C TOO MANY FAILURES HAVE OCCURRED.
2725 IF (IRES .GT. -2) GO TO 655
2731 IF (NCF .LT. 10 .AND. ABS(H) .GE. HMIN) GO TO 690
2733 IF (IRES .LT. 0) IDID = -10
2734 IF (NEF .GE. 3) IDID = -9
2738 C THE NEWTON SCHEME CONVERGED,AND THE CAUSE
2739 C OF THE FAILURE WAS THE ERROR ESTIMATE
2740 C EXCEEDING THE TOLERANCE.
2742 IWM(LETF)=IWM(LETF)+1
2743 IF (NEF .GT. 1) GO TO 665
2745 C ON FIRST ERROR TEST FAILURE, KEEP CURRENT ORDER OR LOWER
2746 C ORDER BY ONE. COMPUTE NEW STEPSIZE BASED ON DIFFERENCES
2750 R = 0.90D0*(2.0D0*EST+0.0001D0)**(-1.0D0/TEMP2)
2751 R = MAX(0.25D0,MIN(0.9D0,R))
2753 IF (ABS(H) .GE. HMIN) GO TO 690
2757 C ON SECOND ERROR TEST FAILURE, USE THE CURRENT ORDER OR
2758 C DECREASE ORDER BY ONE. REDUCE THE STEPSIZE BY A FACTOR OF
2760 665 IF (NEF .GT. 2) GO TO 670
2763 IF (ABS(H) .GE. HMIN) GO TO 690
2767 C ON THIRD AND SUBSEQUENT ERROR TEST FAILURES, SET THE ORDER TO
2768 C ONE AND REDUCE THE STEPSIZE BY A FACTOR OF FOUR.
2771 IF (ABS(H) .GE. HMIN) GO TO 690
2778 C FOR ALL CRASHES, RESTORE Y TO ITS LAST VALUE,
2779 C INTERPOLATE TO FIND YPRIME AT LAST X, AND RETURN
2781 CALL DDATRP(X,X,Y,YPRIME,NEQ,K,PHI,PSI)
2785 C GO BACK AND TRY THIS STEP AGAIN
2788 C------END OF SUBROUTINE DDASTP------
2790 SUBROUTINE DDATRP (X, XOUT, YOUT, YPOUT, NEQ, KOLD, PHI, PSI)
2791 C***BEGIN PROLOGUE DDATRP
2793 C***PURPOSE Interpolation routine for DDASSL.
2794 C***LIBRARY SLATEC (DASSL)
2795 C***TYPE DOUBLE PRECISION (SDATRP-S, DDATRP-D)
2796 C***AUTHOR PETZOLD, LINDA R., (LLNL)
2798 C-----------------------------------------------------------------------
2799 C THE METHODS IN SUBROUTINE DDASTP USE POLYNOMIALS
2800 C TO APPROXIMATE THE SOLUTION. DDATRP APPROXIMATES THE
2801 C SOLUTION AND ITS DERIVATIVE AT TIME XOUT BY EVALUATING
2802 C ONE OF THESE POLYNOMIALS,AND ITS DERIVATIVE,THERE.
2803 C INFORMATION DEFINING THIS POLYNOMIAL IS PASSED FROM
2804 C DDASTP, SO DDATRP CANNOT BE USED ALONE.
2806 C THE PARAMETERS ARE:
2807 C X THE CURRENT TIME IN THE INTEGRATION.
2808 C XOUT THE TIME AT WHICH THE SOLUTION IS DESIRED
2809 C YOUT THE INTERPOLATED APPROXIMATION TO Y AT XOUT
2811 C YPOUT THE INTERPOLATED APPROXIMATION TO YPRIME AT XOUT
2813 C NEQ NUMBER OF EQUATIONS
2814 C KOLD ORDER USED ON LAST SUCCESSFUL STEP
2815 C PHI ARRAY OF SCALED DIVIDED DIFFERENCES OF Y
2816 C PSI ARRAY OF PAST STEPSIZE HISTORY
2817 C-----------------------------------------------------------------------
2818 C***ROUTINES CALLED (NONE)
2819 C***REVISION HISTORY (YYMMDD)
2820 C 830315 DATE WRITTEN
2821 C 901009 Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
2822 C 901019 Merged changes made by C. Ulrich with SLATEC 4.0 format.
2823 C 901026 Added explicit declarations for all variables and minor
2824 C cosmetic changes to prologue. (FNF)
2825 C***END PROLOGUE DDATRP
2828 DOUBLE PRECISION X, XOUT, YOUT(*), YPOUT(*), PHI(NEQ,*), PSI(*)
2830 INTEGER I, J, KOLDP1
2831 DOUBLE PRECISION C, D, GAMMA, TEMP1
2833 C***FIRST EXECUTABLE STATEMENT DDATRP
2843 D=D*GAMMA+C/PSI(J-1)
2845 GAMMA=(TEMP1+PSI(J-1))/PSI(J)
2847 YOUT(I)=YOUT(I)+C*PHI(I,J)
2848 20 YPOUT(I)=YPOUT(I)+D*PHI(I,J)
2852 C------END OF SUBROUTINE DDATRP------
2854 SUBROUTINE DDAWTS (NEQ, IWT, RTOL, ATOL, Y, WT, RPAR, IPAR)
2855 C***BEGIN PROLOGUE DDAWTS
2857 C***PURPOSE Set error weight vector for DDASSL.
2858 C***LIBRARY SLATEC (DASSL)
2859 C***TYPE DOUBLE PRECISION (SDAWTS-S, DDAWTS-D)
2860 C***AUTHOR PETZOLD, LINDA R., (LLNL)
2862 C-----------------------------------------------------------------------
2863 C THIS SUBROUTINE SETS THE ERROR WEIGHT VECTOR
2864 C WT ACCORDING TO WT(I)=RTOL(I)*ABS(Y(I))+ATOL(I),
2866 C RTOL AND ATOL ARE SCALARS IF IWT = 0,
2867 C AND VECTORS IF IWT = 1.
2868 C-----------------------------------------------------------------------
2869 C***ROUTINES CALLED (NONE)
2870 C***REVISION HISTORY (YYMMDD)
2871 C 830315 DATE WRITTEN
2872 C 901009 Finished conversion to SLATEC 4.0 format (F.N.Fritsch)
2873 C 901019 Merged changes made by C. Ulrich with SLATEC 4.0 format.
2874 C 901026 Added explicit declarations for all variables and minor
2875 C cosmetic changes to prologue. (FNF)
2876 C***END PROLOGUE DDAWTS
2878 INTEGER NEQ, IWT, IPAR(*)
2879 DOUBLE PRECISION RTOL(*), ATOL(*), Y(*), WT(*), RPAR(*)
2882 DOUBLE PRECISION ATOLI, RTOLI
2884 C***FIRST EXECUTABLE STATEMENT DDAWTS
2888 IF (IWT .EQ.0) GO TO 10
2891 10 WT(I)=RTOLI*ABS(Y(I))+ATOLI
2894 C-----------END OF SUBROUTINE DDAWTS------------------------------------