int main(void) { int i,j; float eps,hdid,hnext,htry,x=1.0,*y,*dydx,*dysav,*ysav,*yscal; y=vector(1,N); dydx=vector(1,N); dysav=vector(1,N); ysav=vector(1,N); yscal=vector(1,N); ysav[1]=bessj0(x); ysav[2]=bessj1(x); ysav[3]=bessj(2,x); ysav[4]=bessj(3,x); derivs(x,ysav,dysav); for (i=1;i<=N;i++) yscal[i]=1.0; htry=0.6; printf("%10s %11s %12s %13s\n","eps","htry","hdid","hnext"); for (i=1;i<=15;i++) { eps=exp((double) -i); x=1.0; for (j=1;j<=N;j++) { y[j]=ysav[j]; dydx[j]=dysav[j]; } rkqs(y,dydx,N,&x,htry,eps,yscal,&hdid,&hnext,derivs); printf("%13f %8.2f %14.6f %12.6f \n",eps,htry,hdid,hnext); } free_vector(yscal,1,N); free_vector(ysav,1,N); free_vector(dysav,1,N); free_vector(dydx,1,N); free_vector(y,1,N); return 0; }
void RungeKuttaSolver::ode_rk(int nvar, double x1, double x2, double eps, double h1, double hmin, int *nok, int *nbad, RungeKuttaEquation *Equations[]) { int nstp,i; double xsav, x, hnext, hdid, h; // DJA: h is the current time step value double *yscal,*y,*dydx; yscal=new_vector(1,nvar); y=new_vector(1,nvar); dydx=new_vector(1,nvar); x=x1; h=SIGN(h1,x2-x1); *nok = (*nbad) = kount = 0; for (i = 1; i <= nvar ; i++) y[i] = Equations[i]->InitialY; if (kmax > 0) xsav=x-dxsav*2.0; for (nstp=1;nstp<=MAXSTP;nstp++) { // (*derivs)(x,y,dydx); DJA: This is the old call which we've replaced with the following two lines for (i = 1; i <= nvar ; i++) dydx[i] = Equations[i]->GetDerivative(y[i], y[5]); for (i=1;i<=nvar;i++) yscal[i]=fabs(y[i])+fabs(dydx[i]*h)+TINY; if (kmax > 0 && kount < kmax-1 && fabs(x-xsav) > fabs(dxsav)) { xp[++kount]=x; for (i=1;i<=nvar;i++) yp[i][kount]=y[i]; xsav=x; } if ((x+h-x2)*(x+h-x1) > 0.0) h=x2-x; rkqs(y,dydx,nvar,&x,h,eps,yscal,&hdid,&hnext,Equations); if (hdid == h) ++(*nok); else ++(*nbad); if ((x-x2)*(x2-x1) >= 0.0) { for (i=1;i<=nvar;i++) Equations[i]->InitialY = y[i]; if (kmax) { xp[++kount]=x; for (i=1;i<=nvar;i++) yp[i][kount]=y[i]; } delete_vector(dydx,1,nvar); delete_vector(y,1,nvar); delete_vector(yscal,1,nvar); return; } // printf("hnext %f hmin %f\n",hnext,hmin); if (fabs(hnext) <= hmin) { nrerror("Step size too small in odeint"); } h=hnext; } nrerror("Too many steps in routine odeint"); }