void problem_init(int argc, char* argv[]){ dt = 0.01*2.*M_PI; // initial timestep #ifdef OPENGL display_wire = 1; // show instantaneous orbits #endif // OPENGL collision_resolve = collision_resolve_merger; // Setup our own collision routine. init_boxwidth(10); struct particle star; star.m = 1; star.r = 0.1; star.x = 0; star.y = 0; star.z = 0; star.vx = 0; star.vy = 0; star.vz = 0; particles_add(star); // Add planets int N_planets = 7; for (int i=0;i<N_planets;i++){ double a = 1.+(double)i/(double)(N_planets-1); // semi major axis in AU double v = sqrt(1./a); // velocity (circular orbit) struct particle planet; planet.m = 1e-4; planet.r = 4e-2; // radius in AU (it is unphysically large in this example) planet.lastcollision = 0; // The first time particles can collide with each other planet.x = a; planet.y = 0; planet.z = 0; planet.vx = 0; planet.vy = v; planet.vz = 0; particles_add(planet); } tools_move_to_center_of_momentum(); // This makes sure the planetary systems stays within the computational domain and doesn't drift. }
void problem_init(int argc, char* argv[]){ // Setup constants G = 1; // Gravitational constant #ifdef OPENGL display_wire = 1; // show istantaneous orbits. #endif // OPENGL double e_testparticle = 1.-1e-7; double mass_scale = 1.; // Some integrators have problems when changing the mass scale, IAS15 does not. double size_scale = 1; // Some integrators have problems when changing the size scale, IAS15 does not. boxsize = 25.*size_scale; init_box(); struct particle star; star.m = mass_scale; star.x = 0; star.y = 0; star.z = 0; star.vx = 0; star.vy = 0; star.vz = 0; particles_add(star); struct particle planet; planet.m = 0; planet.x = size_scale*(1.-e_testparticle); planet.y = 0; planet.z = 0; planet.vx = 0; planet.vy = sqrt((1.+e_testparticle)/(1.-e_testparticle)*mass_scale/size_scale); planet.vz = 0; particles_add(planet); tools_move_to_center_of_momentum(); // initial timestep dt = 1e-13*sqrt(size_scale*size_scale*size_scale/mass_scale); tmax = 1e2*2.*M_PI*sqrt(size_scale*size_scale*size_scale/mass_scale); }
void problem_init(int argc, char* argv[]){ dt = 0.01*2.*M_PI; // initial timestep // integrator_epsilon = 1e-2; // accuracy parameter, default is 1e-2 and should work in most cases. #ifdef OPENGL display_wire = 1; // show instantaneous orbits #endif // OPENGL init_boxwidth(10); struct particle star; star.m = 1; star.x = 0; star.y = 0; star.z = 0; star.vx = 0; star.vy = 0; star.vz = 0; particles_add(star); // Add planets int N_planets = 7; for (int i=0;i<N_planets;i++){ double a = 1.+(double)i/(double)(N_planets-1); // semi major axis double v = sqrt(1./a); // velocity (circular orbit) struct particle planet; planet.m = 1e-4; planet.x = a; planet.y = 0; planet.z = 0; planet.vx = 0; planet.vy = v; planet.vz = 0; particles_add(planet); } tools_move_to_center_of_momentum(); // This makes sure the planetary systems stays within the computational domain and doesn't drift. }
void problem_init(int argc, char* argv[]){ // Setup constants dt = 40; // in days N_active = 5; // we treat pluto as a test particle. If all your particles have mass, remove this line. tmax = 7.3e10; // 200 Myr G = k*k; // These are the same units as used by the mercury6 code. #ifdef OPENGL display_wire = 1; // Show orbits. #endif // OPENGL init_boxwidth(200); // Init box with width 200 astronomical units // Initial conditions for (int i=0;i<6;i++){ struct particle p; p.x = ss_pos[i][0]; p.y = ss_pos[i][1]; p.z = ss_pos[i][2]; p.vx = ss_vel[i][0]; p.vy = ss_vel[i][1]; p.vz = ss_vel[i][2]; p.ax = 0; p.ay = 0; p.az = 0; p.m = ss_mass[i]; particles_add(p); } #ifdef INTEGRATOR_WH // Move to heliocentric frame (required by WH integrator) for (int i=1;i<N;i++){ particles[i].x -= particles[0].x; particles[i].y -= particles[0].y; particles[i].z -= particles[0].z; particles[i].vx -= particles[0].vx; particles[i].vy -= particles[0].vy; particles[i].vz -= particles[0].vz; } particles[0].x = 0; particles[0].y = 0; particles[0].z = 0; particles[0].vx= 0; particles[0].vy= 0; particles[0].vz= 0; #else tools_move_to_center_of_momentum(); #endif // INTEGRATOR_WH system("rm -f orbits.txt"); }
void problem_init(int argc, char* argv[]){ // Setup constants G = 1; // Setup particles int _N = 100; // Number of particles double M = 1; // Total mass of the cluster double R = 1; // Radius of the cluster double E = 3./64.*M_PI*M*M/R; // Energy of the cluster double r0 = 16./(3.*M_PI)*R; // Chacateristic length scale double t0 = G*pow(M,5./2.)*pow(4.*E,-3./2.)*(double)_N/log(0.4*(double)_N); // Rellaxation time printf("Characteristic size: %f\n", r0); printf("Characteristic time (relaxation): %f\n", t0); dt = 1e-4*t0; // timestep tmax = 20.*t0; // Integration time boxsize = 20.*r0; // Size of box (open boundaries) softening = 0.01*r0; // Softening parameter init_box(); // Set up box (uses variable 'boxsize') tools_init_plummer(_N, M, R); // Add particles tools_move_to_center_of_momentum(); // Move to rest frame }
void problem_init(int argc, char* argv[]){ dt = 0.012*2.*M_PI; // initial timestep integrator = HYBRID; //softening = 0.001; //integrator = IAS15; //integrator = WHFAST; integrator_whfast_corrector = 5; integrator_whfast_synchronize_manually = 1; #ifdef OPENGL display_wire = 1; // show instantaneous orbits #endif // OPENGL init_boxwidth(20); struct particle star; star.m = 1; star.x = 0; star.y = 0; star.z = 0; star.vx = 0; star.vy = 0; star.vz = 0; particles_add(star); // Add planets int N_planets = 3; for (int i=0;i<N_planets;i++){ double a = 1.+.1*(double)i; // semi major axis double v = sqrt(1./a); // velocity (circular orbit) struct particle planet; planet.m = 2e-5; planet.x = a; planet.y = 0; planet.z = 0; planet.vx = 0; planet.vy = v; planet.vz = 0; particles_add(planet); } tools_move_to_center_of_momentum(); // This makes sure the planetary systems stays within the computational domain and doesn't drift. e_init = tools_energy(); system("rm -rf energy.txt"); }
void problem_init(int argc, char* argv[]) { // Setup constants integrator = WHFAST; dt = 0.001*2.*M_PI; // initial timestep (in days) init_boxwidth(200); // Initial conditions { struct particle p = {.m=1.,.x=0,.y=0.,.z=0.,.vx=0,.vy=0.,.vz=0.}; particles_add(p); } { double e = 0.999; struct particle p = {.m=0.,.x=0.01,.y=0.,.z=0.,.vx=0,.vy=0.*sqrt((1.+e)/(1.-e)),.vz=0.}; particles_add(p); } tools_move_to_center_of_momentum(); //problem_additional_forces = additional_forces; // Add megno particles //tools_megno_init(1e-16); // N = 6 after this function call. system("rm -f *.txt"); ei = energy(); } void additional_forces() { particles[1].ax += 0.12/6.; } double energy() { double e_kin = 0.; double e_pot = 0.; struct particle pi = particles[1]; e_kin += 0.5 * (pi.vx*pi.vx + pi.vy*pi.vy + pi.vz*pi.vz); struct particle pj = particles[0]; double dx = pi.x - pj.x; double dy = pi.y - pj.y; double dz = pi.z - pj.z; e_pot -= G*pj.m/sqrt(dx*dx + dy*dy + dz*dz); return e_kin +e_pot; } int no =0; void problem_output() { no++; // printf("%d\n", no); if (output_check(1000.*dt)) { output_timing(); } // FILE* f = fopen("Y.txt","a+"); // fprintf(f,"%e %e %e\n",t,(energy()-ei)/ei,tools_megno()); // fclose(f); }
void problem_init(int argc, char* argv[]){ // Setup constants dt = 1e-4; // Initial timestep. boxsize = 10; tmax = 1e6; N_active = 2; // Only the star and the planet are massive. problem_additional_forces = force_radiation; init_box(); // Star struct particle star; star.x = 0; star.y = 0; star.z = 0; star.vx = 0; star.vy = 0; star.vz = 0; star.ax = 0; star.ay = 0; star.az = 0; star.m = 1.; particles_add(star); // Planet struct particle planet; planet.m = 1e-3; planet.x = 1; planet.y = 0.; planet.z = 0.; planet.ax = 0; planet.ay = 0; planet.az = 0; planet.vx = 0; planet.vy = sqrt(G*(star.m+planet.m)/planet.x); planet.vz = 0; particles_add(planet); // Dust particles while(N<3){ // Three particles in total (star, planet, dust particle) struct particle p; p.m = 0; // massless double r = 0.001; // distance from planet planet double v = sqrt(G*planet.m/r); p.x = r; p.y = 0; p.z = 0; p.vx = 0; p.vy = v; p.vz = 0; p.x += planet.x; p.y += planet.y; p.z += planet.z; p.vx += planet.vx; p.vy += planet.vy; p.vz += planet.vz; p.ax = 0; p.ay = 0; p.az = 0; particles_add(p); } tools_move_to_center_of_momentum(); system("rm -v a.txt"); }
void problem_init(int argc, char* argv[]){ // Setup constants integrator = IAS15; dt = 1e-6; // initial timestep boxsize = 0.01; tmax = 3e1; N_active = 2; // only the star and the planet are massive. problem_additional_forces = force_J2; init_box(); // Planet struct particle planet; planet.m = Msaturn; planet.x = 0; planet.y = 0; planet.z = 0; planet.vx = 0; planet.vy = 0; planet.vz = 0; particles_add(planet); // Read obliquity from command line. Default is 0. ObliquityPlanet = input_get_double(argc,argv,"Obliquity",0.)/180.*M_PI; // Add one dust particles while(N<2){ // two particles in total (planet and dust particle) struct particle p; p.m = 0; // massless double a = Rplanet*3.; // small distance from planet (makes J2 important) double e = 0.1; double v = sqrt((1.+e)/(1.-e)*G*planet.m/a); // setup eccentric orbit (ignores J2) p.x = (1.-e)*a; p.y = 0; p.z = 0; p.vx = 0; p.vy = v; p.vz = 0; p.x += planet.x; p.y += planet.y; p.z += planet.z; p.vx += planet.vx; p.vy += planet.vy; p.vz += planet.vz; particles_add(p); } tools_move_to_center_of_momentum(); system("rm -v a.txt"); // delete previous output }
void problem_init(int argc, char* argv[]){ // Setup constants dt = 10; // initial timestep (in days) //integrator = IAS15; integrator = WHFAST; const double k = 0.01720209895; // Gaussian constant G = k*k; // These are the same units that mercury6 uses init_boxwidth(200); // Initial conditions for (int i=0;i<3;i++){ struct particle p; p.x = ss_pos[i][0]; p.y = ss_pos[i][1]; p.z = ss_pos[i][2]; p.vx = ss_vel[i][0]; p.vy = ss_vel[i][1]; p.vz = ss_vel[i][2]; p.ax = 0; p.ay = 0; p.az = 0; p.m = ss_mass[i]; particles_add(p); } tools_move_to_center_of_momentum(); // Add megno particles tools_megno_init(1e-16); // N = 6 after this function call. // The first half of particles are real particles, the second half are particles following the variational equations. }
void problem_init(int argc, char* argv[]){ // Setup constants dt = 4; // in days tmax = 7.3e10; // 200 Myr G = 1.4880826e-34; // in AU^3 / kg / day^2. init_boxwidth(200); // Init box with width 200 astronomical units integrator_whfast_synchronize_manually = 1; // Need to call integrator_synchronize() before outputs. integrator_force_is_velocitydependent = 0; // Force only depends on positions. //integrator = WH; integrator = WHFAST; //integrator = IAS15; // Initial conditions for (int i=0;i<10;i++){ struct particle p; p.x = ss_pos[i][0]; p.y = ss_pos[i][1]; p.z = ss_pos[i][2]; p.vx = ss_vel[i][0]; p.vy = ss_vel[i][1]; p.vz = ss_vel[i][2]; p.ax = 0; p.ay = 0; p.az = 0; p.m = ss_mass[i]; particles_add(p); } if (integrator==WH){ // Move to heliocentric frame (required by WH integrator) for (int i=1;i<N;i++){ particles[i].x -= particles[0].x; particles[i].y -= particles[0].y; particles[i].z -= particles[0].z; particles[i].vx -= particles[0].vx; particles[i].vy -= particles[0].vy; particles[i].vz -= particles[0].vz; } particles[0].x = 0; particles[0].y = 0; particles[0].z = 0; particles[0].vx= 0; particles[0].vy= 0; particles[0].vz= 0; }else{ tools_move_to_center_of_momentum(); } //tools_megno_init(1e-16); e_init = energy(); system("rm -f energy.txt"); system("rm -f pos.txt"); }
void collision_resolve_merger(struct collision c){ struct particle p1 = particles[c.p1]; struct particle p2 = particles[c.p2]; double x21 = p1.x - p2.x; double y21 = p1.y - p2.y; double z21 = p1.z - p2.z; double rp = p1.r+p2.r; printf("collision 1\n"); if (rp*rp < x21*x21 + y21*y21 + z21*z21) return; // not overlapping double vx21 = p1.vx - p2.vx; double vy21 = p1.vy - p2.vy; double vz21 = p1.vz - p2.vz; printf("collision 2\n"); if (vx21*x21 + vy21*y21 + vz21*z21 >0) return; // not approaching printf("collision 3 %f %f %f\n", p1.lastcollision, p2.lastcollision, t); if (p1.lastcollision>=t || p2.lastcollision>=t) return; // already collided printf("collision 4\n"); particles[c.p2].lastcollision = t; particles[c.p1].lastcollision = t; // Note: We assume only one collision per timestep. // Setup new particle (in position of particle p1. Particle p2 will be discarded. struct particle cm = tools_get_center_of_mass(p1, p2); particles[c.p1].x = cm.x; particles[c.p1].y = cm.y; particles[c.p1].z = cm.z; particles[c.p1].vx = cm.vx; particles[c.p1].vy = cm.vy; particles[c.p1].vz = cm.vz; particles[c.p1].r = p1.r*pow(cm.m/p1.m,1./3.); // Assume a constant density particles[c.p1].m = cm.m; // Remove one particle. N--; particles[c.p2] = particles[N]; // Make sure we don't drift, so let's go back to the center of momentum tools_move_to_center_of_momentum(); }
void problem_init(int argc, char* argv[]){ /* Setup constants */ boxsize = 3; // in AU integrator = WHFAST; integrator_whfast_corrector = 0; integrator_whfast_synchronize_manually = 0; tmax = atof(argv[2]); // in year/(2*pi) Keplername = argv[1]; //Kepler system being investigated, Must be first string after ./nbody! p_suppress = 0; //If = 1, suppress all print statements double RT = 0.06; //Resonance Threshold - if abs(P2/2*P1 - 1) < RT, then close enough to resonance double timefac = 25.0; //Number of kicks per orbital period (of closest planet) /* Migration constants */ mig_forces = 1; //If ==0, no migration. K = 100; //tau_a/tau_e ratio. I.e. Lee & Peale (2002) e_ini = atof(argv[3]); //atof(argv[3]); //initial eccentricity of the planets afac = atof(argv[4]); //Factor to increase 'a' of OUTER planets by. double iptmig_fac = atof(argv[5]); //reduction factor of inner planet's t_mig (lower value = more eccentricity) double Cin = atof(argv[6]); //migration speed of outer planet inwards. Nominal is 6 /* Tide constants */ tides_on = 1; //If ==0, then no tidal torques on planets. tide_force = 0; //if ==1, implement tides as *forces*, not as e' and a'. double k2fac = atof(argv[7]); //multiply k2 by this factor inner_only = 0; //if =1, allow only the inner planet to evolve under tidal influence //k2fac_check(Keplername,&k2fac); //For special systems, make sure that if k2fac is set too high, it's reduced. #ifdef OPENGL display_wire = 1; #endif // OPENGL init_box(); printf("%f k2fac \n \n \n",k2fac); //Naming naming(Keplername, txt_file, K, iptmig_fac, e_ini, k2fac, tide_force); // Initial vars if(p_suppress == 0) printf("You have chosen: %s \n",Keplername); double Ms,Rs,a,mp,rp,k2,Q,max_t_mig=0, P_temp; int char_val; //Star & Planet 1 readplanets(Keplername,txt_file,&char_val,&_N,&Ms,&Rs,&mp,&rp,&P_temp,p_suppress); if(mig_forces == 0 && p_suppress == 0) printf("--> Migration is *off* \n"); if(tides_on == 0 && p_suppress == 0) printf("--> Tides are *off* \n"); struct particle star; //Star MUST be the first particle added. star.x = 0; star.y = 0; star.z = 0; star.vx = 0; star.vy = 0; star.vz = 0; star.ax = 0; star.ay = 0; star.az = 0; star.m = Ms; star.r = Rs; particles_add(star); //timestep - units of 2pi*yr (required) dt = 2.*M_PI*P_temp/(365.*timefac); if(p_suppress == 0) printf("The timestep used for this simulation is (2pi*years): %f \n",dt); //Arrays, Extra slot for star, calloc sets values to 0 already. tau_a = calloc(sizeof(double),_N+1); //migration speed of semi-major axis tau_e = calloc(sizeof(double),_N+1); //migration (damp) speed of eccentricity lambda = calloc(sizeof(double),_N+1); //resonant angle for each planet omega = calloc(sizeof(double),_N+1); //argument of periapsis for each planet expmigfac = calloc(sizeof(double),_N+1); t_mig = calloc(sizeof(double),_N+1); t_damp = calloc(sizeof(double),_N+1); phi_i = calloc(sizeof(int),_N+1); //phi index (for outputting resonance angles) if(tide_force == 1){ //tidetau_a = calloc(sizeof(double),_N+1); tidetauinv_e = calloc(sizeof(double),_N+1); } double P[_N+1]; //array of period values, only needed locally P[1] = P_temp; if(inner_only == 1) planets_with_tides = 1; else planets_with_tides = _N+1; //planet 1 calcsemi(&a,Ms,P[1]); //I don't trust archive values. Make it all consistent migration(Keplername,tau_a, t_mig, t_damp, &expmigfac[1], 0, &max_t_mig, P, 1, RT, Ms, mp, iptmig_fac, a, afac, p_suppress, Cin); struct particle p = tools_init_orbit2d(Ms, mp, a*afac, e_ini, 0, 0.); tau_e[1] = tau_a[1]/K; assignk2Q(&k2, &Q, k2fac, rp); p.Q=Q; p.k2=k2; p.r = rp; particles_add(p); //print/writing stuff printf("System Properties: # planets=%d, Rs=%f, Ms=%f \n",_N, Rs, Ms); printwrite(1,txt_file,a,P[1],e_ini,mp,rp,k2/Q,tau_a[1],t_mig[1],t_damp[1],afac,p_suppress); //outer planets (i=0 is star) for(int i=2;i<_N+1;i++){ extractplanets(&char_val,&mp,&rp,&P[i],p_suppress); calcsemi(&a,Ms,P[i]); migration(Keplername,tau_a, t_mig, t_damp, &expmigfac[i], &phi_i[i], &max_t_mig, P, i, RT, Ms, mp, iptmig_fac, a, afac, p_suppress, Cin); struct particle p = tools_init_orbit2d(Ms, mp, a*afac, e_ini, 0, i*M_PI/4.); tau_e[i] = tau_a[i]/K; assignk2Q(&k2, &Q, k2fac, rp); p.Q = Q; p.k2 = k2; p.r = rp; particles_add(p); printwrite(i,txt_file,a,P[i],e_ini,mp,rp,k2/Q,tau_a[i],t_mig[i],t_damp[i],afac,p_suppress); } //tidal delay if(max_t_mig < 20000)tide_delay = 20000.; else tide_delay = max_t_mig + 20000.; //Have at least 30,000 years grace before turning on tides. double tide_delay_output = 0; if(tides_on == 1) tide_delay_output = tide_delay; FILE *write; write=fopen(txt_file, "a"); fprintf(write, "%f \n",tide_delay_output); fclose(write); tide_print = 0; problem_additional_forces = problem_migration_forces; //Set function pointer to add dissipative forces. integrator_force_is_velocitydependent = 1; if (integrator != WH){ // The WH integrator assumes a heliocentric coordinate system. tools_move_to_center_of_momentum(); } }
void problem_output(){ //conditions for entering loops int output_var=0; if(output_check(tmax/10000.)) output_var = 1; //Used to be 100,000 else if(t < tide_delay && output_check(100.)) output_var = 1; //used to be 100 int tide_go = 0; if(tides_on == 1 && tide_force == 0 && t > tide_delay) tide_go = 1; //**Main Loop** if(output_var == 1 || tide_go == 1){ //Calculate Orbital Elements struct particle com = particles[0]; double r_nrgy[N]; //calculating energy of particle double v2_nrgy[N]; double m_nrgy[N]; for(int i=1;i<N;i++){ struct particle* par = &(particles[i]); const double m = par->m; const double mu = G*(com.m + m); const double rp = par->r*0.00464913; //Rp from Solar Radii to AU, G=1, [t]=yr/2pi, [m]=m_star const double Qp = par->k2/(par->Q); const double dvx = par->vx-com.vx; const double dvy = par->vy-com.vy; const double dvz = par->vz-com.vz; const double dx = par->x-com.x; const double dy = par->y-com.y; const double dz = par->z-com.z; const double v = sqrt ( dvx*dvx + dvy*dvy + dvz*dvz ); const double r = sqrt ( dx*dx + dy*dy + dz*dz ); const double rinv = 1./r; //some extra terms to speed up code const double vr = (dx*dvx + dy*dvy + dz*dvz)*rinv; const double muinv = 1./mu; const double term1 = v*v-mu*rinv; const double term2 = r*vr; const double ex = muinv*( term1*dx - term2*dvx ); const double ey = muinv*( term1*dy - term2*dvy ); const double ez = muinv*( term1*dz - term2*dvz ); double e = sqrt( ex*ex + ey*ey + ez*ez ); // eccentricity // true anomaly + periapse (wiki, Fund. of Astrodyn. and App., by Vallado, 2007) const double rdote = dx*ex + dy*ey + dz*ez; double cosf = rdote/(e*r); if(cosf >= 1.) cosf = 1.; if(cosf <= -1.) cosf = -1.; double sinf = sqrt(1. - cosf*cosf); if(vr < 0.) sinf *= -1.; double sinwf = dy*rinv; double coswf = dx*rinv; double a = r*(1. + e*cosf)/(1. - e*e); double n; //Test for collision if(N < _N+1 && collision_print == 0){ printf("\n\n system %s with e_ini=%f,e_now=%f had a collision!! \n\n",Keplername,e_ini,e); FILE *append; append=fopen("python_scripts/Kepler_e_coll.txt", "a"); fprintf(append,"%s,%e,%e\n",Keplername,e_ini,t); fclose(append); collision_print = 1; } //Energy calculation - values may be updated via tides, but probably won't matter r_nrgy[i] = r; v2_nrgy[i] = v*v; m_nrgy[i] = m; //Tides if(tide_go == 1 && i<=planets_with_tides){ const double a2 = a*a; const double rp2 = rp*rp; const double R5a5 = rp2*rp2*rp/(a2*a2*a); const double GM3a3 = sqrt(G*com.m*com.m*com.m/(a2*a)); const double de = -dt*(9.*M_PI*0.5)*Qp*GM3a3*R5a5*e/m; //Tidal change for e const double da = 2.*a*e*de; //Tidal change for a a += da; e += de; integrator_whfast_particles_modified = 1; /* //Test repulsion vs. tugging (change w to put planets out of res) if(repuls_v_tugg_on == 0 && i==1 && p_suppress == 0){ repuls_v_tugg_on = 1; double angle_change = 0.34*(M_PI/180.); double costemp = coswf; double sintemp = sinwf; coswf = costemp*cos(angle_change) - sintemp*sin(angle_change); sinwf = sintemp*cos(angle_change) - costemp*sin(angle_change); printf("\n ***Testing Repulsion vs. tugging. Planets put out of resonance.*** \n"); }*/ //Re-update coords. const double r_new = a*(1. - e*e)/(1. + e*cosf); const double x_new = r_new*coswf + com.x; const double y_new = r_new*sinwf + com.y; n = sqrt(mu/(a*a*a)); const double term = n*a/sqrt(1.- e*e); const double rdot = term*e*sinf; const double rfdot = term*(1. + e*cosf); const double vx_new = rdot*coswf - rfdot*sinwf + com.vx; const double vy_new = rdot*sinwf + rfdot*coswf + com.vy; // ******NOTE NO VZ_NEW CURRENTLY. NEED THIS FOR PLANETESIMALS //Stop program if nan values being produced. if(x_new!=x_new || y_new!=y_new || vx_new!=vx_new ||vy_new!=vy_new){ printf("\n !!Failed run for: %s \n",Keplername); printf("cartesian before: dx=%f,dy=%f,dz=%f,ex=%f,ey=%f,ez=%f,r=%f,vx=%f,vy=%f,com.vx=%f,com.vy=%f,v=%f \n",dx,dy,dz,ex,ey,ez,r,par->vx,par->vy,com.vx,com.vy,v); printf("Orbital elements: mu=%f,e=%f,a=%f,cosf=%.15f,sinf=%.15f,dt=%f,de=%f,da=%f,GM3a3=%f,R5a5=%f \n",mu,e,a,cosf,sinf,dt,de,da,GM3a3,R5a5); printf("\n cartesian after: x_new=%f,y_new=%f,vx_new=%f,vy_new=%f,term=%f,rdot=%f,rfdot=%f \n",x_new,y_new,vx_new,vy_new,term,rdot,rfdot); exit(0); } par->x = x_new; par->y = y_new; par->vx = vx_new; par->vy = vy_new; com = tools_get_center_of_mass(com,particles[i]); //print message if(tide_print == 0 && p_suppress == 0){ printf("\n\n ***Tides (a', e') have just been turned on at t=%f years***\n\n",t); tide_print = 1; } } else { n = sqrt(mu/(a*a*a)); //Still need to calc this for period. } if(output_var == 1){ omega[i] = atan2(ey,ex); if(ey < 0.) omega[i] += 2*M_PI; double cosE = (a - r)/(a*e); double E; if(cosf > 1. || cosf < -1.){ E = M_PI - M_PI*cosE; } else { E = acos(cosE); } if(vr < 0.) E = 2.*M_PI - E; double MA = E - e*sin(E); lambda[i] = MA + omega[i]; double phi = 0., phi2 = 0., phi3 = 0.; //resonant angles if(i>1){//tailored for 2:1 resonance, between inner/outer planet phi = 2.*lambda[i] - lambda[i-phi_i[i]] - omega[i-phi_i[i]]; phi2 = 2.*lambda[i] - lambda[i-phi_i[i]] - omega[i]; phi3 = omega[i-phi_i[i]] - omega[i]; } while(phi >= 2*M_PI) phi -= 2*M_PI; while(phi < 0.) phi += 2*M_PI; while(phi2 >= 2*M_PI) phi2 -= 2*M_PI; while(phi2 < 0.) phi2 += 2*M_PI; while(phi3 >= 2*M_PI) phi3 -= 2*M_PI; while(phi3 < 0.) phi3 += 2*M_PI; //Calculate total Energy and ang. mom. of the system double Etot = 0; double L = 0; if(i==N-1){//Total energy, wait till array values are filled. for(int j=1;j<N;j++){ Etot += 0.5*m*v2_nrgy[j]; //kinetic Etot -= com.m*m/r_nrgy[j]; //star-planet potential for(int k=1;k<j;k++) Etot -= m_nrgy[k]*m_nrgy[j]/(r_nrgy[k] - r_nrgy[j]); //interaction potential } } L = sqrt(G*com.m*a*(1-e*e)); //integrator_synchronize(); //if synchronize_manual = 1, then call this before each output to synchronize x and vx. //output orbits in txt_file. FILE *append; append=fopen(txt_file, "a"); //output order = time(yr/2pi),a(AU),e,P(days),arg. of peri., mean anomaly, // eccentric anomaly, mean longitude, resonant angle, de/dt, phi1 phi2 phi3 fprintf(append,"%e\t%.10e\t%e\t%e\t%e\t%e\t%e\t%e\t%e\t%e\t%e\t%e\t%e\n",t,a,e,365./n,omega[i],MA,E,lambda[i],phi,phi2,phi3,L,Etot); fclose(append); if (integrator != WH){ // The WH integrator assumes a heliocentric coordinate system. tools_move_to_center_of_momentum(); } } } } if(output_check(10000.*dt)){ output_timing(); } }