cdriv3.f 69 KB

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