source: palm/trunk/UTIL/chemistry/gasphase_preproc/kpp/int/kpp_lsode.f90 @ 2718

Last change on this file since 2718 was 2696, checked in by kanani, 7 years ago

Merge of branch palm4u into trunk

File size: 195.4 KB
Line 
1!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
2!  LSODE - Stiff method based on backward differentiation formulas (BDF)  !
3!  By default the code employs the KPP sparse linear algebra routines     !
4!  Compile with -DFULL_ALGEBRA to use full linear algebra (LAPACK)        !
5!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
6! A. Sandu - version of July 2005
7
8MODULE KPP_ROOT_Integrator
9
10  USE KPP_ROOT_Precision
11  USE KPP_ROOT_Global, ONLY: FIX, RCONST, TIME, ATOL, RTOL
12  USE KPP_ROOT_Parameters, ONLY: NVAR, NSPEC, NFIX, LU_NONZERO
13  USE KPP_ROOT_JacobianSP, ONLY: LU_DIAG
14  USE KPP_ROOT_LinearAlgebra, ONLY: KppDecomp, KppSolve, &
15               Set2zero, WLAMCH
16 
17  IMPLICIT NONE
18  PUBLIC
19  SAVE
20 
21  !~~~>  Statistics on the work performed by the LSODE method
22  INTEGER :: Nfun,Njac,Nstp,Nacc,Nrej,Ndec,Nsol,Nsng
23  INTEGER, PARAMETER :: ifun=1, ijac=2, istp=3, iacc=4,  &
24    irej=5, idec=6, isol=7, isng=8, itexit=1, ihexit=2
25  !  SDIRK method coefficients
26  KPP_REAL :: rkAlpha(5,4), rkBeta(5,4), rkD(4,5),  &
27                   rkGamma, rkA(5,5), rkB(5), rkC(5)
28
29  ! mz_rs_20050717: TODO: use strings of IERR_NAMES for error messages
30  ! description of the error numbers IERR
31  CHARACTER(LEN=50), PARAMETER, DIMENSION(-8:1) :: IERR_NAMES = (/ &
32    'Matrix is repeatedly singular                     ', & ! -8
33    'Step size too small                               ', & ! -7
34    'No of steps exceeds maximum bound                 ', & ! -6
35    'Improper tolerance values                         ', & ! -5
36    'FacMin/FacMax/FacRej must be positive             ', & ! -4
37    'Hmin/Hmax/Hstart must be positive                 ', & ! -3
38    'Improper value for maximal no of Newton iterations', & ! -2
39    'Improper value for maximal no of steps            ', & ! -1
40    '                                                  ', & !  0 (not used)
41    'Success                                           ' /) !  1
42
43CONTAINS
44
45SUBROUTINE INTEGRATE( TIN, TOUT, &
46  ICNTRL_U, RCNTRL_U, ISTATUS_U, RSTATUS_U, IERR_U )
47
48   USE KPP_ROOT_Parameters
49   USE KPP_ROOT_Global
50   IMPLICIT NONE
51
52   KPP_REAL, INTENT(IN) :: TIN  ! Start Time
53   KPP_REAL, INTENT(IN) :: TOUT ! End Time
54   ! Optional input parameters and statistics
55   INTEGER,  INTENT(IN),  OPTIONAL :: ICNTRL_U(20)
56   KPP_REAL, INTENT(IN),  OPTIONAL :: RCNTRL_U(20)
57   INTEGER,  INTENT(OUT), OPTIONAL :: ISTATUS_U(20)
58   KPP_REAL, INTENT(OUT), OPTIONAL :: RSTATUS_U(20)
59   INTEGER,  INTENT(OUT), OPTIONAL :: IERR_U
60
61   KPP_REAL :: RCNTRL(20), RSTATUS(20)
62   INTEGER       :: ICNTRL(20), ISTATUS(20), IERR
63!!$   INTEGER, SAVE :: Ntotal = 0
64
65   ICNTRL(:)  = 0
66   RCNTRL(:)  = 0.0_dp
67   ISTATUS(:) = 0
68   RSTATUS(:) = 0.0_dp
69
70   ICNTRL(5) = 2 ! maximal order
71
72   ! If optional parameters are given, and if they are >0,
73   ! then they overwrite default settings.
74   IF (PRESENT(ICNTRL_U)) THEN
75     WHERE(ICNTRL_U(:) > 0) ICNTRL(:) = ICNTRL_U(:)
76   END IF
77   IF (PRESENT(RCNTRL_U)) THEN
78     WHERE(RCNTRL_U(:) > 0) RCNTRL(:) = RCNTRL_U(:)
79   END IF
80
81   CALL KppLsode( TIN,TOUT,VAR,RTOL,ATOL,                &
82                  RCNTRL,ICNTRL,RSTATUS,ISTATUS,IERR )
83
84!     INTEGER ITASK, ISTATE, NG, NEQ, IOUT, JROOT, ISTATS, &
85!     IERROR, I
86!     DOUBLE PRECISION ATOL, RTOL, RSTATS, T, TOUT, Y
87!     DIMENSION JROOT(2)
88!     TYPE(VODE_OPTS) :: OPTIONS
89!     IERROR = 0
90!     ITASK = 1
91!     ISTATE = 1
92!     NG = 2
93!     OPTIONS = SET_OPTS(DENSE_J=.TRUE.,RELERR=RTOL, &
94!       ABSERR_VECTOR=ATOL,NEVENTS=NG)
95!       CALL DVODE_F90(FEX,NEQ,Y,TIN,TOUT,ITASK,ISTATE,OPTIONS,G_FCN=GEX)
96!       CALL GET_STATS(RSTATS, ISTATS, NG, JROOT)
97
98
99   STEPMIN = RSTATUS(ihexit) ! Save last step
100   
101   ! if optional parameters are given for output they to return information
102   IF (PRESENT(ISTATUS_U)) ISTATUS_U(:) = ISTATUS(1:20)
103   IF (PRESENT(RSTATUS_U)) RSTATUS_U(:) = RSTATUS(1:20)
104   IF (PRESENT(IERR_U)) THEN
105     IF (IERR==2) THEN ! DLSODE returns "2" after successful completion
106       IERR_U = 1 ! IERR_U will return "1" for successful completion
107     ELSE
108       IERR_U = IERR
109     ENDIF
110   ENDIF
111
112   END SUBROUTINE INTEGRATE
113
114!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115      SUBROUTINE KppLsode( TIN,TOUT,Y,RelTol,AbsTol,      &
116               RCNTRL,ICNTRL,RSTATUS,ISTATUS,IERR )
117!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118!
119!~~~>     INPUT PARAMETERS:
120!
121!    Note: For input parameters equal to zero the default values of the
122!       corresponding variables are used.
123!
124!    Note: For input parameters equal to zero the default values of the
125!          corresponding variables are used.
126!~~~> 
127!    ICNTRL(1) = not used
128!
129!    ICNTRL(2) = 0: AbsTol, RelTol are NVAR-dimensional vectors
130!              = 1: AbsTol, RelTol are scalars
131!
132!    ICNTRL(3) = not used
133!
134!    ICNTRL(4)  -> maximum number of integration steps
135!        For ICNTRL(4)=0 the default value of 100000 is used
136!
137!    ICNTRL(5)  -> maximum order of the integration formula allowed
138!
139!~~~>  Real parameters
140!
141!    RCNTRL(1)  -> Hmin, lower bound for the integration step size
142!                  It is strongly recommended to keep Hmin = ZERO
143!    RCNTRL(2)  -> Hmax, upper bound for the integration step size
144!    RCNTRL(3)  -> Hstart, starting value for the integration step size
145!
146!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
147!
148!~~~>     OUTPUT PARAMETERS:
149!
150!    Note: each call to Rosenbrock adds the current no. of fcn calls
151!      to previous value of ISTATUS(1), and similar for the other params.
152!      Set ISTATUS(1:10) = 0 before call to avoid this accumulation.
153!
154!    ISTATUS(1) = No. of function calls
155!    ISTATUS(2) = No. of jacobian calls
156!    ISTATUS(3) = No. of steps
157!
158!    RSTATUS(1)  -> Texit, the time corresponding to the
159!                   computed Y upon return
160!    RSTATUS(2)  -> Hexit, last predicted step before exit
161!    For multiple restarts, use Hexit as Hstart in the following run
162!
163!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
164
165      IMPLICIT NONE
166      KPP_REAL :: Y(NVAR), AbsTol(NVAR), RelTol(NVAR), TIN, TOUT
167      KPP_REAL :: RCNTRL(20), RSTATUS(20)
168      INTEGER       :: ICNTRL(20), ISTATUS(20)
169      INTEGER, PARAMETER :: LRW = 25 + 9*NVAR+2*NVAR*NVAR, &
170                            LIW = 32 + NVAR
171      KPP_REAL :: RWORK(LRW), RPAR(1)
172      INTEGER :: IWORK(LIW), IPAR(1), ITOL, ITASK,         &
173                 IERR, IOPT, MF
174
175      !~~~> NORMAL COMPUTATION
176      ITASK  = 1
177      IERR   = 1
178      IOPT   = 1     ! 0=no/1=use optional input
179     
180      RWORK(1:30) = 0.0d0
181      IWORK(1:30) = 0
182     
183      IF (ICNTRL(2)==0) THEN
184         ITOL = 4           ! Abs/RelTol are both vectors
185      ELSE             
186         ITOL = 1           ! Abs/RelTol are both scalars
187      END IF   
188      IWORK(6) = ICNTRL(4)  ! max number of internal steps
189      IWORK(5) = ICNTRL(5)  ! maximal order
190
191      MF = 21  !~~~> stiff case, analytic full Jacobian
192
193      RWORK(5) = RCNTRL(3)  ! Hstart
194      RWORK(6) = RCNTRL(2)  ! Hmax                   
195      RWORK(7) = RCNTRL(1)  ! Hmin                   
196
197      CALL DLSODE ( FUN_CHEM, NVAR, Y, TIN, TOUT, ITOL, RelTol, AbsTol, ITASK,&
198                    IERR, IOPT, RWORK, LRW, IWORK, LIW, JAC_CHEM, MF)
199
200      ISTATUS(1) = IWORK(12) ! Number of function evaluations
201      ISTATUS(2) = IWORK(13) ! Number of Jacobian evaluations   
202      ISTATUS(3) = IWORK(11) ! Number of steps
203
204      RSTATUS(1) = TOUT      ! mz_rs_20050717
205      RSTATUS(2) = RWORK(11) ! mz_rs_20050717
206
207      END SUBROUTINE KppLsode
208!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
209
210
211!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
212!DECK DLSODE                                                           
213      SUBROUTINE DLSODE (F, NEQ, Y, T, TOUT, ITOL, RelTol, AbsTol, ITASK,   &
214                       ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, MF) 
215      EXTERNAL F, JAC 
216      INTEGER NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, LIW, IWORK(LIW), MF 
217      KPP_REAL Y(*), T, TOUT, RelTol(*), AbsTol(*), RWORK(LRW)
218!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
219!***BEGIN PROLOGUE  DLSODE                                             
220!***PURPOSE  Livermore Solver for Ordinary Differential Equations.     
221!            DLSODE solves the initial-value problem for stiff or       
222!            nonstiff systems of first-order ODE's,                     
223!               dy/dt = f(t,y),   or, in component form,               
224!               dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(N)),  i=1,...,N.
225!***CATEGORY  I1A                                                       
226!***TYPE      KPP_REAL (SLSODE-S, DLSODE-D)                     
227!***KEYWORDS  ORDINARY DIFFERENTIAL EQUATIONS, INITIAL VALUE PROBLEM,   
228!             STIFF, NONSTIFF                                           
229!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
230!             Center for Applied Scientific Computing, L-561           
231!             Lawrence Livermore National Laboratory                   
232!             Livermore, CA 94551.                                     
233!***DESCRIPTION                                                         
234!                                                                       
235!     NOTE: The "Usage" and "Arguments" sections treat only a subset of
236!           available options, in condensed fashion.  The options       
237!           covered and the information supplied will support most     
238!           standard uses of DLSODE.                                   
239!                                                                       
240!           For more sophisticated uses, full details on all options are
241!           given in the concluding section, headed "Long Description."
242!           A synopsis of the DLSODE Long Description is provided at the
243!           beginning of that section; general topics covered are:     
244!           - Elements of the call sequence; optional input and output 
245!           - Optional supplemental routines in the DLSODE package     
246!           - internal COMMON block                                     
247!                                                                       
248! *Usage:                                                               
249!     Communication between the user and the DLSODE package, for normal
250!     situations, is summarized here.  This summary describes a subset 
251!     of the available options.  See "Long Description" for complete   
252!     details, including optional communication, nonstandard options,   
253!     and instructions for special situations.                         
254!                                                                       
255!     A sample program is given in the "Examples" section.             
256!                                                                       
257!     Refer to the argument descriptions for the definitions of the     
258!     quantities that appear in the following sample declarations.     
259!                                                                       
260!     For MF = 10,                                                     
261!        PARAMETER  (LRW = 20 + 16*NEQ,           LIW = 20)             
262!     For MF = 21 or 22,                                               
263!        PARAMETER  (LRW = 22 +  9*NEQ + NEQ**2,  LIW = 20 + NEQ)       
264!     For MF = 24 or 25,                                               
265!        PARAMETER  (LRW = 22 + 10*NEQ + (2*ML+MU)*NEQ,                 
266!       *                                         LIW = 20 + NEQ)       
267!                                                                       
268!        EXTERNAL F, JAC                                               
269!        INTEGER  NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK(LIW),     
270!       *         LIW, MF                                               
271!        KPP_REAL Y(NEQ), T, TOUT, RelTol, AbsTol(ntol), RWORK(LRW)
272!                                                                       
273!        CALL DLSODE (F, NEQ, Y, T, TOUT, ITOL, RelTol, AbsTol, ITASK,     
274!       *            ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, MF)     
275!                                                                       
276! *Arguments:                                                           
277!     F     :EXT    Name of subroutine for right-hand-side vector f.   
278!                   This name must be declared EXTERNAL in calling     
279!                   program.  The form of F must be:                   
280!                                                                       
281!                   SUBROUTINE  F (NEQ, T, Y, YDOT)                     
282!                   INTEGER  NEQ                                       
283!                   KPP_REAL  T, Y(*), YDOT(*)                 
284!                                                                       
285!                   The inputs are NEQ, T, Y.  F is to set             
286!                                                                       
287!                   YDOT(i) = f(i,T,Y(1),Y(2),...,Y(NEQ)),             
288!                                                     i = 1, ..., NEQ .
289!                                                                       
290!     NEQ   :IN     Number of first-order ODE's.                       
291!                                                                       
292!     Y     :INOUT  Array of values of the y(t) vector, of length NEQ. 
293!                   Input:  For the first call, Y should contain the   
294!                           values of y(t) at t = T. (Y is an input     
295!                           variable only if ISTATE = 1.)               
296!                   Output: On return, Y will contain the values at the
297!                           new t-value.                               
298!                                                                       
299!     T     :INOUT  Value of the independent variable.  On return it   
300!                   will be the current value of t (normally TOUT).     
301!                                                                       
302!     TOUT  :IN     Next point where output is desired (.NE. T).       
303!                                                                       
304!     ITOL  :IN     1 or 2 according as AbsTol (below) is a scalar or     
305!                   an array.                                           
306!                                                                       
307!     RelTol  :IN     Relative tolerance parameter (scalar).             
308!                                                                       
309!     AbsTol  :IN     Absolute tolerance parameter (scalar or array).     
310!                   If ITOL = 1, AbsTol need not be dimensioned.         
311!                   If ITOL = 2, AbsTol must be dimensioned at least NEQ.
312!                                                                       
313!                   The estimated local error in Y(i) will be controlled
314!                   so as to be roughly less (in magnitude) than       
315!                                                                       
316!                   EWT(i) = RelTol*ABS(Y(i)) + AbsTol     if ITOL = 1, or 
317!                   EWT(i) = RelTol*ABS(Y(i)) + AbsTol(i)  if ITOL = 2.     
318!                                                                       
319!                   Thus the local error test passes if, in each       
320!                   component, either the absolute error is less than   
321!                   AbsTol (or AbsTol(i)), or the relative error is less   
322!                   than RelTol.                                         
323!                                                                       
324!                   Use RelTol = 0.0 for pure absolute error control, and
325!                   use AbsTol = 0.0 (or AbsTol(i) = 0.0) for pure relative
326!                   error control.  Caution:  Actual (global) errors may
327!                   exceed these local tolerances, so choose them       
328!                   conservatively.                                     
329!                                                                       
330!     ITASK :IN     Flag indicating the task DLSODE is to perform.     
331!                   Use ITASK = 1 for normal computation of output     
332!                   values of y at t = TOUT.                           
333!                                                                       
334!     ISTATE:INOUT  Index used for input and output to specify the state
335!                   of the calculation.                                 
336!                   Input:                                             
337!                    1   This is the first call for a problem.         
338!                    2   This is a subsequent call.                     
339!                   Output:                                             
340!                    1   Nothing was done, because TOUT was equal to T.
341!                    2   DLSODE was successful (otherwise, negative).   
342!                        Note that ISTATE need not be modified after a 
343!                        successful return.                             
344!                   -1   Excess work done on this call (perhaps wrong   
345!                        MF).                                           
346!                   -2   Excess accuracy requested (tolerances too     
347!                        small).                                       
348!                   -3   Illegal input detected (see printed message). 
349!                   -4   Repeated error test failures (check all       
350!                        inputs).                                       
351!                   -5   Repeated convergence failures (perhaps bad     
352!                        Jacobian supplied or wrong choice of MF or     
353!                        tolerances).                                   
354!                   -6   Error weight became zero during problem       
355!                        (solution component i vanished, and AbsTol or   
356!                        AbsTol(i) = 0.).                                 
357!                                                                       
358!     IOPT  :IN     Flag indicating whether optional inputs are used:   
359!                   0   No.                                             
360!                   1   Yes.  (See "Optional inputs" under "Long       
361!                       Description," Part 1.)                         
362!                                                                       
363!     RWORK :WORK   Real work array of length at least:                 
364!                   20 + 16*NEQ                    for MF = 10,         
365!                   22 +  9*NEQ + NEQ**2           for MF = 21 or 22,   
366!                   22 + 10*NEQ + (2*ML + MU)*NEQ  for MF = 24 or 25.   
367!                                                                       
368!     LRW   :IN     Declared length of RWORK (in user's DIMENSION       
369!                   statement).                                         
370!                                                                       
371!     IWORK :WORK   Integer work array of length at least:             
372!                   20        for MF = 10,                             
373!                   20 + NEQ  for MF = 21, 22, 24, or 25.               
374!                                                                       
375!                   If MF = 24 or 25, input in IWORK(1),IWORK(2) the   
376!                   lower and upper Jacobian half-bandwidths ML,MU.     
377!                                                                       
378!                   On return, IWORK contains information that may be   
379!                   of interest to the user:                           
380!                                                                       
381!            Name   Location   Meaning                                 
382!            -----  ---------  -----------------------------------------
383!            NST    IWORK(11)  Number of steps taken for the problem so
384!                              far.                                     
385!            NFE    IWORK(12)  Number of f evaluations for the problem 
386!                              so far.                                 
387!            NJE    IWORK(13)  Number of Jacobian evaluations (and of   
388!                              matrix LU decompositions) for the problem
389!                              so far.                                 
390!            NQU    IWORK(14)  Method order last used (successfully).   
391!            LENRW  IWORK(17)  Length of RWORK actually required.  This
392!                              is defined on normal returns and on an   
393!                              illegal input return for insufficient   
394!                              storage.                                 
395!            LENIW  IWORK(18)  Length of IWORK actually required.  This
396!                              is defined on normal returns and on an   
397!                              illegal input return for insufficient   
398!                              storage.                                 
399!                                                                       
400!     LIW   :IN     Declared length of IWORK (in user's DIMENSION       
401!                   statement).                                         
402!                                                                       
403!     JAC   :EXT    Name of subroutine for Jacobian matrix (MF =       
404!                   21 or 24).  If used, this name must be declared     
405!                   EXTERNAL in calling program.  If not used, pass a   
406!                   dummy name.  The form of JAC must be:               
407!                                                                       
408!                   SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)     
409!                   INTEGER  NEQ, ML, MU, NROWPD                       
410!                   KPP_REAL  T, Y(*), PD(NROWPD,*)             
411!                                                                       
412!                   See item c, under "Description" below for more     
413!                   information about JAC.                             
414!                                                                       
415!     MF    :IN     Method flag.  Standard values are:                 
416!                   10  Nonstiff (Adams) method, no Jacobian used.     
417!                   21  Stiff (BDF) method, user-supplied full Jacobian.
418!                   22  Stiff method, internally generated full         
419!                       Jacobian.                                       
420!                   24  Stiff method, user-supplied banded Jacobian.   
421!                   25  Stiff method, internally generated banded       
422!                       Jacobian.                                       
423!                                                                       
424! *Description:                                                         
425!     DLSODE solves the initial value problem for stiff or nonstiff     
426!     systems of first-order ODE's,                                     
427!                                                                       
428!        dy/dt = f(t,y) ,                                               
429!                                                                       
430!     or, in component form,                                           
431!                                                                       
432!        dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(NEQ))                 
433!                                                  (i = 1, ..., NEQ) . 
434!                                                                       
435!     DLSODE is a package based on the GEAR and GEARB packages, and on 
436!     the October 23, 1978, version of the tentative ODEPACK user       
437!     interface standard, with minor modifications.                     
438!                                                                       
439!     The steps in solving such a problem are as follows.               
440!                                                                       
441!     a. First write a subroutine of the form                           
442!                                                                       
443!           SUBROUTINE  F (NEQ, T, Y, YDOT)                             
444!           INTEGER  NEQ                                               
445!           KPP_REAL  T, Y(*), YDOT(*)                         
446!                                                                       
447!        which supplies the vector function f by loading YDOT(i) with   
448!        f(i).                                                         
449!                                                                       
450!     b. Next determine (or guess) whether or not the problem is stiff.
451!        Stiffness occurs when the Jacobian matrix df/dy has an         
452!        eigenvalue whose real part is negative and large in magnitude 
453!        compared to the reciprocal of the t span of interest.  If the 
454!        problem is nonstiff, use method flag MF = 10.  If it is stiff,
455!        there are four standard choices for MF, and DLSODE requires the
456!        Jacobian matrix in some form.  This matrix is regarded either 
457!        as full (MF = 21 or 22), or banded (MF = 24 or 25).  In the   
458!        banded case, DLSODE requires two half-bandwidth parameters ML 
459!        and MU. These are, respectively, the widths of the lower and   
460!        upper parts of the band, excluding the main diagonal.  Thus the
461!        band consists of the locations (i,j) with                     
462!                                                                       
463!           i - ML <= j <= i + MU ,                                     
464!                                                                       
465!        and the full bandwidth is ML + MU + 1 .                       
466!                                                                       
467!     c. If the problem is stiff, you are encouraged to supply the     
468!        Jacobian directly (MF = 21 or 24), but if this is not feasible,
469!        DLSODE will compute it internally by difference quotients (MF =
470!        22 or 25).  If you are supplying the Jacobian, write a         
471!        subroutine of the form                                         
472!                                                                       
473!           SUBROUTINE  JAC (NEQ, T, Y, ML, MU, PD, NROWPD)             
474!           INTEGER  NEQ, ML, MU, NRWOPD                               
475!           KPP_REAL  T, Y(*), PD(NROWPD,*)                     
476!                                                                       
477!        which provides df/dy by loading PD as follows:                 
478!        - For a full Jacobian (MF = 21), load PD(i,j) with df(i)/dy(j),
479!          the partial derivative of f(i) with respect to y(j).  (Ignore
480!          the ML and MU arguments in this case.)                       
481!        - For a banded Jacobian (MF = 24), load PD(i-j+MU+1,j) with   
482!          df(i)/dy(j); i.e., load the diagonal lines of df/dy into the
483!          rows of PD from the top down.                               
484!        - In either case, only nonzero elements need be loaded.       
485!                                                                       
486!     d. Write a main program that calls subroutine DLSODE once for each
487!        point at which answers are desired.  This should also provide 
488!        for possible use of logical unit 6 for output of error messages
489!        by DLSODE.                                                     
490!                                                                       
491!        Before the first call to DLSODE, set ISTATE = 1, set Y and T to
492!        the initial values, and set TOUT to the first output point.  To
493!        continue the integration after a successful return, simply     
494!        reset TOUT and call DLSODE again.  No other parameters need be
495!        reset.                                                         
496!                                                                       
497! *Examples:                                                           
498!     The following is a simple example problem, with the coding needed
499!     for its solution by DLSODE. The problem is from chemical kinetics,
500!     and consists of the following three rate equations:               
501!                                                                       
502!        dy1/dt = -.04*y1 + 1.E4*y2*y3                                 
503!        dy2/dt = .04*y1 - 1.E4*y2*y3 - 3.E7*y2**2                     
504!        dy3/dt = 3.E7*y2**2                                           
505!                                                                       
506!     on the interval from t = 0.0 to t = 4.E10, with initial conditions
507!     y1 = 1.0, y2 = y3 = 0. The problem is stiff.                     
508!                                                                       
509!     The following coding solves this problem with DLSODE, using       
510!     MF = 21 and printing results at t = .4, 4., ..., 4.E10.  It uses 
511!     ITOL = 2 and AbsTol much smaller for y2 than for y1 or y3 because y2
512!     has much smaller values.  At the end of the run, statistical     
513!     quantities of interest are printed.                               
514!                                                                       
515!        EXTERNAL  FEX, JEX                                             
516!        INTEGER  IOPT, IOUT, ISTATE, ITASK, ITOL, IWORK(23), LIW, LRW,
517!       *         MF, NEQ                                               
518!        KPP_REAL  AbsTol(3), RelTol, RWORK(58), T, TOUT, Y(3)     
519!        NEQ = 3                                                       
520!        Y(1) = 1.D0                                                   
521!        Y(2) = 0.D0                                                   
522!        Y(3) = 0.D0                                                   
523!        T = 0.D0                                                       
524!        TOUT = .4D0                                                   
525!        ITOL = 2                                                       
526!        RelTol = 1.D-4                                                   
527!        AbsTol(1) = 1.D-6                                               
528!        AbsTol(2) = 1.D-10                                               
529!        AbsTol(3) = 1.D-6                                               
530!        ITASK = 1                                                     
531!        ISTATE = 1                                                     
532!        IOPT = 0                                                       
533!        LRW = 58                                                       
534!        LIW = 23                                                       
535!        MF = 21                                                       
536!        DO 40 IOUT = 1,12                                             
537!          CALL DLSODE (FEX, NEQ, Y, T, TOUT, ITOL, RelTol, AbsTol, ITASK, 
538!       *               ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JEX, MF) 
539!          WRITE(6,20)  T, Y(1), Y(2), Y(3)                             
540!    20    FORMAT(' At t =',D12.4,'   y =',3D14.6)                     
541!          IF (ISTATE .LT. 0)  GO TO 80                                 
542!    40    TOUT = TOUT*10.D0                                           
543!        WRITE(6,60)  IWORK(11), IWORK(12), IWORK(13)                   
544!    60  FORMAT(/' No. steps =',i4,',  No. f-s =',i4,',  No. J-s =',i4)
545!        STOP                                                           
546!    80  WRITE(6,90)  ISTATE                                           
547!    90  FORMAT(///' Error halt.. ISTATE =',I3)                         
548!        STOP                                                           
549!        END                                                           
550!                                                                       
551!        SUBROUTINE  FEX (NEQ, T, Y, YDOT)                             
552!        INTEGER  NEQ                                                   
553!        KPP_REAL  T, Y(3), YDOT(3)                             
554!        YDOT(1) = -.04D0*Y(1) + 1.D4*Y(2)*Y(3)                         
555!        YDOT(3) = 3.D7*Y(2)*Y(2)                                       
556!        YDOT(2) = -YDOT(1) - YDOT(3)                                   
557!        RETURN                                                         
558!        END                                                           
559!                                                                       
560!        SUBROUTINE  JEX (NEQ, T, Y, ML, MU, PD, NRPD)                 
561!        INTEGER  NEQ, ML, MU, NRPD                                     
562!        KPP_REAL  T, Y(3), PD(NRPD,3)                         
563!        PD(1,1) = -.04D0                                               
564!        PD(1,2) = 1.D4*Y(3)                                           
565!        PD(1,3) = 1.D4*Y(2)                                           
566!        PD(2,1) = .04D0                                               
567!        PD(2,3) = -PD(1,3)                                             
568!        PD(3,2) = 6.D7*Y(2)                                           
569!        PD(2,2) = -PD(1,2) - PD(3,2)                                   
570!        RETURN                                                         
571!        END                                                           
572!                                                                       
573!     The output from this program (on a Cray-1 in single precision)   
574!     is as follows.                                                   
575!                                                                       
576!     At t =  4.0000e-01   y =  9.851726e-01  3.386406e-05  1.479357e-02
577!     At t =  4.0000e+00   y =  9.055142e-01  2.240418e-05  9.446344e-02
578!     At t =  4.0000e+01   y =  7.158050e-01  9.184616e-06  2.841858e-01
579!     At t =  4.0000e+02   y =  4.504846e-01  3.222434e-06  5.495122e-01
580!     At t =  4.0000e+03   y =  1.831701e-01  8.940379e-07  8.168290e-01
581!     At t =  4.0000e+04   y =  3.897016e-02  1.621193e-07  9.610297e-01
582!     At t =  4.0000e+05   y =  4.935213e-03  1.983756e-08  9.950648e-01
583!     At t =  4.0000e+06   y =  5.159269e-04  2.064759e-09  9.994841e-01
584!     At t =  4.0000e+07   y =  5.306413e-05  2.122677e-10  9.999469e-01
585!     At t =  4.0000e+08   y =  5.494530e-06  2.197825e-11  9.999945e-01
586!     At t =  4.0000e+09   y =  5.129458e-07  2.051784e-12  9.999995e-01
587!     At t =  4.0000e+10   y = -7.170603e-08 -2.868241e-13  1.000000e+00
588!                                                                       
589!     No. steps = 330,  No. f-s = 405,  No. J-s = 69                   
590!                                                                       
591! *Accuracy:                                                           
592!     The accuracy of the solution depends on the choice of tolerances 
593!     RelTol and AbsTol.  Actual (global) errors may exceed these local     
594!     tolerances, so choose them conservatively.                       
595!                                                                       
596! *Cautions:                                                           
597!     The work arrays should not be altered between calls to DLSODE for
598!     the same problem, except possibly for the conditional and optional
599!     inputs.                                                           
600!                                                                       
601! *Portability:                                                         
602!     Since NEQ is dimensioned inside DLSODE, some compilers may object
603!     to a call to DLSODE with NEQ a scalar variable.  In this event,   
604!     use DIMENSION NEQ.  Similar remarks apply to RelTol and AbsTol.   
605!                                                                       
606!     Note to Cray users:                                               
607!     For maximum efficiency, use the CFT77 compiler.  Appropriate     
608!     compiler optimization directives have been inserted for CFT77.   
609!                                                                       
610! *Reference:                                                           
611!     Alan C. Hindmarsh, "ODEPACK, A Systematized Collection of ODE     
612!     Solvers," in Scientific Computing, R. S. Stepleman, et al., Eds. 
613!     (North-Holland, Amsterdam, 1983), pp. 55-64.                     
614!                                                                       
615! *Long Description:                                                   
616!     The following complete description of the user interface to       
617!     DLSODE consists of four parts:                                   
618!                                                                       
619!     1.  The call sequence to subroutine DLSODE, which is a driver     
620!         routine for the solver.  This includes descriptions of both   
621!         the call sequence arguments and user-supplied routines.       
622!         Following these descriptions is a description of optional     
623!         inputs available through the call sequence, and then a       
624!         description of optional outputs in the work arrays.           
625!                                                                       
626!     2.  Descriptions of other routines in the DLSODE package that may
627!         be (optionally) called by the user.  These provide the ability
628!         to alter error message handling, save and restore the internal
629!         COMMON, and obtain specified derivatives of the solution y(t).
630!                                                                       
631!     3.  Descriptions of COMMON block to be declared in overlay or     
632!         similar environments, or to be saved when doing an interrupt 
633!         of the problem and continued solution later.                 
634!                                                                       
635!     4.  Description of two routines in the DLSODE package, either of 
636!         which the user may replace with his own version, if desired. 
637!         These relate to the measurement of errors.                   
638!                                                                       
639!                                                                       
640!                         Part 1.  Call Sequence                       
641!                         ----------------------                       
642!                                                                       
643!     Arguments                                                         
644!     ---------                                                         
645!     The call sequence parameters used for input only are             
646!                                                                       
647!        F, NEQ, TOUT, ITOL, RelTol, AbsTol, ITASK, IOPT, LRW, LIW, JAC, MF,
648!                                                                       
649!     and those used for both input and output are                     
650!                                                                       
651!        Y, T, ISTATE.                                                 
652!                                                                       
653!     The work arrays RWORK and IWORK are also used for conditional and
654!     optional inputs and optional outputs.  (The term output here     
655!     refers to the return from subroutine DLSODE to the user's calling
656!     program.)                                                         
657!                                                                       
658!     The legality of input parameters will be thoroughly checked on the
659!     initial call for the problem, but not checked thereafter unless a
660!     change in input parameters is flagged by ISTATE = 3 on input.     
661!                                                                       
662!     The descriptions of the call arguments are as follows.           
663!                                                                       
664!     F        The name of the user-supplied subroutine defining the ODE
665!              system.  The system must be put in the first-order form 
666!              dy/dt = f(t,y), where f is a vector-valued function of   
667!              the scalar t and the vector y. Subroutine F is to compute
668!              the function f. It is to have the form                   
669!                                                                       
670!                 SUBROUTINE F (NEQ, T, Y, YDOT)                       
671!                 KPP_REAL  T, Y(*), YDOT(*)                   
672!                                                                       
673!              where NEQ, T, and Y are input, and the array YDOT =     
674!              f(T,Y) is output.  Y and YDOT are arrays of length NEQ. 
675!              Subroutine F should not alter Y(1),...,Y(NEQ).  F must be
676!              declared EXTERNAL in the calling program.               
677!                                                                       
678!              Subroutine F may access user-defined quantities in       
679!              NEQ(2),... and/or in Y(NEQ+1),..., if NEQ is an array
680!              (dimensioned in F) and/or Y has length exceeding NEQ.
681!              See the descriptions of NEQ and Y below.                 
682!                                                                       
683!              If quantities computed in the F routine are needed       
684!              externally to DLSODE, an extra call to F should be made 
685!              for this purpose, for consistent and accurate results.   
686!              If only the derivative dy/dt is needed, use DINTDY       
687!              instead.                                                 
688!                                                                       
689!     NEQ      The size of the ODE system (number of first-order       
690!              ordinary differential equations).  Used only for input. 
691!              NEQ may be decreased, but not increased, during the     
692!              problem.  If NEQ is decreased (with ISTATE = 3 on input),
693!              the remaining components of Y should be left undisturbed,
694!              if these are to be accessed in F and/or JAC.             
695!                                                                       
696!              Normally, NEQ is a scalar, and it is generally referred 
697!              to as a scalar in this user interface description.       
698!              However, NEQ may be an array, with NEQ set to the     
699!              system size.  (The DLSODE package accesses only NEQ.)
700!              In either case, this parameter is passed as the NEQ     
701!              argument in all calls to F and JAC.  Hence, if it is an 
702!              array, locations NEQ(2),... may be used to store other   
703!              integer data and pass it to F and/or JAC.  Subroutines   
704!              F and/or JAC must include NEQ in a DIMENSION statement   
705!              in that case.                                           
706!                                                                       
707!     Y        A real array for the vector of dependent variables, of   
708!              length NEQ or more.  Used for both input and output on   
709!              the first call (ISTATE = 1), and only for output on     
710!              other calls.  On the first call, Y must contain the     
711!              vector of initial values.  On output, Y contains the     
712!              computed solution vector, evaluated at T. If desired,   
713!              the Y array may be used for other purposes between       
714!              calls to the solver.                                     
715!                                                                       
716!              This array is passed as the Y argument in all calls to F
717!              and JAC.  Hence its length may exceed NEQ, and locations
718!              Y(NEQ+1),... may be used to store other real data and   
719!              pass it to F and/or JAC.  (The DLSODE package accesses   
720!              only Y(1),...,Y(NEQ).)                                   
721!                                                                       
722!     T        The independent variable.  On input, T is used only on   
723!              the first call, as the initial point of the integration.
724!              On output, after each call, T is the value at which a   
725!              computed solution Y is evaluated (usually the same as   
726!              TOUT).  On an error return, T is the farthest point     
727!              reached.                                                 
728!                                                                       
729!     TOUT     The next value of T at which a computed solution is     
730!              desired.  Used only for input.                           
731!                                                                       
732!              When starting the problem (ISTATE = 1), TOUT may be equal
733!              to T for one call, then should not equal T for the next 
734!              call.  For the initial T, an input value of TOUT .NE. T 
735!              is used in order to determine the direction of the       
736!              integration (i.e., the algebraic sign of the step sizes)
737!              and the rough scale of the problem.  Integration in     
738!              either direction (forward or backward in T) is permitted.
739!                                                                       
740!              If ITASK = 2 or 5 (one-step modes), TOUT is ignored     
741!              after the first call (i.e., the first call with         
742!              TOUT .NE. T).  Otherwise, TOUT is required on every call.
743!                                                                       
744!              If ITASK = 1, 3, or 4, the values of TOUT need not be   
745!              monotone, but a value of TOUT which backs up is limited 
746!              to the current internal T interval, whose endpoints are 
747!              TCUR - HU and TCUR.  (See "Optional Outputs" below for   
748!              TCUR and HU.)                                           
749!                                                                       
750!                                                                       
751!     ITOL     An indicator for the type of error control.  See         
752!              description below under AbsTol.  Used only for input.     
753!                                                                       
754!     RelTol     A relative error tolerance parameter, either a scalar or
755!              an array of length NEQ.  See description below under     
756!              AbsTol.  Input only.                                       
757!                                                                       
758!     AbsTol     An absolute error tolerance parameter, either a scalar or
759!              an array of length NEQ.  Input only.                     
760!                                                                       
761!              The input parameters ITOL, RelTol, and AbsTol determine the 
762!              error control performed by the solver.  The solver will 
763!              control the vector e = (e(i)) of estimated local errors 
764!              in Y, according to an inequality of the form             
765!                                                                       
766!                 rms-norm of ( e(i)/EWT(i) ) <= 1,                     
767!                                                                       
768!              where                                                   
769!                                                                       
770!                 EWT(i) = RelTol(i)*ABS(Y(i)) + AbsTol(i),                 
771!                                                                       
772!              and the rms-norm (root-mean-square norm) here is         
773!                                                                       
774!                 rms-norm(v) = SQRT(sum v(i)**2 / NEQ).               
775!                                                                       
776!              Here EWT = (EWT(i)) is a vector of weights which must   
777!              always be positive, and the values of RelTol and AbsTol     
778!              should all be nonnegative.  The following table gives the
779!              types (scalar/array) of RelTol and AbsTol, and the           
780!              corresponding form of EWT(i).                           
781!                                                                       
782!              ITOL    RelTol      AbsTol      EWT(i)                       
783!              ----    ------    ------    -----------------------------
784!              1       scalar    scalar    RelTol*ABS(Y(i)) + AbsTol       
785!              2       scalar    array     RelTol*ABS(Y(i)) + AbsTol(i)     
786!              3       array     scalar    RelTol(i)*ABS(Y(i)) + AbsTol     
787!              4       array     array     RelTol(i)*ABS(Y(i)) + AbsTol(i) 
788!                                                                       
789!              When either of these parameters is a scalar, it need not
790!              be dimensioned in the user's calling program.           
791!                                                                       
792!              If none of the above choices (with ITOL, RelTol, and AbsTol 
793!              fixed throughout the problem) is suitable, more general 
794!              error controls can be obtained by substituting           
795!              user-supplied routines for the setting of EWT and/or for
796!              the norm calculation.  See Part 4 below.                 
797!                                                                       
798!              If global errors are to be estimated by making a repeated
799!              run on the same problem with smaller tolerances, then all
800!              components of RelTol and AbsTol (i.e., of EWT) should be     
801!              scaled down uniformly.                                   
802!                                                                       
803!     ITASK    An index specifying the task to be performed.  Input     
804!              only.  ITASK has the following values and meanings:     
805!              1   Normal computation of output values of y(t) at       
806!                  t = TOUT (by overshooting and interpolating).       
807!              2   Take one step only and return.                       
808!              3   Stop at the first internal mesh point at or beyond   
809!                  t = TOUT and return.                                 
810!              4   Normal computation of output values of y(t) at       
811!                  t = TOUT but without overshooting t = TCRIT.  TCRIT 
812!                  must be input as RWORK(1).  TCRIT may be equal to or
813!                  beyond TOUT, but not behind it in the direction of   
814!                  integration.  This option is useful if the problem   
815!                  has a singularity at or beyond t = TCRIT.           
816!              5   Take one step, without passing TCRIT, and return.   
817!                  TCRIT must be input as RWORK(1).                     
818!                                                                       
819!              Note:  If ITASK = 4 or 5 and the solver reaches TCRIT   
820!              (within roundoff), it will return T = TCRIT (exactly) to
821!              indicate this (unless ITASK = 4 and TOUT comes before   
822!              TCRIT, in which case answers at T = TOUT are returned   
823!              first).                                                 
824!                                                                       
825!     ISTATE   An index used for input and output to specify the state 
826!              of the calculation.                                     
827!                                                                       
828!              On input, the values of ISTATE are as follows:           
829!              1   This is the first call for the problem               
830!                  (initializations will be done).  See "Note" below.   
831!              2   This is not the first call, and the calculation is to
832!                  continue normally, with no change in any input       
833!                  parameters except possibly TOUT and ITASK.  (If ITOL,
834!                  RelTol, and/or AbsTol are changed between calls with     
835!                  ISTATE = 2, the new values will be used but not     
836!                  tested for legality.)                               
837!              3   This is not the first call, and the calculation is to
838!                  continue normally, but with a change in input       
839!                  parameters other than TOUT and ITASK.  Changes are   
840!                  allowed in NEQ, ITOL, RelTol, AbsTol, IOPT, LRW, LIW, MF,
841!                  ML, MU, and any of the optional inputs except H0.   
842!                  (See IWORK description for ML and MU.)               
843!                                                                       
844!              Note:  A preliminary call with TOUT = T is not counted as
845!              a first call here, as no initialization or checking of   
846!              input is done.  (Such a call is sometimes useful for the
847!              purpose of outputting the initial conditions.)  Thus the
848!              first call for which TOUT .NE. T requires ISTATE = 1 on 
849!              input.                                                   
850!                                                                       
851!              On output, ISTATE has the following values and meanings:
852!               1  Nothing was done, as TOUT was equal to T with       
853!                  ISTATE = 1 on input.                                 
854!               2  The integration was performed successfully.         
855!              -1  An excessive amount of work (more than MXSTEP steps)
856!                  was done on this call, before completing the         
857!                  requested task, but the integration was otherwise   
858!                  successful as far as T. (MXSTEP is an optional input
859!                  and is normally 500.)  To continue, the user may     
860!                  simply reset ISTATE to a value >1 and call again (the
861!                  excess work step counter will be reset to 0).  In   
862!                  addition, the user may increase MXSTEP to avoid this
863!                  error return; see "Optional Inputs" below.           
864!              -2  Too much accuracy was requested for the precision of
865!                  the machine being used.  This was detected before   
866!                  completing the requested task, but the integration   
867!                  was successful as far as T. To continue, the         
868!                  tolerance parameters must be reset, and ISTATE must 
869!                  be set to 3. The optional output TOLSF may be used   
870!                  for this purpose.  (Note:  If this condition is     
871!                  detected before taking any steps, then an illegal   
872!                  input return (ISTATE = -3) occurs instead.)         
873!              -3  Illegal input was detected, before taking any       
874!                  integration steps.  See written message for details.
875!                  (Note:  If the solver detects an infinite loop of   
876!                  calls to the solver with illegal input, it will cause
877!                  the run to stop.)                                   
878!              -4  There were repeated error-test failures on one       
879!                  attempted step, before completing the requested task,
880!                  but the integration was successful as far as T.  The
881!                  problem may have a singularity, or the input may be 
882!                  inappropriate.                                       
883!              -5  There were repeated convergence-test failures on one
884!                  attempted step, before completing the requested task,
885!                  but the integration was successful as far as T. This
886!                  may be caused by an inaccurate Jacobian matrix, if   
887!                  one is being used.                                   
888!              -6  EWT(i) became zero for some i during the integration.
889!                  Pure relative error control (AbsTol(i)=0.0) was       
890!                  requested on a variable which has now vanished.  The
891!                  integration was successful as far as T.             
892!                                                                       
893!              Note:  Since the normal output value of ISTATE is 2, it 
894!              does not need to be reset for normal continuation.  Also,
895!              since a negative input value of ISTATE will be regarded 
896!              as illegal, a negative output value requires the user to
897!              change it, and possibly other inputs, before calling the
898!              solver again.                                           
899!                                                                       
900!     IOPT     An integer flag to specify whether any optional inputs   
901!              are being used on this call.  Input only.  The optional 
902!              inputs are listed under a separate heading below.       
903!              0   No optional inputs are being used.  Default values   
904!                  will be used in all cases.                           
905!              1   One or more optional inputs are being used.         
906!                                                                       
907!     RWORK    A real working array (double precision).  The length of 
908!              RWORK must be at least                                   
909!                                                                       
910!                 20 + NYH*(MAXORD + 1) + 3*NEQ + LWM                   
911!                                                                       
912!              where                                                   
913!                 NYH = the initial value of NEQ,                       
914!              MAXORD = 12 (if METH = 1) or 5 (if METH = 2) (unless a   
915!                       smaller value is given as an optional input),   
916!                 LWM = 0           if MITER = 0,                       
917!                 LWM = NEQ**2 + 2  if MITER = 1 or 2,                 
918!                 LWM = NEQ + 2     if MITER = 3, and                   
919!                 LWM = (2*ML + MU + 1)*NEQ + 2                         
920!                                   if MITER = 4 or 5.                 
921!              (See the MF description below for METH and MITER.)       
922!                                                                       
923!              Thus if MAXORD has its default value and NEQ is constant,
924!              this length is:                                         
925!              20 + 16*NEQ                    for MF = 10,             
926!              22 + 16*NEQ + NEQ**2           for MF = 11 or 12,       
927!              22 + 17*NEQ                    for MF = 13,             
928!              22 + 17*NEQ + (2*ML + MU)*NEQ  for MF = 14 or 15,       
929!              20 +  9*NEQ                    for MF = 20,             
930!              22 +  9*NEQ + NEQ**2           for MF = 21 or 22,       
931!              22 + 10*NEQ                    for MF = 23,             
932!              22 + 10*NEQ + (2*ML + MU)*NEQ  for MF = 24 or 25.       
933!                                                                       
934!              The first 20 words of RWORK are reserved for conditional
935!              and optional inputs and optional outputs.               
936!                                                                       
937!              The following word in RWORK is a conditional input:     
938!              RWORK(1) = TCRIT, the critical value of t which the     
939!                         solver is not to overshoot.  Required if ITASK
940!                         is 4 or 5, and ignored otherwise.  See ITASK.
941!                                                                       
942!     LRW      The length of the array RWORK, as declared by the user. 
943!              (This will be checked by the solver.)                   
944!                                                                       
945!     IWORK    An integer work array.  Its length must be at least     
946!              20       if MITER = 0 or 3 (MF = 10, 13, 20, 23), or     
947!              20 + NEQ otherwise (MF = 11, 12, 14, 15, 21, 22, 24, 25).
948!              (See the MF description below for MITER.)  The first few
949!              words of IWORK are used for conditional and optional     
950!              inputs and optional outputs.                             
951!                                                                       
952!              The following two words in IWORK are conditional inputs:
953!              IWORK(1) = ML   These are the lower and upper half-     
954!              IWORK(2) = MU   bandwidths, respectively, of the banded 
955!                              Jacobian, excluding the main diagonal.   
956!                         The band is defined by the matrix locations   
957!                         (i,j) with i - ML <= j <= i + MU. ML and MU   
958!                         must satisfy 0 <= ML,MU <= NEQ - 1. These are
959!                         required if MITER is 4 or 5, and ignored     
960!                         otherwise.  ML and MU may in fact be the band
961!                         parameters for a matrix to which df/dy is only
962!                         approximately equal.                         
963!                                                                       
964!     LIW      The length of the array IWORK, as declared by the user. 
965!              (This will be checked by the solver.)                   
966!                                                                       
967!     Note:  The work arrays must not be altered between calls to DLSODE
968!     for the same problem, except possibly for the conditional and     
969!     optional inputs, and except for the last 3*NEQ words of RWORK.   
970!     The latter space is used for internal scratch space, and so is   
971!     available for use by the user outside DLSODE between calls, if   
972!     desired (but not for use by F or JAC).                           
973!                                                                       
974!     JAC      The name of the user-supplied routine (MITER = 1 or 4) to
975!              compute the Jacobian matrix, df/dy, as a function of the
976!              scalar t and the vector y.  (See the MF description below
977!              for MITER.)  It is to have the form                     
978!                                                                       
979!                 SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)       
980!                 KPP_REAL T, Y(*), PD(NROWPD,*)               
981!                                                                       
982!              where NEQ, T, Y, ML, MU, and NROWPD are input and the   
983!              array PD is to be loaded with partial derivatives       
984!              (elements of the Jacobian matrix) on output.  PD must be
985!              given a first dimension of NROWPD.  T and Y have the same
986!              meaning as in subroutine F.                             
987!                                                                       
988!              In the full matrix case (MITER = 1), ML and MU are       
989!              ignored, and the Jacobian is to be loaded into PD in     
990!              columnwise manner, with df(i)/dy(j) loaded into PD(i,j).
991!                                                                       
992!              In the band matrix case (MITER = 4), the elements within
993!              the band are to be loaded into PD in columnwise manner, 
994!              with diagonal lines of df/dy loaded into the rows of PD.
995!              Thus df(i)/dy(j) is to be loaded into PD(i-j+MU+1,j).  ML
996!              and MU are the half-bandwidth parameters (see IWORK).   
997!              The locations in PD in the two triangular areas which   
998!              correspond to nonexistent matrix elements can be ignored
999!              or loaded arbitrarily, as they are overwritten by DLSODE.
1000!                                                                       
1001!              JAC need not provide df/dy exactly. A crude approximation
1002!              (possibly with a smaller bandwidth) will do.             
1003!                                                                       
1004!              In either case, PD is preset to zero by the solver, so   
1005!              that only the nonzero elements need be loaded by JAC.   
1006!              Each call to JAC is preceded by a call to F with the same
1007!              arguments NEQ, T, and Y. Thus to gain some efficiency,   
1008!              intermediate quantities shared by both calculations may 
1009!              be saved in a user COMMON block by F and not recomputed 
1010!              by JAC, if desired.  Also, JAC may alter the Y array, if
1011!              desired.  JAC must be declared EXTERNAL in the calling   
1012!              program.                                                 
1013!                                                                       
1014!              Subroutine JAC may access user-defined quantities in     
1015!              NEQ(2),... and/or in Y(NEQ+1),... if NEQ is an array 
1016!              (dimensioned in JAC) and/or Y has length exceeding       
1017!              NEQ.  See the descriptions of NEQ and Y above.       
1018!                                                                       
1019!     MF       The method flag.  Used only for input.  The legal values
1020!              of MF are 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24,   
1021!              and 25.  MF has decimal digits METH and MITER:           
1022!                 MF = 10*METH + MITER .                               
1023!                                                                       
1024!              METH indicates the basic linear multistep method:       
1025!              1   Implicit Adams method.                               
1026!              2   Method based on backward differentiation formulas   
1027!                  (BDF's).                                             
1028!                                                                       
1029!              MITER indicates the corrector iteration method:         
1030!              0   Functional iteration (no Jacobian matrix is         
1031!                  involved).                                           
1032!              1   Chord iteration with a user-supplied full (NEQ by   
1033!                  NEQ) Jacobian.                                       
1034!              2   Chord iteration with an internally generated         
1035!                  (difference quotient) full Jacobian (using NEQ       
1036!                  extra calls to F per df/dy value).                   
1037!              3   Chord iteration with an internally generated         
1038!                  diagonal Jacobian approximation (using one extra call
1039!                  to F per df/dy evaluation).                         
1040!              4   Chord iteration with a user-supplied banded Jacobian.
1041!              5   Chord iteration with an internally generated banded 
1042!                  Jacobian (using ML + MU + 1 extra calls to F per     
1043!                  df/dy evaluation).                                   
1044!                                                                       
1045!              If MITER = 1 or 4, the user must supply a subroutine JAC
1046!              (the name is arbitrary) as described above under JAC.   
1047!              For other values of MITER, a dummy argument can be used.
1048!                                                                       
1049!     Optional Inputs                                                   
1050!     ---------------                                                   
1051!     The following is a list of the optional inputs provided for in the
1052!     call sequence.  (See also Part 2.)  For each such input variable,
1053!     this table lists its name as used in this documentation, its     
1054!     location in the call sequence, its meaning, and the default value.
1055!     The use of any of these inputs requires IOPT = 1, and in that case
1056!     all of these inputs are examined.  A value of zero for any of     
1057!     these optional inputs will cause the default value to be used.   
1058!     Thus to use a subset of the optional inputs, simply preload       
1059!     locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively,   
1060!     and then set those of interest to nonzero values.                 
1061!                                                                       
1062!     Name    Location   Meaning and default value                     
1063!     ------  ---------  -----------------------------------------------
1064!     H0      RWORK(5)   Step size to be attempted on the first step.   
1065!                        The default value is determined by the solver.
1066!     HMAX    RWORK(6)   Maximum absolute step size allowed.  The       
1067!                        default value is infinite.                     
1068!     HMIN    RWORK(7)   Minimum absolute step size allowed.  The       
1069!                        default value is 0.  (This lower bound is not 
1070!                        enforced on the final step before reaching     
1071!                        TCRIT when ITASK = 4 or 5.)                   
1072!     MAXORD  IWORK(5)   Maximum order to be allowed.  The default value
1073!                        is 12 if METH = 1, and 5 if METH = 2. (See the
1074!                        MF description above for METH.)  If MAXORD     
1075!                        exceeds the default value, it will be reduced 
1076!                        to the default value.  If MAXORD is changed   
1077!                        during the problem, it may cause the current   
1078!                        order to be reduced.                           
1079!     MXSTEP  IWORK(6)   Maximum number of (internally defined) steps   
1080!                        allowed during one call to the solver.  The   
1081!                        default value is 500.                         
1082!     MXHNIL  IWORK(7)   Maximum number of messages printed (per       
1083!                        problem) warning that T + H = T on a step     
1084!                        (H = step size).  This must be positive to     
1085!                        result in a nondefault value.  The default     
1086!                        value is 10.                                   
1087!                                                                       
1088!     Optional Outputs                                                 
1089!     ----------------                                                 
1090!     As optional additional output from DLSODE, the variables listed   
1091!     below are quantities related to the performance of DLSODE which   
1092!     are available to the user.  These are communicated by way of the 
1093!     work arrays, but also have internal mnemonic names as shown.     
1094!     Except where stated otherwise, all of these outputs are defined on
1095!     any successful return from DLSODE, and on any return with ISTATE =
1096!     -1, -2, -4, -5, or -6.  On an illegal input return (ISTATE = -3),
1097!     they will be unchanged from their existing values (if any), except
1098!     possibly for TOLSF, LENRW, and LENIW.  On any error return,       
1099!     outputs relevant to the error will be defined, as noted below.   
1100!                                                                       
1101!     Name   Location   Meaning                                         
1102!     -----  ---------  ------------------------------------------------
1103!     HU     RWORK(11)  Step size in t last used (successfully).       
1104!     HCUR   RWORK(12)  Step size to be attempted on the next step.     
1105!     TCUR   RWORK(13)  Current value of the independent variable which
1106!                       the solver has actually reached, i.e., the     
1107!                       current internal mesh point in t. On output,   
1108!                       TCUR will always be at least as far as the     
1109!                       argument T, but may be farther (if interpolation
1110!                       was done).                                     
1111!     TOLSF  RWORK(14)  Tolerance scale factor, greater than 1.0,       
1112!                       computed when a request for too much accuracy   
1113!                       was detected (ISTATE = -3 if detected at the   
1114!                       start of the problem, ISTATE = -2 otherwise).   
1115!                       If ITOL is left unaltered but RelTol and AbsTol are
1116!                       uniformly scaled up by a factor of TOLSF for the
1117!                       next call, then the solver is deemed likely to 
1118!                       succeed.  (The user may also ignore TOLSF and   
1119!                       alter the tolerance parameters in any other way
1120!                       appropriate.)                                   
1121!     NST    IWORK(11)  Number of steps taken for the problem so far.   
1122!     NFE    IWORK(12)  Number of F evaluations for the problem so far.
1123!     NJE    IWORK(13)  Number of Jacobian evaluations (and of matrix LU
1124!                       decompositions) for the problem so far.         
1125!     NQU    IWORK(14)  Method order last used (successfully).         
1126!     NQCUR  IWORK(15)  Order to be attempted on the next step.         
1127!     IMXER  IWORK(16)  Index of the component of largest magnitude in 
1128!                       the weighted local error vector ( e(i)/EWT(i) ),
1129!                       on an error return with ISTATE = -4 or -5.     
1130!     LENRW  IWORK(17)  Length of RWORK actually required.  This is     
1131!                       defined on normal returns and on an illegal     
1132!                       input return for insufficient storage.         
1133!     LENIW  IWORK(18)  Length of IWORK actually required.  This is     
1134!                       defined on normal returns and on an illegal     
1135!                       input return for insufficient storage.         
1136!                                                                       
1137!     The following two arrays are segments of the RWORK array which may
1138!     also be of interest to the user as optional outputs.  For each   
1139!     array, the table below gives its internal name, its base address 
1140!     in RWORK, and its description.                                   
1141!                                                                       
1142!     Name  Base address  Description                                   
1143!     ----  ------------  ----------------------------------------------
1144!     YH    21            The Nordsieck history array, of size NYH by   
1145!                         (NQCUR + 1), where NYH is the initial value of
1146!                         NEQ.  For j = 0,1,...,NQCUR, column j + 1 of 
1147!                         YH contains HCUR**j/factorial(j) times the jth
1148!                         derivative of the interpolating polynomial   
1149!                         currently representing the solution, evaluated
1150!                         at t = TCUR.                                 
1151!     ACOR  LENRW-NEQ+1   Array of size NEQ used for the accumulated   
1152!                         corrections on each step, scaled on output to
1153!                         represent the estimated local error in Y on   
1154!                         the last step.  This is the vector e in the   
1155!                         description of the error control.  It is     
1156!                         defined only on successful return from DLSODE.
1157!                                                                       
1158!                                                                       
1159!                    Part 2.  Other Callable Routines                   
1160!                    --------------------------------                   
1161!                                                                       
1162!     The following are optional calls which the user may make to gain 
1163!     additional capabilities in conjunction with DLSODE.               
1164!                                                                       
1165!     Form of call              Function                               
1166!     ------------------------  ----------------------------------------
1167!     CALL XSETUN(LUN)          Set the logical unit number, LUN, for   
1168!                               output of messages from DLSODE, if the 
1169!                               default is not desired.  The default   
1170!                               value of LUN is 6. This call may be made
1171!                               at any time and will take effect       
1172!                               immediately.                           
1173!     CALL XSETF(MFLAG)         Set a flag to control the printing of   
1174!                               messages by DLSODE.  MFLAG = 0 means do
1175!                               not print.  (Danger:  this risks losing
1176!                               valuable information.)  MFLAG = 1 means
1177!                               print (the default).  This call may be 
1178!                               made at any time and will take effect   
1179!                               immediately.                           
1180!     CALL DSRCOM(RSAV,ISAV,JOB)  Saves and restores the contents of the
1181!                               internal COMMON blocks used by DLSODE   
1182!                               (see Part 3 below).  RSAV must be a     
1183!                               real array of length 218 or more, and   
1184!                               ISAV must be an integer array of length
1185!                               37 or more.  JOB = 1 means save COMMON 
1186!                               into RSAV/ISAV.  JOB = 2 means restore 
1187!                               COMMON from same.  DSRCOM is useful if 
1188!                               one is interrupting a run and restarting
1189!                               later, or alternating between two or   
1190!                               more problems solved with DLSODE.       
1191!     CALL DINTDY(,,,,,)        Provide derivatives of y, of various   
1192!     (see below)               orders, at a specified point t, if     
1193!                               desired.  It may be called only after a
1194!                               successful return from DLSODE.  Detailed
1195!                               instructions follow.                   
1196!                                                                       
1197!     Detailed instructions for using DINTDY                           
1198!     --------------------------------------                           
1199!     The form of the CALL is:                                         
1200!                                                                       
1201!           CALL DINTDY (T, K, RWORK(21), NYH, DKY, IFLAG)             
1202!                                                                       
1203!     The input parameters are:                                         
1204!                                                                       
1205!     T          Value of independent variable where answers are       
1206!                desired (normally the same as the T last returned by   
1207!                DLSODE).  For valid results, T must lie between       
1208!                TCUR - HU and TCUR.  (See "Optional Outputs" above     
1209!                for TCUR and HU.)                                     
1210!     K          Integer order of the derivative desired.  K must       
1211!                satisfy 0 <= K <= NQCUR, where NQCUR is the current   
1212!                order (see "Optional Outputs").  The capability       
1213!                corresponding to K = 0, i.e., computing y(t), is       
1214!                already provided by DLSODE directly.  Since           
1215!                NQCUR >= 1, the first derivative dy/dt is always       
1216!                available with DINTDY.                                 
1217!     RWORK(21)  The base address of the history array YH.             
1218!     NYH        Column length of YH, equal to the initial value of NEQ.
1219!                                                                       
1220!     The output parameters are:                                       
1221!                                                                       
1222!     DKY        Real array of length NEQ containing the computed value
1223!                of the Kth derivative of y(t).                         
1224!     IFLAG      Integer flag, returned as 0 if K and T were legal,     
1225!                -1 if K was illegal, and -2 if T was illegal.         
1226!                On an error return, a message is also written.         
1227!                                                                       
1228!                                                                       
1229!                          Part 3.  Common Blocks                       
1230!                          ----------------------                       
1231!                                                                       
1232!     If DLSODE is to be used in an overlay situation, the user must   
1233!     declare, in the primary overlay, the variables in:               
1234!     (1) the call sequence to DLSODE,                                 
1235!     (2) the internal COMMON block /DLS001/, of length 255             
1236!         (218 double precision words followed by 37 integer words).   
1237!                                                                       
1238!     If DLSODE is used on a system in which the contents of internal   
1239!     COMMON blocks are not preserved between calls, the user should   
1240!     declare the above COMMON block in his main program to insure that
1241!     its contents are preserved.                                       
1242!                                                                       
1243!     If the solution of a given problem by DLSODE is to be interrupted
1244!     and then later continued, as when restarting an interrupted run or
1245!     alternating between two or more problems, the user should save,   
1246!     following the return from the last DLSODE call prior to the       
1247!     interruption, the contents of the call sequence variables and the
1248!     internal COMMON block, and later restore these values before the 
1249!     next DLSODE call for that problem.   In addition, if XSETUN and/or
1250!     XSETF was called for non-default handling of error messages, then
1251!     these calls must be repeated.  To save and restore the COMMON     
1252!     block, use subroutine DSRCOM (see Part 2 above).                 
1253!                                                                       
1254!                                                                       
1255!              Part 4.  Optionally Replaceable Solver Routines         
1256!              -----------------------------------------------         
1257!                                                                       
1258!     Below are descriptions of two routines in the DLSODE package which
1259!     relate to the measurement of errors.  Either routine can be       
1260!     replaced by a user-supplied version, if desired.  However, since 
1261!     such a replacement may have a major impact on performance, it     
1262!     should be done only when absolutely necessary, and only with great
1263!     caution.  (Note:  The means by which the package version of a     
1264!     routine is superseded by the user's version may be system-       
1265!     dependent.)                                                       
1266!                                                                       
1267!     DEWSET                                                           
1268!     ------                                                           
1269!     The following subroutine is called just before each internal     
1270!     integration step, and sets the array of error weights, EWT, as   
1271!     described under ITOL/RelTol/AbsTol above:                             
1272!                                                                       
1273!           SUBROUTINE DEWSET (NEQ, ITOL, RelTol, AbsTol, YCUR, EWT)       
1274!                                                                       
1275!     where NEQ, ITOL, RelTol, and AbsTol are as in the DLSODE call         
1276!     sequence, YCUR contains the current dependent variable vector,   
1277!     and EWT is the array of weights set by DEWSET.                   
1278!                                                                       
1279!     If the user supplies this subroutine, it must return in EWT(i)   
1280!     (i = 1,...,NEQ) a positive quantity suitable for comparing errors
1281!     in Y(i) to.  The EWT array returned by DEWSET is passed to the   
1282!     DVNORM routine (see below), and also used by DLSODE in the       
1283!     computation of the optional output IMXER, the diagonal Jacobian   
1284!     approximation, and the increments for difference quotient         
1285!     Jacobians.                                                       
1286!                                                                       
1287!     In the user-supplied version of DEWSET, it may be desirable to use
1288!     the current values of derivatives of y. Derivatives up to order NQ
1289!     are available from the history array YH, described above under   
1290!     optional outputs.  In DEWSET, YH is identical to the YCUR array, 
1291!     extended to NQ + 1 columns with a column length of NYH and scale 
1292!     factors of H**j/factorial(j).  On the first call for the problem,
1293!     given by NST = 0, NQ is 1 and H is temporarily set to 1.0.       
1294!     NYH is the initial value of NEQ.  The quantities NQ, H, and NST   
1295!     can be obtained by including in SEWSET the statements:           
1296!           KPP_REAL RLS                                       
1297!           COMMON /DLS001/ RLS(218),ILS(37)                           
1298!           NQ = ILS(33)                                               
1299!           NST = ILS(34)                                               
1300!           H = RLS(212)                                               
1301!     Thus, for example, the current value of dy/dt can be obtained as 
1302!     YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is unnecessary
1303!     when NST = 0).                                                   
1304!                                                                       
1305!     DVNORM                                                           
1306!     ------                                                           
1307!     DVNORM is a real function routine which computes the weighted     
1308!     root-mean-square norm of a vector v:                             
1309!                                                                       
1310!        d = DVNORM (n, v, w)                                           
1311!                                                                       
1312!     where:                                                           
1313!     n = the length of the vector,                                     
1314!     v = real array of length n containing the vector,                 
1315!     w = real array of length n containing weights,                   
1316!     d = SQRT( (1/n) * sum(v(i)*w(i))**2 ).                           
1317!                                                                       
1318!     DVNORM is called with n = NEQ and with w(i) = 1.0/EWT(i), where   
1319!     EWT is as set by subroutine DEWSET.                               
1320!                                                                       
1321!     If the user supplies this function, it should return a nonnegative
1322!     value of DVNORM suitable for use in the error control in DLSODE. 
1323!     None of the arguments should be altered by DVNORM.  For example, a
1324!     user-supplied DVNORM routine might:                               
1325!     - Substitute a max-norm of (v(i)*w(i)) for the rms-norm, or       
1326!     - Ignore some components of v in the norm, with the effect of     
1327!       suppressing the error control on those components of Y.         
1328!  ---------------------------------------------------------------------
1329!***ROUTINES CALLED  DEWSET, DINTDY, DUMACH, DSTODE, DVNORM, XERRWD     
1330!***COMMON BLOCKS    DLS001                                             
1331!***REVISION HISTORY  (YYYYMMDD)                                       
1332! 19791129  DATE WRITTEN                                               
1333! 19791213  Minor changes to declarations; DELP init. in STODE.         
1334! 19800118  Treat NEQ as array; integer declarations added throughout; 
1335!           minor changes to prologue.                                 
1336! 19800306  Corrected TESCO(1,NQP1) setting in CFODE.                   
1337! 19800519  Corrected access of YH on forced order reduction;           
1338!           numerous corrections to prologues and other comments.       
1339! 19800617  In main driver, added loading of SQRT(UROUND) in RWORK;     
1340!           minor corrections to main prologue.                         
1341! 19800923  Added zero initialization of HU and NQU.                   
1342! 19801218  Revised XERRWD routine; minor corrections to main prologue.
1343! 19810401  Minor changes to comments and an error message.             
1344! 19810814  Numerous revisions: replaced EWT by 1/EWT; used flags       
1345!           JCUR, ICF, IERPJ, IERSL between STODE and subordinates;     
1346!           added tuning parameters CCMAX, MAXCOR, MSBP, MXNCF;         
1347!           reorganized returns from STODE; reorganized type decls.;   
1348!           fixed message length in XERRWD; changed default LUNIT to 6;
1349!           changed Common lengths; changed comments throughout.       
1350! 19870330  Major update by ACH: corrected comments throughout;         
1351!           removed TRET from Common; rewrote EWSET with 4 loops;       
1352!           fixed t test in INTDY; added Cray directives in STODE;     
1353!           in STODE, fixed DELP init. and logic around PJAC call;     
1354!           combined routines to save/restore Common;                   
1355!           passed LEVEL = 0 in error message calls (except run abort).
1356! 19890426  Modified prologue to SLATEC/LDOC format.  (FNF)             
1357! 19890501  Many improvements to prologue.  (FNF)                       
1358! 19890503  A few final corrections to prologue.  (FNF)                 
1359! 19890504  Minor cosmetic changes.  (FNF)                             
1360! 19890510  Corrected description of Y in Arguments section.  (FNF)     
1361! 19890517  Minor corrections to prologue.  (FNF)                       
1362! 19920514  Updated with prologue edited 891025 by G. Shaw for manual. 
1363! 19920515  Converted source lines to upper case.  (FNF)               
1364! 19920603  Revised XERRWD calls using mixed upper-lower case.  (ACH)   
1365! 19920616  Revised prologue comment regarding CFT.  (ACH)             
1366! 19921116  Revised prologue comments regarding Common.  (ACH).         
1367! 19930326  Added comment about non-reentrancy.  (FNF)                 
1368! 19930723  Changed D1MACH to DUMACH. (FNF)                             
1369! 19930801  Removed ILLIN and NTREP from Common (affects driver logic);
1370!           minor changes to prologue and internal comments;           
1371!           changed Hollerith strings to quoted strings;               
1372!           changed internal comments to mixed case;                   
1373!           replaced XERRWD with new version using character type;     
1374!           changed dummy dimensions from 1 to *. (ACH)                 
1375! 19930809  Changed to generic intrinsic names; changed names of       
1376!           subprograms and Common blocks to DLSODE etc. (ACH)         
1377! 19930929  Eliminated use of REAL intrinsic; other minor changes. (ACH)
1378! 20010412  Removed all 'own' variables from Common block /DLS001/     
1379!           (affects declarations in 6 routines). (ACH)                 
1380! 20010509  Minor corrections to prologue. (ACH)                       
1381! 20031105  Restored 'own' variables to Common block /DLS001/, to       
1382!           enable interrupt/restart feature. (ACH)                     
1383! 20031112  Added SAVE statements for data-loaded constants.           
1384!                                                                       
1385!***END PROLOGUE  DLSODE                                               
1386!                                                                       
1387!*Internal Notes:                                                       
1388!                                                                       
1389! Other Routines in the DLSODE Package.                                 
1390!                                                                       
1391! In addition to Subroutine DLSODE, the DLSODE package includes the     
1392! following subroutines and function routines:                         
1393!  DINTDY   computes an interpolated value of the y vector at t = TOUT.
1394!  DSTODE   is the core integrator, which does one step of the         
1395!           integration and the associated error control.               
1396!  DCFODE   sets all method coefficients and test constants.           
1397!  DPREPJ   computes and preprocesses the Jacobian matrix J = df/dy     
1398!           and the Newton iteration matrix P = I - h*l0*J.             
1399!  DSOLSY   manages solution of linear system in chord iteration.       
1400!  DEWSET   sets the error weight vector EWT before each step.         
1401!  DVNORM   computes the weighted R.M.S. norm of a vector.             
1402!  DSRCOM   is a user-callable routine to save and restore             
1403!           the contents of the internal Common block.                 
1404!  DGEFA and DGESL   are routines from LINPACK for solving full         
1405!           systems of linear algebraic equations.                     
1406!  DGBFA and DGBSL   are routines from LINPACK for solving banded       
1407!           linear systems.                                             
1408!  DUMACH   computes the unit roundoff in a machine-independent manner.
1409!  XERRWD, XSETUN, XSETF, IXSAV, IUMACH   handle the printing of all   
1410!           error messages and warnings.  XERRWD is machine-dependent. 
1411! Note: DVNORM, DUMACH, IXSAV, and IUMACH are function routines.       
1412! All the others are subroutines.                                       
1413!                                                                       
1414!**End                                                                 
1415!                                                                       
1416!  Declare externals.
1417!  Note: they are now internal                                                   
1418      !EXTERNAL DPREPJ, DSOLSY
1419      !KPP_REAL DUMACH, DVNORM
1420!                                                                       
1421!  Declare all other variables.                                         
1422      INTEGER INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS,          &
1423        ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,                      &
1424        LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,                &
1425        MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU         
1426      INTEGER I, I1, I2, IFLAG, IMXER, KGO, LF0,                        &
1427        LENIW, LENRW, LENWM, ML, MORD(2), MU, MXHNL0, MXSTP0             
1428      KPP_REAL ROWNS,                                           &
1429        CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND                 
1430      KPP_REAL AbsTolI, AYI, BIG, EWTI, H0, HMAX, HMX, RH, RelTolI, &
1431        TCRIT, TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0             
1432
1433      LOGICAL IHIT 
1434      CHARACTER*80 MSG 
1435      SAVE MORD, MXSTP0, MXHNL0 
1436!-----------------------------------------------------------------------
1437! The following internal Common block contains                         
1438! (a) variables which are local to any subroutine but whose values must
1439!     be preserved between calls to the routine ("own" variables), and 
1440! (b) variables which are communicated between subroutines.             
1441! The block DLS001 is declared in subroutines DLSODE, DINTDY, DSTODE,   
1442! DPREPJ, and DSOLSY.                                                   
1443! Groups of variables are replaced by dummy arrays in the Common       
1444! declarations in routines where those variables are not used.         
1445!-----------------------------------------------------------------------
1446      COMMON /DLS001/ ROWNS(209),                                      &
1447        CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,                 &
1448        INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6),            &
1449        ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,                     &
1450        LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,               &
1451        MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU         
1452!                                                                       
1453      DATA  MORD(1),MORD(2)/12,5/, MXSTP0/5000/, MXHNL0/10/ 
1454!-----------------------------------------------------------------------
1455! Block A.                                                             
1456! This code block is executed on every call.                           
1457! It tests ISTATE and ITASK for legality and branches appropriately.   
1458! If ISTATE .GT. 1 but the flag INIT shows that initialization has     
1459! not yet been done, an error return occurs.                           
1460! If ISTATE = 1 and TOUT = T, return immediately.                       
1461!-----------------------------------------------------------------------
1462!                                                                       
1463!***FIRST EXECUTABLE STATEMENT  DLSODE                                 
1464      IF (ISTATE .LT. 1 .OR. ISTATE .GT. 3) GO TO 601 
1465      IF (ITASK .LT. 1 .OR. ITASK .GT. 5) GO TO 602 
1466      IF (ISTATE .EQ. 1) GO TO 10 
1467      IF (INIT .EQ. 0) GO TO 603 
1468      IF (ISTATE .EQ. 2) GO TO 200 
1469      GO TO 20 
1470   10 INIT = 0 
1471      IF (TOUT .EQ. T) RETURN 
1472!-----------------------------------------------------------------------
1473! Block B.                                                             
1474! The next code block is executed for the initial call (ISTATE = 1),   
1475! or for a continuation call with parameter changes (ISTATE = 3).       
1476! It contains checking of all inputs and various initializations.       
1477!                                                                       
1478! First check legality of the non-optional inputs NEQ, ITOL, IOPT,     
1479! MF, ML, and MU.                                                       
1480!-----------------------------------------------------------------------
1481   20 IF (NEQ .LE. 0) GO TO 604 
1482      IF (ISTATE .EQ. 1) GO TO 25 
1483      IF (NEQ .GT. N) GO TO 605 
1484   25 N = NEQ 
1485      IF (ITOL .LT. 1 .OR. ITOL .GT. 4) GO TO 606 
1486      IF (IOPT .LT. 0 .OR. IOPT .GT. 1) GO TO 607 
1487      METH = MF/10 
1488      MITER = MF - 10*METH 
1489      IF (METH .LT. 1 .OR. METH .GT. 2) GO TO 608 
1490      IF (MITER .LT. 0 .OR. MITER .GT. 5) GO TO 608 
1491      IF (MITER .LE. 3) GO TO 30 
1492      ML = IWORK(1) 
1493      MU = IWORK(2) 
1494      IF (ML .LT. 0 .OR. ML .GE. N) GO TO 609 
1495      IF (MU .LT. 0 .OR. MU .GE. N) GO TO 610 
1496   30 CONTINUE 
1497! Next process and check the optional inputs. --------------------------
1498      IF (IOPT .EQ. 1) GO TO 40 
1499      MAXORD = MORD(METH) 
1500      MXSTEP = MXSTP0 
1501      MXHNIL = MXHNL0 
1502      IF (ISTATE .EQ. 1) H0 = 0.0D0 
1503      HMXI = 0.0D0 
1504      HMIN = 0.0D0 
1505      GO TO 60 
1506   40 MAXORD = IWORK(5) 
1507      IF (MAXORD .LT. 0) GO TO 611 
1508      IF (MAXORD .EQ. 0) MAXORD = 100 
1509      MAXORD = MIN(MAXORD,MORD(METH)) 
1510      MXSTEP = IWORK(6) 
1511      IF (MXSTEP .LT. 0) GO TO 612 
1512      IF (MXSTEP .EQ. 0) MXSTEP = MXSTP0 
1513      MXHNIL = IWORK(7) 
1514      IF (MXHNIL .LT. 0) GO TO 613 
1515      IF (MXHNIL .EQ. 0) MXHNIL = MXHNL0 
1516      IF (ISTATE .NE. 1) GO TO 50 
1517      H0 = RWORK(5) 
1518      IF ((TOUT - T)*H0 .LT. 0.0D0) GO TO 614 
1519   50 HMAX = RWORK(6) 
1520      IF (HMAX .LT. 0.0D0) GO TO 615 
1521      HMXI = 0.0D0 
1522      IF (HMAX .GT. 0.0D0) HMXI = 1.0D0/HMAX 
1523      HMIN = RWORK(7) 
1524      IF (HMIN .LT. 0.0D0) GO TO 616 
1525!-----------------------------------------------------------------------
1526! Set work array pointers and check lengths LRW and LIW.               
1527! Pointers to segments of RWORK and IWORK are named by prefixing L to   
1528! the name of the segment.  E.g., the segment YH starts at RWORK(LYH). 
1529! Segments of RWORK (in order) are denoted  YH, WM, EWT, SAVF, ACOR.   
1530!-----------------------------------------------------------------------
1531   60 LYH = 21 
1532      IF (ISTATE .EQ. 1) NYH = N 
1533      LWM = LYH + (MAXORD + 1)*NYH 
1534      IF (MITER .EQ. 0) LENWM = 0 
1535      IF (MITER .EQ. 1 .OR. MITER .EQ. 2) LENWM = N*N + 2 
1536      IF (MITER .EQ. 3) LENWM = N + 2 
1537      IF (MITER .GE. 4) LENWM = (2*ML + MU + 1)*N + 2 
1538      LEWT = LWM + LENWM 
1539      LSAVF = LEWT + N 
1540      LACOR = LSAVF + N 
1541      LENRW = LACOR + N - 1 
1542      IWORK(17) = LENRW 
1543      LIWM = 1 
1544      LENIW = 20 + N 
1545      IF (MITER .EQ. 0 .OR. MITER .EQ. 3) LENIW = 20 
1546      IWORK(18) = LENIW 
1547      IF (LENRW .GT. LRW) GO TO 617 
1548      IF (LENIW .GT. LIW) GO TO 618 
1549! Check RelTol and AbsTol for legality. ------------------------------------
1550      RelTolI = RelTol(1) 
1551      AbsTolI = AbsTol(1) 
1552      DO 70 I = 1,N 
1553        IF (ITOL .GE. 3) RelTolI = RelTol(I) 
1554        IF (ITOL .EQ. 2 .OR. ITOL .EQ. 4) AbsTolI = AbsTol(I) 
1555        IF (RelTolI .LT. 0.0D0) GO TO 619 
1556        IF (AbsTolI .LT. 0.0D0) GO TO 620 
1557   70   CONTINUE
1558      IF (ISTATE .EQ. 1) GO TO 100 
1559! If ISTATE = 3, set flag to signal parameter changes to DSTODE. -------
1560      JSTART = -1 
1561      IF (NQ .LE. MAXORD) GO TO 90 
1562! MAXORD was reduced below NQ.  Copy YH(*,MAXORD+2) into SAVF. ---------
1563      DO 80 I = 1,N 
1564   80   RWORK(I+LSAVF-1) = RWORK(I+LWM-1) 
1565! Reload WM(1) = RWORK(LWM), since LWM may have changed. ---------------
1566   90 IF (MITER .GT. 0) RWORK(LWM) = SQRT(UROUND) 
1567      IF (N .EQ. NYH) GO TO 200 
1568! NEQ was reduced.  Zero part of YH to avoid undefined references. -----
1569      I1 = LYH + L*NYH 
1570      I2 = LYH + (MAXORD + 1)*NYH - 1 
1571      IF (I1 .GT. I2) GO TO 200 
1572      DO 95 I = I1,I2 
1573   95   RWORK(I) = 0.0D0 
1574      GO TO 200 
1575!-----------------------------------------------------------------------
1576! Block C.                                                             
1577! The next block is for the initial call only (ISTATE = 1).             
1578! It contains all remaining initializations, the initial call to F,     
1579! and the calculation of the initial step size.                         
1580! The error weights in EWT are inverted after being loaded.             
1581!-----------------------------------------------------------------------
1582  100 UROUND = DUMACH() 
1583      TN = T 
1584      IF (ITASK .NE. 4 .AND. ITASK .NE. 5) GO TO 110 
1585      TCRIT = RWORK(1) 
1586      IF ((TCRIT - TOUT)*(TOUT - T) .LT. 0.0D0) GO TO 625 
1587      IF (H0 .NE. 0.0D0 .AND. (T + H0 - TCRIT)*H0 .GT. 0.0D0)           &
1588        H0 = TCRIT - T                                                 
1589  110 JSTART = 0 
1590      IF (MITER .GT. 0) RWORK(LWM) = SQRT(UROUND) 
1591      NHNIL = 0 
1592      NST = 0 
1593      NJE = 0 
1594      NSLAST = 0 
1595      HU = 0.0D0 
1596      NQU = 0 
1597      CCMAX = 0.3D0 
1598      MAXCOR = 3 
1599      MSBP = 20 
1600      MXNCF = 10 
1601! Initial call to F.  (LF0 points to YH(*,2).) -------------------------
1602      LF0 = LYH + NYH 
1603      CALL F (NEQ, T, Y, RWORK(LF0)) 
1604      NFE = 1 
1605! Load the initial value vector in YH. ---------------------------------
1606      DO 115 I = 1,N 
1607  115   RWORK(I+LYH-1) = Y(I) 
1608! Load and invert the EWT array.  (H is temporarily set to 1.0.) -------
1609      NQ = 1 
1610      H = 1.0D0 
1611      CALL DEWSET (N, ITOL, RelTol, AbsTol, RWORK(LYH), RWORK(LEWT)) 
1612      DO 120 I = 1,N 
1613        IF (RWORK(I+LEWT-1) .LE. 0.0D0) GO TO 621 
1614  120   RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1) 
1615!-----------------------------------------------------------------------
1616! The coding below computes the step size, H0, to be attempted on the   
1617! first step, unless the user has supplied a value for this.           
1618! First check that TOUT - T differs significantly from zero.           
1619! A scalar tolerance quantity TOL is computed, as MAX(RelTol(I))         
1620! if this is positive, or MAX(AbsTol(I)/ABS(Y(I))) otherwise, adjusted   
1621! so as to be between 100*UROUND and 1.0E-3.                           
1622! Then the computed value H0 is given by..                             
1623!                                      NEQ                             
1624!   H0**2 = TOL / ( w0**-2 + (1/NEQ) * SUM ( f(i)/ywt(i) )**2  )       
1625!                                       1                               
1626! where   w0     = MAX ( ABS(T), ABS(TOUT) ),                           
1627!         f(i)   = i-th component of initial value of f,               
1628!         ywt(i) = EWT(i)/TOL  (a weight for y(i)).                     
1629! The sign of H0 is inferred from the initial values of TOUT and T.     
1630!-----------------------------------------------------------------------
1631      IF (H0 .NE. 0.0D0) GO TO 180 
1632      TDIST = ABS(TOUT - T) 
1633      W0 = MAX(ABS(T),ABS(TOUT)) 
1634      IF (TDIST .LT. 2.0D0*UROUND*W0) GO TO 622 
1635      TOL = RelTol(1) 
1636      IF (ITOL .LE. 2) GO TO 140 
1637      DO 130 I = 1,N 
1638  130   TOL = MAX(TOL,RelTol(I)) 
1639  140 IF (TOL .GT. 0.0D0) GO TO 160 
1640      AbsTolI = AbsTol(1) 
1641      DO 150 I = 1,N 
1642        IF (ITOL .EQ. 2 .OR. ITOL .EQ. 4) AbsTolI = AbsTol(I) 
1643        AYI = ABS(Y(I)) 
1644        IF (AYI .NE. 0.0D0) TOL = MAX(TOL,AbsTolI/AYI) 
1645  150   CONTINUE
1646  160 TOL = MAX(TOL,100.0D0*UROUND) 
1647      TOL = MIN(TOL,0.001D0) 
1648      SUM = DVNORM (N, RWORK(LF0), RWORK(LEWT)) 
1649      SUM = 1.0D0/(TOL*W0*W0) + TOL*SUM**2 
1650      H0 = 1.0D0/SQRT(SUM) 
1651      H0 = MIN(H0,TDIST) 
1652      H0 = SIGN(H0,TOUT-T) 
1653! Adjust H0 if necessary to meet HMAX bound. ---------------------------
1654  180 RH = ABS(H0)*HMXI 
1655      IF (RH .GT. 1.0D0) H0 = H0/RH 
1656! Load H with H0 and scale YH(*,2) by H0. ------------------------------
1657      H = H0 
1658      DO 190 I = 1,N 
1659  190   RWORK(I+LF0-1) = H0*RWORK(I+LF0-1) 
1660      GO TO 270 
1661!-----------------------------------------------------------------------
1662! Block D.                                                             
1663! The next code block is for continuation calls only (ISTATE = 2 or 3) 
1664! and is to check stop conditions before taking a step.                 
1665!-----------------------------------------------------------------------
1666  200 NSLAST = NST 
1667      GO TO (210, 250, 220, 230, 240), ITASK 
1668  210 IF ((TN - TOUT)*H .LT. 0.0D0) GO TO 250 
1669      CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG) 
1670      IF (IFLAG .NE. 0) GO TO 627 
1671      T = TOUT 
1672      GO TO 420 
1673  220 TP = TN - HU*(1.0D0 + 100.0D0*UROUND) 
1674      IF ((TP - TOUT)*H .GT. 0.0D0) GO TO 623 
1675      IF ((TN - TOUT)*H .LT. 0.0D0) GO TO 250 
1676      GO TO 400 
1677  230 TCRIT = RWORK(1) 
1678      IF ((TN - TCRIT)*H .GT. 0.0D0) GO TO 624 
1679      IF ((TCRIT - TOUT)*H .LT. 0.0D0) GO TO 625 
1680      IF ((TN - TOUT)*H .LT. 0.0D0) GO TO 245 
1681      CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG) 
1682      IF (IFLAG .NE. 0) GO TO 627 
1683      T = TOUT 
1684      GO TO 420 
1685  240 TCRIT = RWORK(1) 
1686      IF ((TN - TCRIT)*H .GT. 0.0D0) GO TO 624 
1687  245 HMX = ABS(TN) + ABS(H) 
1688      IHIT = ABS(TN - TCRIT) .LE. 100.0D0*UROUND*HMX 
1689      IF (IHIT) GO TO 400 
1690      TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND) 
1691      IF ((TNEXT - TCRIT)*H .LE. 0.0D0) GO TO 250 
1692      H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND) 
1693      IF (ISTATE .EQ. 2) JSTART = -2 
1694!-----------------------------------------------------------------------
1695! Block E.                                                             
1696! The next block is normally executed for all calls and contains       
1697! the call to the one-step core integrator DSTODE.                     
1698!                                                                       
1699! This is a looping point for the integration steps.                   
1700!                                                                       
1701! First check for too many steps being taken, update EWT (if not at     
1702! start of problem), check for too much accuracy being requested, and   
1703! check for H below the roundoff level in T.                           
1704!-----------------------------------------------------------------------
1705  250 CONTINUE
1706      IF ((NST-NSLAST) .GE. MXSTEP) GO TO 500 
1707      CALL DEWSET (N, ITOL, RelTol, AbsTol, RWORK(LYH), RWORK(LEWT)) 
1708      DO 260 I = 1,N 
1709        IF (RWORK(I+LEWT-1) .LE. 0.0D0) GO TO 510 
1710  260   RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1) 
1711  270 TOLSF = UROUND*DVNORM (N, RWORK(LYH), RWORK(LEWT)) 
1712      IF (TOLSF .LE. 1.0D0) GO TO 280 
1713      TOLSF = TOLSF*2.0D0 
1714      IF (NST .EQ. 0) GO TO 626 
1715      GO TO 520 
1716  280 IF ((TN + H) .NE. TN) GO TO 290 
1717      NHNIL = NHNIL + 1 
1718      IF (NHNIL .GT. MXHNIL) GO TO 290 
1719      MSG = 'DLSODE-  Warning..internal T (=R1) and H (=R2) are' 
1720      CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) 
1721      MSG='      such that in the machine, T + H = T on the next step  ' 
1722      CALL XERRWD (MSG, 60, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) 
1723      MSG = '      (H = step size). Solver will continue anyway' 
1724      CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 2, TN, H) 
1725      IF (NHNIL .LT. MXHNIL) GO TO 290 
1726      MSG = 'DLSODE-  Above warning has been issued I1 times.  ' 
1727      CALL XERRWD (MSG, 50, 102, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) 
1728      MSG = '      It will not be issued again for this problem' 
1729      CALL XERRWD (MSG, 50, 102, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0) 
1730  290 CONTINUE 
1731!-----------------------------------------------------------------------
1732!  CALL DSTODE(NEQ,Y,YH,NYH,YH,EWT,SAVF,ACOR,WM,IWM,F,JAC,DPREPJ,DSOLSY)
1733!-----------------------------------------------------------------------
1734      CALL DSTODE (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT),   &
1735        RWORK(LSAVF), RWORK(LACOR), RWORK(LWM), IWORK(LIWM),           &
1736        F, JAC)                                       
1737        !F, JAC, DPREPJ, DSOLSY)                                       
1738      KGO = 1 - KFLAG 
1739      GO TO (300, 530, 540), KGO 
1740!-----------------------------------------------------------------------
1741! Block F.                                                             
1742! The following block handles the case of a successful return from the 
1743! core integrator (KFLAG = 0).  Test for stop conditions.               
1744!-----------------------------------------------------------------------
1745  300 INIT = 1 
1746      GO TO (310, 400, 330, 340, 350), ITASK 
1747! ITASK = 1.  If TOUT has been reached, interpolate. -------------------
1748  310 IF ((TN - TOUT)*H .LT. 0.0D0) GO TO 250 
1749      CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG) 
1750      T = TOUT 
1751      GO TO 420 
1752! ITASK = 3.  Jump to exit if TOUT was reached. ------------------------
1753  330 IF ((TN - TOUT)*H .GE. 0.0D0) GO TO 400 
1754      GO TO 250 
1755! ITASK = 4.  See if TOUT or TCRIT was reached.  Adjust H if necessary.
1756  340 IF ((TN - TOUT)*H .LT. 0.0D0) GO TO 345 
1757      CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG) 
1758      T = TOUT 
1759      GO TO 420 
1760  345 HMX = ABS(TN) + ABS(H) 
1761      IHIT = ABS(TN - TCRIT) .LE. 100.0D0*UROUND*HMX 
1762      IF (IHIT) GO TO 400 
1763      TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND) 
1764      IF ((TNEXT - TCRIT)*H .LE. 0.0D0) GO TO 250 
1765      H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND) 
1766      JSTART = -2 
1767      GO TO 250 
1768! ITASK = 5.  See if TCRIT was reached and jump to exit. ---------------
1769  350 HMX = ABS(TN) + ABS(H) 
1770      IHIT = ABS(TN - TCRIT) .LE. 100.0D0*UROUND*HMX 
1771!-----------------------------------------------------------------------
1772! Block G.                                                             
1773! The following block handles all successful returns from DLSODE.       
1774! If ITASK .NE. 1, Y is loaded from YH and T is set accordingly.       
1775! ISTATE is set to 2, and the optional outputs are loaded into the     
1776! work arrays before returning.                                         
1777!-----------------------------------------------------------------------
1778  400 DO 410 I = 1,N 
1779  410   Y(I) = RWORK(I+LYH-1) 
1780      T = TN 
1781      IF (ITASK .NE. 4 .AND. ITASK .NE. 5) GO TO 420 
1782      IF (IHIT) T = TCRIT 
1783  420 ISTATE = 2 
1784      RWORK(11) = HU 
1785      RWORK(12) = H 
1786      RWORK(13) = TN 
1787      IWORK(11) = NST 
1788      IWORK(12) = NFE 
1789      IWORK(13) = NJE 
1790      IWORK(14) = NQU 
1791      IWORK(15) = NQ 
1792      RETURN 
1793!-----------------------------------------------------------------------
1794! Block H.                                                             
1795! The following block handles all unsuccessful returns other than       
1796! those for illegal input.  First the error message routine is called. 
1797! If there was an error test or convergence test failure, IMXER is set.
1798! Then Y is loaded from YH and T is set to TN.  The optional outputs   
1799! are loaded into the work arrays before returning.                     
1800!-----------------------------------------------------------------------
1801! The maximum number of steps was taken before reaching TOUT. ----------
1802  500 MSG = 'DLSODE-  At current T (=R1), MXSTEP (=I1) steps   ' 
1803      CALL XERRWD (MSG, 50, 201, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) 
1804      MSG = '      taken on this call before reaching TOUT     ' 
1805      CALL XERRWD (MSG, 50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0D0) 
1806      ISTATE = -1 
1807      GO TO 580 
1808! EWT(I) .LE. 0.0 for some I (not at start of problem). ----------------
1809  510 EWTI = RWORK(LEWT+I-1) 
1810      MSG = 'DLSODE-  At T (=R1), EWT(I1) has become R2 .LE. 0.' 
1811      CALL XERRWD (MSG, 50, 202, 0, 1, I, 0, 2, TN, EWTI) 
1812      ISTATE = -6 
1813      GO TO 580 
1814! Too much accuracy requested for machine precision. -------------------
1815  520 MSG = 'DLSODE-  At T (=R1), too much accuracy requested  ' 
1816      CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) 
1817      MSG = '      for precision of machine..  see TOLSF (=R2) ' 
1818      CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 2, TN, TOLSF) 
1819      RWORK(14) = TOLSF 
1820      ISTATE = -2 
1821      GO TO 580 
1822! KFLAG = -1.  Error test failed repeatedly or with ABS(H) = HMIN. -----
1823  530 MSG = 'DLSODE-  At T(=R1) and step size H(=R2), the error' 
1824      CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) 
1825      MSG = '      test failed repeatedly or with ABS(H) = HMIN' 
1826      CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 2, TN, H) 
1827      ISTATE = -4 
1828      GO TO 560 
1829! KFLAG = -2.  Convergence failed repeatedly or with ABS(H) = HMIN. ----
1830  540 MSG = 'DLSODE-  At T (=R1) and step size H (=R2), the    ' 
1831      CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) 
1832      MSG = '      corrector convergence failed repeatedly     ' 
1833      CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) 
1834      MSG = '      or with ABS(H) = HMIN   ' 
1835      CALL XERRWD (MSG, 30, 205, 0, 0, 0, 0, 2, TN, H) 
1836      ISTATE = -5 
1837! Compute IMXER if relevant. -------------------------------------------
1838  560 BIG = 0.0D0 
1839      IMXER = 1 
1840      DO 570 I = 1,N 
1841        SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1)) 
1842        IF (BIG .GE. SIZE) GO TO 570 
1843        BIG = SIZE 
1844        IMXER = I 
1845  570   CONTINUE
1846      IWORK(16) = IMXER 
1847! Set Y vector, T, and optional outputs. -------------------------------
1848  580 DO 590 I = 1,N 
1849  590   Y(I) = RWORK(I+LYH-1) 
1850      T = TN 
1851      RWORK(11) = HU 
1852      RWORK(12) = H 
1853      RWORK(13) = TN 
1854      IWORK(11) = NST 
1855      IWORK(12) = NFE 
1856      IWORK(13) = NJE 
1857      IWORK(14) = NQU 
1858      IWORK(15) = NQ 
1859      RETURN 
1860!-----------------------------------------------------------------------
1861! Block I.                                                             
1862! The following block handles all error returns due to illegal input   
1863! (ISTATE = -3), as detected before calling the core integrator.       
1864! First the error message routine is called.  If the illegal input     
1865! is a negative ISTATE, the run is aborted (apparent infinite loop).   
1866!-----------------------------------------------------------------------
1867  601 MSG = 'DLSODE-  ISTATE (=I1) illegal ' 
1868      CALL XERRWD (MSG, 30, 1, 0, 1, ISTATE, 0, 0, 0.0D0, 0.0D0) 
1869      IF (ISTATE .LT. 0) GO TO 800 
1870      GO TO 700 
1871  602 MSG = 'DLSODE-  ITASK (=I1) illegal  ' 
1872      CALL XERRWD (MSG, 30, 2, 0, 1, ITASK, 0, 0, 0.0D0, 0.0D0) 
1873      GO TO 700 
1874  603 MSG = 'DLSODE-  ISTATE .GT. 1 but DLSODE not initialized ' 
1875      CALL XERRWD (MSG, 50, 3, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) 
1876      GO TO 700 
1877  604 MSG = 'DLSODE-  NEQ (=I1) .LT. 1     ' 
1878      CALL XERRWD (MSG, 30, 4, 0, 1, NEQ, 0, 0, 0.0D0, 0.0D0) 
1879      GO TO 700 
1880  605 MSG = 'DLSODE-  ISTATE = 3 and NEQ increased (I1 to I2)  ' 
1881      CALL XERRWD (MSG, 50, 5, 0, 2, N, NEQ, 0, 0.0D0, 0.0D0) 
1882      GO TO 700 
1883  606 MSG = 'DLSODE-  ITOL (=I1) illegal   ' 
1884      CALL XERRWD (MSG, 30, 6, 0, 1, ITOL, 0, 0, 0.0D0, 0.0D0) 
1885      GO TO 700 
1886  607 MSG = 'DLSODE-  IOPT (=I1) illegal   ' 
1887      CALL XERRWD (MSG, 30, 7, 0, 1, IOPT, 0, 0, 0.0D0, 0.0D0) 
1888      GO TO 700 
1889  608 MSG = 'DLSODE-  MF (=I1) illegal     ' 
1890      CALL XERRWD (MSG, 30, 8, 0, 1, MF, 0, 0, 0.0D0, 0.0D0) 
1891      GO TO 700 
1892  609 MSG = 'DLSODE-  ML (=I1) illegal.. .LT.0 or .GE.NEQ (=I2)' 
1893      CALL XERRWD (MSG, 50, 9, 0, 2, ML, NEQ, 0, 0.0D0, 0.0D0) 
1894      GO TO 700 
1895  610 MSG = 'DLSODE-  MU (=I1) illegal.. .LT.0 or .GE.NEQ (=I2)' 
1896      CALL XERRWD (MSG, 50, 10, 0, 2, MU, NEQ, 0, 0.0D0, 0.0D0) 
1897      GO TO 700 
1898  611 MSG = 'DLSODE-  MAXORD (=I1) .LT. 0  ' 
1899      CALL XERRWD (MSG, 30, 11, 0, 1, MAXORD, 0, 0, 0.0D0, 0.0D0) 
1900      GO TO 700 
1901  612 MSG = 'DLSODE-  MXSTEP (=I1) .LT. 0  ' 
1902      CALL XERRWD (MSG, 30, 12, 0, 1, MXSTEP, 0, 0, 0.0D0, 0.0D0) 
1903      GO TO 700 
1904  613 MSG = 'DLSODE-  MXHNIL (=I1) .LT. 0  ' 
1905      CALL XERRWD (MSG, 30, 13, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0) 
1906      GO TO 700 
1907  614 MSG = 'DLSODE-  TOUT (=R1) behind T (=R2)      ' 
1908      CALL XERRWD (MSG, 40, 14, 0, 0, 0, 0, 2, TOUT, T) 
1909      MSG = '      Integration direction is given by H0 (=R1)  ' 
1910      CALL XERRWD (MSG, 50, 14, 0, 0, 0, 0, 1, H0, 0.0D0) 
1911      GO TO 700 
1912  615 MSG = 'DLSODE-  HMAX (=R1) .LT. 0.0  ' 
1913      CALL XERRWD (MSG, 30, 15, 0, 0, 0, 0, 1, HMAX, 0.0D0) 
1914      GO TO 700 
1915  616 MSG = 'DLSODE-  HMIN (=R1) .LT. 0.0  ' 
1916      CALL XERRWD (MSG, 30, 16, 0, 0, 0, 0, 1, HMIN, 0.0D0) 
1917      GO TO 700 
1918  617 CONTINUE
1919      MSG='DLSODE-  RWORK length needed, LENRW (=I1), exceeds LRW (=I2)' 
1920      CALL XERRWD (MSG, 60, 17, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0) 
1921      GO TO 700 
1922  618 CONTINUE
1923      MSG='DLSODE-  IWORK length needed, LENIW (=I1), exceeds LIW (=I2)' 
1924      CALL XERRWD (MSG, 60, 18, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0) 
1925      GO TO 700 
1926  619 MSG = 'DLSODE-  RelTol(I1) is R1 .LT. 0.0        ' 
1927      CALL XERRWD (MSG, 40, 19, 0, 1, I, 0, 1, RelTolI, 0.0D0) 
1928      GO TO 700 
1929  620 MSG = 'DLSODE-  AbsTol(I1) is R1 .LT. 0.0        ' 
1930      CALL XERRWD (MSG, 40, 20, 0, 1, I, 0, 1, AbsTolI, 0.0D0) 
1931      GO TO 700 
1932  621 EWTI = RWORK(LEWT+I-1) 
1933      MSG = 'DLSODE-  EWT(I1) is R1 .LE. 0.0         ' 
1934      CALL XERRWD (MSG, 40, 21, 0, 1, I, 0, 1, EWTI, 0.0D0) 
1935      GO TO 700 
1936  622 CONTINUE
1937      MSG='DLSODE-  TOUT (=R1) too close to T(=R2) to start integration' 
1938      CALL XERRWD (MSG, 60, 22, 0, 0, 0, 0, 2, TOUT, T) 
1939      GO TO 700 
1940  623 CONTINUE
1941      MSG='DLSODE-  ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2)  ' 
1942      CALL XERRWD (MSG, 60, 23, 0, 1, ITASK, 0, 2, TOUT, TP) 
1943      GO TO 700 
1944  624 CONTINUE
1945      MSG='DLSODE-  ITASK = 4 OR 5 and TCRIT (=R1) behind TCUR (=R2)   ' 
1946      CALL XERRWD (MSG, 60, 24, 0, 0, 0, 0, 2, TCRIT, TN) 
1947      GO TO 700 
1948  625 CONTINUE
1949      MSG='DLSODE-  ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2)   ' 
1950      CALL XERRWD (MSG, 60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT) 
1951      GO TO 700 
1952  626 MSG = 'DLSODE-  At start of problem, too much accuracy   ' 
1953      CALL XERRWD (MSG, 50, 26, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) 
1954      MSG='      requested for precision of machine..  See TOLSF (=R1) ' 
1955      CALL XERRWD (MSG, 60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0D0) 
1956      RWORK(14) = TOLSF 
1957      GO TO 700 
1958  627 MSG = 'DLSODE-  Trouble in DINTDY.  ITASK = I1, TOUT = R1' 
1959      CALL XERRWD (MSG, 50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0D0) 
1960!                                                                       
1961  700 ISTATE = -3 
1962      RETURN 
1963!                                                                       
1964  800 MSG = 'DLSODE-  Run aborted.. apparent infinite loop     ' 
1965      CALL XERRWD (MSG, 50, 303, 2, 0, 0, 0, 0, 0.0D0, 0.0D0) 
1966      RETURN 
1967!----------------------- END OF SUBROUTINE DLSODE ----------------------
1968      !END SUBROUTINE DLSODE                                         
1969      CONTAINS                                         
1970
1971
1972!DECK DUMACH   
1973      KPP_REAL FUNCTION DUMACH () 
1974!***BEGIN PROLOGUE  DUMACH                                             
1975!***PURPOSE  Compute the unit roundoff of the machine.                 
1976!***CATEGORY  R1                                                       
1977!***TYPE      KPP_REAL (RUMACH-S, DUMACH-D)                     
1978!***KEYWORDS  MACHINE CONSTANTS                                         
1979!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
1980!***DESCRIPTION                                                         
1981! *Usage:                                                               
1982!        KPP_REAL  A, DUMACH                                   
1983!        A = DUMACH()                                                   
1984!                                                                       
1985! *Function Return Values:                                             
1986!     A : the unit roundoff of the machine.                             
1987!                                                                       
1988! *Description:                                                         
1989!     The unit roundoff is defined as the smallest positive machine     
1990!     number u such that  1.0 + u .ne. 1.0.  This is computed by DUMACH
1991!     in a machine-independent manner.                                 
1992!                                                                       
1993!***REFERENCES  (NONE)                                                 
1994!***ROUTINES CALLED  DUMSUM                                             
1995!***REVISION HISTORY  (YYYYMMDD)                                       
1996!   19930216  DATE WRITTEN                                             
1997!   19930818  Added SLATEC-format prologue.  (FNF)                     
1998!   20030707  Added DUMSUM to force normal storage of COMP.  (ACH)     
1999!***END PROLOGUE  DUMACH                                               
2000!                                                                       
2001      KPP_REAL U, COMP 
2002!***FIRST EXECUTABLE STATEMENT  DUMACH                                 
2003      U = 1.0D0 
2004   10 U = U*0.5D0 
2005      CALL DUMSUM(1.0D0, U, COMP) 
2006      IF (COMP .NE. 1.0D0) GO TO 10 
2007      DUMACH = U*2.0D0 
2008      RETURN 
2009!----------------------- End of Function DUMACH ------------------------
2010      END FUNCTION DUMACH 
2011                                             
2012      SUBROUTINE DUMSUM(A,B,C) 
2013!     Routine to force normal storing of A + B, for DUMACH.             
2014      KPP_REAL A, B, C 
2015      C = A + B 
2016      RETURN
2017      END SUBROUTINE DUMSUM                                       
2018!DECK DCFODE                                                           
2019      SUBROUTINE DCFODE (METH, ELCO, TESCO) 
2020!***BEGIN PROLOGUE  DCFODE                                             
2021!***SUBSIDIARY                                                         
2022!***PURPOSE  Set ODE integrator coefficients.                           
2023!***TYPE      KPP_REAL (SCFODE-S, DCFODE-D)                     
2024!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
2025!***DESCRIPTION                                                         
2026!                                                                       
2027!  DCFODE is called by the integrator routine to set coefficients       
2028!  needed there.  The coefficients for the current method, as           
2029!  given by the value of METH, are set for all orders and saved.       
2030!  The maximum order assumed here is 12 if METH = 1 and 5 if METH = 2. 
2031!  (A smaller value of the maximum order is also allowed.)             
2032!  DCFODE is called once at the beginning of the problem,               
2033!  and is not called again unless and until METH is changed.           
2034!                                                                       
2035!  The ELCO array contains the basic method coefficients.               
2036!  The coefficients el(i), 1 .le. i .le. nq+1, for the method of       
2037!  order nq are stored in ELCO(i,nq).  They are given by a genetrating 
2038!  polynomial, i.e.,                                                   
2039!      l(x) = el(1) + el(2)*x + ... + el(nq+1)*x**nq.                   
2040!  For the implicit Adams methods, l(x) is given by                     
2041!      dl/dx = (x+1)*(x+2)*...*(x+nq-1)/factorial(nq-1),    l(-1) = 0. 
2042!  For the BDF methods, l(x) is given by                               
2043!      l(x) = (x+1)*(x+2)* ... *(x+nq)/K,                               
2044!  where         K = factorial(nq)*(1 + 1/2 + ... + 1/nq).             
2045!                                                                       
2046!  The TESCO array contains test constants used for the                 
2047!  local error test and the selection of step size and/or order.       
2048!  At order nq, TESCO(k,nq) is used for the selection of step           
2049!  size at order nq - 1 if k = 1, at order nq if k = 2, and at order   
2050!  nq + 1 if k = 3.                                                     
2051!                                                                       
2052!***SEE ALSO  DLSODE                                                   
2053!***ROUTINES CALLED  (NONE)                                             
2054!***REVISION HISTORY  (YYMMDD)                                         
2055!   791129  DATE WRITTEN                                               
2056!   890501  Modified prologue to SLATEC/LDOC format.  (FNF)             
2057!   890503  Minor cosmetic changes.  (FNF)                             
2058!   930809  Renamed to allow single/double precision versions. (ACH)   
2059!***END PROLOGUE  DCFODE                                               
2060!**End                                                                 
2061      INTEGER METH 
2062      INTEGER I, IB, NQ, NQM1, NQP1 
2063      KPP_REAL ELCO(13,12), TESCO(3,12), PC(12) 
2064      KPP_REAL AGAMQ, FNQ, FNQM1, PINT, RAGQ, RQFAC, RQ1FAC, TSIGN, XPIN
2065!                                                                       
2066!***FIRST EXECUTABLE STATEMENT  DCFODE                                 
2067      GO TO (100, 200), METH 
2068!                                                                       
2069  100 ELCO(1,1) = 1.0D0 
2070      ELCO(2,1) = 1.0D0 
2071      TESCO(1,1) = 0.0D0 
2072      TESCO(2,1) = 2.0D0 
2073      TESCO(1,2) = 1.0D0 
2074      TESCO(3,12) = 0.0D0 
2075      PC(1) = 1.0D0 
2076      RQFAC = 1.0D0 
2077      DO 140 NQ = 2,12 
2078!-----------------------------------------------------------------------
2079! The PC array will contain the coefficients of the polynomial         
2080!     p(x) = (x+1)*(x+2)*...*(x+nq-1).                                 
2081! Initially, p(x) = 1.                                                 
2082!-----------------------------------------------------------------------
2083        RQ1FAC = RQFAC 
2084        RQFAC = RQFAC/NQ 
2085        NQM1 = NQ - 1 
2086        FNQM1 = NQM1 
2087        NQP1 = NQ + 1 
2088! Form coefficients of p(x)*(x+nq-1). ----------------------------------
2089        PC(NQ) = 0.0D0 
2090        DO 110 IB = 1,NQM1 
2091          I = NQP1 - IB 
2092  110     PC(I) = PC(I-1) + FNQM1*PC(I) 
2093        PC(1) = FNQM1*PC(1) 
2094! Compute integral, -1 to 0, of p(x) and x*p(x). -----------------------
2095        PINT = PC(1) 
2096        XPIN = PC(1)/2.0D0 
2097        TSIGN = 1.0D0 
2098        DO 120 I = 2,NQ 
2099          TSIGN = -TSIGN 
2100          PINT = PINT + TSIGN*PC(I)/I 
2101  120     XPIN = XPIN + TSIGN*PC(I)/(I+1) 
2102! Store coefficients in ELCO and TESCO. --------------------------------
2103        ELCO(1,NQ) = PINT*RQ1FAC 
2104        ELCO(2,NQ) = 1.0D0 
2105        DO 130 I = 2,NQ 
2106  130     ELCO(I+1,NQ) = RQ1FAC*PC(I)/I 
2107        AGAMQ = RQFAC*XPIN 
2108        RAGQ = 1.0D0/AGAMQ 
2109        TESCO(2,NQ) = RAGQ 
2110        IF (NQ .LT. 12) TESCO(1,NQP1) = RAGQ*RQFAC/NQP1 
2111        TESCO(3,NQM1) = RAGQ 
2112  140   CONTINUE
2113      RETURN 
2114!                                                                       
2115  200 PC(1) = 1.0D0 
2116      RQ1FAC = 1.0D0 
2117      DO 230 NQ = 1,5 
2118!-----------------------------------------------------------------------
2119! The PC array will contain the coefficients of the polynomial         
2120!     p(x) = (x+1)*(x+2)*...*(x+nq).                                   
2121! Initially, p(x) = 1.                                                 
2122!-----------------------------------------------------------------------
2123        FNQ = NQ 
2124        NQP1 = NQ + 1 
2125! Form coefficients of p(x)*(x+nq). ------------------------------------
2126        PC(NQP1) = 0.0D0 
2127        DO 210 IB = 1,NQ 
2128          I = NQ + 2 - IB 
2129  210     PC(I) = PC(I-1) + FNQ*PC(I) 
2130        PC(1) = FNQ*PC(1) 
2131! Store coefficients in ELCO and TESCO. --------------------------------
2132        DO 220 I = 1,NQP1 
2133  220     ELCO(I,NQ) = PC(I)/PC(2) 
2134        ELCO(2,NQ) = 1.0D0 
2135        TESCO(1,NQ) = RQ1FAC 
2136        TESCO(2,NQ) = NQP1/ELCO(1,NQ) 
2137        TESCO(3,NQ) = (NQ+2)/ELCO(1,NQ) 
2138        RQ1FAC = RQ1FAC/FNQ 
2139  230   CONTINUE
2140      RETURN 
2141!----------------------- END OF SUBROUTINE DCFODE ----------------------
2142      END SUBROUTINE DCFODE                                         
2143!DECK DINTDY                                                           
2144      SUBROUTINE DINTDY (T, K, YH, NYH, DKY, IFLAG) 
2145!***BEGIN PROLOGUE  DINTDY                                             
2146!***SUBSIDIARY                                                         
2147!***PURPOSE  Interpolate solution derivatives.                         
2148!***TYPE      KPP_REAL (SINTDY-S, DINTDY-D)                     
2149!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
2150!***DESCRIPTION                                                         
2151!                                                                       
2152!  DINTDY computes interpolated values of the K-th derivative of the   
2153!  dependent variable vector y, and stores it in DKY.  This routine     
2154!  is called within the package with K = 0 and T = TOUT, but may       
2155!  also be called by the user for any K up to the current order.       
2156!  (See detailed instructions in the usage documentation.)             
2157!                                                                       
2158!  The computed values in DKY are gotten by interpolation using the     
2159!  Nordsieck history array YH.  This array corresponds uniquely to a   
2160!  vector-valued polynomial of degree NQCUR or less, and DKY is set     
2161!  to the K-th derivative of this polynomial at T.                     
2162!  The formula for DKY is:                                             
2163!               q                                                       
2164!   DKY(i)  =  sum  c(j,K) * (T - tn)**(j-K) * h**(-j) * YH(i,j+1)     
2165!              j=K                                                     
2166!  where  c(j,K) = j*(j-1)*...*(j-K+1), q = NQCUR, tn = TCUR, h = HCUR.
2167!  The quantities  nq = NQCUR, l = nq+1, N = NEQ, tn, and h are         
2168!  communicated by COMMON.  The above sum is done in reverse order.     
2169!  IFLAG is returned negative if either K or T is out of bounds.       
2170!                                                                       
2171!***SEE ALSO  DLSODE                                                   
2172!***ROUTINES CALLED  XERRWD                                             
2173!***COMMON BLOCKS    DLS001                                             
2174!***REVISION HISTORY  (YYMMDD)                                         
2175!   791129  DATE WRITTEN                                               
2176!   890501  Modified prologue to SLATEC/LDOC format.  (FNF)             
2177!   890503  Minor cosmetic changes.  (FNF)                             
2178!   930809  Renamed to allow single/double precision versions. (ACH)   
2179!   010418  Reduced size of Common block /DLS001/. (ACH)               
2180!   031105  Restored 'own' variables to Common block /DLS001/, to       
2181!           enable interrupt/restart feature. (ACH)                     
2182!   050427  Corrected roundoff decrement in TP. (ACH)                   
2183!***END PROLOGUE  DINTDY                                               
2184!**End                                                                 
2185      INTEGER K, NYH, IFLAG 
2186      KPP_REAL T, YH(NYH,*), DKY(*) 
2187      INTEGER IOWND, IOWNS,                                            &
2188        ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,                     &
2189        LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,               &
2190        MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU         
2191      KPP_REAL ROWNS,                                          &
2192        CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND                 
2193      COMMON /DLS001/ ROWNS(209),                                      &
2194        CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,                 &
2195        IOWND(6), IOWNS(6),                                            &
2196        ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,                     &
2197        LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,               &
2198        MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU         
2199      INTEGER I, IC, J, JB, JB2, JJ, JJ1, JP1 
2200      KPP_REAL C, R, S, TP 
2201      CHARACTER*80 MSG 
2202!                                                                       
2203!***FIRST EXECUTABLE STATEMENT  DINTDY                                 
2204      IFLAG = 0 
2205      IF (K .LT. 0 .OR. K .GT. NQ) GO TO 80 
2206      TP = TN - HU -  100.0D0*UROUND*SIGN(ABS(TN) + ABS(HU), HU) 
2207      IF ((T-TP)*(T-TN) .GT. 0.0D0) GO TO 90 
2208!                                                                       
2209      S = (T - TN)/H 
2210      IC = 1 
2211      IF (K .EQ. 0) GO TO 15 
2212      JJ1 = L - K 
2213      DO 10 JJ = JJ1,NQ 
2214   10   IC = IC*JJ 
2215   15 C = IC 
2216      DO 20 I = 1,N 
2217   20   DKY(I) = C*YH(I,L) 
2218      IF (K .EQ. NQ) GO TO 55 
2219      JB2 = NQ - K 
2220      DO 50 JB = 1,JB2 
2221        J = NQ - JB 
2222        JP1 = J + 1 
2223        IC = 1 
2224        IF (K .EQ. 0) GO TO 35 
2225        JJ1 = JP1 - K 
2226        DO 30 JJ = JJ1,J 
2227   30     IC = IC*JJ 
2228   35   C = IC 
2229        DO 40 I = 1,N 
2230   40     DKY(I) = C*YH(I,JP1) + S*DKY(I) 
2231   50   CONTINUE
2232      IF (K .EQ. 0) RETURN
2233   55 R = H**(-K) 
2234      DO 60 I = 1,N 
2235   60   DKY(I) = R*DKY(I) 
2236      RETURN 
2237!                                                                       
2238   80 MSG = 'DINTDY-  K (=I1) illegal      ' 
2239      CALL XERRWD (MSG, 30, 51, 0, 1, K, 0, 0, 0.0D0, 0.0D0) 
2240      IFLAG = -1 
2241      RETURN
2242   90 MSG = 'DINTDY-  T (=R1) illegal      ' 
2243      CALL XERRWD (MSG, 30, 52, 0, 0, 0, 0, 1, T, 0.0D0) 
2244      MSG='      T not in interval TCUR - HU (= R1) to TCUR (=R2)      ' 
2245      CALL XERRWD (MSG, 60, 52, 0, 0, 0, 0, 2, TP, TN) 
2246      IFLAG = -2 
2247      RETURN 
2248!----------------------- END OF SUBROUTINE DINTDY ----------------------
2249      END SUBROUTINE DINTDY                                         
2250!DECK DPREPJ                                                           
2251      SUBROUTINE DPREPJ (NEQ, Y, YH, NYH, EWT, FTEM, SAVF, WM, IWM, F, JAC)                                                       
2252!***BEGIN PROLOGUE  DPREPJ                                             
2253!***SUBSIDIARY                                                         
2254!***PURPOSE  Compute and process Newton iteration matrix.               
2255!***TYPE      KPP_REAL (SPREPJ-S, DPREPJ-D)                     
2256!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
2257!***DESCRIPTION                                                         
2258!                                                                       
2259!  DPREPJ is called by DSTODE to compute and process the matrix         
2260!  P = I - h*el(1)*J , where J is an approximation to the Jacobian.     
2261!  Here J is computed by the user-supplied routine JAC if               
2262!  MITER = 1 or 4, or by finite differencing if MITER = 2, 3, or 5.     
2263!  If MITER = 3, a diagonal approximation to J is used.                 
2264!  J is stored in WM and replaced by P.  If MITER .ne. 3, P is then     
2265!  subjected to LU decomposition in preparation for later solution     
2266!  of linear systems with P as coefficient matrix.  This is done       
2267!  by DGEFA if MITER = 1 or 2, and by DGBFA if MITER = 4 or 5.         
2268!                                                                       
2269!  In addition to variables described in DSTODE and DLSODE prologues,   
2270!  communication with DPREPJ uses the following:                       
2271!  Y     = array containing predicted values on entry.                 
2272!  FTEM  = work array of length N (ACOR in DSTODE).                     
2273!  SAVF  = array containing f evaluated at predicted y.                 
2274!  WM    = real work space for matrices.  On output it contains the     
2275!          inverse diagonal matrix if MITER = 3 and the LU decomposition
2276!          of P if MITER is 1, 2 , 4, or 5.                             
2277!          Storage of matrix elements starts at WM(3).                 
2278!          WM also contains the following matrix-related data:         
2279!          WM(1) = SQRT(UROUND), used in numerical Jacobian increments.
2280!          WM(2) = H*EL0, saved for later use if MITER = 3.             
2281!  IWM   = integer work space containing pivot information, starting at
2282!          IWM(21), if MITER is 1, 2, 4, or 5.  IWM also contains band 
2283!          parameters ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.   
2284!  EL0   = EL(1) (input).                                               
2285!  IERPJ = output error flag,  = 0 if no trouble, .gt. 0 if             
2286!          P matrix found to be singular.                               
2287!  JCUR  = output flag = 1 to indicate that the Jacobian matrix         
2288!          (or approximation) is now current.                           
2289!  This routine also uses the COMMON variables EL0, H, TN, UROUND,     
2290!  MITER, N, NFE, and NJE.                                             
2291!                                                                       
2292!***SEE ALSO  DLSODE                                                   
2293!***ROUTINES CALLED  DGBFA, DGEFA, DVNORM                               
2294!***COMMON BLOCKS    DLS001                                             
2295!***REVISION HISTORY  (YYMMDD)                                         
2296!   791129  DATE WRITTEN                                               
2297!   890501  Modified prologue to SLATEC/LDOC format.  (FNF)             
2298!   890504  Minor cosmetic changes.  (FNF)                             
2299!   930809  Renamed to allow single/double precision versions. (ACH)   
2300!   010418  Reduced size of Common block /DLS001/. (ACH)               
2301!   031105  Restored 'own' variables to Common block /DLS001/, to       
2302!           enable interrupt/restart feature. (ACH)                     
2303!***END PROLOGUE  DPREPJ                                               
2304!**End                                                                 
2305      EXTERNAL F, JAC 
2306      INTEGER NEQ, NYH, IWM(*)
2307      KPP_REAL Y(*), YH(NYH,*), EWT(*), FTEM(*), SAVF(*), WM(*) 
2308      INTEGER IOWND, IOWNS, IER,                                           &
2309        ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,                     &
2310        LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,               &
2311        MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU         
2312      KPP_REAL ROWNS,                                          &
2313        CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND                 
2314      COMMON /DLS001/ ROWNS(209),                                      &
2315        CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,                 &
2316        IOWND(6), IOWNS(6),                                            &
2317        ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,                     &
2318        LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,               &
2319        MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU         
2320      INTEGER I, I1, I2, ISING, II, J, J1, JJ, LENP,                     &
2321              MBA, MBAND, MEB1, MEBAND, ML, ML3, MU, NP1                     
2322      KPP_REAL CON, DI, FAC, HL0, R, R0, SRUR, YI, YJ, YJJ
2323      !KPP_REAL  DVNORM                                                         
2324!                                                                       
2325!***FIRST EXECUTABLE STATEMENT  DPREPJ                                 
2326      NJE = NJE + 1 
2327      IERPJ = 0 
2328      JCUR = 1 
2329      HL0 = H*EL0 
2330      CON = -HL0 
2331
2332#ifdef FULL_ALGEBRA
2333      LENP = N*N 
2334      DO i = 1,LENP 
2335         WM(i+2) = 0.0D0 
2336      END DO
2337      CALL JAC_CHEM (NEQ, TN, Y, WM(3)) 
2338      DO I = 1,LENP 
2339        WM(I+2) = WM(I+2)*CON
2340      END DO 
2341      ! Add identity matrix
2342      J = 3 
2343      NP1 = N + 1 
2344      DO I = 1,N 
2345        WM(J) = WM(J) + 1.0D0 
2346        J = J + NP1 
2347      END DO
2348      ! Do LU decomposition on P
2349      CALL DGETRF(N,N,WM(3),N,IWM(21),ISING)
2350#else
2351      CALL JAC_CHEM (NEQ, TN, Y, WM(3)) 
2352      DO i = 1,LU_NONZERO 
2353         WM(i+2) = WM(i+2)*CON 
2354      END DO
2355      ! Add identity matrix
2356      DO i = 1,N 
2357        j = 2+LU_DIAG(i)
2358        WM(j) = WM(j) + 1.0D0 
2359      END DO 
2360      ! Do LU decomposition on P
2361      CALL KppDecomp(WM(3),IER)
2362#endif     
2363      IF (IER .NE. 0) IERPJ = 1 
2364      RETURN 
2365 !----------------------- END OF SUBROUTINE DPREPJ ----------------------
2366      END SUBROUTINE DPREPJ                                         
2367!DECK DSOLSY                                                           
2368      SUBROUTINE DSOLSY (WM, IWM, X, TEM) 
2369!***BEGIN PROLOGUE  DSOLSY                                             
2370!***SUBSIDIARY                                                         
2371!***PURPOSE  ODEPACK linear system solver.                             
2372!***TYPE      KPP_REAL (SSOLSY-S, DSOLSY-D)                     
2373!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
2374!***DESCRIPTION                                                         
2375!                                                                       
2376!  This routine manages the solution of the linear system arising from 
2377!  a chord iteration.  It is called if MITER .ne. 0.                   
2378!  If MITER is 1 or 2, it calls DGESL to accomplish this.               
2379!  If MITER = 3 it updates the coefficient h*EL0 in the diagonal       
2380!  matrix, and then computes the solution.                             
2381!  If MITER is 4 or 5, it calls DGBSL.                                 
2382!  Communication with DSOLSY uses the following variables:             
2383!  WM    = real work space containing the inverse diagonal matrix if   
2384!          MITER = 3 and the LU decomposition of the matrix otherwise. 
2385!          Storage of matrix elements starts at WM(3).                 
2386!          WM also contains the following matrix-related data:         
2387!          WM(1) = SQRT(UROUND) (not used here),                       
2388!          WM(2) = HL0, the previous value of h*EL0, used if MITER = 3.
2389!  IWM   = integer work space containing pivot information, starting at
2390!          IWM(21), if MITER is 1, 2, 4, or 5.  IWM also contains band 
2391!          parameters ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.   
2392!  X     = the right-hand side vector on input, and the solution vector
2393!          on output, of length N.                                     
2394!  TEM   = vector of work space of length N, not used in this version. 
2395!  IERSL = output flag (in COMMON).  IERSL = 0 if no trouble occurred. 
2396!          IERSL = 1 if a singular matrix arose with MITER = 3.         
2397!  This routine also uses the COMMON variables EL0, H, MITER, and N.   
2398!                                                                       
2399!***SEE ALSO  DLSODE                                                   
2400!***ROUTINES CALLED  DGBSL, DGESL                                       
2401!***COMMON BLOCKS    DLS001                                             
2402!***REVISION HISTORY  (YYMMDD)                                         
2403!   791129  DATE WRITTEN                                               
2404!   890501  Modified prologue to SLATEC/LDOC format.  (FNF)             
2405!   890503  Minor cosmetic changes.  (FNF)                             
2406!   930809  Renamed to allow single/double precision versions. (ACH)   
2407!   010418  Reduced size of Common block /DLS001/. (ACH)               
2408!   031105  Restored 'own' variables to Common block /DLS001/, to       
2409!           enable interrupt/restart feature. (ACH)                     
2410!***END PROLOGUE  DSOLSY                                               
2411!**End                                                                 
2412      INTEGER IWM(*) 
2413      KPP_REAL WM(*), X(*), TEM(*) 
2414      INTEGER IOWND, IOWNS,                                            &
2415        ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,                     &
2416        LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,               &
2417        MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU         
2418      KPP_REAL ROWNS,                                          &
2419        CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND                 
2420      COMMON /DLS001/ ROWNS(209),                                      &
2421        CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,                 &
2422        IOWND(6), IOWNS(6),                                            &
2423        ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,                     &
2424        LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,               &
2425        MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU         
2426      INTEGER I, MEBAND, ML, MU 
2427      KPP_REAL DI, HL0, PHL0, R 
2428#ifdef FULL_ALGEBRA     
2429      INTEGER ISING
2430#endif     
2431!                                                                       
2432!***FIRST EXECUTABLE STATEMENT  DSOLSY                                 
2433      IERSL = 0 
2434#ifdef FULL_ALGEBRA     
2435      CALL DGETRS ('N',N,1,WM(3),N,IWM(21),X,N,ISING)
2436#else
2437      CALL KppSolve(WM(3),X)
2438#endif     
2439      RETURN 
2440!----------------------- END OF SUBROUTINE DSOLSY ----------------------
2441      END SUBROUTINE DSOLSY                                         
2442!DECK DSRCOM                                                           
2443      SUBROUTINE DSRCOM (RSAV, ISAV, JOB) 
2444!***BEGIN PROLOGUE  DSRCOM                                             
2445!***SUBSIDIARY                                                         
2446!***PURPOSE  Save/restore ODEPACK COMMON blocks.                       
2447!***TYPE      KPP_REAL (SSRCOM-S, DSRCOM-D)                     
2448!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
2449!***DESCRIPTION                                                         
2450!                                                                       
2451!  This routine saves or restores (depending on JOB) the contents of   
2452!  the COMMON block DLS001, which is used internally                   
2453!  by one or more ODEPACK solvers.                                     
2454!                                                                       
2455!  RSAV = real array of length 218 or more.                             
2456!  ISAV = integer array of length 37 or more.                           
2457!  JOB  = flag indicating to save or restore the COMMON blocks:         
2458!         JOB  = 1 if COMMON is to be saved (written to RSAV/ISAV)     
2459!         JOB  = 2 if COMMON is to be restored (read from RSAV/ISAV)   
2460!         A call with JOB = 2 presumes a prior call with JOB = 1.       
2461!                                                                       
2462!***SEE ALSO  DLSODE                                                   
2463!***ROUTINES CALLED  (NONE)                                             
2464!***COMMON BLOCKS    DLS001                                             
2465!***REVISION HISTORY  (YYMMDD)                                         
2466!   791129  DATE WRITTEN                                               
2467!   890501  Modified prologue to SLATEC/LDOC format.  (FNF)             
2468!   890503  Minor cosmetic changes.  (FNF)                             
2469!   921116  Deleted treatment of block /EH0001/.  (ACH)                 
2470!   930801  Reduced Common block length by 2.  (ACH)                   
2471!   930809  Renamed to allow single/double precision versions. (ACH)   
2472!   010418  Reduced Common block length by 209+12. (ACH)               
2473!   031105  Restored 'own' variables to Common block /DLS001/, to       
2474!           enable interrupt/restart feature. (ACH)                     
2475!   031112  Added SAVE statement for data-loaded constants.             
2476!***END PROLOGUE  DSRCOM                                               
2477!**End                                                                 
2478      INTEGER ISAV(*), JOB 
2479      INTEGER ILS 
2480      INTEGER I, LENILS, LENRLS 
2481      KPP_REAL RSAV(*),   RLS 
2482      SAVE LENRLS, LENILS 
2483      COMMON /DLS001/ RLS(218), ILS(37) 
2484      DATA LENRLS/218/, LENILS/37/ 
2485!                                                                       
2486!***FIRST EXECUTABLE STATEMENT  DSRCOM                                 
2487      IF (JOB .EQ. 2) GO TO 100 
2488!                                                                       
2489      DO 10 I = 1,LENRLS 
2490   10   RSAV(I) = RLS(I) 
2491      DO 20 I = 1,LENILS 
2492   20   ISAV(I) = ILS(I) 
2493      RETURN 
2494!                                                                       
2495  100 CONTINUE
2496      DO 110 I = 1,LENRLS 
2497  110    RLS(I) = RSAV(I) 
2498      DO 120 I = 1,LENILS 
2499  120    ILS(I) = ISAV(I) 
2500      RETURN 
2501!----------------------- END OF SUBROUTINE DSRCOM ----------------------
2502      END SUBROUTINE DSRCOM                                         
2503!DECK DSTODE                                                           
2504      SUBROUTINE DSTODE (NEQ, Y, YH, NYH, YH1, EWT, SAVF, ACOR, &
2505                         WM, IWM, F, JAC)                                   
2506                        !WM, IWM, F, JAC, PJAC, SLVS)                                   
2507!***BEGIN PROLOGUE  DSTODE                                             
2508!***SUBSIDIARY                                                         
2509!***PURPOSE  Performs one step of an ODEPACK integration.               
2510!***TYPE      KPP_REAL (SSTODE-S, DSTODE-D)                     
2511!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
2512!***DESCRIPTION                                                         
2513!                                                                       
2514!  DSTODE performs one step of the integration of an initial value     
2515!  problem for a system of ordinary differential equations.             
2516!  Note:  DSTODE is independent of the value of the iteration method   
2517!  indicator MITER, when this is .ne. 0, and hence is independent       
2518!  of the type of chord method used, or the Jacobian structure.         
2519!  Communication with DSTODE is done with the following variables:     
2520!                                                                       
2521!  NEQ    = integer array containing problem size in NEQ, and       
2522!           passed as the NEQ argument in all calls to F and JAC.       
2523!  Y      = an array of length .ge. N used as the Y argument in         
2524!           all calls to F and JAC.                                     
2525!  YH     = an NYH by LMAX array containing the dependent variables     
2526!           and their approximate scaled derivatives, where             
2527!           LMAX = MAXORD + 1.  YH(i,j+1) contains the approximate     
2528!           j-th derivative of y(i), scaled by h**j/factorial(j)       
2529!           (j = 0,1,...,NQ).  on entry for the first step, the first   
2530!           two columns of YH must be set from the initial values.     
2531!  NYH    = a constant integer .ge. N, the first dimension of YH.       
2532!  YH1    = a one-dimensional array occupying the same space as YH.     
2533!  EWT    = an array of length N containing multiplicative weights     
2534!           for local error measurements.  Local errors in Y(i) are     
2535!           compared to 1.0/EWT(i) in various error tests.             
2536!  SAVF   = an array of working storage, of length N.                   
2537!           Also used for input of YH(*,MAXORD+2) when JSTART = -1     
2538!           and MAXORD .lt. the current order NQ.                       
2539!  ACOR   = a work array of length N, used for the accumulated         
2540!           corrections.  On a successful return, ACOR(i) contains     
2541!           the estimated one-step local error in Y(i).                 
2542!  WM,IWM = real and integer work arrays associated with matrix         
2543!           operations in chord iteration (MITER .ne. 0).               
2544!  PJAC   = name of routine to evaluate and preprocess Jacobian matrix 
2545!           and P = I - h*el0*JAC, if a chord method is being used.     
2546!  SLVS   = name of routine to solve linear system in chord iteration. 
2547!  CCMAX  = maximum relative change in h*el0 before PJAC is called.     
2548!  H      = the step size to be attempted on the next step.             
2549!           H is altered by the error control algorithm during the     
2550!           problem.  H can be either positive or negative, but its     
2551!           sign must remain constant throughout the problem.           
2552!  HMIN   = the minimum absolute value of the step size h to be used.   
2553!  HMXI   = inverse of the maximum absolute value of h to be used.     
2554!           HMXI = 0.0 is allowed and corresponds to an infinite hmax. 
2555!           HMIN and HMXI may be changed at any time, but will not     
2556!           take effect until the next change of h is considered.       
2557!  TN     = the independent variable. TN is updated on each step taken.
2558!  JSTART = an integer used for input only, with the following         
2559!           values and meanings:                                       
2560!                0  perform the first step.                             
2561!            .gt.0  take a new step continuing from the last.           
2562!               -1  take the next step with a new value of H, MAXORD,   
2563!                     N, METH, MITER, and/or matrix parameters.         
2564!               -2  take the next step with a new value of H,           
2565!                     but with other inputs unchanged.                 
2566!           On return, JSTART is set to 1 to facilitate continuation.   
2567!  KFLAG  = a completion code with the following meanings:             
2568!                0  the step was succesful.                             
2569!               -1  the requested error could not be achieved.         
2570!               -2  corrector convergence could not be achieved.       
2571!               -3  fatal error in PJAC or SLVS.                       
2572!           A return with KFLAG = -1 or -2 means either                 
2573!           abs(H) = HMIN or 10 consecutive failures occurred.         
2574!           On a return with KFLAG negative, the values of TN and       
2575!           the YH array are as of the beginning of the last           
2576!           step, and H is the last step size attempted.               
2577!  MAXORD = the maximum order of integration method to be allowed.     
2578!  MAXCOR = the maximum number of corrector iterations allowed.         
2579!  MSBP   = maximum number of steps between PJAC calls (MITER .gt. 0). 
2580!  MXNCF  = maximum number of convergence failures allowed.             
2581!  METH/MITER = the method flags.  See description in driver.           
2582!  N      = the number of first-order differential equations.           
2583!  The values of CCMAX, H, HMIN, HMXI, TN, JSTART, KFLAG, MAXORD,       
2584!  MAXCOR, MSBP, MXNCF, METH, MITER, and N are communicated via COMMON.
2585!                                                                       
2586!***SEE ALSO  DLSODE                                                   
2587!***ROUTINES CALLED  DCFODE, DVNORM                                     
2588!***COMMON BLOCKS    DLS001                                             
2589!***REVISION HISTORY  (YYMMDD)                                         
2590!   791129  DATE WRITTEN                                               
2591!   890501  Modified prologue to SLATEC/LDOC format.  (FNF)             
2592!   890503  Minor cosmetic changes.  (FNF)                             
2593!   930809  Renamed to allow single/double precision versions. (ACH)   
2594!   010418  Reduced size of Common block /DLS001/. (ACH)               
2595!   031105  Restored 'own' variables to Common block /DLS001/, to       
2596!           enable interrupt/restart feature. (ACH)                     
2597!***END PROLOGUE  DSTODE                                               
2598!**End                                                                 
2599      EXTERNAL F, JAC !, PJAC, SLVS
2600      INTEGER NEQ, NYH, IWM(*) 
2601      KPP_REAL Y(*), YH(NYH,*), YH1(*), EWT(*), SAVF(*),       &
2602                       ACOR(*), WM(*) 
2603      INTEGER IOWND, IALTH, IPUP, LMAX, MEO, NQNYH, NSLP,              &
2604        ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,                     &
2605        LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,               &
2606        MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU         
2607      INTEGER I, I1, IREDO, IRET, J, JB, M, NCF, NEWQ 
2608      KPP_REAL CONIT, CRATE, EL, ELCO, HOLD, RMAX, TESCO,      &
2609        CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND                 
2610      KPP_REAL DCON, DDN, DEL, DELP, DSM, DUP, EXDN, EXSM,     &
2611              EXUP,R, RH, RHDN, RHSM, RHUP, TOLD
2612      !KPP_REAL DVNORM                         
2613      COMMON /DLS001/ CONIT, CRATE, EL(13), ELCO(13,12),               &
2614        HOLD, RMAX, TESCO(3,12),                                       &
2615        CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND,                 &
2616        IOWND(6), IALTH, IPUP, LMAX, MEO, NQNYH, NSLP,                 &
2617        ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L,                     &
2618        LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER,               &
2619        MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU         
2620!                                                                       
2621!***FIRST EXECUTABLE STATEMENT  DSTODE                                 
2622      KFLAG = 0 
2623      TOLD = TN 
2624      NCF = 0 
2625      IERPJ = 0 
2626      IERSL = 0 
2627      JCUR = 0 
2628      ICF = 0 
2629      DELP = 0.0D0 
2630      IF (JSTART .GT. 0) GO TO 200 
2631      IF (JSTART .EQ. -1) GO TO 100 
2632      IF (JSTART .EQ. -2) GO TO 160 
2633!-----------------------------------------------------------------------
2634! On the first call, the order is set to 1, and other variables are     
2635! initialized.  RMAX is the maximum ratio by which H can be increased   
2636! in a single step.  It is initially 1.E4 to compensate for the small   
2637! initial H, but then is normally equal to 10.  If a failure           
2638! occurs (in corrector convergence or error test), RMAX is set to 2     
2639! for the next increase.                                               
2640!-----------------------------------------------------------------------
2641      LMAX = MAXORD + 1 
2642      NQ = 1 
2643      L = 2 
2644      IALTH = 2 
2645      RMAX = 10000.0D0 
2646      RC = 0.0D0 
2647      EL0 = 1.0D0 
2648      CRATE = 0.7D0 
2649      HOLD = H 
2650      MEO = METH 
2651      NSLP = 0 
2652      IPUP = MITER 
2653      IRET = 3 
2654      GO TO 140 
2655!-----------------------------------------------------------------------
2656! The following block handles preliminaries needed when JSTART = -1.   
2657! IPUP is set to MITER to force a matrix update.                       
2658! If an order increase is about to be considered (IALTH = 1),           
2659! IALTH is reset to 2 to postpone consideration one more step.         
2660! If the caller has changed METH, DCFODE is called to reset             
2661! the coefficients of the method.                                       
2662! If the caller has changed MAXORD to a value less than the current     
2663! order NQ, NQ is reduced to MAXORD, and a new H chosen accordingly.   
2664! If H is to be changed, YH must be rescaled.                           
2665! If H or METH is being changed, IALTH is reset to L = NQ + 1           
2666! to prevent further changes in H for that many steps.                 
2667!-----------------------------------------------------------------------
2668  100 IPUP = MITER 
2669      LMAX = MAXORD + 1 
2670      IF (IALTH .EQ. 1) IALTH = 2 
2671      IF (METH .EQ. MEO) GO TO 110 
2672      CALL DCFODE (METH, ELCO, TESCO) 
2673      MEO = METH 
2674      IF (NQ .GT. MAXORD) GO TO 120 
2675      IALTH = L 
2676      IRET = 1 
2677      GO TO 150 
2678  110 IF (NQ .LE. MAXORD) GO TO 160 
2679  120 NQ = MAXORD 
2680      L = LMAX 
2681      DO 125 I = 1,L 
2682  125   EL(I) = ELCO(I,NQ) 
2683      NQNYH = NQ*NYH 
2684      RC = RC*EL(1)/EL0 
2685      EL0 = EL(1) 
2686      CONIT = 0.5D0/(NQ+2) 
2687      DDN = DVNORM (N, SAVF, EWT)/TESCO(1,L) 
2688      EXDN = 1.0D0/L 
2689      RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0) 
2690      RH = MIN(RHDN,1.0D0) 
2691      IREDO = 3 
2692      IF (H .EQ. HOLD) GO TO 170 
2693      RH = MIN(RH,ABS(H/HOLD)) 
2694      H = HOLD 
2695      GO TO 175 
2696!-----------------------------------------------------------------------
2697! DCFODE is called to get all the integration coefficients for the     
2698! current METH.  Then the EL vector and related constants are reset     
2699! whenever the order NQ is changed, or at the start of the problem.     
2700!-----------------------------------------------------------------------
2701  140 CALL DCFODE (METH, ELCO, TESCO) 
2702  150 DO 155 I = 1,L 
2703  155   EL(I) = ELCO(I,NQ) 
2704      NQNYH = NQ*NYH 
2705      RC = RC*EL(1)/EL0 
2706      EL0 = EL(1) 
2707      CONIT = 0.5D0/(NQ+2) 
2708      GO TO (160, 170, 200), IRET 
2709!-----------------------------------------------------------------------
2710! If H is being changed, the H ratio RH is checked against             
2711! RMAX, HMIN, and HMXI, and the YH array rescaled.  IALTH is set to     
2712! L = NQ + 1 to prevent a change of H for that many steps, unless       
2713! forced by a convergence or error test failure.                       
2714!-----------------------------------------------------------------------
2715  160 IF (H .EQ. HOLD) GO TO 200 
2716      RH = H/HOLD 
2717      H = HOLD 
2718      IREDO = 3 
2719      GO TO 175 
2720  170 RH = MAX(RH,HMIN/ABS(H)) 
2721  175 RH = MIN(RH,RMAX) 
2722      RH = RH/MAX(1.0D0,ABS(H)*HMXI*RH) 
2723      R = 1.0D0 
2724      DO 180 J = 2,L 
2725        R = R*RH 
2726        DO 180 I = 1,N 
2727  180     YH(I,J) = YH(I,J)*R 
2728      H = H*RH 
2729      RC = RC*RH 
2730      IALTH = L 
2731      IF (IREDO .EQ. 0) GO TO 690 
2732!-----------------------------------------------------------------------
2733! This section computes the predicted values by effectively             
2734! multiplying the YH array by the Pascal Triangle matrix.               
2735! RC is the ratio of new to old values of the coefficient  H*EL(1).     
2736! When RC differs from 1 by more than CCMAX, IPUP is set to MITER       
2737! to force PJAC to be called, if a Jacobian is involved.               
2738! In any case, PJAC is called at least every MSBP steps.               
2739!-----------------------------------------------------------------------
2740  200 IF (ABS(RC-1.0D0) .GT. CCMAX) IPUP = MITER 
2741      IF (NST .GE. NSLP+MSBP) IPUP = MITER 
2742      TN = TN + H 
2743      I1 = NQNYH + 1 
2744      DO 215 JB = 1,NQ 
2745        I1 = I1 - NYH 
2746!dir$ ivdep                                                             
2747        DO 210 I = I1,NQNYH 
2748  210     YH1(I) = YH1(I) + YH1(I+NYH) 
2749  215   CONTINUE 
2750!-----------------------------------------------------------------------
2751! Up to MAXCOR corrector iterations are taken.  A convergence test is   
2752! made on the R.M.S. norm of each correction, weighted by the error     
2753! weight vector EWT.  The sum of the corrections is accumulated in the 
2754! vector ACOR(i).  The YH array is not altered in the corrector loop.   
2755!-----------------------------------------------------------------------
2756  220 M = 0 
2757      DO 230 I = 1,N 
2758  230   Y(I) = YH(I,1) 
2759      CALL F (NEQ, TN, Y, SAVF) 
2760      NFE = NFE + 1 
2761      IF (IPUP .LE. 0) GO TO 250 
2762!-----------------------------------------------------------------------
2763! If indicated, the matrix P = I - h*el(1)*J is reevaluated and         
2764! preprocessed before starting the corrector iteration.  IPUP is set   
2765! to 0 as an indicator that this has been done.                         
2766!-----------------------------------------------------------------------
2767      !CALL PJAC (NEQ, Y, YH, NYH, EWT, ACOR, SAVF, WM, IWM, F, JAC)
2768      CALL DPREPJ(NEQ, Y, YH, NYH, EWT, ACOR, SAVF, WM, IWM, F, JAC)
2769      IPUP = 0 
2770      RC = 1.0D0 
2771      NSLP = NST 
2772      CRATE = 0.7D0 
2773      IF (IERPJ .NE. 0) GO TO 430 
2774  250 DO 260 I = 1,N 
2775  260   ACOR(I) = 0.0D0 
2776  270 IF (MITER .NE. 0) GO TO 350 
2777!-----------------------------------------------------------------------
2778! In the case of functional iteration, update Y directly from           
2779! the result of the last function evaluation.                           
2780!-----------------------------------------------------------------------
2781      DO 290 I = 1,N 
2782        SAVF(I) = H*SAVF(I) - YH(I,2) 
2783  290   Y(I) = SAVF(I) - ACOR(I) 
2784      DEL = DVNORM (N, Y, EWT) 
2785      DO 300 I = 1,N 
2786        Y(I) = YH(I,1) + EL(1)*SAVF(I) 
2787  300   ACOR(I) = SAVF(I) 
2788      GO TO 400 
2789!-----------------------------------------------------------------------
2790! In the case of the chord method, compute the corrector error,         
2791! and solve the linear system with that as right-hand side and         
2792! P as coefficient matrix.                                             
2793!-----------------------------------------------------------------------
2794  350 DO 360 I = 1,N 
2795  360   Y(I) = H*SAVF(I) - (YH(I,2) + ACOR(I)) 
2796      !CALL SLVS (WM, IWM, Y, SAVF)
2797      CALL DSOLSY(WM, IWM, Y, SAVF)
2798      IF (IERSL .LT. 0) GO TO 430 
2799      IF (IERSL .GT. 0) GO TO 410 
2800      DEL = DVNORM (N, Y, EWT) 
2801      DO 380 I = 1,N 
2802        ACOR(I) = ACOR(I) + Y(I) 
2803  380   Y(I) = YH(I,1) + EL(1)*ACOR(I) 
2804!-----------------------------------------------------------------------
2805! Test for convergence.  If M.gt.0, an estimate of the convergence     
2806! rate constant is stored in CRATE, and this is used in the test.       
2807!-----------------------------------------------------------------------
2808  400 IF (M .NE. 0) CRATE = MAX(0.2D0*CRATE,DEL/DELP) 
2809      DCON = DEL*MIN(1.0D0,1.5D0*CRATE)/(TESCO(2,NQ)*CONIT) 
2810      IF (DCON .LE. 1.0D0) GO TO 450 
2811      M = M + 1 
2812      IF (M .EQ. MAXCOR) GO TO 410 
2813      IF (M .GE. 2 .AND. DEL .GT. 2.0D0*DELP) GO TO 410 
2814      DELP = DEL 
2815      CALL F (NEQ, TN, Y, SAVF) 
2816      NFE = NFE + 1 
2817      GO TO 270 
2818!-----------------------------------------------------------------------
2819! The corrector iteration failed to converge.                           
2820! If MITER .ne. 0 and the Jacobian is out of date, PJAC is called for   
2821! the next try.  Otherwise the YH array is retracted to its values     
2822! before prediction, and H is reduced, if possible.  If H cannot be     
2823! reduced or MXNCF failures have occurred, exit with KFLAG = -2.       
2824!-----------------------------------------------------------------------
2825  410 IF (MITER .EQ. 0 .OR. JCUR .EQ. 1) GO TO 430 
2826      ICF = 1 
2827      IPUP = MITER 
2828      GO TO 220 
2829  430 ICF = 2 
2830      NCF = NCF + 1 
2831      RMAX = 2.0D0 
2832      TN = TOLD 
2833      I1 = NQNYH + 1 
2834      DO 445 JB = 1,NQ 
2835        I1 = I1 - NYH 
2836!dir$ ivdep                                                             
2837        DO 440 I = I1,NQNYH 
2838  440     YH1(I) = YH1(I) - YH1(I+NYH) 
2839  445   CONTINUE
2840      IF (IERPJ .LT. 0 .OR. IERSL .LT. 0) GO TO 680 
2841      IF (ABS(H) .LE. HMIN*1.00001D0) GO TO 670 
2842      IF (NCF .EQ. MXNCF) GO TO 670 
2843      RH = 0.25D0 
2844      IPUP = MITER 
2845      IREDO = 1 
2846      GO TO 170 
2847!-----------------------------------------------------------------------
2848! The corrector has converged.  JCUR is set to 0                       
2849! to signal that the Jacobian involved may need updating later.         
2850! The local error test is made and control passes to statement 500     
2851! if it fails.                                                         
2852!-----------------------------------------------------------------------
2853  450 JCUR = 0 
2854      IF (M .EQ. 0) DSM = DEL/TESCO(2,NQ) 
2855      IF (M .GT. 0) DSM = DVNORM (N, ACOR, EWT)/TESCO(2,NQ) 
2856      IF (DSM .GT. 1.0D0) GO TO 500 
2857!-----------------------------------------------------------------------
2858! After a successful step, update the YH array.                         
2859! Consider changing H if IALTH = 1.  Otherwise decrease IALTH by 1.     
2860! If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for         
2861! use in a possible order increase on the next step.                   
2862! If a change in H is considered, an increase or decrease in order     
2863! by one is considered also.  A change in H is made only if it is by a 
2864! factor of at least 1.1.  If not, IALTH is set to 3 to prevent         
2865! testing for that many steps.                                         
2866!-----------------------------------------------------------------------
2867      KFLAG = 0 
2868      IREDO = 0 
2869      NST = NST + 1 
2870      HU = H 
2871      NQU = NQ 
2872      DO 470 J = 1,L 
2873        DO 470 I = 1,N 
2874  470     YH(I,J) = YH(I,J) + EL(J)*ACOR(I) 
2875      IALTH = IALTH - 1 
2876      IF (IALTH .EQ. 0) GO TO 520 
2877      IF (IALTH .GT. 1) GO TO 700 
2878      IF (L .EQ. LMAX) GO TO 700 
2879      DO 490 I = 1,N 
2880  490   YH(I,LMAX) = ACOR(I) 
2881      GO TO 700 
2882!-----------------------------------------------------------------------
2883! The error test failed.  KFLAG keeps track of multiple failures.       
2884! Restore TN and the YH array to their previous values, and prepare     
2885! to try the step again.  Compute the optimum step size for this or     
2886! one lower order.  After 2 or more failures, H is forced to decrease   
2887! by a factor of 0.2 or less.                                           
2888!-----------------------------------------------------------------------
2889  500 KFLAG = KFLAG - 1 
2890      TN = TOLD 
2891      I1 = NQNYH + 1 
2892      DO 515 JB = 1,NQ 
2893        I1 = I1 - NYH 
2894!dir$ ivdep                                                             
2895        DO 510 I = I1,NQNYH 
2896  510     YH1(I) = YH1(I) - YH1(I+NYH) 
2897  515   CONTINUE
2898      RMAX = 2.0D0 
2899      IF (ABS(H) .LE. HMIN*1.00001D0) GO TO 660 
2900      IF (KFLAG .LE. -3) GO TO 640 
2901      IREDO = 2 
2902      RHUP = 0.0D0 
2903      GO TO 540 
2904!-----------------------------------------------------------------------
2905! Regardless of the success or failure of the step, factors             
2906! RHDN, RHSM, and RHUP are computed, by which H could be multiplied     
2907! at order NQ - 1, order NQ, or order NQ + 1, respectively.             
2908! In the case of failure, RHUP = 0.0 to avoid an order increase.       
2909! The largest of these is determined and the new order chosen           
2910! accordingly.  If the order is to be increased, we compute one         
2911! additional scaled derivative.                                         
2912!-----------------------------------------------------------------------
2913  520 RHUP = 0.0D0 
2914      IF (L .EQ. LMAX) GO TO 540 
2915      DO 530 I = 1,N 
2916  530   SAVF(I) = ACOR(I) - YH(I,LMAX) 
2917      DUP = DVNORM (N, SAVF, EWT)/TESCO(3,NQ) 
2918      EXUP = 1.0D0/(L+1) 
2919      RHUP = 1.0D0/(1.4D0*DUP**EXUP + 0.0000014D0) 
2920  540 EXSM = 1.0D0/L 
2921      RHSM = 1.0D0/(1.2D0*DSM**EXSM + 0.0000012D0) 
2922      RHDN = 0.0D0 
2923      IF (NQ .EQ. 1) GO TO 560 
2924      DDN = DVNORM (N, YH(1,L), EWT)/TESCO(1,NQ) 
2925      EXDN = 1.0D0/NQ 
2926      RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0) 
2927  560 IF (RHSM .GE. RHUP) GO TO 570 
2928      IF (RHUP .GT. RHDN) GO TO 590 
2929      GO TO 580 
2930  570 IF (RHSM .LT. RHDN) GO TO 580 
2931      NEWQ = NQ 
2932      RH = RHSM 
2933      GO TO 620 
2934  580 NEWQ = NQ - 1 
2935      RH = RHDN 
2936      IF (KFLAG .LT. 0 .AND. RH .GT. 1.0D0) RH = 1.0D0 
2937      GO TO 620 
2938  590 NEWQ = L 
2939      RH = RHUP 
2940      IF (RH .LT. 1.1D0) GO TO 610 
2941      R = EL(L)/L 
2942      DO 600 I = 1,N 
2943  600   YH(I,NEWQ+1) = ACOR(I)*R 
2944      GO TO 630 
2945  610 IALTH = 3 
2946      GO TO 700 
2947  620 IF ((KFLAG .EQ. 0) .AND. (RH .LT. 1.1D0)) GO TO 610 
2948      IF (KFLAG .LE. -2) RH = MIN(RH,0.2D0) 
2949!-----------------------------------------------------------------------
2950! If there is a change of order, reset NQ, l, and the coefficients.     
2951! In any case H is reset according to RH and the YH array is rescaled. 
2952! Then exit from 690 if the step was OK, or redo the step otherwise.   
2953!-----------------------------------------------------------------------
2954      IF (NEWQ .EQ. NQ) GO TO 170 
2955  630 NQ = NEWQ 
2956      L = NQ + 1 
2957      IRET = 2 
2958      GO TO 150 
2959!-----------------------------------------------------------------------
2960! Control reaches this section if 3 or more failures have occured.     
2961! If 10 failures have occurred, exit with KFLAG = -1.                   
2962! It is assumed that the derivatives that have accumulated in the       
2963! YH array have errors of the wrong order.  Hence the first             
2964! derivative is recomputed, and the order is set to 1.  Then           
2965! H is reduced by a factor of 10, and the step is retried,             
2966! until it succeeds or H reaches HMIN.                                 
2967!-----------------------------------------------------------------------
2968  640 IF (KFLAG .EQ. -10) GO TO 660 
2969      RH = 0.1D0 
2970      RH = MAX(HMIN/ABS(H),RH) 
2971      H = H*RH 
2972      DO 645 I = 1,N 
2973  645   Y(I) = YH(I,1) 
2974      CALL F (NEQ, TN, Y, SAVF) 
2975      NFE = NFE + 1 
2976      DO 650 I = 1,N 
2977  650   YH(I,2) = H*SAVF(I) 
2978      IPUP = MITER 
2979      IALTH = 5 
2980      IF (NQ .EQ. 1) GO TO 200 
2981      NQ = 1 
2982      L = 2 
2983      IRET = 3 
2984      GO TO 150 
2985!-----------------------------------------------------------------------
2986! All returns are made through this section.  H is saved in HOLD       
2987! to allow the caller to change H on the next step.                     
2988!-----------------------------------------------------------------------
2989  660 KFLAG = -1 
2990      GO TO 720 
2991  670 KFLAG = -2 
2992      GO TO 720 
2993  680 KFLAG = -3 
2994      GO TO 720 
2995  690 RMAX = 10.0D0 
2996  700 R = 1.0D0/TESCO(2,NQU) 
2997      DO 710 I = 1,N 
2998  710   ACOR(I) = ACOR(I)*R 
2999  720 HOLD = H 
3000      JSTART = 1 
3001      RETURN 
3002!----------------------- END OF SUBROUTINE DSTODE ----------------------
3003      END SUBROUTINE DSTODE                                         
3004!DECK DEWSET                                                           
3005      SUBROUTINE DEWSET (N, ITOL, RelTol, AbsTol, YCUR, EWT) 
3006!***BEGIN PROLOGUE  DEWSET                                             
3007!***SUBSIDIARY                                                         
3008!***PURPOSE  Set error weight vector.                                   
3009!***TYPE      KPP_REAL (SEWSET-S, DEWSET-D)                     
3010!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
3011!***DESCRIPTION                                                         
3012!                                                                       
3013!  This subroutine sets the error weight vector EWT according to       
3014!      EWT(i) = RelTol(i)*ABS(YCUR(i)) + AbsTol(i),  i = 1,...,N,           
3015!  with the subscript on RelTol and/or AbsTol possibly replaced by 1 above,
3016!  depending on the value of ITOL.                                     
3017!                                                                       
3018!***SEE ALSO  DLSODE                                                   
3019!***ROUTINES CALLED  (NONE)                                             
3020!***REVISION HISTORY  (YYMMDD)                                         
3021!   791129  DATE WRITTEN                                               
3022!   890501  Modified prologue to SLATEC/LDOC format.  (FNF)             
3023!   890503  Minor cosmetic changes.  (FNF)                             
3024!   930809  Renamed to allow single/double precision versions. (ACH)   
3025!***END PROLOGUE  DEWSET                                               
3026!**End                                                                 
3027      INTEGER N, ITOL 
3028      INTEGER I 
3029      KPP_REAL RelTol(*), AbsTol(*), YCUR(N), EWT(N) 
3030!                                                                       
3031!***FIRST EXECUTABLE STATEMENT  DEWSET                                 
3032      GO TO (10, 20, 30, 40), ITOL 
3033   10 CONTINUE
3034      DO 15 I = 1,N 
3035   15   EWT(I) = RelTol(1)*ABS(YCUR(I)) + AbsTol(1) 
3036      RETURN
3037   20 CONTINUE
3038      DO 25 I = 1,N 
3039   25   EWT(I) = RelTol(1)*ABS(YCUR(I)) + AbsTol(I) 
3040      RETURN
3041   30 CONTINUE
3042      DO 35 I = 1,N 
3043   35   EWT(I) = RelTol(I)*ABS(YCUR(I)) + AbsTol(1) 
3044      RETURN
3045   40 CONTINUE
3046      DO 45 I = 1,N 
3047   45   EWT(I) = RelTol(I)*ABS(YCUR(I)) + AbsTol(I) 
3048      RETURN 
3049!----------------------- END OF SUBROUTINE DEWSET ----------------------
3050      END SUBROUTINE DEWSET                                         
3051!DECK DVNORM                                                           
3052      KPP_REAL FUNCTION DVNORM (N, V, W) 
3053!***BEGIN PROLOGUE  DVNORM                                             
3054!***SUBSIDIARY                                                         
3055!***PURPOSE  Weighted root-mean-square vector norm.                     
3056!***TYPE      KPP_REAL (SVNORM-S, DVNORM-D)                     
3057!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
3058!***DESCRIPTION                                                         
3059!                                                                       
3060!  This function routine computes the weighted root-mean-square norm   
3061!  of the vector of length N contained in the array V, with weights     
3062!  contained in the array W of length N:                               
3063!    DVNORM = SQRT( (1/N) * SUM( V(i)*W(i) )**2 )                       
3064!                                                                       
3065!***SEE ALSO  DLSODE                                                   
3066!***ROUTINES CALLED  (NONE)                                             
3067!***REVISION HISTORY  (YYMMDD)                                         
3068!   791129  DATE WRITTEN                                               
3069!   890501  Modified prologue to SLATEC/LDOC format.  (FNF)             
3070!   890503  Minor cosmetic changes.  (FNF)                             
3071!   930809  Renamed to allow single/double precision versions. (ACH)   
3072!***END PROLOGUE  DVNORM                                               
3073!**End                                                                 
3074      INTEGER N,   I 
3075      KPP_REAL V(N), W(N), SUM 
3076!                                                                       
3077!***FIRST EXECUTABLE STATEMENT  DVNORM                                 
3078      SUM = 0.0D0 
3079      DO 10 I = 1,N 
3080   10   SUM = SUM + (V(I)*W(I))**2 
3081      DVNORM = SQRT(SUM/N) 
3082      RETURN 
3083!----------------------- END OF FUNCTION DVNORM ------------------------
3084      END FUNCTION DVNORM                                         
3085!DECK XERRWD                                                           
3086      SUBROUTINE XERRWD (MSG, NMES, NERR, LEVEL, NI, I1, I2, NR, R1, R2) 
3087!***BEGIN PROLOGUE  XERRWD                                             
3088!***SUBSIDIARY                                                         
3089!***PURPOSE  Write error message with values.                           
3090!***CATEGORY  R3C                                                       
3091!***TYPE      KPP_REAL (XERRWV-S, XERRWD-D)                     
3092!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
3093!***DESCRIPTION                                                         
3094!                                                                       
3095!  Subroutines XERRWD, XSETF, XSETUN, and the function routine IXSAV,   
3096!  as given here, constitute a simplified version of the SLATEC error   
3097!  handling package.                                                   
3098!                                                                       
3099!  All arguments are input arguments.                                   
3100!                                                                       
3101!  MSG    = The message (character array).                             
3102!  NMES   = The length of MSG (number of characters).                   
3103!  NERR   = The error number (not used).                               
3104!  LEVEL  = The error level..                                           
3105!           0 or 1 means recoverable (control returns to caller).       
3106!           2 means fatal (run is aborted--see note below).             
3107!  NI     = Number of integers (0, 1, or 2) to be printed with message.
3108!  I1,I2  = Integers to be printed, depending on NI.                   
3109!  NR     = Number of reals (0, 1, or 2) to be printed with message.   
3110!  R1,R2  = Reals to be printed, depending on NR.                       
3111!                                                                       
3112!  Note..  this routine is machine-dependent and specialized for use   
3113!  in limited context, in the following ways..                         
3114!  1. The argument MSG is assumed to be of type CHARACTER, and         
3115!     the message is printed with a format of (1X,A).                   
3116!  2. The message is assumed to take only one line.                     
3117!     Multi-line messages are generated by repeated calls.             
3118!  3. If LEVEL = 2, control passes to the statement   STOP             
3119!     to abort the run.  This statement may be machine-dependent.       
3120!  4. R1 and R2 are assumed to be in double precision and are printed   
3121!     in D21.13 format.                                                 
3122!                                                                       
3123!***ROUTINES CALLED  IXSAV                                             
3124!***REVISION HISTORY  (YYMMDD)                                         
3125!   920831  DATE WRITTEN                                               
3126!   921118  Replaced MFLGSV/LUNSAV by IXSAV. (ACH)                     
3127!   930329  Modified prologue to SLATEC format. (FNF)                   
3128!   930407  Changed MSG from CHARACTER*1 array to variable. (FNF)       
3129!   930922  Minor cosmetic change. (FNF)                               
3130!***END PROLOGUE  XERRWD                                               
3131!                                                                       
3132!*Internal Notes:                                                       
3133!                                                                       
3134! For a different default logical unit number, IXSAV (or a subsidiary   
3135! routine that it calls) will need to be modified.                     
3136! For a different run-abort command, change the statement following     
3137! statement 100 at the end.                                             
3138!-----------------------------------------------------------------------
3139! Subroutines called by XERRWD.. None                                   
3140! Function routine called by XERRWD.. IXSAV                             
3141!-----------------------------------------------------------------------
3142!**End                                                                 
3143!                                                                       
3144!  Declare arguments.                                                   
3145!                                                                       
3146      KPP_REAL R1, R2 
3147      INTEGER NMES, NERR, LEVEL, NI, I1, I2, NR 
3148      CHARACTER*(*) MSG 
3149!                                                                       
3150!  Declare local variables.                                             
3151!                                                                       
3152      INTEGER LUNIT, MESFLG !, IXSAV
3153!                                                                       
3154!  Get logical unit number and message print flag.                     
3155!                                                                       
3156!***FIRST EXECUTABLE STATEMENT  XERRWD                                 
3157      LUNIT = IXSAV (1, 0, .FALSE.) 
3158      MESFLG = IXSAV (2, 0, .FALSE.) 
3159      IF (MESFLG .EQ. 0) GO TO 100 
3160!                                                                       
3161!  Write the message.                                                   
3162!                                                                       
3163      WRITE (LUNIT,10)  MSG 
3164   10 FORMAT(1X,A) 
3165      IF (NI .EQ. 1) WRITE (LUNIT, 20) I1 
3166   20 FORMAT(6X,'In above message,  I1 =',I10) 
3167      IF (NI .EQ. 2) WRITE (LUNIT, 30) I1,I2 
3168   30 FORMAT(6X,'In above message,  I1 =',I10,3X,'I2 =',I10) 
3169      IF (NR .EQ. 1) WRITE (LUNIT, 40) R1 
3170   40 FORMAT(6X,'In above message,  R1 =',D21.13) 
3171      IF (NR .EQ. 2) WRITE (LUNIT, 50) R1,R2 
3172   50 FORMAT(6X,'In above,  R1 =',D21.13,3X,'R2 =',D21.13) 
3173!                                                                       
3174!  Abort the run if LEVEL = 2.                                         
3175!                                                                       
3176  100 IF (LEVEL .NE. 2) RETURN
3177      STOP 
3178!----------------------- End of Subroutine XERRWD ----------------------
3179      END SUBROUTINE XERRWD                                         
3180!DECK XSETF                                                             
3181      SUBROUTINE XSETF (MFLAG) 
3182!***BEGIN PROLOGUE  XSETF                                               
3183!***PURPOSE  Reset the error print control flag.                       
3184!***CATEGORY  R3A                                                       
3185!***TYPE      ALL (XSETF-A)                                             
3186!***KEYWORDS  ERROR CONTROL                                             
3187!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
3188!***DESCRIPTION                                                         
3189!                                                                       
3190!   XSETF sets the error print control flag to MFLAG:                   
3191!      MFLAG=1 means print all messages (the default).                 
3192!      MFLAG=0 means no printing.                                       
3193!                                                                       
3194!***SEE ALSO  XERRWD, XERRWV                                           
3195!***REFERENCES  (NONE)                                                 
3196!***ROUTINES CALLED  IXSAV                                             
3197!***REVISION HISTORY  (YYMMDD)                                         
3198!   921118  DATE WRITTEN                                               
3199!   930329  Added SLATEC format prologue. (FNF)                         
3200!   930407  Corrected SEE ALSO section. (FNF)                           
3201!   930922  Made user-callable, and other cosmetic changes. (FNF)       
3202!***END PROLOGUE  XSETF                                                 
3203!                                                                       
3204! Subroutines called by XSETF.. None                                   
3205! Function routine called by XSETF.. IXSAV                             
3206!-----------------------------------------------------------------------
3207!**End                                                                 
3208      INTEGER MFLAG, JUNK !, IXSAV
3209!                                                                       
3210!***FIRST EXECUTABLE STATEMENT  XSETF                                   
3211      IF (MFLAG .EQ. 0 .OR. MFLAG .EQ. 1) JUNK = IXSAV (2,MFLAG,.TRUE.) 
3212      RETURN 
3213!----------------------- End of Subroutine XSETF -----------------------
3214      END SUBROUTINE XSETF                                         
3215!DECK XSETUN                                                           
3216      SUBROUTINE XSETUN (LUN) 
3217!***BEGIN PROLOGUE  XSETUN                                             
3218!***PURPOSE  Reset the logical unit number for error messages.         
3219!***CATEGORY  R3B                                                       
3220!***TYPE      ALL (XSETUN-A)                                           
3221!***KEYWORDS  ERROR CONTROL                                             
3222!***DESCRIPTION                                                         
3223!                                                                       
3224!   XSETUN sets the logical unit number for error messages to LUN.     
3225!                                                                       
3226!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
3227!***SEE ALSO  XERRWD, XERRWV                                           
3228!***REFERENCES  (NONE)                                                 
3229!***ROUTINES CALLED  IXSAV                                             
3230!***REVISION HISTORY  (YYMMDD)                                         
3231!   921118  DATE WRITTEN                                               
3232!   930329  Added SLATEC format prologue. (FNF)                         
3233!   930407  Corrected SEE ALSO section. (FNF)                           
3234!   930922  Made user-callable, and other cosmetic changes. (FNF)       
3235!***END PROLOGUE  XSETUN                                               
3236!                                                                       
3237! Subroutines called by XSETUN.. None                                   
3238! Function routine called by XSETUN.. IXSAV                             
3239!-----------------------------------------------------------------------
3240!**End                                                                 
3241      INTEGER LUN, JUNK !, IXSAV
3242!                                                                       
3243!***FIRST EXECUTABLE STATEMENT  XSETUN                                 
3244      IF (LUN .GT. 0) JUNK = IXSAV (1,LUN,.TRUE.) 
3245      RETURN 
3246!----------------------- End of Subroutine XSETUN ----------------------
3247      END SUBROUTINE XSETUN                                         
3248!DECK IXSAV                                                             
3249      INTEGER FUNCTION IXSAV (IPAR, IVALUE, ISET) 
3250!***BEGIN PROLOGUE  IXSAV                                               
3251!***SUBSIDIARY                                                         
3252!***PURPOSE  Save and recall error message control parameters.         
3253!***CATEGORY  R3C                                                       
3254!***TYPE      ALL (IXSAV-A)                                             
3255!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
3256!***DESCRIPTION                                                         
3257!                                                                       
3258!  IXSAV saves and recalls one of two error message parameters:         
3259!    LUNIT, the logical unit number to which messages are printed, and 
3260!    MESFLG, the message print flag.                                   
3261!  This is a modification of the SLATEC library routine J4SAVE.         
3262!                                                                       
3263!  Saved local variables..                                             
3264!   LUNIT  = Logical unit number for messages.  The default is obtained
3265!            by a call to IUMACH (may be machine-dependent).           
3266!   MESFLG = Print control flag..                                       
3267!            1 means print all messages (the default).                 
3268!            0 means no printing.                                       
3269!                                                                       
3270!  On input..                                                           
3271!    IPAR   = Parameter indicator (1 for LUNIT, 2 for MESFLG).         
3272!    IVALUE = The value to be set for the parameter, if ISET = .TRUE.   
3273!    ISET   = Logical flag to indicate whether to read or write.       
3274!             If ISET = .TRUE., the parameter will be given             
3275!             the value IVALUE.  If ISET = .FALSE., the parameter       
3276!             will be unchanged, and IVALUE is a dummy argument.       
3277!                                                                       
3278!  On return..                                                         
3279!    IXSAV = The (old) value of the parameter.                         
3280!                                                                       
3281!***SEE ALSO  XERRWD, XERRWV                                           
3282!***ROUTINES CALLED  IUMACH                                             
3283!***REVISION HISTORY  (YYMMDD)                                         
3284!   921118  DATE WRITTEN                                               
3285!   930329  Modified prologue to SLATEC format. (FNF)                   
3286!   930915  Added IUMACH call to get default output unit.  (ACH)       
3287!   930922  Minor cosmetic changes. (FNF)                               
3288!   010425  Type declaration for IUMACH added. (ACH)                   
3289!***END PROLOGUE  IXSAV                                                 
3290!                                                                       
3291! Subroutines called by IXSAV.. None                                   
3292! Function routine called by IXSAV.. IUMACH                             
3293!-----------------------------------------------------------------------
3294!**End                                                                 
3295      LOGICAL ISET 
3296      INTEGER IPAR, IVALUE 
3297!-----------------------------------------------------------------------
3298      INTEGER LUNIT, MESFLG!, IUMACH
3299!-----------------------------------------------------------------------
3300! The following Fortran-77 declaration is to cause the values of the   
3301! listed (local) variables to be saved between calls to this routine.   
3302!-----------------------------------------------------------------------
3303      SAVE LUNIT, MESFLG 
3304      DATA LUNIT/-1/, MESFLG/1/ 
3305!                                                                       
3306!***FIRST EXECUTABLE STATEMENT  IXSAV                                   
3307      IF (IPAR .EQ. 1) THEN
3308        IF (LUNIT .EQ. -1) LUNIT = IUMACH() 
3309        IXSAV = LUNIT 
3310        IF (ISET) LUNIT = IVALUE 
3311        ENDIF 
3312!                                                                       
3313      IF (IPAR .EQ. 2) THEN                                             
3314        IXSAV = MESFLG                                                 
3315        IF (ISET) MESFLG = IVALUE                                       
3316        ENDIF                                                           
3317!                                                                       
3318      RETURN                                                           
3319!----------------------- End of Function IXSAV -------------------------
3320      END FUNCTION IXSAV                                         
3321!DECK IUMACH                                                           
3322      INTEGER FUNCTION IUMACH() 
3323!***BEGIN PROLOGUE  IUMACH                                             
3324!***PURPOSE  Provide standard output unit number.                       
3325!***CATEGORY  R1                                                       
3326!***TYPE      INTEGER (IUMACH-I)                                       
3327!***KEYWORDS  MACHINE CONSTANTS                                         
3328!***AUTHOR  Hindmarsh, Alan C., (LLNL)                                 
3329!***DESCRIPTION                                                         
3330! *Usage:                                                               
3331!        INTEGER  LOUT, IUMACH                                         
3332!        LOUT = IUMACH()                                               
3333!                                                                       
3334! *Function Return Values:                                             
3335!     LOUT : the standard logical unit for Fortran output.             
3336!                                                                       
3337!***REFERENCES  (NONE)                                                 
3338!***ROUTINES CALLED  (NONE)                                             
3339!***REVISION HISTORY  (YYMMDD)                                         
3340!   930915  DATE WRITTEN                                               
3341!   930922  Made user-callable, and other cosmetic changes. (FNF)       
3342!***END PROLOGUE  IUMACH                                               
3343!                                                                       
3344!*Internal Notes:                                                       
3345!  The built-in value of 6 is standard on a wide range of Fortran       
3346!  systems.  This may be machine-dependent.                             
3347!**End                                                                 
3348!***FIRST EXECUTABLE STATEMENT  IUMACH                                 
3349      IUMACH = 6 
3350!                                                                       
3351      RETURN 
3352!----------------------- End of Function IUMACH ------------------------
3353      END FUNCTION IUMACH                                         
3354
3355!---- END OF SUBROUTINE DLSODE AND ITS INTERNAL PROCEDURES
3356      END SUBROUTINE DLSODE                                         
3357!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3358      SUBROUTINE FUN_CHEM(N, T, V, FCT)
3359!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3360
3361      USE KPP_ROOT_Parameters
3362      USE KPP_ROOT_Global
3363      USE KPP_ROOT_Function, ONLY: Fun
3364      USE KPP_ROOT_Rates
3365
3366      IMPLICIT NONE
3367
3368      INTEGER :: N
3369      KPP_REAL :: V(NVAR), FCT(NVAR), T
3370     
3371!      TOLD = TIME
3372!      TIME = T
3373!      CALL Update_SUN()
3374!      CALL Update_RCONST()
3375!      CALL Update_PHOTO()
3376!      TIME = TOLD
3377
3378      CALL Fun(V, FIX, RCONST, FCT)
3379     
3380      !Nfun=Nfun+1
3381
3382      END SUBROUTINE FUN_CHEM
3383
3384
3385!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3386      SUBROUTINE JAC_CHEM (N, T, V, JF)
3387!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3388
3389      USE KPP_ROOT_Parameters
3390      USE KPP_ROOT_Global
3391      USE KPP_ROOT_JacobianSP
3392      USE KPP_ROOT_Jacobian, ONLY: Jac_SP
3393      USE KPP_ROOT_Rates
3394
3395      IMPLICIT NONE
3396
3397      KPP_REAL :: V(NVAR), T
3398      INTEGER :: N
3399#ifdef FULL_ALGEBRA   
3400      INTEGER :: I, J
3401      KPP_REAL :: JV(LU_NONZERO), JF(NVAR,NVAR)
3402#else
3403      KPP_REAL :: JF(LU_NONZERO)
3404#endif   
3405 
3406!      TOLD = TIME
3407!      TIME = T
3408!      CALL Update_SUN()
3409!      CALL Update_RCONST()
3410!      CALL Update_PHOTO()
3411!      TIME = TOLD
3412   
3413#ifdef FULL_ALGEBRA   
3414      CALL Jac_SP(V, FIX, RCONST, JV)
3415      DO j=1,NVAR
3416      DO i=1,NVAR
3417         JF(i,j) = 0.0d0
3418      END DO
3419      END DO
3420      DO i=1,LU_NONZERO
3421         JF(LU_IROW(i),LU_ICOL(i)) = JV(i)
3422      END DO
3423#else
3424      CALL Jac_SP(V, FIX, RCONST, JF) 
3425#endif   
3426      !Njac=Njac+1
3427   
3428      END SUBROUTINE JAC_CHEM
3429
3430
3431END MODULE KPP_ROOT_Integrator
Note: See TracBrowser for help on using the repository browser.