GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
ddasrt.f
Go to the documentation of this file.
1 SUBROUTINE ddasrt (RES,NEQ,T,Y,YPRIME,TOUT,
2 * INFO,RTOL,ATOL,IDID,RWORK,LRW,IWORK,LIW,RPAR,IPAR,JAC,
3 * G,NG,JROOT)
4C
5C***BEGIN PROLOGUE DDASRT
6C***DATE WRITTEN 821001 (YYMMDD)
7C***REVISION DATE 910624 (YYMMDD)
8C***KEYWORDS DIFFERENTIAL/ALGEBRAIC,BACKWARD DIFFERENTIATION FORMULAS
9C IMPLICIT DIFFERENTIAL SYSTEMS
10C***AUTHOR PETZOLD,LINDA R.,COMPUTING AND MATHEMATICS RESEARCH DIVISION
11C LAWRENCE LIVERMORE NATIONAL LABORATORY
12C L - 316, P.O. Box 808,
13C LIVERMORE, CA. 94550
14C***PURPOSE This code solves a system of differential/algebraic
15C equations of the form F(T,Y,YPRIME) = 0.
16C***DESCRIPTION
17C
18C *Usage:
19C
20C IMPLICIT DOUBLE PRECISION (A-H,O-Z)
21C EXTERNAL RES, JAC, G
22C INTEGER NEQ, INFO(N), IDID, LRW, LIW, IWORK(LIW), IPAR, NG,
23C * JROOT(NG)
24C DOUBLE PRECISION T, Y(NEQ), YPRIME(NEQ), TOUT, RTOL, ATOL,
25C * RWORK(LRW), RPAR
26C
27C CALL DDASRT (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
28C * IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC)
29C
30C
31C
32C *Arguments:
33C
34C RES:EXT This is a subroutine which you provide to define the
35C differential/algebraic system.
36C
37C NEQ:IN This is the number of equations to be solved.
38C
39C T:INOUT This is the current value of the independent variable.
40C
41C Y(*):INOUT This array contains the solution components at T.
42C
43C YPRIME(*):INOUT This array contains the derivatives of the solution
44C components at T.
45C
46C TOUT:IN This is a point at which a solution is desired.
47C
48C INFO(N):IN The basic task of the code is to solve the system from T
49C to TOUT and return an answer at TOUT. INFO is an integer
50C array which is used to communicate exactly how you want
51C this task to be carried out. N must be greater than or
52C equal to 15.
53C
54C RTOL,ATOL:INOUT These quantities represent absolute and relative
55C error tolerances which you provide to indicate how
56C accurately you wish the solution to be computed.
57C You may choose them to be both scalars or else
58C both vectors.
59C
60C IDID:OUT This scalar quantity is an indicator reporting what the
61C code did. You must monitor this integer variable to decide
62C what action to take next.
63C
64C RWORK:WORK A real work array of length LRW which provides the
65C code with needed storage space.
66C
67C LRW:IN The length of RWORK.
68C
69C IWORK:WORK An integer work array of length LIW which probides the
70C code with needed storage space.
71C
72C LIW:IN The length of IWORK.
73C
74C RPAR,IPAR:IN These are real and integer parameter arrays which
75C you can use for communication between your calling
76C program and the RES subroutine (and the JAC subroutine)
77C
78C JAC:EXT This is the name of a subroutine which you may choose to
79C provide for defining a matrix of partial derivatives
80C described below.
81C
82C G This is the name of the subroutine for defining
83C constraint functions, G(T,Y), whose roots are desired
84C during the integration. This name must be declared
85C external in the calling program.
86C
87C NG This is the number of constraint functions G(I).
88C If there are none, set NG=0, and pass a dummy name
89C for G.
90C
91C JROOT This is an integer array of length NG for output
92C of root information.
93C
94C
95C *Description
96C
97C QUANTITIES WHICH MAY BE ALTERED BY THE CODE ARE
98C T,Y(*),YPRIME(*),INFO(1),RTOL,ATOL,
99C IDID,RWORK(*) AND IWORK(*).
100C
101C Subroutine DDASRT uses the backward differentiation formulas of
102C orders one through five to solve a system of the above form for Y and
103C YPRIME. Values for Y and YPRIME at the initial time must be given as
104C input. These values must be consistent, (that is, if T,Y,YPRIME are
105C the given initial values, they must satisfy F(T,Y,YPRIME) = 0.). The
106C subroutine solves the system from T to TOUT.
107C It is easy to continue the solution to get results at additional
108C TOUT. This is the interval mode of operation. Intermediate results
109C can also be obtained easily by using the intermediate-output
110C capability. If DDASRT detects a sign-change in G(T,Y), then
111C it will return the intermediate value of T and Y for which
112C G(T,Y) = 0.
113C
114C ---------INPUT-WHAT TO DO ON THE FIRST CALL TO DDASRT---------------
115C
116C
117C The first call of the code is defined to be the start of each new
118C problem. Read through the descriptions of all the following items,
119C provide sufficient storage space for designated arrays, set
120C appropriate variables for the initialization of the problem, and
121C give information about how you want the problem to be solved.
122C
123C
124C RES -- Provide a subroutine of the form
125C SUBROUTINE RES(T,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
126C to define the system of differential/algebraic
127C equations which is to be solved. For the given values
128C of T,Y and YPRIME, the subroutine should
129C return the residual of the defferential/algebraic
130C system
131C DELTA = F(T,Y,YPRIME)
132C (DELTA(*) is a vector of length NEQ which is
133C output for RES.)
134C
135C Subroutine RES must not alter T,Y or YPRIME.
136C You must declare the name RES in an external
137C statement in your program that calls DDASRT.
138C You must dimension Y,YPRIME and DELTA in RES.
139C
140C IRES is an integer flag which is always equal to
141C zero on input. Subroutine RES should alter IRES
142C only if it encounters an illegal value of Y or
143C a stop condition. Set IRES = -1 if an input value
144C is illegal, and DDASRT will try to solve the problem
145C without getting IRES = -1. If IRES = -2, DDASRT
146C will return control to the calling program
147C with IDID = -11.
148C
149C RPAR and IPAR are real and integer parameter arrays which
150C you can use for communication between your calling program
151C and subroutine RES. They are not altered by DDASRT. If you
152C do not need RPAR or IPAR, ignore these parameters by treat-
153C ing them as dummy arguments. If you do choose to use them,
154C dimension them in your calling program and in RES as arrays
155C of appropriate length.
156C
157C NEQ -- Set it to the number of differential equations.
158C (NEQ .GE. 1)
159C
160C T -- Set it to the initial point of the integration.
161C T must be defined as a variable.
162C
163C Y(*) -- Set this vector to the initial values of the NEQ solution
164C components at the initial point. You must dimension Y of
165C length at least NEQ in your calling program.
166C
167C YPRIME(*) -- Set this vector to the initial values of
168C the NEQ first derivatives of the solution
169C components at the initial point. You
170C must dimension YPRIME at least NEQ
171C in your calling program. If you do not
172C know initial values of some of the solution
173C components, see the explanation of INFO(11).
174C
175C TOUT - Set it to the first point at which a solution
176C is desired. You can not take TOUT = T.
177C integration either forward in T (TOUT .GT. T) or
178C backward in T (TOUT .LT. T) is permitted.
179C
180C The code advances the solution from T to TOUT using
181C step sizes which are automatically selected so as to
182C achieve the desired accuracy. If you wish, the code will
183C return with the solution and its derivative at
184C intermediate steps (intermediate-output mode) so that
185C you can monitor them, but you still must provide TOUT in
186C accord with the basic aim of the code.
187C
188C the first step taken by the code is a critical one
189C because it must reflect how fast the solution changes near
190C the initial point. The code automatically selects an
191C initial step size which is practically always suitable for
192C the problem. By using the fact that the code will not step
193C past TOUT in the first step, you could, if necessary,
194C restrict the length of the initial step size.
195C
196C For some problems it may not be permissable to integrate
197C past a point TSTOP because a discontinuity occurs there
198C or the solution or its derivative is not defined beyond
199C TSTOP. When you have declared a TSTOP point (SEE INFO(4)
200C and RWORK(1)), you have told the code not to integrate
201C past TSTOP. In this case any TOUT beyond TSTOP is invalid
202C input.
203C
204C INFO(*) - Use the INFO array to give the code more details about
205C how you want your problem solved. This array should be
206C dimensioned of length 15, though DDASRT uses
207C only the first twelve entries. You must respond to all of
208C the following items which are arranged as questions. The
209C simplest use of the code corresponds to answering all
210C questions as yes, i.e. setting all entries of INFO to 0.
211C
212C INFO(1) - This parameter enables the code to initialize
213C itself. You must set it to indicate the start of every
214C new problem.
215C
216C **** Is this the first call for this problem ...
217C Yes - Set INFO(1) = 0
218C No - Not applicable here.
219C See below for continuation calls. ****
220C
221C INFO(2) - How much accuracy you want of your solution
222C is specified by the error tolerances RTOL and ATOL.
223C The simplest use is to take them both to be scalars.
224C To obtain more flexibility, they can both be vectors.
225C The code must be told your choice.
226C
227C **** Are both error tolerances RTOL, ATOL scalars ...
228C Yes - Set INFO(2) = 0
229C and input scalars for both RTOL and ATOL
230C No - Set INFO(2) = 1
231C and input arrays for both RTOL and ATOL ****
232C
233C INFO(3) - The code integrates from T in the direction
234C of TOUT by steps. If you wish, it will return the
235C computed solution and derivative at the next
236C intermediate step (the intermediate-output mode) or
237C TOUT, whichever comes first. This is a good way to
238C proceed if you want to see the behavior of the solution.
239C If you must have solutions at a great many specific
240C TOUT points, this code will compute them efficiently.
241C
242C **** Do you want the solution only at
243C TOUT (and not at the next intermediate step) ...
244C Yes - Set INFO(3) = 0
245C No - Set INFO(3) = 1 ****
246C
247C INFO(4) - To handle solutions at a great many specific
248C values TOUT efficiently, this code may integrate past
249C TOUT and interpolate to obtain the result at TOUT.
250C Sometimes it is not possible to integrate beyond some
251C point TSTOP because the equation changes there or it is
252C not defined past TSTOP. Then you must tell the code
253C not to go past.
254C
255C **** Can the integration be carried out without any
256C restrictions on the independent variable T ...
257C Yes - Set INFO(4)=0
258C No - Set INFO(4)=1
259C and define the stopping point TSTOP by
260C setting RWORK(1)=TSTOP ****
261C
262C INFO(5) - To solve differential/algebraic problems it is
263C necessary to use a matrix of partial derivatives of the
264C system of differential equations. If you do not
265C provide a subroutine to evaluate it analytically (see
266C description of the item JAC in the call list), it will
267C be approximated by numerical differencing in this code.
268C although it is less trouble for you to have the code
269C compute partial derivatives by numerical differencing,
270C the solution will be more reliable if you provide the
271C derivatives via JAC. Sometimes numerical differencing
272C is cheaper than evaluating derivatives in JAC and
273C sometimes it is not - this depends on your problem.
274C
275C **** Do you want the code to evaluate the partial
276C derivatives automatically by numerical differences ...
277C Yes - Set INFO(5)=0
278C No - Set INFO(5)=1
279C and provide subroutine JAC for evaluating the
280C matrix of partial derivatives ****
281C
282C INFO(6) - DDASRT will perform much better if the matrix of
283C partial derivatives, DG/DY + CJ*DG/DYPRIME,
284C (here CJ is a scalar determined by DDASRT)
285C is banded and the code is told this. In this
286C case, the storage needed will be greatly reduced,
287C numerical differencing will be performed much cheaper,
288C and a number of important algorithms will execute much
289C faster. The differential equation is said to have
290C half-bandwidths ML (lower) and MU (upper) if equation i
291C involves only unknowns Y(J) with
292C I-ML .LE. J .LE. I+MU
293C for all I=1,2,...,NEQ. Thus, ML and MU are the widths
294C of the lower and upper parts of the band, respectively,
295C with the main diagonal being excluded. If you do not
296C indicate that the equation has a banded matrix of partial
297C derivatives, the code works with a full matrix of NEQ**2
298C elements (stored in the conventional way). Computations
299C with banded matrices cost less time and storage than with
300C full matrices if 2*ML+MU .LT. NEQ. If you tell the
301C code that the matrix of partial derivatives has a banded
302C structure and you want to provide subroutine JAC to
303C compute the partial derivatives, then you must be careful
304C to store the elements of the matrix in the special form
305C indicated in the description of JAC.
306C
307C **** Do you want to solve the problem using a full
308C (dense) matrix (and not a special banded
309C structure) ...
310C Yes - Set INFO(6)=0
311C No - Set INFO(6)=1
312C and provide the lower (ML) and upper (MU)
313C bandwidths by setting
314C IWORK(1)=ML
315C IWORK(2)=MU ****
316C
317C
318C INFO(7) -- You can specify a maximum (absolute value of)
319C stepsize, so that the code
320C will avoid passing over very
321C large regions.
322C
323C **** Do you want the code to decide
324C on its own maximum stepsize?
325C Yes - Set INFO(7)=0
326C No - Set INFO(7)=1
327C and define HMAX by setting
328C RWORK(2)=HMAX ****
329C
330C INFO(8) -- Differential/algebraic problems
331C may occaisionally suffer from
332C severe scaling difficulties on the
333C first step. If you know a great deal
334C about the scaling of your problem, you can
335C help to alleviate this problem by
336C specifying an initial stepsize H0.
337C
338C **** Do you want the code to define
339C its own initial stepsize?
340C Yes - Set INFO(8)=0
341C No - Set INFO(8)=1
342C and define H0 by setting
343C RWORK(3)=H0 ****
344C
345C INFO(9) -- If storage is a severe problem,
346C you can save some locations by
347C restricting the maximum order MAXORD.
348C the default value is 5. for each
349C order decrease below 5, the code
350C requires NEQ fewer locations, however
351C it is likely to be slower. In any
352C case, you must have 1 .LE. MAXORD .LE. 5
353C **** Do you want the maximum order to
354C default to 5?
355C Yes - Set INFO(9)=0
356C No - Set INFO(9)=1
357C and define MAXORD by setting
358C IWORK(3)=MAXORD ****
359C
360C INFO(10) --If you know that the solutions to your equations
361C will always be nonnegative, it may help to set this
362C parameter. However, it is probably best to
363C try the code without using this option first,
364C and only to use this option if that doesn't
365C work very well.
366C **** Do you want the code to solve the problem without
367C invoking any special nonnegativity constraints?
368C Yes - Set INFO(10)=0
369C No - Set INFO(10)=1
370C
371C INFO(11) --DDASRT normally requires the initial T,
372C Y, and YPRIME to be consistent. That is,
373C you must have F(T,Y,YPRIME) = 0 at the initial
374C time. If you do not know the initial
375C derivative precisely, you can let DDASRT try
376C to compute it.
377C **** Are the initial T, Y, YPRIME consistent?
378C Yes - Set INFO(11) = 0
379C No - Set INFO(11) = 1,
380C and set YPRIME to an initial approximation
381C to YPRIME. (If you have no idea what
382C YPRIME should be, set it to zero. Note
383C that the initial Y should be such
384C that there must exist a YPRIME so that
385C F(T,Y,YPRIME) = 0.)
386C
387C INFO(12) --Maximum number of steps.
388C **** Do you want to let DDASRT use the default limit for
389C the number of steps?
390C Yes - Set INFO(12) = 0
391C No - Set INFO(12) = 1,
392C and define the maximum number of steps
393C by setting IWORK(21)=MXSTEP
394C
395C RTOL, ATOL -- You must assign relative (RTOL) and absolute (ATOL
396C error tolerances to tell the code how accurately you
397C want the solution to be computed. They must be defined
398C as variables because the code may change them. You
399C have two choices --
400C Both RTOL and ATOL are scalars. (INFO(2)=0)
401C Both RTOL and ATOL are vectors. (INFO(2)=1)
402C in either case all components must be non-negative.
403C
404C The tolerances are used by the code in a local error
405C test at each step which requires roughly that
406C ABS(LOCAL ERROR) .LE. RTOL*ABS(Y)+ATOL
407C for each vector component.
408C (More specifically, a root-mean-square norm is used to
409C measure the size of vectors, and the error test uses the
410C magnitude of the solution at the beginning of the step.)
411C
412C The true (global) error is the difference between the
413C true solution of the initial value problem and the
414C computed approximation. Practically all present day
415C codes, including this one, control the local error at
416C each step and do not even attempt to control the global
417C error directly.
418C Usually, but not always, the true accuracy of the
419C computed Y is comparable to the error tolerances. This
420C code will usually, but not always, deliver a more
421C accurate solution if you reduce the tolerances and
422C integrate again. By comparing two such solutions you
423C can get a fairly reliable idea of the true error in the
424C solution at the bigger tolerances.
425C
426C Setting ATOL=0. results in a pure relative error test on
427C that component. Setting RTOL=0. results in a pure
428C absolute error test on that component. A mixed test
429C with non-zero RTOL and ATOL corresponds roughly to a
430C relative error test when the solution component is much
431C bigger than ATOL and to an absolute error test when the
432C solution component is smaller than the threshhold ATOL.
433C
434C The code will not attempt to compute a solution at an
435C accuracy unreasonable for the machine being used. It
436C will advise you if you ask for too much accuracy and
437C inform you as to the maximum accuracy it believes
438C possible.
439C
440C RWORK(*) -- Dimension this real work array of length LRW in your
441C calling program.
442C
443C LRW -- Set it to the declared length of the RWORK array.
444C You must have
445C LRW .GE. 50+(MAXORD+4)*NEQ+NEQ**2+3*NG
446C for the full (dense) JACOBIAN case (when INFO(6)=0), or
447C LRW .GE. 50+(MAXORD+4)*NEQ+(2*ML+MU+1)*NEQ+3*NG
448C for the banded user-defined JACOBIAN case
449C (when INFO(5)=1 and INFO(6)=1), or
450C LRW .GE. 50+(MAXORD+4)*NEQ+(2*ML+MU+1)*NEQ
451C +2*(NEQ/(ML+MU+1)+1)+3*NG
452C for the banded finite-difference-generated JACOBIAN case
453C (when INFO(5)=0 and INFO(6)=1)
454C
455C IWORK(*) -- Dimension this integer work array of length LIW in
456C your calling program.
457C
458C LIW -- Set it to the declared length of the IWORK array.
459C you must have LIW .GE. 21+NEQ
460C
461C RPAR, IPAR -- These are parameter arrays, of real and integer
462C type, respectively. You can use them for communication
463C between your program that calls DDASRT and the
464C RES subroutine (and the JAC subroutine). They are not
465C altered by DDASRT. If you do not need RPAR or IPAR,
466C ignore these parameters by treating them as dummy
467C arguments. If you do choose to use them, dimension
468C them in your calling program and in RES (and in JAC)
469C as arrays of appropriate length.
470C
471C JAC -- If you have set INFO(5)=0, you can ignore this parameter
472C by treating it as a dummy argument. Otherwise, you must
473C provide a subroutine of the form
474C JAC(T,Y,YPRIME,PD,CJ,RPAR,IPAR)
475C to define the matrix of partial derivatives
476C PD=DG/DY+CJ*DG/DYPRIME
477C CJ is a scalar which is input to JAC.
478C For the given values of T,Y,YPRIME, the
479C subroutine must evaluate the non-zero partial
480C derivatives for each equation and each solution
481C component, and store these values in the
482C matrix PD. The elements of PD are set to zero
483C before each call to JAC so only non-zero elements
484C need to be defined.
485C
486C Subroutine JAC must not alter T,Y,(*),YPRIME(*), or CJ.
487C You must declare the name JAC in an
488C EXTERNAL STATEMENT in your program that calls
489C DDASRT. You must dimension Y, YPRIME and PD
490C in JAC.
491C
492C The way you must store the elements into the PD matrix
493C depends on the structure of the matrix which you
494C indicated by INFO(6).
495C *** INFO(6)=0 -- Full (dense) matrix ***
496C Give PD a first dimension of NEQ.
497C When you evaluate the (non-zero) partial derivative
498C of equation I with respect to variable J, you must
499C store it in PD according to
500C PD(I,J) = * DF(I)/DY(J)+CJ*DF(I)/DYPRIME(J)*
501C *** INFO(6)=1 -- Banded JACOBIAN with ML lower and MU
502C upper diagonal bands (refer to INFO(6) description
503C of ML and MU) ***
504C Give PD a first dimension of 2*ML+MU+1.
505C when you evaluate the (non-zero) partial derivative
506C of equation I with respect to variable J, you must
507C store it in PD according to
508C IROW = I - J + ML + MU + 1
509C PD(IROW,J) = *DF(I)/DY(J)+CJ*DF(I)/DYPRIME(J)*
510C RPAR and IPAR are real and integer parameter arrays
511C which you can use for communication between your calling
512C program and your JACOBIAN subroutine JAC. They are not
513C altered by DDASRT. If you do not need RPAR or IPAR,
514C ignore these parameters by treating them as dummy
515C arguments. If you do choose to use them, dimension
516C them in your calling program and in JAC as arrays of
517C appropriate length.
518C
519C G -- This is the name of the subroutine for defining constraint
520C functions, whose roots are desired during the
521C integration. It is to have the form
522C SUBROUTINE G(NEQ,T,Y,NG,GOUT,RPAR,IPAR)
523C DIMENSION Y(NEQ),GOUT(NG),
524C where NEQ, T, Y and NG are INPUT, and the array GOUT is
525C output. NEQ, T, and Y have the same meaning as in the
526C RES routine, and GOUT is an array of length NG.
527C For I=1,...,NG, this routine is to load into GOUT(I)
528C the value at (T,Y) of the I-th constraint function G(I).
529C DDASRT will find roots of the G(I) of odd multiplicity
530C (that is, sign changes) as they occur during
531C the integration. G must be declared EXTERNAL in the
532C calling program.
533C
534C CAUTION..because of numerical errors in the functions
535C G(I) due to roundoff and integration error, DDASRT
536C may return false roots, or return the same root at two
537C or more nearly equal values of T. If such false roots
538C are suspected, the user should consider smaller error
539C tolerances and/or higher precision in the evaluation of
540C the G(I).
541C
542C If a root of some G(I) defines the end of the problem,
543C the input to DDASRT should nevertheless allow
544C integration to a point slightly past that ROOT, so
545C that DDASRT can locate the root by interpolation.
546C
547C NG -- The number of constraint functions G(I). If there are none,
548C set NG = 0, and pass a dummy name for G.
549C
550C JROOT -- This is an integer array of length NG. It is used only for
551C output. On a return where one or more roots have been
552C found, JROOT(I)=1 If G(I) has a root at T,
553C or JROOT(I)=0 if not.
554C
555C
556C
557C OPTIONALLY REPLACEABLE NORM ROUTINE:
558C DDASRT uses a weighted norm DDANRM to measure the size
559C of vectors such as the estimated error in each step.
560C A FUNCTION subprogram
561C DOUBLE PRECISION FUNCTION DDANRM(NEQ,V,WT,RPAR,IPAR)
562C DIMENSION V(NEQ),WT(NEQ)
563C is used to define this norm. Here, V is the vector
564C whose norm is to be computed, and WT is a vector of
565C weights. A DDANRM routine has been included with DDASRT
566C which computes the weighted root-mean-square norm
567C given by
568C DDANRM=SQRT((1/NEQ)*SUM(V(I)/WT(I))**2)
569C this norm is suitable for most problems. In some
570C special cases, it may be more convenient and/or
571C efficient to define your own norm by writing a function
572C subprogram to be called instead of DDANRM. This should
573C ,however, be attempted only after careful thought and
574C consideration.
575C
576C
577C------OUTPUT-AFTER ANY RETURN FROM DDASRT----
578C
579C The principal aim of the code is to return a computed solution at
580C TOUT, although it is also possible to obtain intermediate results
581C along the way. To find out whether the code achieved its goal
582C or if the integration process was interrupted before the task was
583C completed, you must check the IDID parameter.
584C
585C
586C T -- The solution was successfully advanced to the
587C output value of T.
588C
589C Y(*) -- Contains the computed solution approximation at T.
590C
591C YPRIME(*) -- Contains the computed derivative
592C approximation at T.
593C
594C IDID -- Reports what the code did.
595C
596C *** Task completed ***
597C Reported by positive values of IDID
598C
599C IDID = 1 -- A step was successfully taken in the
600C intermediate-output mode. The code has not
601C yet reached TOUT.
602C
603C IDID = 2 -- The integration to TSTOP was successfully
604C completed (T=TSTOP) by stepping exactly to TSTOP.
605C
606C IDID = 3 -- The integration to TOUT was successfully
607C completed (T=TOUT) by stepping past TOUT.
608C Y(*) is obtained by interpolation.
609C YPRIME(*) is obtained by interpolation.
610C
611C IDID = 4 -- The integration was successfully completed
612C by finding one or more roots of G at T.
613C
614C *** Task interrupted ***
615C Reported by negative values of IDID
616C
617C IDID = -1 -- A large amount of work has been expended.
618C (About INFO(12) steps)
619C
620C IDID = -2 -- The error tolerances are too stringent.
621C
622C IDID = -3 -- The local error test cannot be satisfied
623C because you specified a zero component in ATOL
624C and the corresponding computed solution
625C component is zero. Thus, a pure relative error
626C test is impossible for this component.
627C
628C IDID = -6 -- DDASRT had repeated error test
629C failures on the last attempted step.
630C
631C IDID = -7 -- The corrector could not converge.
632C
633C IDID = -8 -- The matrix of partial derivatives
634C is singular.
635C
636C IDID = -9 -- The corrector could not converge.
637C there were repeated error test failures
638C in this step.
639C
640C IDID =-10 -- The corrector could not converge
641C because IRES was equal to minus one.
642C
643C IDID =-11 -- IRES equal to -2 was encountered
644C and control is being returned to the
645C calling program.
646C
647C IDID =-12 -- DDASRT failed to compute the initial
648C YPRIME.
649C
650C
651C
652C IDID = -13,..,-32 -- Not applicable for this code
653C
654C *** Task terminated ***
655C Reported by the value of IDID=-33
656C
657C IDID = -33 -- The code has encountered trouble from which
658C it cannot recover. A message is printed
659C explaining the trouble and control is returned
660C to the calling program. For example, this occurs
661C when invalid input is detected.
662C
663C RTOL, ATOL -- These quantities remain unchanged except when
664C IDID = -2. In this case, the error tolerances have been
665C increased by the code to values which are estimated to
666C be appropriate for continuing the integration. However,
667C the reported solution at T was obtained using the input
668C values of RTOL and ATOL.
669C
670C RWORK, IWORK -- Contain information which is usually of no
671C interest to the user but necessary for subsequent calls.
672C However, you may find use for
673C
674C RWORK(3)--Which contains the step size H to be
675C attempted on the next step.
676C
677C RWORK(4)--Which contains the current value of the
678C independent variable, i.e., the farthest point
679C integration has reached. This will be different
680C from T only when interpolation has been
681C performed (IDID=3).
682C
683C RWORK(7)--Which contains the stepsize used
684C on the last successful step.
685C
686C IWORK(7)--Which contains the order of the method to
687C be attempted on the next step.
688C
689C IWORK(8)--Which contains the order of the method used
690C on the last step.
691C
692C IWORK(11)--Which contains the number of steps taken so
693C far.
694C
695C IWORK(12)--Which contains the number of calls to RES
696C so far.
697C
698C IWORK(13)--Which contains the number of evaluations of
699C the matrix of partial derivatives needed so
700C far.
701C
702C IWORK(14)--Which contains the total number
703C of error test failures so far.
704C
705C IWORK(15)--Which contains the total number
706C of convergence test failures so far.
707C (includes singular iteration matrix
708C failures.)
709C
710C IWORK(16)--Which contains the total number of calls
711C to the constraint function g so far
712C
713C
714C
715C INPUT -- What to do to continue the integration
716C (calls after the first) **
717C
718C This code is organized so that subsequent calls to continue the
719C integration involve little (if any) additional effort on your
720C part. You must monitor the IDID parameter in order to determine
721C what to do next.
722C
723C Recalling that the principal task of the code is to integrate
724C from T to TOUT (the interval mode), usually all you will need
725C to do is specify a new TOUT upon reaching the current TOUT.
726C
727C Do not alter any quantity not specifically permitted below,
728C in particular do not alter NEQ,T,Y(*),YPRIME(*),RWORK(*),IWORK(*)
729C or the differential equation in subroutine RES. Any such
730C alteration constitutes a new problem and must be treated as such,
731C i.e., you must start afresh.
732C
733C You cannot change from vector to scalar error control or vice
734C versa (INFO(2)), but you can change the size of the entries of
735C RTOL, ATOL. Increasing a tolerance makes the equation easier
736C to integrate. Decreasing a tolerance will make the equation
737C harder to integrate and should generally be avoided.
738C
739C You can switch from the intermediate-output mode to the
740C interval mode (INFO(3)) or vice versa at any time.
741C
742C If it has been necessary to prevent the integration from going
743C past a point TSTOP (INFO(4), RWORK(1)), keep in mind that the
744C code will not integrate to any TOUT beyond the currently
745C specified TSTOP. Once TSTOP has been reached you must change
746C the value of TSTOP or set INFO(4)=0. You may change INFO(4)
747C or TSTOP at any time but you must supply the value of TSTOP in
748C RWORK(1) whenever you set INFO(4)=1.
749C
750C Do not change INFO(5), INFO(6), IWORK(1), or IWORK(2)
751C unless you are going to restart the code.
752C
753C *** Following a completed task ***
754C If
755C IDID = 1, call the code again to continue the integration
756C another step in the direction of TOUT.
757C
758C IDID = 2 or 3, define a new TOUT and call the code again.
759C TOUT must be different from T. You cannot change
760C the direction of integration without restarting.
761C
762C IDID = 4, call the code again to continue the integration
763C another step in the direction of TOUT. You may
764C change the functions in G after a return with IDID=4,
765C but the number of constraint functions NG must remain
766C the same. If you wish to change
767C the functions in RES or in G, then you
768C must restart the code.
769C
770C *** Following an interrupted task ***
771C To show the code that you realize the task was
772C interrupted and that you want to continue, you
773C must take appropriate action and set INFO(1) = 1
774C If
775C IDID = -1, The code has reached the step iteration.
776C If you want to continue, set INFO(1) = 1 and
777C call the code again. See also INFO(12).
778C
779C IDID = -2, The error tolerances RTOL, ATOL have been
780C increased to values the code estimates appropriate
781C for continuing. You may want to change them
782C yourself. If you are sure you want to continue
783C with relaxed error tolerances, set INFO(1)=1 and
784C call the code again.
785C
786C IDID = -3, A solution component is zero and you set the
787C corresponding component of ATOL to zero. If you
788C are sure you want to continue, you must first
789C alter the error criterion to use positive values
790C for those components of ATOL corresponding to zero
791C solution components, then set INFO(1)=1 and call
792C the code again.
793C
794C IDID = -4,-5 --- Cannot occur with this code.
795C
796C IDID = -6, Repeated error test failures occurred on the
797C last attempted step in DDASRT. A singularity in the
798C solution may be present. If you are absolutely
799C certain you want to continue, you should restart
800C the integration. (Provide initial values of Y and
801C YPRIME which are consistent)
802C
803C IDID = -7, Repeated convergence test failures occurred
804C on the last attempted step in DDASRT. An inaccurate
805C or ill-conditioned JACOBIAN may be the problem. If
806C you are absolutely certain you want to continue, you
807C should restart the integration.
808C
809C IDID = -8, The matrix of partial derivatives is singular.
810C Some of your equations may be redundant.
811C DDASRT cannot solve the problem as stated.
812C It is possible that the redundant equations
813C could be removed, and then DDASRT could
814C solve the problem. It is also possible
815C that a solution to your problem either
816C does not exist or is not unique.
817C
818C IDID = -9, DDASRT had multiple convergence test
819C failures, preceeded by multiple error
820C test failures, on the last attempted step.
821C It is possible that your problem
822C is ill-posed, and cannot be solved
823C using this code. Or, there may be a
824C discontinuity or a singularity in the
825C solution. If you are absolutely certain
826C you want to continue, you should restart
827C the integration.
828C
829C IDID =-10, DDASRT had multiple convergence test failures
830C because IRES was equal to minus one.
831C If you are absolutely certain you want
832C to continue, you should restart the
833C integration.
834C
835C IDID =-11, IRES=-2 was encountered, and control is being
836C returned to the calling program.
837C
838C IDID =-12, DDASRT failed to compute the initial YPRIME.
839C This could happen because the initial
840C approximation to YPRIME was not very good, or
841C if a YPRIME consistent with the initial Y
842C does not exist. The problem could also be caused
843C by an inaccurate or singular iteration matrix.
844C
845C
846C
847C IDID = -13,..,-32 --- Cannot occur with this code.
848C
849C *** Following a terminated task ***
850C If IDID= -33, you cannot continue the solution of this
851C problem. An attempt to do so will result in your
852C run being terminated.
853C
854C ---------------------------------------------------------------------
855C
856C***REFERENCE
857C K. E. Brenan, S. L. Campbell, and L. R. Petzold, Numerical
858C Solution of Initial-Value Problems in Differential-Algebraic
859C Equations, Elsevier, New York, 1989.
860C
861C***ROUTINES CALLED DDASTP,DDAINI,DDANRM,DDAWTS,DDATRP,DRCHEK,DROOTS,
862C XERRWD,D1MACH
863C***END PROLOGUE DDASRT
864C
865C**End
866C
867 IMPLICIT DOUBLE PRECISION(a-h,o-z)
868 LOGICAL DONE
869 EXTERNAL res, jac, g
870 dimension y(*),yprime(*)
871 dimension info(15)
872 dimension rwork(*),iwork(*)
873 dimension rtol(*),atol(*)
874 dimension rpar(*),ipar(*)
875 CHARACTER MSG*80
876C
877C SET POINTERS INTO IWORK
878 parameter(lml=1, lmu=2, lmxord=3, lmtype=4, lnst=11,
879 * lnre=12, lnje=13, letf=14, lctf=15, lnge=16, lnpd=17,
880 * lirfnd=18, lmxstp=21, lipvt=22, ljcalc=5, lphase=6, lk=7,
881 * lkold=8, lns=9, lnstl=10, liwm=1)
882C
883C SET RELATIVE OFFSET INTO RWORK
884 parameter(npd=1)
885C
886C SET POINTERS INTO RWORK
887 parameter(ltstop=1, lhmax=2, lh=3, ltn=4,
888 * lcj=5, lcjold=6, lhold=7, ls=8, lround=9,
889 * lalpha=11, lbeta=17, lgamma=23,
890 * lpsi=29, lsigma=35, lt0=41, ltlast=42, lalphr=43, lx2=44,
891 * ldelta=51)
892C
893C***FIRST EXECUTABLE STATEMENT DDASRT
894 IF(info(1).NE.0)GO TO 100
895C
896C-----------------------------------------------------------------------
897C THIS BLOCK IS EXECUTED FOR THE INITIAL CALL ONLY.
898C IT CONTAINS CHECKING OF INPUTS AND INITIALIZATIONS.
899C-----------------------------------------------------------------------
900C
901C FIRST CHECK INFO ARRAY TO MAKE SURE ALL ELEMENTS OF INFO
902C ARE EITHER ZERO OR ONE.
903 DO 10 i=2,12
904 IF(info(i).NE.0.AND.info(i).NE.1)GO TO 701
90510 CONTINUE
906C
907 IF(neq.LE.0)GO TO 702
908C
909C CHECK AND COMPUTE MAXIMUM ORDER
910 mxord=5
911 IF(info(9).EQ.0)GO TO 20
912 mxord=iwork(lmxord)
913 IF(mxord.LT.1.OR.mxord.GT.5)GO TO 703
91420 iwork(lmxord)=mxord
915C
916C COMPUTE MTYPE,LENPD,LENRW.CHECK ML AND MU.
917 IF(info(6).NE.0)GO TO 40
918 lenpd=neq**2
919 lenrw=50+(iwork(lmxord)+4)*neq+lenpd+3*ng
920 IF(info(5).NE.0)GO TO 30
921 iwork(lmtype)=2
922 GO TO 60
92330 iwork(lmtype)=1
924 GO TO 60
92540 IF(iwork(lml).LT.0.OR.iwork(lml).GE.neq)GO TO 717
926 IF(iwork(lmu).LT.0.OR.iwork(lmu).GE.neq)GO TO 718
927 lenpd=(2*iwork(lml)+iwork(lmu)+1)*neq
928 IF(info(5).NE.0)GO TO 50
929 iwork(lmtype)=5
930 mband=iwork(lml)+iwork(lmu)+1
931 msave=(neq/mband)+1
932 lenrw=50+(iwork(lmxord)+4)*neq+lenpd+2*msave+3*ng
933 GO TO 60
93450 iwork(lmtype)=4
935 lenrw=50+(iwork(lmxord)+4)*neq+lenpd+3*ng
936C
937C CHECK LENGTHS OF RWORK AND IWORK
93860 leniw=21+neq
939 iwork(lnpd)=lenpd
940 IF(lrw.LT.lenrw)GO TO 704
941 IF(liw.LT.leniw)GO TO 705
942C
943C CHECK TO SEE THAT TOUT IS DIFFERENT FROM T
944C Also check to see that NG is larger than 0.
945 IF(tout .EQ. t)GO TO 719
946 IF(ng .LT. 0) GO TO 730
947C
948C CHECK HMAX
949 IF(info(7).EQ.0)GO TO 70
950 hmax=rwork(lhmax)
951 IF(hmax.LE.0.0d0)GO TO 710
95270 CONTINUE
953C
954C CHECK AND COMPUTE MAXIMUM STEPS
955 mxstp=500
956 IF(info(12).EQ.0)GO TO 80
957 mxstp=iwork(lmxstp)
958 IF(mxstp.LT.0)GO TO 716
95980 iwork(lmxstp)=mxstp
960C
961C INITIALIZE COUNTERS
962 iwork(lnst)=0
963 iwork(lnre)=0
964 iwork(lnje)=0
965 iwork(lnge)=0
966C
967 iwork(lnstl)=0
968 idid=1
969 GO TO 200
970C
971C-----------------------------------------------------------------------
972C THIS BLOCK IS FOR CONTINUATION CALLS
973C ONLY. HERE WE CHECK INFO(1),AND IF THE
974C LAST STEP WAS INTERRUPTED WE CHECK WHETHER
975C APPROPRIATE ACTION WAS TAKEN.
976C-----------------------------------------------------------------------
977C
978100 CONTINUE
979 IF(info(1).EQ.1)GO TO 110
980 IF(info(1).NE.-1)GO TO 701
981C IF WE ARE HERE, THE LAST STEP WAS INTERRUPTED
982C BY AN ERROR CONDITION FROM DDASTP,AND
983C APPROPRIATE ACTION WAS NOT TAKEN. THIS
984C IS A FATAL ERROR.
985 msg = 'DASRT-- THE LAST STEP TERMINATED WITH A NEGATIVE'
986 CALL xerrwd(msg,49,201,0,0,0,0,0,0.0d0,0.0d0)
987 msg = 'DASRT-- VALUE (=I1) OF IDID AND NO APPROPRIATE'
988 CALL xerrwd(msg,47,202,0,1,idid,0,0,0.0d0,0.0d0)
989 msg = 'DASRT-- ACTION WAS TAKEN. RUN TERMINATED'
990 CALL xerrwd(msg,41,203,1,0,0,0,0,0.0d0,0.0d0)
991 RETURN
992110 CONTINUE
993 iwork(lnstl)=iwork(lnst)
994C
995C-----------------------------------------------------------------------
996C THIS BLOCK IS EXECUTED ON ALL CALLS.
997C THE ERROR TOLERANCE PARAMETERS ARE
998C CHECKED, AND THE WORK ARRAY POINTERS
999C ARE SET.
1000C-----------------------------------------------------------------------
1001C
1002200 CONTINUE
1003C CHECK RTOL,ATOL
1004 nzflg=0
1005 rtoli=rtol(1)
1006 atoli=atol(1)
1007 DO 210 i=1,neq
1008 IF(info(2).EQ.1)rtoli=rtol(i)
1009 IF(info(2).EQ.1)atoli=atol(i)
1010 IF(rtoli.GT.0.0d0.OR.atoli.GT.0.0d0)nzflg=1
1011 IF(rtoli.LT.0.0d0)GO TO 706
1012 IF(atoli.LT.0.0d0)GO TO 707
1013210 CONTINUE
1014 IF(nzflg.EQ.0)GO TO 708
1015C
1016C SET UP RWORK STORAGE.IWORK STORAGE IS FIXED
1017C IN DATA STATEMENT.
1018 lg0=ldelta+neq
1019 lg1=lg0+ng
1020 lgx=lg1+ng
1021 le=lgx+ng
1022 lwt=le+neq
1023 lphi=lwt+neq
1024 lpd=lphi+(iwork(lmxord)+1)*neq
1025 lwm=lpd
1026 ntemp=npd+iwork(lnpd)
1027 IF(info(1).EQ.1)GO TO 400
1028C
1029C-----------------------------------------------------------------------
1030C THIS BLOCK IS EXECUTED ON THE INITIAL CALL
1031C ONLY. SET THE INITIAL STEP SIZE, AND
1032C THE ERROR WEIGHT VECTOR, AND PHI.
1033C COMPUTE INITIAL YPRIME, IF NECESSARY.
1034C-----------------------------------------------------------------------
1035C
1036300 CONTINUE
1037 tn=t
1038 idid=1
1039C
1040C SET ERROR WEIGHT VECTOR WT
1041 CALL ddawts(neq,info(2),rtol,atol,y,rwork(lwt),rpar,ipar)
1042 DO 305 i = 1,neq
1043 IF(rwork(lwt+i-1).LE.0.0d0) GO TO 713
1044305 CONTINUE
1045C
1046C COMPUTE UNIT ROUNDOFF AND HMIN
1047 uround = d1mach(4)
1048 rwork(lround) = uround
1049 hmin = 4.0d0*uround*dmax1(dabs(t),dabs(tout))
1050C
1051C CHECK INITIAL INTERVAL TO SEE THAT IT IS LONG ENOUGH
1052 tdist = dabs(tout - t)
1053 IF(tdist .LT. hmin) GO TO 714
1054C
1055C CHECK H0, IF THIS WAS INPUT
1056 IF (info(8) .EQ. 0) GO TO 310
1057 ho = rwork(lh)
1058 IF ((tout - t)*ho .LT. 0.0d0) GO TO 711
1059 IF (ho .EQ. 0.0d0) GO TO 712
1060 GO TO 320
1061310 CONTINUE
1062C
1063C COMPUTE INITIAL STEPSIZE, TO BE USED BY EITHER
1064C DDASTP OR DDAINI, DEPENDING ON INFO(11)
1065 ho = 0.001d0*tdist
1066 ypnorm = ddanrm(neq,yprime,rwork(lwt),rpar,ipar)
1067 IF (ypnorm .GT. 0.5d0/ho) ho = 0.5d0/ypnorm
1068 ho = dsign(ho,tout-t)
1069C ADJUST HO IF NECESSARY TO MEET HMAX BOUND
1070320 IF (info(7) .EQ. 0) GO TO 330
1071 rh = dabs(ho)/rwork(lhmax)
1072 IF (rh .GT. 1.0d0) ho = ho/rh
1073C COMPUTE TSTOP, IF APPLICABLE
1074330 IF (info(4) .EQ. 0) GO TO 340
1075 tstop = rwork(ltstop)
1076 IF ((tstop - t)*ho .LT. 0.0d0) GO TO 715
1077 IF ((t + ho - tstop)*ho .GT. 0.0d0) ho = tstop - t
1078 IF ((tstop - tout)*ho .LT. 0.0d0) GO TO 709
1079C
1080C COMPUTE INITIAL DERIVATIVE, UPDATING TN AND Y, IF APPLICABLE
1081340 IF (info(11) .EQ. 0) GO TO 350
1082 CALL ddaini(tn,y,yprime,neq,
1083 * res,jac,ho,rwork(lwt),idid,rpar,ipar,
1084 * rwork(lphi),rwork(ldelta),rwork(le),
1085 * rwork(lwm),iwork(liwm),hmin,rwork(lround),
1086 * info(10),ntemp)
1087 IF (idid .LT. 0) GO TO 390
1088C
1089C LOAD H WITH H0. STORE H IN RWORK(LH)
1090350 h = ho
1091 rwork(lh) = h
1092C
1093C LOAD Y AND H*YPRIME INTO PHI(*,1) AND PHI(*,2)
1094360 itemp = lphi + neq
1095 DO 370 i = 1,neq
1096 rwork(lphi + i - 1) = y(i)
1097370 rwork(itemp + i - 1) = h*yprime(i)
1098C
1099C INITIALIZE T0 IN RWORK AND CHECK FOR A ZERO OF G NEAR THE
1100C INITIAL T.
1101C
1102 rwork(lt0) = t
1103 iwork(lirfnd) = 0
1104 rwork(lpsi)=h
1105 rwork(lpsi+1)=2.0d0*h
1106 iwork(lkold)=1
1107 IF(ng .EQ. 0) GO TO 390
1108 CALL drchek(1,g,ng,neq,t,tout,y,rwork(le),rwork(lphi),
1109 * rwork(lpsi),iwork(lkold),rwork(lg0),rwork(lg1),
1110 * rwork(lgx),jroot,irt,rwork(lround),info(3),
1111 * rwork,iwork,rpar,ipar)
1112 IF(irt .NE. 0) GO TO 732
1113C
1114C Check for a root in the interval (T0,TN], unless DDASRT
1115C did not have to initialize YPRIME.
1116C
1117 IF(ng .EQ. 0 .OR. info(11) .EQ. 0) GO TO 390
1118 CALL drchek(3,g,ng,neq,tn,tout,y,rwork(le),rwork(lphi),
1119 * rwork(lpsi),iwork(lkold),rwork(lg0),rwork(lg1),
1120 * rwork(lgx),jroot,irt,rwork(lround),info(3),
1121 * rwork,iwork,rpar,ipar)
1122 IF(irt .NE. 1) GO TO 390
1123 iwork(lirfnd) = 1
1124 idid = 4
1125 t = rwork(lt0)
1126 GO TO 580
1127C
1128390 GO TO 500
1129C
1130C-------------------------------------------------------
1131C THIS BLOCK IS FOR CONTINUATION CALLS ONLY. ITS
1132C PURPOSE IS TO CHECK STOP CONDITIONS BEFORE
1133C TAKING A STEP.
1134C ADJUST H IF NECESSARY TO MEET HMAX BOUND
1135C-------------------------------------------------------
1136C
1137400 CONTINUE
1138 uround=rwork(lround)
1139 done = .false.
1140 tn=rwork(ltn)
1141 h=rwork(lh)
1142 IF(ng .EQ. 0) GO TO 405
1143C
1144C Check for a zero of G near TN.
1145C
1146 CALL drchek(2,g,ng,neq,tn,tout,y,rwork(le),rwork(lphi),
1147 * rwork(lpsi),iwork(lkold),rwork(lg0),rwork(lg1),
1148 * rwork(lgx),jroot,irt,rwork(lround),info(3),
1149 * rwork,iwork,rpar,ipar)
1150 IF(irt .NE. 1) GO TO 405
1151 iwork(lirfnd) = 1
1152 idid = 4
1153 t = rwork(lt0)
1154 done = .true.
1155 GO TO 490
1156C
1157405 CONTINUE
1158 IF(info(7) .EQ. 0) GO TO 410
1159 rh = dabs(h)/rwork(lhmax)
1160 IF(rh .GT. 1.0d0) h = h/rh
1161410 CONTINUE
1162 IF(t .EQ. tout) GO TO 719
1163 IF((t - tout)*h .GT. 0.0d0) GO TO 711
1164 IF(info(4) .EQ. 1) GO TO 430
1165 IF(info(3) .EQ. 1) GO TO 420
1166 IF((tn-tout)*h.LT.0.0d0)GO TO 490
1167 CALL ddatrp(tn,tout,y,yprime,neq,iwork(lkold),
1168 * rwork(lphi),rwork(lpsi))
1169 t=tout
1170 idid = 3
1171 done = .true.
1172 GO TO 490
1173420 IF((tn-t)*h .LE. 0.0d0) GO TO 490
1174 IF((tn - tout)*h .GT. 0.0d0) GO TO 425
1175 CALL ddatrp(tn,tn,y,yprime,neq,iwork(lkold),
1176 * rwork(lphi),rwork(lpsi))
1177 t = tn
1178 idid = 1
1179 done = .true.
1180 GO TO 490
1181425 CONTINUE
1182 CALL ddatrp(tn,tout,y,yprime,neq,iwork(lkold),
1183 * rwork(lphi),rwork(lpsi))
1184 t = tout
1185 idid = 3
1186 done = .true.
1187 GO TO 490
1188430 IF(info(3) .EQ. 1) GO TO 440
1189 tstop=rwork(ltstop)
1190 IF((tn-tstop)*h.GT.0.0d0) GO TO 715
1191 IF((tstop-tout)*h.LT.0.0d0)GO TO 709
1192 IF((tn-tout)*h.LT.0.0d0)GO TO 450
1193 CALL ddatrp(tn,tout,y,yprime,neq,iwork(lkold),
1194 * rwork(lphi),rwork(lpsi))
1195 t=tout
1196 idid = 3
1197 done = .true.
1198 GO TO 490
1199440 tstop = rwork(ltstop)
1200 IF((tn-tstop)*h .GT. 0.0d0) GO TO 715
1201 IF((tstop-tout)*h .LT. 0.0d0) GO TO 709
1202 IF((tn-t)*h .LE. 0.0d0) GO TO 450
1203 IF((tn - tout)*h .GT. 0.0d0) GO TO 445
1204 CALL ddatrp(tn,tn,y,yprime,neq,iwork(lkold),
1205 * rwork(lphi),rwork(lpsi))
1206 t = tn
1207 idid = 1
1208 done = .true.
1209 GO TO 490
1210445 CONTINUE
1211 CALL ddatrp(tn,tout,y,yprime,neq,iwork(lkold),
1212 * rwork(lphi),rwork(lpsi))
1213 t = tout
1214 idid = 3
1215 done = .true.
1216 GO TO 490
1217450 CONTINUE
1218C CHECK WHETHER WE ARE WITH IN ROUNDOFF OF TSTOP
1219 IF(dabs(tn-tstop).GT.100.0d0*uround*
1220 * (dabs(tn)+dabs(h)))GO TO 460
1221 CALL ddatrp(tn,tstop,y,yprime,neq,iwork(lkold),
1222 * rwork(lphi),rwork(lpsi))
1223 idid=2
1224 t=tstop
1225 done = .true.
1226 GO TO 490
1227460 tnext=tn+h
1228 IF((tnext-tstop)*h.LE.0.0d0)GO TO 490
1229 h=tstop-tn
1230 rwork(lh)=h
1231C
1232490 IF (done) GO TO 590
1233C
1234C-------------------------------------------------------
1235C THE NEXT BLOCK CONTAINS THE CALL TO THE
1236C ONE-STEP INTEGRATOR DDASTP.
1237C THIS IS A LOOPING POINT FOR THE INTEGRATION STEPS.
1238C CHECK FOR TOO MANY STEPS.
1239C UPDATE WT.
1240C CHECK FOR TOO MUCH ACCURACY REQUESTED.
1241C COMPUTE MINIMUM STEPSIZE.
1242C-------------------------------------------------------
1243C
1244500 CONTINUE
1245C CHECK FOR FAILURE TO COMPUTE INITIAL YPRIME
1246 IF (idid .EQ. -12) GO TO 527
1247C
1248C CHECK FOR TOO MANY STEPS
1249 IF((iwork(lnst)-iwork(lnstl)).LT.iwork(lmxstp))
1250 * GO TO 510
1251 idid=-1
1252 GO TO 527
1253C
1254C UPDATE WT
1255510 CALL ddawts(neq,info(2),rtol,atol,rwork(lphi),
1256 * rwork(lwt),rpar,ipar)
1257 DO 520 i=1,neq
1258 IF(rwork(i+lwt-1).GT.0.0d0)GO TO 520
1259 idid=-3
1260 GO TO 527
1261520 CONTINUE
1262C
1263C TEST FOR TOO MUCH ACCURACY REQUESTED.
1264 r=ddanrm(neq,rwork(lphi),rwork(lwt),rpar,ipar)*
1265 * 100.0d0*uround
1266 IF(r.LE.1.0d0)GO TO 525
1267C MULTIPLY RTOL AND ATOL BY R AND RETURN
1268 IF(info(2).EQ.1)GO TO 523
1269 rtol(1)=r*rtol(1)
1270 atol(1)=r*atol(1)
1271 idid=-2
1272 GO TO 527
1273523 DO 524 i=1,neq
1274 rtol(i)=r*rtol(i)
1275524 atol(i)=r*atol(i)
1276 idid=-2
1277 GO TO 527
1278525 CONTINUE
1279C
1280C COMPUTE MINIMUM STEPSIZE
1281 hmin=4.0d0*uround*dmax1(dabs(tn),dabs(tout))
1282C
1283C TEST H VS. HMAX
1284 IF (info(7) .EQ. 0) GO TO 526
1285 rh = abs(h)/rwork(lhmax)
1286 IF (rh .GT. 1.0d0) h = h/rh
1287526 CONTINUE
1288C
1289 CALL ddastp(tn,y,yprime,neq,
1290 * res,jac,h,rwork(lwt),info(1),idid,rpar,ipar,
1291 * rwork(lphi),rwork(ldelta),rwork(le),
1292 * rwork(lwm),iwork(liwm),
1293 * rwork(lalpha),rwork(lbeta),rwork(lgamma),
1294 * rwork(lpsi),rwork(lsigma),
1295 * rwork(lcj),rwork(lcjold),rwork(lhold),
1296 * rwork(ls),hmin,rwork(lround),
1297 * iwork(lphase),iwork(ljcalc),iwork(lk),
1298 * iwork(lkold),iwork(lns),info(10),ntemp)
1299527 IF(idid.LT.0)GO TO 600
1300C
1301C--------------------------------------------------------
1302C THIS BLOCK HANDLES THE CASE OF A SUCCESSFUL RETURN
1303C FROM DDASTP (IDID=1). TEST FOR STOP CONDITIONS.
1304C--------------------------------------------------------
1305C
1306 IF(ng .EQ. 0) GO TO 529
1307C
1308C Check for a zero of G near TN.
1309C
1310 CALL drchek(3,g,ng,neq,tn,tout,y,rwork(le),rwork(lphi),
1311 * rwork(lpsi),iwork(lkold),rwork(lg0),rwork(lg1),
1312 * rwork(lgx),jroot,irt,rwork(lround),info(3),
1313 * rwork,iwork,rpar,ipar)
1314 IF(irt .NE. 1) GO TO 529
1315 iwork(lirfnd) = 1
1316 idid = 4
1317 t = rwork(lt0)
1318 GO TO 580
1319C
1320529 CONTINUE
1321 IF(info(4).NE.0)GO TO 540
1322 IF(info(3).NE.0)GO TO 530
1323 IF((tn-tout)*h.LT.0.0d0)GO TO 500
1324 CALL ddatrp(tn,tout,y,yprime,neq,
1325 * iwork(lkold),rwork(lphi),rwork(lpsi))
1326 idid=3
1327 t=tout
1328 GO TO 580
1329530 IF((tn-tout)*h.GE.0.0d0)GO TO 535
1330 t=tn
1331 idid=1
1332 GO TO 580
1333535 CALL ddatrp(tn,tout,y,yprime,neq,
1334 * iwork(lkold),rwork(lphi),rwork(lpsi))
1335 idid=3
1336 t=tout
1337 GO TO 580
1338540 IF(info(3).NE.0)GO TO 550
1339 IF((tn-tout)*h.LT.0.0d0)GO TO 542
1340 CALL ddatrp(tn,tout,y,yprime,neq,
1341 * iwork(lkold),rwork(lphi),rwork(lpsi))
1342 t=tout
1343 idid=3
1344 GO TO 580
1345542 IF(dabs(tn-tstop).LE.100.0d0*uround*
1346 * (dabs(tn)+dabs(h)))GO TO 545
1347 tnext=tn+h
1348 IF((tnext-tstop)*h.LE.0.0d0)GO TO 500
1349 h=tstop-tn
1350 GO TO 500
1351545 CALL ddatrp(tn,tstop,y,yprime,neq,
1352 * iwork(lkold),rwork(lphi),rwork(lpsi))
1353 idid=2
1354 t=tstop
1355 GO TO 580
1356550 IF((tn-tout)*h.GE.0.0d0)GO TO 555
1357 IF(dabs(tn-tstop).LE.100.0d0*uround*(dabs(tn)+dabs(h)))GO TO 552
1358 t=tn
1359 idid=1
1360 GO TO 580
1361552 CALL ddatrp(tn,tstop,y,yprime,neq,
1362 * iwork(lkold),rwork(lphi),rwork(lpsi))
1363 idid=2
1364 t=tstop
1365 GO TO 580
1366555 CALL ddatrp(tn,tout,y,yprime,neq,
1367 * iwork(lkold),rwork(lphi),rwork(lpsi))
1368 t=tout
1369 idid=3
1370580 CONTINUE
1371C
1372C--------------------------------------------------------
1373C ALL SUCCESSFUL RETURNS FROM DDASRT ARE MADE FROM
1374C THIS BLOCK.
1375C--------------------------------------------------------
1376C
1377590 CONTINUE
1378 rwork(ltn)=tn
1379 rwork(lh)=h
1380 rwork(ltlast) = t
1381 RETURN
1382C
1383C-----------------------------------------------------------------------
1384C THIS BLOCK HANDLES ALL UNSUCCESSFUL
1385C RETURNS OTHER THAN FOR ILLEGAL INPUT.
1386C-----------------------------------------------------------------------
1387C
1388600 CONTINUE
1389 itemp=-idid
1390 GO TO (610,620,630,690,690,640,650,660,670,675,
1391 * 680,685), itemp
1392C
1393C THE MAXIMUM NUMBER OF STEPS WAS TAKEN BEFORE
1394C REACHING TOUT
1395610 msg = 'DASRT-- AT CURRENT T (=R1) 500 STEPS'
1396 CALL xerrwd(msg,38,610,0,0,0,0,1,tn,0.0d0)
1397 msg = 'DASRT-- TAKEN ON THIS CALL BEFORE REACHING TOUT'
1398 CALL xerrwd(msg,48,611,0,0,0,0,0,0.0d0,0.0d0)
1399 GO TO 690
1400C
1401C TOO MUCH ACCURACY FOR MACHINE PRECISION
1402620 msg = 'DASRT-- AT T (=R1) TOO MUCH ACCURACY REQUESTED'
1403 CALL xerrwd(msg,47,620,0,0,0,0,1,tn,0.0d0)
1404 msg = 'DASRT-- FOR PRECISION OF MACHINE. RTOL AND ATOL'
1405 CALL xerrwd(msg,48,621,0,0,0,0,0,0.0d0,0.0d0)
1406 msg = 'DASRT-- WERE INCREASED TO APPROPRIATE VALUES'
1407 CALL xerrwd(msg,45,622,0,0,0,0,0,0.0d0,0.0d0)
1408C
1409 GO TO 690
1410C WT(I) .LE. 0.0D0 FOR SOME I (NOT AT START OF PROBLEM)
1411630 msg = 'DASRT-- AT T (=R1) SOME ELEMENT OF WT'
1412 CALL xerrwd(msg,38,630,0,0,0,0,1,tn,0.0d0)
1413 msg = .LE.'DASRT-- HAS BECOME 0.0'
1414 CALL xerrwd(msg,28,631,0,0,0,0,0,0.0d0,0.0d0)
1415 GO TO 690
1416C
1417C ERROR TEST FAILED REPEATEDLY OR WITH H=HMIN
1418640 msg = 'DASRT-- AT T (=R1) AND STEPSIZE H (=R2) THE'
1419 CALL xerrwd(msg,44,640,0,0,0,0,2,tn,h)
1420 msg='DASRT-- ERROR TEST FAILED REPEATEDLY OR WITH ABS(H)=HMIN'
1421 CALL xerrwd(msg,57,641,0,0,0,0,0,0.0d0,0.0d0)
1422 GO TO 690
1423C
1424C CORRECTOR CONVERGENCE FAILED REPEATEDLY OR WITH H=HMIN
1425650 msg = 'DASRT-- AT T (=R1) AND STEPSIZE H (=R2) THE'
1426 CALL xerrwd(msg,44,650,0,0,0,0,2,tn,h)
1427 msg = 'DASRT-- CORRECTOR FAILED TO CONVERGE REPEATEDLY'
1428 CALL xerrwd(msg,48,651,0,0,0,0,0,0.0d0,0.0d0)
1429 msg = 'DASRT-- OR WITH ABS(H)=HMIN'
1430 CALL xerrwd(msg,28,652,0,0,0,0,0,0.0d0,0.0d0)
1431 GO TO 690
1432C
1433C THE ITERATION MATRIX IS SINGULAR
1434660 msg = 'DASRT-- AT T (=R1) AND STEPSIZE H (=R2) THE'
1435 CALL xerrwd(msg,44,660,0,0,0,0,2,tn,h)
1436 msg = 'DASRT-- ITERATION MATRIX IS SINGULAR'
1437 CALL xerrwd(msg,37,661,0,0,0,0,0,0.0d0,0.0d0)
1438 GO TO 690
1439C
1440C CORRECTOR FAILURE PRECEEDED BY ERROR TEST FAILURES.
1441670 msg = 'DASRT-- AT T (=R1) AND STEPSIZE H (=R2) THE'
1442 CALL xerrwd(msg,44,670,0,0,0,0,2,tn,h)
1443 msg = 'DASRT-- CORRECTOR COULD NOT CONVERGE. ALSO, THE'
1444 CALL xerrwd(msg,49,671,0,0,0,0,0,0.0d0,0.0d0)
1445 msg = 'DASRT-- ERROR TEST FAILED REPEATEDLY.'
1446 CALL xerrwd(msg,38,672,0,0,0,0,0,0.0d0,0.0d0)
1447 GO TO 690
1448C
1449C CORRECTOR FAILURE BECAUSE IRES = -1
1450675 msg = 'DASRT-- AT T (=R1) AND STEPSIZE H (=R2) THE'
1451 CALL xerrwd(msg,44,675,0,0,0,0,2,tn,h)
1452 msg = 'DASRT-- CORRECTOR COULD NOT CONVERGE BECAUSE'
1453 CALL xerrwd(msg,45,676,0,0,0,0,0,0.0d0,0.0d0)
1454 msg = 'DASRT-- IRES WAS EQUAL TO MINUS ONE'
1455 CALL xerrwd(msg,36,677,0,0,0,0,0,0.0d0,0.0d0)
1456 GO TO 690
1457C
1458C FAILURE BECAUSE IRES = -2
1459680 msg = 'DASRT-- AT T (=R1) AND STEPSIZE H (=R2)'
1460 CALL xerrwd(msg,40,680,0,0,0,0,2,tn,h)
1461 msg = 'DASRT-- IRES WAS EQUAL TO MINUS TWO'
1462 CALL xerrwd(msg,36,681,0,0,0,0,0,0.0d0,0.0d0)
1463 GO TO 690
1464C
1465C FAILED TO COMPUTE INITIAL YPRIME
1466685 msg = 'DASRT-- AT T (=R1) AND STEPSIZE H (=R2) THE'
1467 CALL xerrwd(msg,44,685,0,0,0,0,2,tn,ho)
1468 msg = 'DASRT-- INITIAL YPRIME COULD NOT BE COMPUTED'
1469 CALL xerrwd(msg,45,686,0,0,0,0,0,0.0d0,0.0d0)
1470 GO TO 690
1471690 CONTINUE
1472 info(1)=-1
1473 t=tn
1474 rwork(ltn)=tn
1475 rwork(lh)=h
1476 RETURN
1477C-----------------------------------------------------------------------
1478C THIS BLOCK HANDLES ALL ERROR RETURNS DUE
1479C TO ILLEGAL INPUT, AS DETECTED BEFORE CALLING
1480C DDASTP. FIRST THE ERROR MESSAGE ROUTINE IS
1481C CALLED. IF THIS HAPPENS TWICE IN
1482C SUCCESSION, EXECUTION IS TERMINATED
1483C
1484C-----------------------------------------------------------------------
1485701 msg = 'DASRT-- SOME ELEMENT OF INFO VECTOR IS NOT ZERO OR ONE'
1486 CALL xerrwd(msg,55,1,0,0,0,0,0,0.0d0,0.0d0)
1487 GO TO 750
1488702 msg = .LE.'DASRT-- NEQ (=I1) 0'
1489 CALL xerrwd(msg,25,2,0,1,neq,0,0,0.0d0,0.0d0)
1490 GO TO 750
1491703 msg = 'DASRT-- MAXORD (=I1) NOT IN RANGE'
1492 CALL xerrwd(msg,34,3,0,1,mxord,0,0,0.0d0,0.0d0)
1493 GO TO 750
1494704 msg='DASRT-- RWORK LENGTH NEEDED, LENRW (=I1), EXCEEDS LRW (=I2)'
1495 CALL xerrwd(msg,60,4,0,2,lenrw,lrw,0,0.0d0,0.0d0)
1496 GO TO 750
1497705 msg='DASRT-- IWORK LENGTH NEEDED, LENIW (=I1), EXCEEDS LIW (=I2)'
1498 CALL xerrwd(msg,60,5,0,2,leniw,liw,0,0.0d0,0.0d0)
1499 GO TO 750
1500706 msg = .LT.'DASRT-- SOME ELEMENT OF RTOL IS 0'
1501 CALL xerrwd(msg,39,6,0,0,0,0,0,0.0d0,0.0d0)
1502 GO TO 750
1503707 msg = .LT.'DASRT-- SOME ELEMENT OF ATOL IS 0'
1504 CALL xerrwd(msg,39,7,0,0,0,0,0,0.0d0,0.0d0)
1505 GO TO 750
1506708 msg = 'DASRT-- ALL ELEMENTS OF RTOL AND ATOL ARE ZERO'
1507 CALL xerrwd(msg,47,8,0,0,0,0,0,0.0d0,0.0d0)
1508 GO TO 750
1509709 msg='DASRT-- INFO(4) = 1 AND TSTOP (=R1) BEHIND TOUT (=R2)'
1510 CALL xerrwd(msg,54,9,0,0,0,0,2,tstop,tout)
1511 GO TO 750
1512710 msg = .LT.'DASRT-- HMAX (=R1) 0.0'
1513 CALL xerrwd(msg,28,10,0,0,0,0,1,hmax,0.0d0)
1514 GO TO 750
1515711 msg = 'DASRT-- TOUT (=R1) BEHIND T (=R2)'
1516 CALL xerrwd(msg,34,11,0,0,0,0,2,tout,t)
1517 GO TO 750
1518712 msg = 'DASRT-- INFO(8)=1 AND H0=0.0'
1519 CALL xerrwd(msg,29,12,0,0,0,0,0,0.0d0,0.0d0)
1520 GO TO 750
1521713 msg = .LE.'DASRT-- SOME ELEMENT OF WT IS 0.0'
1522 CALL xerrwd(msg,39,13,0,0,0,0,0,0.0d0,0.0d0)
1523 GO TO 750
1524714 msg='DASRT-- TOUT (=R1) TOO CLOSE TO T (=R2) TO START INTEGRATION'
1525 CALL xerrwd(msg,60,14,0,0,0,0,2,tout,t)
1526 GO TO 750
1527715 msg = 'DASRT-- INFO(4)=1 AND TSTOP (=R1) BEHIND T (=R2)'
1528 CALL xerrwd(msg,49,15,0,0,0,0,2,tstop,t)
1529 GO TO 750
1530716 msg = .LT.'DASRT-- INFO(12)=1 AND MXSTP (=I1) 0'
1531 CALL xerrwd(msg,42,16,0,1,iwork(lmxstp),0,0,0.0d0,0.0d0)
1532 GO TO 750
1533717 msg = .LT..GT.'DASRT-- ML (=I1) ILLEGAL. EITHER 0 OR NEQ'
1534 CALL xerrwd(msg,52,17,0,1,iwork(lml),0,0,0.0d0,0.0d0)
1535 GO TO 750
1536718 msg = .LT..GT.'DASRT-- MU (=I1) ILLEGAL. EITHER 0 OR NEQ'
1537 CALL xerrwd(msg,52,18,0,1,iwork(lmu),0,0,0.0d0,0.0d0)
1538 GO TO 750
1539719 msg = 'DASRT-- TOUT (=R1) IS EQUAL TO T (=R2)'
1540 CALL xerrwd(msg,39,19,0,0,0,0,2,tout,t)
1541 GO TO 750
1542730 msg = .LT.'DASRT-- NG (=I1) 0'
1543 CALL xerrwd(msg,24,30,1,1,ng,0,0,0.0d0,0.0d0)
1544 GO TO 750
1545732 msg = 'DASRT-- ONE OR MORE COMPONENTS OF G HAS A ROOT'
1546 CALL xerrwd(msg,47,32,1,0,0,0,0,0.0d0,0.0d0)
1547 msg = ' TOO NEAR TO THE INITIAL POINT'
1548 CALL xerrwd(msg,38,32,1,0,0,0,0,0.0d0,0.0d0)
1549750 IF(info(1).EQ.-1) GO TO 760
1550 info(1)=-1
1551 idid=-33
1552 RETURN
1553760 msg = 'DASRT-- REPEATED OCCURRENCES OF ILLEGAL INPUT'
1554 CALL xerrwd(msg,46,801,0,0,0,0,0,0.0d0,0.0d0)
1555770 msg = 'DASRT-- RUN TERMINATED. APPARENT INFINITE LOOP'
1556 CALL xerrwd(msg,47,802,1,0,0,0,0,0.0d0,0.0d0)
1557 RETURN
1558C-----------END OF SUBROUTINE DDASRT------------------------------------
1559 END
double precision function d1mach(i)
Definition d1mach.f:23
subroutine ddaini(x, y, yprime, neq, res, jac, h, wt, idid, rpar, ipar, phi, delta, e, wm, iwm, hmin, uround, nonneg, ntemp)
Definition ddaini.f:3
double precision function ddanrm(neq, v, wt, rpar, ipar)
Definition ddanrm.f:2
subroutine ddasrt(res, neq, t, y, yprime, tout, info, rtol, atol, idid, rwork, lrw, iwork, liw, rpar, ipar, jac, g, ng, jroot)
Definition ddasrt.f:4
subroutine ddastp(x, y, yprime, neq, res, jac, h, wt, jstart, idid, rpar, ipar, phi, delta, e, wm, iwm, alpha, beta, gamma, psi, sigma, cj, cjold, hold, s, hmin, uround, iphase, jcalc, k, kold, ns, nonneg, ntemp)
Definition ddastp.f:5
subroutine ddatrp(x, xout, yout, ypout, neq, kold, phi, psi)
Definition ddatrp.f:2
subroutine ddawts(neq, iwt, rtol, atol, y, wt, rpar, ipar)
Definition ddawts.f:2
subroutine drchek(job, g, ng, neq, tn, tout, y, yp, phi, psi, kold, g0, g1, gx, jroot, irt, uround, info3, rwork, iwork, rpar, ipar)
Definition drchek.f:4
double lgamma(double x)
Definition lo-specfun.h:336
subroutine xerrwd(msg, nmes, nerr, level, ni, i1, i2, nr, r1, r2)
Definition xerrwd.f:4