#include #include #include #include #define N 4 #ifdef __GNUC__ #define MIN(i,j) ({ typeof(i) ti=(i); typeof(j) tj=(j); ti<=tj?ti:tj; }) #else /* defined(__GNUC__) */ #define MIN(i,j) ((i)<=(j)?(i):(j)) #endif /* defined(__GNUC__) */ #define SIGNE(x) ((x)>=0?1:-1) /* * RTBP pla en sinòdiques (posicions + velocitats) i variacionals * primeres */ #define X x[0] #define Y x[1] #define U x[2] #define V x[3] int rtbp (int kv, int nv[], void *prm, double t, double x[], double f[]) { double mu, xmmu, xmmup1, y2, td1, td2, rh12, rh22, rh1, rh2, rh13, rh23, pot3, potx3, onemmu; mu=*((double *)prm); onemmu=1-mu; xmmu=X-mu; xmmup1=xmmu+1; y2=Y*Y; rh12=xmmu*xmmu+y2; rh22=xmmup1*xmmup1+y2; rh1=sqrt(rh12); rh2=sqrt(rh22); rh13=rh12*rh1; rh23=rh22*rh2; td1=-onemmu/rh13; td2=-mu/rh23; pot3=td1+td2; potx3=td1*xmmu+td2*xmmup1; /* Equacions */ f[0]=U; f[1]=V; f[2]=2*V+X+potx3; f[3]=-2*U+Y*(1+pot3); /* Variacionals primeres */ if (kv>=1) { #define VARX(i,j) x[(1+(j))*N+(i)] #define VARF(i,j) f[(1+(j))*N+(i)] double pot5, potx5, omgxx, omgxy, omgyy; int j; td1=onemmu/(rh13*rh12); td2=mu/(rh23*rh22); pot5=td1+td2; td1*=xmmu; td2*=xmmup1; potx5=td1+td2; omgxx=1+pot3+3*(td1*xmmu+td2*xmmup1); omgxy=3*Y*potx5; omgyy=1+pot3+3*y2*pot5; for (j=0; j=1?nv[0]:0 )), iret; double tt, bet, d, dd, e3, wksp[15*nn], *r=wksp, *b=wksp+13*nn, *f=wksp+14*nn; /* Bucle en el pas */ do { /* Fem RK7 -> b[] i RK8 -> f[] * Mitjana per coordenades de RK7-RK8 -> d * Norma sub-1 de RK7-RK8 -> dd */ ib=0; for (j=0; j<13; j++) { memcpy(b, x, nn*sizeof(double)); tt=(*t)+alfa[j]*(*h); for (k=0; k=1) fprintf(stderr,"rkf78():: t %G : ajusto a pasmin %G !!\n", *t, hmin); } else if (fabs(*h)>hmax) { /* els limits permesos. */ (*h)=SIGNE(*h)*hmax; if (ivb>=2) fprintf(stderr,"rkf78():: t %G : ajusto a pasmax %G\n", *t, hmax); } /* Tornem l'estimació de l'error */ if (eerr!=NULL) *eerr=d; return 0; } #define PMIN 1e-6 #define TOL 1e-14 #define TOLS 1e-12 #define IX 0 #define IY 1 #define IU 2 #define IV 3 #define IVB 1 void rva2z (double mu, double r0, double v0, double csa, double sna, double *z) { z[0]=mu+r0*csa; z[1]= r0*sna; z[2]= -v0*sna; z[3]= v0*csa; } void proptraj (double mu, int nt, double *z0, double *zf, double *du, double pmax, FILE *fp) { int kv, nv, ivar=(du!=NULL), nn=ivar?5*N:N, i, j, it, isgn; double t, xx[nn], h, f[N], ta, xxa[nn]; if (ivar) { kv=1; nv=4; } else kv=0; /* Inicialització int num */ memcpy(xx,z0,N*sizeof(double)); if (ivar) { for (i=N; i=TOLS) isgn=(xx[IY]>0) ? 1 : -1; else isgn=(xx[IV]>0) ? 1 : -1; /* Vol lliure */ for (it=0; it=0); isgn=-isgn; } /* Ajustar a secció */ t=ta; memcpy(xx,xxa,nn*sizeof(double)); while (fabs(xx[IY])>TOLS) { rtbp(0/*kv*/,NULL/*nv*/,&mu,t,xx,f); h=-xx[IY]/f[IY]; rkf78(N,kv,&nv,&mu,rtbp,&t,xx,&h, MIN(PMIN,fabs(h))/*hmin*/,fabs(h)/*hmax*/,TOL,NULL/*eerr*/,IVB); } if (fp!=NULL) fprintf(fp,"%.16G %.16G %.16G %.16G %.16G\n\n", t, xx[0], xx[1], xx[2], xx[3]); /* Torno u, xf */ if (zf!=NULL) memcpy(zf,xx,N*sizeof(double)); if (ivar) { #define VAR(i,j) xx[(1+(j))*N+(i)] /* Torno la fila IU de la dif de l'apl Poinc. */ rtbp(0/*kv*/,NULL/*nv*/,&mu,t,xx,f); for (j=0; j<4; j++) du[j]=VAR(IU,j)-f[IU]*VAR(IY,j)/f[IY]; #undef VAR } } #undef IVB #undef TOLS #undef TOL #undef PMIN #undef IV #undef IU #undef IY #undef IX