#include #include #include "xpplim.h" #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) int (*rhs)(); int mod_euler(/* double *,double *,double,int,int,int *,double * */); int rung_kut(/* double *,double *,double,int,int,int *,double * */); int adams(/* double *,double *,double,int,int, int*,double * */); int abmpc(/* double *,double *,double,int */); double pow(),sqrt(); double coefp[]={ 6.875/3.00,-7.375/3.00,4.625/3.00,-.375}, coefc[]={ .375,2.375/3.00,-.625/3.00,0.125/3.00 }; double *y_s[4],*y_p[4],*ypred; double symp_b[]={7/24.,.75,-1./24}; double symp_B[]={2/3.,-2./3.,1.0}; extern int MaxEulIter; extern double EulTol,NEWT_ERR; extern int NFlags; extern double TOLER,ATOLER; extern int cv_bandflag,cv_bandupper,cv_bandlower; /* my first symplectic integrator */ int symplect3(y,tim,dt,nt,neq,istart,work) double *y,*tim,dt,*work; int nt,neq,*istart; { int i; if(NFlags==0){ for(i=0;iMaxEulIter)return(-2); } } one_step_discrete(y,dt,yp,neq,t) double dt,*t; double *y,*yp; int neq; { int j; set_wieners(dt,y,*t); rhs(*t,y,yp,neq); *t=*t+dt; for(j=0;j1) goto n350; istpst=0; goto n400; n20: x0=xst; rhs(x0,y,y_p[3],neq); for(k=1;k<4;k++) { rung_kut(y,&x0,dt,1,neq,&irk,work1); stor_delay(y); for(i=0;i0;k--)y_p[k][i]=y_p[k-1][i]; x1=x0+dt; rhs(x1,ypred,y_p[0],neq); for(i=0;itfinal)tdir=-1; hmax=fabs(tfinal-t); if(*istart==1) htry=hmax; rhs(t0,y,f0,n); hmin=16*eps*fabs(t); absh = MIN(hmax, MAX(hmin, htry)); while(!done) { nofailed=1; hmin = 16*eps*fabs(t); absh = MIN(hmax, MAX(hmin, absh)); h = tdir * absh; if(1.1*absh >= fabs(tfinal - t)){ h = tfinal - t; absh = fabs(h); done = 1; } get_the_jac(t,y,f0,ypnew,dfdy,n,epsjac,1.0); tdel = (t + tdir*MIN(sqrteps*MAX(fabs(t),fabs(t+h)),absh)) - t; rhs(t+tdel,y,f1,n); for(i=0;irtol){ if(absh0.2) absh=absh/temp; else absh=5*absh; } /* printf(" absh=%g \n",absh); */ t=tnew; for(i=0;in1)continue; a[k*mt+j+ml]=dsy*(ypnew[k]-ypold[k]); } y[i]=yhat; } } bandfac(a,ml,mr,n) /* factors the matrix */ int ml,mr,n; double *a; { int i,j,k; int n1=n-1,mt=ml+mr+1,row,rowi,m,r0,ri0; int mlo; double al; for(row=0;rown1)break; ri0=rowi*mt+ml; al=a[ri0-i]; if(al==0.0)continue; for(k=1;k<=m;k++) a[ri0-i+k]=a[ri0-i+k]-(al*a[r0+k]); a[ri0-i]=-al; } } return(0); } bandsol(a,b,ml,mr,n) /* requires that the matrix be factored */ double *a,*b; int ml,mr,n; { int i,j,k,r0; int mt=ml+mr+1; int m,n1=n-1,row; double sum; for(i=0;i=0;row--){ m=MIN(mr,n1-row); r0=row*mt+ml; for(k=1;k<=m;k++) b[row]=b[row]-a[r0+k]*b[row+k]; } }