// Planet.cc // Simulates planet (inverse square law) // using leapfrog method. // example usage: // mkdir output // ./Planet > output/1 // recommended gnuplot commands: // set size ratio -1 // plot 'output/1' u 2:3 w linesp lt 3 pt 4 // replot 'output/1' u 2:3:4:5 w vector lt 5 #include #include using namespace std; #define D 2 // number of dimensions struct particle { double x[D] ; // (x,y) coordinates double p[D] ; // momentum double F[D] ; // force double im ; // inverse mass double GMm ; // gravitational parameter of this particle double v[D] ; // velocity double T ; // kinetic energy double V ; // potential energy double r ; // absolute distance from origin } ; // Note the definition of a structure ends with a semicolon struct control { int verbose ; // program verbosity int printing ; // period with which to print }; void Force( particle &a ) // sets the force vector and the potential energy { double R = 0.0 ; for ( int i = 0 ; i < D ; i++ ) { R += a.x[i] * a.x[i] ; } double r = sqrt(R) ; a.V = - a.GMm / r ; a.r = r ; for ( int i = 0 ; i < D ; i++ ) { a.F[i] = - a.GMm * a.x[i] / (r*R) ; // inverse sq } } void PositionStep ( particle &a , double dt ) { // the "&" indicates 'this is a pass by reference' for ( int i = 0 ; i < D ; i++ ) { a.x[i] += dt * a.p[i] * a.im ; } } void MomentumStep ( particle &a , double dt ) { // the "&" indicates 'this is a pass by reference. for ( int i = 0 ; i < D ; i++ ) { a.p[i] += dt * a.F[i] ; } } void v2p( particle &a ) // propagate a change in velocity into the momentum vector { for ( int i = 0 ; i < D ; i++ ) { a.p[i] = a.v[i] / a.im ; } } void p2v ( particle &a ) { for ( int i = 0 ; i < D ; i++ ) { a.v[i] = a.p[i] * a.im ; } } void pv2T ( particle &a ) { a.T=0.0; for ( int i = 0 ; i < D ; i++ ) { a.T += 0.5*a.v[i] * a.p[i] ; } } void showState ( particle &a ) { for ( int i = 0 ; i < D ; i++ ) { cout << "\t"<