Example #1
0
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");
}