home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 22 gnu
/
22-gnu.zip
/
c_lsode.zip
/
DEMOE.C
next >
Wrap
Text File
|
1994-01-03
|
13KB
|
307 lines
/* demo.c */
/* file origin: */
/* /netlib/odepack/demo.Z */
/* node address: research.att.com */
/* --------------------------------------------------------------------- */
/* see test.doc for both fortran and c sources and outputs. */
/* --------------------------------------------------------------------- */
/* */
/* demonstration program for the lsode package. */
/* this is the version of 13 august, 1981. */
/* */
/* this version is in double precision. */
/* */
/* the package is used to solve two simple problems, */
/* one with a full jacobian, the other with a banded jacobian, */
/* with all 8 of the appropriate values of mf in each case. */
/* if the errors are too large, or other difficulty occurs, */
/* a warning message is printed. */
/* */
/* this program has been tested with following compilers. */
/* bc++ 3.1 for win/dos */
/* djgpp gcc 1.10 */
/* gcc/2 2.3.3 for os/2 */
/* ibm c set++ of os/2 */
/* msc/c++ 7.0 for win/dos */
/* power c for dos */
/* c89 for dec ultrix */
/* */
/* about the result.... */
/* + bc++ and ibm c++ generate exactly the same results with demo.c, */
/* however they are slightly different with that of ms fortran 5.1. */
/* ms fortran 5.1 produced two different results when with and/or */
/* without time optimizations. you have to turn the optimization */
/* off to obtain the same result you will have with c compilers. */
/* + although you could have the same results from f77 and c89, they */
/* are not identical to one from any dos or os/2 compiler. */
/* */
/* recommendation for compiling.... */
/* ms fortran 5.1 - turn time optimization off. */
/* borland c++ 3.1 - no optimization for common subexpressions */
/* */
/* --------------------------------------------------------------------- */
#include <stdlib.h>
#include <math.h>
#include "lsode.h"
void fcn1(int [], double, double [], double []);
void jac1(int [], double, double [], int, int, double [], int);
void fcn2(int [], double, double [], double []);
void jac2(int [], double, double [], int, int, double [], int);
double edit2(double [], double);
int main()
{
int i, iopar, iopt, iout, istate, itask, itol, *iwork,
leniw, lenrw, liw, lrw, mband, mf, miter, miter1, meth,
ml, mu, neq[2], nerr, nfe, nfea, nje, nout, nqu, nst;
double atole[2], dtout, er, erm, ero, hu, rtol[2], *rwork, t, tout,
tout1, *y;
tout1 = 1.39283880203e0;
dtout = 2.214773875e0;
neq[1] = 2;
nerr = 0;
itol = 1;
rtol[1] = 0.0e0;
atole[1] = 1.0e-6;
lrw = 697;
liw = 45;
iwork = ivector(liw);
rwork = dvector(lrw);
y = dvector(neq[1]);
iopt = 0;
/* */
/* first problem ------------------------------------------------------ */
/* */
nout = 4;
printf("\f\n\n demonstration program for clsode package\n\n\n\n");
printf("\n problem 1.. van der pol oscillator..");
printf("\n xdotdot - 3*(1 - x**2)*xdot + x = 0,");
printf(" x(0) = 2, xdot(0) = 0");
printf("\n neq = %2d",neq[1]);
printf("\n itol = %3d rtol = %10.1e atol = %10.1e",
itol, rtol[1], atole[1]);
for(meth=1;meth<=2;meth++) {
for(miter1=1;miter1<=4;miter1++) {
miter = miter1 - 1;
mf = 10*meth + miter;
printf("\n\n\n\n mf = %3d\n\n\n",mf);
printf(" t\t\t x\t\t xdot");
printf(" nq h\n");
t = 0.0e0;
y[1] = 2.0e0;
y[2] = 0.0e0;
itask = 1;
istate = 1;
tout = tout1;
ero = 0.0e0;
for(iout=1;iout<=nout;iout++) {
lsode(fcn1,neq,y,&t,tout,itol,rtol,atole,itask,&istate,
iopt,rwork,lrw,iwork,liw,jac1,mf,stdout);
hu = rwork[11];
nqu = iwork[14];
printf("\n %15.5e %16.5e %14.3e %5d %14.3e",
t, y[1], y[2], nqu, hu);
if (istate < 0) break;
iopar = iout - 2*(iout/2);
if (iopar == 0) {
er = fabs(y[1])/atole[1];
ero = max(ero,er);
if (er >= 1000.0e0) {
printf("\n\n\n warning.. error ");
printf("exceeds 1000 * tolerance\n\n");
nerr = nerr + 1;
}
}
tout += dtout;
}
if (istate < 0) nerr++;
nst = iwork[11];
nfe = iwork[12];
nje = iwork[13];
lenrw = iwork[17];
leniw = iwork[18];
nfea = nfe;
if (miter == 2) nfea = nfe - neq[1]*nje;
if (miter == 3) nfea = nfe - nje;
printf("\n\n final statistics for this run..");
printf("\n rwork size = %4d iwork size = %4d",lenrw,leniw);
printf("\n number of steps = %5d",nst);
printf("\n number of f-s = %5d",nfe);
printf("\n (excluding j-s) = %5d",nfea);
printf("\n number of j-s = %5d",nje);
printf("\n error overrun = %10.2e",ero);
}
}
/* */
/* second problem ----------------------------------------------------- */
/* */
neq[1] = 25;
y = (double *) realloc(y, (unsigned)(neq[1]+1)*sizeof(double));
ml = 5;
mu = 0;
iwork[1] = ml;
iwork[2] = mu;
mband = ml + mu + 1;
nout = 5;
printf("\f\n\n demonstration program for clsode package\n\n\n");
printf("\n\n problem 2.. ydot = a * y , where,");
printf(" a is a banded lower triangular matrix");
printf("\n derived from 2-d advection pde");
printf("\n neq = %3d ml = %2d mu = %2d",neq[1],ml,mu);
printf("\n itol = %3d rtol = %10.1e atol = %10.1e",
itol, rtol[1], atole[1]);
for(meth=1;meth<=2;meth++) {
for(miter1=1;miter1<=6;miter1++) {
miter = miter1 - 1;
if (miter != 1 && miter != 2) {
mf = 10*meth + miter;
printf("\n\n\n\n mf = %3d\n\n\n ",mf);
printf("t\t\t max.err nq h\n");
t = 0.0e0;
for(i=2;i<=neq[1];i++) y[i] = 0.0e0;
y[1] = 1.0e0;
itask = 1;
istate = 1;
tout = 0.01e0;
ero = 0.0e0;
for(iout=1;iout<=nout;iout++) {
lsode(fcn2,neq,y,&t,tout,itol,rtol,atole,
itask,&istate,iopt,rwork,lrw,
iwork,liw,jac2,mf,stdout);
erm = edit2(y,t);
hu = rwork[11];
nqu = iwork[14];
printf("\n %15.5e %14.3e %5d %14.3e",t,erm,nqu,hu);
if (istate < 0) break;
er = erm/atole[1];
ero = max(ero,er);
if (er > 1000.0e0) {
printf("\n\n\n warning.. error ");
printf("exceeds 1000 * tolerance\n\n");
nerr++;
}
tout *= 10.0e0;
}
if (istate < 0) nerr++;
nst = iwork[11];
nfe = iwork[12];
nje = iwork[13];
lenrw = iwork[17];
leniw = iwork[18];
nfea = nfe;
if (miter == 5) nfea = nfe - mband*nje;
if (miter == 3) nfea = nfe - nje;
printf("\n\n final statistics for this run..");
printf("\n rwork size = %4d iwork size = %d",
lenrw,leniw);
printf("\n number of steps = %5d",nst);
printf("\n number of f-s = %5d",nfe);
printf("\n (excluding j-s) = %5d",nfea);
printf("\n number of j-s = %5d",nje);
printf("\n error overrun = %10.2e",ero);
}
}
}
printf("\n\n\n number of errors encountered = %3d",nerr);
free(iwork);
free(rwork);
free(y);
return 1;
}
/* */
/* derivative and jacobi matrix routine ------------------------------- */
/* */
void fcn1(int neq[], double t, double y[], double ydot[])
{
ydot[1] = y[2];
ydot[2] = 3.0e0*(1.0e0 - y[1]*y[1])*y[2] - y[1];
return;
}
#define pd(a,b) pd[nr*(b-1)+a]
void jac1(int neq[], double t, double y[],
int ml, int mu, double pd[], int nr)
{
pd(1,1) = 0.0e0;
pd(1,2) = 1.0e0;
pd(2,1) = -6.0e0*y[1]*y[2] - 1.0e0;
pd(2,2) = 3.0e0*(1.0e0 - y[1]*y[1]);
return;
}
void fcn2(int neq[], double t, double y[], double ydot[])
{
int i, j, k, ng= 5;
double alph1 = 1.0e0, alph2 = 1.0e0, d;
for(j = 1;j<=ng;j++) {
for(i=1;i<=ng;i++) {
k = i + (j - 1)*ng;
d = -2.0e0*y[k];
if (i != 1) d += y[k-1]*alph1;
if (j != 1) d += y[k-ng]*alph2;
ydot[k] = d;
}
}
return;
}
void jac2(int neq[], double t, double y[],
int ml, int mu, double pd[], int nr)
{
int j, mband, mu1, mu2, ng=5;
double alph1 = 1.0e0, alph2 = 1.0e0;
mband = ml + mu + 1;
mu1 = mu + 1;
mu2 = mu + 2;
for(j=1;j<=neq[1];j++) {
pd(mu1,j) = -2.0e0;
pd(mu2,j) = alph1;
pd(mband,j) = alph2;
}
for(j=ng;j<=neq[1];j+=ng) pd(mu2,j) = 0.0e0;
return;
}
double edit2 (double y[], double t)
{
int i, j, k, ng=5;
double alph1=1.0e0, alph2=1.0e0;
double a1, a2, er, ex, yt, erm;
erm = 0.0e0;
if (t == 0.0e0) return erm;
ex = 0.0e0;
if (t <= 30.0e0) ex = exp(-2.0e0*t);
a2 = 1.0e0;
for(j=1;j<=ng;j++) {
a1 = 1.0e0;
for(i=1;i<=ng;i++) {
k = i + (j - 1)*ng;
yt = pow(t,(i+j-2))*ex*a1*a2;
er = fabs(y[k]-yt);
erm = max(erm,er);
a1 *= alph1/(double)i;
}
a2 *= alph2/(double)j;
}
return erm;
}