1 !**********************************************************************************
2 ! This computer software was prepared by Battelle Memorial Institute, hereinafter
3 ! the Contractor, under Contract No. DE-AC05-76RL0 1830 with the Department of
4 ! Energy (DOE). NEITHER THE GOVERNMENT NOR THE CONTRACTOR MAKES ANY WARRANTY,
5 ! EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE.
7 ! MOSAIC module: see module_mosaic_driver.F for references and terms of use
8 !**********************************************************************************
10 !-----------------------------------------------------------------------
11 ! module_cmu_dvode_solver - from vode.f & vode_subs.f on 27-oct-2005
12 ! (vode.f - downloaded from www.netlib.org on 28-jul-2004)
13 ! (vode_subs.f - created on 28-jul-2004
14 ! by downloading following from www.netlib.org
15 ! 1. daxpy, dcopy, ddot, dnrm2, dscal, idamax from blas
16 ! 2. dgbfa, dbgsl, dgefa, dgesl from linpack)
18 ! first converted to lowercase
19 ! then converted to fortran-90
20 ! then converted to module
21 ! for this step, had to comment out declarations of any
22 ! functions that are part of the module
23 ! also changed common block names to reduce potential for conflicts
24 ! dvod01 --> dvod_cmn01
25 ! dvod02 --> dvod_cmn02
26 !-----------------------------------------------------------------------
27 ! 27-oct-2005 - do not declare functions that are in the module
28 ! 04-mar-2008 - eliminated common blocks;
29 ! halt if istate .ne. 1, because repeated 1-step execution
30 ! will not work now that common blocks are gone
31 !-----------------------------------------------------------------------
33 module module_cmu_dvode_solver
39 icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
40 l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
41 locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
42 n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
44 ncfn, netf, nfe, nje, nlu, nni, nqu, nst
46 acnrm, ccmxj, conp, crate, drc, el(13), &
47 eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
48 rc, rl1, tau(13), tq(5), tn, uround, &
51 ! common /dvod_cmn01/ acnrm, ccmxj, conp, crate, drc, el(13), &
52 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
53 ! rc, rl1, tau(13), tq(5), tn, uround, &
54 ! icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
55 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
56 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
57 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
59 ! common /dvod_cmn02/ hu, ncfn, netf, nfe, nje, nlu, nni, nqu, nst
60 end type dvode_cmn_vars
68 !-----------------------------------------------------------------------
69 ! vode.f - downloaded from www.netlib.org on 28-jul-2004
70 !-----------------------------------------------------------------------
73 subroutine dvode (f, neq, y, t, tout, itol, rtol, atol, itask, &
74 istate, iopt, rwork, lrw, iwork, liw, jac, mf, &
78 double precision y, t, tout, rtol, atol, rwork, rpar
79 integer neq, itol, itask, istate, iopt, lrw, iwork, liw, &
81 dimension y(*), rtol(*), atol(*), rwork(lrw), iwork(liw), &
83 !-----------------------------------------------------------------------
84 ! dvode: variable-coefficient ordinary differential equation solver,
85 ! with fixed-leading-coefficient implementation.
86 ! this version is in double precision.
88 ! dvode solves the initial value problem for stiff or nonstiff
89 ! systems of first order odes,
90 ! dy/dt = f(t,y) , or, in component form,
91 ! dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(neq)) (i = 1,...,neq).
92 ! dvode is a package based on the episode and episodeb packages, and
93 ! on the odepack user interface standard, with minor modifications.
94 !-----------------------------------------------------------------------
96 ! peter n. brown and alan c. hindmarsh
97 ! center for applied scientific computing, l-561
98 ! lawrence livermore national laboratory
102 ! illinois institute of technology
104 !-----------------------------------------------------------------------
107 ! 1. p. n. brown, g. d. byrne, and a. c. hindmarsh, 'vode: a variable
108 ! coefficient ode solver,' siam j. sci. stat. comput., 10 (1989),
109 ! pp. 1038-1051. also, llnl report ucrl-98412, june 1988.
110 ! 2. g. d. byrne and a. c. hindmarsh, 'a polyalgorithm for the
111 ! numerical solution of ordinary differential equations,'
112 ! acm trans. math. software, 1 (1975), pp. 71-96.
113 ! 3. a. c. hindmarsh and g. d. byrne, 'episode: an effective package
114 ! for the integration of systems of ordinary differential
115 ! equations,' llnl report ucid-30112, rev. 1, april 1977.
116 ! 4. g. d. byrne and a. c. hindmarsh, 'episodeb: an experimental
117 ! package for the integration of systems of ordinary differential
118 ! equations with banded jacobians,' llnl report ucid-30132, april
120 ! 5. a. c. hindmarsh, 'odepack, a systematized collection of ode
121 ! solvers,' in scientific computing, r. s. stepleman et al., eds.,
122 ! north-holland, amsterdam, 1983, pp. 55-64.
123 ! 6. k. r. jackson and r. sacks-davis, 'an alternative implementation
124 ! of variable step-size multistep formulas for stiff odes,' acm
125 ! trans. math. software, 6 (1980), pp. 295-318.
126 !-----------------------------------------------------------------------
129 ! communication between the user and the dvode package, for normal
130 ! situations, is summarized here. this summary describes only a subset
131 ! of the full set of options available. see the full description for
132 ! details, including optional communication, nonstandard options,
133 ! and instructions for special situations. see also the example
134 ! problem (with program and output) following this summary.
136 ! a. first provide a subroutine of the form:
137 ! subroutine f (neq, t, y, ydot, rpar, ipar)
138 ! double precision t, y(neq), ydot(neq), rpar
139 ! which supplies the vector function f by loading ydot(i) with f(i).
141 ! b. next determine (or guess) whether or not the problem is stiff.
142 ! stiffness occurs when the jacobian matrix df/dy has an eigenvalue
143 ! whose real part is negative and large in magnitude, compared to the
144 ! reciprocal of the t span of interest. if the problem is nonstiff,
145 ! use a method flag mf = 10. if it is stiff, there are four standard
146 ! choices for mf (21, 22, 24, 25), and dvode requires the jacobian
147 ! matrix in some form. in these cases (mf .gt. 0), dvode will use a
148 ! saved copy of the jacobian matrix. if this is undesirable because of
149 ! storage limitations, set mf to the corresponding negative value
150 ! (-21, -22, -24, -25). (see full description of mf below.)
151 ! the jacobian matrix is regarded either as full (mf = 21 or 22),
152 ! or banded (mf = 24 or 25). in the banded case, dvode requires two
153 ! half-bandwidth parameters ml and mu. these are, respectively, the
154 ! widths of the lower and upper parts of the band, excluding the main
155 ! diagonal. thus the band consists of the locations (i,j) with
156 ! i-ml .le. j .le. i+mu, and the full bandwidth is ml+mu+1.
158 ! c. if the problem is stiff, you are encouraged to supply the jacobian
159 ! directly (mf = 21 or 24), but if this is not feasible, dvode will
160 ! compute it internally by difference quotients (mf = 22 or 25).
161 ! if you are supplying the jacobian, provide a subroutine of the form:
162 ! subroutine jac (neq, t, y, ml, mu, pd, nrowpd, rpar, ipar)
163 ! double precision t, y(neq), pd(nrowpd,neq), rpar
164 ! which supplies df/dy by loading pd as follows:
165 ! for a full jacobian (mf = 21), load pd(i,j) with df(i)/dy(j),
166 ! the partial derivative of f(i) with respect to y(j). (ignore the
167 ! ml and mu arguments in this case.)
168 ! for a banded jacobian (mf = 24), load pd(i-j+mu+1,j) with
169 ! df(i)/dy(j), i.e. load the diagonal lines of df/dy into the rows of
170 ! pd from the top down.
171 ! in either case, only nonzero elements need be loaded.
173 ! d. write a main program which calls subroutine dvode once for
174 ! each point at which answers are desired. this should also provide
175 ! for possible use of logical unit 6 for output of error messages
176 ! by dvode. on the first call to dvode, supply arguments as follows:
177 ! f = name of subroutine for right-hand side vector f.
178 ! this name must be declared external in calling program.
179 ! neq = number of first order odes.
180 ! y = array of initial values, of length neq.
181 ! t = the initial value of the independent variable.
182 ! tout = first point where output is desired (.ne. t).
183 ! itol = 1 or 2 according as atol (below) is a scalar or array.
184 ! rtol = relative tolerance parameter (scalar).
185 ! atol = absolute tolerance parameter (scalar or array).
186 ! the estimated local error in y(i) will be controlled so as
187 ! to be roughly less (in magnitude) than
188 ! ewt(i) = rtol*abs(y(i)) + atol if itol = 1, or
189 ! ewt(i) = rtol*abs(y(i)) + atol(i) if itol = 2.
190 ! thus the local error test passes if, in each component,
191 ! either the absolute error is less than atol (or atol(i)),
192 ! or the relative error is less than rtol.
193 ! use rtol = 0.0 for pure absolute error control, and
194 ! use atol = 0.0 (or atol(i) = 0.0) for pure relative error
195 ! control. caution: actual (global) errors may exceed these
196 ! local tolerances, so choose them conservatively.
197 ! itask = 1 for normal computation of output values of y at t = tout.
198 ! istate = integer flag (input and output). set istate = 1.
199 ! iopt = 0 to indicate no optional input used.
200 ! rwork = real work array of length at least:
201 ! 20 + 16*neq for mf = 10,
202 ! 22 + 9*neq + 2*neq**2 for mf = 21 or 22,
203 ! 22 + 11*neq + (3*ml + 2*mu)*neq for mf = 24 or 25.
204 ! lrw = declared length of rwork (in user's dimension statement).
205 ! iwork = integer work array of length at least:
207 ! 30 + neq for mf = 21, 22, 24, or 25.
208 ! if mf = 24 or 25, input in iwork(1),iwork(2) the lower
209 ! and upper half-bandwidths ml,mu.
210 ! liw = declared length of iwork (in user's dimension statement).
211 ! jac = name of subroutine for jacobian matrix (mf = 21 or 24).
212 ! if used, this name must be declared external in calling
213 ! program. if not used, pass a dummy name.
214 ! mf = method flag. standard values are:
215 ! 10 for nonstiff (adams) method, no jacobian used.
216 ! 21 for stiff (bdf) method, user-supplied full jacobian.
217 ! 22 for stiff method, internally generated full jacobian.
218 ! 24 for stiff method, user-supplied banded jacobian.
219 ! 25 for stiff method, internally generated banded jacobian.
220 ! rpar,ipar = user-defined real and integer arrays passed to f and jac.
221 ! note that the main program must declare arrays y, rwork, iwork,
222 ! and possibly atol, rpar, and ipar.
224 ! e. the output from the first call (or any call) is:
225 ! y = array of computed values of y(t) vector.
226 ! t = corresponding value of independent variable (normally tout).
227 ! istate = 2 if dvode was successful, negative otherwise.
228 ! -1 means excess work done on this call. (perhaps wrong mf.)
229 ! -2 means excess accuracy requested. (tolerances too small.)
230 ! -3 means illegal input detected. (see printed message.)
231 ! -4 means repeated error test failures. (check all input.)
232 ! -5 means repeated convergence failures. (perhaps bad
233 ! jacobian supplied or wrong choice of mf or tolerances.)
234 ! -6 means error weight became zero during problem. (solution
235 ! component i vanished, and atol or atol(i) = 0.)
237 ! f. to continue the integration after a successful return, simply
238 ! reset tout and call dvode again. no other parameters need be reset.
240 !-----------------------------------------------------------------------
243 ! the following is a simple example problem, with the coding
244 ! needed for its solution by dvode. the problem is from chemical
245 ! kinetics, and consists of the following three rate equations:
246 ! dy1/dt = -.04*y1 + 1.e4*y2*y3
247 ! dy2/dt = .04*y1 - 1.e4*y2*y3 - 3.e7*y2**2
248 ! dy3/dt = 3.e7*y2**2
249 ! on the interval from t = 0.0 to t = 4.e10, with initial conditions
250 ! y1 = 1.0, y2 = y3 = 0. the problem is stiff.
252 ! the following coding solves this problem with dvode, using mf = 21
253 ! and printing results at t = .4, 4., ..., 4.e10. it uses
254 ! itol = 2 and atol much smaller for y2 than y1 or y3 because
255 ! y2 has much smaller values.
256 ! at the end of the run, statistical quantities of interest are
257 ! printed. (see optional output in the full description below.)
258 ! to generate fortran source code, replace c in column 1 with a blank
259 ! in the coding below.
262 ! double precision atol, rpar, rtol, rwork, t, tout, y
263 ! dimension y(3), atol(3), rwork(67), iwork(33)
282 ! call dvode(fex,neq,y,t,tout,itol,rtol,atol,itask,istate,
283 ! 1 iopt,rwork,lrw,iwork,liw,jex,mf,rpar,ipar)
284 ! write(6,20)t,y(1),y(2),y(3)
285 ! 20 format(' at t =',d12.4,' y =',3d14.6)
286 ! if (istate .lt. 0) go to 80
288 ! write(6,60) iwork(11),iwork(12),iwork(13),iwork(19),
289 ! 1 iwork(20),iwork(21),iwork(22)
290 ! 60 format(/' no. steps =',i4,' no. f-s =',i4,
291 ! 1 ' no. j-s =',i4,' no. lu-s =',i4/
292 ! 2 ' no. nonlinear iterations =',i4/
293 ! 3 ' no. nonlinear convergence failures =',i4/
294 ! 4 ' no. error test failures =',i4/)
296 ! 80 write(6,90)istate
297 ! 90 format(///' error halt: istate =',i3)
301 ! subroutine fex (neq, t, y, ydot, rpar, ipar)
302 ! double precision rpar, t, y, ydot
303 ! dimension y(neq), ydot(neq)
304 ! ydot(1) = -.04d0*y(1) + 1.d4*y(2)*y(3)
305 ! ydot(3) = 3.d7*y(2)*y(2)
306 ! ydot(2) = -ydot(1) - ydot(3)
310 ! subroutine jex (neq, t, y, ml, mu, pd, nrpd, rpar, ipar)
311 ! double precision pd, rpar, t, y
312 ! dimension y(neq), pd(nrpd,neq)
314 ! pd(1,2) = 1.d4*y(3)
315 ! pd(1,3) = 1.d4*y(2)
318 ! pd(3,2) = 6.d7*y(2)
319 ! pd(2,2) = -pd(1,2) - pd(3,2)
323 ! the following output was obtained from the above program on a
324 ! cray-1 computer with the cft compiler.
326 ! at t = 4.0000e-01 y = 9.851680e-01 3.386314e-05 1.479817e-02
327 ! at t = 4.0000e+00 y = 9.055255e-01 2.240539e-05 9.445214e-02
328 ! at t = 4.0000e+01 y = 7.158108e-01 9.184883e-06 2.841800e-01
329 ! at t = 4.0000e+02 y = 4.505032e-01 3.222940e-06 5.494936e-01
330 ! at t = 4.0000e+03 y = 1.832053e-01 8.942690e-07 8.167938e-01
331 ! at t = 4.0000e+04 y = 3.898560e-02 1.621875e-07 9.610142e-01
332 ! at t = 4.0000e+05 y = 4.935882e-03 1.984013e-08 9.950641e-01
333 ! at t = 4.0000e+06 y = 5.166183e-04 2.067528e-09 9.994834e-01
334 ! at t = 4.0000e+07 y = 5.201214e-05 2.080593e-10 9.999480e-01
335 ! at t = 4.0000e+08 y = 5.213149e-06 2.085271e-11 9.999948e-01
336 ! at t = 4.0000e+09 y = 5.183495e-07 2.073399e-12 9.999995e-01
337 ! at t = 4.0000e+10 y = 5.450996e-08 2.180399e-13 9.999999e-01
339 ! no. steps = 595 no. f-s = 832 no. j-s = 13 no. lu-s = 112
340 ! no. nonlinear iterations = 831
341 ! no. nonlinear convergence failures = 0
342 ! no. error test failures = 22
343 !-----------------------------------------------------------------------
344 ! full description of user interface to dvode.
346 ! the user interface to dvode consists of the following parts.
348 ! i. the call sequence to subroutine dvode, which is a driver
349 ! routine for the solver. this includes descriptions of both
350 ! the call sequence arguments and of user-supplied routines.
351 ! following these descriptions is
352 ! * a description of optional input available through the
354 ! * a description of optional output (in the work arrays), and
355 ! * instructions for interrupting and restarting a solution.
357 ! ii. descriptions of other routines in the dvode package that may be
358 ! (optionally) called by the user. these provide the ability to
359 ! alter error message handling, save and restore the internal
360 ! common, and obtain specified derivatives of the solution y(t).
362 ! iii. descriptions of common blocks to be declared in overlay
363 ! or similar environments.
365 ! iv. description of two routines in the dvode package, either of
366 ! which the user may replace with his own version, if desired.
367 ! these relate to the measurement of errors.
369 !-----------------------------------------------------------------------
370 ! part i. call sequence.
372 ! the call sequence parameters used for input only are
373 ! f, neq, tout, itol, rtol, atol, itask, iopt, lrw, liw, jac, mf,
374 ! and those used for both input and output are
376 ! the work arrays rwork and iwork are also used for conditional and
377 ! optional input and optional output. (the term output here refers
378 ! to the return from subroutine dvode to the user's calling program.)
380 ! the legality of input parameters will be thoroughly checked on the
381 ! initial call for the problem, but not checked thereafter unless a
382 ! change in input parameters is flagged by istate = 3 in the input.
384 ! the descriptions of the call arguments are as follows.
386 ! f = the name of the user-supplied subroutine defining the
387 ! ode system. the system must be put in the first-order
388 ! form dy/dt = f(t,y), where f is a vector-valued function
389 ! of the scalar t and the vector y. subroutine f is to
390 ! compute the function f. it is to have the form
391 ! subroutine f (neq, t, y, ydot, rpar, ipar)
392 ! double precision t, y(neq), ydot(neq), rpar
393 ! where neq, t, and y are input, and the array ydot = f(t,y)
394 ! is output. y and ydot are arrays of length neq.
395 ! subroutine f should not alter y(1),...,y(neq).
396 ! f must be declared external in the calling program.
398 ! subroutine f may access user-defined real and integer
399 ! work arrays rpar and ipar, which are to be dimensioned
400 ! in the main program.
402 ! if quantities computed in the f routine are needed
403 ! externally to dvode, an extra call to f should be made
404 ! for this purpose, for consistent and accurate results.
405 ! if only the derivative dy/dt is needed, use dvindy instead.
407 ! neq = the size of the ode system (number of first order
408 ! ordinary differential equations). used only for input.
409 ! neq may not be increased during the problem, but
410 ! can be decreased (with istate = 3 in the input).
412 ! y = a real array for the vector of dependent variables, of
413 ! length neq or more. used for both input and output on the
414 ! first call (istate = 1), and only for output on other calls.
415 ! on the first call, y must contain the vector of initial
416 ! values. in the output, y contains the computed solution
417 ! evaluated at t. if desired, the y array may be used
418 ! for other purposes between calls to the solver.
420 ! this array is passed as the y argument in all calls to
423 ! t = the independent variable. in the input, t is used only on
424 ! the first call, as the initial point of the integration.
425 ! in the output, after each call, t is the value at which a
426 ! computed solution y is evaluated (usually the same as tout).
427 ! on an error return, t is the farthest point reached.
429 ! tout = the next value of t at which a computed solution is desired.
430 ! used only for input.
432 ! when starting the problem (istate = 1), tout may be equal
433 ! to t for one call, then should .ne. t for the next call.
434 ! for the initial t, an input value of tout .ne. t is used
435 ! in order to determine the direction of the integration
436 ! (i.e. the algebraic sign of the step sizes) and the rough
437 ! scale of the problem. integration in either direction
438 ! (forward or backward in t) is permitted.
440 ! if itask = 2 or 5 (one-step modes), tout is ignored after
441 ! the first call (i.e. the first call with tout .ne. t).
442 ! otherwise, tout is required on every call.
444 ! if itask = 1, 3, or 4, the values of tout need not be
445 ! monotone, but a value of tout which backs up is limited
446 ! to the current internal t interval, whose endpoints are
447 ! tcur - hu and tcur. (see optional output, below, for
450 ! itol = an indicator for the type of error control. see
451 ! description below under atol. used only for input.
453 ! rtol = a relative error tolerance parameter, either a scalar or
454 ! an array of length neq. see description below under atol.
457 ! atol = an absolute error tolerance parameter, either a scalar or
458 ! an array of length neq. input only.
460 ! the input parameters itol, rtol, and atol determine
461 ! the error control performed by the solver. the solver will
462 ! control the vector e = (e(i)) of estimated local errors
463 ! in y, according to an inequality of the form
464 ! rms-norm of ( e(i)/ewt(i) ) .le. 1,
465 ! where ewt(i) = rtol(i)*abs(y(i)) + atol(i),
466 ! and the rms-norm (root-mean-square norm) here is
467 ! rms-norm(v) = sqrt(sum v(i)**2 / neq). here ewt = (ewt(i))
468 ! is a vector of weights which must always be positive, and
469 ! the values of rtol and atol should all be non-negative.
470 ! the following table gives the types (scalar/array) of
471 ! rtol and atol, and the corresponding form of ewt(i).
473 ! itol rtol atol ewt(i)
474 ! 1 scalar scalar rtol*abs(y(i)) + atol
475 ! 2 scalar array rtol*abs(y(i)) + atol(i)
476 ! 3 array scalar rtol(i)*abs(y(i)) + atol
477 ! 4 array array rtol(i)*abs(y(i)) + atol(i)
479 ! when either of these parameters is a scalar, it need not
480 ! be dimensioned in the user's calling program.
482 ! if none of the above choices (with itol, rtol, and atol
483 ! fixed throughout the problem) is suitable, more general
484 ! error controls can be obtained by substituting
485 ! user-supplied routines for the setting of ewt and/or for
486 ! the norm calculation. see part iv below.
488 ! if global errors are to be estimated by making a repeated
489 ! run on the same problem with smaller tolerances, then all
490 ! components of rtol and atol (i.e. of ewt) should be scaled
493 ! itask = an index specifying the task to be performed.
494 ! input only. itask has the following values and meanings.
495 ! 1 means normal computation of output values of y(t) at
496 ! t = tout (by overshooting and interpolating).
497 ! 2 means take one step only and return.
498 ! 3 means stop at the first internal mesh point at or
499 ! beyond t = tout and return.
500 ! 4 means normal computation of output values of y(t) at
501 ! t = tout but without overshooting t = tcrit.
502 ! tcrit must be input as rwork(1). tcrit may be equal to
503 ! or beyond tout, but not behind it in the direction of
504 ! integration. this option is useful if the problem
505 ! has a singularity at or beyond t = tcrit.
506 ! 5 means take one step, without passing tcrit, and return.
507 ! tcrit must be input as rwork(1).
509 ! note: if itask = 4 or 5 and the solver reaches tcrit
510 ! (within roundoff), it will return t = tcrit (exactly) to
511 ! indicate this (unless itask = 4 and tout comes before tcrit,
512 ! in which case answers at t = tout are returned first).
514 ! istate = an index used for input and output to specify the
515 ! the state of the calculation.
517 ! in the input, the values of istate are as follows.
518 ! 1 means this is the first call for the problem
519 ! (initializations will be done). see note below.
520 ! 2 means this is not the first call, and the calculation
521 ! is to continue normally, with no change in any input
522 ! parameters except possibly tout and itask.
523 ! (if itol, rtol, and/or atol are changed between calls
524 ! with istate = 2, the new values will be used but not
525 ! tested for legality.)
526 ! 3 means this is not the first call, and the
527 ! calculation is to continue normally, but with
528 ! a change in input parameters other than
529 ! tout and itask. changes are allowed in
530 ! neq, itol, rtol, atol, iopt, lrw, liw, mf, ml, mu,
531 ! and any of the optional input except h0.
532 ! (see iwork description for ml and mu.)
533 ! note: a preliminary call with tout = t is not counted
534 ! as a first call here, as no initialization or checking of
535 ! input is done. (such a call is sometimes useful to include
536 ! the initial conditions in the output.)
537 ! thus the first call for which tout .ne. t requires
538 ! istate = 1 in the input.
540 ! in the output, istate has the following values and meanings.
541 ! 1 means nothing was done, as tout was equal to t with
542 ! istate = 1 in the input.
543 ! 2 means the integration was performed successfully.
544 ! -1 means an excessive amount of work (more than mxstep
545 ! steps) was done on this call, before completing the
546 ! requested task, but the integration was otherwise
547 ! successful as far as t. (mxstep is an optional input
548 ! and is normally 500.) to continue, the user may
549 ! simply reset istate to a value .gt. 1 and call again.
550 ! (the excess work step counter will be reset to 0.)
551 ! in addition, the user may increase mxstep to avoid
552 ! this error return. (see optional input below.)
553 ! -2 means too much accuracy was requested for the precision
554 ! of the machine being used. this was detected before
555 ! completing the requested task, but the integration
556 ! was successful as far as t. to continue, the tolerance
557 ! parameters must be reset, and istate must be set
558 ! to 3. the optional output tolsf may be used for this
559 ! purpose. (note: if this condition is detected before
560 ! taking any steps, then an illegal input return
561 ! (istate = -3) occurs instead.)
562 ! -3 means illegal input was detected, before taking any
563 ! integration steps. see written message for details.
564 ! note: if the solver detects an infinite loop of calls
565 ! to the solver with illegal input, it will cause
567 ! -4 means there were repeated error test failures on
568 ! one attempted step, before completing the requested
569 ! task, but the integration was successful as far as t.
570 ! the problem may have a singularity, or the input
571 ! may be inappropriate.
572 ! -5 means there were repeated convergence test failures on
573 ! one attempted step, before completing the requested
574 ! task, but the integration was successful as far as t.
575 ! this may be caused by an inaccurate jacobian matrix,
576 ! if one is being used.
577 ! -6 means ewt(i) became zero for some i during the
578 ! integration. pure relative error control (atol(i)=0.0)
579 ! was requested on a variable which has now vanished.
580 ! the integration was successful as far as t.
582 ! note: since the normal output value of istate is 2,
583 ! it does not need to be reset for normal continuation.
584 ! also, since a negative input value of istate will be
585 ! regarded as illegal, a negative output value requires the
586 ! user to change it, and possibly other input, before
587 ! calling the solver again.
589 ! iopt = an integer flag to specify whether or not any optional
590 ! input is being used on this call. input only.
591 ! the optional input is listed separately below.
592 ! iopt = 0 means no optional input is being used.
593 ! default values will be used in all cases.
594 ! iopt = 1 means optional input is being used.
596 ! rwork = a real working array (double precision).
597 ! the length of rwork must be at least
598 ! 20 + nyh*(maxord + 1) + 3*neq + lwm where
599 ! nyh = the initial value of neq,
600 ! maxord = 12 (if meth = 1) or 5 (if meth = 2) (unless a
601 ! smaller value is given as an optional input),
602 ! lwm = length of work space for matrix-related data:
603 ! lwm = 0 if miter = 0,
604 ! lwm = 2*neq**2 + 2 if miter = 1 or 2, and mf.gt.0,
605 ! lwm = neq**2 + 2 if miter = 1 or 2, and mf.lt.0,
606 ! lwm = neq + 2 if miter = 3,
607 ! lwm = (3*ml+2*mu+2)*neq + 2 if miter = 4 or 5, and mf.gt.0,
608 ! lwm = (2*ml+mu+1)*neq + 2 if miter = 4 or 5, and mf.lt.0.
609 ! (see the mf description for meth and miter.)
610 ! thus if maxord has its default value and neq is constant,
612 ! 20 + 16*neq for mf = 10,
613 ! 22 + 16*neq + 2*neq**2 for mf = 11 or 12,
614 ! 22 + 16*neq + neq**2 for mf = -11 or -12,
615 ! 22 + 17*neq for mf = 13,
616 ! 22 + 18*neq + (3*ml+2*mu)*neq for mf = 14 or 15,
617 ! 22 + 17*neq + (2*ml+mu)*neq for mf = -14 or -15,
618 ! 20 + 9*neq for mf = 20,
619 ! 22 + 9*neq + 2*neq**2 for mf = 21 or 22,
620 ! 22 + 9*neq + neq**2 for mf = -21 or -22,
621 ! 22 + 10*neq for mf = 23,
622 ! 22 + 11*neq + (3*ml+2*mu)*neq for mf = 24 or 25.
623 ! 22 + 10*neq + (2*ml+mu)*neq for mf = -24 or -25.
624 ! the first 20 words of rwork are reserved for conditional
625 ! and optional input and optional output.
627 ! the following word in rwork is a conditional input:
628 ! rwork(1) = tcrit = critical value of t which the solver
629 ! is not to overshoot. required if itask is
630 ! 4 or 5, and ignored otherwise. (see itask.)
632 ! lrw = the length of the array rwork, as declared by the user.
633 ! (this will be checked by the solver.)
635 ! iwork = an integer work array. the length of iwork must be at least
636 ! 30 if miter = 0 or 3 (mf = 10, 13, 20, 23), or
637 ! 30 + neq otherwise (abs(mf) = 11,12,14,15,21,22,24,25).
638 ! the first 30 words of iwork are reserved for conditional and
639 ! optional input and optional output.
641 ! the following 2 words in iwork are conditional input:
642 ! iwork(1) = ml these are the lower and upper
643 ! iwork(2) = mu half-bandwidths, respectively, of the
644 ! banded jacobian, excluding the main diagonal.
645 ! the band is defined by the matrix locations
646 ! (i,j) with i-ml .le. j .le. i+mu. ml and mu
647 ! must satisfy 0 .le. ml,mu .le. neq-1.
648 ! these are required if miter is 4 or 5, and
649 ! ignored otherwise. ml and mu may in fact be
650 ! the band parameters for a matrix to which
651 ! df/dy is only approximately equal.
653 ! liw = the length of the array iwork, as declared by the user.
654 ! (this will be checked by the solver.)
656 ! note: the work arrays must not be altered between calls to dvode
657 ! for the same problem, except possibly for the conditional and
658 ! optional input, and except for the last 3*neq words of rwork.
659 ! the latter space is used for internal scratch space, and so is
660 ! available for use by the user outside dvode between calls, if
661 ! desired (but not for use by f or jac).
663 ! jac = the name of the user-supplied routine (miter = 1 or 4) to
664 ! compute the jacobian matrix, df/dy, as a function of
665 ! the scalar t and the vector y. it is to have the form
666 ! subroutine jac (neq, t, y, ml, mu, pd, nrowpd,
668 ! double precision t, y(neq), pd(nrowpd,neq), rpar
669 ! where neq, t, y, ml, mu, and nrowpd are input and the array
670 ! pd is to be loaded with partial derivatives (elements of the
671 ! jacobian matrix) in the output. pd must be given a first
672 ! dimension of nrowpd. t and y have the same meaning as in
674 ! in the full matrix case (miter = 1), ml and mu are
675 ! ignored, and the jacobian is to be loaded into pd in
676 ! columnwise manner, with df(i)/dy(j) loaded into pd(i,j).
677 ! in the band matrix case (miter = 4), the elements
678 ! within the band are to be loaded into pd in columnwise
679 ! manner, with diagonal lines of df/dy loaded into the rows
680 ! of pd. thus df(i)/dy(j) is to be loaded into pd(i-j+mu+1,j).
681 ! ml and mu are the half-bandwidth parameters. (see iwork).
682 ! the locations in pd in the two triangular areas which
683 ! correspond to nonexistent matrix elements can be ignored
684 ! or loaded arbitrarily, as they are overwritten by dvode.
685 ! jac need not provide df/dy exactly. a crude
686 ! approximation (possibly with a smaller bandwidth) will do.
687 ! in either case, pd is preset to zero by the solver,
688 ! so that only the nonzero elements need be loaded by jac.
689 ! each call to jac is preceded by a call to f with the same
690 ! arguments neq, t, and y. thus to gain some efficiency,
691 ! intermediate quantities shared by both calculations may be
692 ! saved in a user common block by f and not recomputed by jac,
693 ! if desired. also, jac may alter the y array, if desired.
694 ! jac must be declared external in the calling program.
695 ! subroutine jac may access user-defined real and integer
696 ! work arrays, rpar and ipar, whose dimensions are set by the
697 ! user in the main program.
699 ! mf = the method flag. used only for input. the legal values of
700 ! mf are 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25,
701 ! -11, -12, -14, -15, -21, -22, -24, -25.
702 ! mf is a signed two-digit integer, mf = jsv*(10*meth + miter).
703 ! jsv = sign(mf) indicates the jacobian-saving strategy:
704 ! jsv = 1 means a copy of the jacobian is saved for reuse
705 ! in the corrector iteration algorithm.
706 ! jsv = -1 means a copy of the jacobian is not saved
707 ! (valid only for miter = 1, 2, 4, or 5).
708 ! meth indicates the basic linear multistep method:
709 ! meth = 1 means the implicit adams method.
710 ! meth = 2 means the method based on backward
711 ! differentiation formulas (bdf-s).
712 ! miter indicates the corrector iteration method:
713 ! miter = 0 means functional iteration (no jacobian matrix
715 ! miter = 1 means chord iteration with a user-supplied
716 ! full (neq by neq) jacobian.
717 ! miter = 2 means chord iteration with an internally
718 ! generated (difference quotient) full jacobian
719 ! (using neq extra calls to f per df/dy value).
720 ! miter = 3 means chord iteration with an internally
721 ! generated diagonal jacobian approximation
722 ! (using 1 extra call to f per df/dy evaluation).
723 ! miter = 4 means chord iteration with a user-supplied
725 ! miter = 5 means chord iteration with an internally
726 ! generated banded jacobian (using ml+mu+1 extra
727 ! calls to f per df/dy evaluation).
728 ! if miter = 1 or 4, the user must supply a subroutine jac
729 ! (the name is arbitrary) as described above under jac.
730 ! for other values of miter, a dummy argument can be used.
732 ! rpar user-specified array used to communicate real parameters
733 ! to user-supplied subroutines. if rpar is a vector, then
734 ! it must be dimensioned in the user's main program. if it
735 ! is unused or it is a scalar, then it need not be
738 ! ipar user-specified array used to communicate integer parameter
739 ! to user-supplied subroutines. the comments on dimensioning
740 ! rpar apply to ipar.
741 !-----------------------------------------------------------------------
744 ! the following is a list of the optional input provided for in the
745 ! call sequence. (see also part ii.) for each such input variable,
746 ! this table lists its name as used in this documentation, its
747 ! location in the call sequence, its meaning, and the default value.
748 ! the use of any of this input requires iopt = 1, and in that
749 ! case all of this input is examined. a value of zero for any
750 ! of these optional input variables will cause the default value to be
751 ! used. thus to use a subset of the optional input, simply preload
752 ! locations 5 to 10 in rwork and iwork to 0.0 and 0 respectively, and
753 ! then set those of interest to nonzero values.
755 ! name location meaning and default value
757 ! h0 rwork(5) the step size to be attempted on the first step.
758 ! the default value is determined by the solver.
760 ! hmax rwork(6) the maximum absolute step size allowed.
761 ! the default value is infinite.
763 ! hmin rwork(7) the minimum absolute step size allowed.
764 ! the default value is 0. (this lower bound is not
765 ! enforced on the final step before reaching tcrit
766 ! when itask = 4 or 5.)
768 ! maxord iwork(5) the maximum order to be allowed. the default
769 ! value is 12 if meth = 1, and 5 if meth = 2.
770 ! if maxord exceeds the default value, it will
771 ! be reduced to the default value.
772 ! if maxord is changed during the problem, it may
773 ! cause the current order to be reduced.
775 ! mxstep iwork(6) maximum number of (internally defined) steps
776 ! allowed during one call to the solver.
777 ! the default value is 500.
779 ! mxhnil iwork(7) maximum number of messages printed (per problem)
780 ! warning that t + h = t on a step (h = step size).
781 ! this must be positive to result in a non-default
782 ! value. the default value is 10.
784 !-----------------------------------------------------------------------
787 ! as optional additional output from dvode, the variables listed
788 ! below are quantities related to the performance of dvode
789 ! which are available to the user. these are communicated by way of
790 ! the work arrays, but also have internal mnemonic names as shown.
791 ! except where stated otherwise, all of this output is defined
792 ! on any successful return from dvode, and on any return with
793 ! istate = -1, -2, -4, -5, or -6. on an illegal input return
794 ! (istate = -3), they will be unchanged from their existing values
795 ! (if any), except possibly for tolsf, lenrw, and leniw.
796 ! on any error return, output relevant to the error will be defined,
799 ! name location meaning
801 ! hu rwork(11) the step size in t last used (successfully).
803 ! hcur rwork(12) the step size to be attempted on the next step.
805 ! tcur rwork(13) the current value of the independent variable
806 ! which the solver has actually reached, i.e. the
807 ! current internal mesh point in t. in the output,
808 ! tcur will always be at least as far from the
809 ! initial value of t as the current argument t,
810 ! but may be farther (if interpolation was done).
812 ! tolsf rwork(14) a tolerance scale factor, greater than 1.0,
813 ! computed when a request for too much accuracy was
814 ! detected (istate = -3 if detected at the start of
815 ! the problem, istate = -2 otherwise). if itol is
816 ! left unaltered but rtol and atol are uniformly
817 ! scaled up by a factor of tolsf for the next call,
818 ! then the solver is deemed likely to succeed.
819 ! (the user may also ignore tolsf and alter the
820 ! tolerance parameters in any other way appropriate.)
822 ! nst iwork(11) the number of steps taken for the problem so far.
824 ! nfe iwork(12) the number of f evaluations for the problem so far.
826 ! nje iwork(13) the number of jacobian evaluations so far.
828 ! nqu iwork(14) the method order last used (successfully).
830 ! nqcur iwork(15) the order to be attempted on the next step.
832 ! imxer iwork(16) the index of the component of largest magnitude in
833 ! the weighted local error vector ( e(i)/ewt(i) ),
834 ! on an error return with istate = -4 or -5.
836 ! lenrw iwork(17) the length of rwork actually required.
837 ! this is defined on normal returns and on an illegal
838 ! input return for insufficient storage.
840 ! leniw iwork(18) the length of iwork actually required.
841 ! this is defined on normal returns and on an illegal
842 ! input return for insufficient storage.
844 ! nlu iwork(19) the number of matrix lu decompositions so far.
846 ! nni iwork(20) the number of nonlinear (newton) iterations so far.
848 ! ncfn iwork(21) the number of convergence failures of the nonlinear
851 ! netf iwork(22) the number of error test failures of the integrator
854 ! the following two arrays are segments of the rwork array which
855 ! may also be of interest to the user as optional output.
856 ! for each array, the table below gives its internal name,
857 ! its base address in rwork, and its description.
859 ! name base address description
861 ! yh 21 the nordsieck history array, of size nyh by
862 ! (nqcur + 1), where nyh is the initial value
863 ! of neq. for j = 0,1,...,nqcur, column j+1
864 ! of yh contains hcur**j/factorial(j) times
865 ! the j-th derivative of the interpolating
866 ! polynomial currently representing the
867 ! solution, evaluated at t = tcur.
869 ! acor lenrw-neq+1 array of size neq used for the accumulated
870 ! corrections on each step, scaled in the output
871 ! to represent the estimated local error in y
872 ! on the last step. this is the vector e in
873 ! the description of the error control. it is
874 ! defined only on a successful return from dvode.
876 !-----------------------------------------------------------------------
877 ! interrupting and restarting
879 ! if the integration of a given problem by dvode is to be
880 ! interrrupted and then later continued, such as when restarting
881 ! an interrupted run or alternating between two or more ode problems,
882 ! the user should save, following the return from the last dvode call
883 ! prior to the interruption, the contents of the call sequence
884 ! variables and internal common blocks, and later restore these
885 ! values before the next dvode call for that problem. to save
886 ! and restore the common blocks, use subroutine dvsrco, as
887 ! described below in part ii.
889 ! in addition, if non-default values for either lun or mflag are
890 ! desired, an extra call to xsetun and/or xsetf should be made just
891 ! before continuing the integration. see part ii below for details.
893 !-----------------------------------------------------------------------
894 ! part ii. other routines callable.
896 ! the following are optional calls which the user may make to
897 ! gain additional capabilities in conjunction with dvode.
898 ! (the routines xsetun and xsetf are designed to conform to the
899 ! slatec error handling package.)
901 ! form of call function
902 ! call xsetun(lun) set the logical unit number, lun, for
903 ! output of messages from dvode, if
904 ! the default is not desired.
905 ! the default value of lun is 6.
907 ! call xsetf(mflag) set a flag to control the printing of
909 ! mflag = 0 means do not print. (danger:
910 ! this risks losing valuable information.)
911 ! mflag = 1 means print (the default).
913 ! either of the above calls may be made at
914 ! any time and will take effect immediately.
916 ! call dvsrco(rsav,isav,job) saves and restores the contents of
917 ! the internal common blocks used by
918 ! dvode. (see part iii below.)
919 ! rsav must be a real array of length 49
920 ! or more, and isav must be an integer
921 ! array of length 40 or more.
922 ! job=1 means save common into rsav/isav.
923 ! job=2 means restore common from rsav/isav.
924 ! dvsrco is useful if one is
925 ! interrupting a run and restarting
926 ! later, or alternating between two or
927 ! more problems solved with dvode.
929 ! call dvindy(,,,,,) provide derivatives of y, of various
930 ! (see below.) orders, at a specified point t, if
931 ! desired. it may be called only after
932 ! a successful return from dvode.
934 ! the detailed instructions for using dvindy are as follows.
935 ! the form of the call is:
937 ! call dvindy (t, k, rwork(21), nyh, dky, iflag)
939 ! the input parameters are:
941 ! t = value of independent variable where answers are desired
942 ! (normally the same as the t last returned by dvode).
943 ! for valid results, t must lie between tcur - hu and tcur.
944 ! (see optional output for tcur and hu.)
945 ! k = integer order of the derivative desired. k must satisfy
946 ! 0 .le. k .le. nqcur, where nqcur is the current order
947 ! (see optional output). the capability corresponding
948 ! to k = 0, i.e. computing y(t), is already provided
949 ! by dvode directly. since nqcur .ge. 1, the first
950 ! derivative dy/dt is always available with dvindy.
951 ! rwork(21) = the base address of the history array yh.
952 ! nyh = column length of yh, equal to the initial value of neq.
954 ! the output parameters are:
956 ! dky = a real array of length neq containing the computed value
957 ! of the k-th derivative of y(t).
958 ! iflag = integer flag, returned as 0 if k and t were legal,
959 ! -1 if k was illegal, and -2 if t was illegal.
960 ! on an error return, a message is also written.
961 !-----------------------------------------------------------------------
962 ! part iii. common blocks.
963 ! if dvode is to be used in an overlay situation, the user
964 ! must declare, in the primary overlay, the variables in:
965 ! (1) the call sequence to dvode,
966 ! (2) the two internal common blocks
967 ! /dvod_cmn01/ of length 81 (48 double precision words
968 ! followed by 33 integer words),
969 ! /dvod_cmn02/ of length 9 (1 double precision word
970 ! followed by 8 integer words),
972 ! if dvode is used on a system in which the contents of internal
973 ! common blocks are not preserved between calls, the user should
974 ! declare the above two common blocks in his main program to insure
975 ! that their contents are preserved.
977 !-----------------------------------------------------------------------
978 ! part iv. optionally replaceable solver routines.
980 ! below are descriptions of two routines in the dvode package which
981 ! relate to the measurement of errors. either routine can be
982 ! replaced by a user-supplied version, if desired. however, since such
983 ! a replacement may have a major impact on performance, it should be
984 ! done only when absolutely necessary, and only with great caution.
985 ! (note: the means by which the package version of a routine is
986 ! superseded by the user's version may be system-dependent.)
989 ! the following subroutine is called just before each internal
990 ! integration step, and sets the array of error weights, ewt, as
991 ! described under itol/rtol/atol above:
992 ! subroutine dewset (neq, itol, rtol, atol, ycur, ewt)
993 ! where neq, itol, rtol, and atol are as in the dvode call sequence,
994 ! ycur contains the current dependent variable vector, and
995 ! ewt is the array of weights set by dewset.
997 ! if the user supplies this subroutine, it must return in ewt(i)
998 ! (i = 1,...,neq) a positive quantity suitable for comparison with
999 ! errors in y(i). the ewt array returned by dewset is passed to the
1000 ! dvnorm routine (see below.), and also used by dvode in the computation
1001 ! of the optional output imxer, the diagonal jacobian approximation,
1002 ! and the increments for difference quotient jacobians.
1004 ! in the user-supplied version of dewset, it may be desirable to use
1005 ! the current values of derivatives of y. derivatives up to order nq
1006 ! are available from the history array yh, described above under
1007 ! optional output. in dewset, yh is identical to the ycur array,
1008 ! extended to nq + 1 columns with a column length of nyh and scale
1009 ! factors of h**j/factorial(j). on the first call for the problem,
1010 ! given by nst = 0, nq is 1 and h is temporarily set to 1.0.
1011 ! nyh is the initial value of neq. the quantities nq, h, and nst
1012 ! can be obtained by including in dewset the statements:
1013 ! double precision rvod, h, hu
1014 ! common /dvod_cmn01/ rvod(48), ivod(33)
1015 ! common /dvod_cmn02/ hu, ncfn, netf, nfe, nje, nlu, nni, nqu, nst
1018 ! thus, for example, the current value of dy/dt can be obtained as
1019 ! ycur(nyh+i)/h (i=1,...,neq) (and the division by h is
1020 ! unnecessary when nst = 0).
1023 ! the following is a real function routine which computes the weighted
1024 ! root-mean-square norm of a vector v:
1025 ! d = dvnorm (n, v, w)
1027 ! n = the length of the vector,
1028 ! v = real array of length n containing the vector,
1029 ! w = real array of length n containing weights,
1030 ! d = sqrt( (1/n) * sum(v(i)*w(i))**2 ).
1031 ! dvnorm is called with n = neq and with w(i) = 1.0/ewt(i), where
1032 ! ewt is as set by subroutine dewset.
1034 ! if the user supplies this function, it should return a non-negative
1035 ! value of dvnorm suitable for use in the error control in dvode.
1036 ! none of the arguments should be altered by dvnorm.
1037 ! for example, a user-supplied dvnorm routine might:
1038 ! -substitute a max-norm of (v(i)*w(i)) for the rms-norm, or
1039 ! -ignore some components of v in the norm, with the effect of
1040 ! suppressing the error control on those components of y.
1041 !-----------------------------------------------------------------------
1042 ! revision history (yyyymmdd)
1043 ! 19890615 date written. initial release.
1044 ! 19890922 added interrupt/restart ability, minor changes throughout.
1045 ! 19910228 minor revisions in line format, prologue, etc.
1046 ! 19920227 modifications by d. pang:
1047 ! (1) applied subgennam to get generic intrinsic names.
1048 ! (2) changed intrinsic names to generic in comments.
1049 ! (3) added *deck lines before each routine.
1050 ! 19920721 names of routines and labeled common blocks changed, so as
1051 ! to be unique in combined single/double precision code (ach).
1052 ! 19920722 minor revisions to prologue (ach).
1053 ! 19920831 conversion to double precision done (ach).
1054 ! 19921106 fixed minor bug: etaq,etaqm1 in dvstep save statement (ach).
1055 ! 19921118 changed lunsav/mflgsv to ixsav (ach).
1056 ! 19941222 removed mf overwrite; attached sign to h in estimated second
1057 ! deriv. in dvhin; misc. comment changes throughout (ach).
1058 ! 19970515 minor corrections to comments in prologue, dvjac (ach).
1059 ! 19981111 corrected block b by adding final line, go to 200 (ach).
1060 ! 20020430 various upgrades (ach): use odepack error handler package.
1061 ! replaced d1mach by dumach. various changes to main
1062 ! prologue and other routine prologues.
1063 !-----------------------------------------------------------------------
1064 ! other routines in the dvode package.
1066 ! in addition to subroutine dvode, the dvode package includes the
1067 ! following subroutines and function routines:
1068 ! dvhin computes an approximate step size for the initial step.
1069 ! dvindy computes an interpolated value of the y vector at t = tout.
1070 ! dvstep is the core integrator, which does one step of the
1071 ! integration and the associated error control.
1072 ! dvset sets all method coefficients and test constants.
1073 ! dvnlsd solves the underlying nonlinear system -- the corrector.
1074 ! dvjac computes and preprocesses the jacobian matrix j = df/dy
1075 ! and the newton iteration matrix p = i - (h/l1)*j.
1076 ! dvsol manages solution of linear system in chord iteration.
1077 ! dvjust adjusts the history array on a change of order.
1078 ! dewset sets the error weight vector ewt before each step.
1079 ! dvnorm computes the weighted r.m.s. norm of a vector.
1080 ! dvsrco is a user-callable routine to save and restore
1081 ! the contents of the internal common blocks.
1082 ! dacopy is a routine to copy one two-dimensional array to another.
1083 ! dgefa and dgesl are routines from linpack for solving full
1084 ! systems of linear algebraic equations.
1085 ! dgbfa and dgbsl are routines from linpack for solving banded
1087 ! daxpy, dscal, and dcopy are basic linear algebra modules (blas).
1088 ! dumach sets the unit roundoff of the machine.
1089 ! xerrwd, xsetun, xsetf, ixsav, and iumach handle the printing of all
1090 ! error messages and warnings. xerrwd is machine-dependent.
1091 ! note: dvnorm, dumach, ixsav, and iumach are function routines.
1092 ! all the others are subroutines.
1094 !-----------------------------------------------------------------------
1096 !! type declarations for labeled common block dvod_cmn01 --------------------
1098 ! double precision acnrm, ccmxj, conp, crate, drc, el, &
1099 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
1100 ! rc, rl1, tau, tq, tn, uround
1101 ! integer icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
1102 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
1103 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
1104 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
1107 !! type declarations for labeled common block dvod_cmn02 --------------------
1109 ! double precision hu
1110 ! integer ncfn, netf, nfe, nje, nlu, nni, nqu, nst
1112 ! type declarations for local variables --------------------------------
1114 ! 27-oct-2005 rce - do not declare functions that are in the module
1117 double precision atoli, big, ewti, four, h0, hmax, hmx, hun, one, &
1118 pt2, rh, rtoli, size, tcrit, tnext, tolsf, tp, two, zero
1119 integer i, ier, iflag, imxer, jco, kgo, leniw, lenj, lenp, lenrw, &
1120 lenwm, lf0, mband, mfa, ml, mord, mu, mxhnl0, mxstp0, niter, &
1124 ! type declaration for function subroutines called ---------------------
1126 ! 27-oct-2005 rce - do not declare functions that are in the module
1127 ! double precision dumach, dvnorm
1130 !-----------------------------------------------------------------------
1131 ! the following fortran-77 declaration is to cause the values of the
1132 ! listed (local) variables to be saved between calls to dvode.
1133 !-----------------------------------------------------------------------
1134 save mord, mxhnl0, mxstp0
1135 save zero, one, two, four, pt2, hun
1136 !-----------------------------------------------------------------------
1137 ! the following internal common blocks contain variables which are
1138 ! communicated between subroutines in the dvode package, or which are
1139 ! to be saved between calls to dvode.
1140 ! in each block, real variables precede integers.
1141 ! the block /dvod_cmn01/ appears in subroutines dvode, dvindy, dvstep,
1142 ! dvset, dvnlsd, dvjac, dvsol, dvjust and dvsrco.
1143 ! the block /dvod_cmn02/ appears in subroutines dvode, dvindy, dvstep,
1144 ! dvnlsd, dvjac, and dvsrco.
1146 ! the variables stored in the internal common blocks are as follows:
1148 ! acnrm = weighted r.m.s. norm of accumulated correction vectors.
1149 ! ccmxj = threshhold on drc for updating the jacobian. (see drc.)
1150 ! conp = the saved value of tq(5).
1151 ! crate = estimated corrector convergence rate constant.
1152 ! drc = relative change in h*rl1 since last dvjac call.
1153 ! el = real array of integration coefficients. see dvset.
1154 ! eta = saved tentative ratio of new to old h.
1155 ! etamax = saved maximum value of eta to be allowed.
1156 ! h = the step size.
1157 ! hmin = the minimum absolute value of the step size h to be used.
1158 ! hmxi = inverse of the maximum absolute value of h to be used.
1159 ! hmxi = 0.0 is allowed and corresponds to an infinite hmax.
1160 ! hnew = the step size to be attempted on the next step.
1161 ! hscal = stepsize in scaling of yh array.
1162 ! prl1 = the saved value of rl1.
1163 ! rc = ratio of current h*rl1 to value on last dvjac call.
1164 ! rl1 = the reciprocal of the coefficient el(1).
1165 ! tau = real vector of past nq step sizes, length 13.
1166 ! tq = a real vector of length 5 in which dvset stores constants
1167 ! used for the convergence test, the error test, and the
1168 ! selection of h at a new order.
1169 ! tn = the independent variable, updated on each step taken.
1170 ! uround = the machine unit roundoff. the smallest positive real number
1171 ! such that 1.0 + uround .ne. 1.0
1172 ! icf = integer flag for convergence failure in dvnlsd:
1173 ! 0 means no failures.
1174 ! 1 means convergence failure with out of date jacobian
1175 ! (recoverable error).
1176 ! 2 means convergence failure with current jacobian or
1177 ! singular matrix (unrecoverable error).
1178 ! init = saved integer flag indicating whether initialization of the
1179 ! problem has been done (init = 1) or not.
1180 ! ipup = saved flag to signal updating of newton matrix.
1181 ! jcur = output flag from dvjac showing jacobian status:
1182 ! jcur = 0 means j is not current.
1183 ! jcur = 1 means j is current.
1184 ! jstart = integer flag used as input to dvstep:
1185 ! 0 means perform the first step.
1186 ! 1 means take a new step continuing from the last.
1187 ! -1 means take the next step with a new value of maxord,
1188 ! hmin, hmxi, n, meth, miter, and/or matrix parameters.
1189 ! on return, dvstep sets jstart = 1.
1190 ! jsv = integer flag for jacobian saving, = sign(mf).
1191 ! kflag = a completion code from dvstep with the following meanings:
1192 ! 0 the step was succesful.
1193 ! -1 the requested error could not be achieved.
1194 ! -2 corrector convergence could not be achieved.
1195 ! -3, -4 fatal error in vnls (can not occur here).
1196 ! kuth = input flag to dvstep showing whether h was reduced by the
1197 ! driver. kuth = 1 if h was reduced, = 0 otherwise.
1198 ! l = integer variable, nq + 1, current order plus one.
1199 ! lmax = maxord + 1 (used for dimensioning).
1200 ! locjs = a pointer to the saved jacobian, whose storage starts at
1201 ! wm(locjs), if jsv = 1.
1202 ! lyh, lewt, lacor, lsavf, lwm, liwm = saved integer pointers
1203 ! to segments of rwork and iwork.
1204 ! maxord = the maximum order of integration method to be allowed.
1205 ! meth/miter = the method flags. see mf.
1206 ! msbj = the maximum number of steps between j evaluations, = 50.
1207 ! mxhnil = saved value of optional input mxhnil.
1208 ! mxstep = saved value of optional input mxstep.
1209 ! n = the number of first-order odes, = neq.
1210 ! newh = saved integer to flag change of h.
1211 ! newq = the method order to be used on the next step.
1212 ! nhnil = saved counter for occurrences of t + h = t.
1213 ! nq = integer variable, the current integration method order.
1214 ! nqnyh = saved value of nq*nyh.
1215 ! nqwait = a counter controlling the frequency of order changes.
1216 ! an order change is about to be considered if nqwait = 1.
1217 ! nslj = the number of steps taken as of the last jacobian update.
1218 ! nslp = saved value of nst as of last newton matrix update.
1219 ! nyh = saved value of the initial value of neq.
1220 ! hu = the step size in t last used.
1221 ! ncfn = number of nonlinear convergence failures so far.
1222 ! netf = the number of error test failures of the integrator so far.
1223 ! nfe = the number of f evaluations for the problem so far.
1224 ! nje = the number of jacobian evaluations so far.
1225 ! nlu = the number of matrix lu decompositions so far.
1226 ! nni = number of nonlinear iterations so far.
1227 ! nqu = the method order last used.
1228 ! nst = the number of steps taken for the problem so far.
1229 !-----------------------------------------------------------------------
1230 ! common /dvod_cmn01/ acnrm, ccmxj, conp, crate, drc, el(13), &
1231 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
1232 ! rc, rl1, tau(13), tq(5), tn, uround, &
1233 ! icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
1234 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
1235 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
1236 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
1238 ! common /dvod_cmn02/ hu, ncfn, netf, nfe, nje, nlu, nni, nqu, nst
1240 ! in this routine only, declare h and n as local variables
1241 ! before/after calls where cmn12 is passed as an argument,
1242 ! load/unload them to/from cmn12
1243 type( dvode_cmn_vars ) :: cmn12
1248 data mord(1) /12/, mord(2) /5/, mxstp0 /500/, mxhnl0 /10/
1249 data zero /0.0d0/, one /1.0d0/, two /2.0d0/, four /4.0d0/, &
1250 pt2 /0.2d0/, hun /100.0d0/
1251 !-----------------------------------------------------------------------
1253 ! this code block is executed on every call.
1254 ! it tests istate and itask for legality and branches appropriately.
1255 ! if istate .gt. 1 but the flag init shows that initialization has
1256 ! not yet been done, an error return occurs.
1257 ! if istate = 1 and tout = t, return immediately.
1258 !-----------------------------------------------------------------------
1260 ! in this modified-for-wrf version of dvode, istate must be 1
1261 if (istate .ne. 1) then
1262 msg = '*** module_cmu_dvode_solver/dvode -- ' // &
1263 'fatal error, istate must be 1'
1264 call wrf_error_fatal( msg )
1267 if (istate .lt. 1 .or. istate .gt. 3) go to 601
1268 if (itask .lt. 1 .or. itask .gt. 5) go to 602
1269 if (istate .eq. 1) go to 10
1270 if (cmn12%init .ne. 1) go to 603
1271 if (istate .eq. 2) go to 200
1274 if (tout .eq. t) return
1275 !-----------------------------------------------------------------------
1277 ! the next code block is executed for the initial call (istate = 1),
1278 ! or for a continuation call with parameter changes (istate = 3).
1279 ! it contains checking of all input and various initializations.
1281 ! first check legality of the non-optional input neq, itol, iopt,
1283 !-----------------------------------------------------------------------
1284 20 if (neq .le. 0) go to 604
1285 if (istate .eq. 1) go to 25
1286 if (neq .gt. n) go to 605
1288 if (itol .lt. 1 .or. itol .gt. 4) go to 606
1289 if (iopt .lt. 0 .or. iopt .gt. 1) go to 607
1290 cmn12%jsv = sign(1,mf)
1293 cmn12%miter = mfa - 10*cmn12%meth
1294 if (cmn12%meth .lt. 1 .or. cmn12%meth .gt. 2) go to 608
1295 if (cmn12%miter .lt. 0 .or. cmn12%miter .gt. 5) go to 608
1296 if (cmn12%miter .le. 3) go to 30
1299 if (ml .lt. 0 .or. ml .ge. n) go to 609
1300 if (mu .lt. 0 .or. mu .ge. n) go to 610
1302 ! next process and check the optional input. ---------------------------
1303 if (iopt .eq. 1) go to 40
1304 cmn12%maxord = mord(cmn12%meth)
1305 cmn12%mxstep = mxstp0
1306 cmn12%mxhnil = mxhnl0
1307 if (istate .eq. 1) h0 = zero
1311 40 cmn12%maxord = iwork(5)
1312 if (cmn12%maxord .lt. 0) go to 611
1313 if (cmn12%maxord .eq. 0) cmn12%maxord = 100
1314 cmn12%maxord = min(cmn12%maxord,mord(cmn12%meth))
1315 cmn12%mxstep = iwork(6)
1316 if (cmn12%mxstep .lt. 0) go to 612
1317 if (cmn12%mxstep .eq. 0) cmn12%mxstep = mxstp0
1318 cmn12%mxhnil = iwork(7)
1319 if (cmn12%mxhnil .lt. 0) go to 613
1320 if (cmn12%mxhnil .eq. 0) cmn12%mxhnil = mxhnl0
1321 if (istate .ne. 1) go to 50
1323 if ((tout - t)*h0 .lt. zero) go to 614
1325 if (hmax .lt. zero) go to 615
1327 if (hmax .gt. zero) cmn12%hmxi = one/hmax
1328 cmn12%hmin = rwork(7)
1329 if (cmn12%hmin .lt. zero) go to 616
1330 !-----------------------------------------------------------------------
1331 ! set work array pointers and check lengths lrw and liw.
1332 ! pointers to segments of rwork and iwork are named by prefixing l to
1333 ! the name of the segment. e.g., the segment yh starts at rwork(lyh).
1334 ! segments of rwork (in order) are denoted yh, wm, ewt, savf, acor.
1335 ! within wm, locjs is the location of the saved jacobian (jsv .gt. 0).
1336 !-----------------------------------------------------------------------
1338 if (istate .eq. 1) cmn12%nyh = n
1339 cmn12%lwm = cmn12%lyh + (cmn12%maxord + 1)*cmn12%nyh
1340 jco = max(0,cmn12%jsv)
1341 if (cmn12%miter .eq. 0) lenwm = 0
1342 if (cmn12%miter .eq. 1 .or. cmn12%miter .eq. 2) then
1343 lenwm = 2 + (1 + jco)*n*n
1344 cmn12%locjs = n*n + 3
1346 if (cmn12%miter .eq. 3) lenwm = 2 + n
1347 if (cmn12%miter .eq. 4 .or. cmn12%miter .eq. 5) then
1349 lenp = (mband + ml)*n
1351 lenwm = 2 + lenp + jco*lenj
1352 cmn12%locjs = lenp + 3
1354 cmn12%lewt = cmn12%lwm + lenwm
1355 cmn12%lsavf = cmn12%lewt + n
1356 cmn12%lacor = cmn12%lsavf + n
1357 lenrw = cmn12%lacor + n - 1
1361 if (cmn12%miter .eq. 0 .or. cmn12%miter .eq. 3) leniw = 30
1363 if (lenrw .gt. lrw) go to 617
1364 if (leniw .gt. liw) go to 618
1365 ! check rtol and atol for legality. ------------------------------------
1369 if (itol .ge. 3) rtoli = rtol(i)
1370 if (itol .eq. 2 .or. itol .eq. 4) atoli = atol(i)
1371 if (rtoli .lt. zero) go to 619
1372 if (atoli .lt. zero) go to 620
1374 if (istate .eq. 1) go to 100
1375 ! if istate = 3, set flag to signal parameter changes to dvstep. -------
1377 if (cmn12%nq .le. cmn12%maxord) go to 90
1378 ! maxord was reduced below nq. copy yh(*,maxord+2) into savf. ---------
1379 call dcopy (n, rwork(cmn12%lwm), 1, rwork(cmn12%lsavf), 1)
1380 ! reload wm(1) = rwork(lwm), since lwm may have changed. ---------------
1381 90 if (cmn12%miter .gt. 0) rwork(cmn12%lwm) = sqrt(cmn12%uround)
1383 !-----------------------------------------------------------------------
1385 ! the next block is for the initial call only (istate = 1).
1386 ! it contains all remaining initializations, the initial call to f,
1387 ! and the calculation of the initial step size.
1388 ! the error weights in ewt are inverted after being loaded.
1389 !-----------------------------------------------------------------------
1390 100 cmn12%uround = dumach()
1392 if (itask .ne. 4 .and. itask .ne. 5) go to 110
1394 if ((tcrit - tout)*(tout - t) .lt. zero) go to 625
1395 if (h0 .ne. zero .and. (t + h0 - tcrit)*h0 .gt. zero) &
1397 110 cmn12%jstart = 0
1398 if (cmn12%miter .gt. 0) rwork(cmn12%lwm) = sqrt(cmn12%uround)
1412 ! initial call to f. (lf0 points to yh(*,2).) -------------------------
1413 lf0 = cmn12%lyh + cmn12%nyh
1414 call f (n, t, y, rwork(lf0), rpar, ipar)
1416 ! load the initial value vector in yh. ---------------------------------
1417 call dcopy (n, y, 1, rwork(cmn12%lyh), 1)
1418 ! load and invert the ewt array. (h is temporarily set to 1.0.) -------
1421 call dewset (n, itol, rtol, atol, rwork(cmn12%lyh), rwork(cmn12%lewt))
1423 if (rwork(i+cmn12%lewt-1) .le. zero) go to 621
1424 120 rwork(i+cmn12%lewt-1) = one/rwork(i+cmn12%lewt-1)
1425 if (h0 .ne. zero) go to 180
1426 ! call dvhin to set initial step size h0 to be attempted. --------------
1427 call dvhin (n, t, rwork(cmn12%lyh), rwork(lf0), f, rpar, ipar, tout, &
1428 cmn12%uround, rwork(cmn12%lewt), itol, atol, y, rwork(cmn12%lacor), h0, &
1430 cmn12%nfe = cmn12%nfe + niter
1431 if (ier .ne. 0) go to 622
1432 ! adjust h0 if necessary to meet hmax bound. ---------------------------
1433 180 rh = abs(h0)*cmn12%hmxi
1434 if (rh .gt. one) h0 = h0/rh
1435 ! load h with h0 and scale yh(*,2) by h0. ------------------------------
1437 call dscal (n, h0, rwork(lf0), 1)
1439 !-----------------------------------------------------------------------
1441 ! the next code block is for continuation calls only (istate = 2 or 3)
1442 ! and is to check stop conditions before taking a step.
1443 !-----------------------------------------------------------------------
1444 200 nslast = cmn12%nst
1446 go to (210, 250, 220, 230, 240), itask
1447 210 if ((cmn12%tn - tout)*h .lt. zero) go to 250
1448 cmn12%h = h ; cmn12%n = n ! load h, n into cmn12
1449 call dvindy (tout, 0, rwork(cmn12%lyh), cmn12%nyh, y, iflag, cmn12)
1450 h = cmn12%h ; n = cmn12%n ! unload h, n from cmn12
1451 if (iflag .ne. 0) go to 627
1454 220 tp = cmn12%tn - cmn12%hu*(one + hun*cmn12%uround)
1455 if ((tp - tout)*h .gt. zero) go to 623
1456 if ((cmn12%tn - tout)*h .lt. zero) go to 250
1458 230 tcrit = rwork(1)
1459 if ((cmn12%tn - tcrit)*h .gt. zero) go to 624
1460 if ((tcrit - tout)*h .lt. zero) go to 625
1461 if ((cmn12%tn - tout)*h .lt. zero) go to 245
1462 cmn12%h = h ; cmn12%n = n ! load h, n into cmn12
1463 call dvindy (tout, 0, rwork(cmn12%lyh), cmn12%nyh, y, iflag, cmn12)
1464 h = cmn12%h ; n = cmn12%n ! unload h, n from cmn12
1465 if (iflag .ne. 0) go to 627
1468 240 tcrit = rwork(1)
1469 if ((cmn12%tn - tcrit)*h .gt. zero) go to 624
1470 245 hmx = abs(cmn12%tn) + abs(h)
1471 ihit = abs(cmn12%tn - tcrit) .le. hun*cmn12%uround*hmx
1473 tnext = cmn12%tn + cmn12%hnew*(one + four*cmn12%uround)
1474 if ((tnext - tcrit)*h .le. zero) go to 250
1475 h = (tcrit - cmn12%tn)*(one - four*cmn12%uround)
1477 !-----------------------------------------------------------------------
1479 ! the next block is normally executed for all calls and contains
1480 ! the call to the one-step core integrator dvstep.
1482 ! this is a looping point for the integration steps.
1484 ! first check for too many steps being taken, update ewt (if not at
1485 ! start of problem), check for too much accuracy being requested, and
1486 ! check for h below the roundoff level in t.
1487 !-----------------------------------------------------------------------
1489 if ((cmn12%nst-nslast) .ge. cmn12%mxstep) go to 500
1490 call dewset (n, itol, rtol, atol, rwork(cmn12%lyh), rwork(cmn12%lewt))
1492 if (rwork(i+cmn12%lewt-1) .le. zero) go to 510
1493 260 rwork(i+cmn12%lewt-1) = one/rwork(i+cmn12%lewt-1)
1494 270 tolsf = cmn12%uround*dvnorm (n, rwork(cmn12%lyh), rwork(cmn12%lewt))
1495 if (tolsf .le. one) go to 280
1497 if (cmn12%nst .eq. 0) go to 626
1499 280 if ((cmn12%tn + h) .ne. cmn12%tn) go to 290
1500 cmn12%nhnil = cmn12%nhnil + 1
1501 if (cmn12%nhnil .gt. cmn12%mxhnil) go to 290
1502 msg = 'dvode-- warning: internal t (=r1) and h (=r2) are'
1503 call xerrwd (msg, 50, 101, 1, 0, 0, 0, 0, zero, zero)
1504 msg=' such that in the machine, t + h = t on the next step '
1505 call xerrwd (msg, 60, 101, 1, 0, 0, 0, 0, zero, zero)
1506 msg = ' (h = step size). solver will continue anyway'
1507 call xerrwd (msg, 50, 101, 1, 0, 0, 0, 2, cmn12%tn, h)
1508 if (cmn12%nhnil .lt. cmn12%mxhnil) go to 290
1509 msg = 'dvode-- above warning has been issued i1 times. '
1510 call xerrwd (msg, 50, 102, 1, 0, 0, 0, 0, zero, zero)
1511 msg = ' it will not be issued again for this problem'
1512 call xerrwd (msg, 50, 102, 1, 1, cmn12%mxhnil, 0, 0, zero, zero)
1514 !-----------------------------------------------------------------------
1515 ! call dvstep (y, yh, nyh, yh, ewt, savf, vsav, acor,
1516 ! wm, iwm, f, jac, f, dvnlsd, rpar, ipar)
1517 !-----------------------------------------------------------------------
1518 cmn12%h = h ; cmn12%n = n ! load h, n into cmn12
1519 call dvstep (y, rwork(cmn12%lyh), cmn12%nyh, rwork(cmn12%lyh), rwork(cmn12%lewt), &
1520 rwork(cmn12%lsavf), y, rwork(cmn12%lacor), rwork(cmn12%lwm), iwork(cmn12%liwm), &
1521 f, jac, f, dvnlsd, rpar, ipar, cmn12)
1522 h = cmn12%h ; n = cmn12%n ! unload h, n from cmn12
1523 kgo = 1 - cmn12%kflag
1524 ! branch on kflag. note: in this version, kflag can not be set to -3.
1525 ! kflag .eq. 0, -1, -2
1526 go to (300, 530, 540), kgo
1527 !-----------------------------------------------------------------------
1529 ! the following block handles the case of a successful return from the
1530 ! core integrator (kflag = 0). test for stop conditions.
1531 !-----------------------------------------------------------------------
1534 go to (310, 400, 330, 340, 350), itask
1535 ! itask = 1. if tout has been reached, interpolate. -------------------
1536 310 if ((cmn12%tn - tout)*h .lt. zero) go to 250
1537 cmn12%h = h ; cmn12%n = n ! load h, n into cmn12
1538 call dvindy (tout, 0, rwork(cmn12%lyh), cmn12%nyh, y, iflag, cmn12)
1539 h = cmn12%h ; n = cmn12%n ! unload h, n from cmn12
1542 ! itask = 3. jump to exit if tout was reached. ------------------------
1543 330 if ((cmn12%tn - tout)*h .ge. zero) go to 400
1545 ! itask = 4. see if tout or tcrit was reached. adjust h if necessary.
1546 340 if ((cmn12%tn - tout)*h .lt. zero) go to 345
1547 cmn12%h = h ; cmn12%n = n ! load h, n into cmn12
1548 call dvindy (tout, 0, rwork(cmn12%lyh), cmn12%nyh, y, iflag, cmn12)
1549 h = cmn12%h ; n = cmn12%n ! unload h, n from cmn12
1552 345 hmx = abs(cmn12%tn) + abs(h)
1553 ihit = abs(cmn12%tn - tcrit) .le. hun*cmn12%uround*hmx
1555 tnext = cmn12%tn + cmn12%hnew*(one + four*cmn12%uround)
1556 if ((tnext - tcrit)*h .le. zero) go to 250
1557 h = (tcrit - cmn12%tn)*(one - four*cmn12%uround)
1560 ! itask = 5. see if tcrit was reached and jump to exit. ---------------
1561 350 hmx = abs(cmn12%tn) + abs(h)
1562 ihit = abs(cmn12%tn - tcrit) .le. hun*cmn12%uround*hmx
1563 !-----------------------------------------------------------------------
1565 ! the following block handles all successful returns from dvode.
1566 ! if itask .ne. 1, y is loaded from yh and t is set accordingly.
1567 ! istate is set to 2, and the optional output is loaded into the work
1568 ! arrays before returning.
1569 !-----------------------------------------------------------------------
1571 call dcopy (n, rwork(cmn12%lyh), 1, y, 1)
1573 if (itask .ne. 4 .and. itask .ne. 5) go to 420
1576 rwork(11) = cmn12%hu
1577 rwork(12) = cmn12%hnew
1578 rwork(13) = cmn12%tn
1579 iwork(11) = cmn12%nst
1580 iwork(12) = cmn12%nfe
1581 iwork(13) = cmn12%nje
1582 iwork(14) = cmn12%nqu
1583 iwork(15) = cmn12%newq
1584 iwork(19) = cmn12%nlu
1585 iwork(20) = cmn12%nni
1586 iwork(21) = cmn12%ncfn
1587 iwork(22) = cmn12%netf
1589 !-----------------------------------------------------------------------
1591 ! the following block handles all unsuccessful returns other than
1592 ! those for illegal input. first the error message routine is called.
1593 ! if there was an error test or convergence test failure, imxer is set.
1594 ! then y is loaded from yh, and t is set to tn.
1595 ! the optional output is loaded into the work arrays before returning.
1596 !-----------------------------------------------------------------------
1597 ! the maximum number of steps was taken before reaching tout. ----------
1598 500 msg = 'dvode-- at current t (=r1), mxstep (=i1) steps '
1599 call xerrwd (msg, 50, 201, 1, 0, 0, 0, 0, zero, zero)
1600 msg = ' taken on this call before reaching tout '
1601 call xerrwd (msg, 50, 201, 1, 1, cmn12%mxstep, 0, 1, cmn12%tn, zero)
1604 ! ewt(i) .le. 0.0 for some i (not at start of problem). ----------------
1605 510 ewti = rwork(cmn12%lewt+i-1)
1606 msg = 'dvode-- at t (=r1), ewt(i1) has become r2 .le. 0.'
1607 call xerrwd (msg, 50, 202, 1, 1, i, 0, 2, cmn12%tn, ewti)
1610 ! too much accuracy requested for machine precision. -------------------
1611 520 msg = 'dvode-- at t (=r1), too much accuracy requested '
1612 call xerrwd (msg, 50, 203, 1, 0, 0, 0, 0, zero, zero)
1613 msg = ' for precision of machine: see tolsf (=r2) '
1614 call xerrwd (msg, 50, 203, 1, 0, 0, 0, 2, cmn12%tn, tolsf)
1618 ! kflag = -1. error test failed repeatedly or with abs(h) = hmin. -----
1619 530 msg = 'dvode-- at t(=r1) and step size h(=r2), the error'
1620 call xerrwd (msg, 50, 204, 1, 0, 0, 0, 0, zero, zero)
1621 msg = ' test failed repeatedly or with abs(h) = hmin'
1622 call xerrwd (msg, 50, 204, 1, 0, 0, 0, 2, cmn12%tn, h)
1625 ! kflag = -2. convergence failed repeatedly or with abs(h) = hmin. ----
1626 540 msg = 'dvode-- at t (=r1) and step size h (=r2), the '
1627 call xerrwd (msg, 50, 205, 1, 0, 0, 0, 0, zero, zero)
1628 msg = ' corrector convergence failed repeatedly '
1629 call xerrwd (msg, 50, 205, 1, 0, 0, 0, 0, zero, zero)
1630 msg = ' or with abs(h) = hmin '
1631 call xerrwd (msg, 30, 205, 1, 0, 0, 0, 2, cmn12%tn, h)
1633 ! compute imxer if relevant. -------------------------------------------
1637 size = abs(rwork(i+cmn12%lacor-1)*rwork(i+cmn12%lewt-1))
1638 if (big .ge. size) go to 570
1643 ! set y vector, t, and optional output. --------------------------------
1645 call dcopy (n, rwork(cmn12%lyh), 1, y, 1)
1647 rwork(11) = cmn12%hu
1649 rwork(13) = cmn12%tn
1650 iwork(11) = cmn12%nst
1651 iwork(12) = cmn12%nfe
1652 iwork(13) = cmn12%nje
1653 iwork(14) = cmn12%nqu
1654 iwork(15) = cmn12%nq
1655 iwork(19) = cmn12%nlu
1656 iwork(20) = cmn12%nni
1657 iwork(21) = cmn12%ncfn
1658 iwork(22) = cmn12%netf
1660 !-----------------------------------------------------------------------
1662 ! the following block handles all error returns due to illegal input
1663 ! (istate = -3), as detected before calling the core integrator.
1664 ! first the error message routine is called. if the illegal input
1665 ! is a negative istate, the run is aborted (apparent infinite loop).
1666 !-----------------------------------------------------------------------
1667 601 msg = 'dvode-- istate (=i1) illegal '
1668 call xerrwd (msg, 30, 1, 1, 1, istate, 0, 0, zero, zero)
1669 if (istate .lt. 0) go to 800
1671 602 msg = 'dvode-- itask (=i1) illegal '
1672 call xerrwd (msg, 30, 2, 1, 1, itask, 0, 0, zero, zero)
1674 603 msg='dvode-- istate (=i1) .gt. 1 but dvode not initialized '
1675 call xerrwd (msg, 60, 3, 1, 1, istate, 0, 0, zero, zero)
1677 604 msg = 'dvode-- neq (=i1) .lt. 1 '
1678 call xerrwd (msg, 30, 4, 1, 1, neq, 0, 0, zero, zero)
1680 605 msg = 'dvode-- istate = 3 and neq increased (i1 to i2) '
1681 call xerrwd (msg, 50, 5, 1, 2, n, neq, 0, zero, zero)
1683 606 msg = 'dvode-- itol (=i1) illegal '
1684 call xerrwd (msg, 30, 6, 1, 1, itol, 0, 0, zero, zero)
1686 607 msg = 'dvode-- iopt (=i1) illegal '
1687 call xerrwd (msg, 30, 7, 1, 1, iopt, 0, 0, zero, zero)
1689 608 msg = 'dvode-- mf (=i1) illegal '
1690 call xerrwd (msg, 30, 8, 1, 1, mf, 0, 0, zero, zero)
1692 609 msg = 'dvode-- ml (=i1) illegal: .lt.0 or .ge.neq (=i2)'
1693 call xerrwd (msg, 50, 9, 1, 2, ml, neq, 0, zero, zero)
1695 610 msg = 'dvode-- mu (=i1) illegal: .lt.0 or .ge.neq (=i2)'
1696 call xerrwd (msg, 50, 10, 1, 2, mu, neq, 0, zero, zero)
1698 611 msg = 'dvode-- maxord (=i1) .lt. 0 '
1699 call xerrwd (msg, 30, 11, 1, 1, cmn12%maxord, 0, 0, zero, zero)
1701 612 msg = 'dvode-- mxstep (=i1) .lt. 0 '
1702 call xerrwd (msg, 30, 12, 1, 1, cmn12%mxstep, 0, 0, zero, zero)
1704 613 msg = 'dvode-- mxhnil (=i1) .lt. 0 '
1705 call xerrwd (msg, 30, 13, 1, 1, cmn12%mxhnil, 0, 0, zero, zero)
1707 614 msg = 'dvode-- tout (=r1) behind t (=r2) '
1708 call xerrwd (msg, 40, 14, 1, 0, 0, 0, 2, tout, t)
1709 msg = ' integration direction is given by h0 (=r1) '
1710 call xerrwd (msg, 50, 14, 1, 0, 0, 0, 1, h0, zero)
1712 615 msg = 'dvode-- hmax (=r1) .lt. 0.0 '
1713 call xerrwd (msg, 30, 15, 1, 0, 0, 0, 1, hmax, zero)
1715 616 msg = 'dvode-- hmin (=r1) .lt. 0.0 '
1716 call xerrwd (msg, 30, 16, 1, 0, 0, 0, 1, cmn12%hmin, zero)
1719 msg='dvode-- rwork length needed, lenrw (=i1), exceeds lrw (=i2)'
1720 call xerrwd (msg, 60, 17, 1, 2, lenrw, lrw, 0, zero, zero)
1723 msg='dvode-- iwork length needed, leniw (=i1), exceeds liw (=i2)'
1724 call xerrwd (msg, 60, 18, 1, 2, leniw, liw, 0, zero, zero)
1726 619 msg = 'dvode-- rtol(i1) is r1 .lt. 0.0 '
1727 call xerrwd (msg, 40, 19, 1, 1, i, 0, 1, rtoli, zero)
1729 620 msg = 'dvode-- atol(i1) is r1 .lt. 0.0 '
1730 call xerrwd (msg, 40, 20, 1, 1, i, 0, 1, atoli, zero)
1732 621 ewti = rwork(cmn12%lewt+i-1)
1733 msg = 'dvode-- ewt(i1) is r1 .le. 0.0 '
1734 call xerrwd (msg, 40, 21, 1, 1, i, 0, 1, ewti, zero)
1737 msg='dvode-- tout (=r1) too close to t(=r2) to start integration'
1738 call xerrwd (msg, 60, 22, 1, 0, 0, 0, 2, tout, t)
1741 msg='dvode-- itask = i1 and tout (=r1) behind tcur - hu (= r2) '
1742 call xerrwd (msg, 60, 23, 1, 1, itask, 0, 2, tout, tp)
1745 msg='dvode-- itask = 4 or 5 and tcrit (=r1) behind tcur (=r2) '
1746 call xerrwd (msg, 60, 24, 1, 0, 0, 0, 2, tcrit, cmn12%tn)
1749 msg='dvode-- itask = 4 or 5 and tcrit (=r1) behind tout (=r2) '
1750 call xerrwd (msg, 60, 25, 1, 0, 0, 0, 2, tcrit, tout)
1752 626 msg = 'dvode-- at start of problem, too much accuracy '
1753 call xerrwd (msg, 50, 26, 1, 0, 0, 0, 0, zero, zero)
1754 msg=' requested for precision of machine: see tolsf (=r1) '
1755 call xerrwd (msg, 60, 26, 1, 0, 0, 0, 1, tolsf, zero)
1758 627 msg='dvode-- trouble from dvindy. itask = i1, tout = r1. '
1759 call xerrwd (msg, 60, 27, 1, 1, itask, 0, 1, tout, zero)
1765 800 msg = 'dvode-- run aborted: apparent infinite loop '
1766 call xerrwd (msg, 50, 303, 2, 0, 0, 0, 0, zero, zero)
1768 !----------------------- end of subroutine dvode -----------------------
1769 end subroutine dvode
1771 subroutine dvhin (n, t0, y0, ydot, f, rpar, ipar, tout, uround, &
1772 ewt, itol, atol, y, temp, h0, niter, ier)
1774 double precision t0, y0, ydot, rpar, tout, uround, ewt, atol, y, &
1776 integer n, ipar, itol, niter, ier
1777 dimension y0(*), ydot(*), ewt(*), atol(*), y(*), &
1778 temp(*), rpar(*), ipar(*)
1779 !-----------------------------------------------------------------------
1780 ! call sequence input -- n, t0, y0, ydot, f, rpar, ipar, tout, uround,
1781 ! ewt, itol, atol, y, temp
1782 ! call sequence output -- h0, niter, ier
1783 ! common block variables accessed -- none
1785 ! subroutines called by dvhin: f
1786 ! function routines called by dvhi: dvnorm
1787 !-----------------------------------------------------------------------
1788 ! this routine computes the step size, h0, to be attempted on the
1789 ! first step, when the user has not supplied a value for this.
1791 ! first we check that tout - t0 differs significantly from zero. then
1792 ! an iteration is done to approximate the initial second derivative
1793 ! and this is used to define h from w.r.m.s.norm(h**2 * yddot / 2) = 1.
1794 ! a bias factor of 1/2 is applied to the resulting h.
1795 ! the sign of h0 is inferred from the initial values of tout and t0.
1797 ! communication with dvhin is done with the following variables:
1799 ! n = size of ode system, input.
1800 ! t0 = initial value of independent variable, input.
1801 ! y0 = vector of initial conditions, input.
1802 ! ydot = vector of initial first derivatives, input.
1803 ! f = name of subroutine for right-hand side f(t,y), input.
1804 ! rpar, ipar = dummy names for user's real and integer work arrays.
1805 ! tout = first output value of independent variable
1806 ! uround = machine unit roundoff
1807 ! ewt, itol, atol = error weights and tolerance parameters
1808 ! as described in the driver routine, input.
1809 ! y, temp = work arrays of length n.
1810 ! h0 = step size to be attempted, output.
1811 ! niter = number of iterations (and of f evaluations) to compute h0,
1813 ! ier = the error flag, returned with the value
1814 ! ier = 0 if no trouble occurred, or
1815 ! ier = -1 if tout and t0 are considered too close to proceed.
1816 !-----------------------------------------------------------------------
1818 ! type declarations for local variables --------------------------------
1820 double precision afi, atoli, delyi, h, half, hg, hlb, hnew, hrat, &
1821 hub, hun, pt1, t1, tdist, tround, two, yddnrm
1824 ! type declaration for function subroutines called ---------------------
1826 ! 27-oct-2005 rce - do not declare functions that are in the module
1827 ! double precision dvnorm
1828 !-----------------------------------------------------------------------
1829 ! the following fortran-77 declaration is to cause the values of the
1830 ! listed (local) variables to be saved between calls to this integrator.
1831 !-----------------------------------------------------------------------
1832 save half, hun, pt1, two
1833 data half /0.5d0/, hun /100.0d0/, pt1 /0.1d0/, two /2.0d0/
1836 tdist = abs(tout - t0)
1837 tround = uround*max(abs(t0),abs(tout))
1838 if (tdist .lt. two*tround) go to 100
1840 ! set a lower bound on h based on the roundoff level in t0 and tout. ---
1842 ! set an upper bound on h based on tout-t0 and the initial y and ydot. -
1846 if (itol .eq. 2 .or. itol .eq. 4) atoli = atol(i)
1847 delyi = pt1*abs(y0(i)) + atoli
1849 if (afi*hub .gt. delyi) hub = delyi/afi
1852 ! set initial guess for h as geometric mean of upper and lower bounds. -
1855 ! if the bounds have crossed, exit with the mean value. ----------------
1856 if (hub .lt. hlb) then
1861 ! looping point for iteration. -----------------------------------------
1863 ! estimate the second derivative as a difference quotient in f. --------
1864 h = sign (hg, tout - t0)
1867 60 y(i) = y0(i) + h*ydot(i)
1868 call f (n, t1, y, temp, rpar, ipar)
1870 70 temp(i) = (temp(i) - ydot(i))/h
1871 yddnrm = dvnorm (n, temp, ewt)
1872 ! get the corresponding new value of h. --------------------------------
1873 if (yddnrm*hub*hub .gt. two) then
1874 hnew = sqrt(two/yddnrm)
1879 !-----------------------------------------------------------------------
1880 ! test the stopping conditions.
1881 ! stop if the new and previous h values differ by a factor of .lt. 2.
1882 ! stop if four iterations have been done. also, stop with previous h
1883 ! if hnew/hg .gt. 2 after first iteration, as this probably means that
1884 ! the second derivative value is bad because of cancellation error.
1885 !-----------------------------------------------------------------------
1886 if (iter .ge. 4) go to 80
1888 if ( (hrat .gt. half) .and. (hrat .lt. two) ) go to 80
1889 if ( (iter .ge. 2) .and. (hnew .gt. two*hg) ) then
1896 ! iteration done. apply bounds, bias factor, and sign. then exit. ----
1898 if (h0 .lt. hlb) h0 = hlb
1899 if (h0 .gt. hub) h0 = hub
1900 90 h0 = sign(h0, tout - t0)
1904 ! error return for tout - t0 too small. --------------------------------
1907 !----------------------- end of subroutine dvhin -----------------------
1908 end subroutine dvhin
1910 subroutine dvindy (t, k, yh, ldyh, dky, iflag, cmn12)
1912 double precision t, yh, dky
1913 integer k, ldyh, iflag
1914 dimension yh(ldyh,*), dky(*)
1915 type( dvode_cmn_vars ) :: cmn12
1916 !-----------------------------------------------------------------------
1917 ! call sequence input -- t, k, yh, ldyh
1918 ! call sequence output -- dky, iflag
1919 ! common block variables accessed:
1920 ! /dvod_cmn01/ -- h, tn, uround, l, n, nq
1921 ! /dvod_cmn02/ -- hu
1923 ! subroutines called by dvindy: dscal, xerrwd
1924 ! function routines called by dvindy: none
1925 !-----------------------------------------------------------------------
1926 ! dvindy computes interpolated values of the k-th derivative of the
1927 ! dependent variable vector y, and stores it in dky. this routine
1928 ! is called within the package with k = 0 and t = tout, but may
1929 ! also be called by the user for any k up to the current order.
1930 ! (see detailed instructions in the usage documentation.)
1931 !-----------------------------------------------------------------------
1932 ! the computed values in dky are gotten by interpolation using the
1933 ! nordsieck history array yh. this array corresponds uniquely to a
1934 ! vector-valued polynomial of degree nqcur or less, and dky is set
1935 ! to the k-th derivative of this polynomial at t.
1936 ! the formula for dky is:
1938 ! dky(i) = sum c(j,k) * (t - tn)**(j-k) * h**(-j) * yh(i,j+1)
1940 ! where c(j,k) = j*(j-1)*...*(j-k+1), q = nqcur, tn = tcur, h = hcur.
1941 ! the quantities nq = nqcur, l = nq+1, n, tn, and h are
1942 ! communicated by common. the above sum is done in reverse order.
1943 ! iflag is returned negative if either k or t is out of bounds.
1945 ! discussion above and comments in driver explain all variables.
1946 !-----------------------------------------------------------------------
1948 !! type declarations for labeled common block dvod_cmn01 --------------------
1950 ! double precision acnrm, ccmxj, conp, crate, drc, el, &
1951 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
1952 ! rc, rl1, tau, tq, tn, uround
1953 ! integer icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
1954 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
1955 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
1956 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
1959 !! type declarations for labeled common block dvod_cmn02 --------------------
1961 ! double precision hu
1962 ! integer ncfn, netf, nfe, nje, nlu, nni, nqu, nst
1964 ! type declarations for local variables --------------------------------
1966 double precision c, hun, r, s, tfuzz, tn1, tp, zero
1967 integer i, ic, j, jb, jb2, jj, jj1, jp1
1969 !-----------------------------------------------------------------------
1970 ! the following fortran-77 declaration is to cause the values of the
1971 ! listed (local) variables to be saved between calls to this integrator.
1972 !-----------------------------------------------------------------------
1975 ! common /dvod_cmn01/ acnrm, ccmxj, conp, crate, drc, el(13), &
1976 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
1977 ! rc, rl1, tau(13), tq(5), tn, uround, &
1978 ! icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
1979 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
1980 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
1981 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
1983 ! common /dvod_cmn02/ hu, ncfn, netf, nfe, nje, nlu, nni, nqu, nst
1985 data hun /100.0d0/, zero /0.0d0/
1988 if (k .lt. 0 .or. k .gt. cmn12%nq) go to 80
1989 tfuzz = hun*cmn12%uround*(cmn12%tn + cmn12%hu)
1990 tp = cmn12%tn - cmn12%hu - tfuzz
1991 tn1 = cmn12%tn + tfuzz
1992 if ((t-tp)*(t-tn1) .gt. zero) go to 90
1994 s = (t - cmn12%tn)/cmn12%h
1996 if (k .eq. 0) go to 15
1998 do 10 jj = jj1, cmn12%nq
2001 do 20 i = 1, cmn12%n
2002 20 dky(i) = c*yh(i,cmn12%l)
2003 if (k .eq. cmn12%nq) go to 55
2009 if (k .eq. 0) go to 35
2014 do 40 i = 1, cmn12%n
2015 40 dky(i) = c*yh(i,jp1) + s*dky(i)
2017 if (k .eq. 0) return
2018 55 r = cmn12%h**(-k)
2019 call dscal (cmn12%n, r, dky, 1)
2022 80 msg = 'dvindy-- k (=i1) illegal '
2023 call xerrwd (msg, 30, 51, 1, 1, k, 0, 0, zero, zero)
2026 90 msg = 'dvindy-- t (=r1) illegal '
2027 call xerrwd (msg, 30, 52, 1, 0, 0, 0, 1, t, zero)
2028 msg=' t not in interval tcur - hu (= r1) to tcur (=r2) '
2029 call xerrwd (msg, 60, 52, 1, 0, 0, 0, 2, tp, cmn12%tn)
2032 !----------------------- end of subroutine dvindy ----------------------
2033 end subroutine dvindy
2035 subroutine dvstep (y, yh, ldyh, yh1, ewt, savf, vsav, acor, &
2036 wm, iwm, f, jac, psol, vnls, rpar, ipar, cmn12)
2038 external f, jac, psol, vnls
2039 double precision y, yh, yh1, ewt, savf, vsav, acor, wm, rpar
2040 integer ldyh, iwm, ipar
2041 dimension y(*), yh(ldyh,*), yh1(*), ewt(*), savf(*), vsav(*), &
2042 acor(*), wm(*), iwm(*), rpar(*), ipar(*)
2043 type( dvode_cmn_vars ) :: cmn12
2044 !-----------------------------------------------------------------------
2045 ! call sequence input -- y, yh, ldyh, yh1, ewt, savf, vsav,
2046 ! acor, wm, iwm, f, jac, psol, vnls, rpar, ipar
2047 ! call sequence output -- yh, acor, wm, iwm
2048 ! common block variables accessed:
2049 ! /dvod_cmn01/ acnrm, el(13), h, hmin, hmxi, hnew, hscal, rc, tau(13),
2050 ! tq(5), tn, jcur, jstart, kflag, kuth,
2051 ! l, lmax, maxord, n, newq, nq, nqwait
2052 ! /dvod_cmn02/ hu, ncfn, netf, nfe, nqu, nst
2054 ! subroutines called by dvstep: f, daxpy, dcopy, dscal,
2055 ! dvjust, vnls, dvset
2056 ! function routines called by dvstep: dvnorm
2057 !-----------------------------------------------------------------------
2058 ! dvstep performs one step of the integration of an initial value
2059 ! problem for a system of ordinary differential equations.
2060 ! dvstep calls subroutine vnls for the solution of the nonlinear system
2061 ! arising in the time step. thus it is independent of the problem
2062 ! jacobian structure and the type of nonlinear system solution method.
2063 ! dvstep returns a completion flag kflag (in common).
2064 ! a return with kflag = -1 or -2 means either abs(h) = hmin or 10
2065 ! consecutive failures occurred. on a return with kflag negative,
2066 ! the values of tn and the yh array are as of the beginning of the last
2067 ! step, and h is the last step size attempted.
2069 ! communication with dvstep is done with the following variables:
2071 ! y = an array of length n used for the dependent variable vector.
2072 ! yh = an ldyh by lmax array containing the dependent variables
2073 ! and their approximate scaled derivatives, where
2074 ! lmax = maxord + 1. yh(i,j+1) contains the approximate
2075 ! j-th derivative of y(i), scaled by h**j/factorial(j)
2076 ! (j = 0,1,...,nq). on entry for the first step, the first
2077 ! two columns of yh must be set from the initial values.
2078 ! ldyh = a constant integer .ge. n, the first dimension of yh.
2079 ! n is the number of odes in the system.
2080 ! yh1 = a one-dimensional array occupying the same space as yh.
2081 ! ewt = an array of length n containing multiplicative weights
2082 ! for local error measurements. local errors in y(i) are
2083 ! compared to 1.0/ewt(i) in various error tests.
2084 ! savf = an array of working storage, of length n.
2085 ! also used for input of yh(*,maxord+2) when jstart = -1
2086 ! and maxord .lt. the current order nq.
2087 ! vsav = a work array of length n passed to subroutine vnls.
2088 ! acor = a work array of length n, used for the accumulated
2089 ! corrections. on a successful return, acor(i) contains
2090 ! the estimated one-step local error in y(i).
2091 ! wm,iwm = real and integer work arrays associated with matrix
2092 ! operations in vnls.
2093 ! f = dummy name for the user supplied subroutine for f.
2094 ! jac = dummy name for the user supplied jacobian subroutine.
2095 ! psol = dummy name for the subroutine passed to vnls, for
2096 ! possible use there.
2097 ! vnls = dummy name for the nonlinear system solving subroutine,
2098 ! whose real name is dependent on the method used.
2099 ! rpar, ipar = dummy names for user's real and integer work arrays.
2100 !-----------------------------------------------------------------------
2102 !! type declarations for labeled common block dvod_cmn01 --------------------
2104 ! double precision acnrm, ccmxj, conp, crate, drc, el, &
2105 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
2106 ! rc, rl1, tau, tq, tn, uround
2107 ! integer icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
2108 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
2109 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
2110 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
2113 !! type declarations for labeled common block dvod_cmn02 --------------------
2115 ! double precision hu
2116 ! integer ncfn, netf, nfe, nje, nlu, nni, nqu, nst
2118 ! type declarations for local variables --------------------------------
2120 ! note -- etaq & etaqm1 are saved variables that are not fixed constants,
2121 ! so put them into cmn12
2122 ! double precision addon, bias1,bias2,bias3, cnquot, ddn, dsm, dup, &
2123 ! etacf, etamin, etamx1, etamx2, etamx3, etamxf, &
2124 ! etaq, etaqm1, etaqp1, flotl, one, onepsm, &
2125 ! r, thresh, told, zero
2126 double precision addon, bias1,bias2,bias3, cnquot, ddn, dsm, dup, &
2127 etacf, etamin, etamx1, etamx2, etamx3, etamxf, &
2128 etaqp1, flotl, one, onepsm, &
2129 r, thresh, told, zero
2130 integer i, i1, i2, iback, j, jb, kfc, kfh, mxncf, ncf, nflag
2132 ! type declaration for function subroutines called ---------------------
2134 ! 27-oct-2005 rce - do not declare functions that are in the module
2135 ! double precision dvnorm
2136 !-----------------------------------------------------------------------
2137 ! the following fortran-77 declaration is to cause the values of the
2138 ! listed (local) variables to be saved between calls to this integrator.
2139 !-----------------------------------------------------------------------
2140 ! note -- etaq & etaqm1 are saved variables that are not fixed constants,
2141 ! so put them into cmn12
2142 ! save addon, bias1, bias2, bias3, &
2143 ! etacf, etamin, etamx1, etamx2, etamx3, etamxf, etaq, etaqm1, &
2144 ! kfc, kfh, mxncf, onepsm, thresh, one, zero
2145 save addon, bias1, bias2, bias3, &
2146 etacf, etamin, etamx1, etamx2, etamx3, etamxf, &
2147 kfc, kfh, mxncf, onepsm, thresh, one, zero
2148 !-----------------------------------------------------------------------
2149 ! common /dvod_cmn01/ acnrm, ccmxj, conp, crate, drc, el(13), &
2150 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
2151 ! rc, rl1, tau(13), tq(5), tn, uround, &
2152 ! icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
2153 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
2154 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
2155 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
2157 ! common /dvod_cmn02/ hu, ncfn, netf, nfe, nje, nlu, nni, nqu, nst
2159 data kfc/-3/, kfh/-7/, mxncf/10/
2160 data addon /1.0d-6/, bias1 /6.0d0/, bias2 /6.0d0/, &
2161 bias3 /10.0d0/, etacf /0.25d0/, etamin /0.1d0/, &
2162 etamxf /0.2d0/, etamx1 /1.0d4/, etamx2 /10.0d0/, &
2163 etamx3 /10.0d0/, onepsm /1.00001d0/, thresh /1.5d0/
2164 data one/1.0d0/, zero/0.0d0/
2171 if (cmn12%jstart .gt. 0) go to 20
2172 if (cmn12%jstart .eq. -1) go to 100
2173 !-----------------------------------------------------------------------
2174 ! on the first call, the order is set to 1, and other variables are
2175 ! initialized. etamax is the maximum ratio by which h can be increased
2176 ! in a single step. it is normally 10, but is larger during the
2177 ! first step to compensate for the small initial h. if a failure
2178 ! occurs (in corrector convergence or error test), etamax is set to 1
2179 ! for the next increase.
2180 !-----------------------------------------------------------------------
2181 cmn12%lmax = cmn12%maxord + 1
2184 cmn12%nqnyh = cmn12%nq*ldyh
2185 cmn12%tau(1) = cmn12%h
2188 cmn12%etamax = etamx1
2190 cmn12%hscal = cmn12%h
2192 !-----------------------------------------------------------------------
2193 ! take preliminary actions on a normal continuation step (jstart.gt.0).
2194 ! if the driver changed h, then eta must be reset and newh set to 1.
2195 ! if a change of order was dictated on the previous step, then
2196 ! it is done here and appropriate adjustments in the history are made.
2197 ! on an order decrease, the history array is adjusted by dvjust.
2198 ! on an order increase, the history array is augmented by a column.
2199 ! on a change of step size h, the history array yh is rescaled.
2200 !-----------------------------------------------------------------------
2202 if (cmn12%kuth .eq. 1) then
2203 cmn12%eta = min(cmn12%eta,cmn12%h/cmn12%hscal)
2206 50 if (cmn12%newh .eq. 0) go to 200
2207 if (cmn12%newq .eq. cmn12%nq) go to 150
2208 if (cmn12%newq .lt. cmn12%nq) then
2209 call dvjust (yh, ldyh, -1, cmn12)
2210 cmn12%nq = cmn12%newq
2211 cmn12%l = cmn12%nq + 1
2212 cmn12%nqwait = cmn12%l
2215 if (cmn12%newq .gt. cmn12%nq) then
2216 call dvjust (yh, ldyh, 1, cmn12)
2217 cmn12%nq = cmn12%newq
2218 cmn12%l = cmn12%nq + 1
2219 cmn12%nqwait = cmn12%l
2222 !-----------------------------------------------------------------------
2223 ! the following block handles preliminaries needed when jstart = -1.
2224 ! if n was reduced, zero out part of yh to avoid undefined references.
2225 ! if maxord was reduced to a value less than the tentative order newq,
2226 ! then nq is set to maxord, and a new h ratio eta is chosen.
2227 ! otherwise, we take the same preliminary actions as for jstart .gt. 0.
2228 ! in any case, nqwait is reset to l = nq + 1 to prevent further
2229 ! changes in order for that many steps.
2230 ! the new h ratio eta is limited by the input h if kuth = 1,
2231 ! by hmin if kuth = 0, and by hmxi in any case.
2232 ! finally, the history array yh is rescaled.
2233 !-----------------------------------------------------------------------
2235 cmn12%lmax = cmn12%maxord + 1
2236 if (cmn12%n .eq. ldyh) go to 120
2237 i1 = 1 + (cmn12%newq + 1)*ldyh
2238 i2 = (cmn12%maxord + 1)*ldyh
2239 if (i1 .gt. i2) go to 120
2242 120 if (cmn12%newq .le. cmn12%maxord) go to 140
2243 flotl = real(cmn12%lmax)
2244 if (cmn12%maxord .lt. cmn12%nq-1) then
2245 ddn = dvnorm (cmn12%n, savf, ewt)/cmn12%tq(1)
2246 cmn12%eta = one/((bias1*ddn)**(one/flotl) + addon)
2248 if (cmn12%maxord .eq. cmn12%nq .and. cmn12%newq .eq. cmn12%nq+1) cmn12%eta = cmn12%etaq
2249 if (cmn12%maxord .eq. cmn12%nq-1 .and. cmn12%newq .eq. cmn12%nq+1) then
2250 cmn12%eta = cmn12%etaqm1
2251 call dvjust (yh, ldyh, -1, cmn12)
2253 if (cmn12%maxord .eq. cmn12%nq-1 .and. cmn12%newq .eq. cmn12%nq) then
2254 ddn = dvnorm (cmn12%n, savf, ewt)/cmn12%tq(1)
2255 cmn12%eta = one/((bias1*ddn)**(one/flotl) + addon)
2256 call dvjust (yh, ldyh, -1, cmn12)
2258 cmn12%eta = min(cmn12%eta,one)
2259 cmn12%nq = cmn12%maxord
2260 cmn12%l = cmn12%lmax
2261 140 if (cmn12%kuth .eq. 1) cmn12%eta = min(cmn12%eta,abs(cmn12%h/cmn12%hscal))
2262 if (cmn12%kuth .eq. 0) cmn12%eta = max(cmn12%eta,cmn12%hmin/abs(cmn12%hscal))
2263 cmn12%eta = cmn12%eta/max(one,abs(cmn12%hscal)*cmn12%hmxi*cmn12%eta)
2265 cmn12%nqwait = cmn12%l
2266 if (cmn12%newq .le. cmn12%maxord) go to 50
2267 ! rescale the history array for a change in h by a factor of eta. ------
2269 do 180 j = 2, cmn12%l
2271 call dscal (cmn12%n, r, yh(1,j), 1 )
2273 cmn12%h = cmn12%hscal*cmn12%eta
2274 cmn12%hscal = cmn12%h
2275 cmn12%rc = cmn12%rc*cmn12%eta
2276 cmn12%nqnyh = cmn12%nq*ldyh
2277 !-----------------------------------------------------------------------
2278 ! this section computes the predicted values by effectively
2279 ! multiplying the yh array by the pascal triangle matrix.
2280 ! dvset is called to calculate all integration coefficients.
2281 ! rc is the ratio of new to old values of the coefficient h/el(2)=h/l1.
2282 !-----------------------------------------------------------------------
2283 200 cmn12%tn = cmn12%tn + cmn12%h
2284 i1 = cmn12%nqnyh + 1
2285 do 220 jb = 1, cmn12%nq
2287 do 210 i = i1, cmn12%nqnyh
2288 210 yh1(i) = yh1(i) + yh1(i+ldyh)
2291 cmn12%rl1 = one/cmn12%el(2)
2292 cmn12%rc = cmn12%rc*(cmn12%rl1/cmn12%prl1)
2293 cmn12%prl1 = cmn12%rl1
2295 ! call the nonlinear system solver. ------------------------------------
2297 call vnls (y, yh, ldyh, vsav, savf, ewt, acor, iwm, wm, &
2298 f, jac, psol, nflag, rpar, ipar, cmn12)
2300 if (nflag .eq. 0) go to 450
2301 !-----------------------------------------------------------------------
2302 ! the vnls routine failed to achieve convergence (nflag .ne. 0).
2303 ! the yh array is retracted to its values before prediction.
2304 ! the step size h is reduced and the step is retried, if possible.
2305 ! otherwise, an error exit is taken.
2306 !-----------------------------------------------------------------------
2308 cmn12%ncfn = cmn12%ncfn + 1
2311 i1 = cmn12%nqnyh + 1
2312 do 430 jb = 1, cmn12%nq
2314 do 420 i = i1, cmn12%nqnyh
2315 420 yh1(i) = yh1(i) - yh1(i+ldyh)
2317 if (nflag .lt. -1) go to 680
2318 if (abs(cmn12%h) .le. cmn12%hmin*onepsm) go to 670
2319 if (ncf .eq. mxncf) go to 670
2321 cmn12%eta = max(cmn12%eta,cmn12%hmin/abs(cmn12%h))
2324 !-----------------------------------------------------------------------
2325 ! the corrector has converged (nflag = 0). the local error test is
2326 ! made and control passes to statement 500 if it fails.
2327 !-----------------------------------------------------------------------
2329 dsm = cmn12%acnrm/cmn12%tq(2)
2330 if (dsm .gt. one) go to 500
2331 !-----------------------------------------------------------------------
2332 ! after a successful step, update the yh and tau arrays and decrement
2333 ! nqwait. if nqwait is then 1 and nq .lt. maxord, then acor is saved
2334 ! for use in a possible order increase on the next step.
2335 ! if etamax = 1 (a failure occurred this step), keep nqwait .ge. 2.
2336 !-----------------------------------------------------------------------
2338 cmn12%nst = cmn12%nst + 1
2340 cmn12%nqu = cmn12%nq
2341 do 470 iback = 1, cmn12%nq
2343 470 cmn12%tau(i+1) = cmn12%tau(i)
2344 cmn12%tau(1) = cmn12%h
2345 do 480 j = 1, cmn12%l
2346 call daxpy (cmn12%n, cmn12%el(j), acor, 1, yh(1,j), 1 )
2348 cmn12%nqwait = cmn12%nqwait - 1
2349 if ((cmn12%l .eq. cmn12%lmax) .or. (cmn12%nqwait .ne. 1)) go to 490
2350 call dcopy (cmn12%n, acor, 1, yh(1,cmn12%lmax), 1 )
2351 cmn12%conp = cmn12%tq(5)
2352 490 if (cmn12%etamax .ne. one) go to 560
2353 if (cmn12%nqwait .lt. 2) cmn12%nqwait = 2
2354 cmn12%newq = cmn12%nq
2357 cmn12%hnew = cmn12%h
2359 !-----------------------------------------------------------------------
2360 ! the error test failed. kflag keeps track of multiple failures.
2361 ! restore tn and the yh array to their previous values, and prepare
2362 ! to try the step again. compute the optimum step size for the
2363 ! same order. after repeated failures, h is forced to decrease
2365 !-----------------------------------------------------------------------
2366 500 cmn12%kflag = cmn12%kflag - 1
2367 cmn12%netf = cmn12%netf + 1
2370 i1 = cmn12%nqnyh + 1
2371 do 520 jb = 1, cmn12%nq
2373 do 510 i = i1, cmn12%nqnyh
2374 510 yh1(i) = yh1(i) - yh1(i+ldyh)
2376 if (abs(cmn12%h) .le. cmn12%hmin*onepsm) go to 660
2378 if (cmn12%kflag .le. kfc) go to 530
2379 ! compute ratio of new h to current h at the current order. ------------
2380 flotl = real(cmn12%l)
2381 cmn12%eta = one/((bias2*dsm)**(one/flotl) + addon)
2382 cmn12%eta = max(cmn12%eta,cmn12%hmin/abs(cmn12%h),etamin)
2383 if ((cmn12%kflag .le. -2) .and. (cmn12%eta .gt. etamxf)) cmn12%eta = etamxf
2385 !-----------------------------------------------------------------------
2386 ! control reaches this section if 3 or more consecutive failures
2387 ! have occurred. it is assumed that the elements of the yh array
2388 ! have accumulated errors of the wrong order. the order is reduced
2389 ! by one, if possible. then h is reduced by a factor of 0.1 and
2390 ! the step is retried. after a total of 7 consecutive failures,
2391 ! an exit is taken with kflag = -1.
2392 !-----------------------------------------------------------------------
2393 530 if (cmn12%kflag .eq. kfh) go to 660
2394 if (cmn12%nq .eq. 1) go to 540
2395 cmn12%eta = max(etamin,cmn12%hmin/abs(cmn12%h))
2396 call dvjust (yh, ldyh, -1, cmn12)
2398 cmn12%nq = cmn12%nq - 1
2399 cmn12%nqwait = cmn12%l
2401 540 cmn12%eta = max(etamin,cmn12%hmin/abs(cmn12%h))
2402 cmn12%h = cmn12%h*cmn12%eta
2403 cmn12%hscal = cmn12%h
2404 cmn12%tau(1) = cmn12%h
2405 call f (cmn12%n, cmn12%tn, y, savf, rpar, ipar)
2406 cmn12%nfe = cmn12%nfe + 1
2407 do 550 i = 1, cmn12%n
2408 550 yh(i,2) = cmn12%h*savf(i)
2411 !-----------------------------------------------------------------------
2412 ! if nqwait = 0, an increase or decrease in order by one is considered.
2413 ! factors etaq, etaqm1, etaqp1 are computed by which h could
2414 ! be multiplied at order q, q-1, or q+1, respectively.
2415 ! the largest of these is determined, and the new order and
2416 ! step size set accordingly.
2417 ! a change of h or nq is made only if h increases by at least a
2418 ! factor of thresh. if an order change is considered and rejected,
2419 ! then nqwait is set to 2 (reconsider it after 2 steps).
2420 !-----------------------------------------------------------------------
2421 ! compute ratio of new h to current h at the current order. ------------
2422 560 flotl = real(cmn12%l)
2423 cmn12%etaq = one/((bias2*dsm)**(one/flotl) + addon)
2424 if (cmn12%nqwait .ne. 0) go to 600
2427 if (cmn12%nq .eq. 1) go to 570
2428 ! compute ratio of new h to current h at the current order less one. ---
2429 ddn = dvnorm (cmn12%n, yh(1,cmn12%l), ewt)/cmn12%tq(1)
2430 cmn12%etaqm1 = one/((bias1*ddn)**(one/(flotl - one)) + addon)
2432 if (cmn12%l .eq. cmn12%lmax) go to 580
2433 ! compute ratio of new h to current h at current order plus one. -------
2434 cnquot = (cmn12%tq(5)/cmn12%conp)*(cmn12%h/cmn12%tau(2))**cmn12%l
2435 do 575 i = 1, cmn12%n
2436 575 savf(i) = acor(i) - cnquot*yh(i,cmn12%lmax)
2437 dup = dvnorm (cmn12%n, savf, ewt)/cmn12%tq(3)
2438 etaqp1 = one/((bias3*dup)**(one/(flotl + one)) + addon)
2439 580 if (cmn12%etaq .ge. etaqp1) go to 590
2440 if (etaqp1 .gt. cmn12%etaqm1) go to 620
2442 590 if (cmn12%etaq .lt. cmn12%etaqm1) go to 610
2443 600 cmn12%eta = cmn12%etaq
2444 cmn12%newq = cmn12%nq
2446 610 cmn12%eta = cmn12%etaqm1
2447 cmn12%newq = cmn12%nq - 1
2449 620 cmn12%eta = etaqp1
2450 cmn12%newq = cmn12%nq + 1
2451 call dcopy (cmn12%n, acor, 1, yh(1,cmn12%lmax), 1)
2452 ! test tentative new h against thresh, etamax, and hmxi, then exit. ----
2453 630 if (cmn12%eta .lt. thresh .or. cmn12%etamax .eq. one) go to 640
2454 cmn12%eta = min(cmn12%eta,cmn12%etamax)
2455 cmn12%eta = cmn12%eta/max(one,abs(cmn12%h)*cmn12%hmxi*cmn12%eta)
2457 cmn12%hnew = cmn12%h*cmn12%eta
2459 640 cmn12%newq = cmn12%nq
2462 cmn12%hnew = cmn12%h
2464 !-----------------------------------------------------------------------
2465 ! all returns are made through this section.
2466 ! on a successful return, etamax is reset and acor is scaled.
2467 !-----------------------------------------------------------------------
2468 660 cmn12%kflag = -1
2470 670 cmn12%kflag = -2
2472 680 if (nflag .eq. -2) cmn12%kflag = -3
2473 if (nflag .eq. -3) cmn12%kflag = -4
2475 690 cmn12%etamax = etamx3
2476 if (cmn12%nst .le. 10) cmn12%etamax = etamx2
2477 700 r = one/cmn12%tq(2)
2478 call dscal (cmn12%n, r, acor, 1)
2479 720 cmn12%jstart = 1
2481 !----------------------- end of subroutine dvstep ----------------------
2482 end subroutine dvstep
2484 subroutine dvset( cmn12 )
2486 type( dvode_cmn_vars ) :: cmn12
2487 !-----------------------------------------------------------------------
2488 ! call sequence communication: none
2489 ! common block variables accessed:
2490 ! /dvod_cmn01/ -- el(13), h, tau(13), tq(5), l(= nq + 1),
2493 ! subroutines called by dvset: none
2494 ! function routines called by dvset: none
2495 !-----------------------------------------------------------------------
2496 ! dvset is called by dvstep and sets coefficients for use there.
2498 ! for each order nq, the coefficients in el are calculated by use of
2499 ! the generating polynomial lambda(x), with coefficients el(i).
2500 ! lambda(x) = el(1) + el(2)*x + ... + el(nq+1)*(x**nq).
2501 ! for the backward differentiation formulas,
2503 ! lambda(x) = (1 + x/xi*(nq)) * product (1 + x/xi(i) ) .
2505 ! for the adams formulas,
2507 ! (d/dx) lambda(x) = c * product (1 + x/xi(i) ) ,
2509 ! lambda(-1) = 0, lambda(0) = 1,
2510 ! where c is a normalization constant.
2511 ! in both cases, xi(i) is defined by
2512 ! h*xi(i) = t sub n - t sub (n-i)
2513 ! = h + tau(1) + tau(2) + ... tau(i-1).
2516 ! in addition to variables described previously, communication
2517 ! with dvset uses the following:
2518 ! tau = a vector of length 13 containing the past nq values
2520 ! el = a vector of length 13 in which vset stores the
2521 ! coefficients for the corrector formula.
2522 ! tq = a vector of length 5 in which vset stores constants
2523 ! used for the convergence test, the error test, and the
2524 ! selection of h at a new order.
2525 ! meth = the basic method indicator.
2526 ! nq = the current order.
2527 ! l = nq + 1, the length of the vector stored in el, and
2528 ! the number of columns of the yh array being used.
2529 ! nqwait = a counter controlling the frequency of order changes.
2530 ! an order change is about to be considered if nqwait = 1.
2531 !-----------------------------------------------------------------------
2533 ! type declarations for labeled common block dvod_cmn01 --------------------
2535 ! double precision acnrm, ccmxj, conp, crate, drc, el, &
2536 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
2537 ! rc, rl1, tau, tq, tn, uround
2538 ! integer icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
2539 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
2540 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
2541 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
2544 ! type declarations for local variables --------------------------------
2546 double precision ahatn0, alph0, cnqm1, cortes, csum, elp, em, &
2547 em0, floti, flotl, flotnq, hsum, one, rxi, rxis, s, six, &
2548 t1, t2, t3, t4, t5, t6, two, xi, zero
2549 integer i, iback, j, jp1, nqm1, nqm2
2552 !-----------------------------------------------------------------------
2553 ! the following fortran-77 declaration is to cause the values of the
2554 ! listed (local) variables to be saved between calls to this integrator.
2555 !-----------------------------------------------------------------------
2556 save cortes, one, six, two, zero
2558 ! common /dvod_cmn01/ acnrm, ccmxj, conp, crate, drc, el(13), &
2559 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
2560 ! rc, rl1, tau(13), tq(5), tn, uround, &
2561 ! icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
2562 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
2563 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
2564 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
2568 data one /1.0d0/, six /6.0d0/, two /2.0d0/, zero /0.0d0/
2570 flotl = real(cmn12%l)
2573 go to (100, 200), cmn12%meth
2575 ! set coefficients for adams methods. ----------------------------------
2576 100 if (cmn12%nq .ne. 1) go to 110
2581 cmn12%tq(3) = six*cmn12%tq(2)
2586 flotnq = flotl - one
2587 do 115 i = 2, cmn12%l
2590 if ((j .ne. nqm1) .or. (cmn12%nqwait .ne. 1)) go to 130
2594 csum = csum + s*em(i)/real(i+1)
2596 cmn12%tq(1) = em(nqm1)/(flotnq*csum)
2597 130 rxi = cmn12%h/hsum
2600 140 em(i) = em(i) + em(i-1)*rxi
2601 hsum = hsum + cmn12%tau(j)
2603 ! compute integral from -1 to 0 of polynomial and of x times it. -------
2607 do 160 i = 1, cmn12%nq
2609 em0 = em0 + s*em(i)/floti
2610 csum = csum + s*em(i)/(floti+one)
2612 ! in el, form coefficients of normalized integrated polynomial. --------
2615 do 170 i = 1, cmn12%nq
2616 170 cmn12%el(i+1) = s*em(i)/real(i)
2618 cmn12%tq(2) = xi*em0/csum
2619 cmn12%tq(5) = xi/cmn12%el(cmn12%l)
2620 if (cmn12%nqwait .ne. 1) go to 300
2621 ! for higher order control constant, multiply polynomial by 1+x/xi(q). -
2623 do 180 iback = 1, cmn12%nq
2624 i = (cmn12%l + 1) - iback
2625 180 em(i) = em(i) + em(i-1)*rxi
2626 ! compute integral of polynomial. --------------------------------------
2629 do 190 i = 1, cmn12%l
2630 csum = csum + s*em(i)/real(i+1)
2632 cmn12%tq(3) = flotl*em0/csum
2635 ! set coefficients for bdf methods. ------------------------------------
2636 200 do 210 i = 3, cmn12%l
2637 210 cmn12%el(i) = zero
2645 if (cmn12%nq .eq. 1) go to 240
2647 ! in el, construct coefficients of (1+x/xi(1))*...*(1+x/xi(j+1)). ------
2648 hsum = hsum + cmn12%tau(j)
2651 alph0 = alph0 - one/real(jp1)
2652 do 220 iback = 1, jp1
2654 220 cmn12%el(i) = cmn12%el(i) + cmn12%el(i-1)*rxi
2656 alph0 = alph0 - one/real(cmn12%nq)
2657 rxis = -cmn12%el(2) - alph0
2658 hsum = hsum + cmn12%tau(nqm1)
2660 ahatn0 = -cmn12%el(2) - rxi
2661 do 235 iback = 1, cmn12%nq
2662 i = (cmn12%nq + 2) - iback
2663 235 cmn12%el(i) = cmn12%el(i) + cmn12%el(i-1)*rxis
2664 240 t1 = one - ahatn0 + alph0
2665 t2 = one + real(cmn12%nq)*t1
2666 cmn12%tq(2) = abs(alph0*t2/t1)
2667 cmn12%tq(5) = abs(t2/(cmn12%el(cmn12%l)*rxi/rxis))
2668 if (cmn12%nqwait .ne. 1) go to 300
2669 cnqm1 = rxis/cmn12%el(cmn12%l)
2670 t3 = alph0 + one/real(cmn12%nq)
2672 elp = t3/(one - t4 + t3)
2673 cmn12%tq(1) = abs(elp/cnqm1)
2674 hsum = hsum + cmn12%tau(cmn12%nq)
2676 t5 = alph0 - one/real(cmn12%nq+1)
2678 elp = t2/(one - t6 + t5)
2679 cmn12%tq(3) = abs(elp*rxi*(flotl + one)*t5)
2680 300 cmn12%tq(4) = cortes*cmn12%tq(2)
2682 !----------------------- end of subroutine dvset -----------------------
2683 end subroutine dvset
2685 subroutine dvjust (yh, ldyh, iord, cmn12)
2689 dimension yh(ldyh,*)
2690 type( dvode_cmn_vars ) :: cmn12
2691 !-----------------------------------------------------------------------
2692 ! call sequence input -- yh, ldyh, iord
2693 ! call sequence output -- yh
2694 ! common block input -- nq, meth, lmax, hscal, tau(13), n
2695 ! common block variables accessed:
2696 ! /dvod_cmn01/ -- hscal, tau(13), lmax, meth, n, nq,
2698 ! subroutines called by dvjust: daxpy
2699 ! function routines called by dvjust: none
2700 !-----------------------------------------------------------------------
2701 ! this subroutine adjusts the yh array on reduction of order,
2702 ! and also when the order is increased for the stiff option (meth = 2).
2703 ! communication with dvjust uses the following:
2704 ! iord = an integer flag used when meth = 2 to indicate an order
2705 ! increase (iord = +1) or an order decrease (iord = -1).
2706 ! hscal = step size h used in scaling of nordsieck array yh.
2707 ! (if iord = +1, dvjust assumes that hscal = tau(1).)
2708 ! see references 1 and 2 for details.
2709 !-----------------------------------------------------------------------
2711 ! type declarations for labeled common block dvod_cmn01 --------------------
2713 ! double precision acnrm, ccmxj, conp, crate, drc, el, &
2714 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
2715 ! rc, rl1, tau, tq, tn, uround
2716 ! integer icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
2717 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
2718 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
2719 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
2722 ! type declarations for local variables --------------------------------
2724 double precision alph0, alph1, hsum, one, prod, t1, xi,xiold, zero
2725 integer i, iback, j, jp1, lp1, nqm1, nqm2, nqp1
2726 !-----------------------------------------------------------------------
2727 ! the following fortran-77 declaration is to cause the values of the
2728 ! listed (local) variables to be saved between calls to this integrator.
2729 !-----------------------------------------------------------------------
2732 ! common /dvod_cmn01/ acnrm, ccmxj, conp, crate, drc, el(13), &
2733 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
2734 ! rc, rl1, tau(13), tq(5), tn, uround, &
2735 ! icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
2736 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
2737 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
2738 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
2741 data one /1.0d0/, zero /0.0d0/
2743 if ((cmn12%nq .eq. 2) .and. (iord .ne. 1)) return
2746 go to (100, 200), cmn12%meth
2747 !-----------------------------------------------------------------------
2748 ! nonstiff option...
2749 ! check to see if the order is being increased or decreased.
2750 !-----------------------------------------------------------------------
2752 if (iord .eq. 1) go to 180
2753 ! order decrease. ------------------------------------------------------
2754 do 110 j = 1, cmn12%lmax
2755 110 cmn12%el(j) = zero
2759 ! construct coefficients of x*(x+xi(1))*...*(x+xi(j)). -----------------
2760 hsum = hsum + cmn12%tau(j)
2761 xi = hsum/cmn12%hscal
2763 do 120 iback = 1, jp1
2765 120 cmn12%el(i) = cmn12%el(i)*xi + cmn12%el(i-1)
2767 ! construct coefficients of integrated polynomial. ---------------------
2769 140 cmn12%el(j+1) = real(cmn12%nq)*cmn12%el(j)/real(j)
2770 ! subtract correction terms from yh array. -----------------------------
2771 do 170 j = 3, cmn12%nq
2772 do 160 i = 1, cmn12%n
2773 160 yh(i,j) = yh(i,j) - yh(i,cmn12%l)*cmn12%el(j)
2776 ! order increase. ------------------------------------------------------
2777 ! zero out next column in yh array. ------------------------------------
2780 do 190 i = 1, cmn12%n
2781 190 yh(i,lp1) = zero
2783 !-----------------------------------------------------------------------
2785 ! check to see if the order is being increased or decreased.
2786 !-----------------------------------------------------------------------
2788 if (iord .eq. 1) go to 300
2789 ! order decrease. ------------------------------------------------------
2790 do 210 j = 1, cmn12%lmax
2791 210 cmn12%el(j) = zero
2795 ! construct coefficients of x*x*(x+xi(1))*...*(x+xi(j)). ---------------
2796 hsum = hsum + cmn12%tau(j)
2797 xi = hsum/cmn12%hscal
2799 do 220 iback = 1, jp1
2801 220 cmn12%el(i) = cmn12%el(i)*xi + cmn12%el(i-1)
2803 ! subtract correction terms from yh array. -----------------------------
2804 do 250 j = 3,cmn12%nq
2805 do 240 i = 1, cmn12%n
2806 240 yh(i,j) = yh(i,j) - yh(i,cmn12%l)*cmn12%el(j)
2809 ! order increase. ------------------------------------------------------
2810 300 do 310 j = 1, cmn12%lmax
2811 310 cmn12%el(j) = zero
2818 if (cmn12%nq .eq. 1) go to 340
2820 ! construct coefficients of x*x*(x+xi(1))*...*(x+xi(j)). ---------------
2822 hsum = hsum + cmn12%tau(jp1)
2823 xi = hsum/cmn12%hscal
2825 alph0 = alph0 - one/real(jp1)
2826 alph1 = alph1 + one/xi
2827 do 320 iback = 1, jp1
2829 320 cmn12%el(i) = cmn12%el(i)*xiold + cmn12%el(i-1)
2833 t1 = (-alph0 - alph1)/prod
2834 ! load column l + 1 in yh array. ---------------------------------------
2836 do 350 i = 1, cmn12%n
2837 350 yh(i,lp1) = t1*yh(i,cmn12%lmax)
2838 ! add correction terms to yh array. ------------------------------------
2841 call daxpy (cmn12%n, cmn12%el(j), yh(1,lp1), 1, yh(1,j), 1 )
2844 !----------------------- end of subroutine dvjust ----------------------
2845 end subroutine dvjust
2847 subroutine dvnlsd (y, yh, ldyh, vsav, savf, ewt, acor, iwm, wm, &
2848 f, jac, pdum, nflag, rpar, ipar, cmn12)
2850 external f, jac, pdum
2851 double precision y, yh, vsav, savf, ewt, acor, wm, rpar
2852 integer ldyh, iwm, nflag, ipar
2853 dimension y(*), yh(ldyh,*), vsav(*), savf(*), ewt(*), acor(*), &
2854 iwm(*), wm(*), rpar(*), ipar(*)
2855 type( dvode_cmn_vars ) :: cmn12
2856 !-----------------------------------------------------------------------
2857 ! call sequence input -- y, yh, ldyh, savf, ewt, acor, iwm, wm,
2858 ! f, jac, nflag, rpar, ipar
2859 ! call sequence output -- yh, acor, wm, iwm, nflag
2860 ! common block variables accessed:
2861 ! /dvod_cmn01/ acnrm, crate, drc, h, rc, rl1, tq(5), tn, icf,
2862 ! jcur, meth, miter, n, nslp
2863 ! /dvod_cmn02/ hu, ncfn, netf, nfe, nje, nlu, nni, nqu, nst
2865 ! subroutines called by dvnlsd: f, daxpy, dcopy, dscal, dvjac, dvsol
2866 ! function routines called by dvnlsd: dvnorm
2867 !-----------------------------------------------------------------------
2868 ! subroutine dvnlsd is a nonlinear system solver, which uses functional
2869 ! iteration or a chord (modified newton) method. for the chord method
2870 ! direct linear algebraic system solvers are used. subroutine dvnlsd
2871 ! then handles the corrector phase of this integration package.
2873 ! communication with dvnlsd is done with the following variables. (for
2874 ! more details, please see the comments in the driver subroutine.)
2876 ! y = the dependent variable, a vector of length n, input.
2877 ! yh = the nordsieck (taylor) array, ldyh by lmax, input
2878 ! and output. on input, it contains predicted values.
2879 ! ldyh = a constant .ge. n, the first dimension of yh, input.
2880 ! vsav = unused work array.
2881 ! savf = a work array of length n.
2882 ! ewt = an error weight vector of length n, input.
2883 ! acor = a work array of length n, used for the accumulated
2884 ! corrections to the predicted y vector.
2885 ! wm,iwm = real and integer work arrays associated with matrix
2886 ! operations in chord iteration (miter .ne. 0).
2887 ! f = dummy name for user supplied routine for f.
2888 ! jac = dummy name for user supplied jacobian routine.
2889 ! pdum = unused dummy subroutine name. included for uniformity
2890 ! over collection of integrators.
2891 ! nflag = input/output flag, with values and meanings as follows:
2893 ! 0 first call for this time step.
2894 ! -1 convergence failure in previous call to dvnlsd.
2895 ! -2 error test failure in dvstep.
2897 ! 0 successful completion of nonlinear solver.
2898 ! -1 convergence failure or singular matrix.
2899 ! -2 unrecoverable error in matrix preprocessing
2900 ! (cannot occur here).
2901 ! -3 unrecoverable error in solution (cannot occur
2903 ! rpar, ipar = dummy names for user's real and integer work arrays.
2905 ! ipup = own variable flag with values and meanings as follows:
2906 ! 0, do not update the newton matrix.
2907 ! miter .ne. 0, update newton matrix, because it is the
2908 ! initial step, order was changed, the error
2909 ! test failed, or an update is indicated by
2910 ! the scalar rc or step counter nst.
2912 ! for more details, see comments in driver subroutine.
2913 !-----------------------------------------------------------------------
2914 !! type declarations for labeled common block dvod_cmn01 --------------------
2916 ! double precision acnrm, ccmxj, conp, crate, drc, el, &
2917 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
2918 ! rc, rl1, tau, tq, tn, uround
2919 ! integer icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
2920 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
2921 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
2922 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
2925 !! type declarations for labeled common block dvod_cmn02 --------------------
2927 ! double precision hu
2928 ! integer ncfn, netf, nfe, nje, nlu, nni, nqu, nst
2930 ! type declarations for local variables --------------------------------
2932 double precision ccmax, crdown, cscale, dcon, del, delp, one, &
2934 integer i, ierpj, iersl, m, maxcor, msbp
2936 ! type declaration for function subroutines called ---------------------
2938 ! 27-oct-2005 rce - do not declare functions that are in the module
2939 ! double precision dvnorm
2940 !-----------------------------------------------------------------------
2941 ! the following fortran-77 declaration is to cause the values of the
2942 ! listed (local) variables to be saved between calls to this integrator.
2943 !-----------------------------------------------------------------------
2944 save ccmax, crdown, maxcor, msbp, rdiv, one, two, zero
2946 ! common /dvod_cmn01/ acnrm, ccmxj, conp, crate, drc, el(13), &
2947 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
2948 ! rc, rl1, tau(13), tq(5), tn, uround, &
2949 ! icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
2950 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
2951 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
2952 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
2954 ! common /dvod_cmn02/ hu, ncfn, netf, nfe, nje, nlu, nni, nqu, nst
2956 data ccmax /0.3d0/, crdown /0.3d0/, maxcor /3/, msbp /20/, &
2958 data one /1.0d0/, two /2.0d0/, zero /0.0d0/
2959 !-----------------------------------------------------------------------
2960 ! on the first step, on a change of method order, or after a
2961 ! nonlinear convergence failure with nflag = -2, set ipup = miter
2962 ! to force a jacobian update when miter .ne. 0.
2963 !-----------------------------------------------------------------------
2964 if (cmn12%jstart .eq. 0) cmn12%nslp = 0
2965 if (nflag .eq. 0) cmn12%icf = 0
2966 if (nflag .eq. -2) cmn12%ipup = cmn12%miter
2967 if ( (cmn12%jstart .eq. 0) .or. (cmn12%jstart .eq. -1) ) cmn12%ipup = cmn12%miter
2968 ! if this is functional iteration, set crate .eq. 1 and drop to 220
2969 if (cmn12%miter .eq. 0) then
2973 !-----------------------------------------------------------------------
2974 ! rc is the ratio of new to old values of the coefficient h/el(2)=h/l1.
2975 ! when rc differs from 1 by more than ccmax, ipup is set to miter
2976 ! to force dvjac to be called, if a jacobian is involved.
2977 ! in any case, dvjac is called at least every msbp steps.
2978 !-----------------------------------------------------------------------
2979 cmn12%drc = abs(cmn12%rc-one)
2980 if (cmn12%drc .gt. ccmax .or. cmn12%nst .ge. cmn12%nslp+msbp) cmn12%ipup = cmn12%miter
2981 !-----------------------------------------------------------------------
2982 ! up to maxcor corrector iterations are taken. a convergence test is
2983 ! made on the r.m.s. norm of each correction, weighted by the error
2984 ! weight vector ewt. the sum of the corrections is accumulated in the
2985 ! vector acor(i). the yh array is not altered in the corrector loop.
2986 !-----------------------------------------------------------------------
2989 call dcopy (cmn12%n, yh(1,1), 1, y, 1 )
2990 call f (cmn12%n, cmn12%tn, y, savf, rpar, ipar)
2991 cmn12%nfe = cmn12%nfe + 1
2992 if (cmn12%ipup .le. 0) go to 250
2993 !-----------------------------------------------------------------------
2994 ! if indicated, the matrix p = i - h*rl1*j is reevaluated and
2995 ! preprocessed before starting the corrector iteration. ipup is set
2996 ! to 0 as an indicator that this has been done.
2997 !-----------------------------------------------------------------------
2998 call dvjac (y, yh, ldyh, ewt, acor, savf, wm, iwm, f, jac, ierpj, &
3004 cmn12%nslp = cmn12%nst
3005 ! if matrix is singular, take error return to force cut in step size. --
3006 if (ierpj .ne. 0) go to 430
3007 250 do 260 i = 1,cmn12%n
3009 ! this is a looping point for the corrector iteration. -----------------
3010 270 if (cmn12%miter .ne. 0) go to 350
3011 !-----------------------------------------------------------------------
3012 ! in the case of functional iteration, update y directly from
3013 ! the result of the last function evaluation.
3014 !-----------------------------------------------------------------------
3015 do 280 i = 1,cmn12%n
3016 280 savf(i) = cmn12%rl1*(cmn12%h*savf(i) - yh(i,2))
3017 do 290 i = 1,cmn12%n
3018 290 y(i) = savf(i) - acor(i)
3019 del = dvnorm (cmn12%n, y, ewt)
3020 do 300 i = 1,cmn12%n
3021 300 y(i) = yh(i,1) + savf(i)
3022 call dcopy (cmn12%n, savf, 1, acor, 1)
3024 !-----------------------------------------------------------------------
3025 ! in the case of the chord method, compute the corrector error,
3026 ! and solve the linear system with that as right-hand side and
3027 ! p as coefficient matrix. the correction is scaled by the factor
3028 ! 2/(1+rc) to account for changes in h*rl1 since the last dvjac call.
3029 !-----------------------------------------------------------------------
3030 350 do 360 i = 1,cmn12%n
3031 360 y(i) = (cmn12%rl1*cmn12%h)*savf(i) - (cmn12%rl1*yh(i,2) + acor(i))
3032 call dvsol (wm, iwm, y, iersl, cmn12)
3033 cmn12%nni = cmn12%nni + 1
3034 if (iersl .gt. 0) go to 410
3035 if (cmn12%meth .eq. 2 .and. cmn12%rc .ne. one) then
3036 cscale = two/(one + cmn12%rc)
3037 call dscal (cmn12%n, cscale, y, 1)
3039 del = dvnorm (cmn12%n, y, ewt)
3040 call daxpy (cmn12%n, one, y, 1, acor, 1)
3041 do 380 i = 1,cmn12%n
3042 380 y(i) = yh(i,1) + acor(i)
3043 !-----------------------------------------------------------------------
3044 ! test for convergence. if m .gt. 0, an estimate of the convergence
3045 ! rate constant is stored in crate, and this is used in the test.
3046 !-----------------------------------------------------------------------
3047 400 if (m .ne. 0) cmn12%crate = max(crdown*cmn12%crate,del/delp)
3048 dcon = del*min(one,cmn12%crate)/cmn12%tq(4)
3049 if (dcon .le. one) go to 450
3051 if (m .eq. maxcor) go to 410
3052 if (m .ge. 2 .and. del .gt. rdiv*delp) go to 410
3054 call f (cmn12%n, cmn12%tn, y, savf, rpar, ipar)
3055 cmn12%nfe = cmn12%nfe + 1
3058 410 if (cmn12%miter .eq. 0 .or. cmn12%jcur .eq. 1) go to 430
3060 cmn12%ipup = cmn12%miter
3066 cmn12%ipup = cmn12%miter
3069 ! return for successful step. ------------------------------------------
3073 if (m .eq. 0) cmn12%acnrm = del
3074 if (m .gt. 0) cmn12%acnrm = dvnorm (cmn12%n, acor, ewt)
3076 !----------------------- end of subroutine dvnlsd ----------------------
3077 end subroutine dvnlsd
3079 subroutine dvjac (y, yh, ldyh, ewt, ftem, savf, wm, iwm, f, jac, &
3080 ierpj, rpar, ipar, cmn12)
3083 double precision y, yh, ewt, ftem, savf, wm, rpar
3084 integer ldyh, iwm, ierpj, ipar
3085 dimension y(*), yh(ldyh,*), ewt(*), ftem(*), savf(*), &
3086 wm(*), iwm(*), rpar(*), ipar(*)
3087 type( dvode_cmn_vars ) :: cmn12
3088 !-----------------------------------------------------------------------
3089 ! call sequence input -- y, yh, ldyh, ewt, ftem, savf, wm, iwm,
3090 ! f, jac, rpar, ipar
3091 ! call sequence output -- wm, iwm, ierpj
3092 ! common block variables accessed:
3093 ! /dvod_cmn01/ ccmxj, drc, h, rl1, tn, uround, icf, jcur, locjs,
3094 ! miter, msbj, n, nslj
3095 ! /dvod_cmn02/ nfe, nst, nje, nlu
3097 ! subroutines called by dvjac: f, jac, dacopy, dcopy, dgbfa, dgefa,
3099 ! function routines called by dvjac: dvnorm
3100 !-----------------------------------------------------------------------
3101 ! dvjac is called by dvnlsd to compute and process the matrix
3102 ! p = i - h*rl1*j , where j is an approximation to the jacobian.
3103 ! here j is computed by the user-supplied routine jac if
3104 ! miter = 1 or 4, or by finite differencing if miter = 2, 3, or 5.
3105 ! if miter = 3, a diagonal approximation to j is used.
3106 ! if jsv = -1, j is computed from scratch in all cases.
3107 ! if jsv = 1 and miter = 1, 2, 4, or 5, and if the saved value of j is
3108 ! considered acceptable, then p is constructed from the saved j.
3109 ! j is stored in wm and replaced by p. if miter .ne. 3, p is then
3110 ! subjected to lu decomposition in preparation for later solution
3111 ! of linear systems with p as coefficient matrix. this is done
3112 ! by dgefa if miter = 1 or 2, and by dgbfa if miter = 4 or 5.
3114 ! communication with dvjac is done with the following variables. (for
3115 ! more details, please see the comments in the driver subroutine.)
3116 ! y = vector containing predicted values on entry.
3117 ! yh = the nordsieck array, an ldyh by lmax array, input.
3118 ! ldyh = a constant .ge. n, the first dimension of yh, input.
3119 ! ewt = an error weight vector of length n.
3120 ! savf = array containing f evaluated at predicted y, input.
3121 ! wm = real work space for matrices. in the output, it contains
3122 ! the inverse diagonal matrix if miter = 3 and the lu
3123 ! decomposition of p if miter is 1, 2 , 4, or 5.
3124 ! storage of matrix elements starts at wm(3).
3125 ! storage of the saved jacobian starts at wm(locjs).
3126 ! wm also contains the following matrix-related data:
3127 ! wm(1) = sqrt(uround), used in numerical jacobian step.
3128 ! wm(2) = h*rl1, saved for later use if miter = 3.
3129 ! iwm = integer work space containing pivot information,
3130 ! starting at iwm(31), if miter is 1, 2, 4, or 5.
3131 ! iwm also contains band parameters ml = iwm(1) and
3132 ! mu = iwm(2) if miter is 4 or 5.
3133 ! f = dummy name for the user supplied subroutine for f.
3134 ! jac = dummy name for the user supplied jacobian subroutine.
3135 ! rpar, ipar = dummy names for user's real and integer work arrays.
3136 ! rl1 = 1/el(2) (input).
3137 ! ierpj = output error flag, = 0 if no trouble, 1 if the p
3138 ! matrix is found to be singular.
3139 ! jcur = output flag to indicate whether the jacobian matrix
3140 ! (or approximation) is now current.
3141 ! jcur = 0 means j is not current.
3142 ! jcur = 1 means j is current.
3143 !-----------------------------------------------------------------------
3145 !! type declarations for labeled common block dvod_cmn01 --------------------
3147 ! double precision acnrm, ccmxj, conp, crate, drc, el, &
3148 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
3149 ! rc, rl1, tau, tq, tn, uround
3150 ! integer icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
3151 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
3152 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
3153 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
3156 !! type declarations for labeled common block dvod_cmn02 --------------------
3158 ! double precision hu
3159 ! integer ncfn, netf, nfe, nje, nlu, nni, nqu, nst
3161 ! type declarations for local variables --------------------------------
3163 double precision con, di, fac, hrl1, one, pt1, r, r0, srur, thou, &
3165 integer i, i1, i2, ier, ii, j, j1, jj, jok, lenp, mba, mband, &
3166 meb1, meband, ml, ml3, mu, np1
3168 ! type declaration for function subroutines called ---------------------
3170 ! 27-oct-2005 rce - do not declare functions that are in the module
3171 ! double precision dvnorm
3172 !-----------------------------------------------------------------------
3173 ! the following fortran-77 declaration is to cause the values of the
3174 ! listed (local) variables to be saved between calls to this subroutine.
3175 !-----------------------------------------------------------------------
3176 save one, pt1, thou, zero
3177 !-----------------------------------------------------------------------
3178 ! common /dvod_cmn01/ acnrm, ccmxj, conp, crate, drc, el(13), &
3179 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
3180 ! rc, rl1, tau(13), tq(5), tn, uround, &
3181 ! icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
3182 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
3183 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
3184 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
3186 ! common /dvod_cmn02/ hu, ncfn, netf, nfe, nje, nlu, nni, nqu, nst
3188 data one /1.0d0/, thou /1000.0d0/, zero /0.0d0/, pt1 /0.1d0/
3191 hrl1 = cmn12%h*cmn12%rl1
3192 ! see whether j should be evaluated (jok = -1) or not (jok = 1). -------
3194 if (cmn12%jsv .eq. 1) then
3195 if (cmn12%nst .eq. 0 .or. cmn12%nst .gt. cmn12%nslj+cmn12%msbj) jok = -1
3196 if (cmn12%icf .eq. 1 .and. cmn12%drc .lt. cmn12%ccmxj) jok = -1
3197 if (cmn12%icf .eq. 2) jok = -1
3199 ! end of setting jok. --------------------------------------------------
3201 if (jok .eq. -1 .and. cmn12%miter .eq. 1) then
3202 ! if jok = -1 and miter = 1, call jac to evaluate jacobian. ------------
3203 cmn12%nje = cmn12%nje + 1
3204 cmn12%nslj = cmn12%nst
3206 lenp = cmn12%n*cmn12%n
3209 call jac (cmn12%n, cmn12%tn, y, 0, 0, wm(3), cmn12%n, rpar, ipar)
3210 if (cmn12%jsv .eq. 1) call dcopy (lenp, wm(3), 1, wm(cmn12%locjs), 1)
3213 if (jok .eq. -1 .and. cmn12%miter .eq. 2) then
3214 ! if miter = 2, make n calls to f to approximate the jacobian. ---------
3215 cmn12%nje = cmn12%nje + 1
3216 cmn12%nslj = cmn12%nst
3218 fac = dvnorm (cmn12%n, savf, ewt)
3219 r0 = thou*abs(cmn12%h)*cmn12%uround*real(cmn12%n)*fac
3220 if (r0 .eq. zero) r0 = one
3223 do 230 j = 1,cmn12%n
3225 r = max(srur*abs(yj),r0/ewt(j))
3228 call f (cmn12%n, cmn12%tn, y, ftem, rpar, ipar)
3229 do 220 i = 1,cmn12%n
3230 220 wm(i+j1) = (ftem(i) - savf(i))*fac
3234 cmn12%nfe = cmn12%nfe + cmn12%n
3235 lenp = cmn12%n*cmn12%n
3236 if (cmn12%jsv .eq. 1) call dcopy (lenp, wm(3), 1, wm(cmn12%locjs), 1)
3239 if (jok .eq. 1 .and. (cmn12%miter .eq. 1 .or. cmn12%miter .eq. 2)) then
3241 lenp = cmn12%n*cmn12%n
3242 call dcopy (lenp, wm(cmn12%locjs), 1, wm(3), 1)
3245 if (cmn12%miter .eq. 1 .or. cmn12%miter .eq. 2) then
3246 ! multiply jacobian by scalar, add identity, and do lu decomposition. --
3248 call dscal (lenp, con, wm(3), 1)
3251 do 250 i = 1,cmn12%n
3254 cmn12%nlu = cmn12%nlu + 1
3255 call dgefa (wm(3), cmn12%n, cmn12%n, iwm(31), ier)
3256 if (ier .ne. 0) ierpj = 1
3259 ! end of code block for miter = 1 or 2. --------------------------------
3261 if (cmn12%miter .eq. 3) then
3262 ! if miter = 3, construct a diagonal approximation to j and p. ---------
3263 cmn12%nje = cmn12%nje + 1
3267 do 310 i = 1,cmn12%n
3268 310 y(i) = y(i) + r*(cmn12%h*savf(i) - yh(i,2))
3269 call f (cmn12%n, cmn12%tn, y, wm(3), rpar, ipar)
3270 cmn12%nfe = cmn12%nfe + 1
3271 do 320 i = 1,cmn12%n
3272 r0 = cmn12%h*savf(i) - yh(i,2)
3273 di = pt1*r0 - cmn12%h*(wm(i+2) - savf(i))
3275 if (abs(r0) .lt. cmn12%uround/ewt(i)) go to 320
3276 if (abs(di) .eq. zero) go to 330
3283 ! end of code block for miter = 3. -------------------------------------
3285 ! set constants for miter = 4 or 5. ------------------------------------
3291 lenp = meband*cmn12%n
3293 if (jok .eq. -1 .and. cmn12%miter .eq. 4) then
3294 ! if jok = -1 and miter = 4, call jac to evaluate jacobian. ------------
3295 cmn12%nje = cmn12%nje + 1
3296 cmn12%nslj = cmn12%nst
3300 call jac (cmn12%n, cmn12%tn, y, ml, mu, wm(ml3), meband, rpar, ipar)
3301 if (cmn12%jsv .eq. 1) &
3302 call dacopy (mband, cmn12%n, wm(ml3), meband, wm(cmn12%locjs), mband)
3305 if (jok .eq. -1 .and. cmn12%miter .eq. 5) then
3306 ! if miter = 5, make ml+mu+1 calls to f to approximate the jacobian. ---
3307 cmn12%nje = cmn12%nje + 1
3308 cmn12%nslj = cmn12%nst
3310 mba = min(mband,cmn12%n)
3313 fac = dvnorm (cmn12%n, savf, ewt)
3314 r0 = thou*abs(cmn12%h)*cmn12%uround*real(cmn12%n)*fac
3315 if (r0 .eq. zero) r0 = one
3317 do 530 i = j,cmn12%n,mband
3319 r = max(srur*abs(yi),r0/ewt(i))
3321 call f (cmn12%n, cmn12%tn, y, ftem, rpar, ipar)
3322 do 550 jj = j,cmn12%n,mband
3325 r = max(srur*abs(yjj),r0/ewt(jj))
3328 i2 = min(jj+ml,cmn12%n)
3329 ii = jj*meb1 - ml + 2
3331 540 wm(ii+i) = (ftem(i) - savf(i))*fac
3334 cmn12%nfe = cmn12%nfe + mba
3335 if (cmn12%jsv .eq. 1) &
3336 call dacopy (mband, cmn12%n, wm(ml3), meband, wm(cmn12%locjs), mband)
3339 if (jok .eq. 1) then
3341 call dacopy (mband, cmn12%n, wm(cmn12%locjs), mband, wm(ml3), meband)
3344 ! multiply jacobian by scalar, add identity, and do lu decomposition.
3346 call dscal (lenp, con, wm(3), 1 )
3348 do 580 i = 1,cmn12%n
3349 wm(ii) = wm(ii) + one
3350 580 ii = ii + meband
3351 cmn12%nlu = cmn12%nlu + 1
3352 call dgbfa (wm(3), meband, cmn12%n, ml, mu, iwm(31), ier)
3353 if (ier .ne. 0) ierpj = 1
3355 ! end of code block for miter = 4 or 5. --------------------------------
3357 !----------------------- end of subroutine dvjac -----------------------
3358 end subroutine dvjac
3360 subroutine dacopy (nrow, ncol, a, nrowa, b, nrowb)
3361 double precision a, b
3362 integer nrow, ncol, nrowa, nrowb
3363 dimension a(nrowa,ncol), b(nrowb,ncol)
3364 !-----------------------------------------------------------------------
3365 ! call sequence input -- nrow, ncol, a, nrowa, nrowb
3366 ! call sequence output -- b
3367 ! common block variables accessed -- none
3369 ! subroutines called by dacopy: dcopy
3370 ! function routines called by dacopy: none
3371 !-----------------------------------------------------------------------
3372 ! this routine copies one rectangular array, a, to another, b,
3373 ! where a and b may have different row dimensions, nrowa and nrowb.
3374 ! the data copied consists of nrow rows and ncol columns.
3375 !-----------------------------------------------------------------------
3379 call dcopy (nrow, a(1,ic), 1, b(1,ic), 1)
3383 !----------------------- end of subroutine dacopy ----------------------
3384 end subroutine dacopy
3386 subroutine dvsol (wm, iwm, x, iersl, cmn12)
3388 double precision wm, x
3390 dimension wm(*), iwm(*), x(*)
3391 type( dvode_cmn_vars ) :: cmn12
3392 !-----------------------------------------------------------------------
3393 ! call sequence input -- wm, iwm, x
3394 ! call sequence output -- x, iersl
3395 ! common block variables accessed:
3396 ! /dvod_cmn01/ -- h, rl1, miter, n
3398 ! subroutines called by dvsol: dgesl, dgbsl
3399 ! function routines called by dvsol: none
3400 !-----------------------------------------------------------------------
3401 ! this routine manages the solution of the linear system arising from
3402 ! a chord iteration. it is called if miter .ne. 0.
3403 ! if miter is 1 or 2, it calls dgesl to accomplish this.
3404 ! if miter = 3 it updates the coefficient h*rl1 in the diagonal
3405 ! matrix, and then computes the solution.
3406 ! if miter is 4 or 5, it calls dgbsl.
3407 ! communication with dvsol uses the following variables:
3408 ! wm = real work space containing the inverse diagonal matrix if
3409 ! miter = 3 and the lu decomposition of the matrix otherwise.
3410 ! storage of matrix elements starts at wm(3).
3411 ! wm also contains the following matrix-related data:
3412 ! wm(1) = sqrt(uround) (not used here),
3413 ! wm(2) = hrl1, the previous value of h*rl1, used if miter = 3.
3414 ! iwm = integer work space containing pivot information, starting at
3415 ! iwm(31), if miter is 1, 2, 4, or 5. iwm also contains band
3416 ! parameters ml = iwm(1) and mu = iwm(2) if miter is 4 or 5.
3417 ! x = the right-hand side vector on input, and the solution vector
3418 ! on output, of length n.
3419 ! iersl = output flag. iersl = 0 if no trouble occurred.
3420 ! iersl = 1 if a singular matrix arose with miter = 3.
3421 !-----------------------------------------------------------------------
3423 !! type declarations for labeled common block dvod_cmn01 --------------------
3425 ! double precision acnrm, ccmxj, conp, crate, drc, el, &
3426 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
3427 ! rc, rl1, tau, tq, tn, uround
3428 ! integer icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
3429 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
3430 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
3431 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
3434 ! type declarations for local variables --------------------------------
3436 integer i, meband, ml, mu
3437 double precision di, hrl1, one, phrl1, r, zero
3438 !-----------------------------------------------------------------------
3439 ! the following fortran-77 declaration is to cause the values of the
3440 ! listed (local) variables to be saved between calls to this integrator.
3441 !-----------------------------------------------------------------------
3444 ! common /dvod_cmn01/ acnrm, ccmxj, conp, crate, drc, el(13), &
3445 ! eta, etamax, h, hmin, hmxi, hnew, hscal, prl1, &
3446 ! rc, rl1, tau(13), tq(5), tn, uround, &
3447 ! icf, init, ipup, jcur, jstart, jsv, kflag, kuth, &
3448 ! l, lmax, lyh, lewt, lacor, lsavf, lwm, liwm, &
3449 ! locjs, maxord, meth, miter, msbj, mxhnil, mxstep, &
3450 ! n, newh, newq, nhnil, nq, nqnyh, nqwait, nslj, &
3453 data one /1.0d0/, zero /0.0d0/
3456 go to (100, 100, 300, 400, 400), cmn12%miter
3457 100 call dgesl (wm(3), cmn12%n, cmn12%n, iwm(31), x, 0)
3461 hrl1 = cmn12%h*cmn12%rl1
3463 if (hrl1 .eq. phrl1) go to 330
3465 do 320 i = 1,cmn12%n
3466 di = one - r*(one - one/wm(i+2))
3467 if (abs(di) .eq. zero) go to 390
3468 320 wm(i+2) = one/di
3470 330 do 340 i = 1,cmn12%n
3471 340 x(i) = wm(i+2)*x(i)
3478 meband = 2*ml + mu + 1
3479 call dgbsl (wm(3), meband, cmn12%n, ml, mu, iwm(31), x, 0)
3481 !----------------------- end of subroutine dvsol -----------------------
3482 end subroutine dvsol
3484 ! subroutine dvsrco (rsav, isav, job)
3485 ! double precision rsav
3487 ! dimension rsav(*), isav(*)
3488 !!-----------------------------------------------------------------------
3489 !! call sequence input -- rsav, isav, job
3490 !! call sequence output -- rsav, isav
3491 !! common block variables accessed -- all of /dvod_cmn01/ and /dvod_cmn02/
3493 !! subroutines/functions called by dvsrco: none
3494 !!-----------------------------------------------------------------------
3495 !! this routine saves or restores (depending on job) the contents of the
3496 !! common blocks dvod_cmn01 and dvod_cmn02, which are used internally by dvode.
3498 !! rsav = real array of length 49 or more.
3499 !! isav = integer array of length 41 or more.
3500 !! job = flag indicating to save or restore the common blocks:
3501 !! job = 1 if common is to be saved (written to rsav/isav).
3502 !! job = 2 if common is to be restored (read from rsav/isav).
3503 !! a call with job = 2 presumes a prior call with job = 1.
3504 !!-----------------------------------------------------------------------
3505 ! double precision rvod1, rvod2
3506 ! integer ivod1, ivod2
3507 ! integer i, leniv1, leniv2, lenrv1, lenrv2
3508 !!-----------------------------------------------------------------------
3509 !! the following fortran-77 declaration is to cause the values of the
3510 !! listed (local) variables to be saved between calls to this integrator.
3511 !!-----------------------------------------------------------------------
3512 ! save lenrv1, leniv1, lenrv2, leniv2
3514 ! common /dvod_cmn01/ rvod1(48), ivod1(33)
3515 ! common /dvod_cmn02/ rvod2(1), ivod2(8)
3516 ! data lenrv1/48/, leniv1/33/, lenrv2/1/, leniv2/8/
3518 ! if (job .eq. 2) go to 100
3519 ! do 10 i = 1,lenrv1
3520 ! 10 rsav(i) = rvod1(i)
3521 ! do 15 i = 1,lenrv2
3522 ! 15 rsav(lenrv1+i) = rvod2(i)
3524 ! do 20 i = 1,leniv1
3525 ! 20 isav(i) = ivod1(i)
3526 ! do 25 i = 1,leniv2
3527 ! 25 isav(leniv1+i) = ivod2(i)
3532 ! do 110 i = 1,lenrv1
3533 ! 110 rvod1(i) = rsav(i)
3534 ! do 115 i = 1,lenrv2
3535 ! 115 rvod2(i) = rsav(lenrv1+i)
3537 ! do 120 i = 1,leniv1
3538 ! 120 ivod1(i) = isav(i)
3539 ! do 125 i = 1,leniv2
3540 ! 125 ivod2(i) = isav(leniv1+i)
3543 !!----------------------- end of subroutine dvsrco ----------------------
3544 ! end subroutine dvsrco
3546 subroutine dewset (n, itol, rtol, atol, ycur, ewt)
3547 !***begin prologue dewset
3549 !***purpose set error weight vector.
3550 !***type double precision (sewset-s, dewset-d)
3551 !***author hindmarsh, alan c., (llnl)
3554 ! this subroutine sets the error weight vector ewt according to
3555 ! ewt(i) = rtol(i)*abs(ycur(i)) + atol(i), i = 1,...,n,
3556 ! with the subscript on rtol and/or atol possibly replaced by 1 above,
3557 ! depending on the value of itol.
3560 !***routines called (none)
3561 !***revision history (yymmdd)
3562 ! 791129 date written
3563 ! 890501 modified prologue to slatec/ldoc format. (fnf)
3564 ! 890503 minor cosmetic changes. (fnf)
3565 ! 930809 renamed to allow single/double precision versions. (ach)
3566 !***end prologue dewset
3570 double precision rtol, atol, ycur, ewt
3571 dimension rtol(*), atol(*), ycur(n), ewt(n)
3573 !***first executable statement dewset
3574 go to (10, 20, 30, 40), itol
3577 15 ewt(i) = rtol(1)*abs(ycur(i)) + atol(1)
3581 25 ewt(i) = rtol(1)*abs(ycur(i)) + atol(i)
3585 35 ewt(i) = rtol(i)*abs(ycur(i)) + atol(1)
3589 45 ewt(i) = rtol(i)*abs(ycur(i)) + atol(i)
3591 !----------------------- end of subroutine dewset ----------------------
3592 end subroutine dewset
3594 double precision function dvnorm (n, v, w)
3595 !***begin prologue dvnorm
3597 !***purpose weighted root-mean-square vector norm.
3598 !***type double precision (svnorm-s, dvnorm-d)
3599 !***author hindmarsh, alan c., (llnl)
3602 ! this function routine computes the weighted root-mean-square norm
3603 ! of the vector of length n contained in the array v, with weights
3604 ! contained in the array w of length n:
3605 ! dvnorm = sqrt( (1/n) * sum( v(i)*w(i) )**2 )
3608 !***routines called (none)
3609 !***revision history (yymmdd)
3610 ! 791129 date written
3611 ! 890501 modified prologue to slatec/ldoc format. (fnf)
3612 ! 890503 minor cosmetic changes. (fnf)
3613 ! 930809 renamed to allow single/double precision versions. (ach)
3614 !***end prologue dvnorm
3617 double precision v, w, sum
3618 dimension v(n), w(n)
3620 !***first executable statement dvnorm
3623 10 sum = sum + (v(i)*w(i))**2
3624 dvnorm = sqrt(sum/n)
3626 !----------------------- end of function dvnorm ------------------------
3629 subroutine xerrwd (msg, nmes, nerr, level, ni, i1, i2, nr, r1, r2)
3630 !***begin prologue xerrwd
3632 !***purpose write error message with values.
3634 !***type double precision (xerrwv-s, xerrwd-d)
3635 !***author hindmarsh, alan c., (llnl)
3638 ! subroutines xerrwd, xsetf, xsetun, and the function routine ixsav,
3639 ! as given here, constitute a simplified version of the slatec error
3642 ! all arguments are input arguments.
3644 ! msg = the message (character array).
3645 ! nmes = the length of msg (number of characters).
3646 ! nerr = the error number (not used).
3647 ! level = the error level..
3648 ! 0 or 1 means recoverable (control returns to caller).
3649 ! 2 means fatal (run is aborted--see note below).
3650 ! ni = number of integers (0, 1, or 2) to be printed with message.
3651 ! i1,i2 = integers to be printed, depending on ni.
3652 ! nr = number of reals (0, 1, or 2) to be printed with message.
3653 ! r1,r2 = reals to be printed, depending on nr.
3655 ! note.. this routine is machine-dependent and specialized for use
3656 ! in limited context, in the following ways..
3657 ! 1. the argument msg is assumed to be of type character, and
3658 ! the message is printed with a format of (1x,a).
3659 ! 2. the message is assumed to take only one line.
3660 ! multi-line messages are generated by repeated calls.
3661 ! 3. if level = 2, control passes to the statement stop
3662 ! to abort the run. this statement may be machine-dependent.
3663 ! 4. r1 and r2 are assumed to be in double precision and are printed
3666 !***routines called ixsav
3667 !***revision history (yymmdd)
3668 ! 920831 date written
3669 ! 921118 replaced mflgsv/lunsav by ixsav. (ach)
3670 ! 930329 modified prologue to slatec format. (fnf)
3671 ! 930407 changed msg from character*1 array to variable. (fnf)
3672 ! 930922 minor cosmetic change. (fnf)
3673 !***end prologue xerrwd
3677 ! for a different default logical unit number, ixsav (or a subsidiary
3678 ! routine that it calls) will need to be modified.
3679 ! for a different run-abort command, change the statement following
3680 ! statement 100 at the end.
3681 !-----------------------------------------------------------------------
3682 ! subroutines called by xerrwd.. none
3683 ! function routine called by xerrwd.. ixsav
3684 !-----------------------------------------------------------------------
3687 ! declare arguments.
3689 double precision r1, r2
3690 integer nmes, nerr, level, ni, i1, i2, nr
3693 ! declare local variables.
3695 ! 27-oct-2005 rce - do not declare functions that are in the module
3696 ! integer lunit, ixsav, mesflg
3697 integer lunit, mesflg
3699 ! get logical unit number and message print flag.
3701 !***first executable statement xerrwd
3702 lunit = ixsav (1, 0, .false.)
3703 mesflg = ixsav (2, 0, .false.)
3704 if (mesflg .eq. 0) go to 100
3706 ! write the message.
3708 write (lunit,10) msg
3710 if (ni .eq. 1) write (lunit, 20) i1
3711 20 format(6x,'in above message, i1 =',i10)
3712 if (ni .eq. 2) write (lunit, 30) i1,i2
3713 30 format(6x,'in above message, i1 =',i10,3x,'i2 =',i10)
3714 if (nr .eq. 1) write (lunit, 40) r1
3715 40 format(6x,'in above message, r1 =',d21.13)
3716 if (nr .eq. 2) write (lunit, 50) r1,r2
3717 50 format(6x,'in above, r1 =',d21.13,3x,'r2 =',d21.13)
3719 ! abort the run if level = 2.
3721 100 if (level .ne. 2) return
3722 call wrf_error_fatal(" ")
3724 !----------------------- end of subroutine xerrwd ----------------------
3725 end subroutine xerrwd
3727 subroutine xsetf (mflag)
3728 !***begin prologue xsetf
3729 !***purpose reset the error print control flag.
3731 !***type all (xsetf-a)
3732 !***keywords error control
3733 !***author hindmarsh, alan c., (llnl)
3736 ! xsetf sets the error print control flag to mflag:
3737 ! mflag=1 means print all messages (the default).
3738 ! mflag=0 means no printing.
3740 !***see also xerrwd, xerrwv
3741 !***references (none)
3742 !***routines called ixsav
3743 !***revision history (yymmdd)
3744 ! 921118 date written
3745 ! 930329 added slatec format prologue. (fnf)
3746 ! 930407 corrected see also section. (fnf)
3747 ! 930922 made user-callable, and other cosmetic changes. (fnf)
3748 !***end prologue xsetf
3750 ! subroutines called by xsetf.. none
3751 ! function routine called by xsetf.. ixsav
3752 !-----------------------------------------------------------------------
3754 ! 27-oct-2005 rce - do not declare functions that are in the module
3755 ! integer mflag, junk, ixsav
3758 !***first executable statement xsetf
3759 if (mflag .eq. 0 .or. mflag .eq. 1) junk = ixsav (2,mflag,.true.)
3761 !----------------------- end of subroutine xsetf -----------------------
3762 end subroutine xsetf
3764 subroutine xsetun (lun)
3765 !***begin prologue xsetun
3766 !***purpose reset the logical unit number for error messages.
3768 !***type all (xsetun-a)
3769 !***keywords error control
3772 ! xsetun sets the logical unit number for error messages to lun.
3774 !***author hindmarsh, alan c., (llnl)
3775 !***see also xerrwd, xerrwv
3776 !***references (none)
3777 !***routines called ixsav
3778 !***revision history (yymmdd)
3779 ! 921118 date written
3780 ! 930329 added slatec format prologue. (fnf)
3781 ! 930407 corrected see also section. (fnf)
3782 ! 930922 made user-callable, and other cosmetic changes. (fnf)
3783 !***end prologue xsetun
3785 ! subroutines called by xsetun.. none
3786 ! function routine called by xsetun.. ixsav
3787 !-----------------------------------------------------------------------
3789 ! 27-oct-2005 rce - do not declare functions that are in the module
3790 ! integer lun, junk, ixsav
3793 !***first executable statement xsetun
3794 if (lun .gt. 0) junk = ixsav (1,lun,.true.)
3796 !----------------------- end of subroutine xsetun ----------------------
3797 end subroutine xsetun
3799 integer function ixsav (ipar, ivalue, iset)
3800 !***begin prologue ixsav
3802 !***purpose save and recall error message control parameters.
3804 !***type all (ixsav-a)
3805 !***author hindmarsh, alan c., (llnl)
3808 ! ixsav saves and recalls one of two error message parameters:
3809 ! lunit, the logical unit number to which messages are printed, and
3810 ! mesflg, the message print flag.
3811 ! this is a modification of the slatec library routine j4save.
3813 ! saved local variables..
3814 ! lunit = logical unit number for messages. the default is obtained
3815 ! by a call to iumach (may be machine-dependent).
3816 ! mesflg = print control flag..
3817 ! 1 means print all messages (the default).
3818 ! 0 means no printing.
3821 ! ipar = parameter indicator (1 for lunit, 2 for mesflg).
3822 ! ivalue = the value to be set for the parameter, if iset = .true.
3823 ! iset = logical flag to indicate whether to read or write.
3824 ! if iset = .true., the parameter will be given
3825 ! the value ivalue. if iset = .false., the parameter
3826 ! will be unchanged, and ivalue is a dummy argument.
3829 ! ixsav = the (old) value of the parameter.
3831 !***see also xerrwd, xerrwv
3832 !***routines called iumach
3833 !***revision history (yymmdd)
3834 ! 921118 date written
3835 ! 930329 modified prologue to slatec format. (fnf)
3836 ! 930915 added iumach call to get default output unit. (ach)
3837 ! 930922 minor cosmetic changes. (fnf)
3838 ! 010425 type declaration for iumach added. (ach)
3839 !***end prologue ixsav
3841 ! subroutines called by ixsav.. none
3842 ! function routine called by ixsav.. iumach
3843 !-----------------------------------------------------------------------
3846 integer ipar, ivalue
3847 !-----------------------------------------------------------------------
3848 ! 27-oct-2005 rce - do not declare functions that are in the module
3849 ! integer iumach, lunit, mesflg
3850 integer lunit, mesflg
3851 !-----------------------------------------------------------------------
3852 ! the following fortran-77 declaration is to cause the values of the
3853 ! listed (local) variables to be saved between calls to this routine.
3854 !-----------------------------------------------------------------------
3856 data lunit/-1/, mesflg/1/
3858 !***first executable statement ixsav
3859 if (ipar .eq. 1) then
3860 if (lunit .eq. -1) lunit = iumach()
3862 if (iset) lunit = ivalue
3865 if (ipar .eq. 2) then
3867 if (iset) mesflg = ivalue
3871 !----------------------- end of function ixsav -------------------------
3874 integer function iumach()
3875 !***begin prologue iumach
3876 !***purpose provide standard output unit number.
3878 !***type integer (iumach-i)
3879 !***keywords machine constants
3880 !***author hindmarsh, alan c., (llnl)
3883 ! integer lout, iumach
3886 ! *function return values:
3887 ! lout : the standard logical unit for fortran output.
3889 !***references (none)
3890 !***routines called (none)
3891 !***revision history (yymmdd)
3892 ! 930915 date written
3893 ! 930922 made user-callable, and other cosmetic changes. (fnf)
3894 !***end prologue iumach
3897 ! the built-in value of 6 is standard on a wide range of fortran
3898 ! systems. this may be machine-dependent.
3900 !***first executable statement iumach
3904 !----------------------- end of function iumach ------------------------
3907 double precision function dumach ()
3908 !***begin prologue dumach
3909 !***purpose compute the unit roundoff of the machine.
3911 !***type double precision (rumach-s, dumach-d)
3912 !***keywords machine constants
3913 !***author hindmarsh, alan c., (llnl)
3916 ! double precision a, dumach
3919 ! *function return values:
3920 ! a : the unit roundoff of the machine.
3923 ! the unit roundoff is defined as the smallest positive machine
3924 ! number u such that 1.0 + u .ne. 1.0. this is computed by dumach
3925 ! in a machine-independent manner.
3927 !***references (none)
3928 !***routines called dumsum
3929 !***revision history (yyyymmdd)
3930 ! 19930216 date written
3931 ! 19930818 added slatec-format prologue. (fnf)
3932 ! 20030707 added dumsum to force normal storage of comp. (ach)
3933 !***end prologue dumach
3935 double precision u, comp
3936 !***first executable statement dumach
3939 call dumsum(1.0d0, u, comp)
3940 if (comp .ne. 1.0d0) go to 10
3943 !----------------------- end of function dumach ------------------------
3945 subroutine dumsum(a,b,c)
3946 ! routine to force normal storing of a + b, for dumach.
3947 double precision a, b, c
3950 end subroutine dumsum
3952 !-----------------------------------------------------------------------
3953 ! vode_subs.f - created on 28-jul-2004
3954 ! by downloading following from www.netlib.org
3955 ! 1. daxpy, dcopy, ddot, dnrm2, dscal, idamax from blas
3956 ! 2. dgbfa, dbgsl, dgefa, dgesl from linpack
3958 ! 27-oct-2005 rce - change '1' dimensions in subr dgefa & dgesl
3959 !-----------------------------------------------------------------------
3962 !-----------------------------------------------------------------------
3963 subroutine daxpy(n,da,dx,incx,dy,incy)
3965 ! constant times a vector plus a vector.
3966 ! uses unrolled loops for increments equal to one.
3967 ! jack dongarra, linpack, 3/11/78.
3968 ! modified 12/3/93, array(1) declarations changed to array(*)
3970 double precision dx(*),dy(*),da
3971 integer i,incx,incy,ix,iy,m,mp1,n
3974 if (da .eq. 0.0d0) return
3975 if(incx.eq.1.and.incy.eq.1)go to 20
3977 ! code for unequal increments or equal increments
3982 if(incx.lt.0)ix = (-n+1)*incx + 1
3983 if(incy.lt.0)iy = (-n+1)*incy + 1
3985 dy(iy) = dy(iy) + da*dx(ix)
3991 ! code for both increments equal to 1
3997 if( m .eq. 0 ) go to 40
3999 dy(i) = dy(i) + da*dx(i)
4001 if( n .lt. 4 ) return
4004 dy(i) = dy(i) + da*dx(i)
4005 dy(i + 1) = dy(i + 1) + da*dx(i + 1)
4006 dy(i + 2) = dy(i + 2) + da*dx(i + 2)
4007 dy(i + 3) = dy(i + 3) + da*dx(i + 3)
4010 end subroutine daxpy
4013 !-----------------------------------------------------------------------
4014 subroutine dcopy(n,dx,incx,dy,incy)
4016 ! copies a vector, x, to a vector, y.
4017 ! uses unrolled loops for increments equal to one.
4018 ! jack dongarra, linpack, 3/11/78.
4019 ! modified 12/3/93, array(1) declarations changed to array(*)
4021 double precision dx(*),dy(*)
4022 integer i,incx,incy,ix,iy,m,mp1,n
4025 if(incx.eq.1.and.incy.eq.1)go to 20
4027 ! code for unequal increments or equal increments
4032 if(incx.lt.0)ix = (-n+1)*incx + 1
4033 if(incy.lt.0)iy = (-n+1)*incy + 1
4041 ! code for both increments equal to 1
4047 if( m .eq. 0 ) go to 40
4051 if( n .lt. 7 ) return
4055 dy(i + 1) = dx(i + 1)
4056 dy(i + 2) = dx(i + 2)
4057 dy(i + 3) = dx(i + 3)
4058 dy(i + 4) = dx(i + 4)
4059 dy(i + 5) = dx(i + 5)
4060 dy(i + 6) = dx(i + 6)
4063 end subroutine dcopy
4066 double precision function ddot(n,dx,incx,dy,incy)
4068 ! forms the dot product of two vectors.
4069 ! uses unrolled loops for increments equal to one.
4070 ! jack dongarra, linpack, 3/11/78.
4071 ! modified 12/3/93, array(1) declarations changed to array(*)
4073 double precision dx(*),dy(*),dtemp
4074 integer i,incx,incy,ix,iy,m,mp1,n
4079 if(incx.eq.1.and.incy.eq.1)go to 20
4081 ! code for unequal increments or equal increments
4086 if(incx.lt.0)ix = (-n+1)*incx + 1
4087 if(incy.lt.0)iy = (-n+1)*incy + 1
4089 dtemp = dtemp + dx(ix)*dy(iy)
4096 ! code for both increments equal to 1
4102 if( m .eq. 0 ) go to 40
4104 dtemp = dtemp + dx(i)*dy(i)
4106 if( n .lt. 5 ) go to 60
4109 dtemp = dtemp + dx(i)*dy(i) + dx(i + 1)*dy(i + 1) + &
4110 dx(i + 2)*dy(i + 2) + dx(i + 3)*dy(i + 3) + dx(i + 4)*dy(i + 4)
4117 !-----------------------------------------------------------------------
4118 double precision function dnrm2 ( n, x, incx )
4119 ! .. scalar arguments ..
4121 ! .. array arguments ..
4122 double precision x( * )
4125 ! dnrm2 returns the euclidean norm of a vector via the function
4128 ! dnrm2 := sqrt( x'*x )
4132 ! -- this version written on 25-october-1982.
4133 ! modified on 14-october-1993 to inline the call to dlassq.
4134 ! sven hammarling, nag ltd.
4138 double precision one , zero
4139 parameter ( one = 1.0d+0, zero = 0.0d+0 )
4140 ! .. local scalars ..
4142 double precision absxi, norm, scale, ssq
4143 ! .. intrinsic functions ..
4146 ! .. executable statements ..
4147 if( n.lt.1 .or. incx.lt.1 )then
4149 else if( n.eq.1 )then
4150 norm = abs( x( 1 ) )
4154 ! the following loop is equivalent to this call to the lapack
4155 ! auxiliary routine:
4156 ! call dlassq( n, x, incx, scale, ssq )
4158 do 10, ix = 1, 1 + ( n - 1 )*incx, incx
4159 if( x( ix ).ne.zero )then
4160 absxi = abs( x( ix ) )
4161 if( scale.lt.absxi )then
4162 ssq = one + ssq*( scale/absxi )**2
4165 ssq = ssq + ( absxi/scale )**2
4169 norm = scale * sqrt( ssq )
4180 !-----------------------------------------------------------------------
4181 subroutine dscal(n,da,dx,incx)
4183 ! scales a vector by a constant.
4184 ! uses unrolled loops for increment equal to one.
4185 ! jack dongarra, linpack, 3/11/78.
4186 ! modified 3/93 to return if incx .le. 0.
4187 ! modified 12/3/93, array(1) declarations changed to array(*)
4189 double precision da,dx(*)
4190 integer i,incx,m,mp1,n,nincx
4192 if( n.le.0 .or. incx.le.0 )return
4193 if(incx.eq.1)go to 20
4195 ! code for increment not equal to 1
4198 do 10 i = 1,nincx,incx
4203 ! code for increment equal to 1
4209 if( m .eq. 0 ) go to 40
4213 if( n .lt. 5 ) return
4217 dx(i + 1) = da*dx(i + 1)
4218 dx(i + 2) = da*dx(i + 2)
4219 dx(i + 3) = da*dx(i + 3)
4220 dx(i + 4) = da*dx(i + 4)
4223 end subroutine dscal
4226 !-----------------------------------------------------------------------
4227 integer function idamax(n,dx,incx)
4229 ! finds the index of element having max. absolute value.
4230 ! jack dongarra, linpack, 3/11/78.
4231 ! modified 3/93 to return if incx .le. 0.
4232 ! modified 12/3/93, array(1) declarations changed to array(*)
4234 double precision dx(*),dmax
4238 if( n.lt.1 .or. incx.le.0 ) return
4241 if(incx.eq.1)go to 20
4243 ! code for increment not equal to 1
4249 if(dabs(dx(ix)).le.dmax) go to 5
4256 ! code for increment equal to 1
4258 20 dmax = dabs(dx(1))
4260 if(dabs(dx(i)).le.dmax) go to 30
4268 !-----------------------------------------------------------------------
4269 subroutine dgbfa(abd,lda,n,ml,mu,ipvt,info)
4270 integer lda,n,ml,mu,ipvt(1),info
4271 double precision abd(lda,1)
4273 ! dgbfa factors a double precision band matrix by elimination.
4275 ! dgbfa is usually called by dgbco, but it can be called
4276 ! directly with a saving in time if rcond is not needed.
4280 ! abd double precision(lda, n)
4281 ! contains the matrix in band storage. the columns
4282 ! of the matrix are stored in the columns of abd and
4283 ! the diagonals of the matrix are stored in rows
4284 ! ml+1 through 2*ml+mu+1 of abd .
4285 ! see the comments below for details.
4288 ! the leading dimension of the array abd .
4289 ! lda must be .ge. 2*ml + mu + 1 .
4292 ! the order of the original matrix.
4295 ! number of diagonals below the main diagonal.
4296 ! 0 .le. ml .lt. n .
4299 ! number of diagonals above the main diagonal.
4300 ! 0 .le. mu .lt. n .
4301 ! more efficient if ml .le. mu .
4304 ! abd an upper triangular matrix in band storage and
4305 ! the multipliers which were used to obtain it.
4306 ! the factorization can be written a = l*u where
4307 ! l is a product of permutation and unit lower
4308 ! triangular matrices and u is upper triangular.
4311 ! an integer vector of pivot indices.
4315 ! = k if u(k,k) .eq. 0.0 . this is not an error
4316 ! condition for this subroutine, but it does
4317 ! indicate that dgbsl will divide by zero if
4318 ! called. use rcond in dgbco for a reliable
4319 ! indication of singularity.
4323 ! if a is a band matrix, the following program segment
4324 ! will set up the input.
4326 ! ml = (band width below the diagonal)
4327 ! mu = (band width above the diagonal)
4330 ! i1 = max0(1, j-mu)
4331 ! i2 = min0(n, j+ml)
4338 ! this uses rows ml+1 through 2*ml+mu+1 of abd .
4339 ! in addition, the first ml rows in abd are used for
4340 ! elements generated during the triangularization.
4341 ! the total number of rows needed in abd is 2*ml+mu+1 .
4342 ! the ml+mu by ml+mu upper left triangle and the
4343 ! ml by ml lower right triangle are not referenced.
4345 ! linpack. this version dated 08/14/78 .
4346 ! cleve moler, university of new mexico, argonne national lab.
4348 ! subroutines and functions
4350 ! blas daxpy,dscal,idamax
4353 ! internal variables
4356 ! 27-oct-2005 rce - do not declare functions that are in the module
4357 ! integer i,idamax,i0,j,ju,jz,j0,j1,k,kp1,l,lm,m,mm,nm1
4358 integer i, i0,j,ju,jz,j0,j1,k,kp1,l,lm,m,mm,nm1
4364 ! zero initial fill-in columns
4368 if (j1 .lt. j0) go to 30
4379 ! gaussian elimination with partial pivoting
4382 if (nm1 .lt. 1) go to 130
4386 ! zero next fill-in column
4389 if (jz .gt. n) go to 50
4390 if (ml .lt. 1) go to 50
4396 ! find l = pivot index
4399 l = idamax(lm+1,abd(m,k),1) + m - 1
4402 ! zero pivot implies this column already triangularized
4404 if (abd(l,k) .eq. 0.0d0) go to 100
4406 ! interchange if necessary
4408 if (l .eq. m) go to 60
4414 ! compute multipliers
4417 call dscal(lm,t,abd(m+1,k),1)
4419 ! row elimination with column indexing
4421 ju = min0(max0(ju,mu+ipvt(k)),n)
4423 if (ju .lt. kp1) go to 90
4428 if (l .eq. mm) go to 70
4429 abd(l,j) = abd(mm,j)
4432 call daxpy(lm,t,abd(m+1,k),1,abd(mm+1,j),1)
4442 if (abd(m,n) .eq. 0.0d0) info = n
4444 end subroutine dgbfa
4447 !-----------------------------------------------------------------------
4448 subroutine dgbsl(abd,lda,n,ml,mu,ipvt,b,job)
4449 integer lda,n,ml,mu,ipvt(1),job
4450 double precision abd(lda,1),b(1)
4452 ! dgbsl solves the double precision band system
4453 ! a * x = b or trans(a) * x = b
4454 ! using the factors computed by dgbco or dgbfa.
4458 ! abd double precision(lda, n)
4459 ! the output from dgbco or dgbfa.
4462 ! the leading dimension of the array abd .
4465 ! the order of the original matrix.
4468 ! number of diagonals below the main diagonal.
4471 ! number of diagonals above the main diagonal.
4474 ! the pivot vector from dgbco or dgbfa.
4476 ! b double precision(n)
4477 ! the right hand side vector.
4480 ! = 0 to solve a*x = b ,
4481 ! = nonzero to solve trans(a)*x = b , where
4482 ! trans(a) is the transpose.
4486 ! b the solution vector x .
4490 ! a division by zero will occur if the input factor contains a
4491 ! zero on the diagonal. technically this indicates singularity
4492 ! but it is often caused by improper arguments or improper
4493 ! setting of lda . it will not occur if the subroutines are
4494 ! called correctly and if dgbco has set rcond .gt. 0.0
4495 ! or dgbfa has set info .eq. 0 .
4497 ! to compute inverse(a) * c where c is a matrix
4499 ! call dgbco(abd,lda,n,ml,mu,ipvt,rcond,z)
4500 ! if (rcond is too small) go to ...
4502 ! call dgbsl(abd,lda,n,ml,mu,ipvt,c(1,j),0)
4505 ! linpack. this version dated 08/14/78 .
4506 ! cleve moler, university of new mexico, argonne national lab.
4508 ! subroutines and functions
4513 ! internal variables
4515 ! 27-oct-2005 rce - do not declare functions that are in the module
4516 ! double precision ddot,t
4518 integer k,kb,l,la,lb,lm,m,nm1
4522 if (job .ne. 0) go to 50
4524 ! job = 0 , solve a * x = b
4525 ! first solve l*y = b
4527 if (ml .eq. 0) go to 30
4528 if (nm1 .lt. 1) go to 30
4533 if (l .eq. k) go to 10
4537 call daxpy(lm,t,abd(m+1,k),1,b(k+1),1)
4545 b(k) = b(k)/abd(m,k)
4550 call daxpy(lm,t,abd(la,k),1,b(lb),1)
4555 ! job = nonzero, solve trans(a) * x = b
4556 ! first solve trans(u)*y = b
4562 t = ddot(lm,abd(la,k),1,b(lb),1)
4563 b(k) = (b(k) - t)/abd(m,k)
4566 ! now solve trans(l)*x = y
4568 if (ml .eq. 0) go to 90
4569 if (nm1 .lt. 1) go to 90
4573 b(k) = b(k) + ddot(lm,abd(m+1,k),1,b(k+1),1)
4575 if (l .eq. k) go to 70
4584 end subroutine dgbsl
4587 !-----------------------------------------------------------------------
4588 subroutine dgefa(a,lda,n,ipvt,info)
4589 ! 27-oct-2005 rce - change '1' dimensions
4590 ! integer lda,n,ipvt(1),info
4591 integer lda,n,ipvt(n),info
4592 ! double precision a(lda,1)
4593 double precision a(lda,n)
4595 ! dgefa factors a double precision matrix by gaussian elimination.
4597 ! dgefa is usually called by dgeco, but it can be called
4598 ! directly with a saving in time if rcond is not needed.
4599 ! (time for dgeco) = (1 + 9/n)*(time for dgefa) .
4603 ! a double precision(lda, n)
4604 ! the matrix to be factored.
4607 ! the leading dimension of the array a .
4610 ! the order of the matrix a .
4614 ! a an upper triangular matrix and the multipliers
4615 ! which were used to obtain it.
4616 ! the factorization can be written a = l*u where
4617 ! l is a product of permutation and unit lower
4618 ! triangular matrices and u is upper triangular.
4621 ! an integer vector of pivot indices.
4625 ! = k if u(k,k) .eq. 0.0 . this is not an error
4626 ! condition for this subroutine, but it does
4627 ! indicate that dgesl or dgedi will divide by zero
4628 ! if called. use rcond in dgeco for a reliable
4629 ! indication of singularity.
4631 ! linpack. this version dated 08/14/78 .
4632 ! cleve moler, university of new mexico, argonne national lab.
4634 ! subroutines and functions
4636 ! blas daxpy,dscal,idamax
4638 ! internal variables
4641 ! 27-oct-2005 rce - do not declare functions that are in the module
4642 ! integer idamax,j,k,kp1,l,nm1
4643 integer j,k,kp1,l,nm1
4646 ! gaussian elimination with partial pivoting
4650 if (nm1 .lt. 1) go to 70
4654 ! find l = pivot index
4656 l = idamax(n-k+1,a(k,k),1) + k - 1
4659 ! zero pivot implies this column already triangularized
4661 if (a(l,k) .eq. 0.0d0) go to 40
4663 ! interchange if necessary
4665 if (l .eq. k) go to 10
4671 ! compute multipliers
4674 call dscal(n-k,t,a(k+1,k),1)
4676 ! row elimination with column indexing
4680 if (l .eq. k) go to 20
4684 call daxpy(n-k,t,a(k+1,k),1,a(k+1,j),1)
4693 if (a(n,n) .eq. 0.0d0) info = n
4695 end subroutine dgefa
4698 !-----------------------------------------------------------------------
4699 subroutine dgesl(a,lda,n,ipvt,b,job)
4700 ! 27-oct-2005 rce - change '1' dimensions
4701 ! integer lda,n,ipvt(1),job
4702 integer lda,n,ipvt(n),job
4703 ! double precision a(lda,1),b(1)
4704 double precision a(lda,n),b(n)
4706 ! dgesl solves the double precision system
4707 ! a * x = b or trans(a) * x = b
4708 ! using the factors computed by dgeco or dgefa.
4712 ! a double precision(lda, n)
4713 ! the output from dgeco or dgefa.
4716 ! the leading dimension of the array a .
4719 ! the order of the matrix a .
4722 ! the pivot vector from dgeco or dgefa.
4724 ! b double precision(n)
4725 ! the right hand side vector.
4728 ! = 0 to solve a*x = b ,
4729 ! = nonzero to solve trans(a)*x = b where
4730 ! trans(a) is the transpose.
4734 ! b the solution vector x .
4738 ! a division by zero will occur if the input factor contains a
4739 ! zero on the diagonal. technically this indicates singularity
4740 ! but it is often caused by improper arguments or improper
4741 ! setting of lda . it will not occur if the subroutines are
4742 ! called correctly and if dgeco has set rcond .gt. 0.0
4743 ! or dgefa has set info .eq. 0 .
4745 ! to compute inverse(a) * c where c is a matrix
4747 ! call dgeco(a,lda,n,ipvt,rcond,z)
4748 ! if (rcond is too small) go to ...
4750 ! call dgesl(a,lda,n,ipvt,c(1,j),0)
4753 ! linpack. this version dated 08/14/78 .
4754 ! cleve moler, university of new mexico, argonne national lab.
4756 ! subroutines and functions
4760 ! internal variables
4762 ! 27-oct-2005 rce - do not declare functions that are in the module
4763 ! double precision ddot,t
4768 if (job .ne. 0) go to 50
4770 ! job = 0 , solve a * x = b
4771 ! first solve l*y = b
4773 if (nm1 .lt. 1) go to 30
4777 if (l .eq. k) go to 10
4781 call daxpy(n-k,t,a(k+1,k),1,b(k+1),1)
4791 call daxpy(k-1,t,a(1,k),1,b(1),1)
4796 ! job = nonzero, solve trans(a) * x = b
4797 ! first solve trans(u)*y = b
4800 t = ddot(k-1,a(1,k),1,b(1),1)
4801 b(k) = (b(k) - t)/a(k,k)
4804 ! now solve trans(l)*x = y
4806 if (nm1 .lt. 1) go to 90
4809 b(k) = b(k) + ddot(n-k,a(k+1,k),1,b(k+1),1)
4811 if (l .eq. k) go to 70
4820 end subroutine dgesl
4824 end module module_cmu_dvode_solver