Beispiel #1
0
// This function creates a simulation with one star, one planet and one test particle.
struct reb_simulation* create_sim(){
	struct reb_simulation* r = reb_create_simulation();
    // r->integrator = REB_INTEGRATOR_WHFAST;  Only first order variational equations supported in WHFast.
    struct reb_particle star = {0.};
    star.m = 1;
    reb_add(r, star);
    struct reb_particle planet = reb_tools_orbit_to_particle(1.,star,1e-3,1.,0.,0.,0.,0.,0.);
    reb_add(r, planet);
    struct reb_particle testparticle = reb_tools_orbit_to_particle(1.,star,0.,1.7,0.1,0.2,0.3,0.4,0.5);
    reb_add(r, testparticle);
    return r;
}
Beispiel #2
0
int main(int argc, char* argv[]) {
	struct reb_simulation* r;
    int var_i, var_ii;

    // We first integrate the vanilla simulation forward in time and look at the position of the testparticle at the end of the simulation.
    r = create_sim();
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100:                             %.8f %.8f\n",r->particles[2].x,r->particles[2].y);
    reb_free_simulation(r);
    
    // Next, we shift the planet's initial x coordinate by a small amount and integrate the system again up til t=100. 
    double DeltaX = 0.001;
    printf("\nShifting planet's x coordinate by %f.\n", DeltaX);
    r = create_sim();
    r->particles[1].x += DeltaX;
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 in shifted simulation:       %.8f %.8f\n",r->particles[2].x,r->particles[2].y);
    reb_free_simulation(r);
    
    // Instead of shifting the initial x coordinate, we can also use variational equations. 
    r = create_sim();
    var_i = reb_add_var_1st_order(r, -1);   // The -1 means we vary a particle which is not a testparticle  and therefore can influence other particles
    
    // By default all components of variational particles are initialized to zero.
    // We are interested in shifting the planet's x coordinates and thus initialize the x coordinate of the variational particle to 1.
    r->particles[var_i+1].x = 1.;           
	reb_integrate(r,100.);
    // After the integration ran, we can estimate where the test particle would have been had we shifted the inner planet's initial x coordinate.
    printf("Position of testparticle at t=100 using 1st order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i+2].x,r->particles[2].y+DeltaX*r->particles[var_i+2].y);
    reb_free_simulation(r);

    // Better yet, we can use second order variational particles.
    r = create_sim();
    var_i = reb_add_var_1st_order(r, -1);
    var_ii = reb_add_var_2nd_order(r, -1, var_i, var_i);
    r->particles[var_i+1].x = 1.;
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 using 2nd order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i+2].x+DeltaX*DeltaX/2.*r->particles[var_ii+2].x,r->particles[2].y+DeltaX*r->particles[var_i+2].y+DeltaX*DeltaX/2.*r->particles[var_ii+2].y);
    reb_free_simulation(r);

    
    // We now do the same as above, but vary the testparticle's position 
    printf("\nShifting testparticle's x coordinate by %f.\n", DeltaX);
    r = create_sim();
    r->particles[2].x += DeltaX;
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 in shifted simulation:       %.8f %.8f\n",r->particles[2].x,r->particles[2].y);
    reb_free_simulation(r);
    
    r = create_sim();
    var_i = reb_add_var_1st_order(r, 2); // The 2 corresponds to the index of the testparticle that we vary.
    r->particles[var_i].x = 1.;
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 using 1st order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i].x,r->particles[2].y+DeltaX*r->particles[var_i].y);
    reb_free_simulation(r);

    r = create_sim();
    var_i = reb_add_var_1st_order(r, 2);
    var_ii = reb_add_var_2nd_order(r, 2, var_i, var_i);
    r->particles[var_i].x = 1.;
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 using 2nd order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i].x+DeltaX*DeltaX/2.*r->particles[var_ii].x,r->particles[2].y+DeltaX*r->particles[var_i].y+DeltaX*DeltaX/2.*r->particles[var_ii].y);
    reb_free_simulation(r);

    
    // Instead of varying cartesian coordinates, we can also vary orbital elements. 
    printf("\nShifting planet's semi-major axis by %f.\n", DeltaX);
    r = create_sim();
    r->particles[2] = reb_tools_orbit_to_particle(1.,r->particles[0],0.,1.7+DeltaX,0.1,0.2,0.3,0.4,0.5);
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 in shifted simulation:       %.8f %.8f\n",r->particles[2].x,r->particles[2].y);
    reb_free_simulation(r);

    r = create_sim();
    var_i = reb_add_var_1st_order(r, 2);
    // The function that sets up the variational particle gets the same orbital parameters as the original particle.
    r->particles[var_i] = reb_derivatives_a(1.,r->particles[0],r->particles[2]);
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 using 1st order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i].x,r->particles[2].y+DeltaX*r->particles[var_i].y);
    reb_free_simulation(r);
    
    r = create_sim();
    var_i = reb_add_var_1st_order(r, 2);
    var_ii = reb_add_var_2nd_order(r, 2, var_i, var_i);
    // first derivative with respect to a
    r->particles[var_i] = reb_derivatives_a(1.,r->particles[0],r->particles[2]);
    // second derivative with respect to a
    r->particles[var_ii] = reb_derivatives_a_a(1.,r->particles[0],r->particles[2]);
	reb_integrate(r,100.);
    printf("Position of testparticle at t=100 using 2nd order var. eqs.:   %.8f %.8f\n",r->particles[2].x+DeltaX*r->particles[var_i].x+DeltaX*DeltaX/2.*r->particles[var_ii].x,r->particles[2].y+DeltaX*r->particles[var_i].y+DeltaX*DeltaX/2.*r->particles[var_ii].y);
    reb_free_simulation(r);


}
Beispiel #3
0
int main(int argc, char* argv[]) {
    int np = 20;
    omp_set_num_threads(np);
    FILE *fp2;
    char hash_name[] = "hash.csv";
    fp2 = fopen(hash_name, "w+");
    fprintf(fp2, "Hash, Mass, Radius\n");
    char filename[512] = "veras_no_frag.bin";
    // Trying to restart from the Simulation Archive.
    struct reb_simulation* r = reb_create_simulation_from_simulationarchive(filename);
    printf("Loaded Simulation Successfully\n");
    printf("Time is: %.16f\n", r->t);
    printf("N_active is: %i\n", r->N);
    printf("Timestep is: %.3f\n", r->dt);
    r->heartbeat	= heartbeat;
    r->dt = 10.0;
    r->gravity = REB_GRAVITY_TREE;
    r->integrator = REB_INTEGRATOR_WHFAST;
    r->collision = REB_COLLISION_TREE;
    r->boundary     = REB_BOUNDARY_OPEN;
    const double boxsize = 2.5e10; // about 0.15 AU, with fragments at 0.0054 AU
    reb_configure_box(r,boxsize,1,1,1);
    struct rebx_extras* rebx = rebx_init(r);
    /*
    struct rebx_effect* rad_params = rebx_add(rebx, "radiation_forces");
    double* c = rebx_add_param(rad_params, "c", REBX_TYPE_DOUBLE);
    *c = 3.e8;                          // speed of light in SI units    */


    struct reb_particle* wd = reb_get_particle_by_hash(r, reb_hash("wd"));
    int wd_index = reb_get_particle_index(wd);
    /*
    int* rad_source = rebx_add_param(&r->particles[wd_index], "radiation_source", REBX_TYPE_INT);
    *rad_source = 1;    */


    struct rebx_effect* gr_params = rebx_add(rebx, "gr");
    double* c_2 = rebx_add_param(gr_params, "c", REBX_TYPE_DOUBLE);
    *c_2 = 3.e8;
    int* source = rebx_add_param(&r->particles[wd_index], "gr_source", REBX_TYPE_INT);
    *source = 1;
    double wd_rad = wd->r;
    double disk_rad_in = 10.0*wd_rad;
    double disk_rad_out = 90.0*wd_rad;
    printf("Inner disk radius is: %f AU\n", disk_rad_in/1.496e11);
    printf("Outer disk radius is: %f AU\n", disk_rad_out/1.496e11);
    int N_disk = 2000;
    double disk_inc_low = 0.0;
    double disk_inc_high = 0.0;
    double e_low = 0.0;
    double e_high = 0.0;
    r->N_active = r->N;
    double* add_beta;
    while(r->N<N_disk + r->N_active){
        struct reb_particle pt = {0};
        double a = reb_random_uniform(disk_rad_in, disk_rad_out);
        double e = reb_random_uniform(e_low, e_high);
        double inc = reb_random_uniform(disk_inc_low, disk_inc_high);
        double Omega = reb_random_uniform(0, 2.*M_PI);
        double apsis = reb_random_uniform(0, 2.*M_PI);
        double phi = reb_random_uniform(0.0, 2.*M_PI);
        pt = reb_tools_orbit_to_particle(r->G, r->particles[wd_index], 0.0, a, e, inc, Omega, apsis, phi);
        int N_count = r->N - r->N_active;
        pt.hash = N_count + 8000;
        reb_add(r, pt);
        add_beta = rebx_add_param(&r->particles[N_count], "beta", REBX_TYPE_DOUBLE);
        *add_beta = 0.01;
    }
    r->simulationarchive_interval = 6.32e6;
    char sim_name[1000];
    filename[strlen(filename) - 4] = 0;
    sprintf(sim_name, "%s_months.bin", filename);
    r->simulationarchive_filename = sim_name;

    for (int i=0; i < r->N; i=i+1){
        fprintf(fp2, "%u, %f, %f\n", r->particles[i].hash, r->particles[i].m, r->particles[i].r);
     }
    fclose(fp2);
    reb_integrate(r, 1.6e8); // ~5 years
    rebx_free(rebx);
}
Beispiel #4
0
int main(int argc, char* argv[]){
    struct reb_simulation* sim = reb_create_simulation();
    // Setup constants 
    sim->integrator     = REB_INTEGRATOR_IAS15;
    sim->G              = 6.674e-11;    // Use SI units
    sim->dt             = 1e4;          // Initial timestep in sec
    sim->N_active       = 2;            // Only the sun and the planet affect other particles gravitationally
    sim->heartbeat      = heartbeat;
    sim->usleep     = 1000;             // Slow down integration (for visualization only)
    
    // sun
    struct reb_particle sun = {0};
    sun.m  = 1.99e30;                   // mass of Sun in kg
    reb_add(sim, sun);
    
    struct rebx_extras* rebx = rebx_init(sim); 
    struct rebx_effect* rad_params = rebx_add(rebx, "radiation_forces");
    double* c = rebx_add_param(rad_params, "c", REBX_TYPE_DOUBLE);
    *c = 3.e8;                          // speed of light in SI units 
    // Will assume particles[0] is the radiation source by default. You can also add a flag to a particle explicitly
    int* source = rebx_add_param(&sim->particles[0], "radiation_source", REBX_TYPE_INT);

    // Saturn (simulation set up in Saturn's orbital plane, i.e., inc=0, so only need 4 orbital elements 
    double mass_sat = 5.68e26;          // Mass of Saturn 
    double a_sat = 1.43e12;             // Semimajor axis of Saturn in m
    double e_sat = 0.056;               // Eccentricity of Saturn
    double pomega_sat = 0.;             // Angle from x axis to pericenter
    double f_sat = 0.;                  // True anomaly of Saturn
    struct reb_particle saturn = reb_tools_orbit2d_to_particle(sim->G, sun, mass_sat, a_sat, e_sat, pomega_sat, f_sat);

    reb_add(sim, saturn);

    /* Dust particles
     Here we imagine particles launched from Saturn's irregular Satellite Phoebe.
     Such grains will inherit the moon's orbital elements (e.g. Tamayo et al. 2011) 
        
     In order for a particle to feel radiation forces, we have to set their beta parameter, 
     the ratio of the radiation pressure force to the gravitional force from the star (Burns et al. 1979). 
     We do this in two ways below.*/
        
    double a_dust = 1.30e10;            // semimajor axis of satellite Phoebe, in m
    double e_dust = 0.16;               // eccentricity of Phoebe
    double inc_dust = 175.*M_PI/180.;   // inclination of Phoebe to Saturn's orbital plane
    double Omega_dust = 0.;             // longitude of ascending node
    double omega_dust = 0.;             // argument of pericenter
    double f_dust = 0.;                 // true anomaly

    // We first set up the orbit and add the particles
    double m_dust = 0.;                 // treat dust particles as massless
    struct reb_particle p = reb_tools_orbit_to_particle(sim->G, sim->particles[1], m_dust, a_dust, e_dust, inc_dust, Omega_dust, omega_dust, f_dust); 
    reb_add(sim, p); 

    // For the first particle we simply specify beta directly.
    double* beta = rebx_add_param(&sim->particles[2], "beta", REBX_TYPE_DOUBLE);    
    *beta = 0.1;

    // We now add a 2nd particle on the same orbit, but set its beta using physical parameters.  
    struct reb_particle p2 = reb_tools_orbit_to_particle(sim->G, sim->particles[1], 0., a_dust, e_dust, inc_dust, Omega_dust, omega_dust, f_dust); 
    reb_add(sim, p2);

    /* REBOUNDx has a convenience function to calculate beta given the gravitational constant G, the star's luminosity and mass, and the grain's physical radius, density and radiation pressure coefficient Q_pr (Burns et al. 1979). */
   
    // Particle parameters
    double radius = 1.e-5;              // in meters
    double density = 1.e3;              // kg/m3 = 1g/cc 
    double Q_pr = 1.;                   // Equals 1 in limit where particle radius >> wavelength of radiation
    double L = 3.85e26;                 // Luminosity of the sun in Watts

    beta = rebx_add_param(&sim->particles[3], "beta", REBX_TYPE_DOUBLE);    
    *beta = rebx_rad_calc_beta(sim->G, *c, sim->particles[0].m, L, radius, density, Q_pr);

    printf("Particle 2 has beta = %f\n", *beta);

    reb_move_to_com(sim);

    printf("Time\t\tEcc (p)\t\tEcc (p2)\n");
    reb_integrate(sim, tmax);
    rebx_free(rebx);                /* free memory allocated by REBOUNDx */
}
Beispiel #5
0
struct reb_particle reb_tools_orbit2d_to_particle(double G, struct reb_particle primary, double m, double a, double e, double omega, double f){
	double Omega = 0.;
	double inc = 0.;
	return reb_tools_orbit_to_particle(G, primary, m, a, e, inc, Omega, omega, f);
}