ddriv3.f 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528
  1. *DECK DDRIV3
  2. SUBROUTINE DDRIV3 (N, T, Y, F, NSTATE, TOUT, NTASK, NROOT, EPS,
  3. 8 EWT, IERROR, MINT, MITER, IMPL, ML, MU, MXORD, HMAX, WORK,
  4. 8 LENW, IWORK, LENIW, JACOBN, FA, NDE, MXSTEP, G, USERS, IERFLG)
  5. C***BEGIN PROLOGUE DDRIV3
  6. C***PURPOSE The function of DDRIV3 is to solve N ordinary differential
  7. C equations of the form dY(I)/dT = F(Y(I),T), given the
  8. C initial conditions Y(I) = YI. The program has options to
  9. C allow the solution of both stiff and non-stiff differential
  10. C equations. Other important options are available. DDRIV3
  11. C uses double precision arithmetic.
  12. C***LIBRARY SLATEC (SDRIVE)
  13. C***CATEGORY I1A2, I1A1B
  14. C***TYPE DOUBLE PRECISION (SDRIV3-S, DDRIV3-D, CDRIV3-C)
  15. C***KEYWORDS DOUBLE PRECISION, GEAR'S METHOD, INITIAL VALUE PROBLEMS,
  16. C ODE, ORDINARY DIFFERENTIAL EQUATIONS, SDRIVE, STIFF
  17. C***AUTHOR Kahaner, D. K., (NIST)
  18. C National Institute of Standards and Technology
  19. C Gaithersburg, MD 20899
  20. C Sutherland, C. D., (LANL)
  21. C Mail Stop D466
  22. C Los Alamos National Laboratory
  23. C Los Alamos, NM 87545
  24. C***DESCRIPTION
  25. C
  26. C I. ABSTRACT .......................................................
  27. C
  28. C The primary function of DDRIV3 is to solve N ordinary differential
  29. C equations of the form dY(I)/dT = F(Y(I),T), given the initial
  30. C conditions Y(I) = YI. The program has options to allow the
  31. C solution of both stiff and non-stiff differential equations. In
  32. C addition, DDRIV3 may be used to solve:
  33. C 1. The initial value problem, A*dY(I)/dT = F(Y(I),T), where A is
  34. C a non-singular matrix depending on Y and T.
  35. C 2. The hybrid differential/algebraic initial value problem,
  36. C A*dY(I)/dT = F(Y(I),T), where A is a vector (whose values may
  37. C depend upon Y and T) some of whose components will be zero
  38. C corresponding to those equations which are algebraic rather
  39. C than differential.
  40. C DDRIV3 is to be called once for each output point of T.
  41. C
  42. C II. PARAMETERS ....................................................
  43. C (REMEMBER--To run DDRIV3 correctly in double precision, ALL
  44. C non-integer arguments in the call sequence, including
  45. C arrays, MUST be declared double precision.)
  46. C
  47. C The user should use parameter names in the call sequence of DDRIV3
  48. C for those quantities whose value may be altered by DDRIV3. The
  49. C parameters in the call sequence are:
  50. C
  51. C N = (Input) The number of dependent functions whose solution
  52. C is desired. N must not be altered during a problem.
  53. C
  54. C T = The independent variable. On input for the first call, T
  55. C is the initial point. On output, T is the point at which
  56. C the solution is given.
  57. C
  58. C Y = The vector of dependent variables. Y is used as input on
  59. C the first call, to set the initial values. On output, Y
  60. C is the computed solution vector. This array Y is passed
  61. C in the call sequence of the user-provided routines F,
  62. C JACOBN, FA, USERS, and G. Thus parameters required by
  63. C those routines can be stored in this array in components
  64. C N+1 and above. (Note: Changes by the user to the first
  65. C N components of this array will take effect only after a
  66. C restart, i.e., after setting NSTATE to 1 .)
  67. C
  68. C F = A subroutine supplied by the user. The name must be
  69. C declared EXTERNAL in the user's calling program. This
  70. C subroutine is of the form:
  71. C SUBROUTINE F (N, T, Y, YDOT)
  72. C DOUBLE PRECISION Y(*), YDOT(*)
  73. C .
  74. C .
  75. C YDOT(1) = ...
  76. C .
  77. C .
  78. C YDOT(N) = ...
  79. C END (Sample)
  80. C This computes YDOT = F(Y,T), the right hand side of the
  81. C differential equations. Here Y is a vector of length at
  82. C least N. The actual length of Y is determined by the
  83. C user's declaration in the program which calls DDRIV3.
  84. C Thus the dimensioning of Y in F, while required by FORTRAN
  85. C convention, does not actually allocate any storage. When
  86. C this subroutine is called, the first N components of Y are
  87. C intermediate approximations to the solution components.
  88. C The user should not alter these values. Here YDOT is a
  89. C vector of length N. The user should only compute YDOT(I)
  90. C for I from 1 to N. Normally a return from F passes
  91. C control back to DDRIV3. However, if the user would like
  92. C to abort the calculation, i.e., return control to the
  93. C program which calls DDRIV3, he should set N to zero.
  94. C DDRIV3 will signal this by returning a value of NSTATE
  95. C equal to 6 . Altering the value of N in F has no effect
  96. C on the value of N in the call sequence of DDRIV3.
  97. C
  98. C NSTATE = An integer describing the status of integration. The
  99. C meaning of NSTATE is as follows:
  100. C 1 (Input) Means the first call to the routine. This
  101. C value must be set by the user. On all subsequent
  102. C calls the value of NSTATE should be tested by the
  103. C user, but must not be altered. (As a convenience to
  104. C the user who may wish to put out the initial
  105. C conditions, DDRIV3 can be called with NSTATE=1, and
  106. C TOUT=T. In this case the program will return with
  107. C NSTATE unchanged, i.e., NSTATE=1.)
  108. C 2 (Output) Means a successful integration. If a normal
  109. C continuation is desired (i.e., a further integration
  110. C in the same direction), simply advance TOUT and call
  111. C again. All other parameters are automatically set.
  112. C 3 (Output)(Unsuccessful) Means the integrator has taken
  113. C MXSTEP steps without reaching TOUT. The user can
  114. C continue the integration by simply calling DDRIV3
  115. C again.
  116. C 4 (Output)(Unsuccessful) Means too much accuracy has
  117. C been requested. EPS has been increased to a value
  118. C the program estimates is appropriate. The user can
  119. C continue the integration by simply calling DDRIV3
  120. C again.
  121. C 5 (Output) A root was found at a point less than TOUT.
  122. C The user can continue the integration toward TOUT by
  123. C simply calling DDRIV3 again.
  124. C 6 (Output)(Unsuccessful) N has been set to zero in
  125. C SUBROUTINE F.
  126. C 7 (Output)(Unsuccessful) N has been set to zero in
  127. C FUNCTION G. See description of G below.
  128. C 8 (Output)(Unsuccessful) N has been set to zero in
  129. C SUBROUTINE JACOBN. See description of JACOBN below.
  130. C 9 (Output)(Unsuccessful) N has been set to zero in
  131. C SUBROUTINE FA. See description of FA below.
  132. C 10 (Output)(Unsuccessful) N has been set to zero in
  133. C SUBROUTINE USERS. See description of USERS below.
  134. C 11 (Output)(Successful) For NTASK = 2 or 3, T is beyond
  135. C TOUT. The solution was obtained by interpolation.
  136. C The user can continue the integration by simply
  137. C advancing TOUT and calling DDRIV3 again.
  138. C 12 (Output)(Unsuccessful) The solution could not be
  139. C obtained. The value of IERFLG (see description
  140. C below) for a "Recoverable" situation indicates the
  141. C type of difficulty encountered: either an illegal
  142. C value for a parameter or an inability to continue the
  143. C solution. For this condition the user should take
  144. C corrective action and reset NSTATE to 1 before
  145. C calling DDRIV3 again. Otherwise the program will
  146. C terminate the run.
  147. C
  148. C TOUT = (Input) The point at which the solution is desired. The
  149. C position of TOUT relative to T on the first call
  150. C determines the direction of integration.
  151. C
  152. C NTASK = (Input) An index specifying the manner of returning the
  153. C solution, according to the following:
  154. C NTASK = 1 Means DDRIV3 will integrate past TOUT and
  155. C interpolate the solution. This is the most
  156. C efficient mode.
  157. C NTASK = 2 Means DDRIV3 will return the solution after
  158. C each internal integration step, or at TOUT,
  159. C whichever comes first. In the latter case,
  160. C the program integrates exactly to TOUT.
  161. C NTASK = 3 Means DDRIV3 will adjust its internal step to
  162. C reach TOUT exactly (useful if a singularity
  163. C exists beyond TOUT.)
  164. C
  165. C NROOT = (Input) The number of equations whose roots are desired.
  166. C If NROOT is zero, the root search is not active. This
  167. C option is useful for obtaining output at points which are
  168. C not known in advance, but depend upon the solution, e.g.,
  169. C when some solution component takes on a specified value.
  170. C The root search is carried out using the user-written
  171. C function G (see description of G below.) DDRIV3 attempts
  172. C to find the value of T at which one of the equations
  173. C changes sign. DDRIV3 can find at most one root per
  174. C equation per internal integration step, and will then
  175. C return the solution either at TOUT or at a root, whichever
  176. C occurs first in the direction of integration. The initial
  177. C point is never reported as a root. The index of the
  178. C equation whose root is being reported is stored in the
  179. C sixth element of IWORK.
  180. C NOTE: NROOT is never altered by this program.
  181. C
  182. C EPS = On input, the requested relative accuracy in all solution
  183. C components. EPS = 0 is allowed. On output, the adjusted
  184. C relative accuracy if the input value was too small. The
  185. C value of EPS should be set as large as is reasonable,
  186. C because the amount of work done by DDRIV3 increases as EPS
  187. C decreases.
  188. C
  189. C EWT = (Input) Problem zero, i.e., the smallest, nonzero,
  190. C physically meaningful value for the solution. (Array,
  191. C possibly of length one. See following description of
  192. C IERROR.) Setting EWT smaller than necessary can adversely
  193. C affect the running time.
  194. C
  195. C IERROR = (Input) Error control indicator. A value of 3 is
  196. C suggested for most problems. Other choices and detailed
  197. C explanations of EWT and IERROR are given below for those
  198. C who may need extra flexibility.
  199. C
  200. C These last three input quantities EPS, EWT and IERROR
  201. C control the accuracy of the computed solution. EWT and
  202. C IERROR are used internally to compute an array YWT. One
  203. C step error estimates divided by YWT(I) are kept less than
  204. C EPS in root mean square norm.
  205. C IERROR (Set by the user) =
  206. C 1 Means YWT(I) = 1. (Absolute error control)
  207. C EWT is ignored.
  208. C 2 Means YWT(I) = ABS(Y(I)), (Relative error control)
  209. C EWT is ignored.
  210. C 3 Means YWT(I) = MAX(ABS(Y(I)), EWT(1)).
  211. C 4 Means YWT(I) = MAX(ABS(Y(I)), EWT(I)).
  212. C This choice is useful when the solution components
  213. C have differing scales.
  214. C 5 Means YWT(I) = EWT(I).
  215. C If IERROR is 3, EWT need only be dimensioned one.
  216. C If IERROR is 4 or 5, the user must dimension EWT at least
  217. C N, and set its values.
  218. C
  219. C MINT = (Input) The integration method indicator.
  220. C MINT = 1 Means the Adams methods, and is used for
  221. C non-stiff problems.
  222. C MINT = 2 Means the stiff methods of Gear (i.e., the
  223. C backward differentiation formulas), and is
  224. C used for stiff problems.
  225. C MINT = 3 Means the program dynamically selects the
  226. C Adams methods when the problem is non-stiff
  227. C and the Gear methods when the problem is
  228. C stiff. When using the Adams methods, the
  229. C program uses a value of MITER=0; when using
  230. C the Gear methods, the program uses the value
  231. C of MITER provided by the user. Only a value
  232. C of IMPL = 0 and a value of MITER = 1, 2, 4, or
  233. C 5 is allowed for this option. The user may
  234. C not alter the value of MINT or MITER without
  235. C restarting, i.e., setting NSTATE to 1.
  236. C
  237. C MITER = (Input) The iteration method indicator.
  238. C MITER = 0 Means functional iteration. This value is
  239. C suggested for non-stiff problems.
  240. C MITER = 1 Means chord method with analytic Jacobian.
  241. C In this case, the user supplies subroutine
  242. C JACOBN (see description below).
  243. C MITER = 2 Means chord method with Jacobian calculated
  244. C internally by finite differences.
  245. C MITER = 3 Means chord method with corrections computed
  246. C by the user-written routine USERS (see
  247. C description of USERS below.) This option
  248. C allows all matrix algebra and storage
  249. C decisions to be made by the user. When using
  250. C a value of MITER = 3, the subroutine FA is
  251. C not required, even if IMPL is not 0. For
  252. C further information on using this option, see
  253. C Section IV-E below.
  254. C MITER = 4 Means the same as MITER = 1 but the A and
  255. C Jacobian matrices are assumed to be banded.
  256. C MITER = 5 Means the same as MITER = 2 but the A and
  257. C Jacobian matrices are assumed to be banded.
  258. C
  259. C IMPL = (Input) The implicit method indicator.
  260. C IMPL = 0 Means solving dY(I)/dT = F(Y(I),T).
  261. C IMPL = 1 Means solving A*dY(I)/dT = F(Y(I),T), non-
  262. C singular A (see description of FA below.)
  263. C Only MINT = 1 or 2, and MITER = 1, 2, 3, 4,
  264. C or 5 are allowed for this option.
  265. C IMPL = 2,3 Means solving certain systems of hybrid
  266. C differential/algebraic equations (see
  267. C description of FA below.) Only MINT = 2 and
  268. C MITER = 1, 2, 3, 4, or 5, are allowed for
  269. C this option.
  270. C The value of IMPL must not be changed during a problem.
  271. C
  272. C ML = (Input) The lower half-bandwidth in the case of a banded
  273. C A or Jacobian matrix. (I.e., maximum(R-C) for nonzero
  274. C A(R,C).)
  275. C
  276. C MU = (Input) The upper half-bandwidth in the case of a banded
  277. C A or Jacobian matrix. (I.e., maximum(C-R).)
  278. C
  279. C MXORD = (Input) The maximum order desired. This is .LE. 12 for
  280. C the Adams methods and .LE. 5 for the Gear methods. Normal
  281. C value is 12 and 5, respectively. If MINT is 3, the
  282. C maximum order used will be MIN(MXORD, 12) when using the
  283. C Adams methods, and MIN(MXORD, 5) when using the Gear
  284. C methods. MXORD must not be altered during a problem.
  285. C
  286. C HMAX = (Input) The maximum magnitude of the step size that will
  287. C be used for the problem. This is useful for ensuring that
  288. C important details are not missed. If this is not the
  289. C case, a large value, such as the interval length, is
  290. C suggested.
  291. C
  292. C WORK
  293. C LENW = (Input)
  294. C WORK is an array of LENW double precision words used
  295. C internally for temporary storage. The user must allocate
  296. C space for this array in the calling program by a statement
  297. C such as
  298. C DOUBLE PRECISION WORK(...)
  299. C The following table gives the required minimum value for
  300. C the length of WORK, depending on the value of IMPL and
  301. C MITER. LENW should be set to the value used. The
  302. C contents of WORK should not be disturbed between calls to
  303. C DDRIV3.
  304. C
  305. C IMPL = 0 1 2 3
  306. C ---------------------------------------------------------
  307. C MITER = 0 (MXORD+4)*N Not allowed Not allowed Not allowed
  308. C + 2*NROOT
  309. C + 250
  310. C
  311. C 1,2 N*N + 2*N*N + N*N + N*(N + NDE)
  312. C (MXORD+5)*N (MXORD+5)*N (MXORD+6)*N + (MXORD+5)*N
  313. C + 2*NROOT + 2*NROOT + 2*NROOT + 2*NROOT
  314. C + 250 + 250 + 250 + 250
  315. C
  316. C 3 (MXORD+4)*N (MXORD+4)*N (MXORD+4)*N (MXORD+4)*N
  317. C + 2*NROOT + 2*NROOT + 2*NROOT + 2*NROOT
  318. C + 250 + 250 + 250 + 250
  319. C
  320. C 4,5 (2*ML+MU+1) 2*(2*ML+MU+1) (2*ML+MU+1) (2*ML+MU+1)*
  321. C *N + *N + *N + (N+NDE) +
  322. C (MXORD+5)*N (MXORD+5)*N (MXORD+6)*N + (MXORD+5)*N
  323. C + 2*NROOT + 2*NROOT + 2*NROOT + 2*NROOT
  324. C + 250 + 250 + 250 + 250
  325. C ---------------------------------------------------------
  326. C
  327. C IWORK
  328. C LENIW = (Input)
  329. C IWORK is an integer array of length LENIW used internally
  330. C for temporary storage. The user must allocate space for
  331. C this array in the calling program by a statement such as
  332. C INTEGER IWORK(...)
  333. C The length of IWORK should be at least
  334. C 50 if MITER is 0 or 3, or
  335. C N+50 if MITER is 1, 2, 4, or 5, or MINT is 3,
  336. C and LENIW should be set to the value used. The contents
  337. C of IWORK should not be disturbed between calls to DDRIV3.
  338. C
  339. C JACOBN = A subroutine supplied by the user, if MITER is 1 or 4.
  340. C If this is the case, the name must be declared EXTERNAL in
  341. C the user's calling program. Given a system of N
  342. C differential equations, it is meaningful to speak about
  343. C the partial derivative of the I-th right hand side with
  344. C respect to the J-th dependent variable. In general there
  345. C are N*N such quantities. Often however the equations can
  346. C be ordered so that the I-th differential equation only
  347. C involves dependent variables with index near I, e.g., I+1,
  348. C I-2. Such a system is called banded. If, for all I, the
  349. C I-th equation depends on at most the variables
  350. C Y(I-ML), Y(I-ML+1), ... , Y(I), Y(I+1), ... , Y(I+MU)
  351. C then we call ML+MU+1 the bandwidth of the system. In a
  352. C banded system many of the partial derivatives above are
  353. C automatically zero. For the cases MITER = 1, 2, 4, and 5,
  354. C some of these partials are needed. For the cases
  355. C MITER = 2 and 5 the necessary derivatives are
  356. C approximated numerically by DDRIV3, and we only ask the
  357. C user to tell DDRIV3 the value of ML and MU if the system
  358. C is banded. For the cases MITER = 1 and 4 the user must
  359. C derive these partials algebraically and encode them in
  360. C subroutine JACOBN. By computing these derivatives the
  361. C user can often save 20-30 per cent of the computing time.
  362. C Usually, however, the accuracy is not much affected and
  363. C most users will probably forego this option. The optional
  364. C user-written subroutine JACOBN has the form:
  365. C SUBROUTINE JACOBN (N, T, Y, DFDY, MATDIM, ML, MU)
  366. C DOUBLE PRECISION Y(*), DFDY(MATDIM,*)
  367. C .
  368. C .
  369. C Calculate values of DFDY
  370. C .
  371. C .
  372. C END (Sample)
  373. C Here Y is a vector of length at least N. The actual
  374. C length of Y is determined by the user's declaration in the
  375. C program which calls DDRIV3. Thus the dimensioning of Y in
  376. C JACOBN, while required by FORTRAN convention, does not
  377. C actually allocate any storage. When this subroutine is
  378. C called, the first N components of Y are intermediate
  379. C approximations to the solution components. The user
  380. C should not alter these values. If the system is not
  381. C banded (MITER=1), the partials of the I-th equation with
  382. C respect to the J-th dependent function are to be stored in
  383. C DFDY(I,J). Thus partials of the I-th equation are stored
  384. C in the I-th row of DFDY. If the system is banded
  385. C (MITER=4), then the partials of the I-th equation with
  386. C respect to Y(J) are to be stored in DFDY(K,J), where
  387. C K=I-J+MU+1 . Normally a return from JACOBN passes control
  388. C back to DDRIV3. However, if the user would like to abort
  389. C the calculation, i.e., return control to the program which
  390. C calls DDRIV3, he should set N to zero. DDRIV3 will signal
  391. C this by returning a value of NSTATE equal to +8(-8).
  392. C Altering the value of N in JACOBN has no effect on the
  393. C value of N in the call sequence of DDRIV3.
  394. C
  395. C FA = A subroutine supplied by the user if IMPL is not zero, and
  396. C MITER is not 3. If so, the name must be declared EXTERNAL
  397. C in the user's calling program. This subroutine computes
  398. C the array A, where A*dY(I)/dT = F(Y(I),T).
  399. C There are three cases:
  400. C
  401. C IMPL=1.
  402. C Subroutine FA is of the form:
  403. C SUBROUTINE FA (N, T, Y, A, MATDIM, ML, MU, NDE)
  404. C DOUBLE PRECISION Y(*), A(MATDIM,*)
  405. C .
  406. C .
  407. C Calculate ALL values of A
  408. C .
  409. C .
  410. C END (Sample)
  411. C In this case A is assumed to be a nonsingular matrix,
  412. C with the same structure as DFDY (see JACOBN description
  413. C above). Programming considerations prevent complete
  414. C generality. If MITER is 1 or 2, A is assumed to be full
  415. C and the user must compute and store all values of
  416. C A(I,J), I,J=1, ... ,N. If MITER is 4 or 5, A is assumed
  417. C to be banded with lower and upper half bandwidth ML and
  418. C MU. The left hand side of the I-th equation is a linear
  419. C combination of dY(I-ML)/dT, dY(I-ML+1)/dT, ... ,
  420. C dY(I)/dT, ... , dY(I+MU-1)/dT, dY(I+MU)/dT. Thus in the
  421. C I-th equation, the coefficient of dY(J)/dT is to be
  422. C stored in A(K,J), where K=I-J+MU+1.
  423. C NOTE: The array A will be altered between calls to FA.
  424. C
  425. C IMPL=2.
  426. C Subroutine FA is of the form:
  427. C SUBROUTINE FA (N, T, Y, A, MATDIM, ML, MU, NDE)
  428. C DOUBLE PRECISION Y(*), A(*)
  429. C .
  430. C .
  431. C Calculate non-zero values of A(1),...,A(NDE)
  432. C .
  433. C .
  434. C END (Sample)
  435. C In this case it is assumed that the system is ordered by
  436. C the user so that the differential equations appear
  437. C first, and the algebraic equations appear last. The
  438. C algebraic equations must be written in the form:
  439. C 0 = F(Y(I),T). When using this option it is up to the
  440. C user to provide initial values for the Y(I) that satisfy
  441. C the algebraic equations as well as possible. It is
  442. C further assumed that A is a vector of length NDE. All
  443. C of the components of A, which may depend on T, Y(I),
  444. C etc., must be set by the user to non-zero values.
  445. C
  446. C IMPL=3.
  447. C Subroutine FA is of the form:
  448. C SUBROUTINE FA (N, T, Y, A, MATDIM, ML, MU, NDE)
  449. C DOUBLE PRECISION Y(*), A(MATDIM,*)
  450. C .
  451. C .
  452. C Calculate ALL values of A
  453. C .
  454. C .
  455. C END (Sample)
  456. C In this case A is assumed to be a nonsingular NDE by NDE
  457. C matrix with the same structure as DFDY (see JACOBN
  458. C description above). Programming considerations prevent
  459. C complete generality. If MITER is 1 or 2, A is assumed
  460. C to be full and the user must compute and store all
  461. C values of A(I,J), I,J=1, ... ,NDE. If MITER is 4 or 5,
  462. C A is assumed to be banded with lower and upper half
  463. C bandwidths ML and MU. The left hand side of the I-th
  464. C equation is a linear combination of dY(I-ML)/dT,
  465. C dY(I-ML+1)/dT, ... , dY(I)/dT, ... , dY(I+MU-1)/dT,
  466. C dY(I+MU)/dT. Thus in the I-th equation, the coefficient
  467. C of dY(J)/dT is to be stored in A(K,J), where K=I-J+MU+1.
  468. C It is assumed that the system is ordered by the user so
  469. C that the differential equations appear first, and the
  470. C algebraic equations appear last. The algebraic
  471. C equations must be written in the form 0 = F(Y(I),T).
  472. C When using this option it is up to the user to provide
  473. C initial values for the Y(I) that satisfy the algebraic
  474. C equations as well as possible.
  475. C NOTE: For IMPL = 3, the array A will be altered between
  476. C calls to FA.
  477. C Here Y is a vector of length at least N. The actual
  478. C length of Y is determined by the user's declaration in the
  479. C program which calls DDRIV3. Thus the dimensioning of Y in
  480. C FA, while required by FORTRAN convention, does not
  481. C actually allocate any storage. When this subroutine is
  482. C called, the first N components of Y are intermediate
  483. C approximations to the solution components. The user
  484. C should not alter these values. FA is always called
  485. C immediately after calling F, with the same values of T
  486. C and Y. Normally a return from FA passes control back to
  487. C DDRIV3. However, if the user would like to abort the
  488. C calculation, i.e., return control to the program which
  489. C calls DDRIV3, he should set N to zero. DDRIV3 will signal
  490. C this by returning a value of NSTATE equal to +9(-9).
  491. C Altering the value of N in FA has no effect on the value
  492. C of N in the call sequence of DDRIV3.
  493. C
  494. C NDE = (Input) The number of differential equations. This is
  495. C required only for IMPL = 2 or 3, with NDE .LT. N.
  496. C
  497. C MXSTEP = (Input) The maximum number of internal steps allowed on
  498. C one call to DDRIV3.
  499. C
  500. C G = A double precision FORTRAN function supplied by the user
  501. C if NROOT is not 0. In this case, the name must be
  502. C declared EXTERNAL in the user's calling program. G is
  503. C repeatedly called with different values of IROOT to obtain
  504. C the value of each of the NROOT equations for which a root
  505. C is desired. G is of the form:
  506. C DOUBLE PRECISION FUNCTION G (N, T, Y, IROOT)
  507. C DOUBLE PRECISION Y(*)
  508. C GO TO (10, ...), IROOT
  509. C 10 G = ...
  510. C .
  511. C .
  512. C END (Sample)
  513. C Here, Y is a vector of length at least N, whose first N
  514. C components are the solution components at the point T.
  515. C The user should not alter these values. The actual length
  516. C of Y is determined by the user's declaration in the
  517. C program which calls DDRIV3. Thus the dimensioning of Y in
  518. C G, while required by FORTRAN convention, does not actually
  519. C allocate any storage. Normally a return from G passes
  520. C control back to DDRIV3. However, if the user would like
  521. C to abort the calculation, i.e., return control to the
  522. C program which calls DDRIV3, he should set N to zero.
  523. C DDRIV3 will signal this by returning a value of NSTATE
  524. C equal to +7(-7). In this case, the index of the equation
  525. C being evaluated is stored in the sixth element of IWORK.
  526. C Altering the value of N in G has no effect on the value of
  527. C N in the call sequence of DDRIV3.
  528. C
  529. C USERS = A subroutine supplied by the user, if MITER is 3.
  530. C If this is the case, the name must be declared EXTERNAL in
  531. C the user's calling program. The routine USERS is called
  532. C by DDRIV3 when certain linear systems must be solved. The
  533. C user may choose any method to form, store and solve these
  534. C systems in order to obtain the solution result that is
  535. C returned to DDRIV3. In particular, this allows sparse
  536. C matrix methods to be used. The call sequence for this
  537. C routine is:
  538. C
  539. C SUBROUTINE USERS (Y, YH, YWT, SAVE1, SAVE2, T, H, EL,
  540. C 8 IMPL, N, NDE, IFLAG)
  541. C DOUBLE PRECISION Y(*), YH(*), YWT(*), SAVE1(*),
  542. C 8 SAVE2(*), T, H, EL
  543. C
  544. C The input variable IFLAG indicates what action is to be
  545. C taken. Subroutine USERS should perform the following
  546. C operations, depending on the value of IFLAG and IMPL.
  547. C
  548. C IFLAG = 0
  549. C IMPL = 0. USERS is not called.
  550. C IMPL = 1, 2 or 3. Solve the system A*X = SAVE2,
  551. C returning the result in SAVE2. The array SAVE1 can
  552. C be used as a work array. For IMPL = 1, there are N
  553. C components to the system, and for IMPL = 2 or 3,
  554. C there are NDE components to the system.
  555. C
  556. C IFLAG = 1
  557. C IMPL = 0. Compute, decompose and store the matrix
  558. C (I - H*EL*J), where I is the identity matrix and J
  559. C is the Jacobian matrix of the right hand side. The
  560. C array SAVE1 can be used as a work array.
  561. C IMPL = 1, 2 or 3. Compute, decompose and store the
  562. C matrix (A - H*EL*J). The array SAVE1 can be used as
  563. C a work array.
  564. C
  565. C IFLAG = 2
  566. C IMPL = 0. Solve the system
  567. C (I - H*EL*J)*X = H*SAVE2 - YH - SAVE1,
  568. C returning the result in SAVE2.
  569. C IMPL = 1, 2 or 3. Solve the system
  570. C (A - H*EL*J)*X = H*SAVE2 - A*(YH + SAVE1)
  571. C returning the result in SAVE2.
  572. C The array SAVE1 should not be altered.
  573. C If IFLAG is 0 and IMPL is 1 or 2 and the matrix A is
  574. C singular, or if IFLAG is 1 and one of the matrices
  575. C (I - H*EL*J), (A - H*EL*J) is singular, the INTEGER
  576. C variable IFLAG is to be set to -1 before RETURNing.
  577. C Normally a return from USERS passes control back to
  578. C DDRIV3. However, if the user would like to abort the
  579. C calculation, i.e., return control to the program which
  580. C calls DDRIV3, he should set N to zero. DDRIV3 will signal
  581. C this by returning a value of NSTATE equal to +10(-10).
  582. C Altering the value of N in USERS has no effect on the
  583. C value of N in the call sequence of DDRIV3.
  584. C
  585. C IERFLG = An error flag. The error number associated with a
  586. C diagnostic message (see Section III-A below) is the same
  587. C as the corresponding value of IERFLG. The meaning of
  588. C IERFLG:
  589. C 0 The routine completed successfully. (No message is
  590. C issued.)
  591. C 3 (Warning) The number of steps required to reach TOUT
  592. C exceeds MXSTEP.
  593. C 4 (Warning) The value of EPS is too small.
  594. C 11 (Warning) For NTASK = 2 or 3, T is beyond TOUT.
  595. C The solution was obtained by interpolation.
  596. C 15 (Warning) The integration step size is below the
  597. C roundoff level of T. (The program issues this
  598. C message as a warning but does not return control to
  599. C the user.)
  600. C 22 (Recoverable) N is not positive.
  601. C 23 (Recoverable) MINT is less than 1 or greater than 3 .
  602. C 24 (Recoverable) MITER is less than 0 or greater than
  603. C 5 .
  604. C 25 (Recoverable) IMPL is less than 0 or greater than 3 .
  605. C 26 (Recoverable) The value of NSTATE is less than 1 or
  606. C greater than 12 .
  607. C 27 (Recoverable) EPS is less than zero.
  608. C 28 (Recoverable) MXORD is not positive.
  609. C 29 (Recoverable) For MINT = 3, either MITER = 0 or 3, or
  610. C IMPL = 0 .
  611. C 30 (Recoverable) For MITER = 0, IMPL is not 0 .
  612. C 31 (Recoverable) For MINT = 1, IMPL is 2 or 3 .
  613. C 32 (Recoverable) Insufficient storage has been allocated
  614. C for the WORK array.
  615. C 33 (Recoverable) Insufficient storage has been allocated
  616. C for the IWORK array.
  617. C 41 (Recoverable) The integration step size has gone
  618. C to zero.
  619. C 42 (Recoverable) The integration step size has been
  620. C reduced about 50 times without advancing the
  621. C solution. The problem setup may not be correct.
  622. C 43 (Recoverable) For IMPL greater than 0, the matrix A
  623. C is singular.
  624. C 999 (Fatal) The value of NSTATE is 12 .
  625. C
  626. C III. OTHER COMMUNICATION TO THE USER ..............................
  627. C
  628. C A. The solver communicates to the user through the parameters
  629. C above. In addition it writes diagnostic messages through the
  630. C standard error handling program XERMSG. A complete description
  631. C of XERMSG is given in "Guide to the SLATEC Common Mathematical
  632. C Library" by Kirby W. Fong et al.. At installations which do not
  633. C have this error handling package the short but serviceable
  634. C routine, XERMSG, available with this package, can be used. That
  635. C program uses the file named OUTPUT to transmit messages.
  636. C
  637. C B. The first three elements of WORK and the first five elements of
  638. C IWORK will contain the following statistical data:
  639. C AVGH The average step size used.
  640. C HUSED The step size last used (successfully).
  641. C AVGORD The average order used.
  642. C IMXERR The index of the element of the solution vector that
  643. C contributed most to the last error test.
  644. C NQUSED The order last used (successfully).
  645. C NSTEP The number of steps taken since last initialization.
  646. C NFE The number of evaluations of the right hand side.
  647. C NJE The number of evaluations of the Jacobian matrix.
  648. C
  649. C IV. REMARKS .......................................................
  650. C
  651. C A. Other routines used:
  652. C DDNTP, DDZRO, DDSTP, DDNTL, DDPST, DDCOR, DDCST,
  653. C DDPSC, and DDSCL;
  654. C DGEFA, DGESL, DGBFA, DGBSL, and DNRM2 (from LINPACK)
  655. C D1MACH (from the Bell Laboratories Machine Constants Package)
  656. C XERMSG (from the SLATEC Common Math Library)
  657. C The last seven routines above, not having been written by the
  658. C present authors, are not explicitly part of this package.
  659. C
  660. C B. On any return from DDRIV3 all information necessary to continue
  661. C the calculation is contained in the call sequence parameters,
  662. C including the work arrays. Thus it is possible to suspend one
  663. C problem, integrate another, and then return to the first.
  664. C
  665. C C. If this package is to be used in an overlay situation, the user
  666. C must declare in the primary overlay the variables in the call
  667. C sequence to DDRIV3.
  668. C
  669. C D. Changing parameters during an integration.
  670. C The value of NROOT, EPS, EWT, IERROR, MINT, MITER, or HMAX may
  671. C be altered by the user between calls to DDRIV3. For example, if
  672. C too much accuracy has been requested (the program returns with
  673. C NSTATE = 4 and an increased value of EPS) the user may wish to
  674. C increase EPS further. In general, prudence is necessary when
  675. C making changes in parameters since such changes are not
  676. C implemented until the next integration step, which is not
  677. C necessarily the next call to DDRIV3. This can happen if the
  678. C program has already integrated to a point which is beyond the
  679. C new point TOUT.
  680. C
  681. C E. As the price for complete control of matrix algebra, the DDRIV3
  682. C USERS option puts all responsibility for Jacobian matrix
  683. C evaluation on the user. It is often useful to approximate
  684. C numerically all or part of the Jacobian matrix. However this
  685. C must be done carefully. The FORTRAN sequence below illustrates
  686. C the method we recommend. It can be inserted directly into
  687. C subroutine USERS to approximate Jacobian elements in rows I1
  688. C to I2 and columns J1 to J2.
  689. C DOUBLE PRECISION DFDY(N,N), EPSJ, H, R, D1MACH,
  690. C 8 SAVE1(N), SAVE2(N), T, UROUND, Y(N), YJ, YWT(N)
  691. C UROUND = D1MACH(4)
  692. C EPSJ = SQRT(UROUND)
  693. C DO 30 J = J1,J2
  694. C R = EPSJ*MAX(ABS(YWT(J)), ABS(Y(J)))
  695. C IF (R .EQ. 0.D0) R = YWT(J)
  696. C YJ = Y(J)
  697. C Y(J) = Y(J) + R
  698. C CALL F (N, T, Y, SAVE1)
  699. C IF (N .EQ. 0) RETURN
  700. C Y(J) = YJ
  701. C DO 20 I = I1,I2
  702. C 20 DFDY(I,J) = (SAVE1(I) - SAVE2(I))/R
  703. C 30 CONTINUE
  704. C Many problems give rise to structured sparse Jacobians, e.g.,
  705. C block banded. It is possible to approximate them with fewer
  706. C function evaluations than the above procedure uses; see Curtis,
  707. C Powell and Reid, J. Inst. Maths Applics, (1974), Vol. 13,
  708. C pp. 117-119.
  709. C
  710. C F. When any of the routines JACOBN, FA, G, or USERS, is not
  711. C required, difficulties associated with unsatisfied externals can
  712. C be avoided by using the name of the routine which calculates the
  713. C right hand side of the differential equations in place of the
  714. C corresponding name in the call sequence of DDRIV3.
  715. C
  716. C***REFERENCES C. W. Gear, Numerical Initial Value Problems in
  717. C Ordinary Differential Equations, Prentice-Hall, 1971.
  718. C***ROUTINES CALLED D1MACH, DDNTP, DDSTP, DDZRO, DGBFA, DGBSL, DGEFA,
  719. C DGESL, DNRM2, XERMSG
  720. C***REVISION HISTORY (YYMMDD)
  721. C 790601 DATE WRITTEN
  722. C 900329 Initial submission to SLATEC.
  723. C***END PROLOGUE DDRIV3
  724. EXTERNAL F, JACOBN, FA, G, USERS
  725. DOUBLE PRECISION AE, BIG, EPS, EWT(*), G, GLAST, GNOW, H, HMAX,
  726. 8 HSIGN, HUSED, NROUND, RE, D1MACH, SIZE, DNRM2, SUM, T, TLAST,
  727. 8 TOUT, TROOT, UROUND, WORK(*), Y(*)
  728. INTEGER I, IA, IAVGH, IAVGRD, ICNVRG, IDFDY, IEL, IERFLG, IERROR,
  729. 8 IFAC, IFLAG, IGNOW, IH, IHMAX, IHOLD, IHSIGN, IHUSED,
  730. 8 IJROOT, IJSTPL, IJTASK, IMNT, IMNTLD, IMPL, IMTR, IMTRLD,
  731. 8 IMTRSV, IMXERR, IMXORD, IMXRDS, INDMXR, INDPRT, INDPVT,
  732. 8 INDTRT, INFE, INFO, INJE, INQ, INQUSE, INROOT, INRTLD,
  733. 8 INSTEP, INWAIT, IRC, IRMAX, IROOT, IMACH1, IMACH4, ISAVE1,
  734. 8 ISAVE2, IT, ITOUT, ITQ, ITREND, ITROOT, IWORK(*), IYH,
  735. 8 IYWT, J, JSTATE, JTROOT, LENCHK, LENIW, LENW, LIWCHK,
  736. 8 MATDIM, MAXORD, MINT, MITER, ML, MU, MXORD, MXSTEP, N,
  737. 8 NDE, NDECOM, NPAR, NROOT, NSTATE, NSTEPL, NTASK
  738. LOGICAL CONVRG
  739. CHARACTER INTGR1*8, INTGR2*8, RL1*16, RL2*16
  740. PARAMETER(NROUND = 20.D0)
  741. PARAMETER(IAVGH = 1, IHUSED = 2, IAVGRD = 3,
  742. 8 IEL = 4, IH = 160, IHMAX = 161, IHOLD = 162,
  743. 8 IHSIGN = 163, IRC = 164, IRMAX = 165, IT = 166,
  744. 8 ITOUT = 167, ITQ = 168, ITREND = 204, IMACH1 = 205,
  745. 8 IMACH4 = 206, IYH = 251,
  746. 8 INDMXR = 1, INQUSE = 2, INSTEP = 3, INFE = 4, INJE = 5,
  747. 8 INROOT = 6, ICNVRG = 7, IJROOT = 8, IJTASK = 9,
  748. 8 IMNTLD = 10, IMTRLD = 11, INQ = 12, INRTLD = 13,
  749. 8 INDTRT = 14, INWAIT = 15, IMNT = 16, IMTRSV = 17,
  750. 8 IMTR = 18, IMXRDS = 19, IMXORD = 20, INDPRT = 21,
  751. 8 IJSTPL = 22, INDPVT = 51)
  752. C***FIRST EXECUTABLE STATEMENT DDRIV3
  753. IF (NSTATE .EQ. 12) THEN
  754. IERFLG = 999
  755. CALL XERMSG('SLATEC', 'DDRIV3',
  756. 8 'Illegal input. The value of NSTATE is 12 .', IERFLG, 2)
  757. RETURN
  758. ELSE IF (NSTATE .LT. 1 .OR. NSTATE .GT. 12) THEN
  759. WRITE(INTGR1, '(I8)') NSTATE
  760. IERFLG = 26
  761. CALL XERMSG('SLATEC', 'DDRIV3',
  762. 8 'Illegal input. Improper value for NSTATE(= '//INTGR1//').',
  763. 8 IERFLG, 1)
  764. NSTATE = 12
  765. RETURN
  766. END IF
  767. NPAR = N
  768. IF (EPS .LT. 0.D0) THEN
  769. WRITE(RL1, '(D16.8)') EPS
  770. IERFLG = 27
  771. CALL XERMSG('SLATEC', 'DDRIV3',
  772. 8 'Illegal input. EPS, '//RL1//', is negative.', IERFLG, 1)
  773. NSTATE = 12
  774. RETURN
  775. END IF
  776. IF (N .LE. 0) THEN
  777. WRITE(INTGR1, '(I8)') N
  778. IERFLG = 22
  779. CALL XERMSG('SLATEC', 'DDRIV3',
  780. 8 'Illegal input. Number of equations, '//INTGR1//
  781. 8 ', is not positive.', IERFLG, 1)
  782. NSTATE = 12
  783. RETURN
  784. END IF
  785. IF (MXORD .LE. 0) THEN
  786. WRITE(INTGR1, '(I8)') MXORD
  787. IERFLG = 28
  788. CALL XERMSG('SLATEC', 'DDRIV3',
  789. 8 'Illegal input. Maximum order, '//INTGR1//
  790. 8 ', is not positive.', IERFLG, 1)
  791. NSTATE = 12
  792. RETURN
  793. END IF
  794. IF (MINT .LT. 1 .OR. MINT .GT. 3) THEN
  795. WRITE(INTGR1, '(I8)') MINT
  796. IERFLG = 23
  797. CALL XERMSG('SLATEC', 'DDRIV3',
  798. 8 'Illegal input. Improper value for the integration method '//
  799. 8 'flag, '//INTGR1//' .', IERFLG, 1)
  800. NSTATE = 12
  801. RETURN
  802. ELSE IF (MITER .LT. 0 .OR. MITER .GT. 5) THEN
  803. WRITE(INTGR1, '(I8)') MITER
  804. IERFLG = 24
  805. CALL XERMSG('SLATEC', 'DDRIV3',
  806. 8 'Illegal input. Improper value for MITER(= '//INTGR1//').',
  807. 8 IERFLG, 1)
  808. NSTATE = 12
  809. RETURN
  810. ELSE IF (IMPL .LT. 0 .OR. IMPL .GT. 3) THEN
  811. WRITE(INTGR1, '(I8)') IMPL
  812. IERFLG = 25
  813. CALL XERMSG('SLATEC', 'DDRIV3',
  814. 8 'Illegal input. Improper value for IMPL(= '//INTGR1//').',
  815. 8 IERFLG, 1)
  816. NSTATE = 12
  817. RETURN
  818. ELSE IF (MINT .EQ. 3 .AND.
  819. 8 (MITER .EQ. 0 .OR. MITER .EQ. 3 .OR. IMPL .NE. 0)) THEN
  820. WRITE(INTGR1, '(I8)') MITER
  821. WRITE(INTGR2, '(I8)') IMPL
  822. IERFLG = 29
  823. CALL XERMSG('SLATEC', 'DDRIV3',
  824. 8 'Illegal input. For MINT = 3, the value of MITER, '//INTGR1//
  825. 8 ', and/or IMPL, '//INTGR2//', is not allowed.', IERFLG, 1)
  826. NSTATE = 12
  827. RETURN
  828. ELSE IF ((IMPL .GE. 1 .AND. IMPL .LE. 3) .AND. MITER .EQ. 0) THEN
  829. WRITE(INTGR1, '(I8)') IMPL
  830. IERFLG = 30
  831. CALL XERMSG('SLATEC', 'DDRIV3',
  832. 8 'Illegal input. For MITER = 0, the value of IMPL, '//INTGR1//
  833. 8 ', is not allowed.', IERFLG, 1)
  834. NSTATE = 12
  835. RETURN
  836. ELSE IF ((IMPL .EQ. 2 .OR. IMPL .EQ. 3) .AND. MINT .EQ. 1) THEN
  837. WRITE(INTGR1, '(I8)') IMPL
  838. IERFLG = 31
  839. CALL XERMSG('SLATEC', 'DDRIV3',
  840. 8 'Illegal input. For MINT = 1, the value of IMPL, '//INTGR1//
  841. 8 ', is not allowed.', IERFLG, 1)
  842. NSTATE = 12
  843. RETURN
  844. END IF
  845. IF (MITER .EQ. 0 .OR. MITER .EQ. 3) THEN
  846. LIWCHK = INDPVT - 1
  847. ELSE IF (MITER .EQ. 1 .OR. MITER .EQ. 2 .OR. MITER .EQ. 4 .OR.
  848. 8 MITER .EQ. 5) THEN
  849. LIWCHK = INDPVT + N - 1
  850. END IF
  851. IF (LENIW .LT. LIWCHK) THEN
  852. WRITE(INTGR1, '(I8)') LIWCHK
  853. IERFLG = 33
  854. CALL XERMSG('SLATEC', 'DDRIV3',
  855. 8 'Illegal input. Insufficient storage allocated for the '//
  856. 8 'IWORK array. Based on the value of the input parameters '//
  857. 8 'involved, the required storage is '//INTGR1//' .', IERFLG, 1)
  858. NSTATE = 12
  859. RETURN
  860. END IF
  861. C Allocate the WORK array
  862. C IYH is the index of YH in WORK
  863. IF (MINT .EQ. 1 .OR. MINT .EQ. 3) THEN
  864. MAXORD = MIN(MXORD, 12)
  865. ELSE IF (MINT .EQ. 2) THEN
  866. MAXORD = MIN(MXORD, 5)
  867. END IF
  868. IDFDY = IYH + (MAXORD + 1)*N
  869. C IDFDY is the index of DFDY
  870. C
  871. IF (MITER .EQ. 0 .OR. MITER .EQ. 3) THEN
  872. IYWT = IDFDY
  873. ELSE IF (MITER .EQ. 1 .OR. MITER .EQ. 2) THEN
  874. IYWT = IDFDY + N*N
  875. ELSE IF (MITER .EQ. 4 .OR. MITER .EQ. 5) THEN
  876. IYWT = IDFDY + (2*ML + MU + 1)*N
  877. END IF
  878. C IYWT is the index of YWT
  879. ISAVE1 = IYWT + N
  880. C ISAVE1 is the index of SAVE1
  881. ISAVE2 = ISAVE1 + N
  882. C ISAVE2 is the index of SAVE2
  883. IGNOW = ISAVE2 + N
  884. C IGNOW is the index of GNOW
  885. ITROOT = IGNOW + NROOT
  886. C ITROOT is the index of TROOT
  887. IFAC = ITROOT + NROOT
  888. C IFAC is the index of FAC
  889. IF (MITER .EQ. 2 .OR. MITER .EQ. 5 .OR. MINT .EQ. 3) THEN
  890. IA = IFAC + N
  891. ELSE
  892. IA = IFAC
  893. END IF
  894. C IA is the index of A
  895. IF (IMPL .EQ. 0 .OR. MITER .EQ. 3) THEN
  896. LENCHK = IA - 1
  897. ELSE IF (IMPL .EQ. 1 .AND. (MITER .EQ. 1 .OR. MITER .EQ. 2)) THEN
  898. LENCHK = IA - 1 + N*N
  899. ELSE IF (IMPL .EQ. 1 .AND. (MITER .EQ. 4 .OR. MITER .EQ. 5)) THEN
  900. LENCHK = IA - 1 + (2*ML + MU + 1)*N
  901. ELSE IF (IMPL .EQ. 2 .AND. MITER .NE. 3) THEN
  902. LENCHK = IA - 1 + N
  903. ELSE IF (IMPL .EQ. 3 .AND. (MITER .EQ. 1 .OR. MITER .EQ. 2)) THEN
  904. LENCHK = IA - 1 + N*NDE
  905. ELSE IF (IMPL .EQ. 3 .AND. (MITER .EQ. 4 .OR. MITER .EQ. 5)) THEN
  906. LENCHK = IA - 1 + (2*ML + MU + 1)*NDE
  907. END IF
  908. IF (LENW .LT. LENCHK) THEN
  909. WRITE(INTGR1, '(I8)') LENCHK
  910. IERFLG = 32
  911. CALL XERMSG('SLATEC', 'DDRIV3',
  912. 8 'Illegal input. Insufficient storage allocated for the '//
  913. 8 'WORK array. Based on the value of the input parameters '//
  914. 8 'involved, the required storage is '//INTGR1//' .', IERFLG, 1)
  915. NSTATE = 12
  916. RETURN
  917. END IF
  918. IF (MITER .EQ. 0 .OR. MITER .EQ. 3) THEN
  919. MATDIM = 1
  920. ELSE IF (MITER .EQ. 1 .OR. MITER .EQ. 2) THEN
  921. MATDIM = N
  922. ELSE IF (MITER .EQ. 4 .OR. MITER .EQ. 5) THEN
  923. MATDIM = 2*ML + MU + 1
  924. END IF
  925. IF (IMPL .EQ. 0 .OR. IMPL .EQ. 1) THEN
  926. NDECOM = N
  927. ELSE IF (IMPL .EQ. 2 .OR. IMPL .EQ. 3) THEN
  928. NDECOM = NDE
  929. END IF
  930. IF (NSTATE .EQ. 1) THEN
  931. C Initialize parameters
  932. IF (MINT .EQ. 1 .OR. MINT .EQ. 3) THEN
  933. IWORK(IMXORD) = MIN(MXORD, 12)
  934. ELSE IF (MINT .EQ. 2) THEN
  935. IWORK(IMXORD) = MIN(MXORD, 5)
  936. END IF
  937. IWORK(IMXRDS) = MXORD
  938. IF (MINT .EQ. 1 .OR. MINT .EQ. 2) THEN
  939. IWORK(IMNT) = MINT
  940. IWORK(IMTR) = MITER
  941. IWORK(IMNTLD) = MINT
  942. IWORK(IMTRLD) = MITER
  943. ELSE IF (MINT .EQ. 3) THEN
  944. IWORK(IMNT) = 1
  945. IWORK(IMTR) = 0
  946. IWORK(IMNTLD) = IWORK(IMNT)
  947. IWORK(IMTRLD) = IWORK(IMTR)
  948. IWORK(IMTRSV) = MITER
  949. END IF
  950. WORK(IHMAX) = HMAX
  951. UROUND = D1MACH (4)
  952. WORK(IMACH4) = UROUND
  953. WORK(IMACH1) = D1MACH (1)
  954. IF (NROOT .NE. 0) THEN
  955. RE = UROUND
  956. AE = WORK(IMACH1)
  957. END IF
  958. H = (TOUT - T)*(1.D0 - 4.D0*UROUND)
  959. H = SIGN(MIN(ABS(H), HMAX), H)
  960. WORK(IH) = H
  961. HSIGN = SIGN(1.D0, H)
  962. WORK(IHSIGN) = HSIGN
  963. IWORK(IJTASK) = 0
  964. WORK(IAVGH) = 0.D0
  965. WORK(IHUSED) = 0.D0
  966. WORK(IAVGRD) = 0.D0
  967. IWORK(INDMXR) = 0
  968. IWORK(INQUSE) = 0
  969. IWORK(INSTEP) = 0
  970. IWORK(IJSTPL) = 0
  971. IWORK(INFE) = 0
  972. IWORK(INJE) = 0
  973. IWORK(INROOT) = 0
  974. WORK(IT) = T
  975. IWORK(ICNVRG) = 0
  976. IWORK(INDPRT) = 0
  977. C Set initial conditions
  978. DO 30 I = 1,N
  979. 30 WORK(I+IYH-1) = Y(I)
  980. IF (T .EQ. TOUT) RETURN
  981. GO TO 180
  982. ELSE
  983. UROUND = WORK(IMACH4)
  984. IF (NROOT .NE. 0) THEN
  985. RE = UROUND
  986. AE = WORK(IMACH1)
  987. END IF
  988. END IF
  989. C On a continuation, check
  990. C that output points have
  991. C been or will be overtaken.
  992. IF (IWORK(ICNVRG) .EQ. 1) THEN
  993. CONVRG = .TRUE.
  994. ELSE
  995. CONVRG = .FALSE.
  996. END IF
  997. T = WORK(IT)
  998. H = WORK(IH)
  999. HSIGN = WORK(IHSIGN)
  1000. IF (IWORK(IJTASK) .EQ. 0) GO TO 180
  1001. C
  1002. C IWORK(IJROOT) flags unreported
  1003. C roots, and is set to the value of
  1004. C NTASK when a root was last selected.
  1005. C It is set to zero when all roots
  1006. C have been reported. IWORK(INROOT)
  1007. C contains the index and WORK(ITOUT)
  1008. C contains the value of the root last
  1009. C selected to be reported.
  1010. C IWORK(INRTLD) contains the value of
  1011. C NROOT and IWORK(INDTRT) contains
  1012. C the value of ITROOT when the array
  1013. C of roots was last calculated.
  1014. IF (NROOT .NE. 0) THEN
  1015. IF (IWORK(IJROOT) .GT. 0) THEN
  1016. C TOUT has just been reported.
  1017. C If TROOT .LE. TOUT, report TROOT.
  1018. IF (NSTATE .NE. 5) THEN
  1019. IF (TOUT*HSIGN .GE. WORK(ITOUT)*HSIGN) THEN
  1020. TROOT = WORK(ITOUT)
  1021. CALL DDNTP (H, 0, N, IWORK(INQ), T, TROOT, WORK(IYH), Y)
  1022. T = TROOT
  1023. NSTATE = 5
  1024. IERFLG = 0
  1025. GO TO 580
  1026. END IF
  1027. C A root has just been reported.
  1028. C Select the next root.
  1029. ELSE
  1030. TROOT = T
  1031. IROOT = 0
  1032. DO 50 I = 1,IWORK(INRTLD)
  1033. JTROOT = I + IWORK(INDTRT) - 1
  1034. IF (WORK(JTROOT)*HSIGN .LE. TROOT*HSIGN) THEN
  1035. C
  1036. C Check for multiple roots.
  1037. C
  1038. IF (WORK(JTROOT) .EQ. WORK(ITOUT) .AND.
  1039. 8 I .GT. IWORK(INROOT)) THEN
  1040. IROOT = I
  1041. TROOT = WORK(JTROOT)
  1042. GO TO 60
  1043. END IF
  1044. IF (WORK(JTROOT)*HSIGN .GT. WORK(ITOUT)*HSIGN) THEN
  1045. IROOT = I
  1046. TROOT = WORK(JTROOT)
  1047. END IF
  1048. END IF
  1049. 50 CONTINUE
  1050. 60 IWORK(INROOT) = IROOT
  1051. WORK(ITOUT) = TROOT
  1052. IWORK(IJROOT) = NTASK
  1053. IF (NTASK .EQ. 1) THEN
  1054. IF (IROOT .EQ. 0) THEN
  1055. IWORK(IJROOT) = 0
  1056. ELSE
  1057. IF (TOUT*HSIGN .GE. TROOT*HSIGN) THEN
  1058. CALL DDNTP (H, 0, N, IWORK(INQ), T, TROOT, WORK(IYH),
  1059. 8 Y)
  1060. NSTATE = 5
  1061. T = TROOT
  1062. IERFLG = 0
  1063. GO TO 580
  1064. END IF
  1065. END IF
  1066. ELSE IF (NTASK .EQ. 2 .OR. NTASK .EQ. 3) THEN
  1067. C
  1068. C If there are no more roots, or the
  1069. C user has altered TOUT to be less
  1070. C than a root, set IJROOT to zero.
  1071. C
  1072. IF (IROOT .EQ. 0 .OR. (TOUT*HSIGN .LT. TROOT*HSIGN)) THEN
  1073. IWORK(IJROOT) = 0
  1074. ELSE
  1075. CALL DDNTP (H, 0, N, IWORK(INQ), T, TROOT, WORK(IYH),
  1076. 8 Y)
  1077. NSTATE = 5
  1078. IERFLG = 0
  1079. T = TROOT
  1080. GO TO 580
  1081. END IF
  1082. END IF
  1083. END IF
  1084. END IF
  1085. END IF
  1086. C
  1087. IF (NTASK .EQ. 1) THEN
  1088. NSTATE = 2
  1089. IF (T*HSIGN .GE. TOUT*HSIGN) THEN
  1090. CALL DDNTP (H, 0, N, IWORK(INQ), T, TOUT, WORK(IYH), Y)
  1091. T = TOUT
  1092. IERFLG = 0
  1093. GO TO 580
  1094. END IF
  1095. ELSE IF (NTASK .EQ. 2) THEN
  1096. C Check if TOUT has
  1097. C been reset .LT. T
  1098. IF (T*HSIGN .GT. TOUT*HSIGN) THEN
  1099. WRITE(RL1, '(D16.8)') T
  1100. WRITE(RL2, '(D16.8)') TOUT
  1101. IERFLG = 11
  1102. CALL XERMSG('SLATEC', 'DDRIV3',
  1103. 8 'While integrating exactly to TOUT, T, '//RL1//
  1104. 8 ', was beyond TOUT, '//RL2//' . Solution obtained by '//
  1105. 8 'interpolation.', IERFLG, 0)
  1106. NSTATE = 11
  1107. CALL DDNTP (H, 0, N, IWORK(INQ), T, TOUT, WORK(IYH), Y)
  1108. T = TOUT
  1109. GO TO 580
  1110. END IF
  1111. C Determine if TOUT has been overtaken
  1112. C
  1113. IF (ABS(TOUT - T).LE.NROUND*UROUND*MAX(ABS(T), ABS(TOUT))) THEN
  1114. T = TOUT
  1115. NSTATE = 2
  1116. IERFLG = 0
  1117. GO TO 560
  1118. END IF
  1119. C If there are no more roots
  1120. C to report, report T.
  1121. IF (NSTATE .EQ. 5) THEN
  1122. NSTATE = 2
  1123. IERFLG = 0
  1124. GO TO 560
  1125. END IF
  1126. NSTATE = 2
  1127. C See if TOUT will
  1128. C be overtaken.
  1129. IF ((T + H)*HSIGN .GT. TOUT*HSIGN) THEN
  1130. H = TOUT - T
  1131. IF ((T + H)*HSIGN .GT. TOUT*HSIGN) H = H*(1.D0 - 4.D0*UROUND)
  1132. WORK(IH) = H
  1133. IF (H .EQ. 0.D0) GO TO 670
  1134. IWORK(IJTASK) = -1
  1135. END IF
  1136. ELSE IF (NTASK .EQ. 3) THEN
  1137. NSTATE = 2
  1138. IF (T*HSIGN .GT. TOUT*HSIGN) THEN
  1139. WRITE(RL1, '(D16.8)') T
  1140. WRITE(RL2, '(D16.8)') TOUT
  1141. IERFLG = 11
  1142. CALL XERMSG('SLATEC', 'DDRIV3',
  1143. 8 'While integrating exactly to TOUT, T, '//RL1//
  1144. 8 ', was beyond TOUT, '//RL2//' . Solution obtained by '//
  1145. 8 'interpolation.', IERFLG, 0)
  1146. NSTATE = 11
  1147. CALL DDNTP (H, 0, N, IWORK(INQ), T, TOUT, WORK(IYH), Y)
  1148. T = TOUT
  1149. GO TO 580
  1150. END IF
  1151. IF (ABS(TOUT - T).LE.NROUND*UROUND*MAX(ABS(T), ABS(TOUT))) THEN
  1152. T = TOUT
  1153. IERFLG = 0
  1154. GO TO 560
  1155. END IF
  1156. IF ((T + H)*HSIGN .GT. TOUT*HSIGN) THEN
  1157. H = TOUT - T
  1158. IF ((T + H)*HSIGN .GT. TOUT*HSIGN) H = H*(1.D0 - 4.D0*UROUND)
  1159. WORK(IH) = H
  1160. IF (H .EQ. 0.D0) GO TO 670
  1161. IWORK(IJTASK) = -1
  1162. END IF
  1163. END IF
  1164. C Implement changes in MINT, MITER, and/or HMAX.
  1165. C
  1166. IF ((MINT .NE. IWORK(IMNTLD) .OR. MITER .NE. IWORK(IMTRLD)) .AND.
  1167. 8 MINT .NE. 3 .AND. IWORK(IMNTLD) .NE. 3) IWORK(IJTASK) = -1
  1168. IF (HMAX .NE. WORK(IHMAX)) THEN
  1169. H = SIGN(MIN(ABS(H), HMAX), H)
  1170. IF (H .NE. WORK(IH)) THEN
  1171. IWORK(IJTASK) = -1
  1172. WORK(IH) = H
  1173. END IF
  1174. WORK(IHMAX) = HMAX
  1175. END IF
  1176. C
  1177. 180 NSTEPL = IWORK(INSTEP)
  1178. DO 190 I = 1,N
  1179. 190 Y(I) = WORK(I+IYH-1)
  1180. IF (NROOT .NE. 0) THEN
  1181. DO 200 I = 1,NROOT
  1182. WORK(I+IGNOW-1) = G (NPAR, T, Y, I)
  1183. IF (NPAR .EQ. 0) THEN
  1184. IWORK(INROOT) = I
  1185. NSTATE = 7
  1186. RETURN
  1187. END IF
  1188. 200 CONTINUE
  1189. END IF
  1190. IF (IERROR .EQ. 1) THEN
  1191. DO 230 I = 1,N
  1192. 230 WORK(I+IYWT-1) = 1.D0
  1193. GO TO 410
  1194. ELSE IF (IERROR .EQ. 5) THEN
  1195. DO 250 I = 1,N
  1196. 250 WORK(I+IYWT-1) = EWT(I)
  1197. GO TO 410
  1198. END IF
  1199. C Reset YWT array. Looping point.
  1200. 260 IF (IERROR .EQ. 2) THEN
  1201. DO 280 I = 1,N
  1202. IF (Y(I) .EQ. 0.D0) GO TO 290
  1203. 280 WORK(I+IYWT-1) = ABS(Y(I))
  1204. GO TO 410
  1205. 290 IF (IWORK(IJTASK) .EQ. 0) THEN
  1206. CALL F (NPAR, T, Y, WORK(ISAVE2))
  1207. IF (NPAR .EQ. 0) THEN
  1208. NSTATE = 6
  1209. RETURN
  1210. END IF
  1211. IWORK(INFE) = IWORK(INFE) + 1
  1212. IF (MITER .EQ. 3 .AND. IMPL .NE. 0) THEN
  1213. IFLAG = 0
  1214. CALL USERS (Y, WORK(IYH), WORK(IYWT), WORK(ISAVE1),
  1215. 8 WORK(ISAVE2), T, H, WORK(IEL), IMPL, NPAR,
  1216. 8 NDECOM, IFLAG)
  1217. IF (IFLAG .EQ. -1) GO TO 690
  1218. IF (NPAR .EQ. 0) THEN
  1219. NSTATE = 10
  1220. RETURN
  1221. END IF
  1222. ELSE IF (IMPL .EQ. 1) THEN
  1223. IF (MITER .EQ. 1 .OR. MITER .EQ. 2) THEN
  1224. CALL FA (NPAR, T, Y, WORK(IA), MATDIM, ML, MU, NDECOM)
  1225. IF (NPAR .EQ. 0) THEN
  1226. NSTATE = 9
  1227. RETURN
  1228. END IF
  1229. CALL DGEFA (WORK(IA), MATDIM, N, IWORK(INDPVT), INFO)
  1230. IF (INFO .NE. 0) GO TO 690
  1231. CALL DGESL (WORK(IA), MATDIM, N, IWORK(INDPVT),
  1232. 8 WORK(ISAVE2), 0)
  1233. ELSE IF (MITER .EQ. 4 .OR. MITER .EQ. 5) THEN
  1234. CALL FA (NPAR, T, Y, WORK(IA+ML), MATDIM, ML, MU, NDECOM)
  1235. IF (NPAR .EQ. 0) THEN
  1236. NSTATE = 9
  1237. RETURN
  1238. END IF
  1239. CALL DGBFA (WORK(IA), MATDIM, N, ML, MU, IWORK(INDPVT),
  1240. 8 INFO)
  1241. IF (INFO .NE. 0) GO TO 690
  1242. CALL DGBSL (WORK(IA), MATDIM, N, ML, MU, IWORK(INDPVT),
  1243. 8 WORK(ISAVE2), 0)
  1244. END IF
  1245. ELSE IF (IMPL .EQ. 2) THEN
  1246. CALL FA (NPAR, T, Y, WORK(IA), MATDIM, ML, MU, NDECOM)
  1247. IF (NPAR .EQ. 0) THEN
  1248. NSTATE = 9
  1249. RETURN
  1250. END IF
  1251. DO 340 I = 1,NDECOM
  1252. IF (WORK(I+IA-1) .EQ. 0.D0) GO TO 690
  1253. 340 WORK(I+ISAVE2-1) = WORK(I+ISAVE2-1)/WORK(I+IA-1)
  1254. ELSE IF (IMPL .EQ. 3) THEN
  1255. IF (MITER .EQ. 1 .OR. MITER .EQ. 2) THEN
  1256. CALL FA (NPAR, T, Y, WORK(IA), MATDIM, ML, MU, NDECOM)
  1257. IF (NPAR .EQ. 0) THEN
  1258. NSTATE = 9
  1259. RETURN
  1260. END IF
  1261. CALL DGEFA (WORK(IA), MATDIM, NDE, IWORK(INDPVT), INFO)
  1262. IF (INFO .NE. 0) GO TO 690
  1263. CALL DGESL (WORK(IA), MATDIM, NDE, IWORK(INDPVT),
  1264. 8 WORK(ISAVE2), 0)
  1265. ELSE IF (MITER .EQ. 4 .OR. MITER .EQ. 5) THEN
  1266. CALL FA (NPAR, T, Y, WORK(IA+ML), MATDIM, ML, MU, NDECOM)
  1267. IF (NPAR .EQ. 0) THEN
  1268. NSTATE = 9
  1269. RETURN
  1270. END IF
  1271. CALL DGBFA (WORK(IA), MATDIM, NDE, ML, MU, IWORK(INDPVT),
  1272. 8 INFO)
  1273. IF (INFO .NE. 0) GO TO 690
  1274. CALL DGBSL (WORK(IA), MATDIM, NDE, ML, MU, IWORK(INDPVT),
  1275. 8 WORK(ISAVE2), 0)
  1276. END IF
  1277. END IF
  1278. END IF
  1279. DO 360 J = I,N
  1280. IF (Y(J) .NE. 0.D0) THEN
  1281. WORK(J+IYWT-1) = ABS(Y(J))
  1282. ELSE
  1283. IF (IWORK(IJTASK) .EQ. 0) THEN
  1284. WORK(J+IYWT-1) = ABS(H*WORK(J+ISAVE2-1))
  1285. ELSE
  1286. WORK(J+IYWT-1) = ABS(WORK(J+IYH+N-1))
  1287. END IF
  1288. END IF
  1289. IF (WORK(J+IYWT-1) .EQ. 0.D0) WORK(J+IYWT-1) = UROUND
  1290. 360 CONTINUE
  1291. ELSE IF (IERROR .EQ. 3) THEN
  1292. DO 380 I = 1,N
  1293. 380 WORK(I+IYWT-1) = MAX(EWT(1), ABS(Y(I)))
  1294. ELSE IF (IERROR .EQ. 4) THEN
  1295. DO 400 I = 1,N
  1296. 400 WORK(I+IYWT-1) = MAX(EWT(I), ABS(Y(I)))
  1297. END IF
  1298. C
  1299. 410 DO 420 I = 1,N
  1300. 420 WORK(I+ISAVE2-1) = Y(I)/WORK(I+IYWT-1)
  1301. SUM = DNRM2(N, WORK(ISAVE2), 1)/SQRT(DBLE(N))
  1302. SUM = MAX(1.D0, SUM)
  1303. IF (EPS .LT. SUM*UROUND) THEN
  1304. EPS = SUM*UROUND*(1.D0 + 10.D0*UROUND)
  1305. WRITE(RL1, '(D16.8)') T
  1306. WRITE(RL2, '(D16.8)') EPS
  1307. IERFLG = 4
  1308. CALL XERMSG('SLATEC', 'DDRIV3',
  1309. 8 'At T, '//RL1//', the requested accuracy, EPS, was not '//
  1310. 8 'obtainable with the machine precision. EPS has been '//
  1311. 8 'increased to '//RL2//' .', IERFLG, 0)
  1312. NSTATE = 4
  1313. GO TO 560
  1314. END IF
  1315. IF (ABS(H) .GE. UROUND*ABS(T)) THEN
  1316. IWORK(INDPRT) = 0
  1317. ELSE IF (IWORK(INDPRT) .EQ. 0) THEN
  1318. WRITE(RL1, '(D16.8)') T
  1319. WRITE(RL2, '(D16.8)') H
  1320. IERFLG = 15
  1321. CALL XERMSG('SLATEC', 'DDRIV3',
  1322. 8 'At T, '//RL1//', the step size, '//RL2//', is smaller '//
  1323. 8 'than the roundoff level of T. This may occur if there is '//
  1324. 8 'an abrupt change in the right hand side of the '//
  1325. 8 'differential equations.', IERFLG, 0)
  1326. IWORK(INDPRT) = 1
  1327. END IF
  1328. IF (NTASK.NE.2) THEN
  1329. IF ((IWORK(INSTEP)-NSTEPL) .EQ. MXSTEP) THEN
  1330. WRITE(RL1, '(D16.8)') T
  1331. WRITE(INTGR1, '(I8)') MXSTEP
  1332. WRITE(RL2, '(D16.8)') TOUT
  1333. IERFLG = 3
  1334. CALL XERMSG('SLATEC', 'DDRIV3',
  1335. 8 'At T, '//RL1//', '//INTGR1//' steps have been taken '//
  1336. 8 'without reaching TOUT, '//RL2//' .', IERFLG, 0)
  1337. NSTATE = 3
  1338. GO TO 560
  1339. END IF
  1340. END IF
  1341. C
  1342. C CALL DDSTP (EPS, F, FA, HMAX, IMPL, IERROR, JACOBN, MATDIM,
  1343. C 8 MAXORD, MINT, MITER, ML, MU, N, NDE, YWT, UROUND,
  1344. C 8 USERS, AVGH, AVGORD, H, HUSED, JTASK, MNTOLD, MTROLD,
  1345. C 8 NFE, NJE, NQUSED, NSTEP, T, Y, YH, A, CONVRG,
  1346. C 8 DFDY, EL, FAC, HOLD, IPVT, JSTATE, JSTEPL, NQ, NWAIT,
  1347. C 8 RC, RMAX, SAVE1, SAVE2, TQ, TREND, ISWFLG, MTRSV,
  1348. C 8 MXRDSV)
  1349. C
  1350. CALL DDSTP (EPS, F, FA, WORK(IHMAX), IMPL, IERROR, JACOBN,
  1351. 8 MATDIM, IWORK(IMXORD), IWORK(IMNT), IWORK(IMTR), ML,
  1352. 8 MU, NPAR, NDECOM, WORK(IYWT), UROUND, USERS,
  1353. 8 WORK(IAVGH), WORK(IAVGRD), WORK(IH), HUSED,
  1354. 8 IWORK(IJTASK), IWORK(IMNTLD), IWORK(IMTRLD),
  1355. 8 IWORK(INFE), IWORK(INJE), IWORK(INQUSE),
  1356. 8 IWORK(INSTEP), WORK(IT), Y, WORK(IYH), WORK(IA),
  1357. 8 CONVRG, WORK(IDFDY), WORK(IEL), WORK(IFAC),
  1358. 8 WORK(IHOLD), IWORK(INDPVT), JSTATE, IWORK(IJSTPL),
  1359. 8 IWORK(INQ), IWORK(INWAIT), WORK(IRC), WORK(IRMAX),
  1360. 8 WORK(ISAVE1), WORK(ISAVE2), WORK(ITQ), WORK(ITREND),
  1361. 8 MINT, IWORK(IMTRSV), IWORK(IMXRDS))
  1362. T = WORK(IT)
  1363. H = WORK(IH)
  1364. IF (CONVRG) THEN
  1365. IWORK(ICNVRG) = 1
  1366. ELSE
  1367. IWORK(ICNVRG) = 0
  1368. END IF
  1369. GO TO (470, 670, 680, 690, 690, 660, 660, 660, 660, 660), JSTATE
  1370. 470 IWORK(IJTASK) = 1
  1371. C Determine if a root has been overtaken
  1372. IF (NROOT .NE. 0) THEN
  1373. IROOT = 0
  1374. DO 500 I = 1,NROOT
  1375. GLAST = WORK(I+IGNOW-1)
  1376. GNOW = G (NPAR, T, Y, I)
  1377. IF (NPAR .EQ. 0) THEN
  1378. IWORK(INROOT) = I
  1379. NSTATE = 7
  1380. RETURN
  1381. END IF
  1382. WORK(I+IGNOW-1) = GNOW
  1383. IF (GLAST*GNOW .GT. 0.D0) THEN
  1384. WORK(I+ITROOT-1) = T + H
  1385. ELSE
  1386. IF (GNOW .EQ. 0.D0) THEN
  1387. WORK(I+ITROOT-1) = T
  1388. IROOT = I
  1389. ELSE
  1390. IF (GLAST .EQ. 0.D0) THEN
  1391. WORK(I+ITROOT-1) = T + H
  1392. ELSE
  1393. IF (ABS(HUSED) .GE. UROUND*ABS(T)) THEN
  1394. TLAST = T - HUSED
  1395. IROOT = I
  1396. TROOT = T
  1397. CALL DDZRO (AE, G, H, NPAR, IWORK(INQ), IROOT, RE, T,
  1398. 8 WORK(IYH), UROUND, TROOT, TLAST,
  1399. 8 GNOW, GLAST, Y)
  1400. DO 480 J = 1,N
  1401. 480 Y(J) = WORK(IYH+J-1)
  1402. IF (NPAR .EQ. 0) THEN
  1403. IWORK(INROOT) = I
  1404. NSTATE = 7
  1405. RETURN
  1406. END IF
  1407. WORK(I+ITROOT-1) = TROOT
  1408. ELSE
  1409. WORK(I+ITROOT-1) = T
  1410. IROOT = I
  1411. END IF
  1412. END IF
  1413. END IF
  1414. END IF
  1415. 500 CONTINUE
  1416. IF (IROOT .EQ. 0) THEN
  1417. IWORK(IJROOT) = 0
  1418. C Select the first root
  1419. ELSE
  1420. IWORK(IJROOT) = NTASK
  1421. IWORK(INRTLD) = NROOT
  1422. IWORK(INDTRT) = ITROOT
  1423. TROOT = T + H
  1424. DO 510 I = 1,NROOT
  1425. IF (WORK(I+ITROOT-1)*HSIGN .LT. TROOT*HSIGN) THEN
  1426. TROOT = WORK(I+ITROOT-1)
  1427. IROOT = I
  1428. END IF
  1429. 510 CONTINUE
  1430. IWORK(INROOT) = IROOT
  1431. WORK(ITOUT) = TROOT
  1432. IF (TROOT*HSIGN .LE. TOUT*HSIGN) THEN
  1433. CALL DDNTP (H, 0, N, IWORK(INQ), T, TROOT, WORK(IYH), Y)
  1434. NSTATE = 5
  1435. T = TROOT
  1436. IERFLG = 0
  1437. GO TO 580
  1438. END IF
  1439. END IF
  1440. END IF
  1441. C Test for NTASK condition to be satisfied
  1442. NSTATE = 2
  1443. IF (NTASK .EQ. 1) THEN
  1444. IF (T*HSIGN .LT. TOUT*HSIGN) GO TO 260
  1445. CALL DDNTP (H, 0, N, IWORK(INQ), T, TOUT, WORK(IYH), Y)
  1446. T = TOUT
  1447. IERFLG = 0
  1448. GO TO 580
  1449. C TOUT is assumed to have been attained
  1450. C exactly if T is within twenty roundoff
  1451. C units of TOUT, relative to MAX(TOUT, T).
  1452. C
  1453. ELSE IF (NTASK .EQ. 2) THEN
  1454. IF (ABS(TOUT - T).LE.NROUND*UROUND*MAX(ABS(T), ABS(TOUT))) THEN
  1455. T = TOUT
  1456. ELSE
  1457. IF ((T + H)*HSIGN .GT. TOUT*HSIGN) THEN
  1458. H = TOUT - T
  1459. IF ((T + H)*HSIGN.GT.TOUT*HSIGN) H = H*(1.D0 - 4.D0*UROUND)
  1460. WORK(IH) = H
  1461. IF (H .EQ. 0.D0) GO TO 670
  1462. IWORK(IJTASK) = -1
  1463. END IF
  1464. END IF
  1465. ELSE IF (NTASK .EQ. 3) THEN
  1466. IF (ABS(TOUT - T).LE.NROUND*UROUND*MAX(ABS(T), ABS(TOUT))) THEN
  1467. T = TOUT
  1468. ELSE
  1469. IF ((T + H)*HSIGN .GT. TOUT*HSIGN) THEN
  1470. H = TOUT - T
  1471. IF ((T + H)*HSIGN.GT.TOUT*HSIGN) H = H*(1.D0 - 4.D0*UROUND)
  1472. WORK(IH) = H
  1473. IF (H .EQ. 0.D0) GO TO 670
  1474. IWORK(IJTASK) = -1
  1475. END IF
  1476. GO TO 260
  1477. END IF
  1478. END IF
  1479. IERFLG = 0
  1480. C All returns are made through this
  1481. C section. IMXERR is determined.
  1482. 560 DO 570 I = 1,N
  1483. 570 Y(I) = WORK(I+IYH-1)
  1484. 580 IF (IWORK(IJTASK) .EQ. 0) RETURN
  1485. BIG = 0.D0
  1486. IMXERR = 1
  1487. DO 590 I = 1,N
  1488. C SIZE = ABS(ERROR(I)/YWT(I))
  1489. SIZE = ABS(WORK(I+ISAVE1-1)/WORK(I+IYWT-1))
  1490. IF (BIG .LT. SIZE) THEN
  1491. BIG = SIZE
  1492. IMXERR = I
  1493. END IF
  1494. 590 CONTINUE
  1495. IWORK(INDMXR) = IMXERR
  1496. WORK(IHUSED) = HUSED
  1497. RETURN
  1498. C
  1499. 660 NSTATE = JSTATE
  1500. RETURN
  1501. C Fatal errors are processed here
  1502. C
  1503. 670 WRITE(RL1, '(D16.8)') T
  1504. IERFLG = 41
  1505. CALL XERMSG('SLATEC', 'DDRIV3',
  1506. 8 'At T, '//RL1//', the attempted step size has gone to '//
  1507. 8 'zero. Often this occurs if the problem setup is incorrect.',
  1508. 8 IERFLG, 1)
  1509. NSTATE = 12
  1510. RETURN
  1511. C
  1512. 680 WRITE(RL1, '(D16.8)') T
  1513. IERFLG = 42
  1514. CALL XERMSG('SLATEC', 'DDRIV3',
  1515. 8 'At T, '//RL1//', the step size has been reduced about 50 '//
  1516. 8 'times without advancing the solution. Often this occurs '//
  1517. 8 'if the problem setup is incorrect.', IERFLG, 1)
  1518. NSTATE = 12
  1519. RETURN
  1520. C
  1521. 690 WRITE(RL1, '(D16.8)') T
  1522. IERFLG = 43
  1523. CALL XERMSG('SLATEC', 'DDRIV3',
  1524. 8 'At T, '//RL1//', while solving A*YDOT = F, A is singular.',
  1525. 8 IERFLG, 1)
  1526. NSTATE = 12
  1527. RETURN
  1528. END