Пример #1
0
void problem_inloop(){
	if(output_check(M_PI*2.)){
		output_timing();
	}
	if(output_check(M_PI*2.*100.)){ // output every 100 years
		FILE* f = fopen("a.txt","a");
		const struct particle planet = particles[1];
		for (int i=2;i<N;i++){
			const struct particle p = particles[i]; 
			const double prx  = p.x-planet.x;
			const double pry  = p.y-planet.y;
			const double prz  = p.z-planet.z;
			const double pr   = sqrt(prx*prx + pry*pry + prz*prz); 	// distance relative to star
			
			const double pvx  = p.vx-planet.vx;
			const double pvy  = p.vy-planet.vy;
			const double pvz  = p.vz-planet.vz;
			const double pv   = sqrt(pvx*pvx + pvy*pvy + pvz*pvz); 	// distance relative to star
			
			const double a = -G*planet.m/( pv*pv - 2.*G*planet.m/pr );			// semi major axis
			
			fprintf(f,"%e\t%e\n",t,a);
		}
		fclose(f);
	}
}
Пример #2
0
void problem_output(){
	if (output_check(1e-1*2.*M_PI/OMEGA)){
		output_timing();
	}
	if (output_check(.2*M_PI/OMEGA)){
		output_ascii_mod("ascii.txt");
	}
}
Пример #3
0
void problem_output(){
	if (output_check(1000.*dt)){
		output_timing();
	}
	if (output_check(3652422.)){ 	// output heliocentric orbital elements every 10000 years
		output_append_orbits("orbits.txt");
	}
}
Пример #4
0
void problem_output(){
	if(output_check(tmax/10000.)){		// outputs to the screen
		output_timing();
	}
	// Output the time and the current timestep. Plot it to see how IAS15 automatically reduces the timestep at pericentre. 
	FILE* of = fopen("timestep.txt","a"); 
	fprintf(of,"%e\t%e\t\n",t/tmax,dt/tmax);
	fclose(of);
}
Пример #5
0
void problem_output(){
	// Output some information to the screen every 100th timestep
	if(output_check(100.*dt)){
		output_timing();
	}
	// Output the particle position to a file every timestep.
	FILE* f = fopen("r.txt","a");
	fprintf(f,"%e\t%e\t%e\n",t,particles[0].x, particles[1].vx);
	fclose(f);
}
void problem_output(){
	if (output_check(10000.)){
		output_timing();
		integrator_synchronize();
		FILE* f = fopen("energy.txt","a");
		double e = energy();
		fprintf(f,"%e %e %e\n",t, fabs((e-e_init)/e_init), tools_megno());
		fclose(f);
		printf("  Y = %.3f",tools_megno());
	}
}
void problem_output(){
	if (output_check(10.*2.*M_PI)){  
		output_timing();
	}
	if (output_check(2.*M_PI)){  
		FILE* f = fopen("energy.txt","a");
		integrator_synchronize();
		double e = tools_energy();
		fprintf(f,"%e %e\n",t, fabs((e-e_init)/e_init));
		fclose(f);
	}
}
Пример #8
0
void problem_output(){
	if (output_check(1000.*dt)){
		output_timing();
	}
	if (output_check(362.)){
		// Output the time and the MEGNO to the screen and a file.
		FILE* f = fopen("Y.txt","a+");
		fprintf(f,"        %.20e     %.20e\n",t, tools_megno());
		printf("        %.20e     %.20e\n",t, tools_megno());
		fclose(f);
	}
}
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);
}
Пример #10
0
void problem_output(){
#ifdef LIBPNG
	if (output_check(1e-3*2.*M_PI/OMEGA)){
		output_png("png/");
	}
#endif //LIBPNG
	if (output_check(1e-3*2.*M_PI/OMEGA)){
		output_timing();
		//output_append_velocity_dispersion("veldisp.txt");
	}
	if (output_check(2.*M_PI/OMEGA)){
		//output_ascii("position.txt");
	}
}
Пример #11
0
void problem_output(){
	if(output_check(4000.*dt)){				// output something to screen	
		output_timing();
	}
	if(output_check(M_PI*2.*0.01)){				// output semimajor axis to file
		FILE* f = fopen("a.txt","a");
		const struct particle planet = particles[0];
		for (int i=1;i<N;i++){
			struct orbit o = tools_p2orbit(particles[i],planet);
			fprintf(f,"%.15e\t%.15e\t%.15e\t%.15e\n",t,o.a,o.e,o.omega);
		}
		fclose(f);
	}
}
Пример #12
0
void problem_output(){
	if (output_check(10.0*dt)){
		output_timing();
	}
	for (int i=N_active;i<N;i++){
		struct particle p = particles[i];
		double r = sqrt(p.x*p.x + p.y*p.y + p.z*p.z);
		// Remove particles falling into the star.
		if (r<0.03){
			particles[i] = particles[N-1];
			i--;
			N--;
		}
	}
}
Пример #13
0
void problem_output(){
	if (t>0){
		// The damping is done at the end of the timestep rather than in the loop
		// because we need the position and velocities at the same time to 
		// calculate orbital elements. We also update both the positions 
		// and velocities in these routines.
		problem_adot();
		problem_edot();
	}
	if(output_check(10000.*dt)){
		output_timing();
	}
	if(output_check(10.)){
		output_orbits_append("orbits.txt");
	}
}
Пример #14
0
void problem_finish(){
    // Output final state
	if (output_check(dt/2)) output_timing();
	if (output_check(dt/2)) output_append_ascii("rebound.txt");
	
	/*FILE* of = fopen("error.txt","a+"); 
	double error= N_init-N;
	struct timeval tim;
	gettimeofday(&tim, NULL);
	double timing_final = tim.tv_sec+(tim.tv_usec/1000000.0);
	double error_limit = 0.1;
	int pass = (error>error_limit?0:1);
	fprintf(of,"%d\t%e\t%e\t%e\t%d\t%e\t",N,dt,error,error_limit,pass,timing_final-timing_initial);
	fprintf(of,"N_init = %d",N_init);
	fprintf(of,"\n");
	fclose(of);*/
}
Пример #15
0
void problem_output() {
    output_timing();
    if (t>tmax/2.) {
        if(reset==1) {
            collisions_plog_last 	= t;
            collisions_plog		= 0;
            nuN 			= 0;
            nutrans_tot 		= 0;
            nucoll_tot  		= 0;
            nugrav_tot  		= 0;
            reset 			= 0;
        } else {
            // Calculate viscosity
            nutrans_tot 	+= calculate_viscosity_trans();
            nugrav_tot 	+= calculate_viscosity_grav();
            nucoll_tot	 = calculate_viscosity_coll();
            nuN++;
        }
    }
}
Пример #16
0
void problem_inloop(){
	if(output_check(tmax/10000.)){		// outputs to the screen
		output_timing();
	}
}
Пример #17
0
void problem_output(){
	if (output_check(10.0*dt)) output_timing();
	if (output_check(1.)) output_ascii("ascii.txt");
}
Пример #18
0
void problem_output(){
	output_timing();
}
Пример #19
0
void problem_output(){
	if (output_check(2.*M_PI)){
		output_timing();
	}
}
Пример #20
0
void problem_inloop(){
	if(output_check(100.*dt)){
		output_timing();
	}
}
Пример #21
0
void problem_output(){
	output_timing();
	if (output_check(2.*M_PI)){
		output_orbits("orbit.txt");
	}
}
Пример #22
0
void problem_output(){
	// Screen and file output
	if (output_check(Nsteps_per_output*dt)) output_timing();
	if (output_check(Nsteps_per_output*dt)) output_append_ascii("rebound.txt");
}
Пример #23
0
void problem_output(){
	if (output_check(10.0*dt)) output_timing();
}
Пример #24
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();
	}
}