// // henon.C Copyright Jun Makino 1998 // // demonstration program for numerical integration of // Henon-Heiles Hamiltonian // H = \frac{1}{2}(p_1^2 + p_2^2) + \frac{1}{2}(q_1^2 + q_2^2) + // q_1^2q_2 - \frac{1}{3}q_2^3 // // dp_1/dt= -q_1 - 2q_1q_2 // dp_2/dt= -q_2 - q_1^2 + q_2^2 // uses a simple VECTOR class // x_0 = q_1 // x_1 = p_1 // x_2 = q_2 // x_3 = p_2 // #include "cpgplot.h" #include #include #include const int VLEN = 4; #include "vector.h" #define PR(x) cerr << #x << " = " << x << " " #define PRC(x) cerr << #x << " = " << x << ", " #define PRL(x) cerr << #x << " = " << x << "\n" typedef struct plot_control{ int xvarid; int yvarid; int secvarid; int mode; }PLOT_CONTROL; struct plot_control pctr; void initgraph(const double xmax, const double h0) { cerr << "Enter var to plot (x, y, and sos):"; cin >> pctr.xvarid >> pctr.yvarid >> pctr.secvarid ; if ( pctr.secvarid < 0){ pctr.mode = 0; }else{ pctr.mode = 1; } char pgdevname[255]; cerr << "Enter devname"; cin >> pgdevname ; if(cpgopen(pgdevname) != 1) exit(EXIT_FAILURE); cpgask(0); cpgenv(-xmax, xmax, -xmax, xmax, 1, 0); const char * name[4]={"q1","p1","q2","p2"}; char label[255]; sprintf(label, "H0 = %g", h0); cpglab(name[pctr.xvarid],name[pctr.yvarid], label); } #ifndef WRONG_PLOT void plot( vector x, vector xold) { if (pctr.mode == 0 ){ cpgpt1(x[pctr.xvarid],x[pctr.yvarid],-1); }else if (x[pctr.secvarid]*xold[pctr.secvarid] <= 0) { vector xinterp = (-x*xold[pctr.secvarid]+xold*x[pctr.secvarid]) /(x[pctr.secvarid]-xold[pctr.secvarid]); cpgpt1(xinterp[pctr.xvarid],xinterp[pctr.yvarid],-1); } } #else void plot( vector x, vector xold) { if (pctr.mode == 0 ){ cpgpt1(x[pctr.xvarid],x[pctr.yvarid],-1); }else if (x[pctr.secvarid]*xold[pctr.secvarid] <= 0) { cpgpt1(x[pctr.xvarid],x[pctr.yvarid],-1); } } #endif const vector dxdt( vector & x) { vector d; d[0] = x[1]; d[1] = -x[0] - 2* x[0]*x[2]; d[2] = x[3]; d[3] = -x[2] - x[0]*x[0] + x[2]*x[2]; return d; } double energy( vector &x) { return 0.5*(x[1]*x[1]+x[3]*x[3]) + 0.5*(x[0]*x[0]+x[2]*x[2]) + x[0]*x[0]*x[2]-x[2]*x[2]*x[2]/3; } void rk4(vector & x, vfunc_ptr f, double h, int & first_call) { static vector kx1,kx2,kx3,kx4; kx1 = f(x)*h; kx2 = f(x+kx1*0.5)*h; kx3 = f(x+kx2*0.5)*h; kx4 = f(x+kx3)*h; x += (kx1+2*(kx2+kx3)+kx4)*0.166666666666666666666666667; } void leapfrog(vector & x, vfunc_ptr f, double h, int & first_call) { static vector fprev; if (first_call != 0){ fprev = f(x); first_call = 0; } for(int i = 0; i<4;i+=2){ x[1+i] += h*fprev[1+i]*0.5; x[i] += h*x[1+i]; } fprev = f(x); for(int i = 0; i<4;i+=2){ x[1+i] += h*fprev[1+i]*0.5; } } const int niter = 6; void trapezoidal(vector & x, vfunc_ptr f, double h, int & first_call) { static vector fprev; if (first_call != 0){ fprev = f(x); first_call = 0; } vector xnew = x + fprev*h; vector fnew; for(int i = 0; i> nsteps >> ntime >> print_interval; cout.precision(16); h = 1.0/nsteps; cerr << " x= " << x << " h = " << h <<"\n"; cerr << " tend= " << ntime <<"\n"; int integrator_type; cerr << "Enter integrator type (0: rk4, 1: yoshida4, 2: yoshida6b,3:gauss4):"; cin >> integrator_type; cerr << integname[integrator_type] << " will be used\n"; double h0; cerr << "Enter h0 (=p1) "; cin >> h0; initgraph(sqrt(h0*6),h0); double theta; cerr << "Enter new theta (<0) to finish):"; cin >> theta; while (theta >= 0){ theta *= M_PI/180; x[0] = 0; x[1] = 0; x[2] = 0; x[3] = 0; x[1] = cos(theta)*sqrt(2*h0); x[3] = sin(theta)*sqrt(2*h0); double e0 = energy(x); int first_call = 1; for(i=0; i> theta; } cpgend(); }