⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adams_pece_impl.h

📁 TSTOOL应用软件,内有说明文件,可以适当修改,应用比较方便.
💻 H
📖 第 1 页 / 共 2 页
字号:
#ifndef ADAM_PECE_DECL_H#define ADAM_PECE_DECL_H#include <math.h>#define TRUE_ (1)#define FALSE_ (0)#define abs(x) ((x) >= 0 ? (x) : -(x))#define dabs(x) (double)abs(x)#define min(a,b) ((a) <= (b) ? (a) : (b))#define max(a,b) ((a) >= (b) ? (a) : (b))#define dmin(a,b) (double)min(a,b)#define dmax(a,b) (double)max(a,b)template<class ExplicitODE>int Adams<ExplicitODE>::ode(double *t, double *tout, double *relerr, double *abserr, long *iflag){    /* Initialized data */    static long ialpha = 1;    static long ih = 89;    static long ihold = 90;    static long istart = 91;    static long itold = 92;    static long idelsn = 93;    static long ibeta = 13;    static long isig = 25;    static long iv = 38;    static long iw = 50;    static long ig = 62;    static long iphase = 75;    static long ipsi = 76;    static long ix = 88;    long iphi;    long nornd, start, phase1;	long ip, iypout, iyp, iwt, iyy;		long* const iwork = iwork_c - 1;	double* const y = f.v-1;    double* const work = work_c - 1;       /* Function Body */    iyy = 100;    iwt = iyy + neqn;    ip = iwt + neqn;    iyp = ip + neqn;    iypout = iyp + neqn;    iphi = iypout + neqn;    if (abs(*iflag) == 1) {		goto L1;    }    start = work[istart] > 0.;    phase1 = work[iphase] > 0.;    nornd = iwork[2] != -1;L1:    de(neqn, &y[1], t, tout, relerr, abserr, iflag, &work[iyy], &	    work[iwt], &work[ip], &work[iyp], &work[iypout], &work[iphi], &	    work[ialpha], &work[ibeta], &work[isig], &work[iv], &work[iw], &	    work[ig], &phase1, &work[ipsi], &work[ix], &work[ih], &work[ihold]	    , &start, &work[itold], &work[idelsn], &iwork[1], &nornd, &iwork[3], &iwork[4], &iwork[5]);       work[istart] = -1.;    if (start) {		work[istart] = 1.;    }    work[iphase] = -1.;    if (phase1) {		work[iphase] = 1.;    }    iwork[2] = -1;    if (nornd) {		iwork[2] = 1;    }	    return 0;} /* ode_ */template<class ExplicitODE>int Adams<ExplicitODE>::de(const long neqn, double *y, double *t, 	double *tout, double *relerr, double *abserr, long *	iflag, double *yy, double *wt, double *p, double *yp, 	double *ypout, double *phi, double *alpha, double *	beta, double *sig, double *v, double *w, double *g, 	long *phase1, double *psi, double *x, double *h__, 	double *hold, long *start, double *told, double *	delsgn, long *ns, long *nornd, long *k, long *kold, 	long *isnold){    /* Initialized data */    const long maxnum = 1000;    /* System generated locals */    long phi_dim1, phi_offset, i__1;    double d__1, d__2, d__3, d__4, d__5;    /* Local variables */    double tend;    long l;    long crash, stiff;    double absdel, abseps, releps;    long nostep;    double del, eps;    long isn, kle4;    /* Parameter adjustments */    phi_dim1 = neqn;    phi_offset = 1 + phi_dim1 * 1;    phi -= phi_offset;    --ypout;    --yp;    --p;    --wt;    --yy;    --y;    --alpha;    --beta;    --sig;    --v;    --w;    --g;    --psi;    /* Function Body *//*            ***            ***            *** *//*   test for improper parameters */    if (neqn < 1) {		goto L10;    }    if (*t == *tout) {		goto L10;    }    if (*relerr < 0. || *abserr < 0.) {		goto L10;    }    eps = max(*relerr,*abserr);    if (eps <= 0.) {		goto L10;    }    if (*iflag == 0) {		goto L10;    }    isn = i_sign(&c__1, iflag);    *iflag = abs(*iflag);    if (*iflag == 1) {		goto L20;    }    if (*t != *told) {		goto L10;    }    if (*iflag >= 2 && *iflag <= 5) {		goto L20;    }L10:    *iflag = 6;    return 0;/*   on each call set interval of integration and counter for number of *//*   steps.  adjust input error tolerances to define weight vector for *//*   subroutine  step */L20:    del = *tout - *t;    absdel = abs(del);    tend = *t + del * 10.;    if (isn < 0) {		tend = *tout;    }    nostep = 0;    kle4 = 0;    stiff = FALSE_;    releps = *relerr / eps;    abseps = *abserr / eps;    if (*iflag == 1) {		goto L30;    }    if (*isnold < 0) {		goto L30;    }    if (*delsgn * del > 0.) {		goto L50;    }/*   on start and restart also set work variables x and yy(*), store the *//*   direction of integration and initialize the step size */L30:    *start = TRUE_;    *x = *t;    i__1 = neqn;    for (l = 1; l <= i__1; ++l) {		yy[l] = y[l];    }    *delsgn = d_sign(&c_b11, &del);	/* Computing MAX */    	d__3 = (d__1 = *tout - *x, abs(d__1)), d__4 = fouru * abs(*x);    d__2 = max(d__3,d__4);    d__5 = *tout - *x;    *h__ = d_sign(&d__2, &d__5);/*   if already past output point, interpolate and return */L50:    if ((d__1 = *x - *t, abs(d__1)) < absdel) {		goto L60;    }    intrp(*x, &yy[1], *tout, &y[1], &ypout[1], neqn, *kold, &phi[phi_offset], &psi[1]);	    *iflag = 2;    *t = *tout;    *told = *t;    *isnold = isn;    return 0;/*   if cannot go past output point and sufficiently close, *//*   extrapolate and return */L60:    if (isn > 0 || (d__1 = *tout - *x, abs(d__1)) >= fouru * abs(*x)) {		goto L80;    }    *h__ = *tout - *x;    f(x, &yy[1], &yp[1]);    i__1 = neqn;    for (l = 1; l <= i__1; ++l) {		y[l] = yy[l] + *h__ * yp[l];    }    *iflag = 2;    *t = *tout;    *told = *t;    *isnold = isn;    return 0;/*   test for too many steps */L80:    if (nostep < maxnum) {		goto L100;    }    *iflag = isn << 2;    if (stiff) {		*iflag = isn * 5;    }    i__1 = neqn;    for (l = 1; l <= i__1; ++l) {/* L90: */		y[l] = yy[l];    }    *t = *x;    *told = *t;    *isnold = 1;    return 0;/*   limit step size, set weight vector and take a step */L100:	/* Computing MIN */    d__3 = abs(*h__), d__4 = (d__1 = tend - *x, abs(d__1));    d__2 = min(d__3,d__4);    *h__ = d_sign(&d__2, h__);	    i__1 = neqn;	    for (l = 1; l <= i__1; ++l) {		wt[l] = releps * (d__1 = yy[l], abs(d__1)) + abseps;    }	    step(x, &yy[1], neqn, h__, &eps, &wt[1], start, hold, k, kold, &	    crash, &phi[phi_offset], &p[1], &yp[1], &psi[1], &alpha[1], &beta[	    1], &sig[1], &v[1], &w[1], &g[1], phase1, ns, nornd);/*   test for tolerances too small */    if (! crash) {		goto L130;    }    *iflag = isn * 3;    *relerr = eps * releps;    *abserr = eps * abseps;    i__1 = neqn;	    for (l = 1; l <= i__1; ++l) {		y[l] = yy[l];    }	    *t = *x;    *told = *t;    *isnold = 1;    return 0;/*   augment counter on number of steps and test for stiffness */L130:    ++nostep;    ++kle4;    if (*kold > 4) {	kle4 = 0;    }    if (kle4 >= 50) {		stiff = TRUE_;    }    goto L50;} /* de_ */template<class ExplicitODE>int Adams<ExplicitODE>::step(double *x, double *y, const long neqn, double *h__, double *eps, double *wt, long *start, double *hold, long *k, 	long *kold, long *crash, double *phi, double *p, double *yp, double *psi, double *alpha, double *beta, double *sig, double *v, 	double *w, double *g, long *phase1, long *ns, long *nornd){    /* Initialized data */    static double two[13] = { 2.,4.,8.,16.,32.,64.,128.,256.,512.,1024.,	    2048.,4096.,8192. };    static double gstr[13] = { .5,.0833,.0417,.0264,.0188,.0143,.0114,	    .00936,.00789,.00679,.00592,.00524,.00468 };    /* System generated locals */    long phi_dim1, phi_offset, i__1, i__2;    double d__1, d__2, d__3;    /* Local variables */    double absh, hnew;    long knew;    double xold, erkm1, erkm2, erkp1, temp1, temp2, temp3, temp4, temp5, temp6, p5eps;    long i__, j, l;    double r__;    long ifail;    double reali, round;    long limit1, limit2, iq;    double realns;    long im1, km1, km2, ip1, kp1, kp2;    double erk, err, tau, rho, sum;    long nsm2, nsp1, nsp2;    /* Parameter adjustments */    --yp;    --p;    phi_dim1 = neqn;    phi_offset = 1 + phi_dim1 * 1;    phi -= phi_offset;    --wt;    --y;    --psi;    --alpha;    --beta;    --sig;    --v;    --w;    --g;    /* Function Body *//*     data g(1),g(2)/1.0,0.5/,sig(1)/1.0/ *//*       ***     begin block 0     *** *//*   check if step size or error tolerance is too small for machine *//*   precision.  if first step, initialize phi array and estimate a *//*   starting step size. *//*                   *** *//*   if step size is too small, determine an acceptable one */    *crash = TRUE_;    if (abs(*h__) >= fouru * abs(*x)) {	goto L5;    }    d__1 = fouru * abs(*x);    *h__ = d_sign(&d__1, h__);    return 0;L5:    p5eps = *eps * .5;/*   if error tolerance is too small, increase it to an acceptable value */    round = 0.;    i__1 = neqn;    for (l = 1; l <= i__1; ++l) {/* L10: *//* Computing 2nd power */	d__1 = y[l] / wt[l];	round += d__1 * d__1;    }    round = twou * sqrt(round);    if (p5eps >= round) {	goto L15;    }    *eps = round * 2.f * (fouru + 1.);    return 0;L15:    *crash = FALSE_;    g[1] = 1.;    g[2] = .5;    sig[1] = 1.;    if (! (*start)) {	goto L99;    }/*   initialize.  compute appropriate step size for first step */    f(x, &y[1], &yp[1]);    sum = 0.;    i__1 = neqn;    for (l = 1; l <= i__1; ++l) {	phi[l + phi_dim1] = yp[l];	phi[l + (phi_dim1 << 1)] = 0.;/* L20: *//* Computing 2nd power */	d__1 = yp[l] / wt[l];	sum += d__1 * d__1;    }    sum = sqrt(sum);    absh = abs(*h__);    if (*eps < sum * 16. * *h__ * *h__) {	absh = sqrt(*eps / sum) * .25;    }/* Computing MAX */    d__2 = absh, d__3 = fouru * abs(*x);    d__1 = max(d__2,d__3);    *h__ = d_sign(&d__1, h__);    *hold = 0.;    *k = 1;    *kold = 0;    *start = FALSE_;    *phase1 = TRUE_;    *nornd = TRUE_;    if (p5eps > round * 100.) {	goto L99;    }    *nornd = FALSE_;    i__1 = neqn;    for (l = 1; l <= i__1; ++l) {/* L25: */	phi[l + phi_dim1 * 15] = 0.;    }L99:    ifail = 0;/*       ***     end block 0     *** *//*       ***     begin block 1     *** *//*   compute coefficients of formulas for this step.  avoid computing *//*   those quantities not changed when step size is not changed. *//*                   *** */L100:    kp1 = *k + 1;    kp2 = *k + 2;    km1 = *k - 1;    km2 = *k - 2;/*   ns is the number of steps taken with size h, including the current *//*   one.  when k.lt.ns, no coefficients change */    if (*h__ != *hold) {	*ns = 0;    }    if (*ns <= *kold) {	++(*ns);    }    nsp1 = *ns + 1;    if (*k < *ns) {	goto L199;    }/*   compute those components of alpha(*),beta(*),psi(*),sig(*) which *//*   are changed */    beta[*ns] = 1.;    realns = (double) (*ns);    alpha[*ns] = 1. / realns;    temp1 = *h__ * realns;    sig[nsp1] = 1.;    if (*k < nsp1) {	goto L110;    }    i__1 = *k;    for (i__ = nsp1; i__ <= i__1; ++i__) {	im1 = i__ - 1;	temp2 = psi[im1];	psi[im1] = temp1;	beta[i__] = beta[im1] * psi[im1] / temp2;	temp1 = temp2 + *h__;	alpha[i__] = *h__ / temp1;	reali = (double) i__;/* L105: */	sig[i__ + 1] = reali * alpha[i__] * sig[i__];    }L110:    psi[*k] = temp1;/*   compute coefficients g(*) *//*   initialize v(*) and set w(*).  g(2) is set in data statement */    if (*ns > 1) {	goto L120;    }    i__1 = *k;    for (iq = 1; iq <= i__1; ++iq) {	temp3 = (double) (iq * (iq + 1));	v[iq] = 1. / temp3;/* L115: */	w[iq] = v[iq];    }    goto L140;/*   if order was raised, update diagonal part of v(*) */L120:    if (*k <= *kold) {	goto L130;    }    temp4 = (double) (*k * kp1);    v[*k] = 1. / temp4;    nsm2 = *ns - 2;    if (nsm2 < 1) {	goto L130;    }    i__1 = nsm2;    for (j = 1; j <= i__1; ++j) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -