hide long namesshow long names
hide short namesshow short names
Integer type:  int32  int64  nag_int  show int32  show int32  show int64  show int64  show nag_int  show nag_int

PDF version (NAG web site, 64-bit version, 64-bit version)
Chapter Contents
Chapter Introduction
NAG Toolbox

NAG Toolbox: nag_ode_ivp_stiff_imp_revcom (d02nn)

Purpose

nag_ode_ivp_stiff_imp_revcom (d02nn) is a reverse communication function for integrating stiff systems of implicit ordinary differential equations coupled with algebraic equations.

Syntax

[t, tout, y, ydot, rwork, inform, ysav, wkjac, jacpvt, imon, inln, ires, irevcm, lderiv, ifail] = d02nn(t, tout, y, ydot, rwork, rtol, atol, itol, inform, ysav, wkjac, jacpvt, imon, inln, ires, irevcm, lderiv, itask, itrace, 'neq', neq, 'sdysav', sdysav, 'nwkjac', nwkjac)
[t, tout, y, ydot, rwork, inform, ysav, wkjac, jacpvt, imon, inln, ires, irevcm, lderiv, ifail] = nag_ode_ivp_stiff_imp_revcom(t, tout, y, ydot, rwork, rtol, atol, itol, inform, ysav, wkjac, jacpvt, imon, inln, ires, irevcm, lderiv, itask, itrace, 'neq', neq, 'sdysav', sdysav, 'nwkjac', nwkjac)
Note: the interface to this routine has changed since earlier releases of the toolbox:
Mark 22: njcpvt has been removed from the interface; neq has been made optional
.

Description

nag_ode_ivp_stiff_imp_revcom (d02nn) is a general purpose function for integrating the initial value problem for a stiff system of implicit ordinary differential equations coupled with algebraic equations, written in the form
A(t,y)y = g(t,y).
A(t,y)y=g(t,y).
An outline of a typical calling program is given below:
% 
% data initialization
% 
call linear algebra setup routine 
call integrator setup routine 
irevcm = int64(0);
[..., irevcm, ...] = d02nn();
while (irevcm > 0)
  if (irevcm > 7 and irevcm < 11)
    if (irevcm == 8)
      supply the jacobian matrix                              (i)
    elseif (irevcm == 9)
      perform monitoring tasks requested by the user         (ii)
    elseif (irevcm == 10)
      indicates an unsuccessful step 
    end
  else
    evaluate the residual                                   (iii)
  end 
  [..., irevcm, ...] = d02nn();
end
% 
% post processing (optional linear algebra diagnostic call 
% (sparse case only), optional integrator diagnostic call) 
%
There are three major operations that may be required of the calling function on an intermediate return (irevcm0irevcm0) from nag_ode_ivp_stiff_imp_revcom (d02nn); these are denoted (i), (ii) and (iii).
The following sections describe in greater detail exactly what is required of each of these operations.
(i) Supply the Jacobian matrix
You need only provide this facility if the parameter jceval = 'A'jceval='A' (or jceval = 'F'jceval='F' if using sparse matrix linear algebra) in a call to the linear algebra setup function (see jceval in nag_ode_ivp_stiff_sparjac_setup (d02nu)). If the Jacobian matrix is to be evaluated numerically by the integrator, then the remainder of section (i) can be ignored.
We must define the system of nonlinear equations which is solved internally by the integrator. The time derivative, yy, has the form
y = (yz) / (hd),
y=(y-z)/(hd),
where hh is the current step size and dd is a parameter that depends on the integration method in use. The vector yy is the current solution and the vector zz depends on information from previous time steps. This means that d/(dy) (​ ​) = (hd) d/(dy) (​ ​) d dy (​ ​) = (hd) ddy (​ ​) .
The system of nonlinear equations that is solved has the form
A(t,y)yg(t,y) = 0
A(t,y)y-g(t,y)=0
but is solved in the form
f(t,y) = 0 ,
f(t,y) = 0 ,
where ff is the function defined by
f(t,y) = (hd) (A (t,y) (yz) / (hd) g(t,y)) .
f(t,y) = (hd) (A (t,y) (y-z) / (hd) - g(t,y)) .
It is the Jacobian matrix (r)/(y) r y  that you must supply as follows:
(fi)/(yj) = aij(t,y) + hd()/(yj)
(neq )
aik(t,y)ykgi(t,y)
k = 1
,
fi yj = aij(t,y)+hd yj (k=1neqaik(t,y)yk-gi(t,y)) ,
where tt, hh and dd are located in rwork(19)rwork19, rwork(16)rwork16 and rwork(20)rwork20 respectively and the arrays y and ydot contain the current solution and time derivatives respectively. Only the nonzero elements of the Jacobian need be set, since the locations where it is to be stored are preset to zero.
Hereafter in this document this operation will be referred to as jac.
(ii) Perform tasks requested by you
This operation is essentially a monitoring function and additionally provides the opportunity of changing the current values of y, ydot, hnext (the step size that the integrator proposes to take on the next step), hmin (the minimum step size to be taken on the next step), and hmax (the maximum step size to be taken on the next step). The scaled local error at the end of a time step may be obtained by calling the double function nag_ode_ivp_stiff_errest (d02za) as follows:
[errloc, ifail] = d02za(rwork(51+neqmax:51+neqmax+neq-1), rwork(51:51+neq-1));
% Check ifail before proceeding
The following gives details of the location within the array rwork of variables that may be of interest to you:
Variable Specification Location
tcurr the current value of the independent variable rwork(19)rwork19
hlast last step size successfully used by the integrator rwork(15)rwork15
hnext step size that the integrator proposes to take on the next step rwork(16)rwork16
hmin minimum step size to be taken on the next step rwork(17)rwork17
hmax maximum step size to be taken on the next step rwork(18)rwork18
nqu the order of the integrator used on the last step rwork(10)rwork10
You are advised to consult the description of monitr in nag_ode_ivp_stiff_imp_fulljac (d02ng) for details on what optional input can be made.
If either y or ydot are changed, then imon must be set to 22 before return to nag_ode_ivp_stiff_imp_revcom (d02nn). If either of the values hmin or hmax are changed, then imon must be set 33 before return to nag_ode_ivp_stiff_imp_revcom (d02nn). If hnext is changed, then imon must be set to 44 before return to nag_ode_ivp_stiff_imp_revcom (d02nn).
In addition you can force nag_ode_ivp_stiff_imp_revcom (d02nn) to evaluate the residual vector
A(t,y)yg(t,y)
A(t,y)y-g(t,y)
by setting imon = 0imon=0 and inln = 3inln=3 and then returning to nag_ode_ivp_stiff_imp_revcom (d02nn); on return to this monitoring operation the residual vector will be stored in rwork(50 + 2 × neq + i)rwork50+2×neq+i, for i = 1,2,,neqi=1,2,,neq.
Hereafter in this document this operation will be referred to as monitr.
(iii) Evaluate the residual
This operation must evaluate the residual
r = g(t,y) A(t,y) y
-r = g(t,y) - A(t,y) y
(1)
in one case and the reduced residual
= A(t,y) y
-r^ = -A(t,y) y
(2)
in another, where tt is located in rwork(19)rwork19. The form of the residual that is returned is determined by the value of ires returned by nag_ode_ivp_stiff_imp_revcom (d02nn). If ires = 1ires=-1, then the residual defined by equation (2) above must be returned; if ires = 1ires=1, then the residual returned by equation (1) above must be returned.
Hereafter in this document this operation will be referred to as resid.

