GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
ddassl.f
Go to the documentation of this file.
1 SUBROUTINE ddassl (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
2 + IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC)
3C***BEGIN PROLOGUE DDASSL
4C***PURPOSE This code solves a system of differential/algebraic
5C equations of the form G(T,Y,YPRIME) = 0.
6C***LIBRARY SLATEC (DASSL)
7C***CATEGORY I1A2
8C***TYPE DOUBLE PRECISION (SDASSL-S, DDASSL-D)
9C***KEYWORDS DIFFERENTIAL/ALGEBRAIC, BACKWARD DIFFERENTIATION FORMULAS,
10C IMPLICIT DIFFERENTIAL SYSTEMS
11C***AUTHOR PETZOLD, LINDA R., (LLNL)
12C COMPUTING AND MATHEMATICS RESEARCH DIVISION
13C LAWRENCE LIVERMORE NATIONAL LABORATORY
14C L - 316, P.O. BOX 808,
15C LIVERMORE, CA. 94550
16C***DESCRIPTION
17C
18C *Usage:
19C
20C EXTERNAL RES, JAC
21C INTEGER NEQ, INFO(N), IDID, LRW, LIW, IWORK(LIW), IPAR
22C DOUBLE PRECISION T, Y(NEQ), YPRIME(NEQ), TOUT, RTOL, ATOL,
23C * RWORK(LRW), RPAR
24C
25C CALL DDASSL (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL,
26C * IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC)
27C
28C
29C *Arguments:
30C (In the following, all real arrays should be type DOUBLE PRECISION.)
31C
32C RES:EXT This is a subroutine which you provide to define the
33C differential/algebraic system.
34C
35C NEQ:IN This is the number of equations to be solved.
36C
37C T:INOUT This is the current value of the independent variable.
38C
39C Y(*):INOUT This array contains the solution components at T.
40C
41C YPRIME(*):INOUT This array contains the derivatives of the solution
42C components at T.
43C
44C TOUT:IN This is a point at which a solution is desired.
45C
46C INFO(N):IN The basic task of the code is to solve the system from T
47C to TOUT and return an answer at TOUT. INFO is an integer
48C array which is used to communicate exactly how you want
49C this task to be carried out. (See below for details.)
50C N must be greater than or equal to 15.
51C
52C RTOL,ATOL:INOUT These quantities represent relative and absolute
53C error tolerances which you provide to indicate how
54C accurately you wish the solution to be computed. You
55C may choose them to be both scalars or else both vectors.
56C Caution: In Fortran 77, a scalar is not the same as an
57C array of length 1. Some compilers may object
58C to using scalars for RTOL,ATOL.
59C
60C IDID:OUT This scalar quantity is an indicator reporting what the
61C code did. You must monitor this integer variable to
62C decide 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. (See below for required length.)
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. (See below for required length.)
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
79C to provide for defining a matrix of partial derivatives
80C described below.
81C
82C Quantities which may be altered by DDASSL are:
83C T, Y(*), YPRIME(*), INFO(1), RTOL, ATOL,
84C IDID, RWORK(*) AND IWORK(*)
85C
86C *Description
87C
88C Subroutine DDASSL uses the backward differentiation formulas of
89C orders one through five to solve a system of the above form for Y and
90C YPRIME. Values for Y and YPRIME at the initial time must be given as
91C input. These values must be consistent, (that is, if T,Y,YPRIME are
92C the given initial values, they must satisfy G(T,Y,YPRIME) = 0.). The
93C subroutine solves the system from T to TOUT. It is easy to continue
94C the solution to get results at additional TOUT. This is the interval
95C mode of operation. Intermediate results can also be obtained easily
96C by using the intermediate-output capability.
97C
98C The following detailed description is divided into subsections:
99C 1. Input required for the first call to DDASSL.
100C 2. Output after any return from DDASSL.
101C 3. What to do to continue the integration.
102C 4. Error messages.
103C
104C
105C -------- INPUT -- WHAT TO DO ON THE FIRST CALL TO DDASSL ------------
106C
107C The first call of the code is defined to be the start of each new
108C problem. Read through the descriptions of all the following items,
109C provide sufficient storage space for designated arrays, set
110C appropriate variables for the initialization of the problem, and
111C give information about how you want the problem to be solved.
112C
113C
114C RES -- Provide a subroutine of the form
115C SUBROUTINE RES(T,Y,YPRIME,DELTA,IRES,RPAR,IPAR)
116C to define the system of differential/algebraic
117C equations which is to be solved. For the given values
118C of T,Y and YPRIME, the subroutine should
119C return the residual of the defferential/algebraic
120C system
121C DELTA = G(T,Y,YPRIME)
122C (DELTA(*) is a vector of length NEQ which is
123C output for RES.)
124C
125C Subroutine RES must not alter T,Y or YPRIME.
126C You must declare the name RES in an external
127C statement in your program that calls DDASSL.
128C You must dimension Y,YPRIME and DELTA in RES.
129C
130C IRES is an integer flag which is always equal to
131C zero on input. Subroutine RES should alter IRES
132C only if it encounters an illegal value of Y or
133C a stop condition. Set IRES = -1 if an input value
134C is illegal, and DDASSL will try to solve the problem
135C without getting IRES = -1. If IRES = -2, DDASSL
136C will return control to the calling program
137C with IDID = -11.
138C
139C RPAR and IPAR are real and integer parameter arrays which
140C you can use for communication between your calling program
141C and subroutine RES. They are not altered by DDASSL. If you
142C do not need RPAR or IPAR, ignore these parameters by treat-
143C ing them as dummy arguments. If you do choose to use them,
144C dimension them in your calling program and in RES as arrays
145C of appropriate length.
146C
147C NEQ -- Set it to the number of differential equations.
148C (NEQ .GE. 1)
149C
150C T -- Set it to the initial point of the integration.
151C T must be defined as a variable.
152C
153C Y(*) -- Set this vector to the initial values of the NEQ solution
154C components at the initial point. You must dimension Y of
155C length at least NEQ in your calling program.
156C
157C YPRIME(*) -- Set this vector to the initial values of the NEQ
158C first derivatives of the solution components at the initial
159C point. You must dimension YPRIME at least NEQ in your
160C calling program. If you do not know initial values of some
161C of the solution components, see the explanation of INFO(11).
162C
163C TOUT -- Set it to the first point at which a solution
164C is desired. You can not take TOUT = T.
165C integration either forward in T (TOUT .GT. T) or
166C backward in T (TOUT .LT. T) is permitted.
167C
168C The code advances the solution from T to TOUT using
169C step sizes which are automatically selected so as to
170C achieve the desired accuracy. If you wish, the code will
171C return with the solution and its derivative at
172C intermediate steps (intermediate-output mode) so that
173C you can monitor them, but you still must provide TOUT in
174C accord with the basic aim of the code.
175C
176C The first step taken by the code is a critical one
177C because it must reflect how fast the solution changes near
178C the initial point. The code automatically selects an
179C initial step size which is practically always suitable for
180C the problem. By using the fact that the code will not step
181C past TOUT in the first step, you could, if necessary,
182C restrict the length of the initial step size.
183C
184C For some problems it may not be permissible to integrate
185C past a point TSTOP because a discontinuity occurs there
186C or the solution or its derivative is not defined beyond
187C TSTOP. When you have declared a TSTOP point (SEE INFO(4)
188C and RWORK(1)), you have told the code not to integrate
189C past TSTOP. In this case any TOUT beyond TSTOP is invalid
190C input.
191C
192C INFO(*) -- Use the INFO array to give the code more details about
193C how you want your problem solved. This array should be
194C dimensioned of length 15, though DDASSL uses only the first
195C eleven entries. You must respond to all of the following
196C items, which are arranged as questions. The simplest use
197C of the code corresponds to answering all questions as yes,
198C i.e. setting all entries of INFO to 0.
199C
200C INFO(1) - This parameter enables the code to initialize
201C itself. You must set it to indicate the start of every
202C new problem.
203C
204C **** Is this the first call for this problem ...
205C Yes - Set INFO(1) = 0
206C No - Not applicable here.
207C See below for continuation calls. ****
208C
209C INFO(2) - How much accuracy you want of your solution
210C is specified by the error tolerances RTOL and ATOL.
211C The simplest use is to take them both to be scalars.
212C To obtain more flexibility, they can both be vectors.
213C The code must be told your choice.
214C
215C **** Are both error tolerances RTOL, ATOL scalars ...
216C Yes - Set INFO(2) = 0
217C and input scalars for both RTOL and ATOL
218C No - Set INFO(2) = 1
219C and input arrays for both RTOL and ATOL ****
220C
221C INFO(3) - The code integrates from T in the direction
222C of TOUT by steps. If you wish, it will return the
223C computed solution and derivative at the next
224C intermediate step (the intermediate-output mode) or
225C TOUT, whichever comes first. This is a good way to
226C proceed if you want to see the behavior of the solution.
227C If you must have solutions at a great many specific
228C TOUT points, this code will compute them efficiently.
229C
230C **** Do you want the solution only at
231C TOUT (and not at the next intermediate step) ...
232C Yes - Set INFO(3) = 0
233C No - Set INFO(3) = 1 ****
234C
235C INFO(4) - To handle solutions at a great many specific
236C values TOUT efficiently, this code may integrate past
237C TOUT and interpolate to obtain the result at TOUT.
238C Sometimes it is not possible to integrate beyond some
239C point TSTOP because the equation changes there or it is
240C not defined past TSTOP. Then you must tell the code
241C not to go past.
242C
243C **** Can the integration be carried out without any
244C restrictions on the independent variable T ...
245C Yes - Set INFO(4)=0
246C No - Set INFO(4)=1
247C and define the stopping point TSTOP by
248C setting RWORK(1)=TSTOP ****
249C
250C INFO(5) - To solve differential/algebraic problems it is
251C necessary to use a matrix of partial derivatives of the
252C system of differential equations. If you do not
253C provide a subroutine to evaluate it analytically (see
254C description of the item JAC in the call list), it will
255C be approximated by numerical differencing in this code.
256C although it is less trouble for you to have the code
257C compute partial derivatives by numerical differencing,
258C the solution will be more reliable if you provide the
259C derivatives via JAC. Sometimes numerical differencing
260C is cheaper than evaluating derivatives in JAC and
261C sometimes it is not - this depends on your problem.
262C
263C **** Do you want the code to evaluate the partial
264C derivatives automatically by numerical differences ...
265C Yes - Set INFO(5)=0
266C No - Set INFO(5)=1
267C and provide subroutine JAC for evaluating the
268C matrix of partial derivatives ****
269C
270C INFO(6) - DDASSL will perform much better if the matrix of
271C partial derivatives, DG/DY + CJ*DG/DYPRIME,
272C (here CJ is a scalar determined by DDASSL)
273C is banded and the code is told this. In this
274C case, the storage needed will be greatly reduced,
275C numerical differencing will be performed much cheaper,
276C and a number of important algorithms will execute much
277C faster. The differential equation is said to have
278C half-bandwidths ML (lower) and MU (upper) if equation i
279C involves only unknowns Y(J) with
280C I-ML .LE. J .LE. I+MU
281C for all I=1,2,...,NEQ. Thus, ML and MU are the widths
282C of the lower and upper parts of the band, respectively,
283C with the main diagonal being excluded. If you do not
284C indicate that the equation has a banded matrix of partial
285C derivatives, the code works with a full matrix of NEQ**2
286C elements (stored in the conventional way). Computations
287C with banded matrices cost less time and storage than with
288C full matrices if 2*ML+MU .LT. NEQ. If you tell the
289C code that the matrix of partial derivatives has a banded
290C structure and you want to provide subroutine JAC to
291C compute the partial derivatives, then you must be careful
292C to store the elements of the matrix in the special form
293C indicated in the description of JAC.
294C
295C **** Do you want to solve the problem using a full
296C (dense) matrix (and not a special banded
297C structure) ...
298C Yes - Set INFO(6)=0
299C No - Set INFO(6)=1
300C and provide the lower (ML) and upper (MU)
301C bandwidths by setting
302C IWORK(1)=ML
303C IWORK(2)=MU ****
304C
305C
306C INFO(7) -- You can specify a maximum (absolute value of)
307C stepsize, so that the code
308C will avoid passing over very
309C large regions.
310C
311C **** Do you want the code to decide
312C on its own maximum stepsize?
313C Yes - Set INFO(7)=0
314C No - Set INFO(7)=1
315C and define HMAX by setting
316C RWORK(2)=HMAX ****
317C
318C INFO(8) -- Differential/algebraic problems
319C may occaisionally suffer from
320C severe scaling difficulties on the
321C first step. If you know a great deal
322C about the scaling of your problem, you can
323C help to alleviate this problem by
324C specifying an initial stepsize HO.
325C
326C **** Do you want the code to define
327C its own initial stepsize?
328C Yes - Set INFO(8)=0
329C No - Set INFO(8)=1
330C and define HO by setting
331C RWORK(3)=HO ****
332C
333C INFO(9) -- If storage is a severe problem,
334C you can save some locations by
335C restricting the maximum order MAXORD.
336C the default value is 5. for each
337C order decrease below 5, the code
338C requires NEQ fewer locations, however
339C it is likely to be slower. In any
340C case, you must have 1 .LE. MAXORD .LE. 5
341C **** Do you want the maximum order to
342C default to 5?
343C Yes - Set INFO(9)=0
344C No - Set INFO(9)=1
345C and define MAXORD by setting
346C IWORK(3)=MAXORD ****
347C
348C INFO(10) --If you know that the solutions to your equations
349C will always be nonnegative, it may help to set this
350C parameter. However, it is probably best to
351C try the code without using this option first,
352C and only to use this option if that doesn't
353C work very well.
354C **** Do you want the code to solve the problem without
355C invoking any special nonnegativity constraints?
356C Yes - Set INFO(10)=0
357C No - Set INFO(10)=1
358C
359C INFO(11) --DDASSL normally requires the initial T,
360C Y, and YPRIME to be consistent. That is,
361C you must have G(T,Y,YPRIME) = 0 at the initial
362C time. If you do not know the initial
363C derivative precisely, you can let DDASSL try
364C to compute it.
365C **** Are the initialHE INITIAL T, Y, YPRIME consistent?
366C Yes - Set INFO(11) = 0
367C No - Set INFO(11) = 1,
368C and set YPRIME to an initial approximation
369C to YPRIME. (If you have no idea what
370C YPRIME should be, set it to zero. Note
371C that the initial Y should be such
372C that there must exist a YPRIME so that
373C G(T,Y,YPRIME) = 0.)
374C
375C RTOL, ATOL -- You must assign relative (RTOL) and absolute (ATOL
376C error tolerances to tell the code how accurately you
377C want the solution to be computed. They must be defined
378C as variables because the code may change them. You
379C have two choices --
380C Both RTOL and ATOL are scalars. (INFO(2)=0)
381C Both RTOL and ATOL are vectors. (INFO(2)=1)
382C in either case all components must be non-negative.
383C
384C The tolerances are used by the code in a local error
385C test at each step which requires roughly that
386C ABS(LOCAL ERROR) .LE. RTOL*ABS(Y)+ATOL
387C for each vector component.
388C (More specifically, a root-mean-square norm is used to
389C measure the size of vectors, and the error test uses the
390C magnitude of the solution at the beginning of the step.)
391C
392C The true (global) error is the difference between the
393C true solution of the initial value problem and the
394C computed approximation. Practically all present day
395C codes, including this one, control the local error at
396C each step and do not even attempt to control the global
397C error directly.
398C Usually, but not always, the true accuracy of the
399C computed Y is comparable to the error tolerances. This
400C code will usually, but not always, deliver a more
401C accurate solution if you reduce the tolerances and
402C integrate again. By comparing two such solutions you
403C can get a fairly reliable idea of the true error in the
404C solution at the bigger tolerances.
405C
406C Setting ATOL=0. results in a pure relative error test on
407C that component. Setting RTOL=0. results in a pure
408C absolute error test on that component. A mixed test
409C with non-zero RTOL and ATOL corresponds roughly to a
410C relative error test when the solution component is much
411C bigger than ATOL and to an absolute error test when the
412C solution component is smaller than the threshhold ATOL.
413C
414C The code will not attempt to compute a solution at an
415C accuracy unreasonable for the machine being used. It will
416C advise you if you ask for too much accuracy and inform
417C you as to the maximum accuracy it believes possible.
418C
419C RWORK(*) -- Dimension this real work array of length LRW in your
420C calling program.
421C
422C LRW -- Set it to the declared length of the RWORK array.
423C You must have
424C LRW .GE. 40+(MAXORD+4)*NEQ+NEQ**2
425C for the full (dense) JACOBIAN case (when INFO(6)=0), or
426C LRW .GE. 40+(MAXORD+4)*NEQ+(2*ML+MU+1)*NEQ
427C for the banded user-defined JACOBIAN case
428C (when INFO(5)=1 and INFO(6)=1), or
429C LRW .GE. 40+(MAXORD+4)*NEQ+(2*ML+MU+1)*NEQ
430C +2*(NEQ/(ML+MU+1)+1)
431C for the banded finite-difference-generated JACOBIAN case
432C (when INFO(5)=0 and INFO(6)=1)
433C
434C IWORK(*) -- Dimension this integer work array of length LIW in
435C your calling program.
436C
437C LIW -- Set it to the declared length of the IWORK array.
438C You must have LIW .GE. 21+NEQ
439C
440C RPAR, IPAR -- These are parameter arrays, of real and integer
441C type, respectively. You can use them for communication
442C between your program that calls DDASSL and the
443C RES subroutine (and the JAC subroutine). They are not
444C altered by DDASSL. If you do not need RPAR or IPAR,
445C ignore these parameters by treating them as dummy
446C arguments. If you do choose to use them, dimension
447C them in your calling program and in RES (and in JAC)
448C as arrays of appropriate length.
449C
450C JAC -- If you have set INFO(5)=0, you can ignore this parameter
451C by treating it as a dummy argument. Otherwise, you must
452C provide a subroutine of the form
453C SUBROUTINE JAC(T,Y,YPRIME,PD,CJ,RPAR,IPAR)
454C to define the matrix of partial derivatives
455C PD=DG/DY+CJ*DG/DYPRIME
456C CJ is a scalar which is input to JAC.
457C For the given values of T,Y,YPRIME, the
458C subroutine must evaluate the non-zero partial
459C derivatives for each equation and each solution
460C component, and store these values in the
461C matrix PD. The elements of PD are set to zero
462C before each call to JAC so only non-zero elements
463C need to be defined.
464C
465C Subroutine JAC must not alter T,Y,(*),YPRIME(*), or CJ.
466C You must declare the name JAC in an EXTERNAL statement in
467C your program that calls DDASSL. You must dimension Y,
468C YPRIME and PD in JAC.
469C
470C The way you must store the elements into the PD matrix
471C depends on the structure of the matrix which you
472C indicated by INFO(6).
473C *** INFO(6)=0 -- Full (dense) matrix ***
474C Give PD a first dimension of NEQ.
475C When you evaluate the (non-zero) partial derivative
476C of equation I with respect to variable J, you must
477C store it in PD according to
478C PD(I,J) = "DG(I)/DY(J)+CJ*DG(I)/DYPRIME(J)"
479C *** INFO(6)=1 -- Banded JACOBIAN with ML lower and MU
480C upper diagonal bands (refer to INFO(6) description
481C of ML and MU) ***
482C Give PD a first dimension of 2*ML+MU+1.
483C when you evaluate the (non-zero) partial derivative
484C of equation I with respect to variable J, you must
485C store it in PD according to
486C IROW = I - J + ML + MU + 1
487C PD(IROW,J) = "DG(I)/DY(J)+CJ*DG(I)/DYPRIME(J)"
488C
489C RPAR and IPAR are real and integer parameter arrays
490C which you can use for communication between your calling
491C program and your JACOBIAN subroutine JAC. They are not
492C altered by DDASSL. If you do not need RPAR or IPAR,
493C ignore these parameters by treating them as dummy
494C arguments. If you do choose to use them, dimension
495C them in your calling program and in JAC as arrays of
496C appropriate length.
497C
498C
499C OPTIONALLY REPLACEABLE NORM ROUTINE:
500C
501C DDASSL uses a weighted norm DDANRM to measure the size
502C of vectors such as the estimated error in each step.
503C A FUNCTION subprogram
504C DOUBLE PRECISION FUNCTION DDANRM(NEQ,V,WT,RPAR,IPAR)
505C DIMENSION V(NEQ),WT(NEQ)
506C is used to define this norm. Here, V is the vector
507C whose norm is to be computed, and WT is a vector of
508C weights. A DDANRM routine has been included with DDASSL
509C which computes the weighted root-mean-square norm
510C given by
511C DDANRM=SQRT((1/NEQ)*SUM(V(I)/WT(I))**2)
512C this norm is suitable for most problems. In some
513C special cases, it may be more convenient and/or
514C efficient to define your own norm by writing a function
515C subprogram to be called instead of DDANRM. This should,
516C however, be attempted only after careful thought and
517C consideration.
518C
519C
520C -------- OUTPUT -- AFTER ANY RETURN FROM DDASSL ---------------------
521C
522C The principal aim of the code is to return a computed solution at
523C TOUT, although it is also possible to obtain intermediate results
524C along the way. To find out whether the code achieved its goal
525C or if the integration process was interrupted before the task was
526C completed, you must check the IDID parameter.
527C
528C
529C T -- The solution was successfully advanced to the
530C output value of T.
531C
532C Y(*) -- Contains the computed solution approximation at T.
533C
534C YPRIME(*) -- Contains the computed derivative
535C approximation at T.
536C
537C IDID -- Reports what the code did.
538C
539C *** Task completed ***
540C Reported by positive values of IDID
541C
542C IDID = 1 -- A step was successfully taken in the
543C intermediate-output mode. The code has not
544C yet reached TOUT.
545C
546C IDID = 2 -- The integration to TSTOP was successfully
547C completed (T=TSTOP) by stepping exactly to TSTOP.
548C
549C IDID = 3 -- The integration to TOUT was successfully
550C completed (T=TOUT) by stepping past TOUT.
551C Y(*) is obtained by interpolation.
552C YPRIME(*) is obtained by interpolation.
553C
554C *** Task interrupted ***
555C Reported by negative values of IDID
556C
557C IDID = -1 -- A large amount of work has been expended.
558C (About 500 steps)
559C
560C IDID = -2 -- The error tolerances are too stringent.
561C
562C IDID = -3 -- The local error test cannot be satisfied
563C because you specified a zero component in ATOL
564C and the corresponding computed solution
565C component is zero. Thus, a pure relative error
566C test is impossible for this component.
567C
568C IDID = -6 -- DDASSL had repeated error test
569C failures on the last attempted step.
570C
571C IDID = -7 -- The corrector could not converge.
572C
573C IDID = -8 -- The matrix of partial derivatives
574C is singular.
575C
576C IDID = -9 -- The corrector could not converge.
577C there were repeated error test failures
578C in this step.
579C
580C IDID =-10 -- The corrector could not converge
581C because IRES was equal to minus one.
582C
583C IDID =-11 -- IRES equal to -2 was encountered
584C and control is being returned to the
585C calling program.
586C
587C IDID =-12 -- DDASSL failed to compute the initial
588C YPRIME.
589C
590C
591C
592C IDID = -13,..,-32 -- Not applicable for this code
593C
594C *** Task terminated ***
595C Reported by the value of IDID=-33
596C
597C IDID = -33 -- The code has encountered trouble from which
598C it cannot recover. A message is printed
599C explaining the trouble and control is returned
600C to the calling program. For example, this occurs
601C when invalid input is detected.
602C
603C RTOL, ATOL -- These quantities remain unchanged except when
604C IDID = -2. In this case, the error tolerances have been
605C increased by the code to values which are estimated to
606C be appropriate for continuing the integration. However,
607C the reported solution at T was obtained using the input
608C values of RTOL and ATOL.
609C
610C RWORK, IWORK -- Contain information which is usually of no
611C interest to the user but necessary for subsequent calls.
612C However, you may find use for
613C
614C RWORK(3)--Which contains the step size H to be
615C attempted on the next step.
616C
617C RWORK(4)--Which contains the current value of the
618C independent variable, i.e., the farthest point
619C integration has reached. This will be different
620C from T only when interpolation has been
621C performed (IDID=3).
622C
623C RWORK(7)--Which contains the stepsize used
624C on the last successful step.
625C
626C IWORK(7)--Which contains the order of the method to
627C be attempted on the next step.
628C
629C IWORK(8)--Which contains the order of the method used
630C on the last step.
631C
632C IWORK(11)--Which contains the number of steps taken so
633C far.
634C
635C IWORK(12)--Which contains the number of calls to RES
636C so far.
637C
638C IWORK(13)--Which contains the number of evaluations of
639C the matrix of partial derivatives needed so
640C far.
641C
642C IWORK(14)--Which contains the total number
643C of error test failures so far.
644C
645C IWORK(15)--Which contains the total number
646C of convergence test failures so far.
647C (includes singular iteration matrix
648C failures.)
649C
650C
651C -------- INPUT -- WHAT TO DO TO CONTINUE THE INTEGRATION ------------
652C (CALLS AFTER THE FIRST)
653C
654C This code is organized so that subsequent calls to continue the
655C integration involve little (if any) additional effort on your
656C part. You must monitor the IDID parameter in order to determine
657C what to do next.
658C
659C Recalling that the principal task of the code is to integrate
660C from T to TOUT (the interval mode), usually all you will need
661C to do is specify a new TOUT upon reaching the current TOUT.
662C
663C Do not alter any quantity not specifically permitted below,
664C in particular do not alter NEQ,T,Y(*),YPRIME(*),RWORK(*),IWORK(*)
665C or the differential equation in subroutine RES. Any such
666C alteration constitutes a new problem and must be treated as such,
667C i.e., you must start afresh.
668C
669C You cannot change from vector to scalar error control or vice
670C versa (INFO(2)), but you can change the size of the entries of
671C RTOL, ATOL. Increasing a tolerance makes the equation easier
672C to integrate. Decreasing a tolerance will make the equation
673C harder to integrate and should generally be avoided.
674C
675C You can switch from the intermediate-output mode to the
676C interval mode (INFO(3)) or vice versa at any time.
677C
678C If it has been necessary to prevent the integration from going
679C past a point TSTOP (INFO(4), RWORK(1)), keep in mind that the
680C code will not integrate to any TOUT beyond the currently
681C specified TSTOP. Once TSTOP has been reached you must change
682C the value of TSTOP or set INFO(4)=0. You may change INFO(4)
683C or TSTOP at any time but you must supply the value of TSTOP in
684C RWORK(1) whenever you set INFO(4)=1.
685C
686C Do not change INFO(5), INFO(6), IWORK(1), or IWORK(2)
687C unless you are going to restart the code.
688C
689C *** Following a completed task ***
690C If
691C IDID = 1, call the code again to continue the integration
692C another step in the direction of TOUT.
693C
694C IDID = 2 or 3, define a new TOUT and call the code again.
695C TOUT must be different from T. You cannot change
696C the direction of integration without restarting.
697C
698C *** Following an interrupted task ***
699C To show the code that you realize the task was
700C interrupted and that you want to continue, you
701C must take appropriate action and set INFO(1) = 1
702C If
703C IDID = -1, The code has taken about 500 steps.
704C If you want to continue, set INFO(1) = 1 and
705C call the code again. An additional 500 steps
706C will be allowed.
707C
708C IDID = -2, The error tolerances RTOL, ATOL have been
709C increased to values the code estimates appropriate
710C for continuing. You may want to change them
711C yourself. If you are sure you want to continue
712C with relaxed error tolerances, set INFO(1)=1 and
713C call the code again.
714C
715C IDID = -3, A solution component is zero and you set the
716C corresponding component of ATOL to zero. If you
717C are sure you want to continue, you must first
718C alter the error criterion to use positive values
719C for those components of ATOL corresponding to zero
720C solution components, then set INFO(1)=1 and call
721C the code again.
722C
723C IDID = -4,-5 --- Cannot occur with this code.
724C
725C IDID = -6, Repeated error test failures occurred on the
726C last attempted step in DDASSL. A singularity in the
727C solution may be present. If you are absolutely
728C certain you want to continue, you should restart
729C the integration. (Provide initial values of Y and
730C YPRIME which are consistent)
731C
732C IDID = -7, Repeated convergence test failures occurred
733C on the last attempted step in DDASSL. An inaccurate
734C or ill-conditioned JACOBIAN may be the problem. If
735C you are absolutely certain you want to continue, you
736C should restart the integration.
737C
738C IDID = -8, The matrix of partial derivatives is singular.
739C Some of your equations may be redundant.
740C DDASSL cannot solve the problem as stated.
741C It is possible that the redundant equations
742C could be removed, and then DDASSL could
743C solve the problem. It is also possible
744C that a solution to your problem either
745C does not exist or is not unique.
746C
747C IDID = -9, DDASSL had multiple convergence test
748C failures, preceeded by multiple error
749C test failures, on the last attempted step.
750C It is possible that your problem
751C is ill-posed, and cannot be solved
752C using this code. Or, there may be a
753C discontinuity or a singularity in the
754C solution. If you are absolutely certain
755C you want to continue, you should restart
756C the integration.
757C
758C IDID =-10, DDASSL had multiple convergence test failures
759C because IRES was equal to minus one.
760C If you are absolutely certain you want
761C to continue, you should restart the
762C integration.
763C
764C IDID =-11, IRES=-2 was encountered, and control is being
765C returned to the calling program.
766C
767C IDID =-12, DDASSL failed to compute the initial YPRIME.
768C This could happen because the initial
769C approximation to YPRIME was not very good, or
770C if a YPRIME consistent with the initial Y
771C does not exist. The problem could also be caused
772C by an inaccurate or singular iteration matrix.
773C
774C IDID = -13,..,-32 --- Cannot occur with this code.
775C
776C
777C *** Following a terminated task ***
778C
779C If IDID= -33, you cannot continue the solution of this problem.
780C An attempt to do so will result in your
781C run being terminated.
782C
783C
784C -------- ERROR MESSAGES ---------------------------------------------
785C
786C The SLATEC error print routine XERMSG is called in the event of
787C unsuccessful completion of a task. Most of these are treated as
788C "recoverable errors", which means that (unless the user has directed
789C otherwise) control will be returned to the calling program for
790C possible action after the message has been printed.
791C
792C In the event of a negative value of IDID other than -33, an appro-
793C priate message is printed and the "error number" printed by XERMSG
794C is the value of IDID. There are quite a number of illegal input
795C errors that can lead to a returned value IDID=-33. The conditions
796C and their printed "error numbers" are as follows:
797C
798C Error number Condition
799C
800C 1 Some element of INFO vector is not zero or one.
801C 2 NEQ .le. 0
802C 3 MAXORD not in range.
803C 4 LRW is less than the required length for RWORK.
804C 5 LIW is less than the required length for IWORK.
805C 6 Some element of RTOL is .lt. 0
806C 7 Some element of ATOL is .lt. 0
807C 8 All elements of RTOL and ATOL are zero.
808C 9 INFO(4)=1 and TSTOP is behind TOUT.
809C 10 HMAX .lt. 0.0
810C 11 TOUT is behind T.
811C 12 INFO(8)=1 and H0=0.0
812C 13 Some element of WT is .le. 0.0
813C 14 TOUT is too close to T to start integration.
814C 15 INFO(4)=1 and TSTOP is behind T.
815C 16 --( Not used in this version )--
816C 17 ML illegal. Either .lt. 0 or .gt. NEQ
817C 18 MU illegal. Either .lt. 0 or .gt. NEQ
818C 19 TOUT = T.
819C
820C If DDASSL is called again without any action taken to remove the
821C cause of an unsuccessful return, XERMSG will be called with a fatal
822C error flag, which will cause unconditional termination of the
823C program. There are two such fatal errors:
824C
825C Error number -998: The last step was terminated with a negative
826C value of IDID other than -33, and no appropriate action was
827C taken.
828C
829C Error number -999: The previous call was terminated because of
830C illegal input (IDID=-33) and there is illegal input in the
831C present call, as well. (Suspect infinite loop.)
832C
833C ---------------------------------------------------------------------
834C
835C***REFERENCES A DESCRIPTION OF DASSL: A DIFFERENTIAL/ALGEBRAIC
836C SYSTEM SOLVER, L. R. PETZOLD, SAND82-8637,
837C SANDIA NATIONAL LABORATORIES, SEPTEMBER 1982.
838C***ROUTINES CALLED D1MACH, DDAINI, DDANRM, DDASTP, DDATRP, DDAWTS,
839C XERMSG
840C***REVISION HISTORY (YYMMDD)
841C 830315 DATE WRITTEN
842C 880387 Code changes made. All common statements have been
843C replaced by a DATA statement, which defines pointers into
844C RWORK, and PARAMETER statements which define pointers
845C into IWORK. As well the documentation has gone through
846C grammatical changes.
847C 881005 The prologue has been changed to mixed case.
848C The subordinate routines had revision dates changed to
849C this date, although the documentation for these routines
850C is all upper case. No code changes.
851C 890511 Code changes made. The DATA statement in the declaration
852C section of DDASSL was replaced with a PARAMETER
853C statement. Also the statement S = 100.D0 was removed
854C from the top of the Newton iteration in DDASTP.
855C The subordinate routines had revision dates changed to
856C this date.
857C 890517 The revision date syntax was replaced with the revision
858C history syntax. Also the "DECK" comment was added to
859C the top of all subroutines. These changes are consistent
860C with new SLATEC guidelines.
861C The subordinate routines had revision dates changed to
862C this date. No code changes.
863C 891013 Code changes made.
864C Removed all occurrances of FLOAT or DBLE. All operations
865C are now performed with "mixed-mode" arithmetic.
866C Also, specific function names were replaced with generic
867C function names to be consistent with new SLATEC guidelines.
868C In particular:
869C Replaced DSQRT with SQRT everywhere.
870C Replaced DABS with ABS everywhere.
871C Replaced DMIN1 with MIN everywhere.
872C Replaced MIN0 with MIN everywhere.
873C Replaced DMAX1 with MAX everywhere.
874C Replaced MAX0 with MAX everywhere.
875C Replaced DSIGN with SIGN everywhere.
876C Also replaced REVISION DATE with REVISION HISTORY in all
877C subordinate routines.
878C 901004 Miscellaneous changes to prologue to complete conversion
879C to SLATEC 4.0 format. No code changes. (F.N.Fritsch)
880C 901009 Corrected GAMS classification code and converted subsidiary
881C routines to 4.0 format. No code changes. (F.N.Fritsch)
882C 901010 Converted XERRWV calls to XERMSG calls. (R.Clemens,AFWL)
883C 901019 Code changes made.
884C Merged SLATEC 4.0 changes with previous changes made
885C by C. Ulrich. Below is a history of the changes made by
886C C. Ulrich. (Changes in subsidiary routines are implied
887C by this history)
888C 891228 Bug was found and repaired inside the DDASSL
889C and DDAINI routines. DDAINI was incorrectly
890C returning the initial T with Y and YPRIME
891C computed at T+H. The routine now returns T+H
892C rather than the initial T.
893C Cosmetic changes made to DDASTP.
894C 900904 Three modifications were made to fix a bug (inside
895C DDASSL) re interpolation for continuation calls and
896C cases where TN is very close to TSTOP:
897C
898C 1) In testing for whether H is too large, just
899C compare H to (TSTOP - TN), rather than
900C (TSTOP - TN) * (1-4*UROUND), and set H to
901C TSTOP - TN. This will force DDASTP to step
902C exactly to TSTOP under certain situations
903C (i.e. when H returned from DDASTP would otherwise
904C take TN beyond TSTOP).
905C
906C 2) Inside the DDASTP loop, interpolate exactly to
907C TSTOP if TN is very close to TSTOP (rather than
908C interpolating to within roundoff of TSTOP).
909C
910C 3) Modified IDID description for IDID = 2 to say that
911C the solution is returned by stepping exactly to
912C TSTOP, rather than TOUT. (In some cases the
913C solution is actually obtained by extrapolating
914C over a distance near unit roundoff to TSTOP,
915C but this small distance is deemed acceptable in
916C these circumstances.)
917C 901026 Added explicit declarations for all variables and minor
918C cosmetic changes to prologue, removed unreferenced labels,
919C and improved XERMSG calls. (FNF)
920C 901030 Added ERROR MESSAGES section and reworked other sections to
921C be of more uniform format. (FNF)
922C 910624 Fixed minor bug related to HMAX (five lines ending in
923C statement 526 in DDASSL). (LRP)
924C
925C***END PROLOGUE DDASSL
926C
927C**End
928C
929C Declare arguments.
930C
931 INTEGER NEQ, INFO(15), IDID, LRW, IWORK(*), LIW, IPAR(*)
932 double precision
933 * t, y(*), yprime(*), tout, rtol(*), atol(*), rwork(*),
934 * rpar(*)
935 EXTERNAL res, jac
936C
937C Declare externals.
938C
940 DOUBLE PRECISION D1MACH, DDANRM
941C
942C Declare local variables.
943C
944 INTEGER I, ITEMP, LALPHA, LBETA, LCJ, LCJOLD, LCTF, LDELTA,
945 * leniw, lenpd, lenrw, le, letf, lgamma, lh, lhmax, lhold,
946 * lmxstp, lipvt,
947 * ljcalc, lk, lkold, liwm, lml, lmtype, lmu, lmxord, lnje, lnpd,
948 * lnre, lns, lnst, lnstl, lpd, lphase, lphi, lpsi, lround, ls,
949 * lsigma, ltn, ltstop, lwm, lwt, mband, msave, mxord, npd, ntemp,
950 * nzflg
951 double precision
952 * atoli, h, hmax, hmin, ho, r, rh, rtoli, tdist, tn, tnext,
953 * tstop, uround, ypnorm
954 LOGICAL DONE
955C Auxiliary variables for conversion of values to be included in
956C error messages.
957 CHARACTER*8 XERN1, XERN2
958 CHARACTER*16 XERN3, XERN4
959C
960C SET POINTERS INTO IWORK
961 parameter(lml=1, lmu=2, lmxord=3, lmtype=4, lnst=11,
962 * lnre=12, lnje=13, letf=14, lctf=15, lnpd=16, lmxstp=21,
963 * lipvt=22, ljcalc=5, lphase=6, lk=7, lkold=8,
964 * lns=9, lnstl=10, liwm=1)
965C
966C SET RELATIVE OFFSET INTO RWORK
967 parameter(npd=1)
968C
969C SET POINTERS INTO RWORK
970 parameter(ltstop=1, lhmax=2, lh=3, ltn=4,
971 * lcj=5, lcjold=6, lhold=7, ls=8, lround=9,
972 * lalpha=11, lbeta=17, lgamma=23,
973 * lpsi=29, lsigma=35, ldelta=41)
974C
975C***FIRST EXECUTABLE STATEMENT DDASSL
976 IF(info(1).NE.0)GO TO 100
977C
978C-----------------------------------------------------------------------
979C THIS BLOCK IS EXECUTED FOR THE INITIAL CALL ONLY.
980C IT CONTAINS CHECKING OF INPUTS AND INITIALIZATIONS.
981C-----------------------------------------------------------------------
982C
983C FIRST CHECK INFO ARRAY TO MAKE SURE ALL ELEMENTS OF INFO
984C ARE EITHER ZERO OR ONE.
985 DO 10 i=2,11
986 IF(info(i).NE.0.AND.info(i).NE.1)GO TO 701
98710 CONTINUE
988C
989 IF(neq.LE.0)GO TO 702
990C
991C CHECK AND COMPUTE MAXIMUM ORDER
992 mxord=5
993 IF(info(9).EQ.0)GO TO 20
994 mxord=iwork(lmxord)
995 IF(mxord.LT.1.OR.mxord.GT.5)GO TO 703
99620 iwork(lmxord)=mxord
997C
998C COMPUTE MTYPE,LENPD,LENRW.CHECK ML AND MU.
999 IF(info(6).NE.0)GO TO 40
1000 lenpd=neq**2
1001 lenrw=40+(iwork(lmxord)+4)*neq+lenpd
1002 IF(info(5).NE.0)GO TO 30
1003 iwork(lmtype)=2
1004 GO TO 60
100530 iwork(lmtype)=1
1006 GO TO 60
100740 IF(iwork(lml).LT.0.OR.iwork(lml).GE.neq)GO TO 717
1008 IF(iwork(lmu).LT.0.OR.iwork(lmu).GE.neq)GO TO 718
1009 lenpd=(2*iwork(lml)+iwork(lmu)+1)*neq
1010 IF(info(5).NE.0)GO TO 50
1011 iwork(lmtype)=5
1012 mband=iwork(lml)+iwork(lmu)+1
1013 msave=(neq/mband)+1
1014 lenrw=40+(iwork(lmxord)+4)*neq+lenpd+2*msave
1015 GO TO 60
101650 iwork(lmtype)=4
1017 lenrw=40+(iwork(lmxord)+4)*neq+lenpd
1018C
1019C CHECK LENGTHS OF RWORK AND IWORK
102060 leniw=21+neq
1021 iwork(lnpd)=lenpd
1022 IF(lrw.LT.lenrw)GO TO 704
1023 IF(liw.LT.leniw)GO TO 705
1024C
1025C CHECK TO SEE THAT TOUT IS DIFFERENT FROM T
1026 IF(tout .EQ. t)GO TO 719
1027C
1028C CHECK HMAX
1029 IF(info(7).EQ.0)GO TO 70
1030 hmax=rwork(lhmax)
1031 IF(hmax.LE.0.0d0)GO TO 710
103270 CONTINUE
1033C
1034C CHECK AND COMPUTE MAXIMUM STEPS
1035 mxstp=500
1036 IF(info(12).EQ.0)GO TO 80
1037 mxstp=iwork(lmxstp)
1038 IF(mxstp.LT.0)GO TO 716
103980 iwork(lmxstp)=mxstp
1040C
1041C INITIALIZE COUNTERS
1042 iwork(lnst)=0
1043 iwork(lnre)=0
1044 iwork(lnje)=0
1045C
1046 iwork(lnstl)=0
1047 idid=1
1048 GO TO 200
1049C
1050C-----------------------------------------------------------------------
1051C THIS BLOCK IS FOR CONTINUATION CALLS
1052C ONLY. HERE WE CHECK INFO(1),AND IF THE
1053C LAST STEP WAS INTERRUPTED WE CHECK WHETHER
1054C APPROPRIATE ACTION WAS TAKEN.
1055C-----------------------------------------------------------------------
1056C
1057100 CONTINUE
1058 IF(info(1).EQ.1)GO TO 110
1059 IF(info(1).NE.-1)GO TO 701
1060C
1061C IF WE ARE HERE, THE LAST STEP WAS INTERRUPTED
1062C BY AN ERROR CONDITION FROM DDASTP,AND
1063C APPROPRIATE ACTION WAS NOT TAKEN. THIS
1064C IS A FATAL ERROR.
1065 WRITE (xern1, '(I8)') idid
1066 CALL xermsg ('SLATEC', 'DDASSL',
1067 * 'THE LAST STEP TERMINATED WITH A NEGATIVE VALUE OF IDID = ' //
1068 * xern1 // ' AND NO APPROPRIATE ACTION WAS TAKEN. ' //
1069 * 'RUN TERMINATED', -998, 2)
1070 RETURN
1071110 CONTINUE
1072 iwork(lnstl)=iwork(lnst)
1073C
1074C-----------------------------------------------------------------------
1075C THIS BLOCK IS EXECUTED ON ALL CALLS.
1076C THE ERROR TOLERANCE PARAMETERS ARE
1077C CHECKED, AND THE WORK ARRAY POINTERS
1078C ARE SET.
1079C-----------------------------------------------------------------------
1080C
1081200 CONTINUE
1082C CHECK RTOL,ATOL
1083 nzflg=0
1084 rtoli=rtol(1)
1085 atoli=atol(1)
1086 DO 210 i=1,neq
1087 IF(info(2).EQ.1)rtoli=rtol(i)
1088 IF(info(2).EQ.1)atoli=atol(i)
1089 IF(rtoli.GT.0.0d0.OR.atoli.GT.0.0d0)nzflg=1
1090 IF(rtoli.LT.0.0d0)GO TO 706
1091 IF(atoli.LT.0.0d0)GO TO 707
1092210 CONTINUE
1093 IF(nzflg.EQ.0)GO TO 708
1094C
1095C SET UP RWORK STORAGE.IWORK STORAGE IS FIXED
1096C IN DATA STATEMENT.
1097 le=ldelta+neq
1098 lwt=le+neq
1099 lphi=lwt+neq
1100 lpd=lphi+(iwork(lmxord)+1)*neq
1101 lwm=lpd
1102 ntemp=npd+iwork(lnpd)
1103 IF(info(1).EQ.1)GO TO 400
1104C
1105C-----------------------------------------------------------------------
1106C THIS BLOCK IS EXECUTED ON THE INITIAL CALL
1107C ONLY. SET THE INITIAL STEP SIZE, AND
1108C THE ERROR WEIGHT VECTOR, AND PHI.
1109C COMPUTE INITIAL YPRIME, IF NECESSARY.
1110C-----------------------------------------------------------------------
1111C
1112 tn=t
1113 idid=1
1114C
1115C SET ERROR WEIGHT VECTOR WT
1116 CALL ddawts(neq,info(2),rtol,atol,y,rwork(lwt),rpar,ipar)
1117 DO 305 i = 1,neq
1118 IF(rwork(lwt+i-1).LE.0.0d0) GO TO 713
1119305 CONTINUE
1120C
1121C COMPUTE UNIT ROUNDOFF AND HMIN
1122 uround = d1mach(4)
1123 rwork(lround) = uround
1124 hmin = 4.0d0*uround*max(abs(t),abs(tout))
1125C
1126C CHECK INITIAL INTERVAL TO SEE THAT IT IS LONG ENOUGH
1127 tdist = abs(tout - t)
1128 IF(tdist .LT. hmin) GO TO 714
1129C
1130C CHECK HO, IF THIS WAS INPUT
1131 IF (info(8) .EQ. 0) GO TO 310
1132 ho = rwork(lh)
1133 IF ((tout - t)*ho .LT. 0.0d0) GO TO 711
1134 IF (ho .EQ. 0.0d0) GO TO 712
1135 GO TO 320
1136310 CONTINUE
1137C
1138C COMPUTE INITIAL STEPSIZE, TO BE USED BY EITHER
1139C DDASTP OR DDAINI, DEPENDING ON INFO(11)
1140 ho = 0.001d0*tdist
1141 ypnorm = ddanrm(neq,yprime,rwork(lwt),rpar,ipar)
1142 IF (ypnorm .GT. 0.5d0/ho) ho = 0.5d0/ypnorm
1143 ho = sign(ho,tout-t)
1144C ADJUST HO IF NECESSARY TO MEET HMAX BOUND
1145320 IF (info(7) .EQ. 0) GO TO 330
1146 rh = abs(ho)/rwork(lhmax)
1147 IF (rh .GT. 1.0d0) ho = ho/rh
1148C COMPUTE TSTOP, IF APPLICABLE
1149330 IF (info(4) .EQ. 0) GO TO 340
1150 tstop = rwork(ltstop)
1151 IF ((tstop - t)*ho .LT. 0.0d0) GO TO 715
1152 IF ((t + ho - tstop)*ho .GT. 0.0d0) ho = tstop - t
1153 IF ((tstop - tout)*ho .LT. 0.0d0) GO TO 709
1154C
1155C COMPUTE INITIAL DERIVATIVE, UPDATING TN AND Y, IF APPLICABLE
1156340 IF (info(11) .EQ. 0) GO TO 350
1157 CALL ddaini(tn,y,yprime,neq,
1158 * res,jac,ho,rwork(lwt),idid,rpar,ipar,
1159 * rwork(lphi),rwork(ldelta),rwork(le),
1160 * rwork(lwm),iwork(liwm),hmin,rwork(lround),
1161 * info(10),ntemp)
1162 IF (idid .LT. 0) GO TO 390
1163C
1164C LOAD H WITH HO. STORE H IN RWORK(LH)
1165350 h = ho
1166 rwork(lh) = h
1167C
1168C LOAD Y AND H*YPRIME INTO PHI(*,1) AND PHI(*,2)
1169 itemp = lphi + neq
1170 DO 370 i = 1,neq
1171 rwork(lphi + i - 1) = y(i)
1172370 rwork(itemp + i - 1) = h*yprime(i)
1173C
1174390 GO TO 500
1175C
1176C-------------------------------------------------------
1177C THIS BLOCK IS FOR CONTINUATION CALLS ONLY. ITS
1178C PURPOSE IS TO CHECK STOP CONDITIONS BEFORE
1179C TAKING A STEP.
1180C ADJUST H IF NECESSARY TO MEET HMAX BOUND
1181C-------------------------------------------------------
1182C
1183400 CONTINUE
1184 uround=rwork(lround)
1185 done = .false.
1186 tn=rwork(ltn)
1187 h=rwork(lh)
1188 IF(info(7) .EQ. 0) GO TO 410
1189 rh = abs(h)/rwork(lhmax)
1190 IF(rh .GT. 1.0d0) h = h/rh
1191410 CONTINUE
1192 IF(t .EQ. tout) GO TO 719
1193 IF((t - tout)*h .GT. 0.0d0) GO TO 711
1194 IF(info(4) .EQ. 1) GO TO 430
1195 IF(info(3) .EQ. 1) GO TO 420
1196 IF((tn-tout)*h.LT.0.0d0)GO TO 490
1197 CALL ddatrp(tn,tout,y,yprime,neq,iwork(lkold),
1198 * rwork(lphi),rwork(lpsi))
1199 t=tout
1200 idid = 3
1201 done = .true.
1202 GO TO 490
1203420 IF((tn-t)*h .LE. 0.0d0) GO TO 490
1204 IF((tn - tout)*h .GT. 0.0d0) GO TO 425
1205 CALL ddatrp(tn,tn,y,yprime,neq,iwork(lkold),
1206 * rwork(lphi),rwork(lpsi))
1207 t = tn
1208 idid = 1
1209 done = .true.
1210 GO TO 490
1211425 CONTINUE
1212 CALL ddatrp(tn,tout,y,yprime,neq,iwork(lkold),
1213 * rwork(lphi),rwork(lpsi))
1214 t = tout
1215 idid = 3
1216 done = .true.
1217 GO TO 490
1218430 IF(info(3) .EQ. 1) GO TO 440
1219 tstop=rwork(ltstop)
1220 IF((tn-tstop)*h.GT.0.0d0) GO TO 715
1221 IF((tstop-tout)*h.LT.0.0d0)GO TO 709
1222 IF((tn-tout)*h.LT.0.0d0)GO TO 450
1223 CALL ddatrp(tn,tout,y,yprime,neq,iwork(lkold),
1224 * rwork(lphi),rwork(lpsi))
1225 t=tout
1226 idid = 3
1227 done = .true.
1228 GO TO 490
1229440 tstop = rwork(ltstop)
1230 IF((tn-tstop)*h .GT. 0.0d0) GO TO 715
1231 IF((tstop-tout)*h .LT. 0.0d0) GO TO 709
1232 IF((tn-t)*h .LE. 0.0d0) GO TO 450
1233 IF((tn - tout)*h .GT. 0.0d0) GO TO 445
1234 CALL ddatrp(tn,tn,y,yprime,neq,iwork(lkold),
1235 * rwork(lphi),rwork(lpsi))
1236 t = tn
1237 idid = 1
1238 done = .true.
1239 GO TO 490
1240445 CONTINUE
1241 CALL ddatrp(tn,tout,y,yprime,neq,iwork(lkold),
1242 * rwork(lphi),rwork(lpsi))
1243 t = tout
1244 idid = 3
1245 done = .true.
1246 GO TO 490
1247450 CONTINUE
1248C CHECK WHETHER WE ARE WITHIN ROUNDOFF OF TSTOP
1249 IF(abs(tn-tstop).GT.100.0d0*uround*
1250 * (abs(tn)+abs(h)))GO TO 460
1251 CALL ddatrp(tn,tstop,y,yprime,neq,iwork(lkold),
1252 * rwork(lphi),rwork(lpsi))
1253 idid=2
1254 t=tstop
1255 done = .true.
1256 GO TO 490
1257460 tnext=tn+h
1258 IF((tnext-tstop)*h.LE.0.0d0)GO TO 490
1259 h=tstop-tn
1260 rwork(lh)=h
1261C
1262490 IF (done) GO TO 580
1263C
1264C-------------------------------------------------------
1265C THE NEXT BLOCK CONTAINS THE CALL TO THE
1266C ONE-STEP INTEGRATOR DDASTP.
1267C THIS IS A LOOPING POINT FOR THE INTEGRATION STEPS.
1268C CHECK FOR TOO MANY STEPS.
1269C UPDATE WT.
1270C CHECK FOR TOO MUCH ACCURACY REQUESTED.
1271C COMPUTE MINIMUM STEPSIZE.
1272C-------------------------------------------------------
1273C
1274500 CONTINUE
1275C CHECK FOR FAILURE TO COMPUTE INITIAL YPRIME
1276 IF (idid .EQ. -12) GO TO 527
1277C
1278C CHECK FOR TOO MANY STEPS
1279 IF((iwork(lnst)-iwork(lnstl)).LT.iwork(lmxstp))
1280 * GO TO 510
1281 idid=-1
1282 GO TO 527
1283C
1284C UPDATE WT
1285510 CALL ddawts(neq,info(2),rtol,atol,rwork(lphi),
1286 * rwork(lwt),rpar,ipar)
1287 DO 520 i=1,neq
1288 IF(rwork(i+lwt-1).GT.0.0d0)GO TO 520
1289 idid=-3
1290 GO TO 527
1291520 CONTINUE
1292C
1293C TEST FOR TOO MUCH ACCURACY REQUESTED.
1294 r=ddanrm(neq,rwork(lphi),rwork(lwt),rpar,ipar)*
1295 * 100.0d0*uround
1296 IF(r.LE.1.0d0)GO TO 525
1297C MULTIPLY RTOL AND ATOL BY R AND RETURN
1298 IF(info(2).EQ.1)GO TO 523
1299 rtol(1)=r*rtol(1)
1300 atol(1)=r*atol(1)
1301 idid=-2
1302 GO TO 527
1303523 DO 524 i=1,neq
1304 rtol(i)=r*rtol(i)
1305524 atol(i)=r*atol(i)
1306 idid=-2
1307 GO TO 527
1308525 CONTINUE
1309C
1310C COMPUTE MINIMUM STEPSIZE
1311 hmin=4.0d0*uround*max(abs(tn),abs(tout))
1312C
1313C TEST H VS. HMAX
1314 IF (info(7) .EQ. 0) GO TO 526
1315 rh = abs(h)/rwork(lhmax)
1316 IF (rh .GT. 1.0d0) h = h/rh
1317526 CONTINUE
1318C
1319 CALL ddastp(tn,y,yprime,neq,
1320 * res,jac,h,rwork(lwt),info(1),idid,rpar,ipar,
1321 * rwork(lphi),rwork(ldelta),rwork(le),
1322 * rwork(lwm),iwork(liwm),
1323 * rwork(lalpha),rwork(lbeta),rwork(lgamma),
1324 * rwork(lpsi),rwork(lsigma),
1325 * rwork(lcj),rwork(lcjold),rwork(lhold),
1326 * rwork(ls),hmin,rwork(lround),
1327 * iwork(lphase),iwork(ljcalc),iwork(lk),
1328 * iwork(lkold),iwork(lns),info(10),ntemp)
1329527 IF(idid.LT.0)GO TO 600
1330C
1331C--------------------------------------------------------
1332C THIS BLOCK HANDLES THE CASE OF A SUCCESSFUL RETURN
1333C FROM DDASTP (IDID=1). TEST FOR STOP CONDITIONS.
1334C--------------------------------------------------------
1335C
1336 IF(info(4).NE.0)GO TO 540
1337 IF(info(3).NE.0)GO TO 530
1338 IF((tn-tout)*h.LT.0.0d0)GO TO 500
1339 CALL ddatrp(tn,tout,y,yprime,neq,
1340 * iwork(lkold),rwork(lphi),rwork(lpsi))
1341 idid=3
1342 t=tout
1343 GO TO 580
1344530 IF((tn-tout)*h.GE.0.0d0)GO TO 535
1345 t=tn
1346 idid=1
1347 GO TO 580
1348535 CALL ddatrp(tn,tout,y,yprime,neq,
1349 * iwork(lkold),rwork(lphi),rwork(lpsi))
1350 idid=3
1351 t=tout
1352 GO TO 580
1353540 IF(info(3).NE.0)GO TO 550
1354 IF((tn-tout)*h.LT.0.0d0)GO TO 542
1355 CALL ddatrp(tn,tout,y,yprime,neq,
1356 * iwork(lkold),rwork(lphi),rwork(lpsi))
1357 t=tout
1358 idid=3
1359 GO TO 580
1360542 IF(abs(tn-tstop).LE.100.0d0*uround*
1361 * (abs(tn)+abs(h)))GO TO 545
1362 tnext=tn+h
1363 IF((tnext-tstop)*h.LE.0.0d0)GO TO 500
1364 h=tstop-tn
1365 GO TO 500
1366545 CALL ddatrp(tn,tstop,y,yprime,neq,
1367 * iwork(lkold),rwork(lphi),rwork(lpsi))
1368 idid=2
1369 t=tstop
1370 GO TO 580
1371550 IF((tn-tout)*h.GE.0.0d0)GO TO 555
1372 IF(abs(tn-tstop).LE.100.0d0*uround*(abs(tn)+abs(h)))GO TO 552
1373 t=tn
1374 idid=1
1375 GO TO 580
1376552 CALL ddatrp(tn,tstop,y,yprime,neq,
1377 * iwork(lkold),rwork(lphi),rwork(lpsi))
1378 idid=2
1379 t=tstop
1380 GO TO 580
1381555 CALL ddatrp(tn,tout,y,yprime,neq,
1382 * iwork(lkold),rwork(lphi),rwork(lpsi))
1383 t=tout
1384 idid=3
1385 GO TO 580
1386C
1387C--------------------------------------------------------
1388C ALL SUCCESSFUL RETURNS FROM DDASSL ARE MADE FROM
1389C THIS BLOCK.
1390C--------------------------------------------------------
1391C
1392580 CONTINUE
1393 rwork(ltn)=tn
1394 rwork(lh)=h
1395 RETURN
1396C
1397C-----------------------------------------------------------------------
1398C THIS BLOCK HANDLES ALL UNSUCCESSFUL
1399C RETURNS OTHER THAN FOR ILLEGAL INPUT.
1400C-----------------------------------------------------------------------
1401C
1402600 CONTINUE
1403 itemp=-idid
1404 GO TO (610,620,630,690,690,640,650,660,670,675,
1405 * 680,685), itemp
1406C
1407C THE MAXIMUM NUMBER OF STEPS WAS TAKEN BEFORE
1408C REACHING TOUT
1409610 WRITE (xern3, '(1P,D15.6)') tn
1410 CALL xermsg ('SLATEC', 'DDASSL',
1411 * 'AT CURRENT T = ' // xern3 // ' 500 STEPS TAKEN ON THIS ' //
1412 * 'CALL BEFORE REACHING TOUT', idid, 1)
1413 GO TO 690
1414C
1415C TOO MUCH ACCURACY FOR MACHINE PRECISION
1416620 WRITE (xern3, '(1P,D15.6)') tn
1417 CALL xermsg ('SLATEC', 'DDASSL',
1418 * 'AT T = ' // xern3 // ' TOO MUCH ACCURACY REQUESTED FOR ' //
1419 * 'PRECISION OF MACHINE. RTOL AND ATOL WERE INCREASED TO ' //
1420 * 'APPROPRIATE VALUES', idid, 1)
1421 GO TO 690
1422C
1423C WT(I) .LE. 0.0 FOR SOME I (NOT AT START OF PROBLEM)
1424630 WRITE (xern3, '(1P,D15.6)') tn
1425 CALL xermsg ('SLATEC', 'DDASSL',
1426 * 'AT T = ' // xern3 // .LE.' SOME ELEMENT OF WT HAS BECOME ' //
1427 * '0.0', idid, 1)
1428 GO TO 690
1429C
1430C ERROR TEST FAILED REPEATEDLY OR WITH H=HMIN
1431640 WRITE (xern3, '(1P,D15.6)') tn
1432 WRITE (xern4, '(1P,D15.6)') h
1433 CALL xermsg ('SLATEC', 'DDASSL',
1434 * 'AT T = ' // xern3 // ' AND STEPSIZE H = ' // xern4 //
1435 * ' THE ERROR TEST FAILED REPEATEDLY OR WITH ABS(H)=HMIN',
1436 * idid, 1)
1437 GO TO 690
1438C
1439C CORRECTOR CONVERGENCE FAILED REPEATEDLY OR WITH H=HMIN
1440650 WRITE (xern3, '(1P,D15.6)') tn
1441 WRITE (xern4, '(1P,D15.6)') h
1442 CALL xermsg ('SLATEC', 'DDASSL',
1443 * 'AT T = ' // xern3 // ' AND STEPSIZE H = ' // xern4 //
1444 * ' THE CORRECTOR FAILED TO CONVERGE REPEATEDLY OR WITH ' //
1445 * 'ABS(H)=HMIN', idid, 1)
1446 GO TO 690
1447C
1448C THE ITERATION MATRIX IS SINGULAR
1449660 WRITE (xern3, '(1P,D15.6)') tn
1450 WRITE (xern4, '(1P,D15.6)') h
1451 CALL xermsg ('SLATEC', 'DDASSL',
1452 * 'AT T = ' // xern3 // ' AND STEPSIZE H = ' // xern4 //
1453 * ' THE ITERATION MATRIX IS SINGULAR', idid, 1)
1454 GO TO 690
1455C
1456C CORRECTOR FAILURE PRECEEDED BY ERROR TEST FAILURES.
1457670 WRITE (xern3, '(1P,D15.6)') tn
1458 WRITE (xern4, '(1P,D15.6)') h
1459 CALL xermsg ('SLATEC', 'DDASSL',
1460 * 'AT T = ' // xern3 // ' AND STEPSIZE H = ' // xern4 //
1461 * ' THE CORRECTOR COULD NOT CONVERGE. ALSO, THE ERROR TEST ' //
1462 * 'FAILED REPEATEDLY.', idid, 1)
1463 GO TO 690
1464C
1465C CORRECTOR FAILURE BECAUSE IRES = -1
1466675 WRITE (xern3, '(1P,D15.6)') tn
1467 WRITE (xern4, '(1P,D15.6)') h
1468 CALL xermsg ('SLATEC', 'DDASSL',
1469 * 'AT T = ' // xern3 // ' AND STEPSIZE H = ' // xern4 //
1470 * ' THE CORRECTOR COULD NOT CONVERGE BECAUSE IRES WAS EQUAL ' //
1471 * 'TO MINUS ONE', idid, 1)
1472 GO TO 690
1473C
1474C FAILURE BECAUSE IRES = -2
1475680 WRITE (xern3, '(1P,D15.6)') tn
1476 WRITE (xern4, '(1P,D15.6)') h
1477 CALL xermsg ('SLATEC', 'DDASSL',
1478 * 'AT T = ' // xern3 // ' AND STEPSIZE H = ' // xern4 //
1479 * ' IRES WAS EQUAL TO MINUS TWO', idid, 1)
1480 GO TO 690
1481C
1482C FAILED TO COMPUTE INITIAL YPRIME
1483685 WRITE (xern3, '(1P,D15.6)') tn
1484 WRITE (xern4, '(1P,D15.6)') ho
1485 CALL xermsg ('SLATEC', 'DDASSL',
1486 * 'AT T = ' // xern3 // ' AND STEPSIZE H = ' // xern4 //
1487 * ' THE INITIAL YPRIME COULD NOT BE COMPUTED', idid, 1)
1488 GO TO 690
1489C
1490690 CONTINUE
1491 info(1)=-1
1492 t=tn
1493 rwork(ltn)=tn
1494 rwork(lh)=h
1495 RETURN
1496C
1497C-----------------------------------------------------------------------
1498C THIS BLOCK HANDLES ALL ERROR RETURNS DUE
1499C TO ILLEGAL INPUT, AS DETECTED BEFORE CALLING
1500C DDASTP. FIRST THE ERROR MESSAGE ROUTINE IS
1501C CALLED. IF THIS HAPPENS TWICE IN
1502C SUCCESSION, EXECUTION IS TERMINATED
1503C
1504C-----------------------------------------------------------------------
1505701 CALL xermsg ('SLATEC', 'DDASSL',
1506 * 'SOME ELEMENT OF INFO VECTOR IS NOT ZERO OR ONE', 1, 1)
1507 GO TO 750
1508C
1509702 WRITE (xern1, '(I8)') neq
1510 CALL xermsg ('SLATEC', 'DDASSL',
1511 * 'NEQ = ' // xern1 // .LE.' 0', 2, 1)
1512 GO TO 750
1513C
1514703 WRITE (xern1, '(I8)') mxord
1515 CALL xermsg ('SLATEC', 'DDASSL',
1516 * 'MAXORD = ' // xern1 // ' NOT IN RANGE', 3, 1)
1517 GO TO 750
1518C
1519704 WRITE (xern1, '(I8)') lenrw
1520 WRITE (xern2, '(I8)') lrw
1521 CALL xermsg ('SLATEC', 'DDASSL',
1522 * 'RWORK LENGTH NEEDED, LENRW = ' // xern1 //
1523 * ', EXCEEDS LRW = ' // xern2, 4, 1)
1524 GO TO 750
1525C
1526705 WRITE (xern1, '(I8)') leniw
1527 WRITE (xern2, '(I8)') liw
1528 CALL xermsg ('SLATEC', 'DDASSL',
1529 * 'IWORK LENGTH NEEDED, LENIW = ' // xern1 //
1530 * ', EXCEEDS LIW = ' // xern2, 5, 1)
1531 GO TO 750
1532C
1533706 CALL xermsg ('SLATEC', 'DDASSL',
1534 * .LT.'SOME ELEMENT OF RTOL IS 0', 6, 1)
1535 GO TO 750
1536C
1537707 CALL xermsg ('SLATEC', 'DDASSL',
1538 * .LT.'SOME ELEMENT OF ATOL IS 0', 7, 1)
1539 GO TO 750
1540C
1541708 CALL xermsg ('SLATEC', 'DDASSL',
1542 * 'ALL ELEMENTS OF RTOL AND ATOL ARE ZERO', 8, 1)
1543 GO TO 750
1544C
1545709 WRITE (xern3, '(1P,D15.6)') tstop
1546 WRITE (xern4, '(1P,D15.6)') tout
1547 CALL xermsg ('SLATEC', 'DDASSL',
1548 * 'INFO(4) = 1 AND TSTOP = ' // xern3 // ' BEHIND TOUT = ' //
1549 * xern4, 9, 1)
1550 GO TO 750
1551C
1552710 WRITE (xern3, '(1P,D15.6)') hmax
1553 CALL xermsg ('SLATEC', 'DDASSL',
1554 * 'HMAX = ' // xern3 // .LT.' 0.0', 10, 1)
1555 GO TO 750
1556C
1557711 WRITE (xern3, '(1P,D15.6)') tout
1558 WRITE (xern4, '(1P,D15.6)') t
1559 CALL xermsg ('SLATEC', 'DDASSL',
1560 * 'TOUT = ' // xern3 // ' BEHIND T = ' // xern4, 11, 1)
1561 GO TO 750
1562C
1563712 CALL xermsg ('SLATEC', 'DDASSL',
1564 * 'INFO(8)=1 AND H0=0.0', 12, 1)
1565 GO TO 750
1566C
1567713 CALL xermsg ('SLATEC', 'DDASSL',
1568 * .LE.'SOME ELEMENT OF WT IS 0.0', 13, 1)
1569 GO TO 750
1570C
1571714 WRITE (xern3, '(1P,D15.6)') tout
1572 WRITE (xern4, '(1P,D15.6)') t
1573 CALL xermsg ('SLATEC', 'DDASSL',
1574 * 'TOUT = ' // xern3 // ' TOO CLOSE TO T = ' // xern4 //
1575 * ' TO START INTEGRATION', 14, 1)
1576 GO TO 750
1577C
1578715 WRITE (xern3, '(1P,D15.6)') tstop
1579 WRITE (xern4, '(1P,D15.6)') t
1580 CALL xermsg ('SLATEC', 'DDASSL',
1581 * 'INFO(4)=1 AND TSTOP = ' // xern3 // ' BEHIND T = ' // xern4,
1582 * 15, 1)
1583 GO TO 750
1584C
1585716 WRITE (xern1, '(I8)') mxstp
1586 CALL xermsg ('SLATEC', 'DDASSL',
1587 * 'INFO(12)=1 AND MXSTP = ' // xern1 // ' ILLEGAL.', 3, 1)
1588 GO TO 750
1589C
1590717 WRITE (xern1, '(I8)') iwork(lml)
1591 CALL xermsg ('SLATEC', 'DDASSL',
1592 * 'ML = ' // xern1 // .LT..GT.' ILLEGAL. EITHER 0 OR NEQ',
1593 * 17, 1)
1594 GO TO 750
1595C
1596718 WRITE (xern1, '(I8)') iwork(lmu)
1597 CALL xermsg ('SLATEC', 'DDASSL',
1598 * 'MU = ' // xern1 // .LT..GT.' ILLEGAL. EITHER 0 OR NEQ',
1599 * 18, 1)
1600 GO TO 750
1601C
1602719 WRITE (xern3, '(1P,D15.6)') tout
1603 CALL xermsg ('SLATEC', 'DDASSL',
1604 * 'TOUT = T = ' // xern3, 19, 1)
1605 GO TO 750
1606C
1607750 idid=-33
1608 IF(info(1).EQ.-1) THEN
1609 CALL xermsg ('SLATEC', 'DDASSL',
1610 * 'REPEATED OCCURRENCES OF ILLEGAL INPUT$$' //
1611 * 'RUN TERMINATED. APPARENT INFINITE LOOP', -999, 2)
1612 ENDIF
1613C
1614 info(1)=-1
1615 RETURN
1616C-----------END OF SUBROUTINE DDASSL------------------------------------
1617 END
charNDArray max(char d, const charNDArray &m)
Definition chNDArray.cc:230
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 ddassl(res, neq, t, y, yprime, tout, info, rtol, atol, idid, rwork, lrw, iwork, liw, rpar, ipar, jac)
Definition ddassl.f:3
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
double lgamma(double x)
Definition lo-specfun.h:336
subroutine xermsg(librar, subrou, messg, nerr, level)
Definition xermsg.f:3