Пример #1
0
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.
}
Пример #2
0
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);
	
}
Пример #3
0
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.
}
Пример #4
0
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");
}
Пример #5
0
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);
}
Пример #8
0
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
}
Пример #10
0
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.
}
Пример #11
0
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");
}
Пример #12
0
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();	
}
Пример #13
0
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();
    }

}
Пример #14
0
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();
	}
}