References

See the D02M–N sub-chapter Introduction.

Parameters

Note: this function uses reverse communication. Its use involves an initial entry, intermediate exits and re-entries, and a final exit, as indicated by the parameter irevcm. Between intermediate exits and re-entries, all parameters other than ydot, rwork, wkjac, imon, inln and ires must remain unchanged.

Compulsory Input Parameters

1:     t – double scalar
On initial entry: tt, the value of the independent variable. The input value of t is used only on the first call as the initial point of the integration.
2:     tout – double scalar
On initial entry: the next value of tt at which a computed solution is desired. For the initial tt, the input value of tout is used to determine the direction of integration. Integration is permitted in either direction (see also itask).
Constraint: toutttoutt.
3:     y(neq) – double array
neq, the dimension of the array, must satisfy the constraint neq1neq1.
On initial entry: the values of the dependent variables (solution). On the first call the first neq elements of yy must contain the vector of initial values.
4:     ydot(neq) – double array
neq, the dimension of the array, must satisfy the constraint neq1neq1.
On initial entry: if lderiv(1) = truelderiv1=true, ydot must contain approximations to the time derivatives yy of the vector yy. If lderiv(1) = falselderiv1=false, then ydot need not be set on entry.
5:     rwork(50 + 4 × neq50+4×neq) – double array
On initial entry: must be the same array as used by one of the method setup functions nag_ode_ivp_stiff_dassl (d02mv), nag_ode_ivp_stiff_bdf (d02nv) or nag_ode_ivp_stiff_blend (d02nw), and by one of the storage setup functions nag_ode_ivp_stiff_fulljac_setup (d02ns), nag_ode_ivp_stiff_bandjac_setup (d02nt) or nag_ode_ivp_stiff_sparjac_setup (d02nu). The contents of rwork must not be changed between any call to a setup function and the first call to nag_ode_ivp_stiff_imp_revcom (d02nn).
On intermediate re-entry: must contain residual evaluations as described under the parameter irevcm.
6:     rtol( : :) – double array
Note: the dimension of the array rtol must be at least 11 if itol = 1itol=1 or 22, and at least neqneq otherwise.
On initial entry: the relative local error tolerance.
Constraint: rtol(i)0.0rtoli0.0 for all relevant ii (see itol).
7:     atol( : :) – double array
Note: the dimension of the array atol must be at least 11 if itol = 1itol=1 or 33, and at least neqneq otherwise.
On initial entry: the absolute local error tolerance.
Constraint: atol(i)0.0atoli0.0 for all relevant ii (see itol).
8:     itol – int64int32nag_int scalar
On initial entry: a value to indicate the form of the local error test. itol indicates to nag_ode_ivp_stiff_imp_revcom (d02nn) whether to interpret either or both of rtol or atol as a vector or a scalar. The error test to be satisfied is ei / wi < 1.0ei/wi<1.0, where wiwi is defined as follows:
itol rtol atol wiwi
1 scalar scalar rtol(1) × |yi| + atol(1)rtol1×|yi|+atol1
2 scalar vector rtol(1) × |yi| + atol(i)rtol1×|yi|+atoli
3 vector scalar rtol(i) × |yi| + atol(1)rtoli×|yi|+atol1
4 vector vector rtol(i) × |yi| + atol(i)rtoli×|yi|+atoli
eiei is an estimate of the local error in yiyi, computed internally, and the choice of norm to be used is defined by a previous call to an integrator setup function.
Constraint: itol = 1itol=1, 22, 33 or 44.
9:     inform(2323) – int64int32nag_int array
10:   ysav(ldysav,sdysav) – double array
11:   wkjac(nwkjac) – double array
On intermediate re-entry: elements of the Jacobian as defined under the description of irevcm. If a numerical Jacobian was requested then wkjac is used for workspace.
12:   jacpvt(njcpvt) – int64int32nag_int array
On initial entry: the dimension of the array jacpvt as declared in the (sub)program from which nag_ode_ivp_stiff_imp_revcom (d02nn) is called. The actual size depends on the linear algebra method used. An appropriate value for njcpvt is described in the specifications of the linear algebra setup functions nag_ode_ivp_stiff_bandjac_setup (d02nt) and nag_ode_ivp_stiff_sparjac_setup (d02nu) for banded and sparse matrix linear algebra respectively. This value must be the same as that supplied to the linear algebra setup function. When full matrix linear algebra is chosen, the array jacpvt is not used and hence njcpvt should be set to 11.
13:   imon – int64int32nag_int scalar
On intermediate re-entry: may be reset to determine subsequent action in nag_ode_ivp_stiff_imp_revcom (d02nn).
imon = 2imon=-2
Integration is to be halted. A return will be made from nag_ode_ivp_stiff_imp_revcom (d02nn) to the calling (sub)program with ifail = 12ifail=12.
imon = 1imon=-1
Allow nag_ode_ivp_stiff_imp_revcom (d02nn) to continue with its own internal strategy. The integrator will try up to three restarts unless imon1imon-1.
imon = 0imon=0
Return to the internal nonlinear equation solver, where the action taken is determined by the value of inln.
imon = 1imon=1
Normal exit to nag_ode_ivp_stiff_imp_revcom (d02nn) to continue integration.
imon = 2imon=2
Restart the integration at the current time point. The integrator will restart from order 11 when this option is used. The internal initialization module solves for new values of yy and yy by using the values supplied in y and ydot by the monitr operation (see Section [Description]) as initial estimates.
imon = 3imon=3
Try to continue with the same step size and order as was to be used before entering the monitr operation (see Section [Description]). hmin and hmax may be altered if desired.
imon = 4imon=4
Continue the integration but using a new value of hnext and possibly new values of hmin and hmax.
14:   inln – int64int32nag_int scalar
On intermediate re-entry: with imon = 0imon=0 and irevcm = 9irevcm=9, inln specifies the action to be taken by the internal nonlinear equation solver. By setting inln = 3inln=3 and returning to nag_ode_ivp_stiff_imp_revcom (d02nn), the residual vector is evaluated and placed in rwork(50 + 2 × neq + i)rwork50+2×neq+i, for i = 1,2,,neqi=1,2,,neq and then the monitr operation (see Section [Description]) is invoked again. At present this is the only option available: inln must not be set to any other value.
15:   ires – int64int32nag_int scalar
On intermediate re-entry: should be unchanged unless one of the following actions is required of nag_ode_ivp_stiff_imp_revcom (d02nn) in which case ires should be set accordingly.
ires = 2ires=2
Indicates to nag_ode_ivp_stiff_imp_revcom (d02nn) that control should be passed back immediately to the calling (sub)program with the error indicator set to ifail = 11ifail=11.
ires = 3ires=3
Indicates to nag_ode_ivp_stiff_imp_revcom (d02nn) that an error condition has occurred in the solution vector, its time derivative or in the value of tt. The integrator will use a smaller time step to try to avoid this condition. If this is not possible nag_ode_ivp_stiff_imp_revcom (d02nn) returns to the calling (sub)program with the error indicator set to ifail = 7ifail=7.
ires = 4ires=4
Indicates to nag_ode_ivp_stiff_imp_revcom (d02nn) to stop its current operation and to enter the monitr operation (see Section [Description]) immediately.
16:   irevcm – int64int32nag_int scalar
On initial entry: must contain 00.
On intermediate re-entry: should remain unchanged.
Constraint: 0irevcm110irevcm11.
17:   lderiv(22) – logical array
On initial entry: lderiv(1)lderiv1 must be set to true if you have supplied both an initial yy and an initial yy. lderiv(1)lderiv1 must be set to false if only the initial yy has been supplied.
lderiv(2)lderiv2 must be set to true if the integrator is to use a modified Newton method to evaluate the initial yy and yy. Note that yy and yy, if supplied, are used as initial estimates. This method involves taking a small step at the start of the integration, and if itask = 6itask=6 on entry, t and tout will be set to the result of taking this small step. lderiv(2)lderiv2 must be set to false if the integrator is to use functional iteration to evaluate the initial yy and yy, and if this fails a modified Newton method will then be attempted. lderiv(2) = truelderiv2=true is recommended if there are implicit equations or the initial yy and yy are zero.
18:   itask – int64int32nag_int scalar
On initial entry: the task to be performed by the integrator.
itask = 1itask=1
Normal computation of output values of y(t)y(t) at t = toutt=tout (by overshooting and interpolating).
itask = 2itask=2
Take one step only and return.
itask = 3itask=3
Stop at the first internal integration point at or beyond t = toutt=tout and return.
itask = 4itask=4
Normal computation of output values of y(t)y(t) at t = toutt=tout but without overshooting t = tcritt=tcrit. tcrit must be specified as an option in one of the integrator setup functions before the first call to the integrator, or specified in the optional input function before a continuation call. tcrit (e.g., see nag_ode_ivp_stiff_bdf (d02nv)) may be equal to or beyond tout, but not before it in the direction of integration.
itask = 5itask=5
Take one step only and return, without passing tcrit (e.g., see nag_ode_ivp_stiff_bdf (d02nv)). tcrit must be specified under itask = 4itask=4.
itask = 6itask=6
The integrator will solve for the initial values of yy and yy only and then return to the calling (sub)program without doing the integration. This option can be used to check the initial values of yy and yy. Functional iteration or a ‘small’ backward Euler method used in conjunction with a damped Newton iteration is used to calculate these values (see lderiv). Note that if a backward Euler step is used then the value of tt will have been advanced a short distance from the initial point.
Note:  if nag_ode_ivp_stiff_imp_revcom (d02nn) is recalled with a different value of itask (and tout altered) then the initialization procedure is repeated, possibly leading to different initial conditions.
Constraint: 1itask61itask6.
19:   itrace – int64int32nag_int scalar
On initial entry: the level of output that is printed by the integrator. itrace may take the value 1-1, 00, 11, 22 or 33.
itrace < 1itrace<-1
1-1 is assumed and similarly if itrace > 3itrace>3, then 33 is assumed.
itrace = 1itrace=-1
No output is generated.
itrace = 0itrace=0
Only warning messages are printed on the current error message unit (see nag_file_set_unit_error (x04aa)).
itrace > 0itrace>0
Warning messages are printed as above, and on the current advisory message unit (see nag_file_set_unit_advisory (x04ab)) output is generated which details Jacobian entries, the nonlinear iteration and the time integration. The advisory messages are given in greater detail the larger the value of itrace.

