~ubuntu-branches/ubuntu/hoary/scilab/hoary

« back to all changes in this revision

Viewing changes to routines/integ/ddaskr.f

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2005-01-09 22:58:21 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050109225821-473xr8vhgugxxx5j
Tags: 3.0-12
changed configure.in to build scilab's own malloc.o, closes: #255869

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
      SUBROUTINE DDASKR (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
 
2
     *   IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC, PSOL,
 
3
     *   RT, NRT, JROOT)
 
4
C
 
5
C***BEGIN PROLOGUE  DDASKR
 
6
C***REVISION HISTORY  (YYMMDD)
 
7
C   020815  DATE WRITTEN   
 
8
C   021105  Changed yprime argument in DRCHEK calls to YPRIME.
 
9
C   021217  Modified error return for zeros found too close together.
 
10
C   021217  Added root direction output in JROOT.
 
11
C   031201  stuck root masking 
 
12
c   040615  Removing Hmin requirement
 
13
c   040615  Separating the error message of Singular Jacobian in DDASID
 
14
c
 
15
C***CATEGORY NO.  I1A2
 
16
C***KEYWORDS  DIFFERENTIAL/ALGEBRAIC, BACKWARD DIFFERENTIATION FORMULAS,
 
17
C             IMPLICIT DIFFERENTIAL SYSTEMS, KRYLOV ITERATION
 
18
C***AUTHORS   Linda R. Petzold, Peter N. Brown, Alan C. Hindmarsh, and
 
19
C                  Clement W. Ulrich
 
20
C             Center for Computational Sciences & Engineering, L-316
 
21
C             Lawrence Livermore National Laboratory
 
22
C             P.O. Box 808,
 
23
C             Livermore, CA 94551
 
24
C***PURPOSE  This code solves a system of differential/algebraic 
 
25
C            equations of the form 
 
26
C               G(t,y,y') = 0 , 
 
27
C            using a combination of Backward Differentiation Formula 
 
28
C            (BDF) methods and a choice of two linear system solution 
 
29
C            methods: direct (dense or band) or Krylov (iterative).
 
30
C            This version is in double precision.
 
31
C-----------------------------------------------------------------------
 
32
C***DESCRIPTION
 
33
C
 
34
C *Usage:
 
35
C
 
36
C      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
37
C      INTEGER NEQ, INFO(N), IDID, LRW, LIW, IWORK(LIW), IPAR(*)
 
38
C      DOUBLE PRECISION T, Y(*), YPRIME(*), TOUT, RTOL(*), ATOL(*),
 
39
C         RWORK(LRW), RPAR(*)
 
40
C      EXTERNAL RES, JAC, PSOL, RT
 
41
C
 
42
C      CALL DDASKR (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
 
43
C     *             IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC, PSOL,
 
44
C     *             RT, NRT, JROOT)
 
45
C
 
46
C  Quantities which may be altered by the code are:
 
47
C     T, Y(*), YPRIME(*), INFO(1), RTOL, ATOL, IDID, RWORK(*), IWORK(*)
 
48
C
 
49
C
 
50
C *Arguments:
 
51
C
 
52
C  RES:EXT          This is the name of a subroutine which you
 
53
C                   provide to define the residual function G(t,y,y')
 
54
C                   of the differential/algebraic system.
 
55
C
 
56
C  NEQ:IN           This is the number of equations in the system.
 
57
C
 
58
C  T:INOUT          This is the current value of the independent 
 
59
C                   variable.
 
60
C
 
61
C  Y(*):INOUT       This array contains the solution components at T.
 
62
C
 
63
C  YPRIME(*):INOUT  This array contains the derivatives of the solution
 
64
C                   components at T.
 
65
C
 
66
C  TOUT:IN          This is a point at which a solution is desired.
 
67
C
 
68
C  INFO(N):IN       This is an integer array used to communicate details
 
69
C                   of how the solution is to be carried out, such as
 
70
C                   tolerance type, matrix structure, step size and
 
71
C                   order limits, and choice of nonlinear system method.
 
72
C                   N must be at least 20.
 
73
C
 
74
C  RTOL,ATOL:INOUT  These quantities represent absolute and relative
 
75
C                   error tolerances (on local error) which you provide
 
76
C                   to indicate how accurately you wish the solution to
 
77
C                   be computed.  You may choose them to be both scalars
 
78
C                   or else both arrays of length NEQ.
 
79
C
 
80
C  IDID:OUT         This integer scalar is an indicator reporting what
 
81
C                   the code did.  You must monitor this variable to
 
82
C                   decide what action to take next.
 
83
C
 
84
C  RWORK:WORK       A real work array of length LRW which provides the
 
85
C                   code with needed storage space.
 
86
C
 
87
C  LRW:IN           The length of RWORK.
 
88
C
 
89
C  IWORK:WORK       An integer work array of length LIW which provides
 
90
C                   the code with needed storage space.
 
91
C
 
92
C  LIW:IN           The length of IWORK.
 
93
C
 
94
C  RPAR,IPAR:IN     These are real and integer parameter arrays which
 
95
C                   you can use for communication between your calling
 
96
C                   program and the RES, JAC, and PSOL subroutines.
 
97
C
 
98
C  JAC:EXT          This is the name of a subroutine which you may
 
99
C                   provide (optionally) for calculating Jacobian 
 
100
C                   (partial derivative) data involved in solving linear
 
101
C                   systems within DDASKR.
 
102
C
 
103
C  PSOL:EXT         This is the name of a subroutine which you must
 
104
C                   provide for solving linear systems if you selected
 
105
C                   a Krylov method.  The purpose of PSOL is to solve
 
106
C                   linear systems involving a left preconditioner P.
 
107
C
 
108
C  RT:EXT           This is the name of the subroutine for defining
 
109
C                   constraint functions Ri(T,Y,Y')) whose roots are
 
110
C                   desired during the integration.  This name must be
 
111
C                   declared external in the calling program.
 
112
C
 
113
C  NRT:IN           This is the number of constraint functions
 
114
C                   Ri(T,Y,Y').  If there are no constraints, set
 
115
C                   NRT = 0, and pass a dummy name for RT.
 
116
C
 
117
C  JROOT:OUT        This is an integer array of length NRT for output
 
118
C                   of root information.
 
119
C
 
120
C *Overview
 
121
C
 
122
C  The DDASKR solver uses the backward differentiation formulas of
 
123
C  orders one through five to solve a system of the form G(t,y,y') = 0
 
124
C  for y = Y and y' = YPRIME.  Values for Y and YPRIME at the initial 
 
125
C  time must be given as input.  These values should be consistent, 
 
126
C  that is, if T, Y, YPRIME are the given initial values, they should 
 
127
C  satisfy G(T,Y,YPRIME) = 0.  However, if consistent values are not
 
128
C  known, in many cases you can have DDASKR solve for them -- see
 
129
C  INFO(11). (This and other options are described in detail below.)
 
130
C
 
131
C  Normally, DDASKR solves the system from T to TOUT.  It is easy to
 
132
C  continue the solution to get results at additional TOUT.  This is
 
133
C  the interval mode of operation.  Intermediate results can also be
 
134
C  obtained easily by specifying INFO(3).
 
135
C
 
136
C  On each step taken by DDASKR, a sequence of nonlinear algebraic  
 
137
C  systems arises.  These are solved by one of two types of
 
138
C  methods:
 
139
C    * a Newton iteration with a direct method for the linear
 
140
C      systems involved (INFO(12) = 0), or
 
141
C    * a Newton iteration with a preconditioned Krylov iterative 
 
142
C      method for the linear systems involved (INFO(12) = 1).
 
143
C
 
144
C  The direct method choices are dense and band matrix solvers, 
 
145
C  with either a user-supplied or an internal difference quotient 
 
146
C  Jacobian matrix, as specified by INFO(5) and INFO(6).
 
147
C  In the band case, INFO(6) = 1, you must supply half-bandwidths
 
148
C  in IWORK(1) and IWORK(2).
 
149
C
 
150
C  The Krylov method is the Generalized Minimum Residual (GMRES) 
 
151
C  method, in either complete or incomplete form, and with 
 
152
C  scaling and preconditioning.  The method is implemented
 
153
C  in an algorithm called SPIGMR.  Certain options in the Krylov 
 
154
C  method case are specified by INFO(13) and INFO(15).
 
155
C
 
156
C  If the Krylov method is chosen, you may supply a pair of routines,
 
157
C  JAC and PSOL, to apply preconditioning to the linear system.
 
158
C  If the system is A*x = b, the matrix is A = dG/dY + CJ*dG/dYPRIME
 
159
C  (of order NEQ).  This system can then be preconditioned in the form
 
160
C  (P-inverse)*A*x = (P-inverse)*b, with left preconditioner P.
 
161
C  (DDASKR does not allow right preconditioning.)
 
162
C  Then the Krylov method is applied to this altered, but equivalent,
 
163
C  linear system, hopefully with much better performance than without
 
164
C  preconditioning.  (In addition, a diagonal scaling matrix based on
 
165
C  the tolerances is also introduced into the altered system.)
 
166
C
 
167
C  The JAC routine evaluates any data needed for solving systems
 
168
C  with coefficient matrix P, and PSOL carries out that solution.
 
169
C  In any case, in order to improve convergence, you should try to
 
170
C  make P approximate the matrix A as much as possible, while keeping
 
171
C  the system P*x = b reasonably easy and inexpensive to solve for x,
 
172
C  given a vector b.
 
173
C
 
174
C  While integrating the given DAE system, DDASKR also searches for
 
175
C  roots of the given constraint functions Ri(T,Y,Y') given by RT.
 
176
C  If DDASKR detects a sign change in any Ri(T,Y,Y'), it will return
 
177
C  the intermediate value of T and Y for which Ri(T,Y,Y') = 0.
 
178
C
 
179
C *Description
 
180
C
 
181
C------INPUT - WHAT TO DO ON THE FIRST CALL TO DDASKR-------------------
 
182
C
 
183
C
 
184
C  The first call of the code is defined to be the start of each new
 
185
C  problem.  Read through the descriptions of all the following items,
 
186
C  provide sufficient storage space for designated arrays, set
 
187
C  appropriate variables for the initialization of the problem, and
 
188
C  give information about how you want the problem to be solved.
 
189
C
 
190
C
 
191
C  RES -- Provide a subroutine of the form
 
192
C
 
193
C             SUBROUTINE RES (T, Y, YPRIME, CJ, DELTA, IRES, RPAR, IPAR)
 
194
C
 
195
C         to define the system of differential/algebraic
 
196
C         equations which is to be solved. For the given values
 
197
C         of T, Y and YPRIME, the subroutine should return
 
198
C         the residual of the differential/algebraic system
 
199
C             DELTA = G(T,Y,YPRIME)
 
200
C         DELTA is a vector of length NEQ which is output from RES.
 
201
C
 
202
C         Subroutine RES must not alter T, Y, YPRIME, or CJ.
 
203
C         You must declare the name RES in an EXTERNAL
 
204
C         statement in your program that calls DDASKR.
 
205
C         You must dimension Y, YPRIME, and DELTA in RES.
 
206
C
 
207
C         The input argument CJ can be ignored, or used to rescale
 
208
C         constraint equations in the system (see Ref. 2, p. 145).
 
209
C         Note: In this respect, DDASKR is not downward-compatible
 
210
C         with DDASSL, which does not have the RES argument CJ.
 
211
C
 
212
C         IRES is an integer flag which is always equal to zero
 
213
C         on input.  Subroutine RES should alter IRES only if it
 
214
C         encounters an illegal value of Y or a stop condition.
 
215
C         Set IRES = -1 if an input value is illegal, and DDASKR
 
216
C         will try to solve the problem without getting IRES = -1.
 
217
C         If IRES = -2, DDASKR will return control to the calling
 
218
C         program with IDID = -11.
 
219
C
 
220
C         RPAR and IPAR are real and integer parameter arrays which
 
221
C         you can use for communication between your calling program
 
222
C         and subroutine RES. They are not altered by DDASKR. If you
 
223
C         do not need RPAR or IPAR, ignore these parameters by treat-
 
224
C         ing them as dummy arguments. If you do choose to use them,
 
225
C         dimension them in your calling program and in RES as arrays
 
226
C         of appropriate length.
 
227
C
 
228
C  NEQ -- Set it to the number of equations in the system (NEQ .GE. 1).
 
229
C
 
230
C  T -- Set it to the initial point of the integration. (T must be
 
231
C       a variable.)
 
232
C
 
233
C  Y(*) -- Set this array to the initial values of the NEQ solution
 
234
C          components at the initial point.  You must dimension Y of
 
235
C          length at least NEQ in your calling program.
 
236
C
 
237
C  YPRIME(*) -- Set this array to the initial values of the NEQ first
 
238
C               derivatives of the solution components at the initial
 
239
C               point.  You must dimension YPRIME at least NEQ in your
 
240
C               calling program. 
 
241
C
 
242
C  TOUT - Set it to the first point at which a solution is desired.
 
243
C         You cannot take TOUT = T.  Integration either forward in T
 
244
C         (TOUT .GT. T) or backward in T (TOUT .LT. T) is permitted.
 
245
C
 
246
C         The code advances the solution from T to TOUT using step
 
247
C         sizes which are automatically selected so as to achieve the
 
248
C         desired accuracy.  If you wish, the code will return with the
 
249
C         solution and its derivative at intermediate steps (the
 
250
C         intermediate-output mode) so that you can monitor them,
 
251
C         but you still must provide TOUT in accord with the basic
 
252
C         aim of the code.
 
253
C
 
254
C         The first step taken by the code is a critical one because
 
255
C         it must reflect how fast the solution changes near the
 
256
C         initial point.  The code automatically selects an initial
 
257
C         step size which is practically always suitable for the
 
258
C         problem.  By using the fact that the code will not step past
 
259
C         TOUT in the first step, you could, if necessary, restrict the
 
260
C         length of the initial step.
 
261
C
 
262
C         For some problems it may not be permissible to integrate
 
263
C         past a point TSTOP, because a discontinuity occurs there
 
264
C         or the solution or its derivative is not defined beyond
 
265
C         TSTOP.  When you have declared a TSTOP point (see INFO(4)
 
266
C         and RWORK(1)), you have told the code not to integrate past
 
267
C         TSTOP.  In this case any tout beyond TSTOP is invalid input.
 
268
C
 
269
C  INFO(*) - Use the INFO array to give the code more details about
 
270
C            how you want your problem solved.  This array should be
 
271
C            dimensioned of length 20, though DDASKR uses only the 
 
272
C            first 15 entries.  You must respond to all of the following
 
273
C            items, which are arranged as questions.  The simplest use
 
274
C            of DDASKR corresponds to setting all entries of INFO to 0.
 
275
C
 
276
C       INFO(1) - This parameter enables the code to initialize itself.
 
277
C              You must set it to indicate the start of every new 
 
278
C              problem.
 
279
C
 
280
C          **** Is this the first call for this problem ...
 
281
C                yes - set INFO(1) = 0
 
282
C                 no - not applicable here.
 
283
C                      See below for continuation calls.  ****
 
284
C
 
285
C       INFO(2) - How much accuracy you want of your solution
 
286
C              is specified by the error tolerances RTOL and ATOL.
 
287
C              The simplest use is to take them both to be scalars.
 
288
C              To obtain more flexibility, they can both be arrays.
 
289
C              The code must be told your choice.
 
290
C
 
291
C          **** Are both error tolerances RTOL, ATOL scalars ...
 
292
C                yes - set INFO(2) = 0
 
293
C                      and input scalars for both RTOL and ATOL
 
294
C                 no - set INFO(2) = 1
 
295
C                      and input arrays for both RTOL and ATOL ****
 
296
C
 
297
C       INFO(3) - The code integrates from T in the direction of TOUT
 
298
C              by steps.  If you wish, it will return the computed
 
299
C              solution and derivative at the next intermediate step
 
300
C              (the intermediate-output mode) or TOUT, whichever comes
 
301
C              first.  This is a good way to proceed if you want to
 
302
C              see the behavior of the solution.  If you must have
 
303
C              solutions at a great many specific TOUT points, this
 
304
C              code will compute them efficiently.
 
305
C
 
306
C          **** Do you want the solution only at
 
307
C               TOUT (and not at the next intermediate step) ...
 
308
C                yes - set INFO(3) = 0 (interval-output mode)
 
309
C                 no - set INFO(3) = 1 (intermediate-output mode) ****
 
310
C
 
311
C       INFO(4) - To handle solutions at a great many specific
 
312
C              values TOUT efficiently, this code may integrate past
 
313
C              TOUT and interpolate to obtain the result at TOUT.
 
314
C              Sometimes it is not possible to integrate beyond some
 
315
C              point TSTOP because the equation changes there or it is
 
316
C              not defined past TSTOP.  Then you must tell the code
 
317
C              this stop condition.
 
318
C
 
319
C           **** Can the integration be carried out without any
 
320
C                restrictions on the independent variable T ...
 
321
C                 yes - set INFO(4) = 0
 
322
C                  no - set INFO(4) = 1
 
323
C                       and define the stopping point TSTOP by
 
324
C                       setting RWORK(1) = TSTOP ****
 
325
C
 
326
C       INFO(5) - used only when INFO(12) = 0 (direct methods).
 
327
C              To solve differential/algebraic systems you may wish
 
328
C              to use a matrix of partial derivatives of the
 
329
C              system of differential equations.  If you do not
 
330
C              provide a subroutine to evaluate it analytically (see
 
331
C              description of the item JAC in the call list), it will
 
332
C              be approximated by numerical differencing in this code.
 
333
C              Although it is less trouble for you to have the code
 
334
C              compute partial derivatives by numerical differencing,
 
335
C              the solution will be more reliable if you provide the
 
336
C              derivatives via JAC.  Usually numerical differencing is
 
337
C              more costly than evaluating derivatives in JAC, but
 
338
C              sometimes it is not - this depends on your problem.
 
339
C
 
340
C           **** Do you want the code to evaluate the partial deriv-
 
341
C                atives automatically by numerical differences ...
 
342
C                 yes - set INFO(5) = 0
 
343
C                  no - set INFO(5) = 1
 
344
C                       and provide subroutine JAC for evaluating the
 
345
C                       matrix of partial derivatives ****
 
346
C
 
347
C       INFO(6) - used only when INFO(12) = 0 (direct methods).
 
348
C              DDASKR will perform much better if the matrix of
 
349
C              partial derivatives, dG/dY + CJ*dG/dYPRIME (here CJ is
 
350
C              a scalar determined by DDASKR), is banded and the code
 
351
C              is told this.  In this case, the storage needed will be
 
352
C              greatly reduced, numerical differencing will be performed
 
353
C              much cheaper, and a number of important algorithms will
 
354
C              execute much faster.  The differential equation is said 
 
355
C              to have half-bandwidths ML (lower) and MU (upper) if 
 
356
C              equation i involves only unknowns Y(j) with
 
357
C                             i-ML .le. j .le. i+MU .
 
358
C              For all i=1,2,...,NEQ.  Thus, ML and MU are the widths
 
359
C              of the lower and upper parts of the band, respectively,
 
360
C              with the main diagonal being excluded.  If you do not
 
361
C              indicate that the equation has a banded matrix of partial
 
362
C              derivatives the code works with a full matrix of NEQ**2
 
363
C              elements (stored in the conventional way).  Computations
 
364
C              with banded matrices cost less time and storage than with
 
365
C              full matrices if  2*ML+MU .lt. NEQ.  If you tell the
 
366
C              code that the matrix of partial derivatives has a banded
 
367
C              structure and you want to provide subroutine JAC to
 
368
C              compute the partial derivatives, then you must be careful
 
369
C              to store the elements of the matrix in the special form
 
370
C              indicated in the description of JAC.
 
371
C
 
372
C          **** Do you want to solve the problem using a full (dense)
 
373
C               matrix (and not a special banded structure) ...
 
374
C                yes - set INFO(6) = 0
 
375
C                 no - set INFO(6) = 1
 
376
C                       and provide the lower (ML) and upper (MU)
 
377
C                       bandwidths by setting
 
378
C                       IWORK(1)=ML
 
379
C                       IWORK(2)=MU ****
 
380
C
 
381
C       INFO(7) - You can specify a maximum (absolute value of)
 
382
C              stepsize, so that the code will avoid passing over very
 
383
C              large regions.
 
384
C
 
385
C          ****  Do you want the code to decide on its own the maximum
 
386
C                stepsize ...
 
387
C                 yes - set INFO(7) = 0
 
388
C                  no - set INFO(7) = 1
 
389
C                       and define HMAX by setting
 
390
C                       RWORK(2) = HMAX ****
 
391
C
 
392
C       INFO(8) -  Differential/algebraic problems may occasionally
 
393
C              suffer from severe scaling difficulties on the first
 
394
C              step.  If you know a great deal about the scaling of 
 
395
C              your problem, you can help to alleviate this problem 
 
396
C              by specifying an initial stepsize H0.
 
397
C
 
398
C          ****  Do you want the code to define its own initial
 
399
C                stepsize ...
 
400
C                 yes - set INFO(8) = 0
 
401
C                  no - set INFO(8) = 1
 
402
C                       and define H0 by setting
 
403
C                       RWORK(3) = H0 ****
 
404
C
 
405
C       INFO(9) -  If storage is a severe problem, you can save some
 
406
C              storage by restricting the maximum method order MAXORD.
 
407
C              The default value is 5.  For each order decrease below 5,
 
408
C              the code requires NEQ fewer locations, but it is likely 
 
409
C              to be slower.  In any case, you must have 
 
410
C              1 .le. MAXORD .le. 5.
 
411
C          ****  Do you want the maximum order to default to 5 ...
 
412
C                 yes - set INFO(9) = 0
 
413
C                  no - set INFO(9) = 1
 
414
C                       and define MAXORD by setting
 
415
C                       IWORK(3) = MAXORD ****
 
416
C
 
417
C       INFO(10) - If you know that certain components of the
 
418
C              solutions to your equations are always nonnegative
 
419
C              (or nonpositive), it may help to set this
 
420
C              parameter.  There are three options that are
 
421
C              available:
 
422
C              1.  To have constraint checking only in the initial
 
423
C                  condition calculation.
 
424
C              2.  To enforce nonnegativity in Y during the integration.
 
425
C              3.  To enforce both options 1 and 2.
 
426
C
 
427
C              When selecting option 2 or 3, it is probably best to try
 
428
C              the code without using this option first, and only use
 
429
C              this option if that does not work very well.
 
430
C
 
431
C          ****  Do you want the code to solve the problem without
 
432
C                invoking any special inequality constraints ...
 
433
C                 yes - set INFO(10) = 0
 
434
C                  no - set INFO(10) = 1 to have option 1 enforced 
 
435
C                  no - set INFO(10) = 2 to have option 2 enforced
 
436
C                  no - set INFO(10) = 3 to have option 3 enforced ****
 
437
C
 
438
C                  If you have specified INFO(10) = 1 or 3, then you
 
439
C                  will also need to identify how each component of Y
 
440
C                  in the initial condition calculation is constrained.
 
441
C                  You must set:
 
442
C                  IWORK(40+I) = +1 if Y(I) must be .GE. 0,
 
443
C                  IWORK(40+I) = +2 if Y(I) must be .GT. 0,
 
444
C                  IWORK(40+I) = -1 if Y(I) must be .LE. 0, while
 
445
C                  IWORK(40+I) = -2 if Y(I) must be .LT. 0, while
 
446
C                  IWORK(40+I) =  0 if Y(I) is not constrained.
 
447
C
 
448
C       INFO(11) - DDASKR normally requires the initial T, Y, and
 
449
C              YPRIME to be consistent.  That is, you must have
 
450
C              G(T,Y,YPRIME) = 0 at the initial T.  If you do not know
 
451
C              the initial conditions precisely, in some cases
 
452
C              DDASKR may be able to compute it.
 
453
C
 
454
C              Denoting the differential variables in Y by Y_d
 
455
C              and the algebraic variables by Y_a, DDASKR can solve
 
456
C              one of two initialization problems:
 
457
C              1.  Given Y_d, calculate Y_a and Y'_d, or
 
458
C              2.  Given Y', calculate Y.
 
459
C              In either case, initial values for the given
 
460
C              components are input, and initial guesses for
 
461
C              the unknown components must also be provided as input.
 
462
C
 
463
C          ****  Are the initial T, Y, YPRIME consistent ...
 
464
C
 
465
C                 yes - set INFO(11) = 0
 
466
C                  no - set INFO(11) = 1 to calculate option 1 above,
 
467
C                    or set INFO(11) = 2 to calculate option 2 ****
 
468
C
 
469
C                  If you have specified INFO(11) = 1, then you
 
470
C                  will also need to identify  which are the
 
471
C                  differential and which are the algebraic
 
472
C                  components (algebraic components are components
 
473
C                  whose derivatives do not appear explicitly
 
474
C                  in the function G(T,Y,YPRIME)).  You must set:
 
475
C                  IWORK(LID+I) = +1 if Y(I) is a differential variable
 
476
C                  IWORK(LID+I) = -1 if Y(I) is an algebraic variable,
 
477
C                  where LID = 40 if INFO(10) = 0 or 2 and LID = 40+NEQ
 
478
C                  if INFO(10) = 1 or 3.
 
479
C
 
480
C       INFO(12) - Except for the addition of the RES argument CJ,
 
481
C              DDASKR by default is downward-compatible with DDASSL,
 
482
C              which uses only direct (dense or band) methods to solve 
 
483
C              the linear systems involved.  You must set INFO(12) to
 
484
C              indicate whether you want the direct methods or the
 
485
C              Krylov iterative method.
 
486
C          ****   Do you want DDASKR to use standard direct methods
 
487
C                 (dense or band) or the Krylov (iterative) method ...
 
488
C                   direct methods - set INFO(12) = 0.
 
489
C                   Krylov method  - set INFO(12) = 1,
 
490
C                       and check the settings of INFO(13) and INFO(15).
 
491
C
 
492
C       INFO(13) - used when INFO(12) = 1 (Krylov methods).  
 
493
C              DDASKR uses scalars MAXL, KMP, NRMAX, and EPLI for the
 
494
C              iterative solution of linear systems.  INFO(13) allows 
 
495
C              you to override the default values of these parameters.  
 
496
C              These parameters and their defaults are as follows:
 
497
C              MAXL = maximum number of iterations in the SPIGMR 
 
498
C                 algorithm (MAXL .le. NEQ).  The default is 
 
499
C                 MAXL = MIN(5,NEQ).
 
500
C              KMP = number of vectors on which orthogonalization is 
 
501
C                 done in the SPIGMR algorithm.  The default is 
 
502
C                 KMP = MAXL, which corresponds to complete GMRES 
 
503
C                 iteration, as opposed to the incomplete form.  
 
504
C              NRMAX = maximum number of restarts of the SPIGMR 
 
505
C                 algorithm per nonlinear iteration.  The default is
 
506
C                 NRMAX = 5.
 
507
C              EPLI = convergence test constant in SPIGMR algorithm.
 
508
C                 The default is EPLI = 0.05.
 
509
C              Note that the length of RWORK depends on both MAXL 
 
510
C              and KMP.  See the definition of LRW below.
 
511
C          ****   Are MAXL, KMP, and EPLI to be given their
 
512
C                 default values ...
 
513
C                  yes - set INFO(13) = 0
 
514
C                   no - set INFO(13) = 1,
 
515
C                        and set all of the following:
 
516
C                        IWORK(24) = MAXL (1 .le. MAXL .le. NEQ)
 
517
C                        IWORK(25) = KMP  (1 .le. KMP .le. MAXL)
 
518
C                        IWORK(26) = NRMAX  (NRMAX .ge. 0)
 
519
C                        RWORK(10) = EPLI (0 .lt. EPLI .lt. 1.0) ****
 
520
C
 
521
C        INFO(14) - used with INFO(11) > 0 (initial condition 
 
522
C               calculation is requested).  In this case, you may
 
523
C               request control to be returned to the calling program
 
524
C               immediately after the initial condition calculation,
 
525
C               before proceeding to the integration of the system
 
526
C               (e.g. to examine the computed Y and YPRIME).
 
527
C               If this is done, and if the initialization succeeded
 
528
C               (IDID = 4), you should reset INFO(11) to 0 for the
 
529
C               next call, to prevent the solver from repeating the 
 
530
C               initialization (and to avoid an infinite loop). 
 
531
C          ****   Do you want to proceed to the integration after
 
532
C                 the initial condition calculation is done ...
 
533
C                 yes - set INFO(14) = 0
 
534
C                  no - set INFO(14) = 1                        ****
 
535
C
 
536
C        INFO(15) - used when INFO(12) = 1 (Krylov methods).
 
537
C               When using preconditioning in the Krylov method,
 
538
C               you must supply a subroutine, PSOL, which solves the
 
539
C               associated linear systems using P.
 
540
C               The usage of DDASKR is simpler if PSOL can carry out
 
541
C               the solution without any prior calculation of data.
 
542
C               However, if some partial derivative data is to be
 
543
C               calculated in advance and used repeatedly in PSOL,
 
544
C               then you must supply a JAC routine to do this,
 
545
C               and set INFO(15) to indicate that JAC is to be called
 
546
C               for this purpose.  For example, P might be an
 
547
C               approximation to a part of the matrix A which can be
 
548
C               calculated and LU-factored for repeated solutions of
 
549
C               the preconditioner system.  The arrays WP and IWP
 
550
C               (described under JAC and PSOL) can be used to
 
551
C               communicate data between JAC and PSOL.
 
552
C          ****   Does PSOL operate with no prior preparation ...
 
553
C                 yes - set INFO(15) = 0 (no JAC routine)
 
554
C                  no - set INFO(15) = 1
 
555
C                       and supply a JAC routine to evaluate and
 
556
C                       preprocess any required Jacobian data.  ****
 
557
C
 
558
C         INFO(16) - option to exclude algebraic variables from
 
559
C               the error test.  
 
560
C          ****   Do you wish to control errors locally on
 
561
C                 all the variables...
 
562
C                 yes - set INFO(16) = 0
 
563
C                  no - set INFO(16) = 1
 
564
C                       If you have specified INFO(16) = 1, then you
 
565
C                       will also need to identify  which are the
 
566
C                       differential and which are the algebraic
 
567
C                       components (algebraic components are components
 
568
C                       whose derivatives do not appear explicitly
 
569
C                       in the function G(T,Y,YPRIME)).  You must set:
 
570
C                       IWORK(LID+I) = +1 if Y(I) is a differential 
 
571
C                                      variable, and
 
572
C                       IWORK(LID+I) = -1 if Y(I) is an algebraic
 
573
C                                      variable,
 
574
C                       where LID = 40 if INFO(10) = 0 or 2 and 
 
575
C                       LID = 40 + NEQ if INFO(10) = 1 or 3.
 
576
C
 
577
C       INFO(17) - used when INFO(11) > 0 (DDASKR is to do an 
 
578
C              initial condition calculation).
 
579
C              DDASKR uses several heuristic control quantities in the
 
580
C              initial condition calculation.  They have default values,
 
581
C              but can  also be set by the user using INFO(17).
 
582
C              These parameters and their defaults are as follows:
 
583
C              MXNIT  = maximum number of Newton iterations
 
584
C                 per Jacobian or preconditioner evaluation.
 
585
C                 The default is:
 
586
C                 MXNIT =  5 in the direct case (INFO(12) = 0), and
 
587
C                 MXNIT = 15 in the Krylov case (INFO(12) = 1).
 
588
C              MXNJ   = maximum number of Jacobian or preconditioner
 
589
C                 evaluations.  The default is:
 
590
C                 MXNJ = 6 in the direct case (INFO(12) = 0), and
 
591
C                 MXNJ = 2 in the Krylov case (INFO(12) = 1).
 
592
C              MXNH   = maximum number of values of the artificial
 
593
C                 stepsize parameter H to be tried if INFO(11) = 1.
 
594
C                 The default is MXNH = 5.
 
595
C                 NOTE: the maximum number of Newton iterations
 
596
C                 allowed in all is MXNIT*MXNJ*MXNH if INFO(11) = 1,
 
597
C                 and MXNIT*MXNJ if INFO(11) = 2.
 
598
C              LSOFF  = flag to turn off the linesearch algorithm
 
599
C                 (LSOFF = 0 means linesearch is on, LSOFF = 1 means
 
600
C                 it is turned off).  The default is LSOFF = 0.
 
601
C              STPTOL = minimum scaled step in linesearch algorithm.
 
602
C                 The default is STPTOL = (unit roundoff)**(2/3).
 
603
C              EPINIT = swing factor in the Newton iteration convergence
 
604
C                 test.  The test is applied to the residual vector,
 
605
C                 premultiplied by the approximate Jacobian (in the
 
606
C                 direct case) or the preconditioner (in the Krylov
 
607
C                 case).  For convergence, the weighted RMS norm of
 
608
C                 this vector (scaled by the error weights) must be
 
609
C                 less than EPINIT*EPCON, where EPCON = .33 is the
 
610
C                 analogous test constant used in the time steps.
 
611
C                 The default is EPINIT = .01.
 
612
C          ****   Are the initial condition heuristic controls to be 
 
613
C                 given their default values...
 
614
C                  yes - set INFO(17) = 0
 
615
C                   no - set INFO(17) = 1,
 
616
C                        and set all of the following:
 
617
C                        IWORK(32) = MXNIT (.GT. 0)
 
618
C                        IWORK(33) = MXNJ (.GT. 0)
 
619
C                        IWORK(34) = MXNH (.GT. 0)
 
620
C                        IWORK(35) = LSOFF ( = 0 or 1)
 
621
C                        RWORK(14) = STPTOL (.GT. 0.0)
 
622
C                        RWORK(15) = EPINIT (.GT. 0.0)  ****
 
623
C
 
624
C         INFO(18) - option to get extra printing in initial condition 
 
625
C                calculation.
 
626
C          ****   Do you wish to have extra printing...
 
627
C                 no  - set INFO(18) = 0
 
628
C                 yes - set INFO(18) = 1 for minimal printing, or
 
629
C                       set INFO(18) = 2 for full printing.
 
630
C                       If you have specified INFO(18) .ge. 1, data
 
631
C                       will be printed with the error handler routines.
 
632
C                       To print to a non-default unit number L, include
 
633
C                       the line  CALL XSETUN(L)  in your program.  ****
 
634
C
 
635
C   RTOL, ATOL -- You must assign relative (RTOL) and absolute (ATOL)
 
636
C               error tolerances to tell the code how accurately you
 
637
C               want the solution to be computed.  They must be defined
 
638
C               as variables because the code may change them.
 
639
C               you have two choices --
 
640
C                     Both RTOL and ATOL are scalars (INFO(2) = 0), or
 
641
C                     both RTOL and ATOL are vectors (INFO(2) = 1).
 
642
C               In either case all components must be non-negative.
 
643
C
 
644
C               The tolerances are used by the code in a local error
 
645
C               test at each step which requires roughly that
 
646
C                        abs(local error in Y(i)) .le. EWT(i) ,
 
647
C               where EWT(i) = RTOL*abs(Y(i)) + ATOL is an error weight 
 
648
C               quantity, for each vector component.
 
649
C               (More specifically, a root-mean-square norm is used to
 
650
C               measure the size of vectors, and the error test uses the
 
651
C               magnitude of the solution at the beginning of the step.)
 
652
C
 
653
C               The true (global) error is the difference between the
 
654
C               true solution of the initial value problem and the
 
655
C               computed approximation.  Practically all present day
 
656
C               codes, including this one, control the local error at
 
657
C               each step and do not even attempt to control the global
 
658
C               error directly.
 
659
C
 
660
C               Usually, but not always, the true accuracy of
 
661
C               the computed Y is comparable to the error tolerances.
 
662
C               This code will usually, but not always, deliver a more
 
663
C               accurate solution if you reduce the tolerances and
 
664
C               integrate again.  By comparing two such solutions you 
 
665
C               can get a fairly reliable idea of the true error in the
 
666
C               solution at the larger tolerances.
 
667
C
 
668
C               Setting ATOL = 0. results in a pure relative error test
 
669
C               on that component.  Setting RTOL = 0. results in a pure
 
670
C               absolute error test on that component.  A mixed test
 
671
C               with non-zero RTOL and ATOL corresponds roughly to a
 
672
C               relative error test when the solution component is
 
673
C               much bigger than ATOL and to an absolute error test
 
674
C               when the solution component is smaller than the
 
675
C               threshold ATOL.
 
676
C
 
677
C               The code will not attempt to compute a solution at an
 
678
C               accuracy unreasonable for the machine being used.  It
 
679
C               will advise you if you ask for too much accuracy and
 
680
C               inform you as to the maximum accuracy it believes
 
681
C               possible.
 
682
C
 
683
C  RWORK(*) -- a real work array, which should be dimensioned in your
 
684
C               calling program with a length equal to the value of
 
685
C               LRW (or greater).
 
686
C
 
687
C  LRW -- Set it to the declared length of the RWORK array.  The
 
688
C               minimum length depends on the options you have selected,
 
689
C               given by a base value plus additional storage as
 
690
C               described below.
 
691
C
 
692
C               If INFO(12) = 0 (standard direct method), the base value
 
693
C               is BASE = 60 + max(MAXORD+4,7)*NEQ + 3*NRT.
 
694
C               The default value is MAXORD = 5 (see INFO(9)).  With the
 
695
C               default MAXORD, BASE = 60 + 9*NEQ + 3*NRT.
 
696
C               Additional storage must be added to the base value for
 
697
C               any or all of the following options:
 
698
C                 If INFO(6) = 0 (dense matrix), add NEQ**2.
 
699
C                 If INFO(6) = 1 (banded matrix), then:
 
700
C                    if INFO(5) = 0, add (2*ML+MU+1)*NEQ
 
701
C                                           + 2*[NEQ/(ML+MU+1) + 1], and
 
702
C                    if INFO(5) = 1, add (2*ML+MU+1)*NEQ.
 
703
C                 If INFO(16) = 1, add NEQ.
 
704
C
 
705
C               If INFO(12) = 1 (Krylov method), the base value is
 
706
C               BASE = 60 + (MAXORD+5)*NEQ + 3*NRT
 
707
C                         + [MAXL + 3 + min(1,MAXL-KMP)]*NEQ
 
708
C                         + (MAXL+3)*MAXL + 1 + LENWP.
 
709
C               See PSOL for description of LENWP.  The default values
 
710
C               are: MAXORD = 5 (see INFO(9)), MAXL = min(5,NEQ) and
 
711
C               KMP = MAXL  (see INFO(13)).  With these default values,
 
712
C               BASE = 101 + 18*NEQ + 3*NRT + LENWP.
 
713
C               Additional storage must be added to the base value for
 
714
C               the following option:
 
715
C                 If INFO(16) = 1, add NEQ.
 
716
C
 
717
C
 
718
C  IWORK(*) -- an integer work array, which should be dimensioned in
 
719
C              your calling program with a length equal to the value
 
720
C              of LIW (or greater).
 
721
C
 
722
C  LIW -- Set it to the declared length of the IWORK array.  The
 
723
C             minimum length depends on the options you have selected,
 
724
C             given by a base value plus additions as described below.
 
725
C
 
726
C             If INFO(12) = 0 (standard direct method), the base value
 
727
C             is BASE = 40 + NEQ.
 
728
C             IF INFO(10) = 1 or 3, add NEQ to the base value.
 
729
C             If INFO(11) = 1 or INFO(16) =1, add NEQ to the base value.
 
730
C
 
731
C             If INFO(12) = 1 (Krylov method), the base value is
 
732
C             BASE = 40 + LENIWP.  See PSOL for description of LENIWP.
 
733
C             If INFO(10) = 1 or 3, add NEQ to the base value.
 
734
C             If INFO(11) = 1 or INFO(16) =1, add NEQ to the base value.
 
735
C            >> Due to introduction of Mask in DASKR, NRT has been added 
 
736
c             to the  LIW
 
737
C
 
738
c
 
739
C  RPAR, IPAR -- These are arrays of double precision and integer type,
 
740
C             respectively, which are available for you to use
 
741
C             for communication between your program that calls
 
742
C             DDASKR and the RES subroutine (and the JAC and PSOL
 
743
C             subroutines).  They are not altered by DDASKR.
 
744
C             If you do not need RPAR or IPAR, ignore these
 
745
C             parameters by treating them as dummy arguments.
 
746
C             If you do choose to use them, dimension them in
 
747
C             your calling program and in RES (and in JAC and PSOL)
 
748
C             as arrays of appropriate length.
 
749
C
 
750
C  JAC -- This is the name of a routine that you may supply
 
751
C         (optionally) that relates to the Jacobian matrix of the
 
752
C         nonlinear system that the code must solve at each T step.
 
753
C         The role of JAC (and its call sequence) depends on whether
 
754
C         a direct (INFO(12) = 0) or Krylov (INFO(12) = 1) method 
 
755
C         is selected.
 
756
C
 
757
C         **** INFO(12) = 0 (direct methods):
 
758
C           If you are letting the code generate partial derivatives
 
759
C           numerically (INFO(5) = 0), then JAC can be absent
 
760
C           (or perhaps a dummy routine to satisfy the loader).
 
761
C           Otherwise you must supply a JAC routine to compute
 
762
C           the matrix A = dG/dY + CJ*dG/dYPRIME.  It must have
 
763
C           the form
 
764
C
 
765
C           SUBROUTINE JAC (T, Y, YPRIME, PD, CJ, RPAR, IPAR)
 
766
C
 
767
C           The JAC routine must dimension Y, YPRIME, and PD (and RPAR
 
768
C           and IPAR if used).  CJ is a scalar which is input to JAC.
 
769
C           For the given values of T, Y, and YPRIME, the JAC routine
 
770
C           must evaluate the nonzero elements of the matrix A, and 
 
771
C           store these values in the array PD.  The elements of PD are 
 
772
C           set to zero before each call to JAC, so that only nonzero
 
773
C           elements need to be defined.
 
774
C           The way you store the elements into the PD array depends
 
775
C           on the structure of the matrix indicated by INFO(6).
 
776
C           *** INFO(6) = 0 (full or dense matrix) ***
 
777
C               Give PD a first dimension of NEQ.  When you evaluate the
 
778
C               nonzero partial derivatives of equation i (i.e. of G(i))
 
779
C               with respect to component j (of Y and YPRIME), you must
 
780
C               store the element in PD according to
 
781
C                  PD(i,j) = dG(i)/dY(j) + CJ*dG(i)/dYPRIME(j).
 
782
C           *** INFO(6) = 1 (banded matrix with half-bandwidths ML, MU
 
783
C                            as described under INFO(6)) ***
 
784
C               Give PD a first dimension of 2*ML+MU+1.  When you 
 
785
C               evaluate the nonzero partial derivatives of equation i 
 
786
C               (i.e. of G(i)) with respect to component j (of Y and 
 
787
C               YPRIME), you must store the element in PD according to 
 
788
C                  IROW = i - j + ML + MU + 1
 
789
C                  PD(IROW,j) = dG(i)/dY(j) + CJ*dG(i)/dYPRIME(j).
 
790
C
 
791
C          **** INFO(12) = 1 (Krylov method):
 
792
C            If you are not calculating Jacobian data in advance for use
 
793
C            in PSOL (INFO(15) = 0), JAC can be absent (or perhaps a
 
794
C            dummy routine to satisfy the loader).  Otherwise, you may
 
795
C            supply a JAC routine to compute and preprocess any parts of
 
796
C            of the Jacobian matrix  A = dG/dY + CJ*dG/dYPRIME that are
 
797
C            involved in the preconditioner matrix P.
 
798
C            It is to have the form
 
799
C
 
800
C            SUBROUTINE JAC (RES, IRES, NEQ, T, Y, YPRIME, REWT, SAVR,
 
801
C                            WK, H, CJ, WP, IWP, IER, RPAR, IPAR)
 
802
C
 
803
C           The JAC routine must dimension Y, YPRIME, REWT, SAVR, WK,
 
804
C           and (if used) WP, IWP, RPAR, and IPAR.
 
805
C           The Y, YPRIME, and SAVR arrays contain the current values
 
806
C           of Y, YPRIME, and the residual G, respectively.  
 
807
C           The array WK is work space of length NEQ.  
 
808
C           H is the step size.  CJ is a scalar, input to JAC, that is
 
809
C           normally proportional to 1/H.  REWT is an array of 
 
810
C           reciprocal error weights, 1/EWT(i), where EWT(i) is
 
811
C           RTOL*abs(Y(i)) + ATOL (unless you supplied routine DDAWTS
 
812
C           instead), for use in JAC if needed.  For example, if JAC
 
813
C           computes difference quotient approximations to partial
 
814
C           derivatives, the REWT array may be useful in setting the
 
815
C           increments used.  The JAC routine should do any
 
816
C           factorization operations called for, in preparation for
 
817
C           solving linear systems in PSOL.  The matrix P should
 
818
C           be an approximation to the Jacobian,
 
819
C           A = dG/dY + CJ*dG/dYPRIME.
 
820
C
 
821
C           WP and IWP are real and integer work arrays which you may
 
822
C           use for communication between your JAC routine and your
 
823
C           PSOL routine.  These may be used to store elements of the 
 
824
C           preconditioner P, or related matrix data (such as factored
 
825
C           forms).  They are not altered by DDASKR.
 
826
C           If you do not need WP or IWP, ignore these parameters by
 
827
C           treating them as dummy arguments.  If you do use them,
 
828
C           dimension them appropriately in your JAC and PSOL routines.
 
829
C           See the PSOL description for instructions on setting 
 
830
C           the lengths of WP and IWP.
 
831
C
 
832
C           On return, JAC should set the error flag IER as follows..
 
833
C             IER = 0    if JAC was successful,
 
834
C             IER .ne. 0 if JAC was unsuccessful (e.g. if Y or YPRIME
 
835
C                        was illegal, or a singular matrix is found).
 
836
C           (If IER .ne. 0, a smaller stepsize will be tried.)
 
837
C           IER = 0 on entry to JAC, so need be reset only on a failure.
 
838
C           If RES is used within JAC, then a nonzero value of IRES will
 
839
C           override any nonzero value of IER (see the RES description).
 
840
C
 
841
C         Regardless of the method type, subroutine JAC must not
 
842
C         alter T, Y(*), YPRIME(*), H, CJ, or REWT(*).
 
843
C         You must declare the name JAC in an EXTERNAL statement in
 
844
C         your program that calls DDASKR.
 
845
C
 
846
C PSOL --  This is the name of a routine you must supply if you have
 
847
C         selected a Krylov method (INFO(12) = 1) with preconditioning.
 
848
C         In the direct case (INFO(12) = 0), PSOL can be absent 
 
849
C         (a dummy routine may have to be supplied to satisfy the 
 
850
C         loader).  Otherwise, you must provide a PSOL routine to 
 
851
C         solve linear systems arising from preconditioning.
 
852
C         When supplied with INFO(12) = 1, the PSOL routine is to 
 
853
C         have the form
 
854
C
 
855
C         SUBROUTINE PSOL (NEQ, T, Y, YPRIME, SAVR, WK, CJ, WGHT,
 
856
C                          WP, IWP, B, EPLIN, IER, RPAR, IPAR)
 
857
C
 
858
C         The PSOL routine must solve linear systems of the form 
 
859
C         P*x = b where P is the left preconditioner matrix.
 
860
C
 
861
C         The right-hand side vector b is in the B array on input, and
 
862
C         PSOL must return the solution vector x in B.
 
863
C         The Y, YPRIME, and SAVR arrays contain the current values
 
864
C         of Y, YPRIME, and the residual G, respectively.  
 
865
C
 
866
C         Work space required by JAC and/or PSOL, and space for data to
 
867
C         be communicated from JAC to PSOL is made available in the form
 
868
C         of arrays WP and IWP, which are parts of the RWORK and IWORK
 
869
C         arrays, respectively.  The lengths of these real and integer
 
870
C         work spaces WP and IWP must be supplied in LENWP and LENIWP,
 
871
C         respectively, as follows..
 
872
C           IWORK(27) = LENWP = length of real work space WP
 
873
C           IWORK(28) = LENIWP = length of integer work space IWP.
 
874
C
 
875
C         WK is a work array of length NEQ for use by PSOL.
 
876
C         CJ is a scalar, input to PSOL, that is normally proportional
 
877
C         to 1/H (H = stepsize).  If the old value of CJ
 
878
C         (at the time of the last JAC call) is needed, it must have
 
879
C         been saved by JAC in WP.
 
880
C
 
881
C         WGHT is an array of weights, to be used if PSOL uses an
 
882
C         iterative method and performs a convergence test.  (In terms
 
883
C         of the argument REWT to JAC, WGHT is REWT/sqrt(NEQ).)
 
884
C         If PSOL uses an iterative method, it should use EPLIN
 
885
C         (a heuristic parameter) as the bound on the weighted norm of
 
886
C         the residual for the computed solution.  Specifically, the
 
887
C         residual vector R should satisfy
 
888
C              SQRT (SUM ( (R(i)*WGHT(i))**2 ) ) .le. EPLIN
 
889
C
 
890
C         PSOL must not alter NEQ, T, Y, YPRIME, SAVR, CJ, WGHT, EPLIN.
 
891
C
 
892
C         On return, PSOL should set the error flag IER as follows..
 
893
C           IER = 0 if PSOL was successful,
 
894
C           IER .lt. 0 if an unrecoverable error occurred, meaning
 
895
C                 control will be passed to the calling routine,
 
896
C           IER .gt. 0 if a recoverable error occurred, meaning that
 
897
C                 the step will be retried with the same step size
 
898
C                 but with a call to JAC to update necessary data,
 
899
C                 unless the Jacobian data is current, in which case
 
900
C                 the step will be retried with a smaller step size.
 
901
C           IER = 0 on entry to PSOL so need be reset only on a failure.
 
902
C
 
903
C         You must declare the name PSOL in an EXTERNAL statement in
 
904
C         your program that calls DDASKR.
 
905
C
 
906
C RT --   This is the name of the subroutine for defining the vector
 
907
C         R(T,Y,Y') of constraint functions Ri(T,Y,Y'), whose roots
 
908
C         are desired during the integration.  It is to have the form
 
909
C             SUBROUTINE RT(NEQ, T, Y, YP, NRT, RVAL, RPAR, IPAR)
 
910
C             DIMENSION Y(NEQ), YP(NEQ), RVAL(NRT),
 
911
C         where NEQ, T, Y and NRT are INPUT, and the array RVAL is
 
912
C         output.  NEQ, T, Y, and YP have the same meaning as in the
 
913
C         RES routine, and RVAL is an array of length NRT.
 
914
C         For i = 1,...,NRT, this routine is to load into RVAL(i) the
 
915
C         value at (T,Y,Y') of the i-th constraint function Ri(T,Y,Y').
 
916
C         DDASKR will find roots of the Ri of odd multiplicity
 
917
C         (that is, sign changes) as they occur during the integration.
 
918
C         RT must be declared EXTERNAL in the calling program.
 
919
C
 
920
C         CAUTION.. Because of numerical errors in the functions Ri
 
921
C         due to roundoff and integration error, DDASKR may return
 
922
C         false roots, or return the same root at two or more nearly
 
923
C         equal values of T.  If such false roots are suspected,
 
924
C         the user should consider smaller error tolerances and/or
 
925
C         higher precision in the evaluation of the Ri.
 
926
C
 
927
C         If a root of some Ri defines the end of the problem,
 
928
C         the input to DDASKR should nevertheless allow
 
929
C         integration to a point slightly past that root, so
 
930
C         that DDASKR can locate the root by interpolation.
 
931
C
 
932
C NRT --  The number of constraint functions Ri(T,Y,Y').  If there are
 
933
C         no constraints, set NRT = 0 and pass a dummy name for RT.
 
934
C
 
935
C JROOT -- This is an integer array of length NRT, used only for output.
 
936
C         On a return where one or more roots were found (IDID = 5),
 
937
C         JROOT(i) = 1 or -1 if Ri(T,Y,Y') has a root at T, and
 
938
C         JROOT(i) = 0 if not.  If nonzero, JROOT(i) shows the direction
 
939
C         of the sign change in Ri in the direction of integration: 
 
940
C         JROOT(i) = 1  means Ri changed from negative to positive.
 
941
C         JROOT(i) = -1 means Ri changed from positive to negative.
 
942
C
 
943
C
 
944
C  OPTIONALLY REPLACEABLE SUBROUTINE:
 
945
C
 
946
C  DDASKR uses a weighted root-mean-square norm to measure the 
 
947
C  size of various error vectors.  The weights used in this norm
 
948
C  are set in the following subroutine:
 
949
C
 
950
C    SUBROUTINE DDAWTS1 (NEQ, IWT, RTOL, ATOL, Y, EWT, RPAR, IPAR)
 
951
C    DIMENSION RTOL(*), ATOL(*), Y(*), EWT(*), RPAR(*), IPAR(*)
 
952
C
 
953
C  A DDAWTS routine has been included with DDASKR which sets the
 
954
C  weights according to
 
955
C    EWT(I) = RTOL*ABS(Y(I)) + ATOL
 
956
C  in the case of scalar tolerances (IWT = 0) or
 
957
C    EWT(I) = RTOL(I)*ABS(Y(I)) + ATOL(I)
 
958
C  in the case of array tolerances (IWT = 1).  (IWT is INFO(2).)
 
959
C  In some special cases, it may be appropriate for you to define
 
960
C  your own error weights by writing a subroutine DDAWTS to be 
 
961
C  called instead of the version supplied.  However, this should 
 
962
C  be attempted only after careful thought and consideration. 
 
963
C  If you supply this routine, you may use the tolerances and Y 
 
964
C  as appropriate, but do not overwrite these variables.  You
 
965
C  may also use RPAR and IPAR to communicate data as appropriate.
 
966
C  ***Note: Aside from the values of the weights, the choice of 
 
967
C  norm used in DDASKR (weighted root-mean-square) is not subject
 
968
C  to replacement by the user.  In this respect, DDASKR is not
 
969
C  downward-compatible with the original DDASSL solver (in which
 
970
C  the norm routine was optionally user-replaceable).
 
971
C
 
972
C
 
973
C------OUTPUT - AFTER ANY RETURN FROM DDASKR----------------------------
 
974
C
 
975
C  The principal aim of the code is to return a computed solution at
 
976
C  T = TOUT, although it is also possible to obtain intermediate
 
977
C  results along the way.  To find out whether the code achieved its
 
978
C  goal or if the integration process was interrupted before the task
 
979
C  was completed, you must check the IDID parameter.
 
980
C
 
981
C
 
982
C   T -- The output value of T is the point to which the solution
 
983
C        was successfully advanced.
 
984
C
 
985
C   Y(*) -- contains the computed solution approximation at T.
 
986
C
 
987
C   YPRIME(*) -- contains the computed derivative approximation at T.
 
988
C
 
989
C   IDID -- reports what the code did, described as follows:
 
990
C
 
991
C                     *** TASK COMPLETED ***
 
992
C                Reported by positive values of IDID
 
993
C
 
994
C           IDID = 1 -- A step was successfully taken in the
 
995
C                   interval-output mode.  The code has not
 
996
C                   yet reached TOUT.
 
997
C
 
998
C           IDID = 2 -- The integration to TSTOP was successfully
 
999
C                   completed (T = TSTOP) by stepping exactly to TSTOP.
 
1000
C
 
1001
C           IDID = 3 -- The integration to TOUT was successfully
 
1002
C                   completed (T = TOUT) by stepping past TOUT.
 
1003
C                   Y(*) and YPRIME(*) are obtained by interpolation.
 
1004
C
 
1005
C           IDID = 4 -- The initial condition calculation, with
 
1006
C                   INFO(11) > 0, was successful, and INFO(14) = 1.
 
1007
C                   No integration steps were taken, and the solution
 
1008
C                   is not considered to have been started.
 
1009
C
 
1010
C           IDID = 5 -- The integration was successfully completed
 
1011
C                   by finding one or more roots of R(T,Y,Y') at T.
 
1012
C           IDID = 6 -- The integration was successfully completed
 
1013
C                   by finding A ROOT, LIFTED FROM ZERO.
 
1014
c
 
1015
c
 
1016
C                    *** TASK INTERRUPTED ***
 
1017
C                Reported by negative values of IDID
 
1018
C
 
1019
C           IDID = -1 -- A large amount of work has been expended
 
1020
C                     (about 500 steps).
 
1021
C
 
1022
C           IDID = -2 -- The error tolerances are too stringent.
 
1023
C
 
1024
C           IDID = -3 -- The local error test cannot be satisfied
 
1025
C                     because you specified a zero component in ATOL
 
1026
C                     and the corresponding computed solution component
 
1027
C                     is zero.  Thus, a pure relative error test is
 
1028
C                     impossible for this component.
 
1029
C
 
1030
C           IDID = -5 -- There were repeated failures in the evaluation
 
1031
C                     or processing of the preconditioner (in JAC).
 
1032
C
 
1033
C           IDID = -6 -- DDASKR had repeated error test failures on the
 
1034
C                     last attempted step.
 
1035
C
 
1036
C           IDID = -7 -- The nonlinear system solver in the time
 
1037
C                     integration could not converge.
 
1038
C
 
1039
C           IDID = -8 -- The matrix of partial derivatives appears
 
1040
C                     to be singular (direct method).
 
1041
C
 
1042
C           IDID = -9 -- The nonlinear system solver in the integration
 
1043
C                     failed to achieve convergence, and there were
 
1044
C                     repeated  error test failures in this step.
 
1045
C
 
1046
C           IDID =-10 -- The nonlinear system solver in the integration 
 
1047
C                     failed to achieve convergence because IRES was
 
1048
C                     equal  to -1.
 
1049
C
 
1050
C           IDID =-11 -- IRES = -2 was encountered and control is
 
1051
C                     being returned to the calling program.
 
1052
C
 
1053
C           IDID =-12 -- DDASKR failed to compute the initial Y, YPRIME.
 
1054
C
 
1055
C           IDID =-13 -- An unrecoverable error was encountered inside
 
1056
C                     the user's PSOL routine, and control is being
 
1057
C                     returned to the calling program.
 
1058
C
 
1059
C           IDID =-14 -- The Krylov linear system solver could not 
 
1060
C                     achieve convergence.
 
1061
C
 
1062
c
 
1063
C           IDID =-15,..,-32 -- Not applicable for this code.
 
1064
c
 
1065
C
 
1066
C                    *** TASK TERMINATED ***
 
1067
C                reported by the value of IDID=-33
 
1068
C
 
1069
C           IDID = -33 -- The code has encountered trouble from which
 
1070
C                   it cannot recover.  A message is printed
 
1071
C                   explaining the trouble and control is returned
 
1072
C                   to the calling program.  For example, this occurs
 
1073
C                   when invalid input is detected.
 
1074
C
 
1075
C   RTOL, ATOL -- these quantities remain unchanged except when
 
1076
C               IDID = -2.  In this case, the error tolerances have been
 
1077
C               increased by the code to values which are estimated to
 
1078
C               be appropriate for continuing the integration.  However,
 
1079
C               the reported solution at T was obtained using the input
 
1080
C               values of RTOL and ATOL.
 
1081
C
 
1082
C   RWORK, IWORK -- contain information which is usually of no interest
 
1083
C               to the user but necessary for subsequent calls. 
 
1084
C               However, you may be interested in the performance data
 
1085
C               listed below.  These quantities are accessed in RWORK 
 
1086
C               and IWORK but have internal mnemonic names, as follows..
 
1087
C
 
1088
C               RWORK(3)--contains H, the step size h to be attempted
 
1089
C                        on the next step.
 
1090
C
 
1091
C               RWORK(4)--contains TN, the current value of the
 
1092
C                        independent variable, i.e. the farthest point
 
1093
C                        integration has reached.  This will differ 
 
1094
C                        from T if interpolation has been performed 
 
1095
C                        (IDID = 3).
 
1096
C
 
1097
C               RWORK(7)--contains HOLD, the stepsize used on the last
 
1098
C                        successful step.  If INFO(11) = INFO(14) = 1,
 
1099
C                        this contains the value of H used in the
 
1100
C                        initial condition calculation.
 
1101
C
 
1102
C               IWORK(7)--contains K, the order of the method to be 
 
1103
C                        attempted on the next step.
 
1104
C
 
1105
C               IWORK(8)--contains KOLD, the order of the method used
 
1106
C                        on the last step.
 
1107
C
 
1108
C               IWORK(11)--contains NST, the number of steps (in T) 
 
1109
C                        taken so far.
 
1110
C
 
1111
C               IWORK(12)--contains NRE, the number of calls to RES 
 
1112
C                        so far.
 
1113
C
 
1114
C               IWORK(13)--contains NJE, the number of calls to JAC so
 
1115
C                        far (Jacobian or preconditioner evaluations).
 
1116
C
 
1117
C               IWORK(14)--contains NETF, the total number of error test
 
1118
C                        failures so far.
 
1119
C
 
1120
C               IWORK(15)--contains NCFN, the total number of nonlinear
 
1121
C                        convergence failures so far (includes counts
 
1122
C                        of singular iteration matrix or singular
 
1123
C                        preconditioners).
 
1124
C
 
1125
C               IWORK(16)--contains NCFL, the number of convergence
 
1126
C                        failures of the linear iteration so far.
 
1127
C
 
1128
C               IWORK(17)--contains LENIW, the length of IWORK actually
 
1129
C                        required.  This is defined on normal returns 
 
1130
C                        and on an illegal input return for
 
1131
C                        insufficient storage.
 
1132
C
 
1133
C               IWORK(18)--contains LENRW, the length of RWORK actually
 
1134
C                        required.  This is defined on normal returns 
 
1135
C                        and on an illegal input return for
 
1136
C                        insufficient storage.
 
1137
C
 
1138
C               IWORK(19)--contains NNI, the total number of nonlinear
 
1139
C                        iterations so far (each of which calls a
 
1140
C                        linear solver).
 
1141
C
 
1142
C               IWORK(20)--contains NLI, the total number of linear
 
1143
C                        (Krylov) iterations so far.
 
1144
C
 
1145
C               IWORK(21)--contains NPS, the number of PSOL calls so
 
1146
C                        far, for preconditioning solve operations or
 
1147
C                        for solutions with the user-supplied method.
 
1148
C
 
1149
C               IWORK(36)--contains the total number of calls to the
 
1150
C                        constraint function routine RT so far.
 
1151
C
 
1152
C               Note: The various counters in IWORK do not include 
 
1153
C               counts during a prior call made with INFO(11) > 0 and
 
1154
C               INFO(14) = 1.
 
1155
C
 
1156
C
 
1157
C------INPUT - WHAT TO DO TO CONTINUE THE INTEGRATION  -----------------
 
1158
C              (CALLS AFTER THE FIRST)
 
1159
C
 
1160
C     This code is organized so that subsequent calls to continue the
 
1161
C     integration involve little (if any) additional effort on your
 
1162
C     part.  You must monitor the IDID parameter in order to determine
 
1163
C     what to do next.
 
1164
C
 
1165
C     Recalling that the principal task of the code is to integrate
 
1166
C     from T to TOUT (the interval mode), usually all you will need
 
1167
C     to do is specify a new TOUT upon reaching the current TOUT.
 
1168
C
 
1169
C     Do not alter any quantity not specifically permitted below.  In
 
1170
C     particular do not alter NEQ, T, Y(*), YPRIME(*), RWORK(*), 
 
1171
C     IWORK(*), or the differential equation in subroutine RES.  Any 
 
1172
C     such alteration constitutes a new problem and must be treated 
 
1173
C     as such, i.e. you must start afresh.
 
1174
C
 
1175
C     You cannot change from array to scalar error control or vice
 
1176
C     versa (INFO(2)), but you can change the size of the entries of
 
1177
C     RTOL or ATOL.  Increasing a tolerance makes the equation easier
 
1178
C     to integrate.  Decreasing a tolerance will make the equation
 
1179
C     harder to integrate and should generally be avoided.
 
1180
C
 
1181
C     You can switch from the intermediate-output mode to the
 
1182
C     interval mode (INFO(3)) or vice versa at any time.
 
1183
C
 
1184
C     If it has been necessary to prevent the integration from going
 
1185
C     past a point TSTOP (INFO(4), RWORK(1)), keep in mind that the
 
1186
C     code will not integrate to any TOUT beyond the currently
 
1187
C     specified TSTOP.  Once TSTOP has been reached, you must change
 
1188
C     the value of TSTOP or set INFO(4) = 0.  You may change INFO(4)
 
1189
C     or TSTOP at any time but you must supply the value of TSTOP in
 
1190
C     RWORK(1) whenever you set INFO(4) = 1.
 
1191
C
 
1192
C     Do not change INFO(5), INFO(6), INFO(12-17) or their associated
 
1193
C     IWORK/RWORK locations unless you are going to restart the code.
 
1194
C
 
1195
C                    *** FOLLOWING A COMPLETED TASK ***
 
1196
C
 
1197
C     If..
 
1198
C     IDID = 1, call the code again to continue the integration
 
1199
C                  another step in the direction of TOUT.
 
1200
C
 
1201
C     IDID = 2 or 3, define a new TOUT and call the code again.
 
1202
C                  TOUT must be different from T.  You cannot change
 
1203
C                  the direction of integration without restarting.
 
1204
C
 
1205
C     IDID = 4, reset INFO(11) = 0 and call the code again to begin
 
1206
C                  the integration.  (If you leave INFO(11) > 0 and
 
1207
C                  INFO(14) = 1, you may generate an infinite loop.)
 
1208
C                  In this situation, the next call to DDASKR is 
 
1209
C                  considered to be the first call for the problem,
 
1210
C                  in that all initializations are done.
 
1211
C
 
1212
C     IDID = 5, call the code again to continue the integration in the
 
1213
C                  direction of TOUT.  You may change the functions
 
1214
C                  Ri defined by RT after a return with IDID = 5, but
 
1215
C                  the number of constraint functions NRT must remain
 
1216
C                  the same.  If you wish to change the functions in
 
1217
C                  RES or in RT, then you must restart the code.
 
1218
C
 
1219
C                    *** FOLLOWING AN INTERRUPTED TASK ***
 
1220
C
 
1221
C     To show the code that you realize the task was interrupted and
 
1222
C     that you want to continue, you must take appropriate action and
 
1223
C     set INFO(1) = 1.
 
1224
C
 
1225
C     If..
 
1226
C     IDID = -1, the code has taken about 500 steps.  If you want to
 
1227
C                  continue, set INFO(1) = 1 and call the code again.
 
1228
C                  An additional 500 steps will be allowed.
 
1229
C
 
1230
C
 
1231
C     IDID = -2, the error tolerances RTOL, ATOL have been increased
 
1232
C                  to values the code estimates appropriate for
 
1233
C                  continuing.  You may want to change them yourself.
 
1234
C                  If you are sure you want to continue with relaxed
 
1235
C                  error tolerances, set INFO(1) = 1 and call the code
 
1236
C                  again.
 
1237
C
 
1238
C     IDID = -3, a solution component is zero and you set the
 
1239
C                  corresponding component of ATOL to zero.  If you
 
1240
C                  are sure you want to continue, you must first alter
 
1241
C                  the error criterion to use positive values of ATOL 
 
1242
C                  for those components corresponding to zero solution
 
1243
C                  components, then set INFO(1) = 1 and call the code
 
1244
C                  again.
 
1245
C
 
1246
C     IDID = -4  --- cannot occur with this code.
 
1247
C
 
1248
C     IDID = -5, your JAC routine failed with the Krylov method.  Check
 
1249
C                  for errors in JAC and restart the integration.
 
1250
C
 
1251
C     IDID = -6, repeated error test failures occurred on the last
 
1252
C                  attempted step in DDASKR.  A singularity in the
 
1253
C                  solution may be present.  If you are absolutely
 
1254
C                  certain you want to continue, you should restart
 
1255
C                  the integration.  (Provide initial values of Y and
 
1256
C                  YPRIME which are consistent.)
 
1257
C
 
1258
C     IDID = -7, repeated convergence test failures occurred on the last
 
1259
C                  attempted step in DDASKR.  An inaccurate or ill-
 
1260
C                  conditioned Jacobian or preconditioner may be the
 
1261
C                  problem.  If you are absolutely certain you want
 
1262
C                  to continue, you should restart the integration.
 
1263
C
 
1264
C
 
1265
C     IDID = -8, the matrix of partial derivatives is singular, with
 
1266
C                  the use of direct methods.  Some of your equations
 
1267
C                  may be redundant.  DDASKR cannot solve the problem
 
1268
C                  as stated.  It is possible that the redundant
 
1269
C                  equations could be removed, and then DDASKR could
 
1270
C                  solve the problem.  It is also possible that a
 
1271
C                  solution to your problem either does not exist
 
1272
C                  or is not unique.
 
1273
C
 
1274
C     IDID = -9, DDASKR had multiple convergence test failures, preceded
 
1275
C                  by multiple error test failures, on the last
 
1276
C                  attempted step.  It is possible that your problem is
 
1277
C                  ill-posed and cannot be solved using this code.  Or,
 
1278
C                  there may be a discontinuity or a singularity in the
 
1279
C                  solution.  If you are absolutely certain you want to
 
1280
C                  continue, you should restart the integration.
 
1281
C
 
1282
C     IDID = -10, DDASKR had multiple convergence test failures
 
1283
C                  because IRES was equal to -1.  If you are
 
1284
C                  absolutely certain you want to continue, you
 
1285
C                  should restart the integration.
 
1286
C
 
1287
C     IDID = -11, there was an unrecoverable error (IRES = -2) from RES
 
1288
C                  inside the nonlinear system solver.  Determine the
 
1289
C                  cause before trying again.
 
1290
C
 
1291
C     IDID = -12, DDASKR failed to compute the initial Y and YPRIME
 
1292
C                  vectors.  This could happen because the initial 
 
1293
C                  approximation to Y or YPRIME was not very good, or
 
1294
C                  because no consistent values of these vectors exist.
 
1295
C                  The problem could also be caused by an inaccurate or
 
1296
C                  singular iteration matrix, or a poor preconditioner.
 
1297
C
 
1298
C     IDID = -13, there was an unrecoverable error encountered inside 
 
1299
C                  your PSOL routine.  Determine the cause before 
 
1300
C                  trying again.
 
1301
C
 
1302
C     IDID = -14, the Krylov linear system solver failed to achieve
 
1303
C                  convergence.  This may be due to ill-conditioning
 
1304
C                  in the iteration matrix, or a singularity in the
 
1305
C                  preconditioner (if one is being used).
 
1306
C                  Another possibility is that there is a better
 
1307
C                  choice of Krylov parameters (see INFO(13)).
 
1308
C                  Possibly the failure is caused by redundant equations
 
1309
C                  in the system, or by inconsistent equations.
 
1310
C                  In that case, reformulate the system to make it
 
1311
C                  consistent and non-redundant.
 
1312
C
 
1313
C     IDID = -15,..,-32 --- Cannot occur with this code.
 
1314
C
 
1315
C                       *** FOLLOWING A TERMINATED TASK ***
 
1316
C
 
1317
C     If IDID = -33, you cannot continue the solution of this problem.
 
1318
C                  An attempt to do so will result in your run being
 
1319
C                  terminated.
 
1320
C
 
1321
C  ---------------------------------------------------------------------
 
1322
C
 
1323
C***REFERENCES
 
1324
C  1.  L. R. Petzold, A Description of DASSL: A Differential/Algebraic
 
1325
C      System Solver, in Scientific Computing, R. S. Stepleman et al.
 
1326
C      (Eds.), North-Holland, Amsterdam, 1983, pp. 65-68.
 
1327
C  2.  K. E. Brenan, S. L. Campbell, and L. R. Petzold, Numerical 
 
1328
C      Solution of Initial-Value Problems in Differential-Algebraic
 
1329
C      Equations, Elsevier, New York, 1989.
 
1330
C  3.  P. N. Brown and A. C. Hindmarsh, Reduced Storage Matrix Methods
 
1331
C      in Stiff ODE Systems, J. Applied Mathematics and Computation,
 
1332
C      31 (1989), pp. 40-91.
 
1333
C  4.  P. N. Brown, A. C. Hindmarsh, and L. R. Petzold, Using Krylov
 
1334
C      Methods in the Solution of Large-Scale Differential-Algebraic
 
1335
C      Systems, SIAM J. Sci. Comp., 15 (1994), pp. 1467-1488.
 
1336
C  5.  P. N. Brown, A. C. Hindmarsh, and L. R. Petzold, Consistent
 
1337
C      Initial Condition Calculation for Differential-Algebraic
 
1338
C      Systems, SIAM J. Sci. Comp. 19 (1998), pp. 1495-1512.
 
1339
C
 
1340
C***ROUTINES CALLED
 
1341
C
 
1342
C   The following are all the subordinate routines used by DDASKR.
 
1343
C
 
1344
C   DRCHEK does preliminary checking for roots, and serves as an
 
1345
C          interface between Subroutine DDASKR and Subroutine DROOTS.
 
1346
C   DROOTS finds the leftmost root of a set of functions.
 
1347
C   DDASIC computes consistent initial conditions.
 
1348
C   DYYPNW updates Y and YPRIME in linesearch for initial condition
 
1349
C          calculation.
 
1350
C   DDSTP  carries out one step of the integration.
 
1351
C   DCNSTR/DCNST0 check the current solution for constraint violations.
 
1352
C   DDAWTS sets error weight quantities.
 
1353
C   DINVWT tests and inverts the error weights.
 
1354
C   DDATRP performs interpolation to get an output solution.
 
1355
C   DDWNRM computes the weighted root-mean-square norm of a vector.
 
1356
C   D1MACH provides the unit roundoff of the computer.
 
1357
C   XERRWD/XSETF/XSETUN/IXSAV is a package to handle error messages. 
 
1358
C   DDASID nonlinear equation driver to initialize Y and YPRIME using
 
1359
C          direct linear system solver methods.  Interfaces to Newton
 
1360
C          solver (direct case).
 
1361
C   DNSID  solves the nonlinear system for unknown initial values by
 
1362
C          modified Newton iteration and direct linear system methods.
 
1363
C   DLINSD carries out linesearch algorithm for initial condition
 
1364
C          calculation (direct case).
 
1365
C   DFNRMD calculates weighted norm of preconditioned residual in
 
1366
C          initial condition calculation (direct case).
 
1367
C   DNEDD  nonlinear equation driver for direct linear system solver
 
1368
C          methods.  Interfaces to Newton solver (direct case).
 
1369
C   DMATD  assembles the iteration matrix (direct case).
 
1370
C   DNSD   solves the associated nonlinear system by modified
 
1371
C          Newton iteration and direct linear system methods.
 
1372
C   DSLVD  interfaces to linear system solver (direct case).
 
1373
C   DDASIK nonlinear equation driver to initialize Y and YPRIME using
 
1374
C          Krylov iterative linear system methods.  Interfaces to
 
1375
C          Newton solver (Krylov case).
 
1376
C   DNSIK  solves the nonlinear system for unknown initial values by
 
1377
C          Newton iteration and Krylov iterative linear system methods.
 
1378
C   DLINSK carries out linesearch algorithm for initial condition
 
1379
C          calculation (Krylov case).
 
1380
C   DFNRMK calculates weighted norm of preconditioned residual in
 
1381
C          initial condition calculation (Krylov case).
 
1382
C   DNEDK  nonlinear equation driver for iterative linear system solver
 
1383
C          methods.  Interfaces to Newton solver (Krylov case).
 
1384
C   DNSK   solves the associated nonlinear system by Inexact Newton
 
1385
C          iteration and (linear) Krylov iteration.
 
1386
C   DSLVK  interfaces to linear system solver (Krylov case).
 
1387
C   DSPIGM solves a linear system by SPIGMR algorithm.
 
1388
C   DATV   computes matrix-vector product in Krylov algorithm.
 
1389
C   DORTH  performs orthogonalization of Krylov basis vectors.
 
1390
C   DHEQR  performs QR factorization of Hessenberg matrix.
 
1391
C   DHELS  finds least-squares solution of Hessenberg linear system.
 
1392
C   DGEFA, DGESL, DGBFA, DGBSL are LINPACK routines for solving 
 
1393
C          linear systems (dense or band direct methods).
 
1394
C   DAXPY, DCOPY, DDOT, DNRM2, DSCAL are Basic Linear Algebra (BLAS)
 
1395
C          routines.
 
1396
C
 
1397
C The routines called directly by DDASKR are:
 
1398
C   DCNST0, DDAWTS, DINVWT, D1MACH, DDWNRM, DDASIC, DDATRP, DDSTP,
 
1399
C   DRCHEK, XERRWD
 
1400
C
 
1401
C***END PROLOGUE DDASKR
 
1402
C
 
1403
C
 
1404
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
1405
      LOGICAL DONE, LAVL, LCFN, LCFL, LWARN
 
1406
      DIMENSION Y(*),YPRIME(*)
 
1407
      DIMENSION INFO(20)
 
1408
      DIMENSION RWORK(LRW),IWORK(LIW)
 
1409
      DIMENSION RTOL(*),ATOL(*)
 
1410
      DIMENSION RPAR(*),IPAR(*)
 
1411
      CHARACTER MSG*80
 
1412
      EXTERNAL  RES, JAC, PSOL, RT, DDASID, DDASIK, DNEDD, DNEDK
 
1413
C
 
1414
C     Set pointers into IWORK.
 
1415
C
 
1416
      PARAMETER (LML=1, LMU=2, LMTYPE=4, 
 
1417
     *   LIWM=1, LMXORD=3, LJCALC=5, LPHASE=6, LK=7, LKOLD=8,
 
1418
     *   LNS=9, LNSTL=10, LNST=11, LNRE=12, LNJE=13, LETF=14, LNCFN=15,
 
1419
     *   LNCFL=16, LNIW=17, LNRW=18, LNNI=19, LNLI=20, LNPS=21,
 
1420
     *   LNPD=22, LMITER=23, LMAXL=24, LKMP=25, LNRMAX=26, LLNWP=27,
 
1421
     *   LLNIWP=28, LLOCWP=29, LLCIWP=30, LKPRIN=31, LMXNIT=32,
 
1422
     *   LMXNJ=33, LMXNH=34, LLSOFF=35, LNRTE=36, LIRFND=37, LICNS=41)
 
1423
C
 
1424
C     Set pointers into RWORK.
 
1425
C
 
1426
      PARAMETER (LTSTOP=1, LHMAX=2, LH=3, LTN=4, LCJ=5, LCJOLD=6,
 
1427
     *   LHOLD=7, LS=8, LROUND=9, LEPLI=10, LSQRN=11, LRSQRN=12,
 
1428
     *   LEPCON=13, LSTOL=14, LEPIN=15, LALPHA=21, LBETA=27,
 
1429
     *   LGAMMA=33, LPSI=39, LSIGMA=45, LT0=51, LTLAST=52, LDELTA=61)
 
1430
C
 
1431
      SAVE LID, LENID, NONNEG, NCPHI
 
1432
C
 
1433
C
 
1434
C***FIRST EXECUTABLE STATEMENT  DDASKR
 
1435
C
 
1436
 
1437
 
 
1438
      IF(INFO(1).NE.0) GO TO 100
 
1439
 
 
1440
 
 
1441
C-----------------------------------------------------------------------
 
1442
C     This block is executed for the initial call only.
 
1443
C     It contains checking of inputs and initializations.
 
1444
C-----------------------------------------------------------------------
 
1445
C
 
1446
C     First check INFO array to make sure all elements of INFO
 
1447
C     Are within the proper range.  (INFO(1) is checked later, because
 
1448
C     it must be tested on every call.) ITEMP holds the location
 
1449
C     within INFO which may be out of range.
 
1450
C
 
1451
      DO 10 I=2,9
 
1452
         ITEMP = I
 
1453
         IF (INFO(I) .NE. 0 .AND. INFO(I) .NE. 1) GO TO 701
 
1454
 10      CONTINUE
 
1455
      ITEMP = 10
 
1456
      IF(INFO(10).LT.0 .OR. INFO(10).GT.3) GO TO 701
 
1457
      ITEMP = 11
 
1458
      IF(INFO(11).LT.0 .OR. INFO(11).GT.2) GO TO 701
 
1459
      DO 15 I=12,17
 
1460
         ITEMP = I
 
1461
         IF (INFO(I) .NE. 0 .AND. INFO(I) .NE. 1) GO TO 701
 
1462
 15      CONTINUE
 
1463
      ITEMP = 18
 
1464
      IF(INFO(18).LT.0 .OR. INFO(18).GT.2) GO TO 701
 
1465
 
 
1466
C
 
1467
C     Check NEQ to see if it is positive.
 
1468
C
 
1469
      IF (NEQ .LE. 0) GO TO 702
 
1470
C
 
1471
C     Check and compute maximum order.
 
1472
C
 
1473
      MXORD=5
 
1474
      IF (INFO(9) .NE. 0) THEN
 
1475
         MXORD=IWORK(LMXORD)
 
1476
         IF (MXORD .LT. 1 .OR. MXORD .GT. 5) GO TO 703
 
1477
         ENDIF
 
1478
      IWORK(LMXORD)=MXORD
 
1479
C
 
1480
C     Set and/or check inputs for constraint checking (INFO(10) .NE. 0).
 
1481
C     Set values for ICNFLG, NONNEG, and pointer LID.
 
1482
C
 
1483
      ICNFLG = 0
 
1484
      NONNEG = 0
 
1485
      LID = LICNS
 
1486
      IF (INFO(10) .EQ. 0) GO TO 20
 
1487
      IF (INFO(10) .EQ. 1) THEN
 
1488
         ICNFLG = 1
 
1489
         NONNEG = 0
 
1490
         LID = LICNS + NEQ
 
1491
      ELSEIF (INFO(10) .EQ. 2) THEN
 
1492
         ICNFLG = 0
 
1493
         NONNEG = 1
 
1494
      ELSE
 
1495
         ICNFLG = 1
 
1496
         NONNEG = 1
 
1497
         LID = LICNS + NEQ
 
1498
      ENDIF
 
1499
C
 
1500
 20   CONTINUE
 
1501
C
 
1502
C     Set and/or check inputs for Krylov solver (INFO(12) .NE. 0).
 
1503
C     If indicated, set default values for MAXL, KMP, NRMAX, and EPLI.
 
1504
C     Otherwise, verify inputs required for iterative solver.
 
1505
C
 
1506
      IF (INFO(12) .EQ. 0) GO TO 25
 
1507
C
 
1508
      IWORK(LMITER) = INFO(12)
 
1509
      IF (INFO(13) .EQ. 0) THEN
 
1510
         IWORK(LMAXL) = MIN(5,NEQ)
 
1511
         IWORK(LKMP) = IWORK(LMAXL)
 
1512
         IWORK(LNRMAX) = 5
 
1513
         RWORK(LEPLI) = 0.05D0
 
1514
      ELSE
 
1515
         IF(IWORK(LMAXL) .LT. 1 .OR. IWORK(LMAXL) .GT. NEQ) GO TO 720
 
1516
         IF(IWORK(LKMP) .LT. 1 .OR. IWORK(LKMP) .GT. IWORK(LMAXL))
 
1517
     1      GO TO 721
 
1518
         IF(IWORK(LNRMAX) .LT. 0) GO TO 722
 
1519
         IF(RWORK(LEPLI).LE.0.0D0 .OR. RWORK(LEPLI).GE.1.0D0)GO TO 723
 
1520
         ENDIF
 
1521
C
 
1522
 25   CONTINUE
 
1523
C
 
1524
C     Set and/or check controls for the initial condition calculation
 
1525
C     (INFO(11) .GT. 0).  If indicated, set default values.
 
1526
C     Otherwise, verify inputs required for iterative solver.
 
1527
 
1528
      IF (INFO(11) .EQ. 0) GO TO 30
 
1529
      IF (INFO(17) .EQ. 0) THEN
 
1530
        IWORK(LMXNIT) = 5
 
1531
        IF (INFO(12) .GT. 0) IWORK(LMXNIT) = 15
 
1532
        IWORK(LMXNJ) = 6
 
1533
        IF (INFO(12) .GT. 0) IWORK(LMXNJ) = 2
 
1534
        IWORK(LMXNH) = 5
 
1535
        IWORK(LLSOFF) = 0
 
1536
        RWORK(LEPIN) = 0.01D0
 
1537
      ELSE
 
1538
        IF (IWORK(LMXNIT) .LE. 0) GO TO 725
 
1539
        IF (IWORK(LMXNJ) .LE. 0) GO TO 725
 
1540
        IF (IWORK(LMXNH) .LE. 0) GO TO 725
 
1541
        LSOFF = IWORK(LLSOFF)
 
1542
        IF (LSOFF .LT. 0 .OR. LSOFF .GT. 1) GO TO 725
 
1543
        IF (RWORK(LEPIN) .LE. 0.0D0) GO TO 725
 
1544
        ENDIF
 
1545
C
 
1546
 30   CONTINUE
 
1547
C
 
1548
C     Below is the computation and checking of the work array lengths
 
1549
C     LENIW and LENRW, using direct methods (INFO(12) = 0) or
 
1550
C     the Krylov methods (INFO(12) = 1).
 
1551
C
 
1552
      LENIC = 0
 
1553
      IF (INFO(10) .EQ. 1 .OR. INFO(10) .EQ. 3) LENIC = NEQ
 
1554
      LENID = 0
 
1555
      IF (INFO(11) .EQ. 1 .OR. INFO(16) .EQ. 1) LENID = NEQ
 
1556
      IF (INFO(12) .EQ. 0) THEN
 
1557
C
 
1558
C        Compute MTYPE, etc.  Check ML and MU.
 
1559
C
 
1560
         NCPHI = MAX(MXORD + 1, 4)
 
1561
         IF(INFO(6).EQ.0) THEN 
 
1562
            LENPD = NEQ**2
 
1563
            LENRW = 60 + 3*NRT + (NCPHI+3)*NEQ + LENPD
 
1564
            IF(INFO(5).EQ.0) THEN
 
1565
               IWORK(LMTYPE)=2
 
1566
            ELSE
 
1567
               IWORK(LMTYPE)=1
 
1568
            ENDIF
 
1569
         ELSE
 
1570
            IF(IWORK(LML).LT.0.OR.IWORK(LML).GE.NEQ)GO TO 717
 
1571
            IF(IWORK(LMU).LT.0.OR.IWORK(LMU).GE.NEQ)GO TO 718
 
1572
            LENPD=(2*IWORK(LML)+IWORK(LMU)+1)*NEQ
 
1573
            IF(INFO(5).EQ.0) THEN
 
1574
               IWORK(LMTYPE)=5
 
1575
               MBAND=IWORK(LML)+IWORK(LMU)+1
 
1576
               MSAVE=(NEQ/MBAND)+1
 
1577
               LENRW = 60 + 3*NRT + (NCPHI+3)*NEQ + LENPD + 2*MSAVE
 
1578
            ELSE
 
1579
               IWORK(LMTYPE)=4
 
1580
               LENRW = 60 + 3*NRT + (NCPHI+3)*NEQ + LENPD
 
1581
            ENDIF
 
1582
         ENDIF
 
1583
C
 
1584
C        Compute LENIW, LENWP, LENIWP.
 
1585
C
 
1586
         LENIW = 40 + LENIC + LENID + NEQ
 
1587
         LENWP = 0
 
1588
         LENIWP = 0
 
1589
C
 
1590
      ELSE IF (INFO(12) .EQ. 1)  THEN
 
1591
         NCPHI = MXORD + 1
 
1592
         MAXL = IWORK(LMAXL)
 
1593
         LENWP = IWORK(LLNWP)
 
1594
         LENIWP = IWORK(LLNIWP)
 
1595
         LENPD = (MAXL+3+MIN0(1,MAXL-IWORK(LKMP)))*NEQ
 
1596
     1         + (MAXL+3)*MAXL + 1 + LENWP
 
1597
         LENRW = 60 + 3*NRT + (MXORD+5)*NEQ + LENPD
 
1598
         LENIW = 40 + LENIC + LENID + LENIWP
 
1599
C
 
1600
      ENDIF
 
1601
      IF(INFO(16) .NE. 0) LENRW = LENRW + NEQ
 
1602
C
 
1603
C     Check lengths of RWORK and IWORK.
 
1604
C
 
1605
c     -------------- memory allocation for masking ----------
 
1606
      LENIW=LENIW+NRT
 
1607
c     -------------- masking ------------------------------
 
1608
      IWORK(LNIW)=LENIW
 
1609
      IWORK(LNRW)=LENRW
 
1610
      IWORK(LNPD)=LENPD
 
1611
      IWORK(LLOCWP) = LENPD-LENWP+1
 
1612
      IF(LRW.LT.LENRW)GO TO 704
 
1613
      IF(LIW.LT.LENIW)GO TO 705
 
1614
C
 
1615
C     Check ICNSTR for legality.
 
1616
C
 
1617
      IF (LENIC .GT. 0) THEN
 
1618
        DO 40 I = 1,NEQ
 
1619
          ICI = IWORK(LICNS-1+I)
 
1620
          IF (ICI .LT. -2 .OR. ICI .GT. 2) GO TO 726
 
1621
 40       CONTINUE
 
1622
        ENDIF
 
1623
C
 
1624
C     Check Y for consistency with constraints.
 
1625
C
 
1626
      IF (LENIC .GT. 0) THEN
 
1627
        CALL DCNST0(NEQ,Y,IWORK(LICNS),IRET)
 
1628
        IF (IRET .NE. 0) GO TO 727
 
1629
        ENDIF
 
1630
C
 
1631
C     Check ID for legality and set INDEX = 0 or 1.
 
1632
C
 
1633
      INDEX = 1
 
1634
      IF (LENID .GT. 0) THEN
 
1635
        INDEX = 0
 
1636
        DO 50 I = 1,NEQ
 
1637
          IDI = IWORK(LID-1+I)
 
1638
          IF (IDI .NE. 1 .AND. IDI .NE. -1) GO TO 724
 
1639
          IF (IDI .EQ. -1) INDEX = 1
 
1640
 50       CONTINUE
 
1641
        ENDIF
 
1642
C
 
1643
C     Check to see that TOUT is different from T, and NRT .ge. 0.
 
1644
C
 
1645
      IF(TOUT .EQ. T)GO TO 719
 
1646
      IF(NRT .LT. 0) GO TO 730
 
1647
C
 
1648
C     Check HMAX.
 
1649
C
 
1650
      IF(INFO(7) .NE. 0) THEN
 
1651
         HMAX = RWORK(LHMAX)
 
1652
         IF (HMAX .LE. 0.0D0) GO TO 710
 
1653
         ENDIF
 
1654
C
 
1655
C     Initialize counters and other flags.
 
1656
C
 
1657
      IWORK(LNST)=0
 
1658
      IWORK(LNRE)=0
 
1659
      IWORK(LNJE)=0
 
1660
      IWORK(LETF)=0
 
1661
      IWORK(LNCFN)=0
 
1662
      IWORK(LNNI)=0
 
1663
      IWORK(LNLI)=0
 
1664
      IWORK(LNPS)=0
 
1665
      IWORK(LNCFL)=0
 
1666
      IWORK(LNRTE)=0
 
1667
      IWORK(LKPRIN)=INFO(18)
 
1668
      IDID=1
 
1669
      GO TO 200
 
1670
C
 
1671
C-----------------------------------------------------------------------
 
1672
C     This block is for continuation calls only.
 
1673
C     Here we check INFO(1), and if the last step was interrupted,
 
1674
C     we check whether appropriate action was taken.
 
1675
C-----------------------------------------------------------------------
 
1676
C
 
1677
100   CONTINUE
 
1678
      IF(INFO(1).EQ.1)GO TO 110
 
1679
      ITEMP = 1
 
1680
      IF(INFO(1).NE.-1)GO TO 701
 
1681
C
 
1682
C     If we are here, the last step was interrupted by an error
 
1683
C     condition from DDSTP, and appropriate action was not taken.
 
1684
C     This is a fatal error.
 
1685
C
 
1686
      MSG = 'DASKR--  THE LAST STEP TERMINATED WITH A NEGATIVE'
 
1687
      CALL XERRWD(MSG,49,201,0,0,0,0,0,0.0D0,0.0D0)
 
1688
      MSG = 'DASKR--  VALUE (=I1) OF IDID AND NO APPROPRIATE'
 
1689
      CALL XERRWD(MSG,47,202,0,1,IDID,0,0,0.0D0,0.0D0)
 
1690
      MSG = 'DASKR--  ACTION WAS TAKEN. RUN TERMINATED'
 
1691
      CALL XERRWD(MSG,41,203,1,0,0,0,0,0.0D0,0.0D0)
 
1692
      RETURN
 
1693
110   CONTINUE
 
1694
C
 
1695
C-----------------------------------------------------------------------
 
1696
C     This block is executed on all calls.
 
1697
C
 
1698
C     Counters are saved for later checks of performance.
 
1699
C     Then the error tolerance parameters are checked, and the
 
1700
C     work array pointers are set.
 
1701
C-----------------------------------------------------------------------
 
1702
C
 
1703
200   CONTINUE
 
1704
C
 
1705
C     Save counters for use later.
 
1706
C
 
1707
      IWORK(LNSTL)=IWORK(LNST)
 
1708
      NLI0 = IWORK(LNLI)
 
1709
      NNI0 = IWORK(LNNI)
 
1710
      NCFN0 = IWORK(LNCFN)
 
1711
      NCFL0 = IWORK(LNCFL)
 
1712
      NWARN = 0
 
1713
C
 
1714
C     Check RTOL and ATOL.
 
1715
C
 
1716
      NZFLG = 0
 
1717
      RTOLI = RTOL(1)
 
1718
      ATOLI = ATOL(1)
 
1719
      DO 210 I=1,NEQ
 
1720
         IF (INFO(2) .EQ. 1) RTOLI = RTOL(I)
 
1721
         IF (INFO(2) .EQ. 1) ATOLI = ATOL(I)
 
1722
         IF (RTOLI .GT. 0.0D0 .OR. ATOLI .GT. 0.0D0) NZFLG = 1
 
1723
         IF (RTOLI .LT. 0.0D0) GO TO 706
 
1724
         IF (ATOLI .LT. 0.0D0) GO TO 707
 
1725
210      CONTINUE
 
1726
      IF (NZFLG .EQ. 0) GO TO 708
 
1727
C
 
1728
C     Set pointers to RWORK and IWORK segments.
 
1729
C     For direct methods, SAVR is not used.
 
1730
C
 
1731
      IWORK(LLCIWP) = LID + LENID
 
1732
      LSAVR = LDELTA
 
1733
      IF (INFO(12) .NE. 0) LSAVR = LDELTA + NEQ
 
1734
      LE = LSAVR + NEQ
 
1735
      LWT = LE + NEQ
 
1736
      LVT = LWT
 
1737
      IF (INFO(16) .NE. 0) LVT = LWT + NEQ
 
1738
      LPHI = LVT + NEQ
 
1739
      LR0 = LPHI + NCPHI*NEQ
 
1740
      LR1 = LR0 + NRT
 
1741
      LRX = LR1 + NRT
 
1742
      LWM = LRX + NRT
 
1743
      IF (INFO(1) .EQ. 1) GO TO 400
 
1744
C
 
1745
C-----------------------------------------------------------------------
 
1746
C     This block is executed on the initial call only.
 
1747
C     Set the initial step size, the error weight vector, and PHI.
 
1748
C     Compute unknown initial components of Y and YPRIME, if requested.
 
1749
C-----------------------------------------------------------------------
 
1750
C
 
1751
300   CONTINUE
 
1752
      TN=T
 
1753
      IDID=1
 
1754
C
 
1755
C     Set error weight array WT and altered weight array VT.
 
1756
C
 
1757
      CALL DDAWTS1(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR)
 
1758
      CALL DINVWT(NEQ,RWORK(LWT),IER)
 
1759
      IF (IER .NE. 0) GO TO 713
 
1760
      IF (INFO(16) .NE. 0) THEN
 
1761
        DO 305 I = 1, NEQ
 
1762
 305      RWORK(LVT+I-1) = MAX(IWORK(LID+I-1),0)*RWORK(LWT+I-1)
 
1763
        ENDIF
 
1764
C
 
1765
C     Compute unit roundoff and HMIN.  >>> instead of D1MACH(4) we use
 
1766
c     DLAMCH, because the optimized compiler affects the D1MACH.
 
1767
c        UROUND = D1MACH(4)
 
1768
        UROUND = DLAMCH('p')
 
1769
        RWORK(LROUND) = UROUND
 
1770
c     ---------------- Hmind chnage ---------------------
 
1771
c     HMIN = 4.0D0*UROUND*MAX(ABS(T),ABS(TOUT))
 
1772
        HMIN = 0.0
 
1773
c     ---------------- Hmind chnage ---------------------
 
1774
C     
 
1775
C     Set/check STPTOL control for initial condition calculation.
 
1776
C     
 
1777
        IF (INFO(11) .NE. 0) THEN
 
1778
           IF( INFO(17) .EQ. 0) THEN
 
1779
              RWORK(LSTOL) = UROUND**.6667D0
 
1780
           ELSE
 
1781
              IF (RWORK(LSTOL) .LE. 0.0D0) GO TO 725
 
1782
           ENDIF
 
1783
        ENDIF
 
1784
C
 
1785
C     Compute EPCON and square root of NEQ and its reciprocal, used
 
1786
C     inside iterative solver.
 
1787
C
 
1788
      RWORK(LEPCON) = 0.33D0
 
1789
      FLOATN = NEQ
 
1790
      RWORK(LSQRN) = SQRT(FLOATN)
 
1791
      RWORK(LRSQRN) = 1.D0/RWORK(LSQRN)
 
1792
C
 
1793
C     Check initial interval to see that it is long enough.
 
1794
C
 
1795
      TDIST = ABS(TOUT - T)
 
1796
c ---------------- Hmind chnage ---------------------
 
1797
cc      IF(TDIST .LT. HMIN) GO TO 714
 
1798
c ---------------- Hmind chnage ---------------------
 
1799
C
 
1800
C     Check H0, if this was input.
 
1801
C
 
1802
      IF (INFO(8) .EQ. 0) GO TO 310
 
1803
         H0 = RWORK(LH)
 
1804
         IF ((TOUT - T)*H0 .LT. 0.0D0) GO TO 711
 
1805
         IF (H0 .EQ. 0.0D0) GO TO 712
 
1806
         GO TO 320
 
1807
310    CONTINUE
 
1808
C
 
1809
C     Compute initial stepsize, to be used by either
 
1810
C     DDSTP or DDASIC, depending on INFO(11).
 
1811
C
 
1812
      H0 = 0.001D0*TDIST
 
1813
      YPNORM = DDWNRM(NEQ,YPRIME,RWORK(LVT),RPAR,IPAR)
 
1814
      IF (YPNORM .GT. 0.5D0/H0) H0 = 0.5D0/YPNORM
 
1815
      H0 = SIGN(H0,TOUT-T)
 
1816
C
 
1817
C     Adjust H0 if necessary to meet HMAX bound.
 
1818
C
 
1819
320   IF (INFO(7) .EQ. 0) GO TO 330
 
1820
         RH = ABS(H0)/RWORK(LHMAX)
 
1821
         IF (RH .GT. 1.0D0) H0 = H0/RH
 
1822
C
 
1823
C     Check against TSTOP, if applicable.
 
1824
C
 
1825
330   IF (INFO(4) .EQ. 0) GO TO 340
 
1826
         TSTOP = RWORK(LTSTOP)
 
1827
         IF ((TSTOP - T)*H0 .LT. 0.0D0) GO TO 715
 
1828
         IF ((T + H0 - TSTOP)*H0 .GT. 0.0D0) H0 = TSTOP - T
 
1829
         IF ((TSTOP - TOUT)*H0 .LT. 0.0D0) GO TO 709
 
1830
C
 
1831
340   IF (INFO(11) .EQ. 0) GO TO 370
 
1832
C
 
1833
C     Compute unknown components of initial Y and YPRIME, depending
 
1834
C     on INFO(11) and INFO(12).  INFO(12) represents the nonlinear
 
1835
C     solver type (direct/Krylov).  Pass the name of the specific 
 
1836
C     nonlinear solver, depending on INFO(12).  The location of the work
 
1837
C     arrays SAVR, YIC, YPIC, PWK also differ in the two cases.
 
1838
C     For use in stopping tests, pass TSCALE = TDIST if INDEX = 0.
 
1839
C
 
1840
      
 
1841
 
 
1842
      NWT = 1
 
1843
      EPCONI = RWORK(LEPIN)*RWORK(LEPCON)
 
1844
      TSCALE = 0.0D0
 
1845
      IF (INDEX .EQ. 0) TSCALE = TDIST
 
1846
350   IF (INFO(12) .EQ. 0) THEN
 
1847
         LYIC = LPHI + 2*NEQ
 
1848
         LYPIC = LYIC + NEQ
 
1849
         LPWK = LYPIC
 
1850
         CALL DDASIC(TN,Y,YPRIME,NEQ,INFO(11),IWORK(LID),
 
1851
     *     RES,JAC,PSOL,H0,TSCALE,RWORK(LWT),NWT,IDID,RPAR,IPAR,
 
1852
     *     RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE),
 
1853
     *     RWORK(LYIC),RWORK(LYPIC),RWORK(LPWK),RWORK(LWM),IWORK(LIWM),
 
1854
     *     RWORK(LROUND),RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN),
 
1855
     *     EPCONI,RWORK(LSTOL),INFO(15),ICNFLG,IWORK(LICNS),DDASID)
 
1856
      ELSE IF (INFO(12) .EQ. 1) THEN
 
1857
         LYIC = LWM
 
1858
         LYPIC = LYIC + NEQ
 
1859
         LPWK = LYPIC + NEQ
 
1860
         CALL DDASIC(TN,Y,YPRIME,NEQ,INFO(11),IWORK(LID),
 
1861
     *     RES,JAC,PSOL,H0,TSCALE,RWORK(LWT),NWT,IDID,RPAR,IPAR,
 
1862
     *     RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE),
 
1863
     *     RWORK(LYIC),RWORK(LYPIC),RWORK(LPWK),RWORK(LWM),IWORK(LIWM),
 
1864
     *     RWORK(LROUND),RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN),
 
1865
     *     EPCONI,RWORK(LSTOL),INFO(15),ICNFLG,IWORK(LICNS),DDASIK)
 
1866
      ENDIF
 
1867
C
 
1868
      IF (IDID .LT. 0) GO TO 600
 
1869
C
 
1870
C     DDASIC was successful.  If this was the first call to DDASIC,
 
1871
C     update the WT array (with the current Y) and call it again.
 
1872
C
 
1873
      IF (NWT .EQ. 2) GO TO 355
 
1874
      NWT = 2
 
1875
      CALL DDAWTS1(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR)
 
1876
      CALL DINVWT(NEQ,RWORK(LWT),IER)
 
1877
      IF (IER .NE. 0) GO TO 713
 
1878
      GO TO 350
 
1879
C
 
1880
C     If INFO(14) = 1, return now with IDID = 4.
 
1881
C
 
1882
 
 
1883
 355  IF (INFO(14) .EQ. 1) THEN
 
1884
        IDID = 4
 
1885
        H = H0
 
1886
        IF (INFO(11) .EQ. 1) RWORK(LHOLD) = H0
 
1887
        GO TO 590
 
1888
      ENDIF
 
1889
C
 
1890
C     Update the WT and VT arrays one more time, with the new Y.
 
1891
C
 
1892
      CALL DDAWTS1(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR)
 
1893
      CALL DINVWT(NEQ,RWORK(LWT),IER)
 
1894
      IF (IER .NE. 0) GO TO 713
 
1895
      IF (INFO(16) .NE. 0) THEN
 
1896
        DO 357 I = 1, NEQ
 
1897
 357      RWORK(LVT+I-1) = MAX(IWORK(LID+I-1),0)*RWORK(LWT+I-1)
 
1898
        ENDIF
 
1899
C
 
1900
C     Reset the initial stepsize to be used by DDSTP.
 
1901
C     Use H0, if this was input.  Otherwise, recompute H0,
 
1902
C     and adjust it if necessary to meet HMAX bound.
 
1903
C
 
1904
      IF (INFO(8) .NE. 0) THEN
 
1905
         H0 = RWORK(LH)
 
1906
         GO TO 360
 
1907
      ENDIF
 
1908
C     
 
1909
      H0 = 0.001D0*TDIST
 
1910
      YPNORM = DDWNRM(NEQ,YPRIME,RWORK(LVT),RPAR,IPAR)
 
1911
      IF (YPNORM .GT. 0.5D0/H0) H0 = 0.5D0/YPNORM
 
1912
      H0 = SIGN(H0,TOUT-T)
 
1913
C
 
1914
360   IF (INFO(7) .NE. 0) THEN
 
1915
         RH = ABS(H0)/RWORK(LHMAX)
 
1916
         IF (RH .GT. 1.0D0) H0 = H0/RH
 
1917
         ENDIF
 
1918
C
 
1919
C     Check against TSTOP, if applicable.
 
1920
C
 
1921
      IF (INFO(4) .NE. 0) THEN
 
1922
         TSTOP = RWORK(LTSTOP)
 
1923
         IF ((T + H0 - TSTOP)*H0 .GT. 0.0D0) H0 = TSTOP - T
 
1924
         ENDIF
 
1925
C
 
1926
C     Load H and RWORK(LH) with H0.
 
1927
C
 
1928
370   H = H0
 
1929
      RWORK(LH) = H
 
1930
C
 
1931
C     Load Y and H*YPRIME into PHI(*,1) and PHI(*,2).
 
1932
C
 
1933
      ITEMP = LPHI + NEQ
 
1934
      DO 380 I = 1,NEQ
 
1935
         RWORK(LPHI + I - 1) = Y(I)
 
1936
380      RWORK(ITEMP + I - 1) = H*YPRIME(I)
 
1937
C
 
1938
C     Initialize T0 in RWORK; check for a zero of R near initial T.
 
1939
C
 
1940
      RWORK(LT0) = T
 
1941
      IWORK(LIRFND) = 0
 
1942
      RWORK(LPSI)=H
 
1943
      RWORK(LPSI+1)=2.0D0*H
 
1944
      IWORK(LKOLD)=1
 
1945
      IF (NRT .EQ. 0) GO TO 390
 
1946
c     -------------- masking ----------------->>>
 
1947
      CALL DRCHEK1(1,RT,NRT,NEQ,T,TOUT,Y,YPRIME,RWORK(LPHI),
 
1948
     *   RWORK(LPSI),IWORK(LKOLD),RWORK(LR0),RWORK(LR1),
 
1949
     *   RWORK(LRX),JROOT,IRT,RWORK(LROUND),INFO(3),
 
1950
     *   RWORK,IWORK,RPAR,IPAR)
 
1951
      IF (IRT .LT. 0) GO TO 731
 
1952
      IF (IRT .EQ. 2)  IWORK(LIRFND) = 2
 
1953
 
 
1954
 390  GO TO 500
 
1955
C
 
1956
C-----------------------------------------------------------------------
 
1957
C     This block is for continuation calls only.
 
1958
C     Its purpose is to check stop conditions before taking a step.
 
1959
C     Adjust H if necessary to meet HMAX bound.
 
1960
C-----------------------------------------------------------------------
 
1961
C
 
1962
400   CONTINUE
 
1963
      UROUND=RWORK(LROUND)
 
1964
      DONE = .FALSE.
 
1965
      TN=RWORK(LTN)
 
1966
      H=RWORK(LH)
 
1967
      IF(NRT .EQ. 0) GO TO 405
 
1968
C
 
1969
C     Check for a zero of R near TN.
 
1970
C
 
1971
      CALL DRCHEK1(2,RT,NRT,NEQ,TN,TOUT,Y,YPRIME,RWORK(LPHI),
 
1972
     *   RWORK(LPSI),IWORK(LKOLD),RWORK(LR0),RWORK(LR1),
 
1973
     *   RWORK(LRX),JROOT,IRT,RWORK(LROUND),INFO(3),
 
1974
     *   RWORK,IWORK,RPAR,IPAR)
 
1975
      IF (IRT .LT. 0) GO TO 731
 
1976
 
 
1977
      IF (IRT .EQ. 1) THEN 
 
1978
         IWORK(LIRFND) = 1
 
1979
         IDID = 5
 
1980
         T = RWORK(LT0)
 
1981
         DONE = .TRUE.
 
1982
         GO TO 490
 
1983
      ENDIF
 
1984
 
 
1985
405   CONTINUE
 
1986
C
 
1987
      IF(INFO(7) .EQ. 0) GO TO 410
 
1988
         RH = ABS(H)/RWORK(LHMAX)
 
1989
         IF(RH .GT. 1.0D0) H = H/RH
 
1990
410   CONTINUE
 
1991
      IF(T .EQ. TOUT) GO TO 719
 
1992
      IF((T - TOUT)*H .GT. 0.0D0) GO TO 711
 
1993
      IF(INFO(4) .EQ. 1) GO TO 430
 
1994
      IF(INFO(3) .EQ. 1) GO TO 420
 
1995
      IF((TN-TOUT)*H.LT.0.0D0)GO TO 490
 
1996
      CALL DDATRP1(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
 
1997
     *  RWORK(LPHI),RWORK(LPSI))
 
1998
      T=TOUT
 
1999
      IDID = 3
 
2000
      DONE = .TRUE.
 
2001
      GO TO 490
 
2002
420   IF((TN-T)*H .LE. 0.0D0) GO TO 490
 
2003
      IF((TN - TOUT)*H .GE. 0.0D0) GO TO 425
 
2004
      CALL DDATRP1(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD),
 
2005
     *  RWORK(LPHI),RWORK(LPSI))
 
2006
      T = TN
 
2007
      IDID = 1
 
2008
      DONE = .TRUE.
 
2009
      GO TO 490
 
2010
425   CONTINUE
 
2011
      CALL DDATRP1(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
 
2012
     *  RWORK(LPHI),RWORK(LPSI))
 
2013
      T = TOUT
 
2014
      IDID = 3
 
2015
      DONE = .TRUE.
 
2016
      GO TO 490
 
2017
430   IF(INFO(3) .EQ. 1) GO TO 440
 
2018
      TSTOP=RWORK(LTSTOP)
 
2019
      IF((TN-TSTOP)*H.GT.0.0D0) GO TO 715
 
2020
      IF((TSTOP-TOUT)*H.LT.0.0D0)GO TO 709
 
2021
      IF((TN-TOUT)*H.LT.0.0D0)GO TO 450
 
2022
      CALL DDATRP1(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
 
2023
     *   RWORK(LPHI),RWORK(LPSI))
 
2024
      T=TOUT
 
2025
      IDID = 3
 
2026
      DONE = .TRUE.
 
2027
      GO TO 490
 
2028
440   TSTOP = RWORK(LTSTOP)
 
2029
      IF((TN-TSTOP)*H .GT. 0.0D0) GO TO 715
 
2030
      IF((TSTOP-TOUT)*H .LT. 0.0D0) GO TO 709
 
2031
      IF((TN-T)*H .LE. 0.0D0) GO TO 450
 
2032
      IF((TN - TOUT)*H .GE. 0.0D0) GO TO 445
 
2033
      CALL DDATRP1(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD),
 
2034
     *  RWORK(LPHI),RWORK(LPSI))
 
2035
      T = TN
 
2036
      IDID = 1
 
2037
      DONE = .TRUE.
 
2038
      GO TO 490
 
2039
445   CONTINUE
 
2040
      CALL DDATRP1(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD),
 
2041
     *  RWORK(LPHI),RWORK(LPSI))
 
2042
      T = TOUT
 
2043
      IDID = 3
 
2044
      DONE = .TRUE.
 
2045
      GO TO 490
 
2046
450   CONTINUE
 
2047
C
 
2048
C     Check whether we are within roundoff of TSTOP.
 
2049
C
 
2050
      IF(ABS(TN-TSTOP).GT.100.0D0*UROUND*
 
2051
     *   (ABS(TN)+ABS(H)))GO TO 460
 
2052
      CALL DDATRP1(TN,TSTOP,Y,YPRIME,NEQ,IWORK(LKOLD),
 
2053
     *  RWORK(LPHI),RWORK(LPSI))
 
2054
      IDID=2
 
2055
      T=TSTOP
 
2056
      DONE = .TRUE.
 
2057
      GO TO 490
 
2058
460   TNEXT=TN+H
 
2059
      IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 490 
 
2060
      H=TSTOP-TN 
 
2061
      RWORK(LH)=H
 
2062
C
 
2063
490   IF (DONE) GO TO 590
 
2064
C
 
2065
C-----------------------------------------------------------------------
 
2066
C     The next block contains the call to the one-step integrator DDSTP.
 
2067
C     This is a looping point for the integration steps.
 
2068
C     Check for too many steps.
 
2069
C     Check for poor Newton/Krylov performance.
 
2070
C     Update WT.  Check for too much accuracy requested.
 
2071
C     Compute minimum stepsize.
 
2072
C-----------------------------------------------------------------------
 
2073
C
 
2074
500   CONTINUE
 
2075
C
 
2076
C     Check for too many steps.
 
2077
C
 
2078
      IF((IWORK(LNST)-IWORK(LNSTL)).LT.500) GO TO 505
 
2079
           IDID=-1
 
2080
           GO TO 527
 
2081
C
 
2082
C Check for poor Newton/Krylov performance.
 
2083
C
 
2084
505   IF (INFO(12) .EQ. 0) GO TO 510
 
2085
      NSTD = IWORK(LNST) - IWORK(LNSTL)
 
2086
      NNID = IWORK(LNNI) - NNI0
 
2087
      IF (NSTD .LT. 10 .OR. NNID .EQ. 0) GO TO 510
 
2088
      AVLIN = REAL(IWORK(LNLI) - NLI0)/REAL(NNID)
 
2089
      RCFN = REAL(IWORK(LNCFN) - NCFN0)/REAL(NSTD)
 
2090
      RCFL = REAL(IWORK(LNCFL) - NCFL0)/REAL(NNID)
 
2091
      FMAXL = IWORK(LMAXL)
 
2092
      LAVL = AVLIN .GT. FMAXL
 
2093
      LCFN = RCFN .GT. 0.9D0
 
2094
      LCFL = RCFL .GT. 0.9D0
 
2095
      LWARN = LAVL .OR. LCFN .OR. LCFL
 
2096
      IF (.NOT.LWARN) GO TO 510
 
2097
      NWARN = NWARN + 1
 
2098
      IF (NWARN .GT. 10) GO TO 510
 
2099
      IF (LAVL) THEN
 
2100
        MSG = 'DASKR-- Warning. Poor iterative algorithm performance   '
 
2101
        CALL XERRWD (MSG, 56, 501, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
 
2102
        MSG = '      at T = R1. Average no. of linear iterations = R2  '
 
2103
        CALL XERRWD (MSG, 56, 501, 0, 0, 0, 0, 2, TN, AVLIN)
 
2104
        ENDIF
 
2105
      IF (LCFN) THEN
 
2106
        MSG = 'DASKR-- Warning. Poor iterative algorithm performance   '
 
2107
        CALL XERRWD (MSG, 56, 502, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
 
2108
        MSG = '      at T = R1. Nonlinear convergence failure rate = R2'
 
2109
        CALL XERRWD (MSG, 56, 502, 0, 0, 0, 0, 2, TN, RCFN)
 
2110
        ENDIF
 
2111
      IF (LCFL) THEN
 
2112
        MSG = 'DASKR-- Warning. Poor iterative algorithm performance   '
 
2113
        CALL XERRWD (MSG, 56, 503, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
 
2114
        MSG = '      at T = R1. Linear convergence failure rate = R2   '
 
2115
        CALL XERRWD (MSG, 56, 503, 0, 0, 0, 0, 2, TN, RCFL)
 
2116
        ENDIF
 
2117
C
 
2118
C     Update WT and VT, if this is not the first call.
 
2119
C
 
2120
510   CALL DDAWTS1(NEQ,INFO(2),RTOL,ATOL,RWORK(LPHI),RWORK(LWT),
 
2121
     *            RPAR,IPAR)
 
2122
      CALL DINVWT(NEQ,RWORK(LWT),IER)
 
2123
      IF (IER .NE. 0) THEN
 
2124
         IDID = -3
 
2125
         GO TO 527
 
2126
      ENDIF
 
2127
      IF (INFO(16) .NE. 0) THEN
 
2128
         DO 515 I = 1, NEQ
 
2129
            RWORK(LVT+I-1) = MAX(IWORK(LID+I-1),0)*RWORK(LWT+I-1)
 
2130
 515     CONTINUE
 
2131
      ENDIF
 
2132
C     
 
2133
C     Test for too much accuracy requested.
 
2134
C     
 
2135
      R = DDWNRM(NEQ,RWORK(LPHI),RWORK(LWT),RPAR,IPAR)*100.0D0*UROUND
 
2136
      IF (R .LE. 1.0D0) GO TO 525
 
2137
C     
 
2138
C     Multiply RTOL and ATOL by R and return.
 
2139
C     
 
2140
      IF(INFO(2).EQ.1)GO TO 523
 
2141
      RTOL(1)=R*RTOL(1)
 
2142
      ATOL(1)=R*ATOL(1)
 
2143
      IDID=-2
 
2144
      GO TO 527
 
2145
 523  DO 524 I=1,NEQ
 
2146
         RTOL(I)=R*RTOL(I)
 
2147
         ATOL(I)=R*ATOL(I)
 
2148
 524  CONTINUE
 
2149
      IDID=-2
 
2150
      GO TO 527
 
2151
 525  CONTINUE
 
2152
C     
 
2153
C     Compute minimum stepsize.
 
2154
C     
 
2155
c     ----------------------- Hmin Change---------------------- 
 
2156
c
 
2157
c     HMIN is intended to be a value slightly above the roundoff level
 
2158
c     in the current T.  As such it is appropriate that it varies with
 
2159
c     T. In DASKR, HMIN is used in two ways: 
 
2160
c
 
2161
c     1. At the start, ABS(TOUT - T) is required to be at least HMIN, to
 
2162
c     guarantee that the user has provided the direction of the
 
2163
c     integration reliably.  For this test, it would be sufficient to
 
2164
c     ignore HMIN and simply require that TOUT - T is nonzero on the
 
2165
c     machine.
 
2166
c
 
2167
c     2. If the integration has difficulty passing the convergence or
 
2168
c     the error test with step size H of size ABS(H) = HMIN, it stops
 
2169
c     with an error message saying that.  In all of these uses, it would
 
2170
c     not hurt to use HMIN = 0, in my opinion.  There are cases where
 
2171
c     the appropriate step size is temporarily below the roundoff level
 
2172
c     in T.  The only negative impact of using HMIN = 0 then is that
 
2173
c     some steps may be taken in which T + H = T on the machine.  In
 
2174
c     contrast to the DASSL family, the ODEPACK solvers have HMIN = 0 as
 
2175
c     the default in these uses of HMIN, but they issue a warning when T
 
2176
c     + H = T, because in most cases this is the result of a user
 
2177
c     program bug or input error of some kind. On the other hand, the
 
2178
c     value HMIN = 4*UROUND makes no sense, because it ignores the scale
 
2179
c     of the T variable completely.  Thus it could ause invalid error
 
2180
c     halts, when values of ABS(H) smaller than that may well be
 
2181
c     appropriate.  If the current HMIN is bothersome, I suggest using
 
2182
c     HMIN = 0, and removing HMIN from the initial test on TOUT - T
 
2183
c
 
2184
c
 
2185
c      HMIN=4.0D0*UROUND*MAX(ABS(TN),ABS(TOUT))
 
2186
      HMIN=0.0
 
2187
c ----------------------- Hmin Change----------------------
 
2188
 
 
2189
C     Test H vs. HMAX
 
2190
      IF (INFO(7) .NE. 0) THEN
 
2191
         RH = ABS(H)/RWORK(LHMAX)
 
2192
         IF (RH .GT. 1.0D0) H = H/RH
 
2193
      ENDIF
 
2194
C     
 
2195
C     Call the one-step integrator.
 
2196
C     Note that INFO(12) represents the nonlinear solver type.
 
2197
C     Pass the required nonlinear solver, depending upon INFO(12).
 
2198
C     
 
2199
c     info(12): 0-> dierct case  1->Krylov
 
2200
      IF (INFO(12) .EQ. 0) THEN
 
2201
         CALL DDSTP(TN,Y,YPRIME,NEQ,
 
2202
     *      RES,JAC,PSOL,H,RWORK(LWT),RWORK(LVT),INFO(1),IDID,RPAR,IPAR,
 
2203
     *      RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE),
 
2204
     *      RWORK(LWM),IWORK(LIWM),
 
2205
     *      RWORK(LALPHA),RWORK(LBETA),RWORK(LGAMMA),
 
2206
     *      RWORK(LPSI),RWORK(LSIGMA),
 
2207
     *      RWORK(LCJ),RWORK(LCJOLD),RWORK(LHOLD),RWORK(LS),HMIN,
 
2208
     *      RWORK(LROUND), RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN),
 
2209
     *      RWORK(LEPCON), IWORK(LPHASE),IWORK(LJCALC),INFO(15),
 
2210
     *      IWORK(LK), IWORK(LKOLD),IWORK(LNS),NONNEG,INFO(12),
 
2211
     *      DNEDD)
 
2212
      ELSE IF (INFO(12) .EQ. 1) THEN
 
2213
         CALL DDSTP(TN,Y,YPRIME,NEQ,
 
2214
     *      RES,JAC,PSOL,H,RWORK(LWT),RWORK(LVT),INFO(1),IDID,RPAR,IPAR,
 
2215
     *      RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE),
 
2216
     *      RWORK(LWM),IWORK(LIWM),
 
2217
     *      RWORK(LALPHA),RWORK(LBETA),RWORK(LGAMMA),
 
2218
     *      RWORK(LPSI),RWORK(LSIGMA),
 
2219
     *      RWORK(LCJ),RWORK(LCJOLD),RWORK(LHOLD),RWORK(LS),HMIN,
 
2220
     *      RWORK(LROUND), RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN),
 
2221
     *      RWORK(LEPCON), IWORK(LPHASE),IWORK(LJCALC),INFO(15),
 
2222
     *      IWORK(LK), IWORK(LKOLD),IWORK(LNS),NONNEG,INFO(12),
 
2223
     *      DNEDK)
 
2224
      ENDIF
 
2225
C
 
2226
527   IF(IDID.LT.0)GO TO 600
 
2227
C
 
2228
C-----------------------------------------------------------------------
 
2229
C     This block handles the case of a successful return from DDSTP
 
2230
C     (IDID=1).  Test for stop conditions.
 
2231
C-----------------------------------------------------------------------
 
2232
C
 
2233
      IF(NRT .EQ. 0) GO TO 529
 
2234
C
 
2235
C     Check for a zero of R near TN.
 
2236
C
 
2237
      CALL DRCHEK1(3,RT,NRT,NEQ,TN,TOUT,Y,YPRIME,RWORK(LPHI),
 
2238
     *     RWORK(LPSI),IWORK(LKOLD),RWORK(LR0),RWORK(LR1),
 
2239
     *     RWORK(LRX),JROOT,IRT,RWORK(LROUND),INFO(3),
 
2240
     *     RWORK,IWORK,RPAR,IPAR)
 
2241
C     >>>>
 
2242
      IF(IRT .EQ. 2) THEN
 
2243
         IWORK(LIRFND) = 2
 
2244
         IDID = 6
 
2245
         T = RWORK(LT0)
 
2246
         GO TO 580
 
2247
      ENDIF
 
2248
C     <<<<<
 
2249
      IF(IRT .NE. 1) GO TO 529
 
2250
      IWORK(LIRFND) = 1
 
2251
      IDID = 5
 
2252
      T = RWORK(LT0)
 
2253
      GO TO 580
 
2254
529   CONTINUE
 
2255
 
 
2256
      IF(INFO(4).NE.0)GO TO 540
 
2257
           IF(INFO(3).NE.0)GO TO 530
 
2258
             IF((TN-TOUT)*H.LT.0.0D0)GO TO 500
 
2259
             CALL DDATRP1(TN,TOUT,Y,YPRIME,NEQ,
 
2260
     *         IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
 
2261
             IDID=3
 
2262
             T=TOUT
 
2263
             GO TO 580
 
2264
530          IF((TN-TOUT)*H.GE.0.0D0)GO TO 535
 
2265
             T=TN
 
2266
             IDID=1
 
2267
             GO TO 580
 
2268
535          CALL DDATRP1(TN,TOUT,Y,YPRIME,NEQ,
 
2269
     *         IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
 
2270
             IDID=3
 
2271
             T=TOUT
 
2272
             GO TO 580
 
2273
540   IF(INFO(3).NE.0)GO TO 550
 
2274
      IF((TN-TOUT)*H.LT.0.0D0)GO TO 542
 
2275
         CALL DDATRP1(TN,TOUT,Y,YPRIME,NEQ,
 
2276
     *     IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
 
2277
         T=TOUT
 
2278
         IDID=3
 
2279
         GO TO 580
 
2280
 542  IF(ABS(TN-TSTOP).LE.100.0D0*UROUND*
 
2281
     *        (ABS(TN)+ABS(H)))GO TO 545
 
2282
      TNEXT=TN+H
 
2283
      IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 500
 
2284
      H=TSTOP-TN
 
2285
      GO TO 500
 
2286
 545  CALL DDATRP1(TN,TSTOP,Y,YPRIME,NEQ,
 
2287
     *  IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
 
2288
      IDID=2
 
2289
      T=TSTOP
 
2290
      GO TO 580
 
2291
550   IF((TN-TOUT)*H.GE.0.0D0)GO TO 555
 
2292
      IF(ABS(TN-TSTOP).LE.100.0D0*UROUND*(ABS(TN)+ABS(H)))GO TO 552
 
2293
      T=TN
 
2294
      IDID=1
 
2295
      GO TO 580
 
2296
552   CALL DDATRP1(TN,TSTOP,Y,YPRIME,NEQ,
 
2297
     *  IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
 
2298
      IDID=2
 
2299
      T=TSTOP
 
2300
      GO TO 580
 
2301
555   CALL DDATRP1(TN,TOUT,Y,YPRIME,NEQ,
 
2302
     *   IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI))
 
2303
      T=TOUT
 
2304
      IDID=3
 
2305
580   CONTINUE
 
2306
C
 
2307
C-----------------------------------------------------------------------
 
2308
C     All successful returns from DDASKR are made from this block.
 
2309
C-----------------------------------------------------------------------
 
2310
C
 
2311
590   CONTINUE
 
2312
      RWORK(LTN)=TN
 
2313
      RWORK(LTLAST)=T
 
2314
      RWORK(LH)=H
 
2315
 
 
2316
      RETURN
 
2317
C
 
2318
C-----------------------------------------------------------------------
 
2319
C     This block handles all unsuccessful returns other than for
 
2320
C     illegal input.
 
2321
C-----------------------------------------------------------------------
 
2322
C
 
2323
600   CONTINUE
 
2324
      ITEMP = -IDID
 
2325
      GO TO (610,620,630,700,655,640,650,660,670,675,
 
2326
     *  680,685,690,695,696), ITEMP
 
2327
C
 
2328
C     The maximum number of steps was taken before
 
2329
C     reaching tout.
 
2330
C
 
2331
610   MSG = 'DASKR--  AT CURRENT T (=R1)  500 STEPS'
 
2332
      CALL XERRWD(MSG,38,610,0,0,0,0,1,TN,0.0D0)
 
2333
      MSG = 'DASKR--  TAKEN ON THIS CALL BEFORE REACHING TOUT'
 
2334
      CALL XERRWD(MSG,48,611,0,0,0,0,0,0.0D0,0.0D0)
 
2335
      GO TO 700
 
2336
C
 
2337
C     Too much accuracy for machine precision.
 
2338
C
 
2339
620   MSG = 'DASKR--  AT T (=R1) TOO MUCH ACCURACY REQUESTED'
 
2340
      CALL XERRWD(MSG,47,620,0,0,0,0,1,TN,0.0D0)
 
2341
      MSG = 'DASKR--  FOR PRECISION OF MACHINE. RTOL AND ATOL'
 
2342
      CALL XERRWD(MSG,48,621,0,0,0,0,0,0.0D0,0.0D0)
 
2343
      MSG = 'DASKR--  WERE INCREASED BY A FACTOR R (=R1)'
 
2344
      CALL XERRWD(MSG,43,622,0,0,0,0,1,R,0.0D0)
 
2345
      GO TO 700
 
2346
C
 
2347
C     WT(I) .LE. 0.0D0 for some I (not at start of problem).
 
2348
C
 
2349
630   MSG = 'DASKR--  AT T (=R1) SOME ELEMENT OF WT'
 
2350
      CALL XERRWD(MSG,38,630,0,0,0,0,1,TN,0.0D0)
 
2351
      MSG = 'DASKR--  HAS BECOME .LE. 0.0'
 
2352
      CALL XERRWD(MSG,28,631,0,0,0,0,0,0.0D0,0.0D0)
 
2353
      GO TO 700
 
2354
C
 
2355
C     Error test failed repeatedly or with H=HMIN.
 
2356
C
 
2357
640   MSG = 'DASKR--  AT T (=R1) AND STEPSIZE H (=R2) THE'
 
2358
      CALL XERRWD(MSG,44,640,0,0,0,0,2,TN,H)
 
2359
      MSG='DASKR--  ERROR TEST FAILED REPEATEDLY OR WITH ABS(H)=HMIN'
 
2360
      CALL XERRWD(MSG,57,641,0,0,0,0,0,0.0D0,0.0D0)
 
2361
      GO TO 700
 
2362
C
 
2363
C     Nonlinear solver failed to converge repeatedly or with H=HMIN.
 
2364
C
 
2365
650   MSG = 'DASKR--  AT T (=R1) AND STEPSIZE H (=R2) THE'
 
2366
      CALL XERRWD(MSG,44,650,0,0,0,0,2,TN,H)
 
2367
      MSG = 'DASKR--  NONLINEAR SOLVER FAILED TO CONVERGE'
 
2368
      CALL XERRWD(MSG,44,651,0,0,0,0,0,0.0D0,0.0D0)
 
2369
      MSG = 'DASKR--  REPEATEDLY OR WITH ABS(H)=HMIN'
 
2370
      CALL XERRWD(MSG,40,652,0,0,0,0,0,0.0D0,0.0D0)
 
2371
      GO TO 700
 
2372
C
 
2373
C     The preconditioner had repeated failures.
 
2374
C
 
2375
655   MSG = 'DASKR--  AT T (=R1) AND STEPSIZE H (=R2) THE'
 
2376
      CALL XERRWD(MSG,44,655,0,0,0,0,2,TN,H)
 
2377
      MSG = 'DASKR--  PRECONDITIONER HAD REPEATED FAILURES.'
 
2378
      CALL XERRWD(MSG,46,656,0,0,0,0,0,0.0D0,0.0D0)
 
2379
      GO TO 700
 
2380
C
 
2381
C     The iteration matrix is singular.
 
2382
C
 
2383
660   MSG = 'DASKR--  AT T (=R1) AND STEPSIZE H (=R2) THE'
 
2384
      CALL XERRWD(MSG,44,660,0,0,0,0,2,TN,H)
 
2385
      MSG = 'DASKR--  ITERATION MATRIX IS SINGULAR.'
 
2386
      CALL XERRWD(MSG,38,661,0,0,0,0,0,0.0D0,0.0D0)
 
2387
      GO TO 700
 
2388
C
 
2389
C     Nonlinear system failure preceded by error test failures.
 
2390
C
 
2391
670   MSG = 'DASKR--  AT T (=R1) AND STEPSIZE H (=R2) THE'
 
2392
      CALL XERRWD(MSG,44,670,0,0,0,0,2,TN,H)
 
2393
      MSG = 'DASKR--  NONLINEAR SOLVER COULD NOT CONVERGE.'
 
2394
      CALL XERRWD(MSG,45,671,0,0,0,0,0,0.0D0,0.0D0)
 
2395
      MSG = 'DASKR--  ALSO, THE ERROR TEST FAILED REPEATEDLY.'
 
2396
      CALL XERRWD(MSG,49,672,0,0,0,0,0,0.0D0,0.0D0)
 
2397
      GO TO 700
 
2398
C
 
2399
C     Nonlinear system failure because IRES = -1.
 
2400
C
 
2401
675   MSG = 'DASKR--  AT T (=R1) AND STEPSIZE H (=R2) THE'
 
2402
      CALL XERRWD(MSG,44,675,0,0,0,0,2,TN,H)
 
2403
      MSG = 'DASKR--  NONLINEAR SYSTEM SOLVER COULD NOT CONVERGE'
 
2404
      CALL XERRWD(MSG,51,676,0,0,0,0,0,0.0D0,0.0D0)
 
2405
      MSG = 'DASKR--  BECAUSE IRES WAS EQUAL TO MINUS ONE'
 
2406
      CALL XERRWD(MSG,44,677,0,0,0,0,0,0.0D0,0.0D0)
 
2407
      GO TO 700
 
2408
C
 
2409
C     Failure because IRES = -2.
 
2410
C
 
2411
680   MSG = 'DASKR--  AT T (=R1) AND STEPSIZE H (=R2)'
 
2412
      CALL XERRWD(MSG,40,680,0,0,0,0,2,TN,H)
 
2413
      MSG = 'DASKR--  IRES WAS EQUAL TO MINUS TWO'
 
2414
      CALL XERRWD(MSG,36,681,0,0,0,0,0,0.0D0,0.0D0)
 
2415
      GO TO 700
 
2416
C
 
2417
C     Failed to compute initial YPRIME.
 
2418
C
 
2419
685   MSG = 'DASKR--  AT T (=R1) AND STEPSIZE H (=R2) THE'
 
2420
      CALL XERRWD(MSG,44,685,0,0,0,0,0,0.0D0,0.0D0)
 
2421
      MSG = 'DASKR--  INITIAL (Y,YPRIME) COULD NOT BE COMPUTED'
 
2422
      CALL XERRWD(MSG,49,686,0,0,0,0,2,TN,H0)
 
2423
      GO TO 700
 
2424
C
 
2425
C     Failure because IER was negative from PSOL.
 
2426
C
 
2427
690   MSG = 'DASKR--  AT T (=R1) AND STEPSIZE H (=R2)'
 
2428
      CALL XERRWD(MSG,40,690,0,0,0,0,2,TN,H)
 
2429
      MSG = 'DASKR--  IER WAS NEGATIVE FROM PSOL'
 
2430
      CALL XERRWD(MSG,35,691,0,0,0,0,0,0.0D0,0.0D0)
 
2431
      GO TO 700
 
2432
C
 
2433
C     Failure because the linear system solver could not converge.
 
2434
C
 
2435
695   MSG = 'DASKR--  AT T (=R1) AND STEPSIZE H (=R2) THE'
 
2436
      CALL XERRWD(MSG,44,695,0,0,0,0,2,TN,H)
 
2437
      MSG = 'DASKR--  LINEAR SYSTEM SOLVER COULD NOT CONVERGE.'
 
2438
      CALL XERRWD(MSG,50,696,0,0,0,0,0,0.0D0,0.0D0)
 
2439
      GO TO 700
 
2440
C
 
2441
 696  MSG = 'DASKR--  AT T (=R1) AND STEPSIZE H (=R2) THE'
 
2442
      CALL XERRWD(MSG,44,685,0,0,0,0,0,0.0D0,0.0D0)
 
2443
      MSG = 'DASKR--  INITIAL Jacobian COULD NOT BE COMPUTED'
 
2444
      CALL XERRWD(MSG,49,686,0,0,0,0,2,TN,H0)
 
2445
      GO TO 700
 
2446
C
 
2447
C
 
2448
700   CONTINUE
 
2449
      INFO(1)=-1
 
2450
      T=TN
 
2451
      RWORK(LTN)=TN
 
2452
      RWORK(LH)=H
 
2453
      RETURN
 
2454
C
 
2455
C-----------------------------------------------------------------------
 
2456
C     This block handles all error returns due to illegal input,
 
2457
C     as detected before calling DDSTP.
 
2458
C     First the error message routine is called.  If this happens
 
2459
C     twice in succession, execution is terminated.
 
2460
C-----------------------------------------------------------------------
 
2461
C
 
2462
701   MSG = 'DASKR--  ELEMENT (=I1) OF INFO VECTOR IS NOT VALID'
 
2463
      CALL XERRWD(MSG,50,1,0,1,ITEMP,0,0,0.0D0,0.0D0)
 
2464
      GO TO 750
 
2465
702   MSG = 'DASKR--  NEQ (=I1) .LE. 0'
 
2466
      CALL XERRWD(MSG,25,2,0,1,NEQ,0,0,0.0D0,0.0D0)
 
2467
      GO TO 750
 
2468
703   MSG = 'DASKR--  MAXORD (=I1) NOT IN RANGE'
 
2469
      CALL XERRWD(MSG,34,3,0,1,MXORD,0,0,0.0D0,0.0D0)
 
2470
      GO TO 750
 
2471
704   MSG='DASKR--  RWORK LENGTH NEEDED, LENRW (=I1), EXCEEDS LRW (=I2)'
 
2472
      CALL XERRWD(MSG,60,4,0,2,LENRW,LRW,0,0.0D0,0.0D0)
 
2473
      GO TO 750
 
2474
705   MSG='DASKR--  IWORK LENGTH NEEDED, LENIW (=I1), EXCEEDS LIW (=I2)'
 
2475
      CALL XERRWD(MSG,60,5,0,2,LENIW,LIW,0,0.0D0,0.0D0)
 
2476
      GO TO 750
 
2477
706   MSG = 'DASKR--  SOME ELEMENT OF RTOL IS .LT. 0'
 
2478
      CALL XERRWD(MSG,39,6,0,0,0,0,0,0.0D0,0.0D0)
 
2479
      GO TO 750
 
2480
707   MSG = 'DASKR--  SOME ELEMENT OF ATOL IS .LT. 0'
 
2481
      CALL XERRWD(MSG,39,7,0,0,0,0,0,0.0D0,0.0D0)
 
2482
      GO TO 750
 
2483
708   MSG = 'DASKR--  ALL ELEMENTS OF RTOL AND ATOL ARE ZERO'
 
2484
      CALL XERRWD(MSG,47,8,0,0,0,0,0,0.0D0,0.0D0)
 
2485
      GO TO 750
 
2486
709   MSG='DASKR--  INFO(4) = 1 AND TSTOP (=R1) BEHIND TOUT (=R2)'
 
2487
      CALL XERRWD(MSG,54,9,0,0,0,0,2,TSTOP,TOUT)
 
2488
      GO TO 750
 
2489
710   MSG = 'DASKR--  HMAX (=R1) .LT. 0.0'
 
2490
      CALL XERRWD(MSG,28,10,0,0,0,0,1,HMAX,0.0D0)
 
2491
      GO TO 750
 
2492
711   MSG = 'DASKR--  TOUT (=R1) BEHIND T (=R2)'
 
2493
      CALL XERRWD(MSG,34,11,0,0,0,0,2,TOUT,T)
 
2494
      GO TO 750
 
2495
712   MSG = 'DASKR--  INFO(8)=1 AND H0=0.0'
 
2496
      CALL XERRWD(MSG,29,12,0,0,0,0,0,0.0D0,0.0D0)
 
2497
      GO TO 750
 
2498
713   MSG = 'DASKR--  SOME ELEMENT OF WT IS .LE. 0.0'
 
2499
      CALL XERRWD(MSG,39,13,0,0,0,0,0,0.0D0,0.0D0)
 
2500
      GO TO 750
 
2501
714   MSG='DASKR-- TOUT (=R1) TOO CLOSE TO T (=R2) TO START INTEGRATION'
 
2502
      CALL XERRWD(MSG,60,14,0,0,0,0,2,TOUT,T)
 
2503
      GO TO 750
 
2504
715   MSG = 'DASKR--  INFO(4)=1 AND TSTOP (=R1) BEHIND T (=R2)'
 
2505
      CALL XERRWD(MSG,49,15,0,0,0,0,2,TSTOP,T)
 
2506
      GO TO 750
 
2507
717   MSG = 'DASKR--  ML (=I1) ILLEGAL. EITHER .LT. 0 OR .GT. NEQ'
 
2508
      CALL XERRWD(MSG,52,17,0,1,IWORK(LML),0,0,0.0D0,0.0D0)
 
2509
      GO TO 750
 
2510
718   MSG = 'DASKR--  MU (=I1) ILLEGAL. EITHER .LT. 0 OR .GT. NEQ'
 
2511
      CALL XERRWD(MSG,52,18,0,1,IWORK(LMU),0,0,0.0D0,0.0D0)
 
2512
      GO TO 750
 
2513
719   MSG = 'DASKR--  TOUT (=R1) IS EQUAL TO T (=R2)'
 
2514
      CALL XERRWD(MSG,39,19,0,0,0,0,2,TOUT,T)
 
2515
      GO TO 750
 
2516
720   MSG = 'DASKR--  MAXL (=I1) ILLEGAL. EITHER .LT. 1 OR .GT. NEQ'
 
2517
      CALL XERRWD(MSG,54,20,0,1,IWORK(LMAXL),0,0,0.0D0,0.0D0)
 
2518
      GO TO 750
 
2519
721   MSG = 'DASKR--  KMP (=I1) ILLEGAL. EITHER .LT. 1 OR .GT. MAXL'
 
2520
      CALL XERRWD(MSG,54,21,0,1,IWORK(LKMP),0,0,0.0D0,0.0D0)
 
2521
      GO TO 750
 
2522
722   MSG = 'DASKR--  NRMAX (=I1) ILLEGAL. .LT. 0'
 
2523
      CALL XERRWD(MSG,36,22,0,1,IWORK(LNRMAX),0,0,0.0D0,0.0D0)
 
2524
      GO TO 750
 
2525
723   MSG = 'DASKR--  EPLI (=R1) ILLEGAL. EITHER .LE. 0.D0 OR .GE. 1.D0'
 
2526
      CALL XERRWD(MSG,58,23,0,0,0,0,1,RWORK(LEPLI),0.0D0)
 
2527
      GO TO 750
 
2528
724   MSG = 'DASKR--  ILLEGAL IWORK VALUE FOR INFO(11) .NE. 0'
 
2529
      CALL XERRWD(MSG,48,24,0,0,0,0,0,0.0D0,0.0D0)
 
2530
      GO TO 750
 
2531
725   MSG = 'DASKR--  ONE OF THE INPUTS FOR INFO(17) = 1 IS ILLEGAL'
 
2532
      CALL XERRWD(MSG,54,25,0,0,0,0,0,0.0D0,0.0D0)
 
2533
      GO TO 750
 
2534
726   MSG = 'DASKR--  ILLEGAL IWORK VALUE FOR INFO(10) .NE. 0'
 
2535
      CALL XERRWD(MSG,48,26,0,0,0,0,0,0.0D0,0.0D0)
 
2536
      GO TO 750
 
2537
727   MSG = 'DASKR--  Y(I) AND IWORK(40+I) (I=I1) INCONSISTENT'
 
2538
      CALL XERRWD(MSG,49,27,0,1,IRET,0,0,0.0D0,0.0D0)
 
2539
      GO TO 750
 
2540
730   MSG = 'DASKR--  NRT (=I1) .LT. 0'
 
2541
      CALL XERRWD(MSG,25,30,1,1,NRT,0,0,0.0D0,0.0D0)
 
2542
      GO TO 750
 
2543
731   MSG = 'DASKR--  R IS ILL-DEFINED.  ZERO VALUES WERE FOUND AT TWO'
 
2544
      CALL XERRWD(MSG,57,31,1,0,0,0,0,0.0D0,0.0D0)
 
2545
      MSG = '         VERY CLOSE T VALUES, AT T = R1'
 
2546
      CALL XERRWD(MSG,39,31,1,0,0,0,1,RWORK(LT0),0.0D0)
 
2547
C
 
2548
750   IF(INFO(1).EQ.-1) GO TO 760
 
2549
      INFO(1)=-1
 
2550
      IDID=-33
 
2551
      RETURN
 
2552
760   MSG = 'DASKR--  REPEATED OCCURRENCES OF ILLEGAL INPUT'
 
2553
      CALL XERRWD(MSG,46,701,0,0,0,0,0,0.0D0,0.0D0)
 
2554
770   MSG = 'DASKR--  RUN TERMINATED. APPARENT INFINITE LOOP'
 
2555
      CALL XERRWD(MSG,47,702,1,0,0,0,0,0.0D0,0.0D0)
 
2556
      RETURN
 
2557
C
 
2558
C------END OF SUBROUTINE DDASKR-----------------------------------------
 
2559
      END
 
2560
      SUBROUTINE DRCHEK1 (JOB, RT, NRT, NEQ, TN, TOUT, Y, YP, PHI, PSI,
 
2561
     *     KOLD, R0, R1, RX, JROOT, IRT, UROUND, INFO3, RWORK, IWORK,
 
2562
     *     RPAR, IPAR)
 
2563
C     
 
2564
C***  BEGIN PROLOGUE  DRCHEK
 
2565
C***  REFER TO DDASKR
 
2566
C***  ROUTINES CALLED  DDATRP, DROOTS, DCOPY, RT
 
2567
C***  REVISION HISTORY  (YYMMDD)
 
2568
C     020815  DATE WRITTEN   
 
2569
C     021217  Added test for roots close when JOB = 2.
 
2570
C***  END PROLOGUE  DRCHEK
 
2571
C     
 
2572
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
2573
C Pointers into IWORK:
 
2574
      PARAMETER (LNRTE=36, LIRFND=37)
 
2575
C     Pointers into RWORK:
 
2576
      PARAMETER (LT0=51, LTLAST=52)
 
2577
      EXTERNAL RT
 
2578
      INTEGER JOB, NRT, NEQ, KOLD, JROOT, IRT, INFO3, IWORK, IPAR
 
2579
      DOUBLE PRECISION TN, TOUT, Y, YP, PHI, PSI, R0, R1, RX, UROUND,
 
2580
     *     RWORK, RPAR
 
2581
      DIMENSION Y(*), YP(*), PHI(NEQ,*), PSI(*),
 
2582
     *          R0(*), R1(*), RX(*), JROOT(*), RWORK(*), IWORK(*)
 
2583
      INTEGER I, JFLAG, LMASK
 
2584
      DOUBLE PRECISION H
 
2585
      DOUBLE PRECISION HMINR, T1, TEMP1, TEMP2, X, ZERO
 
2586
      LOGICAL ZROOT
 
2587
c     -------------- masking -----------------
 
2588
      PARAMETER (LNIW=17)
 
2589
      DATA ZERO/0.0D0/
 
2590
 
 
2591
c     -------------- masking -----------------
 
2592
 
 
2593
C-----------------------------------------------------------------------
 
2594
C This routine checks for the presence of a root of R(T,Y,Y') in the
 
2595
C vicinity of the current T, in a manner depending on the
 
2596
C input flag JOB.  It calls subroutine DROOTS to locate the root
 
2597
C as precisely as possible.
 
2598
C
 
2599
C In addition to variables described previously, DRCHEK
 
2600
C uses the following for communication..
 
2601
C JOB    = integer flag indicating type of call..
 
2602
C          JOB = 1 means the problem is being initialized, and DRCHEK
 
2603
C                  is to look for a root at or very near the initial T.
 
2604
C          JOB = 2 means a continuation call to the solver was just
 
2605
C                  made, and DRCHEK is to check for a root in the
 
2606
C                  relevant part of the step last taken.
 
2607
C          JOB = 3 means a successful step was just taken, and DRCHEK
 
2608
C                  is to look for a root in the interval of the step.
 
2609
C R0     = array of length NRT, containing the value of R at T = T0.
 
2610
C          R0 is input for JOB .ge. 2 and on output in all cases.
 
2611
C R1,RX  = arrays of length NRT for work space.
 
2612
C IRT    = completion flag..
 
2613
C          IRT = 0  means no root was found.
 
2614
C          IRT = -1 means JOB = 1 and a zero was found both at T0 and
 
2615
C                   and very close to T0.
 
2616
C          IRT = -2 means JOB = 2 and some Ri was found to have a zero
 
2617
C                   both at T0 and very close to T0.
 
2618
C          IRT = 1  means a legitimate root was found (JOB = 2 or 3).
 
2619
C                   On return, T0 is the root location, and Y is the
 
2620
C                   corresponding solution vector.
 
2621
c          IRT = 2  A zero-crossing surface has detached from zero
 
2622
c
 
2623
C T0     = value of T at one endpoint of interval of interest.  Only
 
2624
C          roots beyond T0 in the direction of integration are sought.
 
2625
C          T0 is input if JOB .ge. 2, and output in all cases.
 
2626
C          T0 is updated by DRCHEK, whether a root is found or not.
 
2627
C          Stored in the global array RWORK.
 
2628
C TLAST  = last value of T returned by the solver (input only).
 
2629
C          Stored in the global array RWORK.
 
2630
C TOUT   = final output time for the solver.
 
2631
C IRFND  = input flag showing whether the last step taken had a root.
 
2632
C          IRFND = 1 if it did, = 0 if not.
 
2633
C          Stored in the global array IWORK.
 
2634
C INFO3  = copy of INFO(3) (input only).
 
2635
C-----------------------------------------------------------------------
 
2636
C     
 
2637
      H = PSI(1)
 
2638
      IRT = 0
 
2639
      LMASK=IWORK(LNIW)-NRT
 
2640
      HMINR = (ABS(TN) + ABS(H))*UROUND*100.0D0
 
2641
 
 
2642
      GO TO (100, 200, 300), JOB
 
2643
C
 
2644
C Evaluate R at initial T (= RWORK(LT0)); check for zero values.--------
 
2645
 100  CONTINUE
 
2646
      DO 103 I = 1,NRT
 
2647
         JROOT(I) = 0
 
2648
 103     IWORK(LMASK+I)=0
 
2649
      CALL DDATRP1(TN,RWORK(LT0),Y,YP,NEQ,KOLD,PHI,PSI)
 
2650
      CALL RT (NEQ, RWORK(LT0), Y, YP, NRT, R0, RPAR, IPAR)
 
2651
      IWORK(LNRTE) = 1
 
2652
      ZROOT = .FALSE.
 
2653
      DO 110 I = 1,NRT
 
2654
         IF (DABS(R0(I)) .EQ. ZERO) THEN
 
2655
            ZROOT = .TRUE.
 
2656
            JROOT(I)=1
 
2657
         ENDIF
 
2658
 110  CONTINUE
 
2659
 
 
2660
      IF (.NOT. ZROOT) GO TO 190
 
2661
C R has a zero at T.  Look at R at T + (small increment). --------------
 
2662
      TEMP1 = SIGN(HMINR,H)
 
2663
      RWORK(LT0) = RWORK(LT0) + TEMP1
 
2664
      TEMP2 = TEMP1/H
 
2665
      DO 120 I = 1,NEQ
 
2666
 120    Y(I) = Y(I) + TEMP2*PHI(I,2)
 
2667
      CALL RT (NEQ, RWORK(LT0), Y, YP, NRT, R0, RPAR, IPAR)
 
2668
      IWORK(LNRTE) = IWORK(LNRTE) + 1
 
2669
C     ---------   MASKING THE STUCK ZEROS IN COLD-RESTARTS 
 
2670
      IRT = 0
 
2671
      DO 130 I = 1,NRT
 
2672
         IF (JROOT(I) .EQ. 1) THEN
 
2673
            IF (ABS(R0(I)) .EQ. ZERO) THEN
 
2674
               IWORK(LMASK+I)=1
 
2675
            ELSE
 
2676
c     .        to take one step through DDSTP then then in the next arrival->exit!
 
2677
               IRT = 2
 
2678
               JROOT(I)=SIGN(2.0D0,R0(I))
 
2679
            ENDIF
 
2680
         ENDIF
 
2681
 130   CONTINUE
 
2682
 190   CONTINUE
 
2683
 
 
2684
       RETURN
 
2685
C     
 
2686
 200   CONTINUE
 
2687
c     in the previous call there was not a root, so this part can be ignored.
 
2688
       IF (IWORK(LIRFND) .EQ. 0) GO TO 260
 
2689
c     --------------- INITIALIZING THE MASKS 
 
2690
       DO 203 I = 1,NRT
 
2691
          JROOT(I) = 0
 
2692
 203      IWORK(LMASK+I)=0
 
2693
C     If a root was found on the previous step, evaluate R0 = R(T0). -------
 
2694
       CALL DDATRP1 (TN, RWORK(LT0), Y, YP, NEQ, KOLD, PHI, PSI)
 
2695
       CALL RT (NEQ, RWORK(LT0), Y, YP, NRT, R0, RPAR, IPAR)
 
2696
       IWORK(LNRTE) = IWORK(LNRTE) + 1
 
2697
       ZROOT = .FALSE.
 
2698
       DO 210 I = 1,NRT
 
2699
          IF (ABS(R0(I)) .EQ. ZERO) THEN
 
2700
             ZROOT = .TRUE.
 
2701
             JROOT(I) = 1
 
2702
          ENDIF
 
2703
 210   CONTINUE
 
2704
 
 
2705
       IF (.NOT. ZROOT) GO TO 260
 
2706
C     R has a zero at T0.  Look at R at T0+ = T0 + (small increment). ------
 
2707
       TEMP1 = SIGN(HMINR,H)
 
2708
       RWORK(LT0) = RWORK(LT0) + TEMP1
 
2709
       IF ((RWORK(LT0) - TN)*H .LT. ZERO) GO TO 230
 
2710
       TEMP2 = TEMP1/H
 
2711
       DO 220 I = 1,NEQ
 
2712
          Y(I) = Y(I) + TEMP2*PHI(I,2)
 
2713
 220   continue
 
2714
       GO TO 240
 
2715
 230   CALL DDATRP1 (TN, RWORK(LT0), Y, YP, NEQ, KOLD, PHI, PSI)
 
2716
 240   CALL RT (NEQ, RWORK(LT0), Y, YP, NRT, R0, RPAR, IPAR)
 
2717
       IWORK(LNRTE) = IWORK(LNRTE) + 1
 
2718
       DO 250 I = 1,NRT
 
2719
          IF (ABS(R0(I)) .GT. ZERO) GO TO 250
 
2720
C     If Ri has a zero at both T0+ and T0, return an error flag. -----------
 
2721
          IF (JROOT(I) .EQ. 1) THEN
 
2722
C     .      MASKING THE STUCK ZEROS IN HOT-RESTARTS 
 
2723
             IWORK(LMASK+I)=1
 
2724
             JROOT(I)=0
 
2725
          ELSE
 
2726
C     If Ri has a zero at T0+, but not at T0, return valid root. -----------
 
2727
             JROOT(I) = -SIGN(1.0D0,R0(I))
 
2728
             IRT = 1
 
2729
          ENDIF
 
2730
 250   CONTINUE
 
2731
 
 
2732
       IF (IRT .EQ. 1)  RETURN
 
2733
C     R0 has no zero components.  Proceed to check relevant interval. ------
 
2734
 260   IF (TN .EQ. RWORK(LTLAST)) RETURN
 
2735
C     
 
2736
 300   CONTINUE
 
2737
C     AT THE BEGINING OF THE PREVIOUS STEP THERE WERE A MASK-LIFTING
 
2738
       IF (IWORK(LIRFND) .EQ. 2) THEN
 
2739
          IWORK(LIRFND)=0  
 
2740
          IRT=2
 
2741
          RETURN
 
2742
       ENDIF
 
2743
C     Set T1 to TN or TOUT, whichever comes first, and get R at T1. --------
 
2744
       IF (INFO3 .EQ. 1 .OR. (TOUT - TN)*H .GE. ZERO) THEN
 
2745
          T1 = TN
 
2746
          GO TO 330
 
2747
       ENDIF
 
2748
       T1 = TOUT
 
2749
       IF ((T1 - RWORK(LT0))*H .LE. ZERO) RETURN
 
2750
 330   CALL DDATRP1 (TN, T1, Y, YP, NEQ, KOLD, PHI, PSI)
 
2751
       CALL RT (NEQ, T1, Y, YP, NRT, R1, RPAR, IPAR)
 
2752
       IWORK(LNRTE) = IWORK(LNRTE) + 1
 
2753
C     .   PASSING THE MASK THROUGH DROOT2 VIA JROOT(I)
 
2754
       DO 331 I = 1,NRT
 
2755
          JROOT(I)=0
 
2756
 331      IF(IWORK(LMASK+I).EQ.1) jroot(i)=1
 
2757
C     Call DROOTS to search for root in interval from T0 to T1. -----------
 
2758
       JFLAG = 0
 
2759
 350   CONTINUE
 
2760
       CALL DROOTS1(NRT, HMINR, JFLAG,RWORK(LT0),T1, R0,R1,RX, X, JROOT)
 
2761
       IF (JFLAG .GT. 1) GO TO 360
 
2762
       CALL DDATRP1 (TN, X, Y, YP, NEQ, KOLD, PHI, PSI)
 
2763
       CALL RT (NEQ, X, Y, YP, NRT, RX, RPAR, IPAR)
 
2764
       IWORK(LNRTE) = IWORK(LNRTE) + 1
 
2765
       GO TO 350
 
2766
 360   RWORK(LT0) = X
 
2767
       CALL DCOPY (NRT, RX, 1, R0, 1)
 
2768
       IF (JFLAG .NE. 4) THEN
 
2769
          CALL DDATRP1 (TN, X, Y, YP, NEQ, KOLD, PHI, PSI)
 
2770
          
 
2771
          ZROOT=.FALSE.
 
2772
          DO 370 I = 1,NRT
 
2773
             IF(ABS(JROOT(I)).EQ.1) THEN 
 
2774
                ZROOT=.TRUE.
 
2775
                GOTO 375
 
2776
             ENDIF
 
2777
 370      CONTINUE
 
2778
 375      CONTINUE         
 
2779
          IF(ZROOT) THEN
 
2780
             DO 380 I = 1,NRT
 
2781
                IF(ABS(JROOT(I)).EQ.2) JROOT(I)=0
 
2782
 380         CONTINUE  
 
2783
             IRT=1
 
2784
          ELSE
 
2785
             IRT=2
 
2786
          ENDIF
 
2787
       ENDIF
 
2788
       RETURN
 
2789
C---------------------- END OF SUBROUTINE DRCHE -----------------------
 
2790
      END
 
2791
      SUBROUTINE DROOTS1(NRT, HMIN, JFLAG, X0, X1, R0, R1, RX, X, JROOT)
 
2792
C
 
2793
C***BEGIN PROLOGUE  DROOTS
 
2794
C***REFER TO DRCHEK
 
2795
C***ROUTINES CALLED DCOPY
 
2796
C***REVISION HISTORY  (YYMMDD)
 
2797
C   020815  DATE WRITTEN   
 
2798
C   021217  Added root direction information in JROOT.
 
2799
C***END PROLOGUE  DROOTS
 
2800
C
 
2801
      INTEGER NRT, JFLAG, JROOT
 
2802
      DOUBLE PRECISION HMIN, X0, X1, R0, R1, RX, X
 
2803
      DIMENSION R0(NRT), R1(NRT), RX(NRT), JROOT(NRT)
 
2804
C-----------------------------------------------------------------------
 
2805
C This subroutine finds the leftmost root of a set of arbitrary
 
2806
C functions Ri(x) (i = 1,...,NRT) in an interval (X0,X1).  Only roots
 
2807
C of odd multiplicity (i.e. changes of sign of the Ri) are found.
 
2808
C Here the sign of X1 - X0 is arbitrary, but is constant for a given
 
2809
C problem, and -leftmost- means nearest to X0.
 
2810
C The values of the vector-valued function R(x) = (Ri, i=1...NRT)
 
2811
C are communicated through the call sequence of DROOTS.
 
2812
C The method used is the Illinois algorithm.
 
2813
C
 
2814
C Reference:
 
2815
C Kathie L. Hiebert and Lawrence F. Shampine, Implicitly Defined
 
2816
C Output Points for Solutions of ODEs, Sandia Report SAND80-0180,
 
2817
C February 1980.
 
2818
C
 
2819
C Description of parameters.
 
2820
C
 
2821
C NRT    = number of functions Ri, or the number of components of
 
2822
C          the vector valued function R(x).  Input only.
 
2823
C
 
2824
C HMIN   = resolution parameter in X.  Input only.  When a root is
 
2825
C          found, it is located only to within an error of HMIN in X.
 
2826
C          Typically, HMIN should be set to something on the order of
 
2827
C               100 * UROUND * MAX(ABS(X0),ABS(X1)),
 
2828
C          where UROUND is the unit roundoff of the machine.
 
2829
C
 
2830
C JFLAG  = integer flag for input and output communication.
 
2831
C
 
2832
C          On input, set JFLAG = 0 on the first call for the problem,
 
2833
C          and leave it unchanged until the problem is completed.
 
2834
C          (The problem is completed when JFLAG .ge. 2 on return.)
 
2835
C
 
2836
C          On output, JFLAG has the following values and meanings:
 
2837
C          JFLAG = 1 means DROOTS needs a value of R(x).  Set RX = R(X)
 
2838
C                    and call DROOTS again.
 
2839
C          JFLAG = 2 means a root has been found.  The root is
 
2840
C                    at X, and RX contains R(X).  (Actually, X is the
 
2841
C                    rightmost approximation to the root on an interval
 
2842
C                    (X0,X1) of size HMIN or less.)
 
2843
C          JFLAG = 3 means X = X1 is a root, with one or more of the Ri
 
2844
C                    being zero at X1 and no sign changes in (X0,X1).
 
2845
C                    RX contains R(X) on output.
 
2846
C          JFLAG = 4 means no roots (of odd multiplicity) were
 
2847
C                    found in (X0,X1) (no sign changes).
 
2848
C
 
2849
C X0,X1  = endpoints of the interval where roots are sought.
 
2850
C          X1 and X0 are input when JFLAG = 0 (first call), and
 
2851
C          must be left unchanged between calls until the problem is
 
2852
C          completed.  X0 and X1 must be distinct, but X1 - X0 may be
 
2853
C          of either sign.  However, the notion of -left- and -right-
 
2854
C          will be used to mean nearer to X0 or X1, respectively.
 
2855
C          When JFLAG .ge. 2 on return, X0 and X1 are output, and
 
2856
C          are the endpoints of the relevant interval.
 
2857
C
 
2858
C R0,R1  = arrays of length NRT containing the vectors R(X0) and R(X1),
 
2859
C          respectively.  When JFLAG = 0, R0 and R1 are input and
 
2860
C          none of the R0(i) should be zero.
 
2861
C          When JFLAG .ge. 2 on return, R0 and R1 are output.
 
2862
C
 
2863
C RX     = array of length NRT containing R(X).  RX is input
 
2864
C          when JFLAG = 1, and output when JFLAG .ge. 2.
 
2865
C
 
2866
C X      = independent variable value.  Output only.
 
2867
C          When JFLAG = 1 on output, X is the point at which R(x)
 
2868
C          is to be evaluated and loaded into RX.
 
2869
C          When JFLAG = 2 or 3, X is the root.
 
2870
C          When JFLAG = 4, X is the right endpoint of the interval, X1.
 
2871
C
 
2872
C JROOT  = integer array of length NRT.  Output only.
 
2873
C          When JFLAG = 2 or 3, JROOT indicates which components
 
2874
C          of R(x) have a root at X, and the direction of the sign
 
2875
C          change across the root in the direction of integration.
 
2876
C          JROOT(i) =  1 if Ri has a root and changes from - to +.
 
2877
C          JROOT(i) = -1 if Ri has a root and changes from + to -.
 
2878
C          Otherwise JROOT(i) = 0.
 
2879
C-----------------------------------------------------------------------
 
2880
      INTEGER I, IMAX, IMXOLD, LAST, NXLAST,ISTUCK,IUNSTUCK
 
2881
      DOUBLE PRECISION ALPHA, T2, TMAX, X2, ZERO,FRACINT,FRACSUB,TENTH
 
2882
     $     ,HALF,FIVE
 
2883
      LOGICAL ZROOT, SGNCHG, XROOT
 
2884
      SAVE ALPHA, X2, IMAX, LAST
 
2885
      DATA ZERO/0.0D0/, TENTH/0.1D0/, HALF/0.5D0/, FIVE/5.0D0/
 
2886
c
 
2887
 
 
2888
      IF (JFLAG .EQ. 1) GO TO 200
 
2889
C JFLAG .ne. 1.  Check for change in sign of R or zero at X1. ----------
 
2890
      IMAX = 0
 
2891
      ISTUCK=0
 
2892
      IUNSTUCK=0
 
2893
      TMAX = ZERO
 
2894
      ZROOT = .FALSE.
 
2895
      DO 120 I = 1,NRT
 
2896
         if ((jroot(i) .eq. 1).AND.((ABS(R1(I)) .GT. ZERO))) IUNSTUCK=I
 
2897
         IF (ABS(R1(I)) .GT. ZERO) GO TO 110
 
2898
         if (jroot(i) .eq. 1) GOTO 120
 
2899
         ISTUCK=I
 
2900
         GO TO 120
 
2901
C     At this point, R0(i) has been checked and cannot be zero. ------------
 
2902
 110     IF (SIGN(1.0D0,R0(I)) .EQ. SIGN(1.0D0,R1(I))) GO TO 120
 
2903
         T2 = ABS(R1(I)/(R1(I)-R0(I)))
 
2904
         IF (T2 .LE. TMAX) GO TO 120
 
2905
         TMAX = T2
 
2906
         IMAX = I
 
2907
 120  CONTINUE
 
2908
      IF (IMAX .GT. 0) GO TO 130
 
2909
      IMAX=ISTUCK
 
2910
      IF (IMAX .GT. 0) GO TO 130
 
2911
      IMAX=IUNSTUCK
 
2912
      IF (IMAX .GT. 0) GO TO 130
 
2913
 
 
2914
      SGNCHG = .FALSE.
 
2915
      GO TO 140
 
2916
 130  SGNCHG = .TRUE.
 
2917
 140  IF (.NOT. SGNCHG) GO TO 420
 
2918
C There is a sign change.  Find the first root in the interval. --------
 
2919
      XROOT = .FALSE.
 
2920
      NXLAST = 0
 
2921
      LAST = 1
 
2922
C
 
2923
C Repeat until the first root in the interval is found.  Loop point. ---
 
2924
 150  CONTINUE
 
2925
      IF (XROOT) GO TO 300
 
2926
      IF (NXLAST .EQ. LAST) GO TO 160
 
2927
      ALPHA = 1.0D0
 
2928
      GO TO 180
 
2929
 160  IF (LAST .EQ. 0) GO TO 170
 
2930
      ALPHA = 0.5D0*ALPHA
 
2931
      GO TO 180
 
2932
 170  ALPHA = 2.0D0*ALPHA
 
2933
 180  if((ABS(R0(IMAX)).EQ.ZERO).OR.(ABS(R1(IMAX)).EQ.ZERO)) THEN
 
2934
         X2=(X0+ALPHA*X1)/(1+ALPHA)
 
2935
      ELSE
 
2936
         X2 = X1 - (X1-X0)*R1(IMAX)/(R1(IMAX) - ALPHA*R0(IMAX))
 
2937
      ENDIF
 
2938
c----------------------- Hindmarsh ----------------
 
2939
c     I recently studied the rootfinding algorithm in some detail, and
 
2940
c     found that there is a high potential for an infinite loop within
 
2941
c     the subroutine DROOTS/SROOTS.  This is caused by an adjustment to
 
2942
c     the new computed iterate, called X2 there at statement 180.  The
 
2943
c     adjustment following 180 is faulty, and should be replaced as
 
2944
c     follows. This logic moves X2 away from one endpoint of the current
 
2945
c     interval bracketing the root if it is too close, but in a way that
 
2946
c     cannot result in an infinite loop.  Even if you have not
 
2947
c     encountered any trouble at this spot in DASKR, I recommend you
 
2948
c     make the change.
 
2949
cc      IF ((ABS(X2-X0) .LT. HMIN) .AND.
 
2950
cc     1   (ABS(X1-X0) .GT. 10.0D0*HMIN)) X2 = X0 + 0.1D0*(X1-X0)
 
2951
      IF (ABS(X2 - X0) < HALF*HMIN) THEN
 
2952
        FRACINT = ABS(X1 - X0)/HMIN
 
2953
        IF (FRACINT .GT. FIVE) THEN
 
2954
          FRACSUB = TENTH
 
2955
        ELSE
 
2956
          FRACSUB = HALF/FRACINT
 
2957
        ENDIF
 
2958
        X2 = X0 + FRACSUB*(X1 - X0)
 
2959
      ENDIF
 
2960
 
 
2961
      IF (ABS(X1 - X2) < HALF*HMIN) THEN
 
2962
        FRACINT = ABS(X1 - X0)/HMIN
 
2963
        IF (FRACINT .GT. FIVE) THEN
 
2964
          FRACSUB = TENTH
 
2965
        ELSE
 
2966
          FRACSUB = HALF/FRACINT
 
2967
        ENDIF
 
2968
        X2 = X1 - FRACSUB*(X1 - X0)
 
2969
      ENDIF
 
2970
c----------------------- Hindmarsh ----------------
 
2971
      JFLAG = 1
 
2972
      X = X2
 
2973
C     Return to the calling routine to get a value of RX = R(X). ----
 
2974
      RETURN
 
2975
C     Check to see in which interval R changes sign. ----------------
 
2976
 200  IMXOLD = IMAX 
 
2977
      IMAX = 0
 
2978
      ISTUCK=0
 
2979
      IUNSTUCK=0
 
2980
      TMAX = ZERO
 
2981
      ZROOT = .FALSE.
 
2982
      DO 220 I = 1,NRT
 
2983
         if ((jroot(i) .eq. 1).AND.((ABS(RX(I)) .GT. ZERO))) IUNSTUCK=I
 
2984
         IF (ABS(RX(I)) .GT. ZERO) GO TO 210
 
2985
         if (jroot(i) .eq. 1) go to 220
 
2986
         ISTUCK=I
 
2987
         GO TO 220
 
2988
C     Neither R0(i) nor RX(i) can be zero at this point. -------------------
 
2989
 210     IF (SIGN(1.0D0,R0(I)) .EQ. SIGN(1.0D0,RX(I))) GO TO 220
 
2990
         T2 = ABS(RX(I)/(RX(I) - R0(I)))
 
2991
         IF (T2 .LE. TMAX) GO TO 220
 
2992
         TMAX = T2
 
2993
         IMAX = I
 
2994
 220  CONTINUE
 
2995
      IF (IMAX .GT. 0) GO TO 230
 
2996
      IMAX=ISTUCK
 
2997
      IF (IMAX .GT. 0) GO TO 230
 
2998
      IMAX=IUNSTUCK
 
2999
      IF (IMAX .GT. 0) GO TO 230
 
3000
      SGNCHG = .FALSE.
 
3001
      IMAX = IMXOLD
 
3002
      GO TO 240
 
3003
 230  SGNCHG = .TRUE.
 
3004
 240  NXLAST = LAST
 
3005
      IF (.NOT. SGNCHG) GO TO 260
 
3006
C Sign change between X0 and X2, so replace X1 with X2. ----------------
 
3007
      X1 = X2
 
3008
      CALL DCOPY (NRT, RX, 1, R1, 1)
 
3009
      LAST = 1
 
3010
      XROOT = .FALSE.
 
3011
      GO TO 270
 
3012
 
 
3013
 260  CONTINUE
 
3014
      CALL DCOPY (NRT, RX, 1, R0, 1)
 
3015
      X0 = X2
 
3016
      LAST = 0
 
3017
      XROOT = .FALSE.
 
3018
 270  IF (ABS(X1-X0) .LE. HMIN) XROOT = .TRUE.
 
3019
 
 
3020
      GO TO 150
 
3021
C
 
3022
C Return with X1 as the root.  Set JROOT.  Set X = X1 and RX = R1. -----
 
3023
 300  JFLAG = 2
 
3024
      X = X1
 
3025
      CALL DCOPY (NRT, R1, 1, RX, 1)
 
3026
      DO 320 I = 1,NRT
 
3027
         if(jroot(i).eq.1) then
 
3028
            if(ABS(R1(i)).ne. ZERO) THEN
 
3029
               JROOT(I)=SIGN(2.0D0,R1(I))
 
3030
            ELSE
 
3031
               JROOT(I)=0
 
3032
            ENDIF
 
3033
         ELSE
 
3034
            IF (ABS(R1(I)) .EQ. ZERO) THEN
 
3035
               JROOT(I) = -SIGN(1.0D0,R0(I))
 
3036
            ELSE
 
3037
               IF (SIGN(1.0D0,R0(I)) .NE. SIGN(1.0D0,R1(I))) THEN
 
3038
                  JROOT(I) = SIGN(1.0D0,R1(I) - R0(I))
 
3039
               ELSE
 
3040
                  JROOT(I)=0
 
3041
               ENDIF
 
3042
            ENDIF
 
3043
         ENDIF
 
3044
 320  CONTINUE
 
3045
      RETURN
 
3046
C No sign changes in this interval.  Set X = X1, return JFLAG = 4. -----
 
3047
 420  CALL DCOPY (NRT, R1, 1, RX, 1)
 
3048
      X = X1
 
3049
      JFLAG = 4
 
3050
      RETURN
 
3051
C----------------------- END OF SUBROUTINE DROOTS ----------------------
 
3052
      END
 
3053
 
 
3054
      SUBROUTINE DRCHEK0 (JOB, RT, NRT, NEQ, TN, TOUT, Y, YP, PHI, PSI,
 
3055
     *   KOLD, R0, R1, RX, JROOT, IRT, UROUND, INFO3, RWORK, IWORK,
 
3056
     *   RPAR, IPAR)
 
3057
C
 
3058
C***BEGIN PROLOGUE  DRCHEK
 
3059
C***REFER TO DDASKR
 
3060
C***ROUTINES CALLED  DDATRP, DROOTS, DCOPY, RT
 
3061
C***REVISION HISTORY  (YYMMDD)
 
3062
C   020815  DATE WRITTEN   
 
3063
C   021217  Added test for roots close when JOB = 2.
 
3064
C***END PROLOGUE  DRCHEK
 
3065
C
 
3066
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
3067
C Pointers into IWORK:
 
3068
      PARAMETER (LNRTE=36, LIRFND=37)
 
3069
C Pointers into RWORK:
 
3070
      PARAMETER (LT0=51, LTLAST=52)
 
3071
      EXTERNAL RT
 
3072
      INTEGER JOB, NRT, NEQ, KOLD, JROOT, IRT, INFO3, IWORK, IPAR
 
3073
      DOUBLE PRECISION TN, TOUT, Y, YP, PHI, PSI, R0, R1, RX, UROUND,
 
3074
     *  RWORK, RPAR
 
3075
      DIMENSION Y(*), YP(*), PHI(NEQ,*), PSI(*),
 
3076
     *          R0(*), R1(*), RX(*), JROOT(*), RWORK(*), IWORK(*)
 
3077
      INTEGER I, JFLAG
 
3078
      DOUBLE PRECISION H
 
3079
      DOUBLE PRECISION HMINR, T1, TEMP1, TEMP2, X, ZERO
 
3080
      LOGICAL ZROOT
 
3081
      DATA ZERO/0.0D0/
 
3082
C-----------------------------------------------------------------------
 
3083
C This routine checks for the presence of a root of R(T,Y,Y') in the
 
3084
C vicinity of the current T, in a manner depending on the
 
3085
C input flag JOB.  It calls subroutine DROOTS to locate the root
 
3086
C as precisely as possible.
 
3087
C
 
3088
C In addition to variables described previously, DRCHEK
 
3089
C uses the following for communication..
 
3090
C JOB    = integer flag indicating type of call..
 
3091
C          JOB = 1 means the problem is being initialized, and DRCHEK
 
3092
C                  is to look for a root at or very near the initial T.
 
3093
C          JOB = 2 means a continuation call to the solver was just
 
3094
C                  made, and DRCHEK is to check for a root in the
 
3095
C                  relevant part of the step last taken.
 
3096
C          JOB = 3 means a successful step was just taken, and DRCHEK
 
3097
C                  is to look for a root in the interval of the step.
 
3098
C R0     = array of length NRT, containing the value of R at T = T0.
 
3099
C          R0 is input for JOB .ge. 2 and on output in all cases.
 
3100
C R1,RX  = arrays of length NRT for work space.
 
3101
C IRT    = completion flag..
 
3102
C          IRT = 0  means no root was found.
 
3103
C          IRT = -1 means JOB = 1 and a zero was found both at T0 and
 
3104
C                   and very close to T0.
 
3105
C          IRT = -2 means JOB = 2 and some Ri was found to have a zero
 
3106
C                   both at T0 and very close to T0.
 
3107
C          IRT = 1  means a legitimate root was found (JOB = 2 or 3).
 
3108
C                   On return, T0 is the root location, and Y is the
 
3109
C                   corresponding solution vector.
 
3110
C T0     = value of T at one endpoint of interval of interest.  Only
 
3111
C          roots beyond T0 in the direction of integration are sought.
 
3112
C          T0 is input if JOB .ge. 2, and output in all cases.
 
3113
C          T0 is updated by DRCHEK, whether a root is found or not.
 
3114
C          Stored in the global array RWORK.
 
3115
C TLAST  = last value of T returned by the solver (input only).
 
3116
C          Stored in the global array RWORK.
 
3117
C TOUT   = final output time for the solver.
 
3118
C IRFND  = input flag showing whether the last step taken had a root.
 
3119
C          IRFND = 1 if it did, = 0 if not.
 
3120
C          Stored in the global array IWORK.
 
3121
C INFO3  = copy of INFO(3) (input only).
 
3122
C-----------------------------------------------------------------------
 
3123
C     
 
3124
      H = PSI(1)
 
3125
      IRT = 0
 
3126
      DO 10 I = 1,NRT
 
3127
 10     JROOT(I) = 0
 
3128
      HMINR = (ABS(TN) + ABS(H))*UROUND*100.0D0
 
3129
C
 
3130
      GO TO (100, 200, 300), JOB
 
3131
C
 
3132
C Evaluate R at initial T (= RWORK(LT0)); check for zero values.--------
 
3133
 100  CONTINUE
 
3134
      CALL DDATRP1(TN,RWORK(LT0),Y,YP,NEQ,KOLD,PHI,PSI)
 
3135
      CALL RT (NEQ, RWORK(LT0), Y, YP, NRT, R0, RPAR, IPAR)
 
3136
      IWORK(LNRTE) = 1
 
3137
      ZROOT = .FALSE.
 
3138
      DO 110 I = 1,NRT
 
3139
 110    IF (ABS(R0(I)) .EQ. ZERO) ZROOT = .TRUE.
 
3140
      IF (.NOT. ZROOT) GO TO 190
 
3141
C R has a zero at T.  Look at R at T + (small increment). --------------
 
3142
      TEMP1 = SIGN(HMINR,H)
 
3143
      RWORK(LT0) = RWORK(LT0) + TEMP1
 
3144
      TEMP2 = TEMP1/H
 
3145
      DO 120 I = 1,NEQ
 
3146
 120    Y(I) = Y(I) + TEMP2*PHI(I,2)
 
3147
      CALL RT (NEQ, RWORK(LT0), Y, YP, NRT, R0, RPAR, IPAR)
 
3148
      IWORK(LNRTE) = IWORK(LNRTE) + 1
 
3149
      ZROOT = .FALSE.
 
3150
      DO 130 I = 1,NRT
 
3151
 130    IF (ABS(R0(I)) .EQ. ZERO) ZROOT = .TRUE.
 
3152
      IF (.NOT. ZROOT) GO TO 190
 
3153
C R has a zero at T and also close to T.  Take error return. -----------
 
3154
      IRT = -1
 
3155
      RETURN
 
3156
C
 
3157
 190  CONTINUE
 
3158
      RETURN
 
3159
C
 
3160
 200  CONTINUE
 
3161
c     if in the previous step a z-crossing or mask lifting has occured...
 
3162
      IF (IWORK(LIRFND) .EQ. 0) GO TO 260
 
3163
C     If a root was found on the previous step, evaluate R0 = R(T0). ----
 
3164
      CALL DDATRP1 (TN, RWORK(LT0), Y, YP, NEQ, KOLD, PHI, PSI)
 
3165
      CALL RT (NEQ, RWORK(LT0), Y, YP, NRT, R0, RPAR, IPAR)
 
3166
      IWORK(LNRTE) = IWORK(LNRTE) + 1
 
3167
      ZROOT = .FALSE.
 
3168
      DO 210 I = 1,NRT
 
3169
        IF (ABS(R0(I)) .EQ. ZERO) THEN
 
3170
          ZROOT = .TRUE.
 
3171
          JROOT(I) = 1
 
3172
        ENDIF
 
3173
 210    CONTINUE
 
3174
      IF (.NOT. ZROOT) GO TO 260
 
3175
C R has a zero at T0.  Look at R at T0+ = T0 + (small increment). ------
 
3176
      TEMP1 = SIGN(HMINR,H)
 
3177
      RWORK(LT0) = RWORK(LT0) + TEMP1
 
3178
      IF ((RWORK(LT0) - TN)*H .LT. ZERO) GO TO 230
 
3179
      TEMP2 = TEMP1/H
 
3180
      DO 220 I = 1,NEQ
 
3181
 220    Y(I) = Y(I) + TEMP2*PHI(I,2)
 
3182
      GO TO 240
 
3183
 230  CALL DDATRP1 (TN, RWORK(LT0), Y, YP, NEQ, KOLD, PHI, PSI)
 
3184
 240  CALL RT (NEQ, RWORK(LT0), Y, YP, NRT, R0, RPAR, IPAR)
 
3185
      IWORK(LNRTE) = IWORK(LNRTE) + 1
 
3186
      DO 250 I = 1,NRT
 
3187
        IF (ABS(R0(I)) .GT. ZERO) GO TO 250
 
3188
C If Ri has a zero at both T0+ and T0, return an error flag. -----------
 
3189
        IF (JROOT(I) .EQ. 1) THEN
 
3190
          IRT = -2
 
3191
          RETURN
 
3192
        ELSE
 
3193
C If Ri has a zero at T0+, but not at T0, return valid root. -----------
 
3194
          JROOT(I) = -SIGN(1.0D0,R0(I))
 
3195
          IRT = 1
 
3196
        ENDIF
 
3197
 250    CONTINUE
 
3198
      IF (IRT .EQ. 1) RETURN
 
3199
C R0 has no zero components.  Proceed to check relevant interval. ------
 
3200
 260  IF (TN .EQ. RWORK(LTLAST)) RETURN
 
3201
C
 
3202
 300  CONTINUE
 
3203
C Set T1 to TN or TOUT, whichever comes first, and get R at T1. --------
 
3204
      IF (INFO3 .EQ. 1 .OR. (TOUT - TN)*H .GE. ZERO) THEN
 
3205
         T1 = TN
 
3206
         GO TO 330
 
3207
         ENDIF
 
3208
      T1 = TOUT
 
3209
      IF ((T1 - RWORK(LT0))*H .LE. ZERO) GO TO 390
 
3210
 330  CALL DDATRP1 (TN, T1, Y, YP, NEQ, KOLD, PHI, PSI)
 
3211
      CALL RT (NEQ, T1, Y, YP, NRT, R1, RPAR, IPAR)
 
3212
      IWORK(LNRTE) = IWORK(LNRTE) + 1
 
3213
C Call DROOTS to search for root in interval from T0 to T1. ------------
 
3214
      JFLAG = 0
 
3215
 350  CONTINUE
 
3216
      CALL DROOTS0(NRT, HMINR, JFLAG,RWORK(LT0),T1, R0,R1,RX, X, JROOT)
 
3217
      IF (JFLAG .GT. 1) GO TO 360
 
3218
      CALL DDATRP1 (TN, X, Y, YP, NEQ, KOLD, PHI, PSI)
 
3219
      CALL RT (NEQ, X, Y, YP, NRT, RX, RPAR, IPAR)
 
3220
      IWORK(LNRTE) = IWORK(LNRTE) + 1
 
3221
      GO TO 350
 
3222
 360  RWORK(LT0) = X
 
3223
      CALL DCOPY (NRT, RX, 1, R0, 1)
 
3224
      IF (JFLAG .EQ. 4) GO TO 390
 
3225
C Found a root.  Interpolate to X and return. --------------------------
 
3226
      CALL DDATRP1 (TN, X, Y, YP, NEQ, KOLD, PHI, PSI)
 
3227
      IRT = 1
 
3228
      RETURN
 
3229
C
 
3230
 390  CONTINUE
 
3231
      RETURN
 
3232
C---------------------- END OF SUBROUTINE DRCHEK -----------------------
 
3233
      END
 
3234
      SUBROUTINE DROOTS0(NRT, HMIN, JFLAG, X0, X1, R0, R1, RX, X, JROOT)
 
3235
C
 
3236
C***BEGIN PROLOGUE  DROOTS
 
3237
C***REFER TO DRCHEK
 
3238
C***ROUTINES CALLED DCOPY
 
3239
C***REVISION HISTORY  (YYMMDD)
 
3240
C   020815  DATE WRITTEN   
 
3241
C   021217  Added root direction information in JROOT.
 
3242
C***END PROLOGUE  DROOTS
 
3243
C
 
3244
      INTEGER NRT, JFLAG, JROOT
 
3245
      DOUBLE PRECISION HMIN, X0, X1, R0, R1, RX, X
 
3246
      DIMENSION R0(NRT), R1(NRT), RX(NRT), JROOT(NRT)
 
3247
C-----------------------------------------------------------------------
 
3248
C This subroutine finds the leftmost root of a set of arbitrary
 
3249
C functions Ri(x) (i = 1,...,NRT) in an interval (X0,X1).  Only roots
 
3250
C of odd multiplicity (i.e. changes of sign of the Ri) are found.
 
3251
C Here the sign of X1 - X0 is arbitrary, but is constant for a given
 
3252
C problem, and -leftmost- means nearest to X0.
 
3253
C The values of the vector-valued function R(x) = (Ri, i=1...NRT)
 
3254
C are communicated through the call sequence of DROOTS.
 
3255
C The method used is the Illinois algorithm.
 
3256
C
 
3257
C Reference:
 
3258
C Kathie L. Hiebert and Lawrence F. Shampine, Implicitly Defined
 
3259
C Output Points for Solutions of ODEs, Sandia Report SAND80-0180,
 
3260
C February 1980.
 
3261
C
 
3262
C Description of parameters.
 
3263
C
 
3264
C NRT    = number of functions Ri, or the number of components of
 
3265
C          the vector valued function R(x).  Input only.
 
3266
C
 
3267
C HMIN   = resolution parameter in X.  Input only.  When a root is
 
3268
C          found, it is located only to within an error of HMIN in X.
 
3269
C          Typically, HMIN should be set to something on the order of
 
3270
C               100 * UROUND * MAX(ABS(X0),ABS(X1)),
 
3271
C          where UROUND is the unit roundoff of the machine.
 
3272
C
 
3273
C JFLAG  = integer flag for input and output communication.
 
3274
C
 
3275
C          On input, set JFLAG = 0 on the first call for the problem,
 
3276
C          and leave it unchanged until the problem is completed.
 
3277
C          (The problem is completed when JFLAG .ge. 2 on return.)
 
3278
C
 
3279
C          On output, JFLAG has the following values and meanings:
 
3280
C          JFLAG = 1 means DROOTS needs a value of R(x).  Set RX = R(X)
 
3281
C                    and call DROOTS again.
 
3282
C          JFLAG = 2 means a root has been found.  The root is
 
3283
C                    at X, and RX contains R(X).  (Actually, X is the
 
3284
C                    rightmost approximation to the root on an interval
 
3285
C                    (X0,X1) of size HMIN or less.)
 
3286
C          JFLAG = 3 means X = X1 is a root, with one or more of the Ri
 
3287
C                    being zero at X1 and no sign changes in (X0,X1).
 
3288
C                    RX contains R(X) on output.
 
3289
C          JFLAG = 4 means no roots (of odd multiplicity) were
 
3290
C                    found in (X0,X1) (no sign changes).
 
3291
C
 
3292
C X0,X1  = endpoints of the interval where roots are sought.
 
3293
C          X1 and X0 are input when JFLAG = 0 (first call), and
 
3294
C          must be left unchanged between calls until the problem is
 
3295
C          completed.  X0 and X1 must be distinct, but X1 - X0 may be
 
3296
C          of either sign.  However, the notion of -left- and -right-
 
3297
C          will be used to mean nearer to X0 or X1, respectively.
 
3298
C          When JFLAG .ge. 2 on return, X0 and X1 are output, and
 
3299
C          are the endpoints of the relevant interval.
 
3300
C
 
3301
C R0,R1  = arrays of length NRT containing the vectors R(X0) and R(X1),
 
3302
C          respectively.  When JFLAG = 0, R0 and R1 are input and
 
3303
C          none of the R0(i) should be zero.
 
3304
C          When JFLAG .ge. 2 on return, R0 and R1 are output.
 
3305
C
 
3306
C RX     = array of length NRT containing R(X).  RX is input
 
3307
C          when JFLAG = 1, and output when JFLAG .ge. 2.
 
3308
C
 
3309
C X      = independent variable value.  Output only.
 
3310
C          When JFLAG = 1 on output, X is the point at which R(x)
 
3311
C          is to be evaluated and loaded into RX.
 
3312
C          When JFLAG = 2 or 3, X is the root.
 
3313
C          When JFLAG = 4, X is the right endpoint of the interval, X1.
 
3314
C
 
3315
C JROOT  = integer array of length NRT.  Output only.
 
3316
C          When JFLAG = 2 or 3, JROOT indicates which components
 
3317
C          of R(x) have a root at X, and the direction of the sign
 
3318
C          change across the root in the direction of integration.
 
3319
C          JROOT(i) =  1 if Ri has a root and changes from - to +.
 
3320
C          JROOT(i) = -1 if Ri has a root and changes from + to -.
 
3321
C          Otherwise JROOT(i) = 0.
 
3322
C-----------------------------------------------------------------------
 
3323
      INTEGER I, IMAX, IMXOLD, LAST, NXLAST
 
3324
      DOUBLE PRECISION ALPHA, T2, TMAX, X2, ZERO
 
3325
      LOGICAL ZROOT, SGNCHG, XROOT
 
3326
      SAVE ALPHA, X2, IMAX, LAST
 
3327
      DATA ZERO/0.0D0/
 
3328
C
 
3329
      IF (JFLAG .EQ. 1) GO TO 200
 
3330
C JFLAG .ne. 1.  Check for change in sign of R or zero at X1. ----------
 
3331
      IMAX = 0
 
3332
      TMAX = ZERO
 
3333
      ZROOT = .FALSE.
 
3334
      DO 120 I = 1,NRT
 
3335
        IF (ABS(R1(I)) .GT. ZERO) GO TO 110
 
3336
        ZROOT = .TRUE.
 
3337
        GO TO 120
 
3338
C At this point, R0(i) has been checked and cannot be zero. ------------
 
3339
 110    IF (SIGN(1.0D0,R0(I)) .EQ. SIGN(1.0D0,R1(I))) GO TO 120
 
3340
          T2 = ABS(R1(I)/(R1(I)-R0(I)))
 
3341
          IF (T2 .LE. TMAX) GO TO 120
 
3342
            TMAX = T2
 
3343
            IMAX = I
 
3344
 120    CONTINUE
 
3345
      IF (IMAX .GT. 0) GO TO 130
 
3346
      SGNCHG = .FALSE.
 
3347
      GO TO 140
 
3348
 130  SGNCHG = .TRUE.
 
3349
 140  IF (.NOT. SGNCHG) GO TO 400
 
3350
C There is a sign change.  Find the first root in the interval. --------
 
3351
      XROOT = .FALSE.
 
3352
      NXLAST = 0
 
3353
      LAST = 1
 
3354
C
 
3355
C Repeat until the first root in the interval is found.  Loop point. ---
 
3356
 150  CONTINUE
 
3357
      IF (XROOT) GO TO 300
 
3358
      IF (NXLAST .EQ. LAST) GO TO 160
 
3359
      ALPHA = 1.0D0
 
3360
      GO TO 180
 
3361
 160  IF (LAST .EQ. 0) GO TO 170
 
3362
      ALPHA = 0.5D0*ALPHA
 
3363
      GO TO 180
 
3364
 170  ALPHA = 2.0D0*ALPHA
 
3365
 180  X2 = X1 - (X1-X0)*R1(IMAX)/(R1(IMAX) - ALPHA*R0(IMAX))
 
3366
      IF ((ABS(X2-X0) .LT. HMIN) .AND.
 
3367
     1   (ABS(X1-X0) .GT. 10.0D0*HMIN)) X2 = X0 + 0.1D0*(X1-X0)
 
3368
      JFLAG = 1
 
3369
      X = X2
 
3370
C Return to the calling routine to get a value of RX = R(X). -----------
 
3371
      RETURN
 
3372
C Check to see in which interval R changes sign. -----------------------
 
3373
 200  IMXOLD = IMAX
 
3374
      IMAX = 0
 
3375
      TMAX = ZERO
 
3376
      ZROOT = .FALSE.
 
3377
      DO 220 I = 1,NRT
 
3378
        IF (ABS(RX(I)) .GT. ZERO) GO TO 210
 
3379
        ZROOT = .TRUE.
 
3380
        GO TO 220
 
3381
C Neither R0(i) nor RX(i) can be zero at this point. -------------------
 
3382
 210    IF (SIGN(1.0D0,R0(I)) .EQ. SIGN(1.0D0,RX(I))) GO TO 220
 
3383
          T2 = ABS(RX(I)/(RX(I) - R0(I)))
 
3384
          IF (T2 .LE. TMAX) GO TO 220
 
3385
            TMAX = T2
 
3386
            IMAX = I
 
3387
 220    CONTINUE
 
3388
      IF (IMAX .GT. 0) GO TO 230
 
3389
      SGNCHG = .FALSE.
 
3390
      IMAX = IMXOLD
 
3391
      GO TO 240
 
3392
 230  SGNCHG = .TRUE.
 
3393
 240  NXLAST = LAST
 
3394
      IF (.NOT. SGNCHG) GO TO 250
 
3395
C Sign change between X0 and X2, so replace X1 with X2. ----------------
 
3396
      X1 = X2
 
3397
      CALL DCOPY (NRT, RX, 1, R1, 1)
 
3398
      LAST = 1
 
3399
      XROOT = .FALSE.
 
3400
      GO TO 270
 
3401
 250  IF (.NOT. ZROOT) GO TO 260
 
3402
C Zero value at X2 and no sign change in (X0,X2), so X2 is a root. -----
 
3403
      X1 = X2
 
3404
      CALL DCOPY (NRT, RX, 1, R1, 1)
 
3405
      XROOT = .TRUE.
 
3406
      GO TO 270
 
3407
C No sign change between X0 and X2.  Replace X0 with X2. ---------------
 
3408
 260  CONTINUE
 
3409
      CALL DCOPY (NRT, RX, 1, R0, 1)
 
3410
      X0 = X2
 
3411
      LAST = 0
 
3412
      XROOT = .FALSE.
 
3413
 270  IF (ABS(X1-X0) .LE. HMIN) XROOT = .TRUE.
 
3414
      GO TO 150
 
3415
C
 
3416
C Return with X1 as the root.  Set JROOT.  Set X = X1 and RX = R1. -----
 
3417
 300  JFLAG = 2
 
3418
      X = X1
 
3419
      CALL DCOPY (NRT, R1, 1, RX, 1)
 
3420
      DO 320 I = 1,NRT
 
3421
        JROOT(I) = 0
 
3422
        IF (ABS(R1(I)) .EQ. ZERO) THEN
 
3423
          JROOT(I) = -SIGN(1.0D0,R0(I))
 
3424
          GO TO 320
 
3425
          ENDIF
 
3426
        IF (SIGN(1.0D0,R0(I)) .NE. SIGN(1.0D0,R1(I)))
 
3427
     1     JROOT(I) = SIGN(1.0D0,R1(I) - R0(I))
 
3428
 320    CONTINUE
 
3429
      RETURN
 
3430
C
 
3431
C No sign change in the interval.  Check for zero at right endpoint. ---
 
3432
 400  IF (.NOT. ZROOT) GO TO 420
 
3433
C
 
3434
C Zero value at X1 and no sign change in (X0,X1).  Return JFLAG = 3. ---
 
3435
      X = X1
 
3436
      CALL DCOPY (NRT, R1, 1, RX, 1)
 
3437
      DO 410 I = 1,NRT
 
3438
        JROOT(I) = 0
 
3439
        IF (ABS(R1(I)) .EQ. ZERO) JROOT(I) = -SIGN(1.0D0,R0(I))
 
3440
 410  CONTINUE
 
3441
      JFLAG = 3
 
3442
      RETURN
 
3443
C
 
3444
C No sign changes in this interval.  Set X = X1, return JFLAG = 4. -----
 
3445
 420  CALL DCOPY (NRT, R1, 1, RX, 1)
 
3446
      X = X1
 
3447
      JFLAG = 4
 
3448
      RETURN
 
3449
C----------------------- END OF SUBROUTINE DROOTS ----------------------
 
3450
      END
 
3451
 
 
3452
      SUBROUTINE DDASIC (X, Y, YPRIME, NEQ, ICOPT, ID, RES, JAC, PSOL,
 
3453
     *   H, TSCALE, WT, NIC, IDID, RPAR, IPAR, PHI, SAVR, DELTA, E,
 
3454
     *   YIC, YPIC, PWK, WM, IWM, UROUND, EPLI, SQRTN, RSQRTN,
 
3455
     *   EPCONI, STPTOL, JFLG, ICNFLG, ICNSTR, NLSIC)
 
3456
C
 
3457
C***BEGIN PROLOGUE  DDASIC
 
3458
C***REFER TO  DDASPK
 
3459
C***DATE WRITTEN   940628   (YYMMDD)
 
3460
C***REVISION DATE  941206   (YYMMDD)
 
3461
C***REVISION DATE  950714   (YYMMDD)
 
3462
C***REVISION DATE  000628   TSCALE argument added.
 
3463
C
 
3464
C-----------------------------------------------------------------------
 
3465
C***DESCRIPTION
 
3466
C
 
3467
C     DDASIC is a driver routine to compute consistent initial values
 
3468
C     for Y and YPRIME.  There are two different options:  
 
3469
C     Denoting the differential variables in Y by Y_d, and
 
3470
C     the algebraic variables by Y_a, the problem solved is either:
 
3471
C     1.  Given Y_d, calculate Y_a and Y_d', or
 
3472
C     2.  Given Y', calculate Y.
 
3473
C     In either case, initial values for the given components
 
3474
C     are input, and initial guesses for the unknown components
 
3475
C     must also be provided as input.
 
3476
C
 
3477
C     The external routine NLSIC solves the resulting nonlinear system.
 
3478
 
3479
C     The parameters represent
 
3480
 
3481
C     X  --        Independent variable.
 
3482
C     Y  --        Solution vector at X.
 
3483
C     YPRIME --    Derivative of solution vector.
 
3484
C     NEQ --       Number of equations to be integrated.
 
3485
C     ICOPT     -- Flag indicating initial condition option chosen.
 
3486
C                    ICOPT = 1 for option 1 above.
 
3487
C                    ICOPT = 2 for option 2.
 
3488
C     ID        -- Array of dimension NEQ, which must be initialized
 
3489
C                  if option 1 is chosen.
 
3490
C                    ID(i) = +1 if Y_i is a differential variable,
 
3491
C                    ID(i) = -1 if Y_i is an algebraic variable. 
 
3492
C     RES --       External user-supplied subroutine to evaluate the
 
3493
C                  residual.  See RES description in DDASPK prologue.
 
3494
C     JAC --       External user-supplied routine to update Jacobian
 
3495
C                  or preconditioner information in the nonlinear solver
 
3496
C                  (optional).  See JAC description in DDASPK prologue.
 
3497
C     PSOL --      External user-supplied routine to solve
 
3498
C                  a linear system using preconditioning. 
 
3499
C                  See PSOL in DDASPK prologue.
 
3500
C     H --         Scaling factor in iteration matrix.  DDASIC may 
 
3501
C                  reduce H to achieve convergence.
 
3502
C     TSCALE --    Scale factor in T, used for stopping tests if nonzero.
 
3503
C     WT --        Vector of weights for error criterion.
 
3504
C     NIC --       Input number of initial condition calculation call 
 
3505
C                  (= 1 or 2).
 
3506
C     IDID --      Completion code.  See IDID in DDASPK prologue.
 
3507
C     RPAR,IPAR -- Real and integer parameter arrays that
 
3508
C                  are used for communication between the
 
3509
C                  calling program and external user routines.
 
3510
C                  They are not altered by DNSK
 
3511
C     PHI --       Work space for DDASIC of length at least 2*NEQ.
 
3512
C     SAVR --      Work vector for DDASIC of length NEQ.
 
3513
C     DELTA --     Work vector for DDASIC of length NEQ.
 
3514
C     E --         Work vector for DDASIC of length NEQ.
 
3515
C     YIC,YPIC --  Work vectors for DDASIC, each of length NEQ.
 
3516
C     PWK --       Work vector for DDASIC of length NEQ.
 
3517
C     WM,IWM --    Real and integer arrays storing
 
3518
C                  information required by the linear solver.
 
3519
C     EPCONI --    Test constant for Newton iteration convergence.
 
3520
C     ICNFLG --    Flag showing whether constraints on Y are to apply.
 
3521
C     ICNSTR --    Integer array of length NEQ with constraint types.
 
3522
C
 
3523
C     The other parameters are for use internally by DDASIC.
 
3524
C
 
3525
C-----------------------------------------------------------------------
 
3526
C***ROUTINES CALLED
 
3527
C   DCOPY, NLSIC
 
3528
C
 
3529
C***END PROLOGUE  DDASIC
 
3530
C
 
3531
C
 
3532
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
3533
      DIMENSION Y(*),YPRIME(*),ID(*),WT(*),PHI(NEQ,*)
 
3534
      DIMENSION SAVR(*),DELTA(*),E(*),YIC(*),YPIC(*),PWK(*)
 
3535
      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*), ICNSTR(*)
 
3536
      EXTERNAL RES, JAC, PSOL, NLSIC
 
3537
C
 
3538
      PARAMETER (LCFN=15)
 
3539
      PARAMETER (LMXNH=34)
 
3540
C
 
3541
C The following parameters are data-loaded here:
 
3542
C     RHCUT  = factor by which H is reduced on retry of Newton solve.
 
3543
C     RATEMX = maximum convergence rate for which Newton iteration
 
3544
C              is considered converging.
 
3545
C
 
3546
      SAVE RHCUT, RATEMX
 
3547
      DATA RHCUT/0.1D0/, RATEMX/0.8D0/
 
3548
C
 
3549
C
 
3550
C-----------------------------------------------------------------------
 
3551
C     BLOCK 1.
 
3552
C     Initializations.
 
3553
C     JSKIP is a flag set to 1 when NIC = 2 and NH = 1, to signal that
 
3554
C     the initial call to the JAC routine is to be skipped then.
 
3555
C     Save Y and YPRIME in PHI.  Initialize IDID, NH, and CJ.
 
3556
C-----------------------------------------------------------------------
 
3557
C
 
3558
      MXNH = IWM(LMXNH)
 
3559
      IDID = 1
 
3560
      NH = 1
 
3561
      JSKIP = 0
 
3562
      IF (NIC .EQ. 2) JSKIP = 1
 
3563
      CALL DCOPY (NEQ, Y, 1, PHI(1,1), 1)
 
3564
      CALL DCOPY (NEQ, YPRIME, 1, PHI(1,2), 1)
 
3565
C
 
3566
      IF (ICOPT .EQ. 2) THEN
 
3567
        CJ = 0.0D0 
 
3568
      ELSE
 
3569
        CJ = 1.0D0/H
 
3570
      ENDIF
 
3571
C
 
3572
C-----------------------------------------------------------------------
 
3573
C     BLOCK 2
 
3574
C     Call the nonlinear system solver to obtain
 
3575
C     consistent initial values for Y and YPRIME.
 
3576
C-----------------------------------------------------------------------
 
3577
C
 
3578
 200  CONTINUE
 
3579
 
 
3580
      CALL NLSIC(X,Y,YPRIME,NEQ,ICOPT,ID,RES,JAC,PSOL,H,TSCALE,WT,
 
3581
     *   JSKIP,RPAR,IPAR,SAVR,DELTA,E,YIC,YPIC,PWK,WM,IWM,CJ,UROUND,
 
3582
     *   EPLI,SQRTN,RSQRTN,EPCONI,RATEMX,STPTOL,JFLG,ICNFLG,ICNSTR,
 
3583
     *   IERNLS)
 
3584
C
 
3585
      IF (IERNLS .EQ. 0) RETURN
 
3586
C
 
3587
C-----------------------------------------------------------------------
 
3588
C     BLOCK 3
 
3589
C     The nonlinear solver was unsuccessful.  Increment NCFN.
 
3590
C     Return with IDID = -12 if either
 
3591
C       IERNLS = -1: error is considered unrecoverable,
 
3592
C       ICOPT = 2: we are doing initialization problem type 2, or
 
3593
C       NH = MXNH: the maximum number of H values has been tried.
 
3594
C     Otherwise (problem 1 with IERNLS .GE. 1), reduce H and try again.
 
3595
C     If IERNLS > 1, restore Y and YPRIME to their original values.
 
3596
C-----------------------------------------------------------------------
 
3597
C
 
3598
      IWM(LCFN) = IWM(LCFN) + 1
 
3599
      JSKIP = 0
 
3600
C
 
3601
      IF (IERNLS .EQ. -1) GO TO 350
 
3602
c     >>>>>>>> singular Jacobian 
 
3603
      IF (IERNLS .EQ. -2) GO TO 360
 
3604
 
 
3605
      IF (ICOPT .EQ. 2) GO TO 350
 
3606
      IF (NH .EQ. MXNH) GO TO 350
 
3607
C
 
3608
      NH = NH + 1
 
3609
      H = H*RHCUT
 
3610
      CJ = 1.0D0/H
 
3611
C
 
3612
      IF (IERNLS .EQ. 1) GO TO 200
 
3613
C
 
3614
      CALL DCOPY (NEQ, PHI(1,1), 1, Y, 1)
 
3615
      CALL DCOPY (NEQ, PHI(1,2), 1, YPRIME, 1)
 
3616
      GO TO 200
 
3617
C
 
3618
 350  IDID = -12
 
3619
      RETURN
 
3620
c     >> singular Jacobian
 
3621
 360  IDID = -8
 
3622
      RETURN
 
3623
C
 
3624
C------END OF SUBROUTINE DDASIC-----------------------------------------
 
3625
      END
 
3626
      SUBROUTINE DYYPNW (NEQ, Y, YPRIME, CJ, RL, P, ICOPT, ID, 
 
3627
     *                   YNEW, YPNEW)
 
3628
C
 
3629
C***BEGIN PROLOGUE  DYYPNW
 
3630
C***REFER TO  DLINSK
 
3631
C***DATE WRITTEN   940830   (YYMMDD)
 
3632
C
 
3633
C
 
3634
C-----------------------------------------------------------------------
 
3635
C***DESCRIPTION
 
3636
C
 
3637
C     DYYPNW calculates the new (Y,YPRIME) pair needed in the
 
3638
C     linesearch algorithm based on the current lambda value.  It is
 
3639
C     called by DLINSK and DLINSD.  Based on the ICOPT and ID values,
 
3640
C     the corresponding entry in Y or YPRIME is updated.
 
3641
C
 
3642
C     In addition to the parameters described in the calling programs,
 
3643
C     the parameters represent
 
3644
C
 
3645
C     P      -- Array of length NEQ that contains the current
 
3646
C               approximate Newton step.
 
3647
C     RL     -- Scalar containing the current lambda value.
 
3648
C     YNEW   -- Array of length NEQ containing the updated Y vector.
 
3649
C     YPNEW  -- Array of length NEQ containing the updated YPRIME
 
3650
C               vector.
 
3651
C-----------------------------------------------------------------------
 
3652
C
 
3653
C***ROUTINES CALLED (NONE)
 
3654
C
 
3655
C***END PROLOGUE  DYYPNW
 
3656
C
 
3657
C
 
3658
      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
 
3659
      DIMENSION Y(*), YPRIME(*), YNEW(*), YPNEW(*), ID(*), P(*)
 
3660
C
 
3661
      IF (ICOPT .EQ. 1) THEN
 
3662
         DO 10 I=1,NEQ
 
3663
            IF(ID(I) .LT. 0) THEN
 
3664
               YNEW(I) = Y(I) - RL*P(I)
 
3665
               YPNEW(I) = YPRIME(I)
 
3666
            ELSE
 
3667
               YNEW(I) = Y(I)
 
3668
               YPNEW(I) = YPRIME(I) - RL*CJ*P(I)
 
3669
            ENDIF
 
3670
 10      CONTINUE
 
3671
      ELSE
 
3672
         DO 20 I = 1,NEQ
 
3673
            YNEW(I) = Y(I) - RL*P(I)
 
3674
            YPNEW(I) = YPRIME(I)
 
3675
 20      CONTINUE
 
3676
      ENDIF
 
3677
      RETURN
 
3678
C----------------------- END OF SUBROUTINE DYYPNW ----------------------
 
3679
      END
 
3680
      SUBROUTINE DDSTP(X,Y,YPRIME,NEQ,RES,JAC,PSOL,H,WT,VT,
 
3681
     *  JSTART,IDID,RPAR,IPAR,PHI,SAVR,DELTA,E,WM,IWM,
 
3682
     *  ALPHA,BETA,GAMMA,PSI,SIGMA,CJ,CJOLD,HOLD,S,HMIN,UROUND,
 
3683
     *  EPLI,SQRTN,RSQRTN,EPCON,IPHASE,JCALC,JFLG,K,KOLD,NS,NONNEG,
 
3684
     *  NTYPE,NLS)
 
3685
C
 
3686
C***BEGIN PROLOGUE  DDSTP2
 
3687
C***REFER TO  DDASPK 
 
3688
C***DATE WRITTEN   890101   (YYMMDD)
 
3689
C***REVISION DATE  900926   (YYMMDD)
 
3690
C***REVISION DATE  940909   (YYMMDD) (Reset PSI(1), PHI(*,2) at 690)
 
3691
C
 
3692
C
 
3693
C-----------------------------------------------------------------------
 
3694
C***DESCRIPTION
 
3695
C
 
3696
C     DDSTP solves a system of differential/algebraic equations of 
 
3697
C     the form G(X,Y,YPRIME) = 0, for one step (normally from X to X+H).
 
3698
C
 
3699
C     The methods used are modified divided difference, fixed leading 
 
3700
C     coefficient forms of backward differentiation formulas.  
 
3701
C     The code adjusts the stepsize and order to control the local error
 
3702
C     per step.
 
3703
C
 
3704
C
 
3705
C     The parameters represent
 
3706
C     X  --        Independent variable.
 
3707
C     Y  --        Solution vector at X.
 
3708
C     YPRIME --    Derivative of solution vector
 
3709
C                  after successful step.
 
3710
C     NEQ --       Number of equations to be integrated.
 
3711
C     RES --       External user-supplied subroutine
 
3712
C                  to evaluate the residual.  See RES description
 
3713
C                  in DDASPK prologue.
 
3714
C     JAC --       External user-supplied routine to update
 
3715
C                  Jacobian or preconditioner information in the
 
3716
C                  nonlinear solver.  See JAC description in DDASPK
 
3717
C                  prologue.
 
3718
C     PSOL --      External user-supplied routine to solve
 
3719
C                  a linear system using preconditioning. 
 
3720
C                  (This is optional).  See PSOL in DDASPK prologue.
 
3721
C     H --         Appropriate step size for next step.
 
3722
C                  Normally determined by the code.
 
3723
C     WT --        Vector of weights for error criterion used in Newton test.
 
3724
C     VT --        Masked vector of weights used in error test.
 
3725
C     JSTART --    Integer variable set 0 for
 
3726
C                  first step, 1 otherwise.
 
3727
C     IDID --      Completion code returned from the nonlinear solver.
 
3728
C                  See IDID description in DDASPK prologue.
 
3729
C     RPAR,IPAR -- Real and integer parameter arrays that
 
3730
C                  are used for communication between the
 
3731
C                  calling program and external user routines.
 
3732
C                  They are not altered by DNSK
 
3733
C     PHI --       Array of divided differences used by
 
3734
C                  DDSTP. The length is NEQ*(K+1), where
 
3735
C                  K is the maximum order.
 
3736
C     SAVR --      Work vector for DDSTP of length NEQ.
 
3737
C     DELTA,E --   Work vectors for DDSTP of length NEQ.
 
3738
C     WM,IWM --    Real and integer arrays storing
 
3739
C                  information required by the linear solver.
 
3740
C
 
3741
C     The other parameters are information
 
3742
C     which is needed internally by DDSTP to
 
3743
C     continue from step to step.
 
3744
C
 
3745
C-----------------------------------------------------------------------
 
3746
C***ROUTINES CALLED
 
3747
C   NLS, DDWNRM, DDATRP
 
3748
C
 
3749
C***END PROLOGUE  DDSTP
 
3750
C
 
3751
C
 
3752
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
3753
      DIMENSION Y(*),YPRIME(*),WT(*),VT(*)
 
3754
      DIMENSION PHI(NEQ,*),SAVR(*),DELTA(*),E(*)
 
3755
      DIMENSION WM(*),IWM(*)
 
3756
      DIMENSION PSI(*),ALPHA(*),BETA(*),GAMMA(*),SIGMA(*)
 
3757
      DIMENSION RPAR(*),IPAR(*)
 
3758
      EXTERNAL  RES, JAC, PSOL, NLS
 
3759
C
 
3760
      PARAMETER (LMXORD=3)
 
3761
      PARAMETER (LNST=11, LETF=14, LCFN=15)
 
3762
C
 
3763
C
 
3764
C-----------------------------------------------------------------------
 
3765
C     BLOCK 1.
 
3766
C     Initialize.  On the first call, set
 
3767
C     the order to 1 and initialize
 
3768
C     other variables.
 
3769
C-----------------------------------------------------------------------
 
3770
C
 
3771
C     Initializations for all calls
 
3772
C
 
3773
      XOLD=X
 
3774
      NCF=0
 
3775
      NEF=0
 
3776
c     //cold or hot start
 
3777
      IF(JSTART .NE. 0) GO TO 120
 
3778
C
 
3779
C     If this is the first step, perform
 
3780
C     other initializations
 
3781
C
 
3782
      K=1
 
3783
      KOLD=0
 
3784
      HOLD=0.0D0
 
3785
      PSI(1)=H
 
3786
      CJ = 1.D0/H
 
3787
      IPHASE = 0
 
3788
      NS=0
 
3789
120   CONTINUE
 
3790
C
 
3791
C
 
3792
C
 
3793
C
 
3794
C
 
3795
C-----------------------------------------------------------------------
 
3796
C     BLOCK 2
 
3797
C     Compute coefficients of formulas for
 
3798
C     this step.
 
3799
C-----------------------------------------------------------------------
 
3800
200   CONTINUE
 
3801
      KP1=K+1
 
3802
      KP2=K+2
 
3803
      KM1=K-1
 
3804
      IF(H.NE.HOLD.OR.K .NE. KOLD) NS = 0
 
3805
      NS=MIN0(NS+1,KOLD+2)
 
3806
      NSP1=NS+1
 
3807
      IF(KP1 .LT. NS)GO TO 230
 
3808
C
 
3809
      BETA(1)=1.0D0
 
3810
      ALPHA(1)=1.0D0
 
3811
      TEMP1=H
 
3812
      GAMMA(1)=0.0D0
 
3813
      SIGMA(1)=1.0D0
 
3814
      DO 210 I=2,KP1
 
3815
         TEMP2=PSI(I-1)
 
3816
         PSI(I-1)=TEMP1
 
3817
         BETA(I)=BETA(I-1)*PSI(I-1)/TEMP2
 
3818
         TEMP1=TEMP2+H
 
3819
         ALPHA(I)=H/TEMP1
 
3820
         SIGMA(I)=(I-1)*SIGMA(I-1)*ALPHA(I)
 
3821
         GAMMA(I)=GAMMA(I-1)+ALPHA(I-1)/H
 
3822
210      CONTINUE
 
3823
      PSI(KP1)=TEMP1
 
3824
230   CONTINUE
 
3825
C
 
3826
C     Compute ALPHAS, ALPHA0
 
3827
C
 
3828
      ALPHAS = 0.0D0
 
3829
      ALPHA0 = 0.0D0
 
3830
      DO 240 I = 1,K
 
3831
        ALPHAS = ALPHAS - 1.0D0/I
 
3832
        ALPHA0 = ALPHA0 - ALPHA(I)
 
3833
240     CONTINUE
 
3834
C
 
3835
C     Compute leading coefficient CJ
 
3836
C
 
3837
      CJLAST = CJ
 
3838
      CJ = -ALPHAS/H
 
3839
C
 
3840
C     Compute variable stepsize error coefficient CK
 
3841
C
 
3842
      CK = ABS(ALPHA(KP1) + ALPHAS - ALPHA0)
 
3843
      CK = MAX(CK,ALPHA(KP1))
 
3844
C
 
3845
C     Change PHI to PHI STAR
 
3846
C
 
3847
      IF(KP1 .LT. NSP1) GO TO 280
 
3848
      DO 270 J=NSP1,KP1
 
3849
         DO 260 I=1,NEQ
 
3850
260         PHI(I,J)=BETA(J)*PHI(I,J)
 
3851
270      CONTINUE
 
3852
280   CONTINUE
 
3853
C
 
3854
C     Update time
 
3855
C
 
3856
      X=X+H
 
3857
C
 
3858
C     Initialize IDID to 1
 
3859
      IDID = 1
 
3860
C-----------------------------------------------------------------------
 
3861
C     BLOCK 3
 
3862
C     Call the nonlinear system solver to obtain the solution and
 
3863
C     derivative.
 
3864
C-----------------------------------------------------------------------
 
3865
C
 
3866
      CALL NLS(X,Y,YPRIME,NEQ,
 
3867
     *   RES,JAC,PSOL,H,WT,JSTART,IDID,RPAR,IPAR,PHI,GAMMA,
 
3868
     *   SAVR,DELTA,E,WM,IWM,CJ,CJOLD,CJLAST,S,
 
3869
     *   UROUND,EPLI,SQRTN,RSQRTN,EPCON,JCALC,JFLG,KP1,
 
3870
     *   NONNEG,NTYPE,IERNLS)
 
3871
C
 
3872
      IF(IERNLS .NE. 0)GO TO 600
 
3873
C-----------------------------------------------------------------------
 
3874
C     BLOCK 4
 
3875
C     Estimate the errors at orders K,K-1,K-2
 
3876
C     as if constant stepsize was used. Estimate
 
3877
C     the local error at order K and test
 
3878
C     whether the current step is successful.
 
3879
C-----------------------------------------------------------------------
 
3880
C
 
3881
C     Estimate errors at orders K,K-1,K-2
 
3882
C
 
3883
      ENORM = DDWNRM(NEQ,E,VT,RPAR,IPAR)
 
3884
c
 
3885
      ERK = SIGMA(K+1)*ENORM
 
3886
      TERK = (K+1)*ERK
 
3887
      EST = ERK 
 
3888
      KNEW=K
 
3889
      IF(K .EQ. 1)GO TO 430
 
3890
      DO 405 I = 1,NEQ
 
3891
405     DELTA(I) = PHI(I,KP1) + E(I)
 
3892
      ERKM1=SIGMA(K)*DDWNRM(NEQ,DELTA,VT,RPAR,IPAR)
 
3893
      TERKM1 = K*ERKM1
 
3894
      IF(K .GT. 2)GO TO 410
 
3895
      IF(TERKM1 .LE. 0.5*TERK)GO TO 420
 
3896
      GO TO 430
 
3897
410   CONTINUE
 
3898
      DO 415 I = 1,NEQ
 
3899
415     DELTA(I) = PHI(I,K) + DELTA(I)
 
3900
      ERKM2=SIGMA(K-1)*DDWNRM(NEQ,DELTA,VT,RPAR,IPAR)
 
3901
      TERKM2 = (K-1)*ERKM2
 
3902
      IF(MAX(TERKM1,TERKM2).GT.TERK)GO TO 430
 
3903
C
 
3904
C     Lower the order
 
3905
C
 
3906
420   CONTINUE
 
3907
      KNEW=K-1
 
3908
      EST = ERKM1 
 
3909
C
 
3910
C
 
3911
C     Calculate the local error for the current step
 
3912
C     to see if the step was successful
 
3913
C
 
3914
430   CONTINUE
 
3915
      ERR = CK * ENORM
 
3916
      IF(ERR .GT. 1.0D0)GO TO 600
 
3917
C
 
3918
C
 
3919
C
 
3920
C
 
3921
C
 
3922
C-----------------------------------------------------------------------
 
3923
C     BLOCK 5
 
3924
C     The step is successful. Determine
 
3925
C     the best order and stepsize for
 
3926
C     the next step. Update the differences
 
3927
C     for the next step.
 
3928
C-----------------------------------------------------------------------
 
3929
      IDID=1
 
3930
      IWM(LNST)=IWM(LNST)+1
 
3931
      KDIFF=K-KOLD
 
3932
      KOLD=K
 
3933
      HOLD=H
 
3934
C
 
3935
C
 
3936
C     Estimate the error at order K+1 unless
 
3937
C        already decided to lower order, or
 
3938
C        already using maximum order, or
 
3939
C        stepsize not constant, or
 
3940
C        order raised in previous step
 
3941
C
 
3942
      IF(KNEW.EQ.KM1.OR.K.EQ.IWM(LMXORD))IPHASE=1
 
3943
      IF(IPHASE .EQ. 0)GO TO 545
 
3944
      IF(KNEW.EQ.KM1)GO TO 540
 
3945
      IF(K.EQ.IWM(LMXORD)) GO TO 550
 
3946
      IF(KP1.GE.NS.OR.KDIFF.EQ.1)GO TO 550
 
3947
      DO 510 I=1,NEQ
 
3948
510      DELTA(I)=E(I)-PHI(I,KP2)
 
3949
      ERKP1 = (1.0D0/(K+2))*DDWNRM(NEQ,DELTA,VT,RPAR,IPAR)
 
3950
      TERKP1 = (K+2)*ERKP1
 
3951
 
 
3952
      IF(K.GT.1)GO TO 520
 
3953
      IF(TERKP1.GE.0.5D0*TERK)GO TO 550
 
3954
      GO TO 530
 
3955
520   IF(TERKM1.LE.MIN(TERK,TERKP1))GO TO 540
 
3956
      IF(TERKP1.GE.TERK.OR.K.EQ.IWM(LMXORD))GO TO 550
 
3957
C
 
3958
C     Raise order
 
3959
C
 
3960
530   K=KP1
 
3961
      EST = ERKP1
 
3962
      GO TO 550
 
3963
C
 
3964
C     Lower order
 
3965
C
 
3966
540   K=KM1
 
3967
      EST = ERKM1
 
3968
      GO TO 550
 
3969
C
 
3970
C     If IPHASE = 0, increase order by one and multiply stepsize by
 
3971
C     factor two
 
3972
C
 
3973
545   K = KP1
 
3974
      HNEW = H*2.0D0
 
3975
      H = HNEW
 
3976
      GO TO 575
 
3977
C
 
3978
C
 
3979
C     Determine the appropriate stepsize for
 
3980
C     the next step.
 
3981
C
 
3982
550   HNEW=H
 
3983
      TEMP2=K+1
 
3984
      R=(2.0D0*EST+0.0001D0)**(-1.0D0/TEMP2)
 
3985
      IF(R .LT. 2.0D0) GO TO 555
 
3986
      HNEW = 2.0D0*H
 
3987
      GO TO 560
 
3988
555   IF(R .GT. 1.0D0) GO TO 560
 
3989
      R = MAX(0.5D0,MIN(0.9D0,R))
 
3990
      HNEW = H*R
 
3991
560   H=HNEW
 
3992
C
 
3993
C
 
3994
C     Update differences for next step
 
3995
C
 
3996
575   CONTINUE
 
3997
      IF(KOLD.EQ.IWM(LMXORD))GO TO 585
 
3998
      DO 580 I=1,NEQ
 
3999
580      PHI(I,KP2)=E(I)
 
4000
585   CONTINUE
 
4001
      DO 590 I=1,NEQ
 
4002
590      PHI(I,KP1)=PHI(I,KP1)+E(I)
 
4003
      DO 595 J1=2,KP1
 
4004
         J=KP1-J1+1
 
4005
         DO 595 I=1,NEQ
 
4006
595      PHI(I,J)=PHI(I,J)+PHI(I,J+1)
 
4007
      JSTART = 1
 
4008
      RETURN
 
4009
C
 
4010
C
 
4011
C
 
4012
C
 
4013
C
 
4014
C-----------------------------------------------------------------------
 
4015
C     BLOCK 6
 
4016
 
 
4017
C     The step is unsuccessful. Restore X,PSI,PHI
 
4018
C     Determine appropriate stepsize for
 
4019
C     continuing the integration, or exit with
 
4020
C     an error flag if there have been many
 
4021
C     failures.
 
4022
C-----------------------------------------------------------------------
 
4023
600   IPHASE = 1
 
4024
C
 
4025
C     Restore X,PHI,PSI
 
4026
C
 
4027
      X=XOLD
 
4028
      IF(KP1.LT.NSP1)GO TO 630
 
4029
      DO 620 J=NSP1,KP1
 
4030
         TEMP1=1.0D0/BETA(J)
 
4031
         DO 610 I=1,NEQ
 
4032
610         PHI(I,J)=TEMP1*PHI(I,J)
 
4033
620      CONTINUE
 
4034
630   CONTINUE
 
4035
      DO 640 I=2,KP1
 
4036
640      PSI(I-1)=PSI(I)-H
 
4037
C
 
4038
C
 
4039
C     Test whether failure is due to nonlinear solver
 
4040
C     or error test
 
4041
C
 
4042
      IF(IERNLS .EQ. 0)GO TO 660
 
4043
      IWM(LCFN)=IWM(LCFN)+1
 
4044
C
 
4045
C
 
4046
C     The nonlinear solver failed to converge.
 
4047
C     Determine the cause of the failure and take appropriate action.
 
4048
C     If IERNLS .LT. 0, then return.  Otherwise, reduce the stepsize
 
4049
C     and try again, unless too many failures have occurred.
 
4050
C
 
4051
      IF (IERNLS .LT. 0) GO TO 675
 
4052
      NCF = NCF + 1
 
4053
      R = 0.25D0
 
4054
      H = H*R
 
4055
      IF (NCF .LT. 10 .AND. ABS(H) .GE. HMIN) GO TO 690
 
4056
      IF (IDID .EQ. 1) IDID = -7
 
4057
      IF (NEF .GE. 3) IDID = -9
 
4058
      GO TO 675
 
4059
C
 
4060
C
 
4061
C     The nonlinear solver converged, and the cause
 
4062
C     of the failure was the error estimate
 
4063
C     exceeding the tolerance.
 
4064
C
 
4065
660   NEF=NEF+1
 
4066
      IWM(LETF)=IWM(LETF)+1
 
4067
      IF (NEF .GT. 1) GO TO 665
 
4068
C
 
4069
C     On first error test failure, keep current order or lower
 
4070
C     order by one.  Compute new stepsize based on differences
 
4071
C     of the solution.
 
4072
C
 
4073
      K = KNEW
 
4074
      TEMP2 = K + 1
 
4075
      R = 0.90D0*(2.0D0*EST+0.0001D0)**(-1.0D0/TEMP2)
 
4076
      R = MAX(0.25D0,MIN(0.9D0,R))
 
4077
      H = H*R
 
4078
c     ------------------ HMIN chnage---------------------
 
4079
c     IF (ABS(H) .GE. HMIN) GO TO 690
 
4080
      if (X+H .GT. X) GO TO 690
 
4081
c     ------------------ HMIN chnage---------------------
 
4082
      IDID = -6
 
4083
      GO TO 675
 
4084
C
 
4085
C     On second error test failure, use the current order or
 
4086
C     decrease order by one.  Reduce the stepsize by a factor of
 
4087
C     one quarter.
 
4088
C
 
4089
665   IF (NEF .GT. 2) GO TO 670
 
4090
      K = KNEW
 
4091
      R = 0.25D0
 
4092
      H = R*H
 
4093
c     ------------------ HMIN chnage---------------------
 
4094
c     IF (ABS(H) .GE. HMIN) GO TO 690
 
4095
      if (X+H .GT. X) GO TO 690
 
4096
c     ------------------ HMIN chnage---------------------
 
4097
      IDID = -6
 
4098
      GO TO 675
 
4099
C
 
4100
C     On third and subsequent error test failures, set the order to
 
4101
C     one, and reduce the stepsize by a factor of one quarter.
 
4102
C
 
4103
670   K = 1
 
4104
      R = 0.25D0
 
4105
      H = R*H
 
4106
c     ------------------ HMIN chnage---------------------
 
4107
c     IF (ABS(H) .GE. HMIN) GO TO 690
 
4108
      if (X+H .GT. X) GO TO 690
 
4109
c     ------------------ HMIN chnage---------------------
 
4110
      IDID = -6
 
4111
      GO TO 675
 
4112
C
 
4113
C
 
4114
C
 
4115
C
 
4116
C     For all crashes, restore Y to its last value,
 
4117
C     interpolate to find YPRIME at last X, and return.
 
4118
C
 
4119
C     Before returning, verify that the user has not set
 
4120
C     IDID to a nonnegative value.  If the user has set IDID
 
4121
C     to a nonnegative value, then reset IDID to be -7, indicating
 
4122
C     a failure in the nonlinear system solver.
 
4123
C
 
4124
675   CONTINUE
 
4125
      CALL DDATRP1(X,X,Y,YPRIME,NEQ,K,PHI,PSI)
 
4126
      JSTART = 1
 
4127
      IF (IDID .GE. 0) IDID = -7
 
4128
      RETURN
 
4129
C
 
4130
C
 
4131
C     Go back and try this step again.  
 
4132
C     If this is the first step, reset PSI(1) and rescale PHI(*,2).
 
4133
C
 
4134
690   IF (KOLD .EQ. 0) THEN
 
4135
        PSI(1) = H
 
4136
        DO 695 I = 1,NEQ
 
4137
695       PHI(I,2) = R*PHI(I,2)
 
4138
        ENDIF
 
4139
      GO TO 200
 
4140
C
 
4141
C------END OF SUBROUTINE DDSTP------------------------------------------
 
4142
      END
 
4143
      SUBROUTINE DCNSTR (NEQ, Y, YNEW, ICNSTR, TAU, RLX, IRET, IVAR)
 
4144
C
 
4145
C***BEGIN PROLOGUE  DCNSTR
 
4146
C***DATE WRITTEN   950808   (YYMMDD)
 
4147
C***REVISION DATE  950814   (YYMMDD)
 
4148
C
 
4149
C
 
4150
C-----------------------------------------------------------------------
 
4151
C***DESCRIPTION
 
4152
C
 
4153
C This subroutine checks for constraint violations in the proposed 
 
4154
C new approximate solution YNEW.
 
4155
C If a constraint violation occurs, then a new step length, TAU,
 
4156
C is calculated, and this value is to be given to the linesearch routine
 
4157
C to calculate a new approximate solution YNEW.
 
4158
C
 
4159
C On entry:
 
4160
C
 
4161
C   NEQ    -- size of the nonlinear system, and the length of arrays
 
4162
C             Y, YNEW and ICNSTR.
 
4163
C
 
4164
C   Y      -- real array containing the current approximate y.
 
4165
C
 
4166
C   YNEW   -- real array containing the new approximate y.
 
4167
C
 
4168
C   ICNSTR -- INTEGER array of length NEQ containing flags indicating
 
4169
C             which entries in YNEW are to be constrained.
 
4170
C             if ICNSTR(I) =  2, then YNEW(I) must be .GT. 0,
 
4171
C             if ICNSTR(I) =  1, then YNEW(I) must be .GE. 0,
 
4172
C             if ICNSTR(I) = -1, then YNEW(I) must be .LE. 0, while
 
4173
C             if ICNSTR(I) = -2, then YNEW(I) must be .LT. 0, while
 
4174
C             if ICNSTR(I) =  0, then YNEW(I) is not constrained.
 
4175
C
 
4176
C   RLX    -- real scalar restricting update, if ICNSTR(I) = 2 or -2,
 
4177
C             to ABS( (YNEW-Y)/Y ) < FAC2*RLX in component I.
 
4178
C
 
4179
C   TAU    -- the current size of the step length for the linesearch.
 
4180
C
 
4181
C On return
 
4182
C
 
4183
C   TAU    -- the adjusted size of the step length if a constraint
 
4184
C             violation occurred (otherwise, it is unchanged).  it is
 
4185
C             the step length to give to the linesearch routine.
 
4186
C
 
4187
C   IRET   -- output flag.
 
4188
C             IRET=0 means that YNEW satisfied all constraints.
 
4189
C             IRET=1 means that YNEW failed to satisfy all the
 
4190
C                    constraints, and a new linesearch step
 
4191
C                    must be computed.
 
4192
C
 
4193
C   IVAR   -- index of variable causing constraint to be violated.
 
4194
C
 
4195
C-----------------------------------------------------------------------
 
4196
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
4197
      DIMENSION Y(NEQ), YNEW(NEQ), ICNSTR(NEQ)
 
4198
      SAVE FAC, FAC2, ZERO
 
4199
      DATA FAC /0.6D0/, FAC2 /0.9D0/, ZERO/0.0D0/
 
4200
C-----------------------------------------------------------------------
 
4201
C Check constraints for proposed new step YNEW.  If a constraint has
 
4202
C been violated, then calculate a new step length, TAU, to be
 
4203
C used in the linesearch routine.
 
4204
C-----------------------------------------------------------------------
 
4205
      IRET = 0
 
4206
      RDYMX = ZERO
 
4207
      IVAR = 0
 
4208
      DO 100 I = 1,NEQ
 
4209
C
 
4210
         IF (ICNSTR(I) .EQ. 2) THEN
 
4211
            RDY = ABS( (YNEW(I)-Y(I))/Y(I) )
 
4212
            IF (RDY .GT. RDYMX) THEN
 
4213
               RDYMX = RDY
 
4214
               IVAR = I
 
4215
            ENDIF
 
4216
            IF (YNEW(I) .LE. ZERO) THEN
 
4217
               TAU = FAC*TAU
 
4218
               IVAR = I
 
4219
               IRET = 1
 
4220
               RETURN
 
4221
            ENDIF
 
4222
C
 
4223
         ELSEIF (ICNSTR(I) .EQ. 1) THEN
 
4224
            IF (YNEW(I) .LT. ZERO) THEN
 
4225
               TAU = FAC*TAU
 
4226
               IVAR = I
 
4227
               IRET = 1
 
4228
               RETURN
 
4229
            ENDIF
 
4230
C
 
4231
         ELSEIF (ICNSTR(I) .EQ. -1) THEN
 
4232
            IF (YNEW(I) .GT. ZERO) THEN
 
4233
               TAU = FAC*TAU
 
4234
               IVAR = I
 
4235
               IRET = 1
 
4236
               RETURN
 
4237
            ENDIF
 
4238
C
 
4239
         ELSEIF (ICNSTR(I) .EQ. -2) THEN
 
4240
            RDY = ABS( (YNEW(I)-Y(I))/Y(I) )
 
4241
            IF (RDY .GT. RDYMX) THEN
 
4242
               RDYMX = RDY
 
4243
               IVAR = I
 
4244
            ENDIF
 
4245
            IF (YNEW(I) .GE. ZERO) THEN
 
4246
               TAU = FAC*TAU
 
4247
               IVAR = I
 
4248
               IRET = 1
 
4249
               RETURN
 
4250
            ENDIF
 
4251
C
 
4252
         ENDIF
 
4253
 100  CONTINUE
 
4254
 
 
4255
      IF(RDYMX .GE. RLX) THEN
 
4256
         TAU = FAC2*TAU*RLX/RDYMX
 
4257
         IRET = 1
 
4258
      ENDIF
 
4259
C
 
4260
      RETURN
 
4261
C----------------------- END OF SUBROUTINE DCNSTR ----------------------
 
4262
      END
 
4263
      SUBROUTINE DCNST0 (NEQ, Y, ICNSTR, IRET)
 
4264
C
 
4265
C***BEGIN PROLOGUE  DCNST0
 
4266
C***DATE WRITTEN   950808   (YYMMDD)
 
4267
C***REVISION DATE  950808   (YYMMDD)
 
4268
C
 
4269
C
 
4270
C-----------------------------------------------------------------------
 
4271
C***DESCRIPTION
 
4272
C
 
4273
C This subroutine checks for constraint violations in the initial 
 
4274
C approximate solution u.
 
4275
C
 
4276
C On entry
 
4277
C
 
4278
C   NEQ    -- size of the nonlinear system, and the length of arrays
 
4279
C             Y and ICNSTR.
 
4280
C
 
4281
C   Y      -- real array containing the initial approximate root.
 
4282
C
 
4283
C   ICNSTR -- INTEGER array of length NEQ containing flags indicating
 
4284
C             which entries in Y are to be constrained.
 
4285
C             if ICNSTR(I) =  2, then Y(I) must be .GT. 0,
 
4286
C             if ICNSTR(I) =  1, then Y(I) must be .GE. 0,
 
4287
C             if ICNSTR(I) = -1, then Y(I) must be .LE. 0, while
 
4288
C             if ICNSTR(I) = -2, then Y(I) must be .LT. 0, while
 
4289
C             if ICNSTR(I) =  0, then Y(I) is not constrained.
 
4290
C
 
4291
C On return
 
4292
C
 
4293
C   IRET   -- output flag.
 
4294
C             IRET=0    means that u satisfied all constraints.
 
4295
C             IRET.NE.0 means that Y(IRET) failed to satisfy its
 
4296
C                       constraint.
 
4297
C
 
4298
C-----------------------------------------------------------------------
 
4299
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
4300
      DIMENSION Y(NEQ), ICNSTR(NEQ)
 
4301
      SAVE ZERO
 
4302
      DATA ZERO/0.D0/
 
4303
C-----------------------------------------------------------------------
 
4304
C Check constraints for initial Y.  If a constraint has been violated,
 
4305
C set IRET = I to signal an error return to calling routine.
 
4306
C-----------------------------------------------------------------------
 
4307
      IRET = 0
 
4308
      DO 100 I = 1,NEQ
 
4309
         IF (ICNSTR(I) .EQ. 2) THEN
 
4310
            IF (Y(I) .LE. ZERO) THEN
 
4311
               IRET = I
 
4312
               RETURN
 
4313
            ENDIF
 
4314
         ELSEIF (ICNSTR(I) .EQ. 1) THEN
 
4315
            IF (Y(I) .LT. ZERO) THEN
 
4316
               IRET = I
 
4317
               RETURN
 
4318
            ENDIF 
 
4319
         ELSEIF (ICNSTR(I) .EQ. -1) THEN
 
4320
            IF (Y(I) .GT. ZERO) THEN
 
4321
               IRET = I
 
4322
               RETURN
 
4323
            ENDIF 
 
4324
         ELSEIF (ICNSTR(I) .EQ. -2) THEN
 
4325
            IF (Y(I) .GE. ZERO) THEN
 
4326
               IRET = I
 
4327
               RETURN
 
4328
            ENDIF 
 
4329
        ENDIF
 
4330
 100  CONTINUE
 
4331
      RETURN
 
4332
C----------------------- END OF SUBROUTINE DCNST0 ----------------------
 
4333
      END
 
4334
      SUBROUTINE DDAWTS1(NEQ,IWT,RTOL,ATOL,Y,WT,RPAR,IPAR)
 
4335
C
 
4336
C***BEGIN PROLOGUE  DDAWTS
 
4337
C***REFER TO  DDASPK
 
4338
C***ROUTINES CALLED  (NONE)
 
4339
C***DATE WRITTEN   890101   (YYMMDD)
 
4340
C***REVISION DATE  900926   (YYMMDD) 
 
4341
C***END PROLOGUE  DDAWTS
 
4342
C-----------------------------------------------------------------------
 
4343
C     This subroutine sets the error weight vector,
 
4344
C     WT, according to WT(I)=RTOL(I)*ABS(Y(I))+ATOL(I),
 
4345
C     I = 1 to NEQ.
 
4346
C     RTOL and ATOL are scalars if IWT = 0,
 
4347
C     and vectors if IWT = 1.
 
4348
C-----------------------------------------------------------------------
 
4349
C
 
4350
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
4351
      DIMENSION RTOL(*),ATOL(*),Y(*),WT(*)
 
4352
      DIMENSION RPAR(*),IPAR(*)
 
4353
      RTOLI=RTOL(1)
 
4354
      ATOLI=ATOL(1)
 
4355
      DO 20 I=1,NEQ
 
4356
         IF (IWT .EQ.0) GO TO 10
 
4357
           RTOLI=RTOL(I)
 
4358
           ATOLI=ATOL(I)
 
4359
10         WT(I)=RTOLI*ABS(Y(I))+ATOLI
 
4360
20         CONTINUE
 
4361
      RETURN
 
4362
C
 
4363
C------END OF SUBROUTINE DDAWTS-----------------------------------------
 
4364
      END
 
4365
      SUBROUTINE DINVWT(NEQ,WT,IER)
 
4366
C
 
4367
C***BEGIN PROLOGUE  DINVWT
 
4368
C***REFER TO  DDASPK
 
4369
C***ROUTINES CALLED  (NONE)
 
4370
C***DATE WRITTEN   950125   (YYMMDD)
 
4371
C***END PROLOGUE  DINVWT
 
4372
C-----------------------------------------------------------------------
 
4373
C     This subroutine checks the error weight vector WT, of length NEQ,
 
4374
C     for components that are .le. 0, and if none are found, it
 
4375
C     inverts the WT(I) in place.  This replaces division operations
 
4376
C     with multiplications in all norm evaluations.
 
4377
C     IER is returned as 0 if all WT(I) were found positive,
 
4378
C     and the first I with WT(I) .le. 0.0 otherwise.
 
4379
C-----------------------------------------------------------------------
 
4380
C
 
4381
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
4382
      DIMENSION WT(*)
 
4383
C
 
4384
      DO 10 I = 1,NEQ
 
4385
        IF (WT(I) .LE. 0.0D0) GO TO 30
 
4386
 10     CONTINUE
 
4387
      DO 20 I = 1,NEQ
 
4388
 20     WT(I) = 1.0D0/WT(I)
 
4389
      IER = 0
 
4390
      RETURN
 
4391
C
 
4392
 30   IER = I
 
4393
      RETURN
 
4394
C
 
4395
C------END OF SUBROUTINE DINVWT-----------------------------------------
 
4396
      END
 
4397
      SUBROUTINE DDATRP1(X,XOUT,YOUT,YPOUT,NEQ,KOLD,PHI,PSI)
 
4398
C
 
4399
C***BEGIN PROLOGUE  DDATRP
 
4400
C***REFER TO  DDASPK
 
4401
C***ROUTINES CALLED  (NONE)
 
4402
C***DATE WRITTEN   890101   (YYMMDD)
 
4403
C***REVISION DATE  900926   (YYMMDD)
 
4404
C***END PROLOGUE  DDATRP
 
4405
C
 
4406
C-----------------------------------------------------------------------
 
4407
C     The methods in subroutine DDSTP use polynomials
 
4408
C     to approximate the solution.  DDATRP approximates the
 
4409
C     solution and its derivative at time XOUT by evaluating
 
4410
C     one of these polynomials, and its derivative, there.
 
4411
C     Information defining this polynomial is passed from
 
4412
C     DDSTP, so DDATRP cannot be used alone.
 
4413
C
 
4414
C     The parameters are
 
4415
C
 
4416
C     X     The current time in the integration.
 
4417
C     XOUT  The time at which the solution is desired.
 
4418
C     YOUT  The interpolated approximation to Y at XOUT.
 
4419
C           (This is output.)
 
4420
C     YPOUT The interpolated approximation to YPRIME at XOUT.
 
4421
C           (This is output.)
 
4422
C     NEQ   Number of equations.
 
4423
C     KOLD  Order used on last successful step.
 
4424
C     PHI   Array of scaled divided differences of Y.
 
4425
C     PSI   Array of past stepsize history.
 
4426
C-----------------------------------------------------------------------
 
4427
C
 
4428
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
4429
      DIMENSION YOUT(*),YPOUT(*)
 
4430
      DIMENSION PHI(NEQ,*),PSI(*)
 
4431
      KOLDP1=KOLD+1
 
4432
      TEMP1=XOUT-X
 
4433
      DO 10 I=1,NEQ
 
4434
         YOUT(I)=PHI(I,1)
 
4435
10       YPOUT(I)=0.0D0
 
4436
      C=1.0D0
 
4437
      D=0.0D0
 
4438
      GAMMA=TEMP1/PSI(1)
 
4439
      DO 30 J=2,KOLDP1
 
4440
         D=D*GAMMA+C/PSI(J-1)
 
4441
         C=C*GAMMA
 
4442
         GAMMA=(TEMP1+PSI(J-1))/PSI(J)
 
4443
         DO 20 I=1,NEQ
 
4444
            YOUT(I)=YOUT(I)+C*PHI(I,J)
 
4445
20          YPOUT(I)=YPOUT(I)+D*PHI(I,J)
 
4446
30       CONTINUE
 
4447
      RETURN
 
4448
C
 
4449
C------END OF SUBROUTINE DDATRP-----------------------------------------
 
4450
      END
 
4451
      DOUBLE PRECISION FUNCTION DDWNRM(NEQ,V,RWT,RPAR,IPAR)
 
4452
C
 
4453
C***BEGIN PROLOGUE  DDWNRM
 
4454
C***ROUTINES CALLED  (NONE)
 
4455
C***DATE WRITTEN   890101   (YYMMDD)
 
4456
C***REVISION DATE  900926   (YYMMDD)
 
4457
C***END PROLOGUE  DDWNRM
 
4458
C-----------------------------------------------------------------------
 
4459
C     This function routine computes the weighted
 
4460
C     root-mean-square norm of the vector of length
 
4461
C     NEQ contained in the array V, with reciprocal weights
 
4462
C     contained in the array RWT of length NEQ.
 
4463
C        DDWNRM=SQRT((1/NEQ)*SUM(V(I)*RWT(I))**2)
 
4464
C-----------------------------------------------------------------------
 
4465
C
 
4466
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
4467
      DIMENSION V(*),RWT(*)
 
4468
      DIMENSION RPAR(*),IPAR(*)
 
4469
      DDWNRM = 0.0D0
 
4470
      VMAX = 0.0D0
 
4471
      DO 10 I = 1,NEQ
 
4472
        IF(ABS(V(I)*RWT(I)) .GT. VMAX) VMAX = ABS(V(I)*RWT(I))
 
4473
10    CONTINUE
 
4474
      IF(VMAX .LE. 0.0D0) GO TO 30
 
4475
      SUM = 0.0D0
 
4476
      DO 20 I = 1,NEQ
 
4477
 20      SUM = SUM + ((V(I)*RWT(I))/VMAX)**2
 
4478
 
 
4479
      DDWNRM = VMAX*SQRT(SUM/NEQ)
 
4480
30    CONTINUE
 
4481
      RETURN
 
4482
C
 
4483
C------END OF FUNCTION DDWNRM-------------------------------------------
 
4484
      END
 
4485
      SUBROUTINE DDASID(X,Y,YPRIME,NEQ,ICOPT,ID,RES,JACD,PDUM,H,TSCALE,
 
4486
     *  WT,JSDUM,RPAR,IPAR,DUMSVR,DELTA,R,YIC,YPIC,DUMPWK,WM,IWM,CJ,
 
4487
     *  UROUND,DUME,DUMS,DUMR,EPCON,RATEMX,STPTOL,JFDUM,
 
4488
     *  ICNFLG,ICNSTR,IERNLS)
 
4489
C
 
4490
C***BEGIN PROLOGUE  DDASID
 
4491
C***REFER TO  DDASPK
 
4492
C***DATE WRITTEN   940701   (YYMMDD)
 
4493
C***REVISION DATE  950808   (YYMMDD)
 
4494
C***REVISION DATE  951110   Removed unreachable block 390.
 
4495
C***REVISION DATE  000628   TSCALE argument added.
 
4496
C
 
4497
C
 
4498
C-----------------------------------------------------------------------
 
4499
C***DESCRIPTION
 
4500
C
 
4501
C
 
4502
C     DDASID solves a nonlinear system of algebraic equations of the
 
4503
C     form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME in
 
4504
C     the initial conditions.
 
4505
C
 
4506
C     The method used is a modified Newton scheme.
 
4507
C
 
4508
C     The parameters represent
 
4509
C
 
4510
C     X         -- Independent variable.
 
4511
C     Y         -- Solution vector.
 
4512
C     YPRIME    -- Derivative of solution vector.
 
4513
C     NEQ       -- Number of unknowns.
 
4514
C     ICOPT     -- Initial condition option chosen (1 or 2).
 
4515
C     ID        -- Array of dimension NEQ, which must be initialized
 
4516
C                  if ICOPT = 1.  See DDASIC.
 
4517
C     RES       -- External user-supplied subroutine to evaluate the
 
4518
C                  residual.  See RES description in DDASPK prologue.
 
4519
C     JACD      -- External user-supplied routine to evaluate the
 
4520
C                  Jacobian.  See JAC description for the case
 
4521
C                  INFO(12) = 0 in the DDASPK prologue.
 
4522
C     PDUM      -- Dummy argument.
 
4523
C     H         -- Scaling factor for this initial condition calc.
 
4524
C     TSCALE    -- Scale factor in T, used for stopping tests if nonzero.
 
4525
C     WT        -- Vector of weights for error criterion.
 
4526
C     JSDUM     -- Dummy argument.
 
4527
C     RPAR,IPAR -- Real and integer arrays used for communication
 
4528
C                  between the calling program and external user
 
4529
C                  routines.  They are not altered within DASPK.
 
4530
C     DUMSVR    -- Dummy argument.
 
4531
C     DELTA     -- Work vector for NLS of length NEQ.
 
4532
C     R         -- Work vector for NLS of length NEQ.
 
4533
C     YIC,YPIC  -- Work vectors for NLS, each of length NEQ.
 
4534
C     DUMPWK    -- Dummy argument.
 
4535
C     WM,IWM    -- Real and integer arrays storing matrix information
 
4536
C                  such as the matrix of partial derivatives,
 
4537
C                  permutation vector, and various other information.
 
4538
C     CJ        -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2).
 
4539
C     UROUND    -- Unit roundoff.
 
4540
C     DUME      -- Dummy argument.
 
4541
C     DUMS      -- Dummy argument.
 
4542
C     DUMR      -- Dummy argument.
 
4543
C     EPCON     -- Tolerance to test for convergence of the Newton
 
4544
C                  iteration.
 
4545
C     RATEMX    -- Maximum convergence rate for which Newton iteration
 
4546
C                  is considered converging.
 
4547
C     JFDUM     -- Dummy argument.
 
4548
C     STPTOL    -- Tolerance used in calculating the minimum lambda
 
4549
C                  value allowed.
 
4550
C     ICNFLG    -- Integer scalar.  If nonzero, then constraint
 
4551
C                  violations in the proposed new approximate solution
 
4552
C                  will be checked for, and the maximum step length 
 
4553
C                  will be adjusted accordingly.
 
4554
C     ICNSTR    -- Integer array of length NEQ containing flags for
 
4555
C                  checking constraints.
 
4556
C     IERNLS    -- Error flag for nonlinear solver.
 
4557
C                   0   ==> nonlinear solver converged.
 
4558
C                   1,2 ==> recoverable error inside nonlinear solver.
 
4559
C                           1 => retry with current Y, YPRIME
 
4560
C                           2 => retry with original Y, YPRIME
 
4561
C                  -1   ==> unrecoverable error in nonlinear solver.
 
4562
C                  -2   ==> Singular Jacobian
 
4563
C     All variables with "DUM" in their names are dummy variables
 
4564
C     which are not used in this routine.
 
4565
C
 
4566
C-----------------------------------------------------------------------
 
4567
C
 
4568
C***ROUTINES CALLED
 
4569
C   RES, DMATD, DNSID
 
4570
C
 
4571
C***END PROLOGUE  DDASID
 
4572
C
 
4573
C
 
4574
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
4575
      DIMENSION Y(*),YPRIME(*),ID(*),WT(*),ICNSTR(*)
 
4576
      DIMENSION DELTA(*),R(*),YIC(*),YPIC(*)
 
4577
      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
 
4578
      EXTERNAL  RES, JACD
 
4579
C
 
4580
      PARAMETER (LNRE=12, LNJE=13, LMXNIT=32, LMXNJ=33)
 
4581
C
 
4582
C
 
4583
C     Perform initializations.
 
4584
C
 
4585
      MXNIT = IWM(LMXNIT)
 
4586
      MXNJ = IWM(LMXNJ)
 
4587
      IERNLS = 0
 
4588
      NJ = 0
 
4589
C
 
4590
C     Call RES to initialize DELTA.
 
4591
C
 
4592
      IRES = 0
 
4593
      IWM(LNRE) = IWM(LNRE) + 1
 
4594
      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
 
4595
      IF (IRES .LT. 0) GO TO 370
 
4596
 
 
4597
C     Looping point for updating the Jacobian.
 
4598
C
 
4599
300   CONTINUE
 
4600
C
 
4601
C     Initialize all error flags to zero.
 
4602
C
 
4603
      IERJ = 0
 
4604
      IRES = 0
 
4605
      IERNEW = 0
 
4606
C
 
4607
C     Reevaluate the iteration matrix, J = dG/dY + CJ*dG/dYPRIME,
 
4608
C     where G(X,Y,YPRIME) = 0.
 
4609
C
 
4610
      NJ = NJ + 1
 
4611
      IWM(LNJE)=IWM(LNJE)+1
 
4612
 
 
4613
      CALL DMATD(NEQ,X,Y,YPRIME,DELTA,CJ,H,IERJ,WT,R,
 
4614
     *              WM,IWM,RES,IRES,UROUND,JACD,RPAR,IPAR)
 
4615
c     assigning two different error message for singular-Jacobian and
 
4616
c     internal error
 
4617
      IF (IRES .LT. 0) GO TO 370
 
4618
      IF (IERJ .NE. 0) GO TO 375
 
4619
 
 
4620
C     Call the nonlinear Newton solver for up to MXNIT iterations.
 
4621
 
 
4622
      CALL DNSID(X,Y,YPRIME,NEQ,ICOPT,ID,RES,WT,RPAR,IPAR,DELTA,R,
 
4623
     *     YIC,YPIC,WM,IWM,CJ,TSCALE,EPCON,RATEMX,MXNIT,STPTOL,
 
4624
     *     ICNFLG,ICNSTR,IERNEW)
 
4625
 
 
4626
      IF (IERNEW .EQ. 1 .AND. NJ .LT. MXNJ) THEN
 
4627
C     
 
4628
C     MXNIT iterations were done, the convergence rate is < 1,
 
4629
C     and the number of Jacobian evaluations is less than MXNJ.
 
4630
C     Call RES, reevaluate the Jacobian, and try again.
 
4631
C     
 
4632
         IWM(LNRE)=IWM(LNRE)+1
 
4633
         CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
 
4634
         IF (IRES .LT. 0) GO TO 370
 
4635
         GO TO 300
 
4636
      ENDIF
 
4637
      IF (IERNEW .NE. 0) GO TO 380
 
4638
      RETURN
 
4639
C     
 
4640
C     
 
4641
C     Unsuccessful exits from nonlinear solver.
 
4642
C     Compute IERNLS accordingly.
 
4643
C
 
4644
C     unrecoverable error in nonlinear solver.
 
4645
 370  IERNLS = -1
 
4646
      RETURN
 
4647
c     >> singular Jacobian
 
4648
 375  IERNLS = -2
 
4649
      RETURN
 
4650
C     
 
4651
380   IERNLS = MIN(IERNEW,2)
 
4652
      RETURN
 
4653
C
 
4654
C------END OF SUBROUTINE DDASID-----------------------------------------
 
4655
      END
 
4656
      SUBROUTINE DNSID(X,Y,YPRIME,NEQ,ICOPT,ID,RES,WT,RPAR,IPAR,
 
4657
     *   DELTA,R,YIC,YPIC,WM,IWM,CJ,TSCALE,EPCON,RATEMX,MAXIT,STPTOL,
 
4658
     *   ICNFLG,ICNSTR,IERNEW)
 
4659
C
 
4660
C***BEGIN PROLOGUE  DNSID
 
4661
C***REFER TO  DDASPK
 
4662
C***DATE WRITTEN   940701   (YYMMDD)
 
4663
C***REVISION DATE  950713   (YYMMDD)
 
4664
C***REVISION DATE  000628   TSCALE argument added.
 
4665
C
 
4666
C
 
4667
C-----------------------------------------------------------------------
 
4668
C***DESCRIPTION
 
4669
C
 
4670
C     DNSID solves a nonlinear system of algebraic equations of the
 
4671
C     form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME
 
4672
C     in the initial conditions.
 
4673
C
 
4674
C     The method used is a modified Newton scheme.
 
4675
C
 
4676
C     The parameters represent
 
4677
C
 
4678
C     X         -- Independent variable.
 
4679
C     Y         -- Solution vector.
 
4680
C     YPRIME    -- Derivative of solution vector.
 
4681
C     NEQ       -- Number of unknowns.
 
4682
C     ICOPT     -- Initial condition option chosen (1 or 2).
 
4683
C     ID        -- Array of dimension NEQ, which must be initialized
 
4684
C                  if ICOPT = 1.  See DDASIC.
 
4685
C     RES       -- External user-supplied subroutine to evaluate the
 
4686
C                  residual.  See RES description in DDASPK prologue.
 
4687
C     WT        -- Vector of weights for error criterion.
 
4688
C     RPAR,IPAR -- Real and integer arrays used for communication
 
4689
C                  between the calling program and external user
 
4690
C                  routines.  They are not altered within DASPK.
 
4691
C     DELTA     -- Residual vector on entry, and work vector of
 
4692
C                  length NEQ for DNSID.
 
4693
C     WM,IWM    -- Real and integer arrays storing matrix information
 
4694
C                  such as the matrix of partial derivatives,
 
4695
C                  permutation vector, and various other information.
 
4696
C     CJ        -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2).
 
4697
C     TSCALE    -- Scale factor in T, used for stopping tests if nonzero.
 
4698
C     R         -- Array of length NEQ used as workspace by the 
 
4699
C                  linesearch routine DLINSD.
 
4700
C     YIC,YPIC  -- Work vectors for DLINSD, each of length NEQ.
 
4701
C     EPCON     -- Tolerance to test for convergence of the Newton
 
4702
C                  iteration.
 
4703
C     RATEMX    -- Maximum convergence rate for which Newton iteration
 
4704
C                  is considered converging.
 
4705
C     MAXIT     -- Maximum allowed number of Newton iterations.
 
4706
C     STPTOL    -- Tolerance used in calculating the minimum lambda
 
4707
C                  value allowed.
 
4708
C     ICNFLG    -- Integer scalar.  If nonzero, then constraint
 
4709
C                  violations in the proposed new approximate solution
 
4710
C                  will be checked for, and the maximum step length 
 
4711
C                  will be adjusted accordingly.
 
4712
C     ICNSTR    -- Integer array of length NEQ containing flags for
 
4713
C                  checking constraints.
 
4714
C     IERNEW    -- Error flag for Newton iteration.
 
4715
C                   0  ==> Newton iteration converged.
 
4716
C                   1  ==> failed to converge, but RATE .le. RATEMX.
 
4717
C                   2  ==> failed to converge, RATE .gt. RATEMX.
 
4718
C                   3  ==> other recoverable error (IRES = -1, or
 
4719
C                          linesearch failed).
 
4720
C                  -1  ==> unrecoverable error (IRES = -2).
 
4721
C
 
4722
C-----------------------------------------------------------------------
 
4723
C
 
4724
C***ROUTINES CALLED
 
4725
C   DSLVD, DDWNRM, DLINSD, DCOPY
 
4726
C
 
4727
C***END PROLOGUE  DNSID
 
4728
C
 
4729
C
 
4730
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
4731
      DIMENSION Y(*),YPRIME(*),WT(*),R(*)
 
4732
      DIMENSION ID(*),DELTA(*), YIC(*), YPIC(*)
 
4733
      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
 
4734
      DIMENSION ICNSTR(*)
 
4735
      EXTERNAL  RES
 
4736
C
 
4737
      PARAMETER (LNNI=19, LLSOFF=35)
 
4738
C
 
4739
C
 
4740
C     Initializations.  M is the Newton iteration counter.
 
4741
C
 
4742
 
 
4743
      LSOFF = IWM(LLSOFF)
 
4744
      M = 0
 
4745
      RATE = 1.0D0
 
4746
      RLX = 0.4D0
 
4747
C
 
4748
C     Compute a new step vector DELTA by back-substitution.
 
4749
C
 
4750
      CALL DSLVD (NEQ, DELTA, WM, IWM)
 
4751
C
 
4752
 
 
4753
C     Get norm of DELTA.  Return now if norm(DELTA) .le. EPCON.
 
4754
C
 
4755
      DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
 
4756
      FNRM = DELNRM
 
4757
      IF (TSCALE .GT. 0.0D0) FNRM = FNRM*TSCALE*ABS(CJ)
 
4758
      
 
4759
      IF (FNRM .LE. EPCON) RETURN
 
4760
C
 
4761
C     Newton iteration loop.
 
4762
C     
 
4763
 300  CONTINUE
 
4764
      IWM(LNNI) = IWM(LNNI) + 1
 
4765
C     
 
4766
C     Call linesearch routine for global strategy and set RATE
 
4767
C
 
4768
      OLDFNM = FNRM
 
4769
C
 
4770
      CALL DLINSD (NEQ, Y, X, YPRIME, CJ, TSCALE, DELTA, DELNRM, WT,
 
4771
     *             LSOFF, STPTOL, IRET, RES, IRES, WM, IWM, FNRM, ICOPT,
 
4772
     *             ID, R, YIC, YPIC, ICNFLG, ICNSTR, RLX, RPAR, IPAR)
 
4773
C
 
4774
      RATE = FNRM/OLDFNM
 
4775
 
 
4776
C     Check for error condition from linesearch.
 
4777
      IF (IRET .NE. 0) GO TO 390
 
4778
C
 
4779
C     Test for convergence of the iteration, and return or loop.
 
4780
C     ------------------------------------------
 
4781
      IERNEW = 1
 
4782
      RETURN
 
4783
 
 
4784
C     ------------------------------------------
 
4785
c     here epcon=0.33
 
4786
      IF (FNRM .LE. EPCON) RETURN
 
4787
C     
 
4788
C     The iteration has not yet converged.  Update M.
 
4789
C     Test whether the maximum number of iterations have been tried.
 
4790
C
 
4791
      M = M + 1
 
4792
      IF (M .GE. MAXIT) GO TO 380
 
4793
C
 
4794
C     Copy the residual to DELTA and its norm to DELNRM, and loop for
 
4795
C     another iteration.
 
4796
C
 
4797
      CALL DCOPY (NEQ, R, 1, DELTA, 1)
 
4798
      DELNRM = FNRM      
 
4799
      GO TO 300
 
4800
C
 
4801
C     The maximum number of iterations was done.  Set IERNEW and return.
 
4802
C
 
4803
c     here ratemx =0.8
 
4804
 380  IF (RATE .LE. RATEMX) THEN
 
4805
         IERNEW = 1
 
4806
      ELSE
 
4807
         IERNEW = 2
 
4808
      ENDIF
 
4809
      RETURN
 
4810
C
 
4811
 390  IF (IRES .LE. -2) THEN
 
4812
         IERNEW = -1
 
4813
      ELSE
 
4814
         IERNEW = 3
 
4815
      ENDIF
 
4816
      RETURN
 
4817
C
 
4818
C
 
4819
C------END OF SUBROUTINE DNSID------------------------------------------
 
4820
      END
 
4821
      SUBROUTINE DLINSD (NEQ, Y, T, YPRIME, CJ, TSCALE, P, PNRM, WT,
 
4822
     *                   LSOFF, STPTOL, IRET, RES, IRES, WM, IWM,
 
4823
     *                   FNRM, ICOPT, ID, R, YNEW, YPNEW, ICNFLG,
 
4824
     *                   ICNSTR, RLX, RPAR, IPAR)
 
4825
C
 
4826
C***BEGIN PROLOGUE  DLINSD
 
4827
C***REFER TO  DNSID
 
4828
C***DATE WRITTEN   941025   (YYMMDD)
 
4829
C***REVISION DATE  941215   (YYMMDD)
 
4830
C***REVISION DATE  960129   Moved line RL = ONE to top block.
 
4831
C***REVISION DATE  000628   TSCALE argument added.
 
4832
C
 
4833
C
 
4834
C-----------------------------------------------------------------------
 
4835
C***DESCRIPTION
 
4836
C
 
4837
C     DLINSD uses a linesearch algorithm to calculate a new (Y,YPRIME)
 
4838
C     pair (YNEW,YPNEW) such that 
 
4839
C
 
4840
C     f(YNEW,YPNEW) .le. (1 - 2*ALPHA*RL)*f(Y,YPRIME) ,
 
4841
C
 
4842
C     where 0 < RL <= 1.  Here, f(y,y') is defined as
 
4843
C
 
4844
C      f(y,y') = (1/2)*norm( (J-inverse)*G(t,y,y') )**2 ,
 
4845
C
 
4846
C     where norm() is the weighted RMS vector norm, G is the DAE
 
4847
C     system residual function, and J is the system iteration matrix
 
4848
C     (Jacobian).
 
4849
C
 
4850
C     In addition to the parameters defined elsewhere, we have
 
4851
C
 
4852
C     TSCALE  --  Scale factor in T, used for stopping tests if nonzero.
 
4853
C     P       -- Approximate Newton step used in backtracking.
 
4854
C     PNRM    -- Weighted RMS norm of P.
 
4855
C     LSOFF   -- Flag showing whether the linesearch algorithm is
 
4856
C                to be invoked.  0 means do the linesearch, and
 
4857
C                1 means turn off linesearch.
 
4858
C     STPTOL  -- Tolerance used in calculating the minimum lambda
 
4859
C                value allowed.
 
4860
C     ICNFLG  -- Integer scalar.  If nonzero, then constraint violations
 
4861
C                in the proposed new approximate solution will be
 
4862
C                checked for, and the maximum step length will be
 
4863
C                adjusted accordingly.
 
4864
C     ICNSTR  -- Integer array of length NEQ containing flags for
 
4865
C                checking constraints.
 
4866
C     RLX     -- Real scalar restricting update size in DCNSTR.
 
4867
C     YNEW    -- Array of length NEQ used to hold the new Y in
 
4868
C                performing the linesearch.
 
4869
C     YPNEW   -- Array of length NEQ used to hold the new YPRIME in
 
4870
C                performing the linesearch.
 
4871
C     Y       -- Array of length NEQ containing the new Y (i.e.,=YNEW).
 
4872
C     YPRIME  -- Array of length NEQ containing the new YPRIME 
 
4873
C                (i.e.,=YPNEW).
 
4874
C     FNRM    -- Real scalar containing SQRT(2*f(Y,YPRIME)) for the
 
4875
C                current (Y,YPRIME) on input and output.
 
4876
C     R       -- Work array of length NEQ, containing the scaled 
 
4877
C                residual (J-inverse)*G(t,y,y') on return.
 
4878
C     IRET    -- Return flag.
 
4879
C                IRET=0 means that a satisfactory (Y,YPRIME) was found.
 
4880
C                IRET=1 means that the routine failed to find a new
 
4881
C                       (Y,YPRIME) that was sufficiently distinct from
 
4882
C                       the current (Y,YPRIME) pair.
 
4883
C                IRET=2 means IRES .ne. 0 from RES.
 
4884
C-----------------------------------------------------------------------
 
4885
C
 
4886
C***ROUTINES CALLED
 
4887
C   DFNRMD, DYYPNW, DCNSTR, DCOPY, XERRWD
 
4888
C
 
4889
C***END PROLOGUE  DLINSD
 
4890
C
 
4891
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
4892
      EXTERNAL  RES
 
4893
      DIMENSION Y(*), YPRIME(*), WT(*), R(*), ID(*)
 
4894
      DIMENSION WM(*), IWM(*)
 
4895
      DIMENSION YNEW(*), YPNEW(*), P(*), ICNSTR(*)
 
4896
      DIMENSION RPAR(*), IPAR(*)
 
4897
      CHARACTER MSG*80
 
4898
C     
 
4899
      PARAMETER (LNRE=12, LKPRIN=31)
 
4900
C     
 
4901
      SAVE ALPHA, ONE, TWO
 
4902
      DATA ALPHA/1.0D-4/, ONE/1.0D0/, TWO/2.0D0/
 
4903
C     
 
4904
      KPRIN=IWM(LKPRIN)
 
4905
C     
 
4906
      F1NRM = (FNRM*FNRM)/TWO
 
4907
      RATIO = ONE
 
4908
      IF (KPRIN .GE. 2) THEN
 
4909
         MSG = '------ IN ROUTINE DLINSD-- PNRM = (R1)'
 
4910
         CALL XERRWD(MSG, 38, 901, 0, 0, 0, 0, 1, PNRM, 0.0D0)
 
4911
      ENDIF
 
4912
      TAU = PNRM
 
4913
      RL = ONE
 
4914
       
 
4915
C-----------------------------------------------------------------------
 
4916
C     Check for violations of the constraints, if any are imposed.
 
4917
C     If any violations are found, the step vector P is rescaled, and the 
 
4918
C     constraint check is repeated, until no violations are found.
 
4919
C-----------------------------------------------------------------------
 
4920
c     here ICNFLG=0!
 
4921
      IF(ICNFLG .NE. 0) THEN
 
4922
 10     CONTINUE
 
4923
        CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW)
 
4924
        CALL DCNSTR (NEQ, Y, YNEW, ICNSTR, TAU, RLX, IRET, IVAR)
 
4925
        IF (IRET .EQ. 1) THEN
 
4926
           RATIO1 = TAU/PNRM
 
4927
           RATIO = RATIO*RATIO1
 
4928
           DO 20 I = 1,NEQ
 
4929
 20          P(I) = P(I)*RATIO1
 
4930
             PNRM = TAU
 
4931
             IF(KPRIN .GE. 2) THEN
 
4932
             MSG = '------ CONSTRAINT VIOL., PNRM = (R1), INDEX = (I1)'
 
4933
             CALL XERRWD(MSG, 50, 902, 0, 1, IVAR, 0, 1, PNRM, 0.0D0)
 
4934
              ENDIF
 
4935
              IF (PNRM .LE. STPTOL) THEN
 
4936
                 IRET = 1
 
4937
                 RETURN
 
4938
              ENDIF
 
4939
              GO TO 10
 
4940
           ENDIF
 
4941
        ENDIF
 
4942
C     
 
4943
         SLPI = (-TWO*F1NRM)*RATIO
 
4944
         RLMIN = STPTOL/PNRM
 
4945
         IF (LSOFF .EQ. 0 .AND. KPRIN .GE. 2) THEN
 
4946
            MSG = '------ MIN. LAMBDA = (R1)'
 
4947
            CALL XERRWD(MSG, 25, 903, 0, 0, 0, 0, 1, RLMIN, 0.0D0)
 
4948
         ENDIF
 
4949
C-----------------------------------------------------------------------
 
4950
C     Begin iteration to find RL value satisfying alpha-condition.
 
4951
C     If RL becomes less than RLMIN, then terminate with IRET = 1.
 
4952
C-----------------------------------------------------------------------
 
4953
 100     CONTINUE
 
4954
c     ----------------------------------------------------------
 
4955
         CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW)
 
4956
         CALL DFNRMD (NEQ, YNEW, T, YPNEW, R, CJ, TSCALE, WT, RES, IRES,
 
4957
     *        FNRMP, WM, IWM, RPAR, IPAR)
 
4958
 
 
4959
         IWM(LNRE) = IWM(LNRE) + 1
 
4960
         IF (IRES .NE. 0) THEN
 
4961
            IRET = 2
 
4962
            RETURN
 
4963
         ENDIF
 
4964
 
 
4965
         IF (LSOFF .EQ. 1) GO TO 150
 
4966
 
 
4967
         F1NRMP = FNRMP*FNRMP/TWO
 
4968
         IF (KPRIN .GE. 2) THEN
 
4969
            MSG = '------ LAMBDA = (R1)'
 
4970
            CALL XERRWD(MSG, 20, 904, 0, 0, 0, 0, 1, RL, 0.0D0)
 
4971
            MSG = '------ NORM(F1) = (R1),  NORM(F1NEW) = (R2)'
 
4972
            CALL XERRWD(MSG, 43, 905, 0, 0, 0, 0, 2, F1NRM, F1NRMP)
 
4973
         ENDIF
 
4974
         IF (F1NRMP .GT. F1NRM + ALPHA*SLPI*RL) GO TO 200
 
4975
C-----------------------------------------------------------------------
 
4976
C     Alpha-condition is satisfied, or linesearch is turned off.
 
4977
C     Copy YNEW,YPNEW to Y,YPRIME and return.
 
4978
C-----------------------------------------------------------------------
 
4979
 150     IRET = 0
 
4980
         CALL DCOPY (NEQ, YNEW, 1, Y, 1)
 
4981
         CALL DCOPY (NEQ, YPNEW, 1, YPRIME, 1)
 
4982
         FNRM = FNRMP
 
4983
         IF (KPRIN .GE. 1) THEN
 
4984
            MSG = '------ LEAVING ROUTINE DLINSD, FNRM = (R1)'
 
4985
            CALL XERRWD(MSG, 42, 906, 0, 0, 0, 0, 1, FNRM, 0.0D0)
 
4986
         ENDIF
 
4987
         RETURN
 
4988
C-----------------------------------------------------------------------
 
4989
C     Alpha-condition not satisfied.  Perform backtrack to compute new RL
 
4990
C     value.  If no satisfactory YNEW,YPNEW can be found sufficiently 
 
4991
C     distinct from Y,YPRIME, then return IRET = 1.
 
4992
C-----------------------------------------------------------------------
 
4993
 200     CONTINUE
 
4994
         IF (RL .LT. RLMIN) THEN
 
4995
            IRET = 1
 
4996
            RETURN
 
4997
         ENDIF
 
4998
C     
 
4999
         RL = RL/TWO
 
5000
         GO TO 100
 
5001
C     
 
5002
C-----------------------END OF SUBROUTINE DLINSD ----------------------
 
5003
         END
 
5004
      SUBROUTINE DFNRMD (NEQ, Y, T, YPRIME, R, CJ, TSCALE, WT,
 
5005
     *     RES, IRES, FNORM, WM, IWM, RPAR, IPAR)
 
5006
C     
 
5007
C***  BEGIN PROLOGUE  DFNRMD
 
5008
C***  REFER TO  DLINSD
 
5009
C***  DATE WRITTEN   941025   (YYMMDD)
 
5010
C***  REVISION DATE  000628   TSCALE argument added.
 
5011
C     
 
5012
C
 
5013
C-----------------------------------------------------------------------
 
5014
C***DESCRIPTION
 
5015
C
 
5016
C     DFNRMD calculates the scaled preconditioned norm of the nonlinear
 
5017
C     function used in the nonlinear iteration for obtaining consistent
 
5018
C     initial conditions.  Specifically, DFNRMD calculates the weighted
 
5019
C     root-mean-square norm of the vector (J-inverse)*G(T,Y,YPRIME),
 
5020
C     where J is the Jacobian matrix.
 
5021
C
 
5022
C     In addition to the parameters described in the calling program
 
5023
C     DLINSD, the parameters represent
 
5024
C
 
5025
C     R      -- Array of length NEQ that contains
 
5026
C               (J-inverse)*G(T,Y,YPRIME) on return.
 
5027
C     TSCALE -- Scale factor in T, used for stopping tests if nonzero.
 
5028
C     FNORM  -- Scalar containing the weighted norm of R on return.
 
5029
C-----------------------------------------------------------------------
 
5030
C
 
5031
C***ROUTINES CALLED
 
5032
C   RES, DSLVD, DDWNRM
 
5033
C
 
5034
C***END PROLOGUE  DFNRMD
 
5035
C
 
5036
C
 
5037
      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
 
5038
      EXTERNAL RES
 
5039
      DIMENSION Y(*), YPRIME(*), WT(*), R(*)
 
5040
      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
 
5041
C-----------------------------------------------------------------------
 
5042
C     Call RES routine.
 
5043
C-----------------------------------------------------------------------
 
5044
      IRES = 0
 
5045
      CALL RES(T,Y,YPRIME,CJ,R,IRES,RPAR,IPAR)
 
5046
      IF (IRES .LT. 0) RETURN
 
5047
C-----------------------------------------------------------------------
 
5048
C     Apply inverse of Jacobian to vector R.
 
5049
C-----------------------------------------------------------------------
 
5050
      CALL DSLVD(NEQ,R,WM,IWM)
 
5051
C-----------------------------------------------------------------------
 
5052
C     Calculate norm of R.
 
5053
C-----------------------------------------------------------------------
 
5054
      FNORM = DDWNRM(NEQ,R,WT,RPAR,IPAR)
 
5055
      IF (TSCALE .GT. 0.0D0) FNORM = FNORM*TSCALE*ABS(CJ)
 
5056
C     
 
5057
      RETURN
 
5058
C-----------------------END OF SUBROUTINE DFNRMD ----------------------
 
5059
       END
 
5060
      SUBROUTINE DNEDD(X,Y,YPRIME,NEQ,RES,JACD,PDUM,H,WT,
 
5061
     *     JSTART,IDID,RPAR,IPAR,PHI,GAMMA,DUMSVR,DELTA,E,
 
5062
     *   WM,IWM,CJ,CJOLD,CJLAST,S,UROUND,DUME,DUMS,DUMR,
 
5063
     *   EPCON,JCALC,JFDUM,KP1,NONNEG,NTYPE,IERNLS)
 
5064
C
 
5065
C***BEGIN PROLOGUE  DNEDD
 
5066
C***REFER TO  DDASPK
 
5067
C***DATE WRITTEN   891219   (YYMMDD)
 
5068
C***REVISION DATE  900926   (YYMMDD)
 
5069
C
 
5070
C
 
5071
C-----------------------------------------------------------------------
 
5072
C***DESCRIPTION
 
5073
C
 
5074
C     DNEDD solves a nonlinear system of
 
5075
C     algebraic equations of the form
 
5076
C     G(X,Y,YPRIME) = 0 for the unknown Y.
 
5077
C
 
5078
C     The method used is a modified Newton scheme.
 
5079
C
 
5080
C     The parameters represent
 
5081
C
 
5082
C     X         -- Independent variable.
 
5083
C     Y         -- Solution vector.
 
5084
C     YPRIME    -- Derivative of solution vector.
 
5085
C     NEQ       -- Number of unknowns.
 
5086
C     RES       -- External user-supplied subroutine
 
5087
C                  to evaluate the residual.  See RES description
 
5088
C                  in DDASPK prologue.
 
5089
C     JACD      -- External user-supplied routine to evaluate the
 
5090
C                  Jacobian.  See JAC description for the case
 
5091
C                  INFO(12) = 0 in the DDASPK prologue.
 
5092
C     PDUM      -- Dummy argument.
 
5093
C     H         -- Appropriate step size for next step.
 
5094
C     WT        -- Vector of weights for error criterion.
 
5095
C     JSTART    -- Indicates first call to this routine.
 
5096
C                  If JSTART = 0, then this is the first call,
 
5097
C                  otherwise it is not.
 
5098
C     IDID      -- Completion flag, output by DNEDD.
 
5099
C                  See IDID description in DDASPK prologue.
 
5100
C     RPAR,IPAR -- Real and integer arrays used for communication
 
5101
C                  between the calling program and external user
 
5102
C                  routines.  They are not altered within DASPK.
 
5103
C     PHI       -- Array of divided differences used by
 
5104
C                  DNEDD.  The length is NEQ*(K+1),where
 
5105
C                  K is the maximum order.
 
5106
C     GAMMA     -- Array used to predict Y and YPRIME.  The length
 
5107
C                  is MAXORD+1 where MAXORD is the maximum order.
 
5108
C     DUMSVR    -- Dummy argument.
 
5109
C     DELTA     -- Work vector for NLS of length NEQ.
 
5110
C     E         -- Error accumulation vector for NLS of length NEQ.
 
5111
C     WM,IWM    -- Real and integer arrays storing
 
5112
C                  matrix information such as the matrix
 
5113
C                  of partial derivatives, permutation
 
5114
C                  vector, and various other information.
 
5115
C     CJ        -- Parameter always proportional to 1/H.
 
5116
C     CJOLD     -- Saves the value of CJ as of the last call to DMATD.
 
5117
C                  Accounts for changes in CJ needed to
 
5118
C                  decide whether to call DMATD.
 
5119
C     CJLAST    -- Previous value of CJ.
 
5120
C     S         -- A scalar determined by the approximate rate
 
5121
C                  of convergence of the Newton iteration and used
 
5122
C                  in the convergence test for the Newton iteration.
 
5123
C
 
5124
C                  If RATE is defined to be an estimate of the
 
5125
C                  rate of convergence of the Newton iteration,
 
5126
C                  then S = RATE/(1.D0-RATE).
 
5127
C
 
5128
C                  The closer RATE is to 0., the faster the Newton
 
5129
C                  iteration is converging; the closer RATE is to 1.,
 
5130
C                  the slower the Newton iteration is converging.
 
5131
C
 
5132
C                  On the first Newton iteration with an up-dated
 
5133
C                  preconditioner S = 100.D0, Thus the initial
 
5134
C                  RATE of convergence is approximately 1.
 
5135
C
 
5136
C                  S is preserved from call to call so that the rate
 
5137
C                  estimate from a previous step can be applied to
 
5138
C                  the current step.
 
5139
C     UROUND    -- Unit roundoff.
 
5140
C     DUME      -- Dummy argument.
 
5141
C     DUMS      -- Dummy argument.
 
5142
C     DUMR      -- Dummy argument.
 
5143
C     EPCON     -- Tolerance to test for convergence of the Newton
 
5144
C                  iteration.
 
5145
C     JCALC     -- Flag used to determine when to update
 
5146
C                  the Jacobian matrix.  In general:
 
5147
C
 
5148
C                  JCALC = -1 ==> Call the DMATD routine to update
 
5149
C                                 the Jacobian matrix.
 
5150
C                  JCALC =  0 ==> Jacobian matrix is up-to-date.
 
5151
C                  JCALC =  1 ==> Jacobian matrix is out-dated,
 
5152
C                                 but DMATD will not be called unless
 
5153
C                                 JCALC is set to -1.
 
5154
C     JFDUM     -- Dummy argument.
 
5155
C     KP1       -- The current order(K) + 1;  updated across calls.
 
5156
C     NONNEG    -- Flag to determine nonnegativity constraints.
 
5157
C     NTYPE     -- Identification code for the NLS routine.
 
5158
C                   0  ==> modified Newton; direct solver.
 
5159
C     IERNLS    -- Error flag for nonlinear solver.
 
5160
C                   0  ==> nonlinear solver converged.
 
5161
C                   1  ==> recoverable error inside nonlinear solver.
 
5162
C                  -1  ==> unrecoverable error inside nonlinear solver.
 
5163
C
 
5164
C     All variables with "DUM" in their names are dummy variables
 
5165
C     which are not used in this routine.
 
5166
C
 
5167
C     Following is a list and description of local variables which
 
5168
C     may not have an obvious usage.  They are listed in roughly the
 
5169
C     order they occur in this subroutine.
 
5170
C
 
5171
C     The following group of variables are passed as arguments to
 
5172
C     the Newton iteration solver.  They are explained in greater detail
 
5173
C     in DNSD:
 
5174
C        TOLNEW, MULDEL, MAXIT, IERNEW
 
5175
C
 
5176
C     IERTYP -- Flag which tells whether this subroutine is correct.
 
5177
C               0 ==> correct subroutine.
 
5178
C               1 ==> incorrect subroutine.
 
5179
 
5180
C-----------------------------------------------------------------------
 
5181
C***ROUTINES CALLED
 
5182
C   DDWNRM, RES, DMATD, DNSD
 
5183
C
 
5184
C***END PROLOGUE  DNEDD
 
5185
C
 
5186
C
 
5187
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
5188
      DIMENSION Y(*),YPRIME(*),WT(*)
 
5189
      DIMENSION DELTA(*),E(*)
 
5190
      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
 
5191
      DIMENSION PHI(NEQ,*),GAMMA(*)
 
5192
      EXTERNAL  RES, JACD
 
5193
C
 
5194
      PARAMETER (LNRE=12, LNJE=13)
 
5195
C
 
5196
      SAVE MULDEL, MAXIT, XRATE
 
5197
      DATA MULDEL/1/, MAXIT/4/, XRATE/0.25D0/
 
5198
C
 
5199
C     Verify that this is the correct subroutine.
 
5200
C
 
5201
      IERTYP = 0
 
5202
      IF (NTYPE .NE. 0) THEN
 
5203
         IERTYP = 1
 
5204
         GO TO 380
 
5205
         ENDIF
 
5206
C
 
5207
C     If this is the first step, perform initializations.
 
5208
C
 
5209
      IF (JSTART .EQ. 0) THEN
 
5210
         CJOLD = CJ
 
5211
         JCALC = -1
 
5212
         ENDIF
 
5213
C
 
5214
C     Perform all other initializations.
 
5215
C
 
5216
      IERNLS = 0
 
5217
C
 
5218
C     Decide whether new Jacobian is needed.
 
5219
C
 
5220
      TEMP1 = (1.0D0 - XRATE)/(1.0D0 + XRATE)
 
5221
      TEMP2 = 1.0D0/TEMP1
 
5222
      IF (CJ/CJOLD .LT. TEMP1 .OR. CJ/CJOLD .GT. TEMP2) JCALC = -1
 
5223
      IF (CJ .NE. CJLAST) S = 100.D0
 
5224
C
 
5225
C-----------------------------------------------------------------------
 
5226
C     Entry point for updating the Jacobian with current
 
5227
C     stepsize.
 
5228
C-----------------------------------------------------------------------
 
5229
300   CONTINUE
 
5230
C
 
5231
C     Initialize all error flags to zero.
 
5232
C
 
5233
      IERJ = 0
 
5234
      IRES = 0
 
5235
      IERNEW = 0
 
5236
C
 
5237
C     Predict the solution and derivative and compute the tolerance
 
5238
C     for the Newton iteration.
 
5239
C
 
5240
      DO 310 I=1,NEQ
 
5241
         Y(I)=PHI(I,1)
 
5242
310      YPRIME(I)=0.0D0
 
5243
      DO 330 J=2,KP1
 
5244
         DO 320 I=1,NEQ
 
5245
            Y(I)=Y(I)+PHI(I,J)
 
5246
320         YPRIME(I)=YPRIME(I)+GAMMA(J)*PHI(I,J)
 
5247
330   CONTINUE
 
5248
      PNORM = DDWNRM (NEQ,Y,WT,RPAR,IPAR)
 
5249
      TOLNEW = 100.D0*UROUND*PNORM
 
5250
C     
 
5251
C     Call RES to initialize DELTA.
 
5252
C
 
5253
      IWM(LNRE)=IWM(LNRE)+1
 
5254
      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
 
5255
      IF (IRES .LT. 0) GO TO 380
 
5256
 
 
5257
C     If indicated, reevaluate the iteration matrix 
 
5258
C     J = dG/dY + CJ*dG/dYPRIME (where G(X,Y,YPRIME)=0).
 
5259
C     Set JCALC to 0 as an indicator that this has been done.
 
5260
C
 
5261
      IF(JCALC .EQ. -1) THEN
 
5262
         IWM(LNJE)=IWM(LNJE)+1
 
5263
         JCALC=0
 
5264
         CALL DMATD(NEQ,X,Y,YPRIME,DELTA,CJ,H,IERJ,WT,E,WM,IWM,
 
5265
     *              RES,IRES,UROUND,JACD,RPAR,IPAR)
 
5266
         CJOLD=CJ
 
5267
         S = 100.D0
 
5268
         IF (IRES .LT. 0) GO TO 380
 
5269
         IF(IERJ .NE. 0)GO TO 380
 
5270
      ENDIF
 
5271
C
 
5272
C     Call the nonlinear Newton solver.
 
5273
C
 
5274
      TEMP1 = 2.0D0/(1.0D0 + CJ/CJOLD)
 
5275
      CALL DNSD(X,Y,YPRIME,NEQ,RES,PDUM,WT,RPAR,IPAR,DUMSVR,
 
5276
     *          DELTA,E,WM,IWM,CJ,DUMS,DUMR,DUME,EPCON,S,TEMP1,
 
5277
     *          TOLNEW,MULDEL,MAXIT,IRES,IDUM,IERNEW)
 
5278
C
 
5279
      IF (IERNEW .GT. 0 .AND. JCALC .NE. 0) THEN
 
5280
C
 
5281
C        The Newton iteration had a recoverable failure with an old
 
5282
C        iteration matrix.  Retry the step with a new iteration matrix.
 
5283
C
 
5284
         JCALC = -1
 
5285
         GO TO 300
 
5286
      ENDIF
 
5287
 
 
5288
      IF (IERNEW .NE. 0) GO TO 380
 
5289
C
 
5290
C     The Newton iteration has converged.  If nonnegativity of
 
5291
C     solution is required, set the solution nonnegative, if the
 
5292
C     perturbation to do it is small enough.  If the change is too
 
5293
C     large, then consider the corrector iteration to have failed.
 
5294
C
 
5295
375   IF(NONNEG .EQ. 0) GO TO 390
 
5296
      DO 377 I = 1,NEQ
 
5297
377      DELTA(I) = MIN(Y(I),0.0D0)
 
5298
      DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
 
5299
      IF(DELNRM .GT. EPCON) GO TO 380
 
5300
      DO 378 I = 1,NEQ
 
5301
378      E(I) = E(I) - DELTA(I)
 
5302
      GO TO 390
 
5303
C
 
5304
C
 
5305
C     Exits from nonlinear solver.
 
5306
C     No convergence with current iteration
 
5307
C     matrix, or singular iteration matrix.
 
5308
C     Compute IERNLS and IDID accordingly.
 
5309
C
 
5310
380   CONTINUE
 
5311
      IF (IRES .LE. -2 .OR. IERTYP .NE. 0) THEN
 
5312
         IERNLS = -1
 
5313
         IF (IRES .LE. -2) IDID = -11
 
5314
         IF (IERTYP .NE. 0) IDID = -15
 
5315
      ELSE
 
5316
         IERNLS = 1
 
5317
         IF (IRES .LT. 0) IDID = -10
 
5318
         IF (IERJ .NE. 0) IDID = -8
 
5319
      ENDIF
 
5320
C
 
5321
390   JCALC = 1
 
5322
      RETURN
 
5323
C
 
5324
C------END OF SUBROUTINE DNEDD------------------------------------------
 
5325
      END
 
5326
      SUBROUTINE DNSD(X,Y,YPRIME,NEQ,RES,PDUM,WT,RPAR,IPAR,
 
5327
     *   DUMSVR,DELTA,E,WM,IWM,CJ,DUMS,DUMR,DUME,EPCON,
 
5328
     *   S,CONFAC,TOLNEW,MULDEL,MAXIT,IRES,IDUM,IERNEW)
 
5329
C
 
5330
C***BEGIN PROLOGUE  DNSD
 
5331
C***REFER TO  DDASPK
 
5332
C***DATE WRITTEN   891219   (YYMMDD)
 
5333
C***REVISION DATE  900926   (YYMMDD)
 
5334
C***REVISION DATE  950126   (YYMMDD)
 
5335
C***REVISION DATE  000711   (YYMMDD)
 
5336
C
 
5337
C
 
5338
C-----------------------------------------------------------------------
 
5339
C***DESCRIPTION
 
5340
C
 
5341
C     DNSD solves a nonlinear system of
 
5342
C     algebraic equations of the form
 
5343
C     G(X,Y,YPRIME) = 0 for the unknown Y.
 
5344
C
 
5345
C     The method used is a modified Newton scheme.
 
5346
C
 
5347
C     The parameters represent
 
5348
C
 
5349
C     X         -- Independent variable.
 
5350
C     Y         -- Solution vector.
 
5351
C     YPRIME    -- Derivative of solution vector.
 
5352
C     NEQ       -- Number of unknowns.
 
5353
C     RES       -- External user-supplied subroutine
 
5354
C                  to evaluate the residual.  See RES description
 
5355
C                  in DDASPK prologue.
 
5356
C     PDUM      -- Dummy argument.
 
5357
C     WT        -- Vector of weights for error criterion.
 
5358
C     RPAR,IPAR -- Real and integer arrays used for communication
 
5359
C                  between the calling program and external user
 
5360
C                  routines.  They are not altered within DASPK.
 
5361
C     DUMSVR    -- Dummy argument.
 
5362
C     DELTA     -- Work vector for DNSD of length NEQ.
 
5363
C     E         -- Error accumulation vector for DNSD of length NEQ.
 
5364
C     WM,IWM    -- Real and integer arrays storing
 
5365
C                  matrix information such as the matrix
 
5366
C                  of partial derivatives, permutation
 
5367
C                  vector, and various other information.
 
5368
C     CJ        -- Parameter always proportional to 1/H (step size).
 
5369
C     DUMS      -- Dummy argument.
 
5370
C     DUMR      -- Dummy argument.
 
5371
C     DUME      -- Dummy argument.
 
5372
C     EPCON     -- Tolerance to test for convergence of the Newton
 
5373
C                  iteration.
 
5374
C     S         -- Used for error convergence tests.
 
5375
C                  In the Newton iteration: S = RATE/(1 - RATE),
 
5376
C                  where RATE is the estimated rate of convergence
 
5377
C                  of the Newton iteration.
 
5378
C                  The calling routine passes the initial value
 
5379
C                  of S to the Newton iteration.
 
5380
C     CONFAC    -- A residual scale factor to improve convergence.
 
5381
C     TOLNEW    -- Tolerance on the norm of Newton correction in
 
5382
C                  alternative Newton convergence test.
 
5383
C     MULDEL    -- A flag indicating whether or not to multiply
 
5384
C                  DELTA by CONFAC.
 
5385
C                  0  ==> do not scale DELTA by CONFAC.
 
5386
C                  1  ==> scale DELTA by CONFAC.
 
5387
C     MAXIT     -- Maximum allowed number of Newton iterations.
 
5388
C     IRES      -- Error flag returned from RES.  See RES description
 
5389
C                  in DDASPK prologue.  If IRES = -1, then IERNEW
 
5390
C                  will be set to 1.
 
5391
C                  If IRES < -1, then IERNEW will be set to -1.
 
5392
C     IDUM      -- Dummy argument.
 
5393
C     IERNEW    -- Error flag for Newton iteration.
 
5394
C                   0  ==> Newton iteration converged.
 
5395
C                   1  ==> recoverable error inside Newton iteration.
 
5396
C                  -1  ==> unrecoverable error inside Newton iteration.
 
5397
C
 
5398
C     All arguments with "DUM" in their names are dummy arguments
 
5399
C     which are not used in this routine.
 
5400
C-----------------------------------------------------------------------
 
5401
C
 
5402
C***ROUTINES CALLED
 
5403
C   DSLVD, DDWNRM, RES
 
5404
C
 
5405
C***END PROLOGUE  DNSD
 
5406
C
 
5407
C
 
5408
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
5409
      DIMENSION Y(*),YPRIME(*),WT(*),DELTA(*),E(*)
 
5410
      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
 
5411
      EXTERNAL  RES
 
5412
C
 
5413
      PARAMETER (LNRE=12, LNNI=19)
 
5414
C
 
5415
C     Initialize Newton counter M and accumulation vector E. 
 
5416
C
 
5417
      M = 0
 
5418
      DO 100 I=1,NEQ
 
5419
100     E(I)=0.0D0
 
5420
C
 
5421
C     Corrector loop.
 
5422
C
 
5423
300   CONTINUE
 
5424
      IWM(LNNI) = IWM(LNNI) + 1
 
5425
C
 
5426
C     If necessary, multiply residual by convergence factor.
 
5427
C
 
5428
      IF (MULDEL .EQ. 1) THEN
 
5429
         DO 320 I = 1,NEQ
 
5430
320        DELTA(I) = DELTA(I) * CONFAC
 
5431
        ENDIF
 
5432
C
 
5433
C     Compute a new iterate (back-substitution).
 
5434
C     Store the correction in DELTA.
 
5435
C
 
5436
        CALL DSLVD(NEQ,DELTA,WM,IWM)
 
5437
 
 
5438
C     Update Y, E, and YPRIME.
 
5439
C
 
5440
      DO 340 I=1,NEQ
 
5441
         Y(I)=Y(I)-DELTA(I)
 
5442
         E(I)=E(I)-DELTA(I)
 
5443
         YPRIME(I)=YPRIME(I)-CJ*DELTA(I)
 
5444
 
 
5445
 340  continue
 
5446
C
 
5447
C     Test for convergence of the iteration.
 
5448
C
 
5449
      DELNRM=DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
 
5450
      IF (M .EQ. 0) THEN
 
5451
        OLDNRM = DELNRM
 
5452
        IF (DELNRM .LE. TOLNEW) GO TO 370
 
5453
      ELSE
 
5454
        RATE = (DELNRM/OLDNRM)**(1.0D0/M)
 
5455
        IF (RATE .GT. 0.9D0) GO TO 380
 
5456
        S = RATE/(1.0D0 - RATE)
 
5457
      ENDIF
 
5458
      IF (S*DELNRM .LE. EPCON) GO TO 370
 
5459
C
 
5460
C     The corrector has not yet converged.
 
5461
C     Update M and test whether the
 
5462
C     maximum number of iterations have
 
5463
C     been tried.
 
5464
C
 
5465
      M=M+1
 
5466
      IF(M.GE.MAXIT) GO TO 380
 
5467
C
 
5468
C     Evaluate the residual,
 
5469
C     and go back to do another iteration.
 
5470
C
 
5471
      IWM(LNRE)=IWM(LNRE)+1
 
5472
      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
 
5473
      IF (IRES .LT. 0) GO TO 380
 
5474
      GO TO 300
 
5475
C
 
5476
C     The iteration has converged.
 
5477
C
 
5478
370   RETURN
 
5479
C
 
5480
C     The iteration has not converged.  Set IERNEW appropriately.
 
5481
C
 
5482
380   CONTINUE
 
5483
      IF (IRES .LE. -2 ) THEN
 
5484
         IERNEW = -1
 
5485
      ELSE
 
5486
         IERNEW = 1
 
5487
      ENDIF
 
5488
      RETURN
 
5489
C
 
5490
C
 
5491
C------END OF SUBROUTINE DNSD-------------------------------------------
 
5492
      END
 
5493
      SUBROUTINE DMATD(NEQ,X,Y,YPRIME,DELTA,CJ,H,IER,EWT,E,
 
5494
     *                 WM,IWM,RES,IRES,UROUND,JACD,RPAR,IPAR)
 
5495
C
 
5496
C***BEGIN PROLOGUE  DMATD
 
5497
C***REFER TO  DDASPK
 
5498
C***DATE WRITTEN   890101   (YYMMDD)
 
5499
C***REVISION DATE  900926   (YYMMDD)
 
5500
C***REVISION DATE  940701   (YYMMDD) (new LIPVT)
 
5501
C
 
5502
C-----------------------------------------------------------------------
 
5503
C***DESCRIPTION
 
5504
C
 
5505
C     This routine computes the iteration matrix
 
5506
C     J = dG/dY+CJ*dG/dYPRIME (where G(X,Y,YPRIME)=0).
 
5507
C     Here J is computed by:
 
5508
C       the user-supplied routine JACD if IWM(MTYPE) is 1 or 4, or
 
5509
C       by numerical difference quotients if IWM(MTYPE) is 2 or 5.
 
5510
C
 
5511
C     The parameters have the following meanings.
 
5512
C     X        = Independent variable.
 
5513
C     Y        = Array containing predicted values.
 
5514
C     YPRIME   = Array containing predicted derivatives.
 
5515
C     DELTA    = Residual evaluated at (X,Y,YPRIME).
 
5516
C                (Used only if IWM(MTYPE)=2 or 5).
 
5517
C     CJ       = Scalar parameter defining iteration matrix.
 
5518
C     H        = Current stepsize in integration.
 
5519
C     IER      = Variable which is .NE. 0 if iteration matrix
 
5520
C                is singular, and 0 otherwise.
 
5521
C     EWT      = Vector of error weights for computing norms.
 
5522
C     E        = Work space (temporary) of length NEQ.
 
5523
C     WM       = Real work space for matrices.  On output
 
5524
C                it contains the LU decomposition
 
5525
C                of the iteration matrix.
 
5526
C     IWM      = Integer work space containing
 
5527
C                matrix information.
 
5528
C     RES      = External user-supplied subroutine
 
5529
C                to evaluate the residual.  See RES description
 
5530
C                in DDASPK prologue.
 
5531
C     IRES     = Flag which is equal to zero if no illegal values
 
5532
C                in RES, and less than zero otherwise.  (If IRES
 
5533
C                is less than zero, the matrix was not completed).
 
5534
C                In this case (if IRES .LT. 0), then IER = 0.
 
5535
C     UROUND   = The unit roundoff error of the machine being used.
 
5536
C     JACD     = Name of the external user-supplied routine
 
5537
C                to evaluate the iteration matrix.  (This routine
 
5538
C                is only used if IWM(MTYPE) is 1 or 4)
 
5539
C                See JAC description for the case INFO(12) = 0
 
5540
C                in DDASPK prologue.
 
5541
C     RPAR,IPAR= Real and integer parameter arrays that
 
5542
C                are used for communication between the
 
5543
C                calling program and external user routines.
 
5544
C                They are not altered by DMATD.
 
5545
C-----------------------------------------------------------------------
 
5546
C***ROUTINES CALLED
 
5547
C   JACD, RES, DGEFA, DGBFA
 
5548
C
 
5549
C***END PROLOGUE  DMATD
 
5550
C
 
5551
C
 
5552
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
5553
      DIMENSION Y(*),YPRIME(*),DELTA(*),EWT(*),E(*)
 
5554
      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
 
5555
      EXTERNAL  RES, JACD
 
5556
C
 
5557
      PARAMETER (LML=1, LMU=2, LMTYPE=4, LNRE=12, LNPD=22, LLCIWP=30)
 
5558
C
 
5559
      LIPVT = IWM(LLCIWP)
 
5560
      IER = 0
 
5561
      MTYPE=IWM(LMTYPE)
 
5562
      GO TO (100,200,300,400,500),MTYPE
 
5563
C
 
5564
C
 
5565
C     Dense user-supplied matrix.
 
5566
C
 
5567
100   LENPD=IWM(LNPD)
 
5568
      DO 110 I=1,LENPD
 
5569
110      WM(I)=0.0D0
 
5570
      CALL JACD(X,Y,YPRIME,WM,CJ,RPAR,IPAR)
 
5571
      GO TO 230
 
5572
C
 
5573
C
 
5574
C     Dense finite-difference-generated matrix.
 
5575
C
 
5576
200   IRES=0
 
5577
      NROW=0
 
5578
      SQUR = SQRT(UROUND)
 
5579
      DO 210 I=1,NEQ
 
5580
         DEL=SQUR*MAX(1.0D0,ABS(Y(I)),ABS(H*YPRIME(I)),
 
5581
     *     ABS(1.D0/EWT(I)))
 
5582
         DEL=SIGN(DEL,H*YPRIME(I))
 
5583
         DEL=(Y(I)+DEL)-Y(I)
 
5584
         YSAVE=Y(I)
 
5585
         YPSAVE=YPRIME(I)
 
5586
         Y(I)=Y(I)+DEL
 
5587
         YPRIME(I)=YPRIME(I)+CJ*DEL  
 
5588
         IWM(LNRE)=IWM(LNRE)+1
 
5589
         CALL RES(X,Y,YPRIME,CJ,E,IRES,RPAR,IPAR)
 
5590
         IF (IRES .LT. 0) RETURN
 
5591
         DELINV=1.0D0/DEL
 
5592
         DO 220 L=1,NEQ  
 
5593
            WM(NROW+L)=(E(L)-DELTA(L))*DELINV
 
5594
 220     CONTINUE     
 
5595
         NROW=NROW+NEQ
 
5596
         Y(I)=YSAVE
 
5597
         YPRIME(I)=YPSAVE
 
5598
 210  CONTINUE
 
5599
C     plhom
 
5600
C     
 
5601
C     Do dense-matrix LU decomposition on J.
 
5602
C     
 
5603
 230  CALL DGEFA(WM,NEQ,NEQ,IWM(LIPVT),IER)
 
5604
      IF (IER .ne. 0)  THEN
 
5605
         write(6,'('' Singular Jacobian at IER ='',i3)')IER
 
5606
      endif
 
5607
      RETURN
 
5608
C     
 
5609
C
 
5610
C     Dummy section for IWM(MTYPE)=3.
 
5611
C
 
5612
300   RETURN
 
5613
C
 
5614
C
 
5615
C     Banded user-supplied matrix.
 
5616
C
 
5617
400   LENPD=IWM(LNPD)
 
5618
      DO 410 I=1,LENPD
 
5619
410      WM(I)=0.0D0
 
5620
      CALL JACD(X,Y,YPRIME,WM,CJ,RPAR,IPAR)
 
5621
      MEBAND=2*IWM(LML)+IWM(LMU)+1
 
5622
      GO TO 550
 
5623
C
 
5624
C
 
5625
C     Banded finite-difference-generated matrix.
 
5626
C
 
5627
500   MBAND=IWM(LML)+IWM(LMU)+1
 
5628
      MBA=MIN0(MBAND,NEQ)
 
5629
      MEBAND=MBAND+IWM(LML)
 
5630
      MEB1=MEBAND-1
 
5631
      MSAVE=(NEQ/MBAND)+1
 
5632
      ISAVE=IWM(LNPD)
 
5633
      IPSAVE=ISAVE+MSAVE
 
5634
      IRES=0
 
5635
      SQUR=SQRT(UROUND)
 
5636
      DO 540 J=1,MBA
 
5637
        DO 510 N=J,NEQ,MBAND
 
5638
          K= (N-J)/MBAND + 1
 
5639
          WM(ISAVE+K)=Y(N)
 
5640
          WM(IPSAVE+K)=YPRIME(N)
 
5641
          DEL=SQUR*MAX(ABS(Y(N)),ABS(H*YPRIME(N)),
 
5642
     *      ABS(1.D0/EWT(N)))
 
5643
          DEL=SIGN(DEL,H*YPRIME(N))
 
5644
          DEL=(Y(N)+DEL)-Y(N)
 
5645
          Y(N)=Y(N)+DEL
 
5646
510       YPRIME(N)=YPRIME(N)+CJ*DEL
 
5647
        IWM(LNRE)=IWM(LNRE)+1
 
5648
        CALL RES(X,Y,YPRIME,CJ,E,IRES,RPAR,IPAR)
 
5649
        IF (IRES .LT. 0) RETURN
 
5650
        DO 530 N=J,NEQ,MBAND
 
5651
          K= (N-J)/MBAND + 1
 
5652
          Y(N)=WM(ISAVE+K)
 
5653
          YPRIME(N)=WM(IPSAVE+K)
 
5654
          DEL=SQUR*MAX(ABS(Y(N)),ABS(H*YPRIME(N)),
 
5655
     *      ABS(1.D0/EWT(N)))
 
5656
          DEL=SIGN(DEL,H*YPRIME(N))
 
5657
          DEL=(Y(N)+DEL)-Y(N)
 
5658
          DELINV=1.0D0/DEL
 
5659
          I1=MAX0(1,(N-IWM(LMU)))
 
5660
          I2=MIN0(NEQ,(N+IWM(LML)))
 
5661
          II=N*MEB1-IWM(LML)
 
5662
          DO 520 I=I1,I2
 
5663
520         WM(II+I)=(E(I)-DELTA(I))*DELINV
 
5664
530     CONTINUE
 
5665
540   CONTINUE
 
5666
C
 
5667
C
 
5668
C     Do LU decomposition of banded J.
 
5669
C
 
5670
550   CALL DGBFA (WM,MEBAND,NEQ,IWM(LML),IWM(LMU),IWM(LIPVT),IER)
 
5671
      RETURN
 
5672
C
 
5673
C------END OF SUBROUTINE DMATD------------------------------------------
 
5674
      END
 
5675
      SUBROUTINE DSLVD(NEQ,DELTA,WM,IWM)
 
5676
C
 
5677
C***BEGIN PROLOGUE  DSLVD
 
5678
C***REFER TO  DDASPK
 
5679
C***DATE WRITTEN   890101   (YYMMDD)
 
5680
C***REVISION DATE  900926   (YYMMDD)
 
5681
C***REVISION DATE  940701   (YYMMDD) (new LIPVT)
 
5682
C
 
5683
C-----------------------------------------------------------------------
 
5684
C***DESCRIPTION
 
5685
C
 
5686
C     This routine manages the solution of the linear
 
5687
C     system arising in the Newton iteration.
 
5688
C     Real matrix information and real temporary storage
 
5689
C     is stored in the array WM.
 
5690
C     Integer matrix information is stored in the array IWM.
 
5691
C     For a dense matrix, the LINPACK routine DGESL is called.
 
5692
C     For a banded matrix, the LINPACK routine DGBSL is called.
 
5693
C-----------------------------------------------------------------------
 
5694
C***ROUTINES CALLED
 
5695
C   DGESL, DGBSL
 
5696
C
 
5697
C***END PROLOGUE  DSLVD
 
5698
C
 
5699
C
 
5700
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
5701
      DIMENSION DELTA(*),WM(*),IWM(*)
 
5702
C
 
5703
      PARAMETER (LML=1, LMU=2, LMTYPE=4, LLCIWP=30)
 
5704
C
 
5705
      LIPVT = IWM(LLCIWP)
 
5706
      MTYPE=IWM(LMTYPE)
 
5707
      GO TO(100,100,300,400,400),MTYPE
 
5708
C
 
5709
C     Dense matrix.
 
5710
 
 
5711
    
 
5712
 
 
5713
c     subroutine dgesl(a,lda,n,ipvt,b,job)
 
5714
c     a*x=b  => b<-x
 
5715
c     (WM*X=DELTA)
 
5716
 100  CALL DGESL(WM,NEQ,NEQ,IWM(LIPVT),DELTA,0)
 
5717
      
 
5718
      RETURN
 
5719
C
 
5720
C     Dummy section for MTYPE=3.
 
5721
C
 
5722
300   CONTINUE
 
5723
      RETURN
 
5724
C
 
5725
C     Banded matrix.
 
5726
C
 
5727
400   MEBAND=2*IWM(LML)+IWM(LMU)+1
 
5728
      CALL DGBSL(WM,MEBAND,NEQ,IWM(LML),
 
5729
     *  IWM(LMU),IWM(LIPVT),DELTA,0)
 
5730
      RETURN
 
5731
C
 
5732
C------END OF SUBROUTINE DSLVD------------------------------------------
 
5733
      END
 
5734
      SUBROUTINE DDASIK(X,Y,YPRIME,NEQ,ICOPT,ID,RES,JACK,PSOL,H,TSCALE,
 
5735
     *   WT,JSKIP,RPAR,IPAR,SAVR,DELTA,R,YIC,YPIC,PWK,WM,IWM,CJ,UROUND,
 
5736
     *   EPLI,SQRTN,RSQRTN,EPCON,RATEMX,STPTOL,JFLG,
 
5737
     *   ICNFLG,ICNSTR,IERNLS)
 
5738
C
 
5739
C***BEGIN PROLOGUE  DDASIK
 
5740
C***REFER TO  DDASPK
 
5741
C***DATE WRITTEN   941026   (YYMMDD)
 
5742
C***REVISION DATE  950808   (YYMMDD)
 
5743
C***REVISION DATE  951110   Removed unreachable block 390.
 
5744
C***REVISION DATE  000628   TSCALE argument added.
 
5745
C
 
5746
C
 
5747
C-----------------------------------------------------------------------
 
5748
C***DESCRIPTION
 
5749
C
 
5750
C
 
5751
C     DDASIK solves a nonlinear system of algebraic equations of the
 
5752
C     form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME in
 
5753
C     the initial conditions.
 
5754
C
 
5755
C     An initial value for Y and initial guess for YPRIME are input.
 
5756
C
 
5757
C     The method used is a Newton scheme with Krylov iteration and a
 
5758
C     linesearch algorithm.
 
5759
C
 
5760
C     The parameters represent
 
5761
C
 
5762
C     X         -- Independent variable.
 
5763
C     Y         -- Solution vector at x.
 
5764
C     YPRIME    -- Derivative of solution vector.
 
5765
C     NEQ       -- Number of equations to be integrated.
 
5766
C     ICOPT     -- Initial condition option chosen (1 or 2).
 
5767
C     ID        -- Array of dimension NEQ, which must be initialized
 
5768
C                  if ICOPT = 1.  See DDASIC.
 
5769
C     RES       -- External user-supplied subroutine
 
5770
C                  to evaluate the residual.  See RES description
 
5771
C                  in DDASPK prologue.
 
5772
C     JACK     --  External user-supplied routine to update
 
5773
C                  the preconditioner.  (This is optional).
 
5774
C                  See JAC description for the case
 
5775
C                  INFO(12) = 1 in the DDASPK prologue.
 
5776
C     PSOL      -- External user-supplied routine to solve
 
5777
C                  a linear system using preconditioning.
 
5778
C                  (This is optional).  See explanation inside DDASPK.
 
5779
C     H         -- Scaling factor for this initial condition calc.
 
5780
C     TSCALE    -- Scale factor in T, used for stopping tests if nonzero.
 
5781
C     WT        -- Vector of weights for error criterion.
 
5782
C     JSKIP     -- input flag to signal if initial JAC call is to be
 
5783
C                  skipped.  1 => skip the call, 0 => do not skip call.
 
5784
C     RPAR,IPAR -- Real and integer arrays used for communication
 
5785
C                  between the calling program and external user
 
5786
C                  routines.  They are not altered within DASPK.
 
5787
C     SAVR      -- Work vector for DDASIK of length NEQ.
 
5788
C     DELTA     -- Work vector for DDASIK of length NEQ.
 
5789
C     R         -- Work vector for DDASIK of length NEQ.
 
5790
C     YIC,YPIC  -- Work vectors for DDASIK, each of length NEQ.
 
5791
C     PWK       -- Work vector for DDASIK of length NEQ.
 
5792
C     WM,IWM    -- Real and integer arrays storing
 
5793
C                  matrix information for linear system
 
5794
C                  solvers, and various other information.
 
5795
C     CJ        -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2).
 
5796
C     UROUND    -- Unit roundoff.  Not used here.
 
5797
C     EPLI      -- convergence test constant.
 
5798
C                  See DDASPK prologue for more details.
 
5799
C     SQRTN     -- Square root of NEQ.
 
5800
C     RSQRTN    -- reciprical of square root of NEQ.
 
5801
C     EPCON     -- Tolerance to test for convergence of the Newton
 
5802
C                  iteration.
 
5803
C     RATEMX    -- Maximum convergence rate for which Newton iteration
 
5804
C                  is considered converging.
 
5805
C     JFLG      -- Flag showing whether a Jacobian routine is supplied.
 
5806
C     ICNFLG    -- Integer scalar.  If nonzero, then constraint
 
5807
C                  violations in the proposed new approximate solution
 
5808
C                  will be checked for, and the maximum step length 
 
5809
C                  will be adjusted accordingly.
 
5810
C     ICNSTR    -- Integer array of length NEQ containing flags for
 
5811
C                  checking constraints.
 
5812
C     IERNLS    -- Error flag for nonlinear solver.
 
5813
C                   0   ==> nonlinear solver converged.
 
5814
C                   1,2 ==> recoverable error inside nonlinear solver.
 
5815
C                           1 => retry with current Y, YPRIME
 
5816
C                           2 => retry with original Y, YPRIME
 
5817
C                  -1   ==> unrecoverable error in nonlinear solver.
 
5818
C
 
5819
C-----------------------------------------------------------------------
 
5820
C
 
5821
C***ROUTINES CALLED
 
5822
C   RES, JACK, DNSIK, DCOPY
 
5823
C
 
5824
C***END PROLOGUE  DDASIK
 
5825
C
 
5826
C
 
5827
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
5828
      DIMENSION Y(*),YPRIME(*),ID(*),WT(*),ICNSTR(*)
 
5829
      DIMENSION SAVR(*),DELTA(*),R(*),YIC(*),YPIC(*),PWK(*)
 
5830
      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
 
5831
      EXTERNAL RES, JACK, PSOL
 
5832
C
 
5833
      PARAMETER (LNRE=12, LNJE=13, LLOCWP=29, LLCIWP=30)
 
5834
      PARAMETER (LMXNIT=32, LMXNJ=33)
 
5835
C
 
5836
C
 
5837
C     Perform initializations.
 
5838
C
 
5839
      LWP = IWM(LLOCWP)
 
5840
      LIWP = IWM(LLCIWP)
 
5841
      MXNIT = IWM(LMXNIT)
 
5842
      MXNJ = IWM(LMXNJ)
 
5843
      IERNLS = 0
 
5844
      NJ = 0
 
5845
      EPLIN = EPLI*EPCON
 
5846
C
 
5847
C     Call RES to initialize DELTA.
 
5848
C
 
5849
      IRES = 0
 
5850
      IWM(LNRE) = IWM(LNRE) + 1
 
5851
      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
 
5852
      IF (IRES .LT. 0) GO TO 370
 
5853
C
 
5854
C     Looping point for updating the preconditioner.
 
5855
C
 
5856
 300  CONTINUE
 
5857
C
 
5858
C     Initialize all error flags to zero.
 
5859
C
 
5860
      IERPJ = 0
 
5861
      IRES = 0
 
5862
      IERNEW = 0
 
5863
C
 
5864
C     If a Jacobian routine was supplied, call it.
 
5865
C
 
5866
      IF (JFLG .EQ. 1 .AND. JSKIP .EQ. 0) THEN
 
5867
        NJ = NJ + 1
 
5868
        IWM(LNJE)=IWM(LNJE)+1
 
5869
        CALL JACK (RES, IRES, NEQ, X, Y, YPRIME, WT, DELTA, R, H, CJ,
 
5870
     *     WM(LWP), IWM(LIWP), IERPJ, RPAR, IPAR)
 
5871
        IF (IRES .LT. 0 .OR. IERPJ .NE. 0) GO TO 370
 
5872
        ENDIF
 
5873
      JSKIP = 0
 
5874
C
 
5875
C     Call the nonlinear Newton solver for up to MXNIT iterations.
 
5876
C
 
5877
      CALL DNSIK(X,Y,YPRIME,NEQ,ICOPT,ID,RES,PSOL,WT,RPAR,IPAR,
 
5878
     *   SAVR,DELTA,R,YIC,YPIC,PWK,WM,IWM,CJ,TSCALE,SQRTN,RSQRTN,
 
5879
     *   EPLIN,EPCON,RATEMX,MXNIT,STPTOL,ICNFLG,ICNSTR,IERNEW)
 
5880
C
 
5881
      IF (IERNEW .EQ. 1 .AND. NJ .LT. MXNJ .AND. JFLG .EQ. 1) THEN
 
5882
C
 
5883
C       Up to MXNIT iterations were done, the convergence rate is < 1,
 
5884
C       a Jacobian routine is supplied, and the number of JACK calls
 
5885
C       is less than MXNJ.  
 
5886
C       Copy the residual SAVR to DELTA, call JACK, and try again.
 
5887
C
 
5888
        CALL DCOPY (NEQ,  SAVR, 1, DELTA, 1)
 
5889
        GO TO 300
 
5890
        ENDIF
 
5891
C
 
5892
      IF (IERNEW .NE. 0) GO TO 380
 
5893
      RETURN
 
5894
C
 
5895
C
 
5896
C     Unsuccessful exits from nonlinear solver.
 
5897
C     Set IERNLS accordingly.
 
5898
C
 
5899
 370  IERNLS = 2
 
5900
      IF (IRES .LE. -2) IERNLS = -1
 
5901
      RETURN
 
5902
C
 
5903
 380  IERNLS = MIN(IERNEW,2)
 
5904
      RETURN
 
5905
C
 
5906
C----------------------- END OF SUBROUTINE DDASIK-----------------------
 
5907
      END
 
5908
      SUBROUTINE DNSIK(X,Y,YPRIME,NEQ,ICOPT,ID,RES,PSOL,WT,RPAR,IPAR,
 
5909
     *   SAVR,DELTA,R,YIC,YPIC,PWK,WM,IWM,CJ,TSCALE,SQRTN,RSQRTN,EPLIN,
 
5910
     *   EPCON,RATEMX,MAXIT,STPTOL,ICNFLG,ICNSTR,IERNEW)
 
5911
C
 
5912
C***BEGIN PROLOGUE  DNSIK
 
5913
C***REFER TO  DDASPK
 
5914
C***DATE WRITTEN   940701   (YYMMDD)
 
5915
C***REVISION DATE  950714   (YYMMDD)
 
5916
C***REVISION DATE  000628   TSCALE argument added.
 
5917
C***REVISION DATE  000628   Added criterion for IERNEW = 1 return.
 
5918
C
 
5919
C
 
5920
C-----------------------------------------------------------------------
 
5921
C***DESCRIPTION
 
5922
C
 
5923
C     DNSIK solves a nonlinear system of algebraic equations of the
 
5924
C     form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME in
 
5925
C     the initial conditions.
 
5926
C
 
5927
C     The method used is a Newton scheme combined with a linesearch
 
5928
C     algorithm, using Krylov iterative linear system methods.
 
5929
C
 
5930
C     The parameters represent
 
5931
C
 
5932
C     X         -- Independent variable.
 
5933
C     Y         -- Solution vector.
 
5934
C     YPRIME    -- Derivative of solution vector.
 
5935
C     NEQ       -- Number of unknowns.
 
5936
C     ICOPT     -- Initial condition option chosen (1 or 2).
 
5937
C     ID        -- Array of dimension NEQ, which must be initialized
 
5938
C                  if ICOPT = 1.  See DDASIC.
 
5939
C     RES       -- External user-supplied subroutine
 
5940
C                  to evaluate the residual.  See RES description
 
5941
C                  in DDASPK prologue.
 
5942
C     PSOL      -- External user-supplied routine to solve
 
5943
C                  a linear system using preconditioning. 
 
5944
C                  See explanation inside DDASPK.
 
5945
C     WT        -- Vector of weights for error criterion.
 
5946
C     RPAR,IPAR -- Real and integer arrays used for communication
 
5947
C                  between the calling program and external user
 
5948
C                  routines.  They are not altered within DASPK.
 
5949
C     SAVR      -- Work vector for DNSIK of length NEQ.
 
5950
C     DELTA     -- Residual vector on entry, and work vector of
 
5951
C                  length NEQ for DNSIK.
 
5952
C     R         -- Work vector for DNSIK of length NEQ.
 
5953
C     YIC,YPIC  -- Work vectors for DNSIK, each of length NEQ.
 
5954
C     PWK       -- Work vector for DNSIK of length NEQ.
 
5955
C     WM,IWM    -- Real and integer arrays storing
 
5956
C                  matrix information such as the matrix
 
5957
C                  of partial derivatives, permutation
 
5958
C                  vector, and various other information.
 
5959
C     CJ        -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2).
 
5960
C     TSCALE    -- Scale factor in T, used for stopping tests if nonzero.
 
5961
C     SQRTN     -- Square root of NEQ.
 
5962
C     RSQRTN    -- reciprical of square root of NEQ.
 
5963
C     EPLIN     -- Tolerance for linear system solver.
 
5964
C     EPCON     -- Tolerance to test for convergence of the Newton
 
5965
C                  iteration.
 
5966
C     RATEMX    -- Maximum convergence rate for which Newton iteration
 
5967
C                  is considered converging.
 
5968
C     MAXIT     -- Maximum allowed number of Newton iterations.
 
5969
C     STPTOL    -- Tolerance used in calculating the minimum lambda
 
5970
C                  value allowed.
 
5971
C     ICNFLG    -- Integer scalar.  If nonzero, then constraint
 
5972
C                  violations in the proposed new approximate solution
 
5973
C                  will be checked for, and the maximum step length
 
5974
C                  will be adjusted accordingly.
 
5975
C     ICNSTR    -- Integer array of length NEQ containing flags for
 
5976
C                  checking constraints.
 
5977
C     IERNEW    -- Error flag for Newton iteration.
 
5978
C                   0  ==> Newton iteration converged.
 
5979
C                   1  ==> failed to converge, but RATE .lt. 1, or the
 
5980
C                          residual norm was reduced by a factor of .1.
 
5981
C                   2  ==> failed to converge, RATE .gt. RATEMX.
 
5982
C                   3  ==> other recoverable error.
 
5983
C                  -1  ==> unrecoverable error inside Newton iteration.
 
5984
C-----------------------------------------------------------------------
 
5985
C
 
5986
C***ROUTINES CALLED
 
5987
C   DFNRMK, DSLVK, DDWNRM, DLINSK, DCOPY
 
5988
C
 
5989
C***END PROLOGUE  DNSIK
 
5990
C
 
5991
C
 
5992
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
5993
      DIMENSION Y(*),YPRIME(*),WT(*),ID(*),DELTA(*),R(*),SAVR(*)
 
5994
      DIMENSION YIC(*),YPIC(*),PWK(*),WM(*),IWM(*), RPAR(*),IPAR(*)
 
5995
      DIMENSION ICNSTR(*)
 
5996
      EXTERNAL RES, PSOL
 
5997
C
 
5998
      PARAMETER (LNNI=19, LNPS=21, LLOCWP=29, LLCIWP=30)
 
5999
      PARAMETER (LLSOFF=35, LSTOL=14)
 
6000
C
 
6001
C
 
6002
C     Initializations.  M is the Newton iteration counter.
 
6003
C
 
6004
      LSOFF = IWM(LLSOFF)
 
6005
      M = 0
 
6006
      RATE = 1.0D0
 
6007
      LWP = IWM(LLOCWP)
 
6008
      LIWP = IWM(LLCIWP)
 
6009
      RLX = 0.4D0
 
6010
C
 
6011
C     Save residual in SAVR.
 
6012
C
 
6013
      CALL DCOPY (NEQ, DELTA, 1, SAVR, 1)
 
6014
C
 
6015
C     Compute norm of (P-inverse)*(residual).
 
6016
C
 
6017
      CALL DFNRMK (NEQ, Y, X, YPRIME, SAVR, R, CJ, TSCALE, WT,
 
6018
     *   SQRTN, RSQRTN, RES, IRES, PSOL, 1, IER, FNRM, EPLIN,
 
6019
     *   WM(LWP), IWM(LIWP), PWK, RPAR, IPAR)
 
6020
      IWM(LNPS) = IWM(LNPS) + 1
 
6021
      IF (IER .NE. 0) THEN
 
6022
        IERNEW = 3
 
6023
        RETURN
 
6024
      ENDIF
 
6025
C
 
6026
C     Return now if residual norm is .le. EPCON.
 
6027
C
 
6028
      IF (FNRM .LE. EPCON) RETURN
 
6029
C
 
6030
C     Newton iteration loop.
 
6031
C
 
6032
      FNRM0 = FNRM
 
6033
300   CONTINUE
 
6034
      IWM(LNNI) = IWM(LNNI) + 1
 
6035
C
 
6036
C     Compute a new step vector DELTA.
 
6037
C
 
6038
      CALL DSLVK (NEQ, Y, X, YPRIME, SAVR, DELTA, WT, WM, IWM,
 
6039
     *   RES, IRES, PSOL, IERSL, CJ, EPLIN, SQRTN, RSQRTN, RHOK,
 
6040
     *   RPAR, IPAR)
 
6041
      IF (IRES .NE. 0 .OR. IERSL .NE. 0) GO TO 390
 
6042
C
 
6043
C     Get norm of DELTA.  Return now if DELTA is zero.
 
6044
C
 
6045
      DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
 
6046
      IF (DELNRM .EQ. 0.0D0) RETURN
 
6047
C
 
6048
C     Call linesearch routine for global strategy and set RATE.
 
6049
C
 
6050
      OLDFNM = FNRM
 
6051
C
 
6052
      CALL DLINSK (NEQ, Y, X, YPRIME, SAVR, CJ, TSCALE, DELTA, DELNRM,
 
6053
     *   WT, SQRTN, RSQRTN, LSOFF, STPTOL, IRET, RES, IRES, PSOL,
 
6054
     *   WM, IWM, RHOK, FNRM, ICOPT, ID, WM(LWP), IWM(LIWP), R, EPLIN,
 
6055
     *   YIC, YPIC, PWK, ICNFLG, ICNSTR, RLX, RPAR, IPAR)
 
6056
C
 
6057
      RATE = FNRM/OLDFNM
 
6058
C
 
6059
C     Check for error condition from linesearch.
 
6060
      IF (IRET .NE. 0) GO TO 390
 
6061
C
 
6062
C     Test for convergence of the iteration, and return or loop.
 
6063
C
 
6064
      IF (FNRM .LE. EPCON) RETURN
 
6065
C
 
6066
C     The iteration has not yet converged.  Update M.
 
6067
C     Test whether the maximum number of iterations have been tried.
 
6068
C
 
6069
      M = M + 1
 
6070
      IF(M .GE. MAXIT) GO TO 380
 
6071
C
 
6072
C     Copy the residual SAVR to DELTA and loop for another iteration.
 
6073
C
 
6074
      CALL DCOPY (NEQ,  SAVR, 1, DELTA, 1)
 
6075
      GO TO 300
 
6076
C
 
6077
C     The maximum number of iterations was done.  Set IERNEW and return.
 
6078
C
 
6079
380   IF (RATE .LE. RATEMX .OR. FNRM .LE. 0.1D0*FNRM0) THEN
 
6080
         IERNEW = 1
 
6081
      ELSE
 
6082
         IERNEW = 2
 
6083
      ENDIF
 
6084
      RETURN
 
6085
C
 
6086
390   IF (IRES .LE. -2 .OR. IERSL .LT. 0) THEN
 
6087
         IERNEW = -1
 
6088
      ELSE
 
6089
         IERNEW = 3
 
6090
         IF (IRES .EQ. 0 .AND. IERSL .EQ. 1 .AND. M .GE. 2 
 
6091
     1       .AND. RATE .LT. 1.0D0) IERNEW = 1
 
6092
      ENDIF
 
6093
      RETURN
 
6094
C
 
6095
C
 
6096
C----------------------- END OF SUBROUTINE DNSIK------------------------
 
6097
      END
 
6098
      SUBROUTINE DLINSK (NEQ, Y, T, YPRIME, SAVR, CJ, TSCALE, P, PNRM,
 
6099
     *   WT, SQRTN, RSQRTN, LSOFF, STPTOL, IRET, RES, IRES, PSOL,
 
6100
     *   WM, IWM, RHOK, FNRM, ICOPT, ID, WP, IWP, R, EPLIN, YNEW, YPNEW,
 
6101
     *   PWK, ICNFLG, ICNSTR, RLX, RPAR, IPAR)
 
6102
C
 
6103
C***BEGIN PROLOGUE  DLINSK
 
6104
C***REFER TO  DNSIK
 
6105
C***DATE WRITTEN   940830   (YYMMDD)
 
6106
C***REVISION DATE  951006   (Arguments SQRTN, RSQRTN added.)
 
6107
C***REVISION DATE  960129   Moved line RL = ONE to top block.
 
6108
C***REVISION DATE  000628   TSCALE argument added.
 
6109
C***REVISION DATE  000628   RHOK*RHOK term removed in alpha test.
 
6110
C
 
6111
C
 
6112
C-----------------------------------------------------------------------
 
6113
C***DESCRIPTION
 
6114
C
 
6115
C     DLINSK uses a linesearch algorithm to calculate a new (Y,YPRIME)
 
6116
C     pair (YNEW,YPNEW) such that 
 
6117
C
 
6118
C     f(YNEW,YPNEW) .le. (1 - 2*ALPHA*RL)*f(Y,YPRIME)
 
6119
C
 
6120
C     where 0 < RL <= 1, and RHOK is the scaled preconditioned norm of
 
6121
C     the final residual vector in the Krylov iteration.  
 
6122
C     Here, f(y,y') is defined as
 
6123
C
 
6124
C      f(y,y') = (1/2)*norm( (P-inverse)*G(t,y,y') )**2 ,
 
6125
C
 
6126
C     where norm() is the weighted RMS vector norm, G is the DAE
 
6127
C     system residual function, and P is the preconditioner used
 
6128
C     in the Krylov iteration.
 
6129
C
 
6130
C     In addition to the parameters defined elsewhere, we have
 
6131
C
 
6132
C     SAVR    -- Work array of length NEQ, containing the residual
 
6133
C                vector G(t,y,y') on return.
 
6134
C     TSCALE  -- Scale factor in T, used for stopping tests if nonzero.
 
6135
C     P       -- Approximate Newton step used in backtracking.
 
6136
C     PNRM    -- Weighted RMS norm of P.
 
6137
C     LSOFF   -- Flag showing whether the linesearch algorithm is
 
6138
C                to be invoked.  0 means do the linesearch, 
 
6139
C                1 means turn off linesearch.
 
6140
C     STPTOL  -- Tolerance used in calculating the minimum lambda
 
6141
C                value allowed.
 
6142
C     ICNFLG  -- Integer scalar.  If nonzero, then constraint violations
 
6143
C                in the proposed new approximate solution will be
 
6144
C                checked for, and the maximum step length will be
 
6145
C                adjusted accordingly.
 
6146
C     ICNSTR  -- Integer array of length NEQ containing flags for
 
6147
C                checking constraints.
 
6148
C     RHOK    -- Weighted norm of preconditioned Krylov residual.
 
6149
C     RLX     -- Real scalar restricting update size in DCNSTR.
 
6150
C     YNEW    -- Array of length NEQ used to hold the new Y in
 
6151
C                performing the linesearch.
 
6152
C     YPNEW   -- Array of length NEQ used to hold the new YPRIME in
 
6153
C                performing the linesearch.
 
6154
C     PWK     -- Work vector of length NEQ for use in PSOL.
 
6155
C     Y       -- Array of length NEQ containing the new Y (i.e.,=YNEW).
 
6156
C     YPRIME  -- Array of length NEQ containing the new YPRIME 
 
6157
C                (i.e.,=YPNEW).
 
6158
C     FNRM    -- Real scalar containing SQRT(2*f(Y,YPRIME)) for the
 
6159
C                current (Y,YPRIME) on input and output.
 
6160
C     R       -- Work space length NEQ for residual vector.
 
6161
C     IRET    -- Return flag.
 
6162
C                IRET=0 means that a satisfactory (Y,YPRIME) was found.
 
6163
C                IRET=1 means that the routine failed to find a new
 
6164
C                       (Y,YPRIME) that was sufficiently distinct from
 
6165
C                       the current (Y,YPRIME) pair.
 
6166
C                IRET=2 means a failure in RES or PSOL.
 
6167
C-----------------------------------------------------------------------
 
6168
C
 
6169
C***ROUTINES CALLED
 
6170
C   DFNRMK, DYYPNW, DCNSTR, DCOPY, XERRWD
 
6171
C
 
6172
C***END PROLOGUE  DLINSK
 
6173
C
 
6174
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
6175
      EXTERNAL  RES, PSOL
 
6176
      DIMENSION Y(*), YPRIME(*), P(*), WT(*), SAVR(*), R(*), ID(*)
 
6177
      DIMENSION WM(*), IWM(*), YNEW(*), YPNEW(*), PWK(*), ICNSTR(*)
 
6178
      DIMENSION WP(*), IWP(*), RPAR(*), IPAR(*)
 
6179
      CHARACTER MSG*80
 
6180
C
 
6181
      PARAMETER (LNRE=12, LNPS=21, LKPRIN=31)
 
6182
C
 
6183
      SAVE ALPHA, ONE, TWO
 
6184
      DATA ALPHA/1.0D-4/, ONE/1.0D0/, TWO/2.0D0/
 
6185
C
 
6186
      KPRIN=IWM(LKPRIN)
 
6187
      F1NRM = (FNRM*FNRM)/TWO
 
6188
      RATIO = ONE
 
6189
C
 
6190
      IF (KPRIN .GE. 2) THEN
 
6191
        MSG = '------ IN ROUTINE DLINSK-- PNRM = (R1)'
 
6192
        CALL XERRWD(MSG, 38, 921, 0, 0, 0, 0, 1, PNRM, 0.0D0)
 
6193
        ENDIF
 
6194
      TAU = PNRM
 
6195
      RL = ONE
 
6196
C-----------------------------------------------------------------------
 
6197
C Check for violations of the constraints, if any are imposed.
 
6198
C If any violations are found, the step vector P is rescaled, and the 
 
6199
C constraint check is repeated, until no violations are found.
 
6200
C-----------------------------------------------------------------------
 
6201
      IF (ICNFLG .NE. 0) THEN
 
6202
 10      CONTINUE
 
6203
         CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW)
 
6204
         CALL DCNSTR (NEQ, Y, YNEW, ICNSTR, TAU, RLX, IRET, IVAR)
 
6205
         IF (IRET .EQ. 1) THEN
 
6206
            RATIO1 = TAU/PNRM
 
6207
            RATIO = RATIO*RATIO1
 
6208
            DO 20 I = 1,NEQ
 
6209
 20           P(I) = P(I)*RATIO1
 
6210
            PNRM = TAU
 
6211
            IF (KPRIN .GE. 2) THEN
 
6212
              MSG = '------ CONSTRAINT VIOL., PNRM = (R1), INDEX = (I1)'
 
6213
              CALL XERRWD (MSG, 50, 922, 0, 1, IVAR, 0, 1, PNRM, 0.0D0)
 
6214
              ENDIF
 
6215
            IF (PNRM .LE. STPTOL) THEN
 
6216
              IRET = 1
 
6217
              RETURN
 
6218
              ENDIF
 
6219
            GO TO 10
 
6220
            ENDIF
 
6221
         ENDIF
 
6222
C
 
6223
      SLPI = -TWO*F1NRM*RATIO
 
6224
      RLMIN = STPTOL/PNRM
 
6225
      IF (LSOFF .EQ. 0 .AND. KPRIN .GE. 2) THEN
 
6226
        MSG = '------ MIN. LAMBDA = (R1)'
 
6227
        CALL XERRWD(MSG, 25, 923, 0, 0, 0, 0, 1, RLMIN, 0.0D0)
 
6228
        ENDIF
 
6229
C-----------------------------------------------------------------------
 
6230
C Begin iteration to find RL value satisfying alpha-condition.
 
6231
C Update YNEW and YPNEW, then compute norm of new scaled residual and
 
6232
C perform alpha condition test.
 
6233
C-----------------------------------------------------------------------
 
6234
 100  CONTINUE
 
6235
      CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW)
 
6236
      CALL DFNRMK (NEQ, YNEW, T, YPNEW, SAVR, R, CJ, TSCALE, WT,
 
6237
     *   SQRTN, RSQRTN, RES, IRES, PSOL, 0, IER, FNRMP, EPLIN,
 
6238
     *   WP, IWP, PWK, RPAR, IPAR)
 
6239
      IWM(LNRE) = IWM(LNRE) + 1
 
6240
      IF (IRES .GE. 0) IWM(LNPS) = IWM(LNPS) + 1
 
6241
      IF (IRES .NE. 0 .OR. IER .NE. 0) THEN
 
6242
        IRET = 2
 
6243
        RETURN
 
6244
        ENDIF
 
6245
      IF (LSOFF .EQ. 1) GO TO 150
 
6246
C
 
6247
      F1NRMP = FNRMP*FNRMP/TWO
 
6248
      IF (KPRIN .GE. 2) THEN
 
6249
        MSG = '------ LAMBDA = (R1)'
 
6250
        CALL XERRWD(MSG, 20, 924, 0, 0, 0, 0, 1, RL, 0.0D0)
 
6251
        MSG = '------ NORM(F1) = (R1),  NORM(F1NEW) = (R2)'
 
6252
        CALL XERRWD(MSG, 43, 925, 0, 0, 0, 0, 2, F1NRM, F1NRMP)
 
6253
        ENDIF
 
6254
      IF (F1NRMP .GT. F1NRM + ALPHA*SLPI*RL) GO TO 200
 
6255
C-----------------------------------------------------------------------
 
6256
C Alpha-condition is satisfied, or linesearch is turned off.
 
6257
C Copy YNEW,YPNEW to Y,YPRIME and return.
 
6258
C-----------------------------------------------------------------------
 
6259
 150  IRET = 0
 
6260
      CALL DCOPY(NEQ, YNEW, 1, Y, 1)
 
6261
      CALL DCOPY(NEQ, YPNEW, 1, YPRIME, 1)
 
6262
      FNRM = FNRMP
 
6263
      IF (KPRIN .GE. 1) THEN
 
6264
        MSG = '------ LEAVING ROUTINE DLINSK, FNRM = (R1)'
 
6265
        CALL XERRWD(MSG, 42, 926, 0, 0, 0, 0, 1, FNRM, 0.0D0)
 
6266
        ENDIF
 
6267
      RETURN
 
6268
C-----------------------------------------------------------------------
 
6269
C Alpha-condition not satisfied.  Perform backtrack to compute new RL
 
6270
C value.  If RL is less than RLMIN, i.e. no satisfactory YNEW,YPNEW can
 
6271
C be found sufficiently distinct from Y,YPRIME, then return IRET = 1.
 
6272
C-----------------------------------------------------------------------
 
6273
 200  CONTINUE
 
6274
      IF (RL .LT. RLMIN) THEN
 
6275
        IRET = 1
 
6276
        RETURN
 
6277
        ENDIF
 
6278
C
 
6279
      RL = RL/TWO
 
6280
      GO TO 100
 
6281
C
 
6282
C----------------------- END OF SUBROUTINE DLINSK ----------------------
 
6283
      END
 
6284
      SUBROUTINE DFNRMK (NEQ, Y, T, YPRIME, SAVR, R, CJ, TSCALE, WT,
 
6285
     *                   SQRTN, RSQRTN, RES, IRES, PSOL, IRIN, IER,
 
6286
     *                   FNORM, EPLIN, WP, IWP, PWK, RPAR, IPAR)
 
6287
C
 
6288
C***BEGIN PROLOGUE  DFNRMK
 
6289
C***REFER TO  DLINSK
 
6290
C***DATE WRITTEN   940830   (YYMMDD)
 
6291
C***REVISION DATE  951006   (SQRTN, RSQRTN, and scaling of WT added.)
 
6292
C***REVISION DATE  000628   TSCALE argument added.
 
6293
C
 
6294
C
 
6295
C-----------------------------------------------------------------------
 
6296
C***DESCRIPTION
 
6297
C
 
6298
C     DFNRMK calculates the scaled preconditioned norm of the nonlinear
 
6299
C     function used in the nonlinear iteration for obtaining consistent
 
6300
C     initial conditions.  Specifically, DFNRMK calculates the weighted
 
6301
C     root-mean-square norm of the vector (P-inverse)*G(T,Y,YPRIME),
 
6302
C     where P is the preconditioner matrix.
 
6303
C
 
6304
C     In addition to the parameters described in the calling program
 
6305
C     DLINSK, the parameters represent
 
6306
C
 
6307
C     TSCALE -- Scale factor in T, used for stopping tests if nonzero.
 
6308
C     IRIN   -- Flag showing whether the current residual vector is
 
6309
C               input in SAVR.  1 means it is, 0 means it is not.
 
6310
C     R      -- Array of length NEQ that contains
 
6311
C               (P-inverse)*G(T,Y,YPRIME) on return.
 
6312
C     FNORM  -- Scalar containing the weighted norm of R on return.
 
6313
C-----------------------------------------------------------------------
 
6314
C
 
6315
C***ROUTINES CALLED
 
6316
C   RES, DCOPY, DSCAL, PSOL, DDWNRM
 
6317
C
 
6318
C***END PROLOGUE  DFNRMK
 
6319
C
 
6320
C
 
6321
      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
 
6322
      EXTERNAL RES, PSOL
 
6323
      DIMENSION Y(*), YPRIME(*), WT(*), SAVR(*), R(*), PWK(*)
 
6324
      DIMENSION WP(*), IWP(*), RPAR(*), IPAR(*)
 
6325
C-----------------------------------------------------------------------
 
6326
C     Call RES routine if IRIN = 0.
 
6327
C-----------------------------------------------------------------------
 
6328
      IF (IRIN .EQ. 0) THEN
 
6329
        IRES = 0
 
6330
        CALL RES (T, Y, YPRIME, CJ, SAVR, IRES, RPAR, IPAR)
 
6331
        IF (IRES .LT. 0) RETURN
 
6332
        ENDIF
 
6333
C-----------------------------------------------------------------------
 
6334
C     Apply inverse of left preconditioner to vector R.
 
6335
C     First scale WT array by 1/sqrt(N), and undo scaling afterward.
 
6336
C-----------------------------------------------------------------------
 
6337
      CALL DCOPY(NEQ, SAVR, 1, R, 1)
 
6338
      CALL DSCAL (NEQ, RSQRTN, WT, 1)
 
6339
      IER = 0
 
6340
      CALL PSOL (NEQ, T, Y, YPRIME, SAVR, PWK, CJ, WT, WP, IWP,
 
6341
     *           R, EPLIN, IER, RPAR, IPAR)
 
6342
      CALL DSCAL (NEQ, SQRTN, WT, 1)
 
6343
      IF (IER .NE. 0) RETURN
 
6344
C-----------------------------------------------------------------------
 
6345
C     Calculate norm of R.
 
6346
C-----------------------------------------------------------------------
 
6347
      FNORM = DDWNRM (NEQ, R, WT, RPAR, IPAR)
 
6348
      IF (TSCALE .GT. 0.0D0) FNORM = FNORM*TSCALE*ABS(CJ)
 
6349
C
 
6350
      RETURN
 
6351
C----------------------- END OF SUBROUTINE DFNRMK ----------------------
 
6352
      END
 
6353
      SUBROUTINE DNEDK(X,Y,YPRIME,NEQ,RES,JACK,PSOL,
 
6354
     *   H,WT,JSTART,IDID,RPAR,IPAR,PHI,GAMMA,SAVR,DELTA,E,
 
6355
     *   WM,IWM,CJ,CJOLD,CJLAST,S,UROUND,EPLI,SQRTN,RSQRTN,
 
6356
     *   EPCON,JCALC,JFLG,KP1,NONNEG,NTYPE,IERNLS)
 
6357
C
 
6358
C***BEGIN PROLOGUE  DNEDK
 
6359
C***REFER TO  DDASPK
 
6360
C***DATE WRITTEN   891219   (YYMMDD)
 
6361
C***REVISION DATE  900926   (YYMMDD)
 
6362
C***REVISION DATE  940701   (YYMMDD)
 
6363
C
 
6364
C
 
6365
C-----------------------------------------------------------------------
 
6366
C***DESCRIPTION
 
6367
C
 
6368
C     DNEDK solves a nonlinear system of
 
6369
C     algebraic equations of the form
 
6370
C     G(X,Y,YPRIME) = 0 for the unknown Y.
 
6371
C
 
6372
C     The method used is a matrix-free Newton scheme.
 
6373
C
 
6374
C     The parameters represent
 
6375
C     X         -- Independent variable.
 
6376
C     Y         -- Solution vector at x.
 
6377
C     YPRIME    -- Derivative of solution vector
 
6378
C                  after successful step.
 
6379
C     NEQ       -- Number of equations to be integrated.
 
6380
C     RES       -- External user-supplied subroutine
 
6381
C                  to evaluate the residual.  See RES description
 
6382
C                  in DDASPK prologue.
 
6383
C     JACK     --  External user-supplied routine to update
 
6384
C                  the preconditioner.  (This is optional).
 
6385
C                  See JAC description for the case
 
6386
C                  INFO(12) = 1 in the DDASPK prologue.
 
6387
C     PSOL      -- External user-supplied routine to solve
 
6388
C                  a linear system using preconditioning. 
 
6389
C                  (This is optional).  See explanation inside DDASPK.
 
6390
C     H         -- Appropriate step size for this step.
 
6391
C     WT        -- Vector of weights for error criterion.
 
6392
C     JSTART    -- Indicates first call to this routine.
 
6393
C                  If JSTART = 0, then this is the first call,
 
6394
C                  otherwise it is not.
 
6395
C     IDID      -- Completion flag, output by DNEDK.
 
6396
C                  See IDID description in DDASPK prologue.
 
6397
C     RPAR,IPAR -- Real and integer arrays used for communication
 
6398
C                  between the calling program and external user
 
6399
C                  routines.  They are not altered within DASPK.
 
6400
C     PHI       -- Array of divided differences used by
 
6401
C                  DNEDK.  The length is NEQ*(K+1), where
 
6402
C                  K is the maximum order.
 
6403
C     GAMMA     -- Array used to predict Y and YPRIME.  The length
 
6404
C                  is K+1, where K is the maximum order.
 
6405
C     SAVR      -- Work vector for DNEDK of length NEQ.
 
6406
C     DELTA     -- Work vector for DNEDK of length NEQ.
 
6407
C     E         -- Error accumulation vector for DNEDK of length NEQ.
 
6408
C     WM,IWM    -- Real and integer arrays storing
 
6409
C                  matrix information for linear system
 
6410
C                  solvers, and various other information.
 
6411
C     CJ        -- Parameter always proportional to 1/H.
 
6412
C     CJOLD     -- Saves the value of CJ as of the last call to DITMD.
 
6413
C                  Accounts for changes in CJ needed to
 
6414
C                  decide whether to call DITMD.
 
6415
C     CJLAST    -- Previous value of CJ.
 
6416
C     S         -- A scalar determined by the approximate rate
 
6417
C                  of convergence of the Newton iteration and used
 
6418
C                  in the convergence test for the Newton iteration.
 
6419
C
 
6420
C                  If RATE is defined to be an estimate of the
 
6421
C                  rate of convergence of the Newton iteration,
 
6422
C                  then S = RATE/(1.D0-RATE).
 
6423
C
 
6424
C                  The closer RATE is to 0., the faster the Newton
 
6425
C                  iteration is converging; the closer RATE is to 1.,
 
6426
C                  the slower the Newton iteration is converging.
 
6427
C
 
6428
C                  On the first Newton iteration with an up-dated
 
6429
C                  preconditioner S = 100.D0, Thus the initial
 
6430
C                  RATE of convergence is approximately 1.
 
6431
C
 
6432
C                  S is preserved from call to call so that the rate
 
6433
C                  estimate from a previous step can be applied to
 
6434
C                  the current step.
 
6435
C     UROUND    -- Unit roundoff.  Not used here.
 
6436
C     EPLI      -- convergence test constant.
 
6437
C                  See DDASPK prologue for more details.
 
6438
C     SQRTN     -- Square root of NEQ.
 
6439
C     RSQRTN    -- reciprical of square root of NEQ.
 
6440
C     EPCON     -- Tolerance to test for convergence of the Newton
 
6441
C                  iteration.
 
6442
C     JCALC     -- Flag used to determine when to update
 
6443
C                  the Jacobian matrix.  In general:
 
6444
C
 
6445
C                  JCALC = -1 ==> Call the DITMD routine to update
 
6446
C                                 the Jacobian matrix.
 
6447
C                  JCALC =  0 ==> Jacobian matrix is up-to-date.
 
6448
C                  JCALC =  1 ==> Jacobian matrix is out-dated,
 
6449
C                                 but DITMD will not be called unless
 
6450
C                                 JCALC is set to -1.
 
6451
C     JFLG      -- Flag showing whether a Jacobian routine is supplied.
 
6452
C     KP1       -- The current order + 1;  updated across calls.
 
6453
C     NONNEG    -- Flag to determine nonnegativity constraints.
 
6454
C     NTYPE     -- Identification code for the DNEDK routine.
 
6455
C                   1 ==> modified Newton; iterative linear solver.
 
6456
C                   2 ==> modified Newton; user-supplied linear solver.
 
6457
C     IERNLS    -- Error flag for nonlinear solver.
 
6458
C                   0 ==> nonlinear solver converged.
 
6459
C                   1 ==> recoverable error inside non-linear solver.
 
6460
C                  -1 ==> unrecoverable error inside non-linear solver.
 
6461
C
 
6462
C     The following group of variables are passed as arguments to
 
6463
C     the Newton iteration solver.  They are explained in greater detail
 
6464
C     in DNSK:
 
6465
C        TOLNEW, MULDEL, MAXIT, IERNEW
 
6466
C
 
6467
C     IERTYP -- Flag which tells whether this subroutine is correct.
 
6468
C               0 ==> correct subroutine.
 
6469
C               1 ==> incorrect subroutine.
 
6470
C
 
6471
C-----------------------------------------------------------------------
 
6472
C***ROUTINES CALLED
 
6473
C   RES, JACK, DDWNRM, DNSK
 
6474
C
 
6475
C***END PROLOGUE  DNEDK
 
6476
C
 
6477
C
 
6478
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
6479
      DIMENSION Y(*),YPRIME(*),WT(*)
 
6480
      DIMENSION PHI(NEQ,*),SAVR(*),DELTA(*),E(*)
 
6481
      DIMENSION WM(*),IWM(*)
 
6482
      DIMENSION GAMMA(*),RPAR(*),IPAR(*)
 
6483
      EXTERNAL  RES, JACK, PSOL
 
6484
C
 
6485
      PARAMETER (LNRE=12, LNJE=13, LLOCWP=29, LLCIWP=30)
 
6486
C
 
6487
      SAVE MULDEL, MAXIT, XRATE
 
6488
      DATA MULDEL/0/, MAXIT/4/, XRATE/0.25D0/
 
6489
C
 
6490
C     Verify that this is the correct subroutine.
 
6491
C
 
6492
      IERTYP = 0
 
6493
      IF (NTYPE .NE. 1) THEN
 
6494
         IERTYP = 1
 
6495
         GO TO 380
 
6496
         ENDIF
 
6497
C
 
6498
C     If this is the first step, perform initializations.
 
6499
C
 
6500
      IF (JSTART .EQ. 0) THEN
 
6501
         CJOLD = CJ
 
6502
         JCALC = -1
 
6503
         S = 100.D0
 
6504
         ENDIF
 
6505
C
 
6506
C     Perform all other initializations.
 
6507
C
 
6508
      IERNLS = 0
 
6509
      LWP = IWM(LLOCWP)
 
6510
      LIWP = IWM(LLCIWP)
 
6511
C
 
6512
C     Decide whether to update the preconditioner.
 
6513
C
 
6514
      IF (JFLG .NE. 0) THEN
 
6515
         TEMP1 = (1.0D0 - XRATE)/(1.0D0 + XRATE)
 
6516
         TEMP2 = 1.0D0/TEMP1
 
6517
         IF (CJ/CJOLD .LT. TEMP1 .OR. CJ/CJOLD .GT. TEMP2) JCALC = -1
 
6518
         IF (CJ .NE. CJLAST) S = 100.D0
 
6519
      ELSE
 
6520
         JCALC = 0
 
6521
         ENDIF
 
6522
C
 
6523
C     Looping point for updating preconditioner with current stepsize.
 
6524
C
 
6525
300   CONTINUE
 
6526
C
 
6527
C     Initialize all error flags to zero.
 
6528
C
 
6529
      IERPJ = 0
 
6530
      IRES = 0
 
6531
      IERSL = 0
 
6532
      IERNEW = 0
 
6533
C
 
6534
C     Predict the solution and derivative and compute the tolerance
 
6535
C     for the Newton iteration.
 
6536
C
 
6537
      DO 310 I=1,NEQ
 
6538
         Y(I)=PHI(I,1)
 
6539
310      YPRIME(I)=0.0D0
 
6540
      DO 330 J=2,KP1
 
6541
         DO 320 I=1,NEQ
 
6542
            Y(I)=Y(I)+PHI(I,J)
 
6543
320         YPRIME(I)=YPRIME(I)+GAMMA(J)*PHI(I,J)
 
6544
330   CONTINUE
 
6545
      EPLIN = EPLI*EPCON
 
6546
      TOLNEW = EPLIN
 
6547
C
 
6548
C     Call RES to initialize DELTA.
 
6549
C
 
6550
      IWM(LNRE)=IWM(LNRE)+1
 
6551
      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
 
6552
      IF (IRES .LT. 0) GO TO 380
 
6553
C
 
6554
C
 
6555
C     If indicated, update the preconditioner.
 
6556
C     Set JCALC to 0 as an indicator that this has been done.
 
6557
C
 
6558
      IF(JCALC .EQ. -1)THEN
 
6559
         IWM(LNJE) = IWM(LNJE) + 1
 
6560
         JCALC=0
 
6561
         CALL JACK (RES, IRES, NEQ, X, Y, YPRIME, WT, DELTA, E, H, CJ,
 
6562
     *      WM(LWP), IWM(LIWP), IERPJ, RPAR, IPAR)
 
6563
         CJOLD=CJ
 
6564
         S = 100.D0
 
6565
         IF (IRES .LT. 0)  GO TO 380
 
6566
         IF (IERPJ .NE. 0) GO TO 380
 
6567
      ENDIF
 
6568
C
 
6569
C     Call the nonlinear Newton solver.
 
6570
C
 
6571
      CALL DNSK(X,Y,YPRIME,NEQ,RES,PSOL,WT,RPAR,IPAR,SAVR,
 
6572
     *   DELTA,E,WM,IWM,CJ,SQRTN,RSQRTN,EPLIN,EPCON,
 
6573
     *   S,TEMP1,TOLNEW,MULDEL,MAXIT,IRES,IERSL,IERNEW)
 
6574
C
 
6575
      IF (IERNEW .GT. 0 .AND. JCALC .NE. 0) THEN
 
6576
C
 
6577
C     The Newton iteration had a recoverable failure with an old
 
6578
C     preconditioner.  Retry the step with a new preconditioner.
 
6579
C
 
6580
         JCALC = -1
 
6581
         GO TO 300
 
6582
      ENDIF
 
6583
C
 
6584
      IF (IERNEW .NE. 0) GO TO 380
 
6585
C
 
6586
C     The Newton iteration has converged.  If nonnegativity of
 
6587
C     solution is required, set the solution nonnegative, if the
 
6588
C     perturbation to do it is small enough.  If the change is too
 
6589
C     large, then consider the corrector iteration to have failed.
 
6590
C
 
6591
      IF(NONNEG .EQ. 0) GO TO 390
 
6592
      DO 360 I = 1,NEQ
 
6593
 360    DELTA(I) = MIN(Y(I),0.0D0)
 
6594
      DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
 
6595
      IF(DELNRM .GT. EPCON) GO TO 380
 
6596
      DO 370 I = 1,NEQ
 
6597
 370    E(I) = E(I) - DELTA(I)
 
6598
      GO TO 390
 
6599
C
 
6600
C
 
6601
C     Exits from nonlinear solver.
 
6602
C     No convergence with current preconditioner.
 
6603
C     Compute IERNLS and IDID accordingly.
 
6604
C
 
6605
380   CONTINUE
 
6606
      IF (IRES .LE. -2 .OR. IERSL .LT. 0 .OR. IERTYP .NE. 0) THEN
 
6607
         IERNLS = -1
 
6608
         IF (IRES .LE. -2) IDID = -11
 
6609
         IF (IERSL .LT. 0) IDID = -13
 
6610
         IF (IERTYP .NE. 0) IDID = -15
 
6611
      ELSE
 
6612
         IERNLS =  1
 
6613
         IF (IRES .EQ. -1) IDID = -10
 
6614
         IF (IERPJ .NE. 0) IDID = -5
 
6615
         IF (IERSL .GT. 0) IDID = -14
 
6616
      ENDIF
 
6617
C
 
6618
C
 
6619
390   JCALC = 1
 
6620
      RETURN
 
6621
C
 
6622
C------END OF SUBROUTINE DNEDK------------------------------------------
 
6623
      END
 
6624
      SUBROUTINE DNSK(X,Y,YPRIME,NEQ,RES,PSOL,WT,RPAR,IPAR,
 
6625
     *   SAVR,DELTA,E,WM,IWM,CJ,SQRTN,RSQRTN,EPLIN,EPCON,
 
6626
     *   S,CONFAC,TOLNEW,MULDEL,MAXIT,IRES,IERSL,IERNEW)
 
6627
C
 
6628
C***BEGIN PROLOGUE  DNSK
 
6629
C***REFER TO  DDASPK
 
6630
C***DATE WRITTEN   891219   (YYMMDD)
 
6631
C***REVISION DATE  900926   (YYMMDD)
 
6632
C***REVISION DATE  950126   (YYMMDD)
 
6633
C***REVISION DATE  000711   (YYMMDD)
 
6634
C
 
6635
C
 
6636
C-----------------------------------------------------------------------
 
6637
C***DESCRIPTION
 
6638
C
 
6639
C     DNSK solves a nonlinear system of
 
6640
C     algebraic equations of the form
 
6641
C     G(X,Y,YPRIME) = 0 for the unknown Y.
 
6642
C
 
6643
C     The method used is a modified Newton scheme.
 
6644
C
 
6645
C     The parameters represent
 
6646
C
 
6647
C     X         -- Independent variable.
 
6648
C     Y         -- Solution vector.
 
6649
C     YPRIME    -- Derivative of solution vector.
 
6650
C     NEQ       -- Number of unknowns.
 
6651
C     RES       -- External user-supplied subroutine
 
6652
C                  to evaluate the residual.  See RES description
 
6653
C                  in DDASPK prologue.
 
6654
C     PSOL      -- External user-supplied routine to solve
 
6655
C                  a linear system using preconditioning. 
 
6656
C                  See explanation inside DDASPK.
 
6657
C     WT        -- Vector of weights for error criterion.
 
6658
C     RPAR,IPAR -- Real and integer arrays used for communication
 
6659
C                  between the calling program and external user
 
6660
C                  routines.  They are not altered within DASPK.
 
6661
C     SAVR      -- Work vector for DNSK of length NEQ.
 
6662
C     DELTA     -- Work vector for DNSK of length NEQ.
 
6663
C     E         -- Error accumulation vector for DNSK of length NEQ.
 
6664
C     WM,IWM    -- Real and integer arrays storing
 
6665
C                  matrix information such as the matrix
 
6666
C                  of partial derivatives, permutation
 
6667
C                  vector, and various other information.
 
6668
C     CJ        -- Parameter always proportional to 1/H (step size).
 
6669
C     SQRTN     -- Square root of NEQ.
 
6670
C     RSQRTN    -- reciprical of square root of NEQ.
 
6671
C     EPLIN     -- Tolerance for linear system solver.
 
6672
C     EPCON     -- Tolerance to test for convergence of the Newton
 
6673
C                  iteration.
 
6674
C     S         -- Used for error convergence tests.
 
6675
C                  In the Newton iteration: S = RATE/(1.D0-RATE),
 
6676
C                  where RATE is the estimated rate of convergence
 
6677
C                  of the Newton iteration.
 
6678
C
 
6679
C                  The closer RATE is to 0., the faster the Newton
 
6680
C                  iteration is converging; the closer RATE is to 1.,
 
6681
C                  the slower the Newton iteration is converging.
 
6682
C
 
6683
C                  The calling routine sends the initial value
 
6684
C                  of S to the Newton iteration.
 
6685
C     CONFAC    -- A residual scale factor to improve convergence.
 
6686
C     TOLNEW    -- Tolerance on the norm of Newton correction in
 
6687
C                  alternative Newton convergence test.
 
6688
C     MULDEL    -- A flag indicating whether or not to multiply
 
6689
C                  DELTA by CONFAC.
 
6690
C                  0  ==> do not scale DELTA by CONFAC.
 
6691
C                  1  ==> scale DELTA by CONFAC.
 
6692
C     MAXIT     -- Maximum allowed number of Newton iterations.
 
6693
C     IRES      -- Error flag returned from RES.  See RES description
 
6694
C                  in DDASPK prologue.  If IRES = -1, then IERNEW
 
6695
C                  will be set to 1.
 
6696
C                  If IRES < -1, then IERNEW will be set to -1.
 
6697
C     IERSL     -- Error flag for linear system solver.
 
6698
C                  See IERSL description in subroutine DSLVK.
 
6699
C                  If IERSL = 1, then IERNEW will be set to 1.
 
6700
C                  If IERSL < 0, then IERNEW will be set to -1.
 
6701
C     IERNEW    -- Error flag for Newton iteration.
 
6702
C                   0  ==> Newton iteration converged.
 
6703
C                   1  ==> recoverable error inside Newton iteration.
 
6704
C                  -1  ==> unrecoverable error inside Newton iteration.
 
6705
C-----------------------------------------------------------------------
 
6706
C
 
6707
C***ROUTINES CALLED
 
6708
C   RES, DSLVK, DDWNRM
 
6709
C
 
6710
C***END PROLOGUE  DNSK
 
6711
C
 
6712
C
 
6713
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
 
6714
      DIMENSION Y(*),YPRIME(*),WT(*),DELTA(*),E(*),SAVR(*)
 
6715
      DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*)
 
6716
      EXTERNAL  RES, PSOL
 
6717
C
 
6718
      PARAMETER (LNNI=19, LNRE=12)
 
6719
C
 
6720
C     Initialize Newton counter M and accumulation vector E.
 
6721
C
 
6722
      M = 0
 
6723
      DO 100 I=1,NEQ
 
6724
100     E(I) = 0.0D0
 
6725
C
 
6726
C     Corrector loop.
 
6727
C
 
6728
300   CONTINUE
 
6729
      IWM(LNNI) = IWM(LNNI) + 1
 
6730
C
 
6731
C     If necessary, multiply residual by convergence factor.
 
6732
C
 
6733
      IF (MULDEL .EQ. 1) THEN
 
6734
        DO 320 I = 1,NEQ
 
6735
320       DELTA(I) = DELTA(I) * CONFAC
 
6736
        ENDIF
 
6737
C
 
6738
C     Save residual in SAVR.
 
6739
C
 
6740
      DO 340 I = 1,NEQ
 
6741
340     SAVR(I) = DELTA(I)
 
6742
C
 
6743
C     Compute a new iterate.  Store the correction in DELTA.
 
6744
C
 
6745
      CALL DSLVK (NEQ, Y, X, YPRIME, SAVR, DELTA, WT, WM, IWM,
 
6746
     *   RES, IRES, PSOL, IERSL, CJ, EPLIN, SQRTN, RSQRTN, RHOK,
 
6747
     *   RPAR, IPAR)
 
6748
      IF (IRES .NE. 0 .OR. IERSL .NE. 0) GO TO 380
 
6749
C
 
6750
C     Update Y, E, and YPRIME.
 
6751
C
 
6752
      DO 360 I=1,NEQ
 
6753
         Y(I) = Y(I) - DELTA(I)
 
6754
         E(I) = E(I) - DELTA(I)
 
6755
360      YPRIME(I) = YPRIME(I) - CJ*DELTA(I)
 
6756
C
 
6757
C     Test for convergence of the iteration.
 
6758
C
 
6759
      DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR)
 
6760
      IF (M .EQ. 0) THEN
 
6761
        OLDNRM = DELNRM
 
6762
        IF (DELNRM .LE. TOLNEW) GO TO 370
 
6763
      ELSE
 
6764
        RATE = (DELNRM/OLDNRM)**(1.0D0/M)
 
6765
        IF (RATE .GT. 0.9D0) GO TO 380
 
6766
        S = RATE/(1.0D0 - RATE)
 
6767
      ENDIF
 
6768
      IF (S*DELNRM .LE. EPCON) GO TO 370
 
6769
C
 
6770
C     The corrector has not yet converged.  Update M and test whether
 
6771
C     the maximum number of iterations have been tried.
 
6772
C
 
6773
      M = M + 1
 
6774
      IF (M .GE. MAXIT) GO TO 380
 
6775
C
 
6776
C     Evaluate the residual, and go back to do another iteration.
 
6777
C
 
6778
      IWM(LNRE) = IWM(LNRE) + 1
 
6779
      CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR)
 
6780
      IF (IRES .LT. 0) GO TO 380
 
6781
      GO TO 300
 
6782
C
 
6783
C     The iteration has converged.
 
6784
C
 
6785
370    RETURN
 
6786
C
 
6787
C     The iteration has not converged.  Set IERNEW appropriately.
 
6788
C
 
6789
380   CONTINUE
 
6790
      IF (IRES .LE. -2 .OR. IERSL .LT. 0) THEN
 
6791
         IERNEW = -1
 
6792
      ELSE
 
6793
         IERNEW = 1
 
6794
      ENDIF
 
6795
      RETURN
 
6796
C
 
6797
C
 
6798
C------END OF SUBROUTINE DNSK-------------------------------------------
 
6799
      END
 
6800
      SUBROUTINE DSLVK (NEQ, Y, TN, YPRIME, SAVR, X, EWT, WM, IWM,
 
6801
     *   RES, IRES, PSOL, IERSL, CJ, EPLIN, SQRTN, RSQRTN, RHOK,
 
6802
     *   RPAR, IPAR)
 
6803
C
 
6804
C***BEGIN PROLOGUE  DSLVK
 
6805
C***REFER TO  DDASPK
 
6806
C***DATE WRITTEN   890101   (YYMMDD)
 
6807
C***REVISION DATE  900926   (YYMMDD)
 
6808
C***REVISION DATE  940928   Removed MNEWT and added RHOK in call list.
 
6809
C
 
6810
C
 
6811
C-----------------------------------------------------------------------
 
6812
C***DESCRIPTION
 
6813
C
 
6814
C DSLVK uses a restart algorithm and interfaces to DSPIGM for
 
6815
C the solution of the linear system arising from a Newton iteration.
 
6816
C
 
6817
C In addition to variables described elsewhere,
 
6818
C communication with DSLVK uses the following variables..
 
6819
C WM    = Real work space containing data for the algorithm
 
6820
C         (Krylov basis vectors, Hessenberg matrix, etc.).
 
6821
C IWM   = Integer work space containing data for the algorithm.
 
6822
C X     = The right-hand side vector on input, and the solution vector
 
6823
C         on output, of length NEQ.
 
6824
C IRES  = Error flag from RES.
 
6825
C IERSL = Output flag ..
 
6826
C         IERSL =  0 means no trouble occurred (or user RES routine
 
6827
C                    returned IRES < 0)
 
6828
C         IERSL =  1 means the iterative method failed to converge
 
6829
C                    (DSPIGM returned IFLAG > 0.)
 
6830
C         IERSL = -1 means there was a nonrecoverable error in the
 
6831
C                    iterative solver, and an error exit will occur.
 
6832
C-----------------------------------------------------------------------
 
6833
C***ROUTINES CALLED
 
6834
C   DSCAL, DCOPY, DSPIGM
 
6835
C
 
6836
C***END PROLOGUE  DSLVK
 
6837
C
 
6838
      INTEGER NEQ, IWM, IRES, IERSL, IPAR
 
6839
      DOUBLE PRECISION Y, TN, YPRIME, SAVR, X, EWT, WM, CJ, EPLIN,
 
6840
     1   SQRTN, RSQRTN, RHOK, RPAR
 
6841
      DIMENSION Y(*), YPRIME(*), SAVR(*), X(*), EWT(*), 
 
6842
     1  WM(*), IWM(*), RPAR(*), IPAR(*)
 
6843
C
 
6844
      INTEGER IFLAG, IRST, NRSTS, NRMAX, LR, LDL, LHES, LGMR, LQ, LV,
 
6845
     1        LWK, LZ, MAXLP1, NPSL
 
6846
      INTEGER NLI, NPS, NCFL, NRE, MAXL, KMP, MITER
 
6847
      EXTERNAL  RES, PSOL
 
6848
C    
 
6849
      PARAMETER (LNRE=12, LNCFL=16, LNLI=20, LNPS=21) 
 
6850
      PARAMETER (LLOCWP=29, LLCIWP=30)
 
6851
      PARAMETER (LMITER=23, LMAXL=24, LKMP=25, LNRMAX=26)
 
6852
C
 
6853
C-----------------------------------------------------------------------
 
6854
C IRST is set to 1, to indicate restarting is in effect.
 
6855
C NRMAX is the maximum number of restarts.
 
6856
C-----------------------------------------------------------------------
 
6857
      DATA IRST/1/
 
6858
C
 
6859
      LIWP = IWM(LLCIWP)
 
6860
      NLI = IWM(LNLI)
 
6861
      NPS = IWM(LNPS)
 
6862
      NCFL = IWM(LNCFL)
 
6863
      NRE = IWM(LNRE)
 
6864
      LWP = IWM(LLOCWP)
 
6865
      MAXL = IWM(LMAXL) 
 
6866
      KMP = IWM(LKMP)
 
6867
      NRMAX = IWM(LNRMAX) 
 
6868
      MITER = IWM(LMITER)
 
6869
      IERSL = 0
 
6870
      IRES = 0
 
6871
C-----------------------------------------------------------------------
 
6872
C Use a restarting strategy to solve the linear system
 
6873
C P*X = -F.  Parse the work vector, and perform initializations.
 
6874
C Note that zero is the initial guess for X.
 
6875
C-----------------------------------------------------------------------
 
6876
      MAXLP1 = MAXL + 1
 
6877
      LV = 1
 
6878
      LR = LV + NEQ*MAXL
 
6879
      LHES = LR + NEQ + 1
 
6880
      LQ = LHES + MAXL*MAXLP1
 
6881
      LWK = LQ + 2*MAXL
 
6882
      LDL = LWK + MIN0(1,MAXL-KMP)*NEQ
 
6883
      LZ = LDL + NEQ
 
6884
      CALL DSCAL (NEQ, RSQRTN, EWT, 1)
 
6885
      CALL DCOPY (NEQ, X, 1, WM(LR), 1)
 
6886
      DO 110 I = 1,NEQ
 
6887
 110     X(I) = 0.D0
 
6888
C-----------------------------------------------------------------------
 
6889
C Top of loop for the restart algorithm.  Initial pass approximates
 
6890
C X and sets up a transformed system to perform subsequent restarts
 
6891
C to update X.  NRSTS is initialized to -1, because restarting
 
6892
C does not occur until after the first pass.
 
6893
C Update NRSTS; conditionally copy DL to R; call the DSPIGM
 
6894
C algorithm to solve A*Z = R;  updated counters;  update X with
 
6895
C the residual solution.
 
6896
C Note:  if convergence is not achieved after NRMAX restarts,
 
6897
C then the linear solver is considered to have failed.
 
6898
C-----------------------------------------------------------------------
 
6899
      NRSTS = -1
 
6900
 115  CONTINUE
 
6901
      NRSTS = NRSTS + 1
 
6902
      IF (NRSTS .GT. 0) CALL DCOPY (NEQ, WM(LDL), 1, WM(LR),1)
 
6903
      CALL DSPIGM (NEQ, TN, Y, YPRIME, SAVR, WM(LR), EWT, MAXL, MAXLP1,
 
6904
     1   KMP, EPLIN, CJ, RES, IRES, NRES, PSOL, NPSL, WM(LZ), WM(LV),
 
6905
     2   WM(LHES), WM(LQ), LGMR, WM(LWP), IWM(LIWP), WM(LWK),
 
6906
     3   WM(LDL), RHOK, IFLAG, IRST, NRSTS, RPAR, IPAR)
 
6907
      NLI = NLI + LGMR
 
6908
      NPS = NPS + NPSL
 
6909
      NRE = NRE + NRES
 
6910
      DO 120 I = 1,NEQ
 
6911
 120     X(I) = X(I) + WM(LZ+I-1) 
 
6912
      IF ((IFLAG .EQ. 1) .AND. (NRSTS .LT. NRMAX) .AND. (IRES .EQ. 0))
 
6913
     1   GO TO 115
 
6914
C-----------------------------------------------------------------------
 
6915
C The restart scheme is finished.  Test IRES and IFLAG to see if
 
6916
C convergence was not achieved, and set flags accordingly.
 
6917
C-----------------------------------------------------------------------
 
6918
      IF (IRES .LT. 0) THEN
 
6919
         NCFL = NCFL + 1
 
6920
      ELSE IF (IFLAG .NE. 0) THEN
 
6921
         NCFL = NCFL + 1
 
6922
         IF (IFLAG .GT. 0) IERSL = 1 
 
6923
         IF (IFLAG .LT. 0) IERSL = -1 
 
6924
      ENDIF
 
6925
C-----------------------------------------------------------------------
 
6926
C Update IWM with counters, rescale EWT, and return.
 
6927
C-----------------------------------------------------------------------
 
6928
      IWM(LNLI)  = NLI
 
6929
      IWM(LNPS)  = NPS
 
6930
      IWM(LNCFL) = NCFL
 
6931
      IWM(LNRE)  = NRE
 
6932
      CALL DSCAL (NEQ, SQRTN, EWT, 1)
 
6933
      RETURN
 
6934
C
 
6935
C------END OF SUBROUTINE DSLVK------------------------------------------
 
6936
      END
 
6937
      SUBROUTINE DSPIGM (NEQ, TN, Y, YPRIME, SAVR, R, WGHT, MAXL,
 
6938
     *   MAXLP1, KMP, EPLIN, CJ, RES, IRES, NRE, PSOL, NPSL, Z, V,
 
6939
     *   HES, Q, LGMR, WP, IWP, WK, DL, RHOK, IFLAG, IRST, NRSTS,
 
6940
     *   RPAR, IPAR)
 
6941
C
 
6942
C***BEGIN PROLOGUE  DSPIGM
 
6943
C***DATE WRITTEN   890101   (YYMMDD)
 
6944
C***REVISION DATE  900926   (YYMMDD)
 
6945
C***REVISION DATE  940927   Removed MNEWT and added RHOK in call list.
 
6946
C
 
6947
C
 
6948
C-----------------------------------------------------------------------
 
6949
C***DESCRIPTION
 
6950
C
 
6951
C This routine solves the linear system A * Z = R using a scaled
 
6952
C preconditioned version of the generalized minimum residual method.
 
6953
C An initial guess of Z = 0 is assumed.
 
6954
C
 
6955
C      On entry
 
6956
C
 
6957
C          NEQ = Problem size, passed to PSOL.
 
6958
C
 
6959
C           TN = Current Value of T.
 
6960
C
 
6961
C            Y = Array Containing current dependent variable vector.
 
6962
C
 
6963
C       YPRIME = Array Containing current first derivative of Y.
 
6964
C
 
6965
C         SAVR = Array containing current value of G(T,Y,YPRIME).
 
6966
C
 
6967
C            R = The right hand side of the system A*Z = R.
 
6968
C                R is also used as work space when computing
 
6969
C                the final approximation and will therefore be
 
6970
C                destroyed.
 
6971
C                (R is the same as V(*,MAXL+1) in the call to DSPIGM.)
 
6972
C
 
6973
C         WGHT = The vector of length NEQ containing the nonzero
 
6974
C                elements of the diagonal scaling matrix.
 
6975
C
 
6976
C         MAXL = The maximum allowable order of the matrix H.
 
6977
C
 
6978
C       MAXLP1 = MAXL + 1, used for dynamic dimensioning of HES.
 
6979
C
 
6980
C          KMP = The number of previous vectors the new vector, VNEW,
 
6981
C                must be made orthogonal to.  (KMP .LE. MAXL.)
 
6982
C
 
6983
C        EPLIN = Tolerance on residuals R-A*Z in weighted rms norm.
 
6984
C
 
6985
C           CJ = Scalar proportional to current value of 
 
6986
C                1/(step size H).
 
6987
C
 
6988
C           WK = Real work array used by routine DATV and PSOL.
 
6989
C
 
6990
C           DL = Real work array used for calculation of the residual
 
6991
C                norm RHO when the method is incomplete (KMP.LT.MAXL)
 
6992
C                and/or when using restarting.
 
6993
C
 
6994
C           WP = Real work array used by preconditioner PSOL.
 
6995
C
 
6996
C          IWP = Integer work array used by preconditioner PSOL.
 
6997
C
 
6998
C         IRST = Method flag indicating if restarting is being
 
6999
C                performed.  IRST .GT. 0 means restarting is active,
 
7000
C                while IRST = 0 means restarting is not being used.
 
7001
C
 
7002
C        NRSTS = Counter for the number of restarts on the current
 
7003
C                call to DSPIGM.  If NRSTS .GT. 0, then the residual
 
7004
C                R is already scaled, and so scaling of R is not
 
7005
C                necessary.
 
7006
C
 
7007
C
 
7008
C      On Return
 
7009
C
 
7010
C         Z    = The final computed approximation to the solution
 
7011
C                of the system A*Z = R.
 
7012
C
 
7013
C         LGMR = The number of iterations performed and
 
7014
C                the current order of the upper Hessenberg
 
7015
C                matrix HES.
 
7016
C
 
7017
C         NRE  = The number of calls to RES (i.e. DATV)
 
7018
C
 
7019
C         NPSL = The number of calls to PSOL.
 
7020
C
 
7021
C         V    = The neq by (LGMR+1) array containing the LGMR
 
7022
C                orthogonal vectors V(*,1) to V(*,LGMR).
 
7023
C
 
7024
C         HES  = The upper triangular factor of the QR decomposition
 
7025
C                of the (LGMR+1) by LGMR upper Hessenberg matrix whose
 
7026
C                entries are the scaled inner-products of A*V(*,I)
 
7027
C                and V(*,K).
 
7028
C
 
7029
C         Q    = Real array of length 2*MAXL containing the components
 
7030
C                of the givens rotations used in the QR decomposition
 
7031
C                of HES.  It is loaded in DHEQR and used in DHELS.
 
7032
C
 
7033
C         IRES = Error flag from RES.
 
7034
C
 
7035
C           DL = Scaled preconditioned residual, 
 
7036
C                (D-inverse)*(P-inverse)*(R-A*Z). Only loaded when
 
7037
C                performing restarts of the Krylov iteration.
 
7038
C
 
7039
C         RHOK = Weighted norm of final preconditioned residual.
 
7040
C
 
7041
C        IFLAG = Integer error flag..
 
7042
C                0 Means convergence in LGMR iterations, LGMR.LE.MAXL.
 
7043
C                1 Means the convergence test did not pass in MAXL
 
7044
C                  iterations, but the new residual norm (RHO) is
 
7045
C                  .LT. the old residual norm (RNRM), and so Z is
 
7046
C                  computed.
 
7047
C                2 Means the convergence test did not pass in MAXL
 
7048
C                  iterations, new residual norm (RHO) .GE. old residual
 
7049
C                  norm (RNRM), and the initial guess, Z = 0, is
 
7050
C                  returned.
 
7051
C                3 Means there was a recoverable error in PSOL
 
7052
C                  caused by the preconditioner being out of date.
 
7053
C               -1 Means there was an unrecoverable error in PSOL.
 
7054
C
 
7055
C-----------------------------------------------------------------------
 
7056
C***ROUTINES CALLED
 
7057
C   PSOL, DNRM2, DSCAL, DATV, DORTH, DHEQR, DCOPY, DHELS, DAXPY
 
7058
C
 
7059
C***END PROLOGUE  DSPIGM
 
7060
C
 
7061
      INTEGER NEQ,MAXL,MAXLP1,KMP,IRES,NRE,NPSL,LGMR,IWP,
 
7062
     1   IFLAG,IRST,NRSTS,IPAR
 
7063
      DOUBLE PRECISION TN,Y,YPRIME,SAVR,R,WGHT,EPLIN,CJ,Z,V,HES,Q,WP,WK,
 
7064
     1   DL,RHOK,RPAR
 
7065
      DIMENSION Y(*), YPRIME(*), SAVR(*), R(*), WGHT(*), Z(*),
 
7066
     1   V(NEQ,*), HES(MAXLP1,*), Q(*), WP(*), IWP(*), WK(*), DL(*),
 
7067
     2   RPAR(*), IPAR(*)
 
7068
      INTEGER I, IER, INFO, IP1, I2, J, K, LL, LLP1
 
7069
      DOUBLE PRECISION RNRM,C,DLNRM,PROD,RHO,S,SNORMW,DNRM2,TEM
 
7070
      EXTERNAL  RES, PSOL
 
7071
C
 
7072
      IER = 0
 
7073
      IFLAG = 0
 
7074
      LGMR = 0
 
7075
      NPSL = 0
 
7076
      NRE = 0
 
7077
C-----------------------------------------------------------------------
 
7078
C The initial guess for Z is 0.  The initial residual is therefore
 
7079
C the vector R.  Initialize Z to 0.
 
7080
C-----------------------------------------------------------------------
 
7081
      DO 10 I = 1,NEQ
 
7082
 10     Z(I) = 0.0D0
 
7083
C-----------------------------------------------------------------------
 
7084
C Apply inverse of left preconditioner to vector R if NRSTS .EQ. 0.
 
7085
C Form V(*,1), the scaled preconditioned right hand side.
 
7086
C-----------------------------------------------------------------------
 
7087
      IF (NRSTS .EQ. 0) THEN
 
7088
         CALL PSOL (NEQ, TN, Y, YPRIME, SAVR, WK, CJ, WGHT, WP, IWP,
 
7089
     1      R, EPLIN, IER, RPAR, IPAR)
 
7090
         NPSL = 1
 
7091
         IF (IER .NE. 0) GO TO 300
 
7092
         DO 30 I = 1,NEQ
 
7093
 30         V(I,1) = R(I)*WGHT(I)
 
7094
      ELSE
 
7095
         DO 35 I = 1,NEQ
 
7096
 35         V(I,1) = R(I)
 
7097
      ENDIF
 
7098
C-----------------------------------------------------------------------
 
7099
C Calculate norm of scaled vector V(*,1) and normalize it
 
7100
C If, however, the norm of V(*,1) (i.e. the norm of the preconditioned
 
7101
C residual) is .le. EPLIN, then return with Z=0.
 
7102
C-----------------------------------------------------------------------
 
7103
      RNRM = DNRM2 (NEQ, V, 1)
 
7104
      IF (RNRM .LE. EPLIN) THEN
 
7105
        RHOK = RNRM
 
7106
        RETURN
 
7107
        ENDIF
 
7108
      TEM = 1.0D0/RNRM
 
7109
      CALL DSCAL (NEQ, TEM, V(1,1), 1)
 
7110
C-----------------------------------------------------------------------
 
7111
C Zero out the HES array.
 
7112
C-----------------------------------------------------------------------
 
7113
      DO 65 J = 1,MAXL
 
7114
        DO 60 I = 1,MAXLP1
 
7115
 60       HES(I,J) = 0.0D0
 
7116
 65     CONTINUE
 
7117
C-----------------------------------------------------------------------
 
7118
C Main loop to compute the vectors V(*,2) to V(*,MAXL).
 
7119
C The running product PROD is needed for the convergence test.
 
7120
C-----------------------------------------------------------------------
 
7121
      PROD = 1.0D0
 
7122
      DO 90 LL = 1,MAXL
 
7123
        LGMR = LL
 
7124
C-----------------------------------------------------------------------
 
7125
C Call routine DATV to compute VNEW = ABAR*V(LL), where ABAR is
 
7126
C the matrix A with scaling and inverse preconditioner factors applied.
 
7127
C Call routine DORTH to orthogonalize the new vector VNEW = V(*,LL+1).
 
7128
C call routine DHEQR to update the factors of HES.
 
7129
C-----------------------------------------------------------------------
 
7130
        CALL DATV (NEQ, Y, TN, YPRIME, SAVR, V(1,LL), WGHT, Z,
 
7131
     1     RES, IRES, PSOL, V(1,LL+1), WK, WP, IWP, CJ, EPLIN,
 
7132
     1     IER, NRE, NPSL, RPAR, IPAR)
 
7133
        IF (IRES .LT. 0) RETURN
 
7134
        IF (IER .NE. 0) GO TO 300
 
7135
        CALL DORTH (V(1,LL+1), V, HES, NEQ, LL, MAXLP1, KMP, SNORMW)
 
7136
        HES(LL+1,LL) = SNORMW
 
7137
        CALL DHEQR (HES, MAXLP1, LL, Q, INFO, LL)
 
7138
        IF (INFO .EQ. LL) GO TO 120
 
7139
C-----------------------------------------------------------------------
 
7140
C Update RHO, the estimate of the norm of the residual R - A*ZL.
 
7141
C If KMP .LT. MAXL, then the vectors V(*,1),...,V(*,LL+1) are not
 
7142
C necessarily orthogonal for LL .GT. KMP.  The vector DL must then
 
7143
C be computed, and its norm used in the calculation of RHO.
 
7144
C-----------------------------------------------------------------------
 
7145
        PROD = PROD*Q(2*LL)
 
7146
        RHO = ABS(PROD*RNRM)
 
7147
        IF ((LL.GT.KMP) .AND. (KMP.LT.MAXL)) THEN
 
7148
          IF (LL .EQ. KMP+1) THEN
 
7149
            CALL DCOPY (NEQ, V(1,1), 1, DL, 1)
 
7150
            DO 75 I = 1,KMP
 
7151
              IP1 = I + 1
 
7152
              I2 = I*2
 
7153
              S = Q(I2)
 
7154
              C = Q(I2-1)
 
7155
              DO 70 K = 1,NEQ
 
7156
 70             DL(K) = S*DL(K) + C*V(K,IP1)
 
7157
 75           CONTINUE
 
7158
            ENDIF
 
7159
          S = Q(2*LL)
 
7160
          C = Q(2*LL-1)/SNORMW
 
7161
          LLP1 = LL + 1
 
7162
          DO 80 K = 1,NEQ
 
7163
 80         DL(K) = S*DL(K) + C*V(K,LLP1)
 
7164
          DLNRM = DNRM2 (NEQ, DL, 1)
 
7165
          RHO = RHO*DLNRM
 
7166
          ENDIF
 
7167
C-----------------------------------------------------------------------
 
7168
C Test for convergence.  If passed, compute approximation ZL.
 
7169
C If failed and LL .LT. MAXL, then continue iterating.
 
7170
C-----------------------------------------------------------------------
 
7171
        IF (RHO .LE. EPLIN) GO TO 200
 
7172
        IF (LL .EQ. MAXL) GO TO 100
 
7173
C-----------------------------------------------------------------------
 
7174
C Rescale so that the norm of V(1,LL+1) is one.
 
7175
C-----------------------------------------------------------------------
 
7176
        TEM = 1.0D0/SNORMW
 
7177
        CALL DSCAL (NEQ, TEM, V(1,LL+1), 1)
 
7178
 90     CONTINUE
 
7179
 100  CONTINUE
 
7180
      IF (RHO .LT. RNRM) GO TO 150
 
7181
 120  CONTINUE
 
7182
      IFLAG = 2
 
7183
      DO 130 I = 1,NEQ
 
7184
 130     Z(I) = 0.D0
 
7185
      RETURN
 
7186
 150  IFLAG = 1
 
7187
C-----------------------------------------------------------------------
 
7188
C The tolerance was not met, but the residual norm was reduced.
 
7189
C If performing restarting (IRST .gt. 0) calculate the residual vector
 
7190
C RL and store it in the DL array.  If the incomplete version is 
 
7191
C being used (KMP .lt. MAXL) then DL has already been calculated.
 
7192
C-----------------------------------------------------------------------
 
7193
      IF (IRST .GT. 0) THEN
 
7194
         IF (KMP .EQ. MAXL) THEN
 
7195
C
 
7196
C           Calculate DL from the V(I)'s.
 
7197
C
 
7198
            CALL DCOPY (NEQ, V(1,1), 1, DL, 1)
 
7199
            MAXLM1 = MAXL - 1
 
7200
            DO 175 I = 1,MAXLM1
 
7201
               IP1 = I + 1
 
7202
               I2 = I*2
 
7203
               S = Q(I2)
 
7204
               C = Q(I2-1)
 
7205
               DO 170 K = 1,NEQ
 
7206
 170              DL(K) = S*DL(K) + C*V(K,IP1)
 
7207
 175        CONTINUE
 
7208
            S = Q(2*MAXL)
 
7209
            C = Q(2*MAXL-1)/SNORMW
 
7210
            DO 180 K = 1,NEQ
 
7211
 180           DL(K) = S*DL(K) + C*V(K,MAXLP1)
 
7212
         ENDIF
 
7213
C
 
7214
C        Scale DL by RNRM*PROD to obtain the residual RL.
 
7215
C
 
7216
         TEM = RNRM*PROD
 
7217
         CALL DSCAL(NEQ, TEM, DL, 1)
 
7218
      ENDIF
 
7219
C-----------------------------------------------------------------------
 
7220
C Compute the approximation ZL to the solution.
 
7221
C Since the vector Z was used as work space, and the initial guess
 
7222
C of the Newton correction is zero, Z must be reset to zero.
 
7223
C-----------------------------------------------------------------------
 
7224
 200  CONTINUE
 
7225
      LL = LGMR
 
7226
      LLP1 = LL + 1
 
7227
      DO 210 K = 1,LLP1
 
7228
 210    R(K) = 0.0D0
 
7229
      R(1) = RNRM
 
7230
      CALL DHELS (HES, MAXLP1, LL, Q, R)
 
7231
      DO 220 K = 1,NEQ
 
7232
 220    Z(K) = 0.0D0
 
7233
      DO 230 I = 1,LL
 
7234
        CALL DAXPY (NEQ, R(I), V(1,I), 1, Z, 1)
 
7235
 230    CONTINUE
 
7236
      DO 240 I = 1,NEQ
 
7237
 240    Z(I) = Z(I)/WGHT(I)
 
7238
C Load RHO into RHOK.
 
7239
      RHOK = RHO
 
7240
      RETURN
 
7241
C-----------------------------------------------------------------------
 
7242
C This block handles error returns forced by routine PSOL.
 
7243
C-----------------------------------------------------------------------
 
7244
 300  CONTINUE
 
7245
      IF (IER .LT. 0) IFLAG = -1
 
7246
      IF (IER .GT. 0) IFLAG = 3
 
7247
C
 
7248
      RETURN
 
7249
C
 
7250
C------END OF SUBROUTINE DSPIGM-----------------------------------------
 
7251
      END
 
7252
      SUBROUTINE DATV (NEQ, Y, TN, YPRIME, SAVR, V, WGHT, YPTEM, RES,
 
7253
     *   IRES, PSOL, Z, VTEM, WP, IWP, CJ, EPLIN, IER, NRE, NPSL,
 
7254
     *   RPAR,IPAR)
 
7255
C
 
7256
C***BEGIN PROLOGUE  DATV
 
7257
C***DATE WRITTEN   890101   (YYMMDD)
 
7258
C***REVISION DATE  900926   (YYMMDD)
 
7259
C
 
7260
C
 
7261
C-----------------------------------------------------------------------
 
7262
C***DESCRIPTION
 
7263
C
 
7264
C This routine computes the product
 
7265
C
 
7266
C   Z = (D-inverse)*(P-inverse)*(dF/dY)*(D*V),
 
7267
C
 
7268
C where F(Y) = G(T, Y, CJ*(Y-A)), CJ is a scalar proportional to 1/H,
 
7269
C and A involves the past history of Y.  The quantity CJ*(Y-A) is
 
7270
C an approximation to the first derivative of Y and is stored
 
7271
C in the array YPRIME.  Note that dF/dY = dG/dY + CJ*dG/dYPRIME.
 
7272
C
 
7273
C D is a diagonal scaling matrix, and P is the left preconditioning
 
7274
C matrix.  V is assumed to have L2 norm equal to 1.
 
7275
C The product is stored in Z and is computed by means of a
 
7276
C difference quotient, a call to RES, and one call to PSOL.
 
7277
C
 
7278
C      On entry
 
7279
C
 
7280
C          NEQ = Problem size, passed to RES and PSOL.
 
7281
C
 
7282
C            Y = Array containing current dependent variable vector.
 
7283
C
 
7284
C       YPRIME = Array containing current first derivative of y.
 
7285
C
 
7286
C         SAVR = Array containing current value of G(T,Y,YPRIME).
 
7287
C
 
7288
C            V = Real array of length NEQ (can be the same array as Z).
 
7289
C
 
7290
C         WGHT = Array of length NEQ containing scale factors.
 
7291
C                1/WGHT(I) are the diagonal elements of the matrix D.
 
7292
C
 
7293
C        YPTEM = Work array of length NEQ.
 
7294
C
 
7295
C         VTEM = Work array of length NEQ used to store the
 
7296
C                unscaled version of V.
 
7297
C
 
7298
C         WP = Real work array used by preconditioner PSOL.
 
7299
C
 
7300
C         IWP = Integer work array used by preconditioner PSOL.
 
7301
C
 
7302
C           CJ = Scalar proportional to current value of 
 
7303
C                1/(step size H).
 
7304
C
 
7305
C
 
7306
C      On return
 
7307
C
 
7308
C            Z = Array of length NEQ containing desired scaled
 
7309
C                matrix-vector product.
 
7310
C
 
7311
C         IRES = Error flag from RES.
 
7312
C
 
7313
C          IER = Error flag from PSOL.
 
7314
C
 
7315
C         NRE  = The number of calls to RES.
 
7316
C
 
7317
C         NPSL = The number of calls to PSOL.
 
7318
C
 
7319
C-----------------------------------------------------------------------
 
7320
C***ROUTINES CALLED
 
7321
C   RES, PSOL
 
7322
C
 
7323
C***END PROLOGUE  DATV
 
7324
C
 
7325
      INTEGER NEQ, IRES, IWP, IER, NRE, NPSL, IPAR
 
7326
      DOUBLE PRECISION Y, TN, YPRIME, SAVR, V, WGHT, YPTEM, Z, VTEM,
 
7327
     1   WP, CJ, RPAR
 
7328
      DIMENSION Y(*), YPRIME(*), SAVR(*), V(*), WGHT(*), YPTEM(*),
 
7329
     1   Z(*), VTEM(*), WP(*), IWP(*), RPAR(*), IPAR(*)
 
7330
      INTEGER I
 
7331
      DOUBLE PRECISION EPLIN
 
7332
      EXTERNAL  RES, PSOL
 
7333
C
 
7334
      IRES = 0
 
7335
C-----------------------------------------------------------------------
 
7336
C Set VTEM = D * V.
 
7337
C-----------------------------------------------------------------------
 
7338
      DO 10 I = 1,NEQ
 
7339
 10     VTEM(I) = V(I)/WGHT(I)
 
7340
      IER = 0
 
7341
C-----------------------------------------------------------------------
 
7342
C Store Y in Z and increment Z by VTEM.
 
7343
C Store YPRIME in YPTEM and increment YPTEM by VTEM*CJ.
 
7344
C-----------------------------------------------------------------------
 
7345
      DO 20 I = 1,NEQ
 
7346
        YPTEM(I) = YPRIME(I) + VTEM(I)*CJ
 
7347
 20     Z(I) = Y(I) + VTEM(I)
 
7348
C-----------------------------------------------------------------------
 
7349
C Call RES with incremented Y, YPRIME arguments
 
7350
C stored in Z, YPTEM.  VTEM is overwritten with new residual.
 
7351
C-----------------------------------------------------------------------
 
7352
      CONTINUE
 
7353
      CALL RES(TN,Z,YPTEM,CJ,VTEM,IRES,RPAR,IPAR)
 
7354
      NRE = NRE + 1
 
7355
      IF (IRES .LT. 0) RETURN
 
7356
C-----------------------------------------------------------------------
 
7357
C Set Z = (dF/dY) * VBAR using difference quotient.
 
7358
C (VBAR is old value of VTEM before calling RES)
 
7359
C-----------------------------------------------------------------------
 
7360
      DO 70 I = 1,NEQ
 
7361
 70     Z(I) = VTEM(I) - SAVR(I)
 
7362
C-----------------------------------------------------------------------
 
7363
C Apply inverse of left preconditioner to Z.
 
7364
C-----------------------------------------------------------------------
 
7365
      CALL PSOL (NEQ, TN, Y, YPRIME, SAVR, YPTEM, CJ, WGHT, WP, IWP,
 
7366
     1   Z, EPLIN, IER, RPAR, IPAR)
 
7367
      NPSL = NPSL + 1
 
7368
      IF (IER .NE. 0) RETURN
 
7369
C-----------------------------------------------------------------------
 
7370
C Apply D-inverse to Z and return.
 
7371
C-----------------------------------------------------------------------
 
7372
      DO 90 I = 1,NEQ
 
7373
 90     Z(I) = Z(I)*WGHT(I)
 
7374
      RETURN
 
7375
C
 
7376
C------END OF SUBROUTINE DATV-------------------------------------------
 
7377
      END
 
7378
      SUBROUTINE DORTH (VNEW, V, HES, N, LL, LDHES, KMP, SNORMW)
 
7379
C
 
7380
C***BEGIN PROLOGUE  DORTH
 
7381
C***DATE WRITTEN   890101   (YYMMDD)
 
7382
C***REVISION DATE  900926   (YYMMDD)
 
7383
C
 
7384
C
 
7385
C-----------------------------------------------------------------------
 
7386
C***DESCRIPTION
 
7387
C
 
7388
C This routine orthogonalizes the vector VNEW against the previous
 
7389
C KMP vectors in the V array.  It uses a modified Gram-Schmidt
 
7390
C orthogonalization procedure with conditional reorthogonalization.
 
7391
C
 
7392
C      On entry
 
7393
C
 
7394
C         VNEW = The vector of length N containing a scaled product
 
7395
C                OF The Jacobian and the vector V(*,LL).
 
7396
C
 
7397
C         V    = The N x LL array containing the previous LL
 
7398
C                orthogonal vectors V(*,1) to V(*,LL).
 
7399
C
 
7400
C         HES  = An LL x LL upper Hessenberg matrix containing,
 
7401
C                in HES(I,K), K.LT.LL, scaled inner products of
 
7402
C                A*V(*,K) and V(*,I).
 
7403
C
 
7404
C        LDHES = The leading dimension of the HES array.
 
7405
C
 
7406
C         N    = The order of the matrix A, and the length of VNEW.
 
7407
C
 
7408
C         LL   = The current order of the matrix HES.
 
7409
C
 
7410
C          KMP = The number of previous vectors the new vector VNEW
 
7411
C                must be made orthogonal to (KMP .LE. MAXL).
 
7412
C
 
7413
C
 
7414
C      On return
 
7415
C
 
7416
C         VNEW = The new vector orthogonal to V(*,I0),
 
7417
C                where I0 = MAX(1, LL-KMP+1).
 
7418
C
 
7419
C         HES  = Upper Hessenberg matrix with column LL filled in with
 
7420
C                scaled inner products of A*V(*,LL) and V(*,I).
 
7421
C
 
7422
C       SNORMW = L-2 norm of VNEW.
 
7423
C
 
7424
C-----------------------------------------------------------------------
 
7425
C***ROUTINES CALLED
 
7426
C   DDOT, DNRM2, DAXPY 
 
7427
C
 
7428
C***END PROLOGUE  DORTH
 
7429
C
 
7430
      INTEGER N, LL, LDHES, KMP
 
7431
      DOUBLE PRECISION VNEW, V, HES, SNORMW
 
7432
      DIMENSION VNEW(*), V(N,*), HES(LDHES,*)
 
7433
      INTEGER I, I0
 
7434
      DOUBLE PRECISION ARG, DDOT, DNRM2, SUMDSQ, TEM, VNRM
 
7435
C
 
7436
C-----------------------------------------------------------------------
 
7437
C Get norm of unaltered VNEW for later use.
 
7438
C-----------------------------------------------------------------------
 
7439
      VNRM = DNRM2 (N, VNEW, 1)
 
7440
C-----------------------------------------------------------------------
 
7441
C Do Modified Gram-Schmidt on VNEW = A*V(LL).
 
7442
C Scaled inner products give new column of HES.
 
7443
C Projections of earlier vectors are subtracted from VNEW.
 
7444
C-----------------------------------------------------------------------
 
7445
      I0 = MAX0(1,LL-KMP+1)
 
7446
      DO 10 I = I0,LL
 
7447
        HES(I,LL) = DDOT (N, V(1,I), 1, VNEW, 1)
 
7448
        TEM = -HES(I,LL)
 
7449
        CALL DAXPY (N, TEM, V(1,I), 1, VNEW, 1)
 
7450
 10     CONTINUE
 
7451
C-----------------------------------------------------------------------
 
7452
C Compute SNORMW = norm of VNEW.
 
7453
C If VNEW is small compared to its input value (in norm), then
 
7454
C Reorthogonalize VNEW to V(*,1) through V(*,LL).
 
7455
C Correct if relative correction exceeds 1000*(unit roundoff).
 
7456
C Finally, correct SNORMW using the dot products involved.
 
7457
C-----------------------------------------------------------------------
 
7458
      SNORMW = DNRM2 (N, VNEW, 1)
 
7459
      IF (VNRM + 0.001D0*SNORMW .NE. VNRM) RETURN
 
7460
      SUMDSQ = 0.0D0
 
7461
      DO 30 I = I0,LL
 
7462
        TEM = -DDOT (N, V(1,I), 1, VNEW, 1)
 
7463
        IF (HES(I,LL) + 0.001D0*TEM .EQ. HES(I,LL)) GO TO 30
 
7464
        HES(I,LL) = HES(I,LL) - TEM
 
7465
        CALL DAXPY (N, TEM, V(1,I), 1, VNEW, 1)
 
7466
        SUMDSQ = SUMDSQ + TEM**2
 
7467
 30     CONTINUE
 
7468
      IF (SUMDSQ .EQ. 0.0D0) RETURN
 
7469
      ARG = MAX(0.0D0,SNORMW**2 - SUMDSQ)
 
7470
      SNORMW = SQRT(ARG)
 
7471
      RETURN
 
7472
C
 
7473
C------END OF SUBROUTINE DORTH------------------------------------------
 
7474
      END
 
7475
      SUBROUTINE DHEQR (A, LDA, N, Q, INFO, IJOB)
 
7476
C
 
7477
C***BEGIN PROLOGUE  DHEQR
 
7478
C***DATE WRITTEN   890101   (YYMMDD)
 
7479
C***REVISION DATE  900926   (YYMMDD)
 
7480
C
 
7481
C-----------------------------------------------------------------------
 
7482
C***DESCRIPTION
 
7483
C
 
7484
C     This routine performs a QR decomposition of an upper
 
7485
C     Hessenberg matrix A.  There are two options available:
 
7486
C
 
7487
C          (1)  performing a fresh decomposition
 
7488
C          (2)  updating the QR factors by adding a row and A
 
7489
C               column to the matrix A.
 
7490
C
 
7491
C     DHEQR decomposes an upper Hessenberg matrix by using Givens
 
7492
C     rotations.
 
7493
C
 
7494
C     On entry
 
7495
C
 
7496
C        A       DOUBLE PRECISION(LDA, N)
 
7497
C                The matrix to be decomposed.
 
7498
C
 
7499
C        LDA     INTEGER
 
7500
C                The leading dimension of the array A.
 
7501
C
 
7502
C        N       INTEGER
 
7503
C                A is an (N+1) by N Hessenberg matrix.
 
7504
C
 
7505
C        IJOB    INTEGER
 
7506
C                = 1     Means that a fresh decomposition of the
 
7507
C                        matrix A is desired.
 
7508
C                .GE. 2  Means that the current decomposition of A
 
7509
C                        will be updated by the addition of a row
 
7510
C                        and a column.
 
7511
C     On return
 
7512
C
 
7513
C        A       The upper triangular matrix R.
 
7514
C                The factorization can be written Q*A = R, where
 
7515
C                Q is a product of Givens rotations and R is upper
 
7516
C                triangular.
 
7517
C
 
7518
C        Q       DOUBLE PRECISION(2*N)
 
7519
C                The factors C and S of each Givens rotation used
 
7520
C                in decomposing A.
 
7521
C
 
7522
C        INFO    INTEGER
 
7523
C                = 0  normal value.
 
7524
C                = K  If  A(K,K) .EQ. 0.0.  This is not an error
 
7525
C                     condition for this subroutine, but it does
 
7526
C                     indicate that DHELS will divide by zero
 
7527
C                     if called.
 
7528
C
 
7529
C     Modification of LINPACK.
 
7530
C     Peter Brown, Lawrence Livermore Natl. Lab.
 
7531
C
 
7532
C-----------------------------------------------------------------------
 
7533
C***ROUTINES CALLED (NONE)
 
7534
C
 
7535
C***END PROLOGUE  DHEQR
 
7536
C
 
7537
      INTEGER LDA, N, INFO, IJOB
 
7538
      DOUBLE PRECISION A(LDA,*), Q(*)
 
7539
      INTEGER I, IQ, J, K, KM1, KP1, NM1
 
7540
      DOUBLE PRECISION C, S, T, T1, T2
 
7541
C
 
7542
      IF (IJOB .GT. 1) GO TO 70
 
7543
C-----------------------------------------------------------------------
 
7544
C A new factorization is desired.
 
7545
C-----------------------------------------------------------------------
 
7546
C
 
7547
C     QR decomposition without pivoting.
 
7548
C
 
7549
      INFO = 0
 
7550
      DO 60 K = 1, N
 
7551
         KM1 = K - 1
 
7552
         KP1 = K + 1
 
7553
C
 
7554
C           Compute Kth column of R.
 
7555
C           First, multiply the Kth column of A by the previous
 
7556
C           K-1 Givens rotations.
 
7557
C
 
7558
            IF (KM1 .LT. 1) GO TO 20
 
7559
            DO 10 J = 1, KM1
 
7560
              I = 2*(J-1) + 1
 
7561
              T1 = A(J,K)
 
7562
              T2 = A(J+1,K)
 
7563
              C = Q(I)
 
7564
              S = Q(I+1)
 
7565
              A(J,K) = C*T1 - S*T2
 
7566
              A(J+1,K) = S*T1 + C*T2
 
7567
   10         CONTINUE
 
7568
C
 
7569
C           Compute Givens components C and S.
 
7570
C
 
7571
   20       CONTINUE
 
7572
            IQ = 2*KM1 + 1
 
7573
            T1 = A(K,K)
 
7574
            T2 = A(KP1,K)
 
7575
            IF (T2 .NE. 0.0D0) GO TO 30
 
7576
              C = 1.0D0
 
7577
              S = 0.0D0
 
7578
              GO TO 50
 
7579
   30       CONTINUE
 
7580
            IF (ABS(T2) .LT. ABS(T1)) GO TO 40
 
7581
              T = T1/T2
 
7582
              S = -1.0D0/SQRT(1.0D0+T*T)
 
7583
              C = -S*T
 
7584
              GO TO 50
 
7585
   40       CONTINUE
 
7586
              T = T2/T1
 
7587
              C = 1.0D0/SQRT(1.0D0+T*T)
 
7588
              S = -C*T
 
7589
   50       CONTINUE
 
7590
            Q(IQ) = C
 
7591
            Q(IQ+1) = S
 
7592
            A(K,K) = C*T1 - S*T2
 
7593
            IF (A(K,K) .EQ. 0.0D0) INFO = K
 
7594
   60 CONTINUE
 
7595
      RETURN
 
7596
C-----------------------------------------------------------------------
 
7597
C The old factorization of A will be updated.  A row and a column
 
7598
C has been added to the matrix A.
 
7599
C N by N-1 is now the old size of the matrix.
 
7600
C-----------------------------------------------------------------------
 
7601
  70  CONTINUE
 
7602
      NM1 = N - 1
 
7603
C-----------------------------------------------------------------------
 
7604
C Multiply the new column by the N previous Givens rotations.
 
7605
C-----------------------------------------------------------------------
 
7606
      DO 100 K = 1,NM1
 
7607
        I = 2*(K-1) + 1
 
7608
        T1 = A(K,N)
 
7609
        T2 = A(K+1,N)
 
7610
        C = Q(I)
 
7611
        S = Q(I+1)
 
7612
        A(K,N) = C*T1 - S*T2
 
7613
        A(K+1,N) = S*T1 + C*T2
 
7614
 100    CONTINUE
 
7615
C-----------------------------------------------------------------------
 
7616
C Complete update of decomposition by forming last Givens rotation,
 
7617
C and multiplying it times the column vector (A(N,N),A(NP1,N)).
 
7618
C-----------------------------------------------------------------------
 
7619
      INFO = 0
 
7620
      T1 = A(N,N)
 
7621
      T2 = A(N+1,N)
 
7622
      IF (T2 .NE. 0.0D0) GO TO 110
 
7623
        C = 1.0D0
 
7624
        S = 0.0D0
 
7625
        GO TO 130
 
7626
 110  CONTINUE
 
7627
      IF (ABS(T2) .LT. ABS(T1)) GO TO 120
 
7628
        T = T1/T2
 
7629
        S = -1.0D0/SQRT(1.0D0+T*T)
 
7630
        C = -S*T
 
7631
        GO TO 130
 
7632
 120  CONTINUE
 
7633
        T = T2/T1
 
7634
        C = 1.0D0/SQRT(1.0D0+T*T)
 
7635
        S = -C*T
 
7636
 130  CONTINUE
 
7637
      IQ = 2*N - 1
 
7638
      Q(IQ) = C
 
7639
      Q(IQ+1) = S
 
7640
      A(N,N) = C*T1 - S*T2
 
7641
      IF (A(N,N) .EQ. 0.0D0) INFO = N
 
7642
      RETURN
 
7643
C
 
7644
C------END OF SUBROUTINE DHEQR------------------------------------------
 
7645
      END
 
7646
      SUBROUTINE DHELS (A, LDA, N, Q, B)
 
7647
C
 
7648
C***BEGIN PROLOGUE  DHELS
 
7649
C***DATE WRITTEN   890101   (YYMMDD)
 
7650
C***REVISION DATE  900926   (YYMMDD)
 
7651
C
 
7652
C
 
7653
C-----------------------------------------------------------------------
 
7654
C***DESCRIPTION
 
7655
C
 
7656
C This is similar to the LINPACK routine DGESL except that
 
7657
C A is an upper Hessenberg matrix.
 
7658
C
 
7659
C     DHELS solves the least squares problem
 
7660
C
 
7661
C           MIN (B-A*X,B-A*X)
 
7662
C
 
7663
C     using the factors computed by DHEQR.
 
7664
C
 
7665
C     On entry
 
7666
C
 
7667
C        A       DOUBLE PRECISION (LDA, N)
 
7668
C                The output from DHEQR which contains the upper
 
7669
C                triangular factor R in the QR decomposition of A.
 
7670
C
 
7671
C        LDA     INTEGER
 
7672
C                The leading dimension of the array  A .
 
7673
C
 
7674
C        N       INTEGER
 
7675
C                A is originally an (N+1) by N matrix.
 
7676
C
 
7677
C        Q       DOUBLE PRECISION(2*N)
 
7678
C                The coefficients of the N givens rotations
 
7679
C                used in the QR factorization of A.
 
7680
C
 
7681
C        B       DOUBLE PRECISION(N+1)
 
7682
C                The right hand side vector.
 
7683
C
 
7684
C
 
7685
C     On return
 
7686
C
 
7687
C        B       The solution vector X.
 
7688
C
 
7689
C
 
7690
C     Modification of LINPACK.
 
7691
C     Peter Brown, Lawrence Livermore Natl. Lab.
 
7692
C
 
7693
C-----------------------------------------------------------------------
 
7694
C***ROUTINES CALLED
 
7695
C   DAXPY 
 
7696
C
 
7697
C***END PROLOGUE  DHELS
 
7698
C
 
7699
      INTEGER LDA, N
 
7700
      DOUBLE PRECISION A(LDA,*), B(*), Q(*)
 
7701
      INTEGER IQ, K, KB, KP1
 
7702
      DOUBLE PRECISION C, S, T, T1, T2
 
7703
C
 
7704
C        Minimize (B-A*X,B-A*X).
 
7705
C        First form Q*B.
 
7706
C
 
7707
         DO 20 K = 1, N
 
7708
            KP1 = K + 1
 
7709
            IQ = 2*(K-1) + 1
 
7710
            C = Q(IQ)
 
7711
            S = Q(IQ+1)
 
7712
            T1 = B(K)
 
7713
            T2 = B(KP1)
 
7714
            B(K) = C*T1 - S*T2
 
7715
            B(KP1) = S*T1 + C*T2
 
7716
   20    CONTINUE
 
7717
C
 
7718
C        Now solve R*X = Q*B.
 
7719
C
 
7720
         DO 40 KB = 1, N
 
7721
            K = N + 1 - KB
 
7722
            B(K) = B(K)/A(K,K)
 
7723
            T = -B(K)
 
7724
            CALL DAXPY (K-1, T, A(1,K), 1, B(1), 1)
 
7725
   40    CONTINUE
 
7726
      RETURN
 
7727
C
 
7728
C------END OF SUBROUTINE DHELS------------------------------------------
 
7729
      END