12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526 |
- *DECK SDRIV3
- SUBROUTINE SDRIV3 (N, T, Y, F, NSTATE, TOUT, NTASK, NROOT, EPS,
- 8 EWT, IERROR, MINT, MITER, IMPL, ML, MU, MXORD, HMAX, WORK,
- 8 LENW, IWORK, LENIW, JACOBN, FA, NDE, MXSTEP, G, USERS, IERFLG)
- C***BEGIN PROLOGUE SDRIV3
- C***PURPOSE The function of SDRIV3 is to solve N ordinary differential
- C equations of the form dY(I)/dT = F(Y(I),T), given the
- C initial conditions Y(I) = YI. The program has options to
- C allow the solution of both stiff and non-stiff differential
- C equations. Other important options are available. SDRIV3
- C uses single precision arithmetic.
- C***LIBRARY SLATEC (SDRIVE)
- C***CATEGORY I1A2, I1A1B
- C***TYPE SINGLE PRECISION (SDRIV3-S, DDRIV3-D, CDRIV3-C)
- C***KEYWORDS GEAR'S METHOD, INITIAL VALUE PROBLEMS, ODE,
- C ORDINARY DIFFERENTIAL EQUATIONS, SDRIVE, SINGLE PRECISION,
- C STIFF
- C***AUTHOR Kahaner, D. K., (NIST)
- C National Institute of Standards and Technology
- C Gaithersburg, MD 20899
- C Sutherland, C. D., (LANL)
- C Mail Stop D466
- C Los Alamos National Laboratory
- C Los Alamos, NM 87545
- C***DESCRIPTION
- C
- C I. ABSTRACT .......................................................
- C
- C The primary function of SDRIV3 is to solve N ordinary differential
- C equations of the form dY(I)/dT = F(Y(I),T), given the initial
- C conditions Y(I) = YI. The program has options to allow the
- C solution of both stiff and non-stiff differential equations. In
- C addition, SDRIV3 may be used to solve:
- C 1. The initial value problem, A*dY(I)/dT = F(Y(I),T), where A is
- C a non-singular matrix depending on Y and T.
- C 2. The hybrid differential/algebraic initial value problem,
- C A*dY(I)/dT = F(Y(I),T), where A is a vector (whose values may
- C depend upon Y and T) some of whose components will be zero
- C corresponding to those equations which are algebraic rather
- C than differential.
- C SDRIV3 is to be called once for each output point of T.
- C
- C II. PARAMETERS ....................................................
- C
- C The user should use parameter names in the call sequence of SDRIV3
- C for those quantities whose value may be altered by SDRIV3. The
- C parameters in the call sequence are:
- C
- C N = (Input) The number of dependent functions whose solution
- C is desired. N must not be altered during a problem.
- C
- C T = The independent variable. On input for the first call, T
- C is the initial point. On output, T is the point at which
- C the solution is given.
- C
- C Y = The vector of dependent variables. Y is used as input on
- C the first call, to set the initial values. On output, Y
- C is the computed solution vector. This array Y is passed
- C in the call sequence of the user-provided routines F,
- C JACOBN, FA, USERS, and G. Thus parameters required by
- C those routines can be stored in this array in components
- C N+1 and above. (Note: Changes by the user to the first
- C N components of this array will take effect only after a
- C restart, i.e., after setting NSTATE to 1 .)
- C
- C F = A subroutine supplied by the user. The name must be
- C declared EXTERNAL in the user's calling program. This
- C subroutine is of the form:
- C SUBROUTINE F (N, T, Y, YDOT)
- C REAL Y(*), YDOT(*)
- C .
- C .
- C YDOT(1) = ...
- C .
- C .
- C YDOT(N) = ...
- C END (Sample)
- C This computes YDOT = F(Y,T), the right hand side of the
- C differential equations. Here Y is a vector of length at
- C least N. The actual length of Y is determined by the
- C user's declaration in the program which calls SDRIV3.
- C Thus the dimensioning of Y in F, while required by FORTRAN
- C convention, does not actually allocate any storage. When
- C this subroutine is called, the first N components of Y are
- C intermediate approximations to the solution components.
- C The user should not alter these values. Here YDOT is a
- C vector of length N. The user should only compute YDOT(I)
- C for I from 1 to N. Normally a return from F passes
- C control back to SDRIV3. However, if the user would like
- C to abort the calculation, i.e., return control to the
- C program which calls SDRIV3, he should set N to zero.
- C SDRIV3 will signal this by returning a value of NSTATE
- C equal to 6 . Altering the value of N in F has no effect
- C on the value of N in the call sequence of SDRIV3.
- C
- C NSTATE = An integer describing the status of integration. The
- C meaning of NSTATE is as follows:
- C 1 (Input) Means the first call to the routine. This
- C value must be set by the user. On all subsequent
- C calls the value of NSTATE should be tested by the
- C user, but must not be altered. (As a convenience to
- C the user who may wish to put out the initial
- C conditions, SDRIV3 can be called with NSTATE=1, and
- C TOUT=T. In this case the program will return with
- C NSTATE unchanged, i.e., NSTATE=1.)
- C 2 (Output) Means a successful integration. If a normal
- C continuation is desired (i.e., a further integration
- C in the same direction), simply advance TOUT and call
- C again. All other parameters are automatically set.
- C 3 (Output)(Unsuccessful) Means the integrator has taken
- C MXSTEP steps without reaching TOUT. The user can
- C continue the integration by simply calling SDRIV3
- C again.
- C 4 (Output)(Unsuccessful) Means too much accuracy has
- C been requested. EPS has been increased to a value
- C the program estimates is appropriate. The user can
- C continue the integration by simply calling SDRIV3
- C again.
- C 5 (Output) A root was found at a point less than TOUT.
- C The user can continue the integration toward TOUT by
- C simply calling SDRIV3 again.
- C 6 (Output)(Unsuccessful) N has been set to zero in
- C SUBROUTINE F.
- C 7 (Output)(Unsuccessful) N has been set to zero in
- C FUNCTION G. See description of G below.
- C 8 (Output)(Unsuccessful) N has been set to zero in
- C SUBROUTINE JACOBN. See description of JACOBN below.
- C 9 (Output)(Unsuccessful) N has been set to zero in
- C SUBROUTINE FA. See description of FA below.
- C 10 (Output)(Unsuccessful) N has been set to zero in
- C SUBROUTINE USERS. See description of USERS below.
- C 11 (Output)(Successful) For NTASK = 2 or 3, T is beyond
- C TOUT. The solution was obtained by interpolation.
- C The user can continue the integration by simply
- C advancing TOUT and calling SDRIV3 again.
- C 12 (Output)(Unsuccessful) The solution could not be
- C obtained. The value of IERFLG (see description
- C below) for a "Recoverable" situation indicates the
- C type of difficulty encountered: either an illegal
- C value for a parameter or an inability to continue the
- C solution. For this condition the user should take
- C corrective action and reset NSTATE to 1 before
- C calling SDRIV3 again. Otherwise the program will
- C terminate the run.
- C
- C TOUT = (Input) The point at which the solution is desired. The
- C position of TOUT relative to T on the first call
- C determines the direction of integration.
- C
- C NTASK = (Input) An index specifying the manner of returning the
- C solution, according to the following:
- C NTASK = 1 Means SDRIV3 will integrate past TOUT and
- C interpolate the solution. This is the most
- C efficient mode.
- C NTASK = 2 Means SDRIV3 will return the solution after
- C each internal integration step, or at TOUT,
- C whichever comes first. In the latter case,
- C the program integrates exactly to TOUT.
- C NTASK = 3 Means SDRIV3 will adjust its internal step to
- C reach TOUT exactly (useful if a singularity
- C exists beyond TOUT.)
- C
- C NROOT = (Input) The number of equations whose roots are desired.
- C If NROOT is zero, the root search is not active. This
- C option is useful for obtaining output at points which are
- C not known in advance, but depend upon the solution, e.g.,
- C when some solution component takes on a specified value.
- C The root search is carried out using the user-written
- C function G (see description of G below.) SDRIV3 attempts
- C to find the value of T at which one of the equations
- C changes sign. SDRIV3 can find at most one root per
- C equation per internal integration step, and will then
- C return the solution either at TOUT or at a root, whichever
- C occurs first in the direction of integration. The initial
- C point is never reported as a root. The index of the
- C equation whose root is being reported is stored in the
- C sixth element of IWORK.
- C NOTE: NROOT is never altered by this program.
- C
- C EPS = On input, the requested relative accuracy in all solution
- C components. EPS = 0 is allowed. On output, the adjusted
- C relative accuracy if the input value was too small. The
- C value of EPS should be set as large as is reasonable,
- C because the amount of work done by SDRIV3 increases as EPS
- C decreases.
- C
- C EWT = (Input) Problem zero, i.e., the smallest, nonzero,
- C physically meaningful value for the solution. (Array,
- C possibly of length one. See following description of
- C IERROR.) Setting EWT smaller than necessary can adversely
- C affect the running time.
- C
- C IERROR = (Input) Error control indicator. A value of 3 is
- C suggested for most problems. Other choices and detailed
- C explanations of EWT and IERROR are given below for those
- C who may need extra flexibility.
- C
- C These last three input quantities EPS, EWT and IERROR
- C control the accuracy of the computed solution. EWT and
- C IERROR are used internally to compute an array YWT. One
- C step error estimates divided by YWT(I) are kept less than
- C EPS in root mean square norm.
- C IERROR (Set by the user) =
- C 1 Means YWT(I) = 1. (Absolute error control)
- C EWT is ignored.
- C 2 Means YWT(I) = ABS(Y(I)), (Relative error control)
- C EWT is ignored.
- C 3 Means YWT(I) = MAX(ABS(Y(I)), EWT(1)).
- C 4 Means YWT(I) = MAX(ABS(Y(I)), EWT(I)).
- C This choice is useful when the solution components
- C have differing scales.
- C 5 Means YWT(I) = EWT(I).
- C If IERROR is 3, EWT need only be dimensioned one.
- C If IERROR is 4 or 5, the user must dimension EWT at least
- C N, and set its values.
- C
- C MINT = (Input) The integration method indicator.
- C MINT = 1 Means the Adams methods, and is used for
- C non-stiff problems.
- C MINT = 2 Means the stiff methods of Gear (i.e., the
- C backward differentiation formulas), and is
- C used for stiff problems.
- C MINT = 3 Means the program dynamically selects the
- C Adams methods when the problem is non-stiff
- C and the Gear methods when the problem is
- C stiff. When using the Adams methods, the
- C program uses a value of MITER=0; when using
- C the Gear methods, the program uses the value
- C of MITER provided by the user. Only a value
- C of IMPL = 0 and a value of MITER = 1, 2, 4, or
- C 5 is allowed for this option. The user may
- C not alter the value of MINT or MITER without
- C restarting, i.e., setting NSTATE to 1.
- C
- C MITER = (Input) The iteration method indicator.
- C MITER = 0 Means functional iteration. This value is
- C suggested for non-stiff problems.
- C MITER = 1 Means chord method with analytic Jacobian.
- C In this case, the user supplies subroutine
- C JACOBN (see description below).
- C MITER = 2 Means chord method with Jacobian calculated
- C internally by finite differences.
- C MITER = 3 Means chord method with corrections computed
- C by the user-written routine USERS (see
- C description of USERS below.) This option
- C allows all matrix algebra and storage
- C decisions to be made by the user. When using
- C a value of MITER = 3, the subroutine FA is
- C not required, even if IMPL is not 0. For
- C further information on using this option, see
- C Section IV-E below.
- C MITER = 4 Means the same as MITER = 1 but the A and
- C Jacobian matrices are assumed to be banded.
- C MITER = 5 Means the same as MITER = 2 but the A and
- C Jacobian matrices are assumed to be banded.
- C
- C IMPL = (Input) The implicit method indicator.
- C IMPL = 0 Means solving dY(I)/dT = F(Y(I),T).
- C IMPL = 1 Means solving A*dY(I)/dT = F(Y(I),T), non-
- C singular A (see description of FA below.)
- C Only MINT = 1 or 2, and MITER = 1, 2, 3, 4,
- C or 5 are allowed for this option.
- C IMPL = 2,3 Means solving certain systems of hybrid
- C differential/algebraic equations (see
- C description of FA below.) Only MINT = 2 and
- C MITER = 1, 2, 3, 4, or 5, are allowed for
- C this option.
- C The value of IMPL must not be changed during a problem.
- C
- C ML = (Input) The lower half-bandwidth in the case of a banded
- C A or Jacobian matrix. (I.e., maximum(R-C) for nonzero
- C A(R,C).)
- C
- C MU = (Input) The upper half-bandwidth in the case of a banded
- C A or Jacobian matrix. (I.e., maximum(C-R).)
- C
- C MXORD = (Input) The maximum order desired. This is .LE. 12 for
- C the Adams methods and .LE. 5 for the Gear methods. Normal
- C value is 12 and 5, respectively. If MINT is 3, the
- C maximum order used will be MIN(MXORD, 12) when using the
- C Adams methods, and MIN(MXORD, 5) when using the Gear
- C methods. MXORD must not be altered during a problem.
- C
- C HMAX = (Input) The maximum magnitude of the step size that will
- C be used for the problem. This is useful for ensuring that
- C important details are not missed. If this is not the
- C case, a large value, such as the interval length, is
- C suggested.
- C
- C WORK
- C LENW = (Input)
- C WORK is an array of LENW real words used
- C internally for temporary storage. The user must allocate
- C space for this array in the calling program by a statement
- C such as
- C REAL WORK(...)
- C The following table gives the required minimum value for
- C the length of WORK, depending on the value of IMPL and
- C MITER. LENW should be set to the value used. The
- C contents of WORK should not be disturbed between calls to
- C SDRIV3.
- C
- C IMPL = 0 1 2 3
- C ---------------------------------------------------------
- C MITER = 0 (MXORD+4)*N Not allowed Not allowed Not allowed
- C + 2*NROOT
- C + 250
- C
- C 1,2 N*N + 2*N*N + N*N + N*(N + NDE)
- C (MXORD+5)*N (MXORD+5)*N (MXORD+6)*N + (MXORD+5)*N
- C + 2*NROOT + 2*NROOT + 2*NROOT + 2*NROOT
- C + 250 + 250 + 250 + 250
- C
- C 3 (MXORD+4)*N (MXORD+4)*N (MXORD+4)*N (MXORD+4)*N
- C + 2*NROOT + 2*NROOT + 2*NROOT + 2*NROOT
- C + 250 + 250 + 250 + 250
- C
- C 4,5 (2*ML+MU+1) 2*(2*ML+MU+1) (2*ML+MU+1) (2*ML+MU+1)*
- C *N + *N + *N + (N+NDE) +
- C (MXORD+5)*N (MXORD+5)*N (MXORD+6)*N + (MXORD+5)*N
- C + 2*NROOT + 2*NROOT + 2*NROOT + 2*NROOT
- C + 250 + 250 + 250 + 250
- C ---------------------------------------------------------
- C
- C IWORK
- C LENIW = (Input)
- C IWORK is an integer array of length LENIW used internally
- C for temporary storage. The user must allocate space for
- C this array in the calling program by a statement such as
- C INTEGER IWORK(...)
- C The length of IWORK should be at least
- C 50 if MITER is 0 or 3, or
- C N+50 if MITER is 1, 2, 4, or 5, or MINT is 3,
- C and LENIW should be set to the value used. The contents
- C of IWORK should not be disturbed between calls to SDRIV3.
- C
- C JACOBN = A subroutine supplied by the user, if MITER is 1 or 4.
- C If this is the case, the name must be declared EXTERNAL in
- C the user's calling program. Given a system of N
- C differential equations, it is meaningful to speak about
- C the partial derivative of the I-th right hand side with
- C respect to the J-th dependent variable. In general there
- C are N*N such quantities. Often however the equations can
- C be ordered so that the I-th differential equation only
- C involves dependent variables with index near I, e.g., I+1,
- C I-2. Such a system is called banded. If, for all I, the
- C I-th equation depends on at most the variables
- C Y(I-ML), Y(I-ML+1), ... , Y(I), Y(I+1), ... , Y(I+MU)
- C then we call ML+MU+1 the bandwidth of the system. In a
- C banded system many of the partial derivatives above are
- C automatically zero. For the cases MITER = 1, 2, 4, and 5,
- C some of these partials are needed. For the cases
- C MITER = 2 and 5 the necessary derivatives are
- C approximated numerically by SDRIV3, and we only ask the
- C user to tell SDRIV3 the value of ML and MU if the system
- C is banded. For the cases MITER = 1 and 4 the user must
- C derive these partials algebraically and encode them in
- C subroutine JACOBN. By computing these derivatives the
- C user can often save 20-30 per cent of the computing time.
- C Usually, however, the accuracy is not much affected and
- C most users will probably forego this option. The optional
- C user-written subroutine JACOBN has the form:
- C SUBROUTINE JACOBN (N, T, Y, DFDY, MATDIM, ML, MU)
- C REAL Y(*), DFDY(MATDIM,*)
- C .
- C .
- C Calculate values of DFDY
- C .
- C .
- C END (Sample)
- C Here Y is a vector of length at least N. The actual
- C length of Y is determined by the user's declaration in the
- C program which calls SDRIV3. Thus the dimensioning of Y in
- C JACOBN, while required by FORTRAN convention, does not
- C actually allocate any storage. When this subroutine is
- C called, the first N components of Y are intermediate
- C approximations to the solution components. The user
- C should not alter these values. If the system is not
- C banded (MITER=1), the partials of the I-th equation with
- C respect to the J-th dependent function are to be stored in
- C DFDY(I,J). Thus partials of the I-th equation are stored
- C in the I-th row of DFDY. If the system is banded
- C (MITER=4), then the partials of the I-th equation with
- C respect to Y(J) are to be stored in DFDY(K,J), where
- C K=I-J+MU+1 . Normally a return from JACOBN passes control
- C back to SDRIV3. However, if the user would like to abort
- C the calculation, i.e., return control to the program which
- C calls SDRIV3, he should set N to zero. SDRIV3 will signal
- C this by returning a value of NSTATE equal to +8(-8).
- C Altering the value of N in JACOBN has no effect on the
- C value of N in the call sequence of SDRIV3.
- C
- C FA = A subroutine supplied by the user if IMPL is not zero, and
- C MITER is not 3. If so, the name must be declared EXTERNAL
- C in the user's calling program. This subroutine computes
- C the array A, where A*dY(I)/dT = F(Y(I),T).
- C There are three cases:
- C
- C IMPL=1.
- C Subroutine FA is of the form:
- C SUBROUTINE FA (N, T, Y, A, MATDIM, ML, MU, NDE)
- C REAL Y(*), A(MATDIM,*)
- C .
- C .
- C Calculate ALL values of A
- C .
- C .
- C END (Sample)
- C In this case A is assumed to be a nonsingular matrix,
- C with the same structure as DFDY (see JACOBN description
- C above). Programming considerations prevent complete
- C generality. If MITER is 1 or 2, A is assumed to be full
- C and the user must compute and store all values of
- C A(I,J), I,J=1, ... ,N. If MITER is 4 or 5, A is assumed
- C to be banded with lower and upper half bandwidth ML and
- C MU. The left hand side of the I-th equation is a linear
- C combination of dY(I-ML)/dT, dY(I-ML+1)/dT, ... ,
- C dY(I)/dT, ... , dY(I+MU-1)/dT, dY(I+MU)/dT. Thus in the
- C I-th equation, the coefficient of dY(J)/dT is to be
- C stored in A(K,J), where K=I-J+MU+1.
- C NOTE: The array A will be altered between calls to FA.
- C
- C IMPL=2.
- C Subroutine FA is of the form:
- C SUBROUTINE FA (N, T, Y, A, MATDIM, ML, MU, NDE)
- C REAL Y(*), A(*)
- C .
- C .
- C Calculate non-zero values of A(1),...,A(NDE)
- C .
- C .
- C END (Sample)
- C In this case it is assumed that the system is ordered by
- C the user so that the differential equations appear
- C first, and the algebraic equations appear last. The
- C algebraic equations must be written in the form:
- C 0 = F(Y(I),T). When using this option it is up to the
- C user to provide initial values for the Y(I) that satisfy
- C the algebraic equations as well as possible. It is
- C further assumed that A is a vector of length NDE. All
- C of the components of A, which may depend on T, Y(I),
- C etc., must be set by the user to non-zero values.
- C
- C IMPL=3.
- C Subroutine FA is of the form:
- C SUBROUTINE FA (N, T, Y, A, MATDIM, ML, MU, NDE)
- C REAL Y(*), A(MATDIM,*)
- C .
- C .
- C Calculate ALL values of A
- C .
- C .
- C END (Sample)
- C In this case A is assumed to be a nonsingular NDE by NDE
- C matrix with the same structure as DFDY (see JACOBN
- C description above). Programming considerations prevent
- C complete generality. If MITER is 1 or 2, A is assumed
- C to be full and the user must compute and store all
- C values of A(I,J), I,J=1, ... ,NDE. If MITER is 4 or 5,
- C A is assumed to be banded with lower and upper half
- C bandwidths ML and MU. The left hand side of the I-th
- C equation is a linear combination of dY(I-ML)/dT,
- C dY(I-ML+1)/dT, ... , dY(I)/dT, ... , dY(I+MU-1)/dT,
- C dY(I+MU)/dT. Thus in the I-th equation, the coefficient
- C of dY(J)/dT is to be stored in A(K,J), where K=I-J+MU+1.
- C It is assumed that the system is ordered by the user so
- C that the differential equations appear first, and the
- C algebraic equations appear last. The algebraic
- C equations must be written in the form 0 = F(Y(I),T).
- C When using this option it is up to the user to provide
- C initial values for the Y(I) that satisfy the algebraic
- C equations as well as possible.
- C NOTE: For IMPL = 3, the array A will be altered between
- C calls to FA.
- C Here Y is a vector of length at least N. The actual
- C length of Y is determined by the user's declaration in the
- C program which calls SDRIV3. Thus the dimensioning of Y in
- C FA, while required by FORTRAN convention, does not
- C actually allocate any storage. When this subroutine is
- C called, the first N components of Y are intermediate
- C approximations to the solution components. The user
- C should not alter these values. FA is always called
- C immediately after calling F, with the same values of T
- C and Y. Normally a return from FA passes control back to
- C SDRIV3. However, if the user would like to abort the
- C calculation, i.e., return control to the program which
- C calls SDRIV3, he should set N to zero. SDRIV3 will signal
- C this by returning a value of NSTATE equal to +9(-9).
- C Altering the value of N in FA has no effect on the value
- C of N in the call sequence of SDRIV3.
- C
- C NDE = (Input) The number of differential equations. This is
- C required only for IMPL = 2 or 3, with NDE .LT. N.
- C
- C MXSTEP = (Input) The maximum number of internal steps allowed on
- C one call to SDRIV3.
- C
- C G = A real FORTRAN function supplied by the user
- C if NROOT is not 0. In this case, the name must be
- C declared EXTERNAL in the user's calling program. G is
- C repeatedly called with different values of IROOT to obtain
- C the value of each of the NROOT equations for which a root
- C is desired. G is of the form:
- C REAL FUNCTION G (N, T, Y, IROOT)
- C REAL Y(*)
- C GO TO (10, ...), IROOT
- C 10 G = ...
- C .
- C .
- C END (Sample)
- C Here, Y is a vector of length at least N, whose first N
- C components are the solution components at the point T.
- C The user should not alter these values. The actual length
- C of Y is determined by the user's declaration in the
- C program which calls SDRIV3. Thus the dimensioning of Y in
- C G, while required by FORTRAN convention, does not actually
- C allocate any storage. Normally a return from G passes
- C control back to SDRIV3. However, if the user would like
- C to abort the calculation, i.e., return control to the
- C program which calls SDRIV3, he should set N to zero.
- C SDRIV3 will signal this by returning a value of NSTATE
- C equal to +7(-7). In this case, the index of the equation
- C being evaluated is stored in the sixth element of IWORK.
- C Altering the value of N in G has no effect on the value of
- C N in the call sequence of SDRIV3.
- C
- C USERS = A subroutine supplied by the user, if MITER is 3.
- C If this is the case, the name must be declared EXTERNAL in
- C the user's calling program. The routine USERS is called
- C by SDRIV3 when certain linear systems must be solved. The
- C user may choose any method to form, store and solve these
- C systems in order to obtain the solution result that is
- C returned to SDRIV3. In particular, this allows sparse
- C matrix methods to be used. The call sequence for this
- C routine is:
- C
- C SUBROUTINE USERS (Y, YH, YWT, SAVE1, SAVE2, T, H, EL,
- C 8 IMPL, N, NDE, IFLAG)
- C REAL Y(*), YH(*), YWT(*), SAVE1(*),
- C 8 SAVE2(*), T, H, EL
- C
- C The input variable IFLAG indicates what action is to be
- C taken. Subroutine USERS should perform the following
- C operations, depending on the value of IFLAG and IMPL.
- C
- C IFLAG = 0
- C IMPL = 0. USERS is not called.
- C IMPL = 1, 2 or 3. Solve the system A*X = SAVE2,
- C returning the result in SAVE2. The array SAVE1 can
- C be used as a work array. For IMPL = 1, there are N
- C components to the system, and for IMPL = 2 or 3,
- C there are NDE components to the system.
- C
- C IFLAG = 1
- C IMPL = 0. Compute, decompose and store the matrix
- C (I - H*EL*J), where I is the identity matrix and J
- C is the Jacobian matrix of the right hand side. The
- C array SAVE1 can be used as a work array.
- C IMPL = 1, 2 or 3. Compute, decompose and store the
- C matrix (A - H*EL*J). The array SAVE1 can be used as
- C a work array.
- C
- C IFLAG = 2
- C IMPL = 0. Solve the system
- C (I - H*EL*J)*X = H*SAVE2 - YH - SAVE1,
- C returning the result in SAVE2.
- C IMPL = 1, 2 or 3. Solve the system
- C (A - H*EL*J)*X = H*SAVE2 - A*(YH + SAVE1)
- C returning the result in SAVE2.
- C The array SAVE1 should not be altered.
- C If IFLAG is 0 and IMPL is 1 or 2 and the matrix A is
- C singular, or if IFLAG is 1 and one of the matrices
- C (I - H*EL*J), (A - H*EL*J) is singular, the INTEGER
- C variable IFLAG is to be set to -1 before RETURNing.
- C Normally a return from USERS passes control back to
- C SDRIV3. However, if the user would like to abort the
- C calculation, i.e., return control to the program which
- C calls SDRIV3, he should set N to zero. SDRIV3 will signal
- C this by returning a value of NSTATE equal to +10(-10).
- C Altering the value of N in USERS has no effect on the
- C value of N in the call sequence of SDRIV3.
- C
- C IERFLG = An error flag. The error number associated with a
- C diagnostic message (see Section III-A below) is the same
- C as the corresponding value of IERFLG. The meaning of
- C IERFLG:
- C 0 The routine completed successfully. (No message is
- C issued.)
- C 3 (Warning) The number of steps required to reach TOUT
- C exceeds MXSTEP.
- C 4 (Warning) The value of EPS is too small.
- C 11 (Warning) For NTASK = 2 or 3, T is beyond TOUT.
- C The solution was obtained by interpolation.
- C 15 (Warning) The integration step size is below the
- C roundoff level of T. (The program issues this
- C message as a warning but does not return control to
- C the user.)
- C 22 (Recoverable) N is not positive.
- C 23 (Recoverable) MINT is less than 1 or greater than 3 .
- C 24 (Recoverable) MITER is less than 0 or greater than
- C 5 .
- C 25 (Recoverable) IMPL is less than 0 or greater than 3 .
- C 26 (Recoverable) The value of NSTATE is less than 1 or
- C greater than 12 .
- C 27 (Recoverable) EPS is less than zero.
- C 28 (Recoverable) MXORD is not positive.
- C 29 (Recoverable) For MINT = 3, either MITER = 0 or 3, or
- C IMPL = 0 .
- C 30 (Recoverable) For MITER = 0, IMPL is not 0 .
- C 31 (Recoverable) For MINT = 1, IMPL is 2 or 3 .
- C 32 (Recoverable) Insufficient storage has been allocated
- C for the WORK array.
- C 33 (Recoverable) Insufficient storage has been allocated
- C for the IWORK array.
- C 41 (Recoverable) The integration step size has gone
- C to zero.
- C 42 (Recoverable) The integration step size has been
- C reduced about 50 times without advancing the
- C solution. The problem setup may not be correct.
- C 43 (Recoverable) For IMPL greater than 0, the matrix A
- C is singular.
- C 999 (Fatal) The value of NSTATE is 12 .
- C
- C III. OTHER COMMUNICATION TO THE USER ..............................
- C
- C A. The solver communicates to the user through the parameters
- C above. In addition it writes diagnostic messages through the
- C standard error handling program XERMSG. A complete description
- C of XERMSG is given in "Guide to the SLATEC Common Mathematical
- C Library" by Kirby W. Fong et al.. At installations which do not
- C have this error handling package the short but serviceable
- C routine, XERMSG, available with this package, can be used. That
- C program uses the file named OUTPUT to transmit messages.
- C
- C B. The first three elements of WORK and the first five elements of
- C IWORK will contain the following statistical data:
- C AVGH The average step size used.
- C HUSED The step size last used (successfully).
- C AVGORD The average order used.
- C IMXERR The index of the element of the solution vector that
- C contributed most to the last error test.
- C NQUSED The order last used (successfully).
- C NSTEP The number of steps taken since last initialization.
- C NFE The number of evaluations of the right hand side.
- C NJE The number of evaluations of the Jacobian matrix.
- C
- C IV. REMARKS .......................................................
- C
- C A. Other routines used:
- C SDNTP, SDZRO, SDSTP, SDNTL, SDPST, SDCOR, SDCST,
- C SDPSC, and SDSCL;
- C SGEFA, SGESL, SGBFA, SGBSL, and SNRM2 (from LINPACK)
- C R1MACH (from the Bell Laboratories Machine Constants Package)
- C XERMSG (from the SLATEC Common Math Library)
- C The last seven routines above, not having been written by the
- C present authors, are not explicitly part of this package.
- C
- C B. On any return from SDRIV3 all information necessary to continue
- C the calculation is contained in the call sequence parameters,
- C including the work arrays. Thus it is possible to suspend one
- C problem, integrate another, and then return to the first.
- C
- C C. If this package is to be used in an overlay situation, the user
- C must declare in the primary overlay the variables in the call
- C sequence to SDRIV3.
- C
- C D. Changing parameters during an integration.
- C The value of NROOT, EPS, EWT, IERROR, MINT, MITER, or HMAX may
- C be altered by the user between calls to SDRIV3. For example, if
- C too much accuracy has been requested (the program returns with
- C NSTATE = 4 and an increased value of EPS) the user may wish to
- C increase EPS further. In general, prudence is necessary when
- C making changes in parameters since such changes are not
- C implemented until the next integration step, which is not
- C necessarily the next call to SDRIV3. This can happen if the
- C program has already integrated to a point which is beyond the
- C new point TOUT.
- C
- C E. As the price for complete control of matrix algebra, the SDRIV3
- C USERS option puts all responsibility for Jacobian matrix
- C evaluation on the user. It is often useful to approximate
- C numerically all or part of the Jacobian matrix. However this
- C must be done carefully. The FORTRAN sequence below illustrates
- C the method we recommend. It can be inserted directly into
- C subroutine USERS to approximate Jacobian elements in rows I1
- C to I2 and columns J1 to J2.
- C REAL DFDY(N,N), EPSJ, H, R, R1MACH,
- C 8 SAVE1(N), SAVE2(N), T, UROUND, Y(N), YJ, YWT(N)
- C UROUND = R1MACH(4)
- C EPSJ = SQRT(UROUND)
- C DO 30 J = J1,J2
- C R = EPSJ*MAX(ABS(YWT(J)), ABS(Y(J)))
- C IF (R .EQ. 0.E0) R = YWT(J)
- C YJ = Y(J)
- C Y(J) = Y(J) + R
- C CALL F (N, T, Y, SAVE1)
- C IF (N .EQ. 0) RETURN
- C Y(J) = YJ
- C DO 20 I = I1,I2
- C 20 DFDY(I,J) = (SAVE1(I) - SAVE2(I))/R
- C 30 CONTINUE
- C Many problems give rise to structured sparse Jacobians, e.g.,
- C block banded. It is possible to approximate them with fewer
- C function evaluations than the above procedure uses; see Curtis,
- C Powell and Reid, J. Inst. Maths Applics, (1974), Vol. 13,
- C pp. 117-119.
- C
- C F. When any of the routines JACOBN, FA, G, or USERS, is not
- C required, difficulties associated with unsatisfied externals can
- C be avoided by using the name of the routine which calculates the
- C right hand side of the differential equations in place of the
- C corresponding name in the call sequence of SDRIV3.
- C
- C***REFERENCES C. W. Gear, Numerical Initial Value Problems in
- C Ordinary Differential Equations, Prentice-Hall, 1971.
- C***ROUTINES CALLED R1MACH, SDNTP, SDSTP, SDZRO, SGBFA, SGBSL, SGEFA,
- C SGESL, SNRM2, XERMSG
- C***REVISION HISTORY (YYMMDD)
- C 790601 DATE WRITTEN
- C 900329 Initial submission to SLATEC.
- C***END PROLOGUE SDRIV3
- EXTERNAL F, JACOBN, FA, G, USERS
- REAL AE, BIG, EPS, EWT(*), G, GLAST, GNOW, H, HMAX,
- 8 HSIGN, HUSED, NROUND, RE, R1MACH, SIZE, SNRM2, SUM, T, TLAST,
- 8 TOUT, TROOT, UROUND, WORK(*), Y(*)
- INTEGER I, IA, IAVGH, IAVGRD, ICNVRG, IDFDY, IEL, IERFLG, IERROR,
- 8 IFAC, IFLAG, IGNOW, IH, IHMAX, IHOLD, IHSIGN, IHUSED,
- 8 IJROOT, IJSTPL, IJTASK, IMNT, IMNTLD, IMPL, IMTR, IMTRLD,
- 8 IMTRSV, IMXERR, IMXORD, IMXRDS, INDMXR, INDPRT, INDPVT,
- 8 INDTRT, INFE, INFO, INJE, INQ, INQUSE, INROOT, INRTLD,
- 8 INSTEP, INWAIT, IRC, IRMAX, IROOT, IMACH1, IMACH4, ISAVE1,
- 8 ISAVE2, IT, ITOUT, ITQ, ITREND, ITROOT, IWORK(*), IYH,
- 8 IYWT, J, JSTATE, JTROOT, LENCHK, LENIW, LENW, LIWCHK,
- 8 MATDIM, MAXORD, MINT, MITER, ML, MU, MXORD, MXSTEP, N,
- 8 NDE, NDECOM, NPAR, NROOT, NSTATE, NSTEPL, NTASK
- LOGICAL CONVRG
- CHARACTER INTGR1*8, INTGR2*8, RL1*16, RL2*16
- PARAMETER(NROUND = 20.E0)
- PARAMETER(IAVGH = 1, IHUSED = 2, IAVGRD = 3,
- 8 IEL = 4, IH = 160, IHMAX = 161, IHOLD = 162,
- 8 IHSIGN = 163, IRC = 164, IRMAX = 165, IT = 166,
- 8 ITOUT = 167, ITQ = 168, ITREND = 204, IMACH1 = 205,
- 8 IMACH4 = 206, IYH = 251,
- 8 INDMXR = 1, INQUSE = 2, INSTEP = 3, INFE = 4, INJE = 5,
- 8 INROOT = 6, ICNVRG = 7, IJROOT = 8, IJTASK = 9,
- 8 IMNTLD = 10, IMTRLD = 11, INQ = 12, INRTLD = 13,
- 8 INDTRT = 14, INWAIT = 15, IMNT = 16, IMTRSV = 17,
- 8 IMTR = 18, IMXRDS = 19, IMXORD = 20, INDPRT = 21,
- 8 IJSTPL = 22, INDPVT = 51)
- C***FIRST EXECUTABLE STATEMENT SDRIV3
- IF (NSTATE .EQ. 12) THEN
- IERFLG = 999
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. The value of NSTATE is 12 .', IERFLG, 2)
- RETURN
- ELSE IF (NSTATE .LT. 1 .OR. NSTATE .GT. 12) THEN
- WRITE(INTGR1, '(I8)') NSTATE
- IERFLG = 26
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. Improper value for NSTATE(= '//INTGR1//').',
- 8 IERFLG, 1)
- NSTATE = 12
- RETURN
- END IF
- NPAR = N
- IF (EPS .LT. 0.E0) THEN
- WRITE(RL1, '(E16.8)') EPS
- IERFLG = 27
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. EPS, '//RL1//', is negative.', IERFLG, 1)
- NSTATE = 12
- RETURN
- END IF
- IF (N .LE. 0) THEN
- WRITE(INTGR1, '(I8)') N
- IERFLG = 22
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. Number of equations, '//INTGR1//
- 8 ', is not positive.', IERFLG, 1)
- NSTATE = 12
- RETURN
- END IF
- IF (MXORD .LE. 0) THEN
- WRITE(INTGR1, '(I8)') MXORD
- IERFLG = 28
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. Maximum order, '//INTGR1//
- 8 ', is not positive.', IERFLG, 1)
- NSTATE = 12
- RETURN
- END IF
- IF (MINT .LT. 1 .OR. MINT .GT. 3) THEN
- WRITE(INTGR1, '(I8)') MINT
- IERFLG = 23
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. Improper value for the integration method '//
- 8 'flag, '//INTGR1//' .', IERFLG, 1)
- NSTATE = 12
- RETURN
- ELSE IF (MITER .LT. 0 .OR. MITER .GT. 5) THEN
- WRITE(INTGR1, '(I8)') MITER
- IERFLG = 24
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. Improper value for MITER(= '//INTGR1//').',
- 8 IERFLG, 1)
- NSTATE = 12
- RETURN
- ELSE IF (IMPL .LT. 0 .OR. IMPL .GT. 3) THEN
- WRITE(INTGR1, '(I8)') IMPL
- IERFLG = 25
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. Improper value for IMPL(= '//INTGR1//').',
- 8 IERFLG, 1)
- NSTATE = 12
- RETURN
- ELSE IF (MINT .EQ. 3 .AND.
- 8 (MITER .EQ. 0 .OR. MITER .EQ. 3 .OR. IMPL .NE. 0)) THEN
- WRITE(INTGR1, '(I8)') MITER
- WRITE(INTGR2, '(I8)') IMPL
- IERFLG = 29
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. For MINT = 3, the value of MITER, '//INTGR1//
- 8 ', and/or IMPL, '//INTGR2//', is not allowed.', IERFLG, 1)
- NSTATE = 12
- RETURN
- ELSE IF ((IMPL .GE. 1 .AND. IMPL .LE. 3) .AND. MITER .EQ. 0) THEN
- WRITE(INTGR1, '(I8)') IMPL
- IERFLG = 30
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. For MITER = 0, the value of IMPL, '//INTGR1//
- 8 ', is not allowed.', IERFLG, 1)
- NSTATE = 12
- RETURN
- ELSE IF ((IMPL .EQ. 2 .OR. IMPL .EQ. 3) .AND. MINT .EQ. 1) THEN
- WRITE(INTGR1, '(I8)') IMPL
- IERFLG = 31
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. For MINT = 1, the value of IMPL, '//INTGR1//
- 8 ', is not allowed.', IERFLG, 1)
- NSTATE = 12
- RETURN
- END IF
- IF (MITER .EQ. 0 .OR. MITER .EQ. 3) THEN
- LIWCHK = INDPVT - 1
- ELSE IF (MITER .EQ. 1 .OR. MITER .EQ. 2 .OR. MITER .EQ. 4 .OR.
- 8 MITER .EQ. 5) THEN
- LIWCHK = INDPVT + N - 1
- END IF
- IF (LENIW .LT. LIWCHK) THEN
- WRITE(INTGR1, '(I8)') LIWCHK
- IERFLG = 33
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. Insufficient storage allocated for the '//
- 8 'IWORK array. Based on the value of the input parameters '//
- 8 'involved, the required storage is '//INTGR1//' .', IERFLG, 1)
- NSTATE = 12
- RETURN
- END IF
- C Allocate the WORK array
- C IYH is the index of YH in WORK
- IF (MINT .EQ. 1 .OR. MINT .EQ. 3) THEN
- MAXORD = MIN(MXORD, 12)
- ELSE IF (MINT .EQ. 2) THEN
- MAXORD = MIN(MXORD, 5)
- END IF
- IDFDY = IYH + (MAXORD + 1)*N
- C IDFDY is the index of DFDY
- C
- IF (MITER .EQ. 0 .OR. MITER .EQ. 3) THEN
- IYWT = IDFDY
- ELSE IF (MITER .EQ. 1 .OR. MITER .EQ. 2) THEN
- IYWT = IDFDY + N*N
- ELSE IF (MITER .EQ. 4 .OR. MITER .EQ. 5) THEN
- IYWT = IDFDY + (2*ML + MU + 1)*N
- END IF
- C IYWT is the index of YWT
- ISAVE1 = IYWT + N
- C ISAVE1 is the index of SAVE1
- ISAVE2 = ISAVE1 + N
- C ISAVE2 is the index of SAVE2
- IGNOW = ISAVE2 + N
- C IGNOW is the index of GNOW
- ITROOT = IGNOW + NROOT
- C ITROOT is the index of TROOT
- IFAC = ITROOT + NROOT
- C IFAC is the index of FAC
- IF (MITER .EQ. 2 .OR. MITER .EQ. 5 .OR. MINT .EQ. 3) THEN
- IA = IFAC + N
- ELSE
- IA = IFAC
- END IF
- C IA is the index of A
- IF (IMPL .EQ. 0 .OR. MITER .EQ. 3) THEN
- LENCHK = IA - 1
- ELSE IF (IMPL .EQ. 1 .AND. (MITER .EQ. 1 .OR. MITER .EQ. 2)) THEN
- LENCHK = IA - 1 + N*N
- ELSE IF (IMPL .EQ. 1 .AND. (MITER .EQ. 4 .OR. MITER .EQ. 5)) THEN
- LENCHK = IA - 1 + (2*ML + MU + 1)*N
- ELSE IF (IMPL .EQ. 2 .AND. MITER .NE. 3) THEN
- LENCHK = IA - 1 + N
- ELSE IF (IMPL .EQ. 3 .AND. (MITER .EQ. 1 .OR. MITER .EQ. 2)) THEN
- LENCHK = IA - 1 + N*NDE
- ELSE IF (IMPL .EQ. 3 .AND. (MITER .EQ. 4 .OR. MITER .EQ. 5)) THEN
- LENCHK = IA - 1 + (2*ML + MU + 1)*NDE
- END IF
- IF (LENW .LT. LENCHK) THEN
- WRITE(INTGR1, '(I8)') LENCHK
- IERFLG = 32
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'Illegal input. Insufficient storage allocated for the '//
- 8 'WORK array. Based on the value of the input parameters '//
- 8 'involved, the required storage is '//INTGR1//' .', IERFLG, 1)
- NSTATE = 12
- RETURN
- END IF
- IF (MITER .EQ. 0 .OR. MITER .EQ. 3) THEN
- MATDIM = 1
- ELSE IF (MITER .EQ. 1 .OR. MITER .EQ. 2) THEN
- MATDIM = N
- ELSE IF (MITER .EQ. 4 .OR. MITER .EQ. 5) THEN
- MATDIM = 2*ML + MU + 1
- END IF
- IF (IMPL .EQ. 0 .OR. IMPL .EQ. 1) THEN
- NDECOM = N
- ELSE IF (IMPL .EQ. 2 .OR. IMPL .EQ. 3) THEN
- NDECOM = NDE
- END IF
- IF (NSTATE .EQ. 1) THEN
- C Initialize parameters
- IF (MINT .EQ. 1 .OR. MINT .EQ. 3) THEN
- IWORK(IMXORD) = MIN(MXORD, 12)
- ELSE IF (MINT .EQ. 2) THEN
- IWORK(IMXORD) = MIN(MXORD, 5)
- END IF
- IWORK(IMXRDS) = MXORD
- IF (MINT .EQ. 1 .OR. MINT .EQ. 2) THEN
- IWORK(IMNT) = MINT
- IWORK(IMTR) = MITER
- IWORK(IMNTLD) = MINT
- IWORK(IMTRLD) = MITER
- ELSE IF (MINT .EQ. 3) THEN
- IWORK(IMNT) = 1
- IWORK(IMTR) = 0
- IWORK(IMNTLD) = IWORK(IMNT)
- IWORK(IMTRLD) = IWORK(IMTR)
- IWORK(IMTRSV) = MITER
- END IF
- WORK(IHMAX) = HMAX
- UROUND = R1MACH (4)
- WORK(IMACH4) = UROUND
- WORK(IMACH1) = R1MACH (1)
- IF (NROOT .NE. 0) THEN
- RE = UROUND
- AE = WORK(IMACH1)
- END IF
- H = (TOUT - T)*(1.E0 - 4.E0*UROUND)
- H = SIGN(MIN(ABS(H), HMAX), H)
- WORK(IH) = H
- HSIGN = SIGN(1.E0, H)
- WORK(IHSIGN) = HSIGN
- IWORK(IJTASK) = 0
- WORK(IAVGH) = 0.E0
- WORK(IHUSED) = 0.E0
- WORK(IAVGRD) = 0.E0
- IWORK(INDMXR) = 0
- IWORK(INQUSE) = 0
- IWORK(INSTEP) = 0
- IWORK(IJSTPL) = 0
- IWORK(INFE) = 0
- IWORK(INJE) = 0
- IWORK(INROOT) = 0
- WORK(IT) = T
- IWORK(ICNVRG) = 0
- IWORK(INDPRT) = 0
- C Set initial conditions
- DO 30 I = 1,N
- 30 WORK(I+IYH-1) = Y(I)
- IF (T .EQ. TOUT) RETURN
- GO TO 180
- ELSE
- UROUND = WORK(IMACH4)
- IF (NROOT .NE. 0) THEN
- RE = UROUND
- AE = WORK(IMACH1)
- END IF
- END IF
- C On a continuation, check
- C that output points have
- C been or will be overtaken.
- IF (IWORK(ICNVRG) .EQ. 1) THEN
- CONVRG = .TRUE.
- ELSE
- CONVRG = .FALSE.
- END IF
- T = WORK(IT)
- H = WORK(IH)
- HSIGN = WORK(IHSIGN)
- IF (IWORK(IJTASK) .EQ. 0) GO TO 180
- C
- C IWORK(IJROOT) flags unreported
- C roots, and is set to the value of
- C NTASK when a root was last selected.
- C It is set to zero when all roots
- C have been reported. IWORK(INROOT)
- C contains the index and WORK(ITOUT)
- C contains the value of the root last
- C selected to be reported.
- C IWORK(INRTLD) contains the value of
- C NROOT and IWORK(INDTRT) contains
- C the value of ITROOT when the array
- C of roots was last calculated.
- IF (NROOT .NE. 0) THEN
- IF (IWORK(IJROOT) .GT. 0) THEN
- C TOUT has just been reported.
- C If TROOT .LE. TOUT, report TROOT.
- IF (NSTATE .NE. 5) THEN
- IF (TOUT*HSIGN .GE. WORK(ITOUT)*HSIGN) THEN
- TROOT = WORK(ITOUT)
- CALL SDNTP (H, 0, N, IWORK(INQ), T, TROOT, WORK(IYH), Y)
- T = TROOT
- NSTATE = 5
- IERFLG = 0
- GO TO 580
- END IF
- C A root has just been reported.
- C Select the next root.
- ELSE
- TROOT = T
- IROOT = 0
- DO 50 I = 1,IWORK(INRTLD)
- JTROOT = I + IWORK(INDTRT) - 1
- IF (WORK(JTROOT)*HSIGN .LE. TROOT*HSIGN) THEN
- C
- C Check for multiple roots.
- C
- IF (WORK(JTROOT) .EQ. WORK(ITOUT) .AND.
- 8 I .GT. IWORK(INROOT)) THEN
- IROOT = I
- TROOT = WORK(JTROOT)
- GO TO 60
- END IF
- IF (WORK(JTROOT)*HSIGN .GT. WORK(ITOUT)*HSIGN) THEN
- IROOT = I
- TROOT = WORK(JTROOT)
- END IF
- END IF
- 50 CONTINUE
- 60 IWORK(INROOT) = IROOT
- WORK(ITOUT) = TROOT
- IWORK(IJROOT) = NTASK
- IF (NTASK .EQ. 1) THEN
- IF (IROOT .EQ. 0) THEN
- IWORK(IJROOT) = 0
- ELSE
- IF (TOUT*HSIGN .GE. TROOT*HSIGN) THEN
- CALL SDNTP (H, 0, N, IWORK(INQ), T, TROOT, WORK(IYH),
- 8 Y)
- NSTATE = 5
- T = TROOT
- IERFLG = 0
- GO TO 580
- END IF
- END IF
- ELSE IF (NTASK .EQ. 2 .OR. NTASK .EQ. 3) THEN
- C
- C If there are no more roots, or the
- C user has altered TOUT to be less
- C than a root, set IJROOT to zero.
- C
- IF (IROOT .EQ. 0 .OR. (TOUT*HSIGN .LT. TROOT*HSIGN)) THEN
- IWORK(IJROOT) = 0
- ELSE
- CALL SDNTP (H, 0, N, IWORK(INQ), T, TROOT, WORK(IYH),
- 8 Y)
- NSTATE = 5
- IERFLG = 0
- T = TROOT
- GO TO 580
- END IF
- END IF
- END IF
- END IF
- END IF
- C
- IF (NTASK .EQ. 1) THEN
- NSTATE = 2
- IF (T*HSIGN .GE. TOUT*HSIGN) THEN
- CALL SDNTP (H, 0, N, IWORK(INQ), T, TOUT, WORK(IYH), Y)
- T = TOUT
- IERFLG = 0
- GO TO 580
- END IF
- ELSE IF (NTASK .EQ. 2) THEN
- C Check if TOUT has
- C been reset .LT. T
- IF (T*HSIGN .GT. TOUT*HSIGN) THEN
- WRITE(RL1, '(E16.8)') T
- WRITE(RL2, '(E16.8)') TOUT
- IERFLG = 11
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'While integrating exactly to TOUT, T, '//RL1//
- 8 ', was beyond TOUT, '//RL2//' . Solution obtained by '//
- 8 'interpolation.', IERFLG, 0)
- NSTATE = 11
- CALL SDNTP (H, 0, N, IWORK(INQ), T, TOUT, WORK(IYH), Y)
- T = TOUT
- GO TO 580
- END IF
- C Determine if TOUT has been overtaken
- C
- IF (ABS(TOUT - T).LE.NROUND*UROUND*MAX(ABS(T), ABS(TOUT))) THEN
- T = TOUT
- NSTATE = 2
- IERFLG = 0
- GO TO 560
- END IF
- C If there are no more roots
- C to report, report T.
- IF (NSTATE .EQ. 5) THEN
- NSTATE = 2
- IERFLG = 0
- GO TO 560
- END IF
- NSTATE = 2
- C See if TOUT will
- C be overtaken.
- IF ((T + H)*HSIGN .GT. TOUT*HSIGN) THEN
- H = TOUT - T
- IF ((T + H)*HSIGN .GT. TOUT*HSIGN) H = H*(1.E0 - 4.E0*UROUND)
- WORK(IH) = H
- IF (H .EQ. 0.E0) GO TO 670
- IWORK(IJTASK) = -1
- END IF
- ELSE IF (NTASK .EQ. 3) THEN
- NSTATE = 2
- IF (T*HSIGN .GT. TOUT*HSIGN) THEN
- WRITE(RL1, '(E16.8)') T
- WRITE(RL2, '(E16.8)') TOUT
- IERFLG = 11
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'While integrating exactly to TOUT, T, '//RL1//
- 8 ', was beyond TOUT, '//RL2//' . Solution obtained by '//
- 8 'interpolation.', IERFLG, 0)
- NSTATE = 11
- CALL SDNTP (H, 0, N, IWORK(INQ), T, TOUT, WORK(IYH), Y)
- T = TOUT
- GO TO 580
- END IF
- IF (ABS(TOUT - T).LE.NROUND*UROUND*MAX(ABS(T), ABS(TOUT))) THEN
- T = TOUT
- IERFLG = 0
- GO TO 560
- END IF
- IF ((T + H)*HSIGN .GT. TOUT*HSIGN) THEN
- H = TOUT - T
- IF ((T + H)*HSIGN .GT. TOUT*HSIGN) H = H*(1.E0 - 4.E0*UROUND)
- WORK(IH) = H
- IF (H .EQ. 0.E0) GO TO 670
- IWORK(IJTASK) = -1
- END IF
- END IF
- C Implement changes in MINT, MITER, and/or HMAX.
- C
- IF ((MINT .NE. IWORK(IMNTLD) .OR. MITER .NE. IWORK(IMTRLD)) .AND.
- 8 MINT .NE. 3 .AND. IWORK(IMNTLD) .NE. 3) IWORK(IJTASK) = -1
- IF (HMAX .NE. WORK(IHMAX)) THEN
- H = SIGN(MIN(ABS(H), HMAX), H)
- IF (H .NE. WORK(IH)) THEN
- IWORK(IJTASK) = -1
- WORK(IH) = H
- END IF
- WORK(IHMAX) = HMAX
- END IF
- C
- 180 NSTEPL = IWORK(INSTEP)
- DO 190 I = 1,N
- 190 Y(I) = WORK(I+IYH-1)
- IF (NROOT .NE. 0) THEN
- DO 200 I = 1,NROOT
- WORK(I+IGNOW-1) = G (NPAR, T, Y, I)
- IF (NPAR .EQ. 0) THEN
- IWORK(INROOT) = I
- NSTATE = 7
- RETURN
- END IF
- 200 CONTINUE
- END IF
- IF (IERROR .EQ. 1) THEN
- DO 230 I = 1,N
- 230 WORK(I+IYWT-1) = 1.E0
- GO TO 410
- ELSE IF (IERROR .EQ. 5) THEN
- DO 250 I = 1,N
- 250 WORK(I+IYWT-1) = EWT(I)
- GO TO 410
- END IF
- C Reset YWT array. Looping point.
- 260 IF (IERROR .EQ. 2) THEN
- DO 280 I = 1,N
- IF (Y(I) .EQ. 0.E0) GO TO 290
- 280 WORK(I+IYWT-1) = ABS(Y(I))
- GO TO 410
- 290 IF (IWORK(IJTASK) .EQ. 0) THEN
- CALL F (NPAR, T, Y, WORK(ISAVE2))
- IF (NPAR .EQ. 0) THEN
- NSTATE = 6
- RETURN
- END IF
- IWORK(INFE) = IWORK(INFE) + 1
- IF (MITER .EQ. 3 .AND. IMPL .NE. 0) THEN
- IFLAG = 0
- CALL USERS (Y, WORK(IYH), WORK(IYWT), WORK(ISAVE1),
- 8 WORK(ISAVE2), T, H, WORK(IEL), IMPL, NPAR,
- 8 NDECOM, IFLAG)
- IF (IFLAG .EQ. -1) GO TO 690
- IF (NPAR .EQ. 0) THEN
- NSTATE = 10
- RETURN
- END IF
- ELSE IF (IMPL .EQ. 1) THEN
- IF (MITER .EQ. 1 .OR. MITER .EQ. 2) THEN
- CALL FA (NPAR, T, Y, WORK(IA), MATDIM, ML, MU, NDECOM)
- IF (NPAR .EQ. 0) THEN
- NSTATE = 9
- RETURN
- END IF
- CALL SGEFA (WORK(IA), MATDIM, N, IWORK(INDPVT), INFO)
- IF (INFO .NE. 0) GO TO 690
- CALL SGESL (WORK(IA), MATDIM, N, IWORK(INDPVT),
- 8 WORK(ISAVE2), 0)
- ELSE IF (MITER .EQ. 4 .OR. MITER .EQ. 5) THEN
- CALL FA (NPAR, T, Y, WORK(IA+ML), MATDIM, ML, MU, NDECOM)
- IF (NPAR .EQ. 0) THEN
- NSTATE = 9
- RETURN
- END IF
- CALL SGBFA (WORK(IA), MATDIM, N, ML, MU, IWORK(INDPVT),
- 8 INFO)
- IF (INFO .NE. 0) GO TO 690
- CALL SGBSL (WORK(IA), MATDIM, N, ML, MU, IWORK(INDPVT),
- 8 WORK(ISAVE2), 0)
- END IF
- ELSE IF (IMPL .EQ. 2) THEN
- CALL FA (NPAR, T, Y, WORK(IA), MATDIM, ML, MU, NDECOM)
- IF (NPAR .EQ. 0) THEN
- NSTATE = 9
- RETURN
- END IF
- DO 340 I = 1,NDECOM
- IF (WORK(I+IA-1) .EQ. 0.E0) GO TO 690
- 340 WORK(I+ISAVE2-1) = WORK(I+ISAVE2-1)/WORK(I+IA-1)
- ELSE IF (IMPL .EQ. 3) THEN
- IF (MITER .EQ. 1 .OR. MITER .EQ. 2) THEN
- CALL FA (NPAR, T, Y, WORK(IA), MATDIM, ML, MU, NDECOM)
- IF (NPAR .EQ. 0) THEN
- NSTATE = 9
- RETURN
- END IF
- CALL SGEFA (WORK(IA), MATDIM, NDE, IWORK(INDPVT), INFO)
- IF (INFO .NE. 0) GO TO 690
- CALL SGESL (WORK(IA), MATDIM, NDE, IWORK(INDPVT),
- 8 WORK(ISAVE2), 0)
- ELSE IF (MITER .EQ. 4 .OR. MITER .EQ. 5) THEN
- CALL FA (NPAR, T, Y, WORK(IA+ML), MATDIM, ML, MU, NDECOM)
- IF (NPAR .EQ. 0) THEN
- NSTATE = 9
- RETURN
- END IF
- CALL SGBFA (WORK(IA), MATDIM, NDE, ML, MU, IWORK(INDPVT),
- 8 INFO)
- IF (INFO .NE. 0) GO TO 690
- CALL SGBSL (WORK(IA), MATDIM, NDE, ML, MU, IWORK(INDPVT),
- 8 WORK(ISAVE2), 0)
- END IF
- END IF
- END IF
- DO 360 J = I,N
- IF (Y(J) .NE. 0.E0) THEN
- WORK(J+IYWT-1) = ABS(Y(J))
- ELSE
- IF (IWORK(IJTASK) .EQ. 0) THEN
- WORK(J+IYWT-1) = ABS(H*WORK(J+ISAVE2-1))
- ELSE
- WORK(J+IYWT-1) = ABS(WORK(J+IYH+N-1))
- END IF
- END IF
- IF (WORK(J+IYWT-1) .EQ. 0.E0) WORK(J+IYWT-1) = UROUND
- 360 CONTINUE
- ELSE IF (IERROR .EQ. 3) THEN
- DO 380 I = 1,N
- 380 WORK(I+IYWT-1) = MAX(EWT(1), ABS(Y(I)))
- ELSE IF (IERROR .EQ. 4) THEN
- DO 400 I = 1,N
- 400 WORK(I+IYWT-1) = MAX(EWT(I), ABS(Y(I)))
- END IF
- C
- 410 DO 420 I = 1,N
- 420 WORK(I+ISAVE2-1) = Y(I)/WORK(I+IYWT-1)
- SUM = SNRM2(N, WORK(ISAVE2), 1)/SQRT(REAL(N))
- SUM = MAX(1.E0, SUM)
- IF (EPS .LT. SUM*UROUND) THEN
- EPS = SUM*UROUND*(1.E0 + 10.E0*UROUND)
- WRITE(RL1, '(E16.8)') T
- WRITE(RL2, '(E16.8)') EPS
- IERFLG = 4
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'At T, '//RL1//', the requested accuracy, EPS, was not '//
- 8 'obtainable with the machine precision. EPS has been '//
- 8 'increased to '//RL2//' .', IERFLG, 0)
- NSTATE = 4
- GO TO 560
- END IF
- IF (ABS(H) .GE. UROUND*ABS(T)) THEN
- IWORK(INDPRT) = 0
- ELSE IF (IWORK(INDPRT) .EQ. 0) THEN
- WRITE(RL1, '(E16.8)') T
- WRITE(RL2, '(E16.8)') H
- IERFLG = 15
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'At T, '//RL1//', the step size, '//RL2//', is smaller '//
- 8 'than the roundoff level of T. This may occur if there is '//
- 8 'an abrupt change in the right hand side of the '//
- 8 'differential equations.', IERFLG, 0)
- IWORK(INDPRT) = 1
- END IF
- IF (NTASK.NE.2) THEN
- IF ((IWORK(INSTEP)-NSTEPL) .EQ. MXSTEP) THEN
- WRITE(RL1, '(E16.8)') T
- WRITE(INTGR1, '(I8)') MXSTEP
- WRITE(RL2, '(E16.8)') TOUT
- IERFLG = 3
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'At T, '//RL1//', '//INTGR1//' steps have been taken '//
- 8 'without reaching TOUT, '//RL2//' .', IERFLG, 0)
- NSTATE = 3
- GO TO 560
- END IF
- END IF
- C
- C CALL SDSTP (EPS, F, FA, HMAX, IMPL, IERROR, JACOBN, MATDIM,
- C 8 MAXORD, MINT, MITER, ML, MU, N, NDE, YWT, UROUND,
- C 8 USERS, AVGH, AVGORD, H, HUSED, JTASK, MNTOLD, MTROLD,
- C 8 NFE, NJE, NQUSED, NSTEP, T, Y, YH, A, CONVRG,
- C 8 DFDY, EL, FAC, HOLD, IPVT, JSTATE, JSTEPL, NQ, NWAIT,
- C 8 RC, RMAX, SAVE1, SAVE2, TQ, TREND, ISWFLG, MTRSV,
- C 8 MXRDSV)
- C
- CALL SDSTP (EPS, F, FA, WORK(IHMAX), IMPL, IERROR, JACOBN,
- 8 MATDIM, IWORK(IMXORD), IWORK(IMNT), IWORK(IMTR), ML,
- 8 MU, NPAR, NDECOM, WORK(IYWT), UROUND, USERS,
- 8 WORK(IAVGH), WORK(IAVGRD), WORK(IH), HUSED,
- 8 IWORK(IJTASK), IWORK(IMNTLD), IWORK(IMTRLD),
- 8 IWORK(INFE), IWORK(INJE), IWORK(INQUSE),
- 8 IWORK(INSTEP), WORK(IT), Y, WORK(IYH), WORK(IA),
- 8 CONVRG, WORK(IDFDY), WORK(IEL), WORK(IFAC),
- 8 WORK(IHOLD), IWORK(INDPVT), JSTATE, IWORK(IJSTPL),
- 8 IWORK(INQ), IWORK(INWAIT), WORK(IRC), WORK(IRMAX),
- 8 WORK(ISAVE1), WORK(ISAVE2), WORK(ITQ), WORK(ITREND),
- 8 MINT, IWORK(IMTRSV), IWORK(IMXRDS))
- T = WORK(IT)
- H = WORK(IH)
- IF (CONVRG) THEN
- IWORK(ICNVRG) = 1
- ELSE
- IWORK(ICNVRG) = 0
- END IF
- GO TO (470, 670, 680, 690, 690, 660, 660, 660, 660, 660), JSTATE
- 470 IWORK(IJTASK) = 1
- C Determine if a root has been overtaken
- IF (NROOT .NE. 0) THEN
- IROOT = 0
- DO 500 I = 1,NROOT
- GLAST = WORK(I+IGNOW-1)
- GNOW = G (NPAR, T, Y, I)
- IF (NPAR .EQ. 0) THEN
- IWORK(INROOT) = I
- NSTATE = 7
- RETURN
- END IF
- WORK(I+IGNOW-1) = GNOW
- IF (GLAST*GNOW .GT. 0.E0) THEN
- WORK(I+ITROOT-1) = T + H
- ELSE
- IF (GNOW .EQ. 0.E0) THEN
- WORK(I+ITROOT-1) = T
- IROOT = I
- ELSE
- IF (GLAST .EQ. 0.E0) THEN
- WORK(I+ITROOT-1) = T + H
- ELSE
- IF (ABS(HUSED) .GE. UROUND*ABS(T)) THEN
- TLAST = T - HUSED
- IROOT = I
- TROOT = T
- CALL SDZRO (AE, G, H, NPAR, IWORK(INQ), IROOT, RE, T,
- 8 WORK(IYH), UROUND, TROOT, TLAST,
- 8 GNOW, GLAST, Y)
- DO 480 J = 1,N
- 480 Y(J) = WORK(IYH+J-1)
- IF (NPAR .EQ. 0) THEN
- IWORK(INROOT) = I
- NSTATE = 7
- RETURN
- END IF
- WORK(I+ITROOT-1) = TROOT
- ELSE
- WORK(I+ITROOT-1) = T
- IROOT = I
- END IF
- END IF
- END IF
- END IF
- 500 CONTINUE
- IF (IROOT .EQ. 0) THEN
- IWORK(IJROOT) = 0
- C Select the first root
- ELSE
- IWORK(IJROOT) = NTASK
- IWORK(INRTLD) = NROOT
- IWORK(INDTRT) = ITROOT
- TROOT = T + H
- DO 510 I = 1,NROOT
- IF (WORK(I+ITROOT-1)*HSIGN .LT. TROOT*HSIGN) THEN
- TROOT = WORK(I+ITROOT-1)
- IROOT = I
- END IF
- 510 CONTINUE
- IWORK(INROOT) = IROOT
- WORK(ITOUT) = TROOT
- IF (TROOT*HSIGN .LE. TOUT*HSIGN) THEN
- CALL SDNTP (H, 0, N, IWORK(INQ), T, TROOT, WORK(IYH), Y)
- NSTATE = 5
- T = TROOT
- IERFLG = 0
- GO TO 580
- END IF
- END IF
- END IF
- C Test for NTASK condition to be satisfied
- NSTATE = 2
- IF (NTASK .EQ. 1) THEN
- IF (T*HSIGN .LT. TOUT*HSIGN) GO TO 260
- CALL SDNTP (H, 0, N, IWORK(INQ), T, TOUT, WORK(IYH), Y)
- T = TOUT
- IERFLG = 0
- GO TO 580
- C TOUT is assumed to have been attained
- C exactly if T is within twenty roundoff
- C units of TOUT, relative to MAX(TOUT, T).
- C
- ELSE IF (NTASK .EQ. 2) THEN
- IF (ABS(TOUT - T).LE.NROUND*UROUND*MAX(ABS(T), ABS(TOUT))) THEN
- T = TOUT
- ELSE
- IF ((T + H)*HSIGN .GT. TOUT*HSIGN) THEN
- H = TOUT - T
- IF ((T + H)*HSIGN.GT.TOUT*HSIGN) H = H*(1.E0 - 4.E0*UROUND)
- WORK(IH) = H
- IF (H .EQ. 0.E0) GO TO 670
- IWORK(IJTASK) = -1
- END IF
- END IF
- ELSE IF (NTASK .EQ. 3) THEN
- IF (ABS(TOUT - T).LE.NROUND*UROUND*MAX(ABS(T), ABS(TOUT))) THEN
- T = TOUT
- ELSE
- IF ((T + H)*HSIGN .GT. TOUT*HSIGN) THEN
- H = TOUT - T
- IF ((T + H)*HSIGN.GT.TOUT*HSIGN) H = H*(1.E0 - 4.E0*UROUND)
- WORK(IH) = H
- IF (H .EQ. 0.E0) GO TO 670
- IWORK(IJTASK) = -1
- END IF
- GO TO 260
- END IF
- END IF
- IERFLG = 0
- C All returns are made through this
- C section. IMXERR is determined.
- 560 DO 570 I = 1,N
- 570 Y(I) = WORK(I+IYH-1)
- 580 IF (IWORK(IJTASK) .EQ. 0) RETURN
- BIG = 0.E0
- IMXERR = 1
- DO 590 I = 1,N
- C SIZE = ABS(ERROR(I)/YWT(I))
- SIZE = ABS(WORK(I+ISAVE1-1)/WORK(I+IYWT-1))
- IF (BIG .LT. SIZE) THEN
- BIG = SIZE
- IMXERR = I
- END IF
- 590 CONTINUE
- IWORK(INDMXR) = IMXERR
- WORK(IHUSED) = HUSED
- RETURN
- C
- 660 NSTATE = JSTATE
- RETURN
- C Fatal errors are processed here
- C
- 670 WRITE(RL1, '(E16.8)') T
- IERFLG = 41
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'At T, '//RL1//', the attempted step size has gone to '//
- 8 'zero. Often this occurs if the problem setup is incorrect.',
- 8 IERFLG, 1)
- NSTATE = 12
- RETURN
- C
- 680 WRITE(RL1, '(E16.8)') T
- IERFLG = 42
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'At T, '//RL1//', the step size has been reduced about 50 '//
- 8 'times without advancing the solution. Often this occurs '//
- 8 'if the problem setup is incorrect.', IERFLG, 1)
- NSTATE = 12
- RETURN
- C
- 690 WRITE(RL1, '(E16.8)') T
- IERFLG = 43
- CALL XERMSG('SLATEC', 'SDRIV3',
- 8 'At T, '//RL1//', while solving A*YDOT = F, A is singular.',
- 8 IERFLG, 1)
- NSTATE = 12
- RETURN
- END
|