Optional Input Parameters

1:     neq – int64int32nag_int scalar
Default: The dimension of the arrays y, ydot and the first dimension of the array ysav. (An error is raised if these dimensions are not equal.)
On initial entry: the number of equations to be solved.
Constraint: neq1neq1.
2:     sdysav – int64int32nag_int scalar
Default: The second dimension of the array ysav.
On initial entry: the second dimension of the array ysav as declared in the (sub)program from which nag_ode_ivp_stiff_imp_revcom (d02nn) is called. An appropriate value for sdysav is described in the specifications of the integrator setup functions nag_ode_ivp_stiff_dassl (d02mv), nag_ode_ivp_stiff_bdf (d02nv) and nag_ode_ivp_stiff_blend (d02nw). This value must be the same as that supplied to the integrator setup function.
3:     nwkjac – int64int32nag_int scalar
Default: The dimension of the array wkjac.
On initial entry: the dimension of the array wkjac as declared in the (sub)program from which nag_ode_ivp_stiff_imp_revcom (d02nn) is called. The actual size depends on the linear algebra method used. An appropriate value for nwkjac is described in the specifications of the linear algebra setup functions nag_ode_ivp_stiff_fulljac_setup (d02ns), nag_ode_ivp_stiff_bandjac_setup (d02nt) and nag_ode_ivp_stiff_sparjac_setup (d02nu) for full, banded and sparse matrix linear algebra respectively. This value must be the same as that supplied to the linear algebra setup function.

Input Parameters Omitted from the MATLAB Interface

ldysav njcpvt

Output Parameters

1:     t – double scalar
On final exit: the value at which the computed solution yy is returned (usually at tout).
2:     tout – double scalar
Is unaltered unless itask = 6itask=6 and lderiv(2) = truelderiv2=true on entry (see also itask and lderiv) in which case tout will be set to the result of taking a small step at the start of the integration.
3:     y(neq) – double array
On final exit: the computed solution vector evaluated at t (usually t = toutt=tout).
4:     ydot(neq) – double array
On final exit: contains the time derivatives yy of the vector yy at the last integration point.
5:     rwork(50 + 4 × neq50+4×neq) – double array
On intermediate exit: contains information for jac, resid and monitr operations as described under Section [Description] and the parameter irevcm.
6:     inform(2323) – int64int32nag_int array
7:     ysav(ldysav,sdysav) – double array
8:     wkjac(nwkjac) – double array
On intermediate exit: the Jacobian is overwritten.
9:     jacpvt(njcpvt) – int64int32nag_int array
10:   imon – int64int32nag_int scalar
On intermediate exit: used to pass information between nag_ode_ivp_stiff_imp_revcom (d02nn) and the monitr operation (see Section [Description]). With irevcm = 9irevcm=9, imon contains a flag indicating under what circumstances the return from nag_ode_ivp_stiff_imp_revcom (d02nn) occurred:
imon = 2imon=-2
Exit from nag_ode_ivp_stiff_imp_revcom (d02nn) after ires = 4ires=4 (set in the resid operation (see Section [Description]) caused an early termination (this facility could be used to locate discontinuities).
imon = 1imon=-1
The current step failed repeatedly.
imon = 0imon=0
Exit from nag_ode_ivp_stiff_imp_revcom (d02nn) after a call to the internal nonlinear equation solver.
imon = 1imon=1
The current step was successful.
11:   inln – int64int32nag_int scalar
On intermediate exit: contains a flag indicating the action to be taken, if any, by the internal nonlinear equation solver.
12:   ires – int64int32nag_int scalar
On intermediate exit: with irevcm = 1irevcm=1, 22, 33, 44, 55, 66, 77 or 1111, ires specifies the form of the residual to be returned by the resid operation (see Section [Description]).
If ires = 1ires=1, then r = g(t,y)A(t,y)y-r=g(t,y)-A(t,y)y must be returned.
If ires = 1ires=-1, then = A(t,y)y-r^=-A(t,y)y must be returned.
13:   irevcm – int64int32nag_int scalar
On intermediate exit: indicates what action you must take before re-entering nag_ode_ivp_stiff_imp_revcom (d02nn). The possible exit values of irevcm are 11, 22, 33, 44, 55, 66, 77, 88, 99, 1010 or 1111 which should be interpreted as follows:
irevcm = 1irevcm=1, 22, 33, 44, 55, 66, 77 or 1111
Indicates that a resid operation (see Section [Description]) is required: you must supply the residual of the system. For each of these values of irevcm, yiyi is located in y(i)yi, for i = 1,2,,neqi=1,2,,neq.
For irevcm = 1irevcm=1, 33, 66 or 1111, yiyi is located in ydot(i)ydoti and riri should be stored in rwork(50 + 2 × neq + i)rwork50+2×neq+i, for i = 1,2,,neqi=1,2,,neq.
For irevcm = 2irevcm=2, yiyi is located in rwork(50 + neq + i)rwork50+neq+i and riri should be stored in rwork(50 + 2 × neq + i)rwork50+2×neq+i, for i = 1,2,,neqi=1,2,,neq.
For irevcm = 4irevcm=4 or 77, yiyi is located in ydot(i)ydoti and riri should be stored in rwork(50 + neq + i)rwork50+neq+i, for i = 1,2,,neqi=1,2,,neq.
For irevcm = 5irevcm=5, yiyi is located in rwork(50 + 2 × neq + i)rwork50+2×neq+i and riri should be stored in ydot(i)ydoti, for i = 1,2,,neqi=1,2,,neq.
irevcm = 8irevcm=8
Indicates that a jac operation (see Section [Description]) is required: you must supply the Jacobian matrix.
If full matrix linear algebra is being used, then the (i,j)(i,j)th element of the Jacobian must be stored in wkjac((j1) × neq + i)wkjac((j-1)×neq+i).
If banded matrix linear algebra is being used, then the (i,j)(i,j)th element of the Jacobian
must be stored in wkjac((i1) × mB + k)wkjac((i-1)×mB+k), where mB = mL + mU + 1mB=mL+mU+1 and k = min (mLi + 1,0) + jk=min(mL-i+1,0)+j; here mLmL and mUmU are the number of subdiagonals and superdiagonals, respectively, in the band.
If sparse matrix linear algebra is being used, then nag_ode_ivp_stiff_sparjac_enq (d02nr) must be called to determine which column of the Jacobian is required and where it should be stored.
 [j, iplace] = d02nr(inform); 
will return in j the number of the column of the Jacobian that is required and will set iplace = 1iplace=1 or 22 (see nag_ode_ivp_stiff_sparjac_enq (d02nr)). If iplace = 1iplace=1, you must store the nonzero element (i,j)(i,j) of the Jacobian in rwork(50 + 2 × neq + i)rwork50+2×neq+i; otherwise it must be stored in rwork(50 + neq + i)rwork50+neq+i.
irevcm = 9irevcm=9
Indicates that a monitr operation (see Section [Description]) can be performed.
irevcm = 10irevcm=10
Indicates that the current step was not successful, due to error test failure or convergence test failure. The only information supplied to you on this return is the current value of the variable tt, located in rwork(19)rwork19. No values must be changed before re-entering nag_ode_ivp_stiff_imp_revcom (d02nn); this facility enables you to determine the number of unsuccessful steps.
On final exit: irevcm = 0irevcm=0 indicating that the user-specified task has been completed or an error has been encountered (see the descriptions for itask and ifail).
14:   lderiv(22) – logical array
On final exit: lderiv(1)lderiv1 is normally unchanged. However if itask = 6itask=6 and internal initialization was successful then lderiv(1) = truelderiv1=true.
lderiv(2) = truelderiv2=true, if implicit equations were detected. Otherwise lderiv(2) = falselderiv2=false.
15:   ifail – int64int32nag_int scalar
ifail = 0ifail=0 unless the function detects an error (see [Error Indicators and Warnings]).

Error Indicators and Warnings

Errors or warnings detected by the function:

Cases prefixed with W are classified as warnings and do not generate an error of type NAG:error_n. See nag_issue_warnings.

  ifail = 1ifail=1
On entry, the integrator detected an illegal input, or that a linear algebra and/or integrator setup function has not been called prior to the call to the integrator. If itrace0itrace0, the form of the error will be detailed on the current error message unit (see nag_file_set_unit_error (x04aa)).
  ifail = 2ifail=2
The maximum number of steps specified has been taken (see the description of optional inputs in the integrator setup functions and the optional input continuation function, nag_ode_ivp_stiff_contin (d02nz)).
W ifail = 3ifail=3
With the given values of rtol and atol no further progress can be made across the integration range from the current point t. The components y(1),y(2),,y(neq)y1,y2,,yneq contain the computed values of the solution at the current point t.
W ifail = 4ifail=4
There were repeated error test failures on an attempted step, before completing the requested task, but the integration was successful as far as t. The problem may have a singularity, or the local error requirements may be inappropriate.
W ifail = 5ifail=5
There were repeated convergence test failures on an attempted step, before completing the requested task, but the integration was successful as far as t. This may be caused by an inaccurate Jacobian matrix or one which is incorrectly computed.
W ifail = 6ifail=6
Some error weight wiwi became zero during the integration (see the description of itol). Pure relative error control (atol(i) = 0.0atoli=0.0) was requested on a variable (the iith) which has now vanished. The integration was successful as far as t.
  ifail = 7ifail=7
The resid operation (see Section [Description]) set the error flag ires = 3ires=3 continually despite repeated attempts by the integrator to avoid this.
  ifail = 8ifail=8
lderiv(1) = falselderiv1=false on entry but the internal initialization function was unable to initialize yy (more detailed information may be directed to the current error message unit, see nag_file_set_unit_error (x04aa)).
  ifail = 9ifail=9
A singular Jacobian (r)/(y) r y  has been encountered. You should check the problem formulation and Jacobian calculation.
  ifail = 10ifail=10
An error occurred during Jacobian formulation or back-substitution (a more detailed error description may be directed to the current error message unit, see nag_file_set_unit_error (x04aa)).
W ifail = 11ifail=11
The resid operation (see Section [Description]) signalled the integrator to halt the integration and return by setting ires = 2ires=2. Integration was successful as far as t.
W ifail = 12ifail=12
The monitr operation (see Section [Description]) set imon = 2imon=-2 and so forced a return but the integration was successful as far as t.
W ifail = 13ifail=13
The requested task has been completed, but it is estimated that a small change in rtol and atol is unlikely to produce any change in the computed solution. (Only applies when you are not operating in one step mode, that is when itask2itask2 or 55.)
  ifail = 14ifail=14
The values of rtol and atol are so small that nag_ode_ivp_stiff_imp_revcom (d02nn) is unable to start the integration.

Accuracy

The accuracy of the numerical solution may be controlled by a careful choice of the parameters rtol and atol, and to a much lesser extent by the choice of norm. You are advised to use scalar error control unless the components of the solution are expected to be poorly scaled. For the type of decaying solution typical of many stiff problems, relative error control with a small absolute error threshold will be most appropriate (that is, you are advised to choose itol = 1itol=1 with atol(1)atol1 small but positive).

Further Comments

The cost of computing a solution depends critically on the size of the differential system and to a lesser extent on the degree of stiffness of the problem; also on the type of linear algebra being used. For further details see Section [Further Comments] in (d02ng), (d02nh) and (d02nj) of the documents for nag_ode_ivp_stiff_imp_fulljac (d02ng) (full matrix), nag_ode_ivp_stiff_imp_bandjac (d02nh) (banded matrix) or nag_ode_ivp_stiff_imp_sparjac (d02nj) (sparse matrix).
In general, you are advised to choose the Backward Differentiation Formula option (setup function nag_ode_ivp_stiff_bdf (d02nv)) but if efficiency is of great importance and especially if it is suspected that ()/(y)(A1g) y (A-1g) has complex eigenvalues near the imaginary axis for some part of the integration, you should try the BLEND option (setup function nag_ode_ivp_stiff_blend (d02nw)).

Example

function nag_ode_ivp_stiff_imp_revcom_example
t = 0;
tout = 10;
y = [1; 0; 0];
ydot = [0; 0; 0];
rwork = zeros(62, 1);
rtol = [0.0001];
atol = [1e-07];
itol = int64(1);
inform = zeros(23, 1, 'int64');
ysave = zeros(3, 6);
wkjac = zeros(100,1);
jacpvt = zeros(150, 1, 'int64');
imon = int64(0);
inln = int64(0);
ires = int64(1);
irevcm = int64(0);
lderiv = [false; false];
itask = int64(3);
itrace = int64(0);
[const, rwork, ifail] = ...
    nag_ode_ivp_stiff_bdf(int64(3), int64(6), int64(5), 'Newton', false, zeros(6), ...
    0, 1e-10, 10, 0, int64(200), int64(5), 'Average-L2', rwork);
[jacpvt, rwork, ifail] = ...
    nag_ode_ivp_stiff_sparjac_setup(int64(3), int64(3), 'Analytical', int64(100), int64(0), ...
    int64(0), int64(150), 0, 0.1, 1e-4, true, rwork);

nfails = 0;

% indexes into rwork
neq    = 3;
neqmax = neq;
lacorb = neqmax + 50;
lsavrb = lacorb + neqmax;

fprintf('\n    x          y(1)           y(2)           y(3)\n');
fprintf(' %8.3f%13.5f  %13.5f  %13.5f\n', t, y);
first_time = true;
while (irevcm ~= 0 || first_time)
  first_time = false;
  [t, tout, y, ydot, rwork, inform, ysave, wkjac, ...
   jacpvt, imon, inln, ires, irevcm, lderiv, ifail] = ...
    nag_ode_ivp_stiff_imp_revcom(t, tout, y, ydot, rwork, rtol, atol, itol, inform, ...
    ysave, wkjac, jacpvt, imon, inln, ires, irevcm, lderiv, itask, itrace);

  if irevcm == 1 || irevcm == 3 || irevcm == 6 || irevcm == 11
    % Equivalent to resid evaluation in forward communication routines
    rwork(lsavrb+1) = -ydot(1) - ydot(2) - ydot(3);
    rwork(lsavrb+2) = -ydot(2);
    rwork(lsavrb+3) = -ydot(3);
    if (ires == 1)
      rwork(lsavrb+1) = rwork(lsavrb+1);
      rwork(lsavrb+2) = 0.04*y(1) - 1e4*y(2)*y(3) - 3e7*y(2)*y(2) + rwork(lsavrb+2);
      rwork(lsavrb+3) = 3e7*y(2)*y(2) + rwork(lsavrb+3);
    end
  elseif (irevcm == 2)
    % Equivalent to resid evaluation in forward communication routines
    rwork(lsavrb+1) = -rwork(lacorb+1) - rwork(lacorb+2) - rwork(lacorb+3);
    rwork(lsavrb+2) = -rwork(lacorb+2);
    rwork(lsavrb+3) = -rwork(lacorb+3);
  elseif (irevcm == 4 || irevcm == 7)
    % Equivalent to resid evaluation in forward communication routines
    rwork(lacorb+1) = -ydot(1) - ydot(2) - ydot(3);
    rwork(lacorb+2) = -ydot(2);
    rwork(lacorb+3) = -ydot(3);
    if (ires == 1)
      rwork(lacorb+1) = rwork(lacorb+1);
      rwork(lacorb+2) = 0.04*y(1) - 1e4*y(2)*y(3) - 3e7*y(2)*y(2) + rwork(lacorb+2);
      rwork(lacorb+3) = 3e7*y(2)*y(2) + rwork(lacorb+3);
    end
  elseif (irevcm == 5)
    % Equivalent to resid evaluation in forward communication routines
    ydot(1) = 0 - rwork(lsavrb+1) - rwork(lsavrb+2) - rwork(lsavrb+3);
    ydot(2) = 0.04*y(1) - 1e4*y(2)*y(3) - 3e7*y(2)*y(2) - rwork(lsavrb+2);
    ydot(3) = 3e7*y(2)*y(2) - rwork(lsavrb+3);
  elseif (irevcm == 8)
    % Equivalent to jac evaluation in forward communication routines
    [j, iplace] = nag_ode_ivp_stiff_sparjac_enq(inform);
    hxd = rwork(16)*rwork(20);
    if (iplace < 2)
      if (j < 2)
        rwork(lsavrb+1) = 1 - hxd*(0);
        rwork(lsavrb+2) = 0 - hxd*(0.04);
        rwork(lsavrb+3) = 0 - hxd*(0);
      elseif (j == 2)
        rwork(lsavrb+1) = 1 - hxd*(0);
        rwork(lsavrb+2) = 1 - hxd*(-1e4*y(3)-6e7*y(2));
        rwork(lsavrb+3) = 0 - hxd*(6e7*y(2));
      elseif (j > 2)
        rwork(lsavrb+1) = 1 - hxd*(0);
        rwork(lsavrb+2) = 0 - hxd*(-1e4*y(2));
        rwork(lsavrb+3) = 1 - hxd*(0);
      end
    else
      if (j < 2)
        rwork(lacorb+1) = 1 - hxd*(0);
        rwork(lacorb+2) = 0 - hxd*(0.04);
        rwork(lacorb+3) = 0 - hxd*(0);
      elseif (j == 2)
        rwork(lacorb+1) = 1 - hxd*(0);
        rwork(lacorb+2) = 1 - hxd*(-1e4*y(3)-6e7*y(2));
        rwork(lacorb+3) = 0 - hxd*(6e7*y(2));
      elseif (j > 2)
        rwork(lacorb+1) = 1 - hxd*(0);
        rwork(lacorb+2) = 0 - hxd*(-1e4*y(2));
        rwork(lacorb+3) = 1 - hxd*(0);
      end
    end
  elseif (irevcm == 10)
    % Step failure
    nfails = nfails + 1;
  end
end

if (ifail == 0)
  [hu, h, tcur, tolsf, nst, nre, nje, nqu, nq, niter, imxer, algequ, ifail] = ...
    nag_ode_ivp_stiff_integ_diag(int64(neq), int64(neqmax), rwork, inform);

  [y, ifail] = nag_ode_ivp_stiff_interp(tout, int64(neq), int64(neq), ysave, rwork);

  fprintf(' %8.3f%13.5f  %13.5f  %13.5f\n', tout, y);
  fprintf('\nhused = %12.5e hnext = %12.5e tcur = %12.5e\n', hu, h, tcur);
  fprintf('nst = %6d   nre = %6d   nje = %6d\n', nst, nre, nje);
  fprintf('nqa = %6d   nq  = %6d niter = %6d\n', nqu, nq, niter);
  fprintf('Max err comp = %4d   No. of failed steps = %4d\n', imxer, nfails);

  icall = int64(0);
  [liwreq, liwusd, lrwreq, lrwusd, nlu, nz, ngp, isplit, igrow, nblock] = ...
    nag_ode_ivp_stiff_sparjac_diag(icall, true, inform);

  fprintf('\nnjcpvt (required %4d  used %8d)\n', liwreq, liwusd);
  fprintf('nwjac (required %4d  used %8d)\n', lrwreq, lrwusd);
  fprintf('No. of LU-decomps %4d  No. of nonzeros %8d\n', nlu, nz)
  fprintf('No. of fcn calls to form Jacobian %4d Try isplit %4d\n', ngp, isplit);
  fprintf('Growth est %8d  No. of blocks on diagonal %4d\n', igrow, nblock);
elseif (ifail == 10)
  icall = int64(1)
  [liwreq, liwusd, lrwreq, lrwusd, nlu, nz, ngp, isplit, igrow, nblock] = ...
    nag_ode_ivp_stiff_sparjac_diag(icall, true, inform);

  fprintf('\nnjcpvt (required %4d  used %8d)\n', liwreq, liwusd);
  fprintf('nwjac (required %4d  used %8d)\n', lrwreq, lrwusd);
else
  fprintf('Exit nag_ode_ivp_stiff_imp_revcom with ifail = %d and t = %12.5e\n', ifail, t);
end
 

    x          y(1)           y(2)           y(3)
    0.000      1.00000        0.00000        0.00000
 WARNING... EQUATION(=I1) AND POSSIBLY OTHER EQUATIONS ARE
 IMPLICIT AND IN CALCULATING THE INITIAL VALUES THE EQNS
 WILL BE TREATED AS IMPLICIT.
 IN ABOVE MESSAGE I1 =         1
   10.000      0.84135        0.00002        0.15863

hused =  9.01811e-01 hnext =  9.01811e-01 tcur =  1.07667e+01
nst =     55   nre =     89   nje =     17
nqa =      4   nq  =      4 niter =     80
Max err comp =    3   No. of failed steps =    4

njcpvt (required   99  used      150)
nwjac (required   31  used       75)
No. of LU-decomps   17  No. of nonzeros        8
No. of fcn calls to form Jacobian    0 Try isplit   73
Growth est     1531  No. of blocks on diagonal    1

function d02nn_example
t = 0;
tout = 10;
y = [1; 0; 0];
ydot = [0; 0; 0];
rwork = zeros(62, 1);
rtol = [0.0001];
atol = [1e-07];
itol = int64(1);
inform = zeros(23, 1, 'int64');
ysave = zeros(3, 6);
wkjac = zeros(100,1);
jacpvt = zeros(150, 1, 'int64');
imon = int64(0);
inln = int64(0);
ires = int64(1);
irevcm = int64(0);
lderiv = [false; false];
itask = int64(3);
itrace = int64(0);
[const, rwork, ifail] = ...
    d02nv(int64(3), int64(6), int64(5), 'Newton', false, zeros(6), ...
    0, 1e-10, 10, 0, int64(200), int64(5), 'Average-L2', rwork);
[jacpvt, rwork, ifail] = ...
    d02nu(int64(3), int64(3), 'Analytical', int64(100), int64(0), ...
    int64(0), int64(150), 0, 0.1, 1e-4, true, rwork);

nfails = 0;

% indexes into rwork
neq    = 3;
neqmax = neq;
lacorb = neqmax + 50;
lsavrb = lacorb + neqmax;

fprintf('\n    x          y(1)           y(2)           y(3)\n');
fprintf(' %8.3f%13.5f  %13.5f  %13.5f\n', t, y);
first_time = true;
while (irevcm ~= 0 || first_time)
  first_time = false;
  [t, tout, y, ydot, rwork, inform, ysave, wkjac, ...
   jacpvt, imon, inln, ires, irevcm, lderiv, ifail] = ...
    d02nn(t, tout, y, ydot, rwork, rtol, atol, itol, inform, ...
    ysave, wkjac, jacpvt, imon, inln, ires, irevcm, lderiv, itask, itrace);

  if irevcm == 1 || irevcm == 3 || irevcm == 6 || irevcm == 11
    % Equivalent to resid evaluation in forward communication routines
    rwork(lsavrb+1) = -ydot(1) - ydot(2) - ydot(3);
    rwork(lsavrb+2) = -ydot(2);
    rwork(lsavrb+3) = -ydot(3);
    if (ires == 1)
      rwork(lsavrb+1) = rwork(lsavrb+1);
      rwork(lsavrb+2) = 0.04*y(1) - 1e4*y(2)*y(3) - 3e7*y(2)*y(2) + rwork(lsavrb+2);
      rwork(lsavrb+3) = 3e7*y(2)*y(2) + rwork(lsavrb+3);
    end
  elseif (irevcm == 2)
    % Equivalent to resid evaluation in forward communication routines
    rwork(lsavrb+1) = -rwork(lacorb+1) - rwork(lacorb+2) - rwork(lacorb+3);
    rwork(lsavrb+2) = -rwork(lacorb+2);
    rwork(lsavrb+3) = -rwork(lacorb+3);
  elseif (irevcm == 4 || irevcm == 7)
    % Equivalent to resid evaluation in forward communication routines
    rwork(lacorb+1) = -ydot(1) - ydot(2) - ydot(3);
    rwork(lacorb+2) = -ydot(2);
    rwork(lacorb+3) = -ydot(3);
    if (ires == 1)
      rwork(lacorb+1) = rwork(lacorb+1);
      rwork(lacorb+2) = 0.04*y(1) - 1e4*y(2)*y(3) - 3e7*y(2)*y(2) + rwork(lacorb+2);
      rwork(lacorb+3) = 3e7*y(2)*y(2) + rwork(lacorb+3);
    end
  elseif (irevcm == 5)
    % Equivalent to resid evaluation in forward communication routines
    ydot(1) = 0 - rwork(lsavrb+1) - rwork(lsavrb+2) - rwork(lsavrb+3);
    ydot(2) = 0.04*y(1) - 1e4*y(2)*y(3) - 3e7*y(2)*y(2) - rwork(lsavrb+2);
    ydot(3) = 3e7*y(2)*y(2) - rwork(lsavrb+3);
  elseif (irevcm == 8)
    % Equivalent to jac evaluation in forward communication routines
    [j, iplace] = d02nr(inform);
    hxd = rwork(16)*rwork(20);
    if (iplace < 2)
      if (j < 2)
        rwork(lsavrb+1) = 1 - hxd*(0);
        rwork(lsavrb+2) = 0 - hxd*(0.04);
        rwork(lsavrb+3) = 0 - hxd*(0);
      elseif (j == 2)
        rwork(lsavrb+1) = 1 - hxd*(0);
        rwork(lsavrb+2) = 1 - hxd*(-1e4*y(3)-6e7*y(2));
        rwork(lsavrb+3) = 0 - hxd*(6e7*y(2));
      elseif (j > 2)
        rwork(lsavrb+1) = 1 - hxd*(0);
        rwork(lsavrb+2) = 0 - hxd*(-1e4*y(2));
        rwork(lsavrb+3) = 1 - hxd*(0);
      end
    else
      if (j < 2)
        rwork(lacorb+1) = 1 - hxd*(0);
        rwork(lacorb+2) = 0 - hxd*(0.04);
        rwork(lacorb+3) = 0 - hxd*(0);
      elseif (j == 2)
        rwork(lacorb+1) = 1 - hxd*(0);
        rwork(lacorb+2) = 1 - hxd*(-1e4*y(3)-6e7*y(2));
        rwork(lacorb+3) = 0 - hxd*(6e7*y(2));
      elseif (j > 2)
        rwork(lacorb+1) = 1 - hxd*(0);
        rwork(lacorb+2) = 0 - hxd*(-1e4*y(2));
        rwork(lacorb+3) = 1 - hxd*(0);
      end
    end
  elseif (irevcm == 10)
    % Step failure
    nfails = nfails + 1;
  end
end

if (ifail == 0)
  [hu, h, tcur, tolsf, nst, nre, nje, nqu, nq, niter, imxer, algequ, ifail] = ...
    d02ny(int64(neq), int64(neqmax), rwork, inform);

  [y, ifail] = d02mz(tout, int64(neq), int64(neq), ysave, rwork);

  fprintf(' %8.3f%13.5f  %13.5f  %13.5f\n', tout, y);
  fprintf('\nhused = %12.5e hnext = %12.5e tcur = %12.5e\n', hu, h, tcur);
  fprintf('nst = %6d   nre = %6d   nje = %6d\n', nst, nre, nje);
  fprintf('nqa = %6d   nq  = %6d niter = %6d\n', nqu, nq, niter);
  fprintf('Max err comp = %4d   No. of failed steps = %4d\n', imxer, nfails);

  icall = int64(0);
  [liwreq, liwusd, lrwreq, lrwusd, nlu, nz, ngp, isplit, igrow, nblock] = ...
    d02nx(icall, true, inform);

  fprintf('\nnjcpvt (required %4d  used %8d)\n', liwreq, liwusd);
  fprintf('nwjac (required %4d  used %8d)\n', lrwreq, lrwusd);
  fprintf('No. of LU-decomps %4d  No. of nonzeros %8d\n', nlu, nz)
  fprintf('No. of fcn calls to form Jacobian %4d Try isplit %4d\n', ngp, isplit);
  fprintf('Growth est %8d  No. of blocks on diagonal %4d\n', igrow, nblock);
elseif (ifail == 10)
  icall = int64(1)
  [liwreq, liwusd, lrwreq, lrwusd, nlu, nz, ngp, isplit, igrow, nblock] = ...
    d02nx(icall, true, inform);

  fprintf('\nnjcpvt (required %4d  used %8d)\n', liwreq, liwusd);
  fprintf('nwjac (required %4d  used %8d)\n', lrwreq, lrwusd);
else
  fprintf('Exit d02nn with ifail = %d and t = %12.5e\n', ifail, t);
end
 

    x          y(1)           y(2)           y(3)
    0.000      1.00000        0.00000        0.00000
 WARNING... EQUATION(=I1) AND POSSIBLY OTHER EQUATIONS ARE
 IMPLICIT AND IN CALCULATING THE INITIAL VALUES THE EQNS
 WILL BE TREATED AS IMPLICIT.
 IN ABOVE MESSAGE I1 =         1
   10.000      0.84135        0.00002        0.15863

hused =  9.01811e-01 hnext =  9.01811e-01 tcur =  1.07667e+01
nst =     55   nre =     89   nje =     17
nqa =      4   nq  =      4 niter =     80
Max err comp =    3   No. of failed steps =    4

njcpvt (required   99  used      150)
nwjac (required   31  used       75)
No. of LU-decomps   17  No. of nonzeros        8
No. of fcn calls to form Jacobian    0 Try isplit   73
Growth est     1531  No. of blocks on diagonal    1


PDF version (NAG web site, 64-bit version, 64-bit version)
Chapter Contents
Chapter Introduction
NAG Toolbox

© The Numerical Algorithms Group Ltd, Oxford, UK. 2009–2013