Beispiel #1
0
void reb_move_to_com(struct reb_simulation* const r){
	const int N = r->N;
	struct reb_particle* restrict const particles = r->particles;
	struct reb_particle com = reb_get_com(r);
	for (int i=0;i<N;i++){
		particles[i].x  -= com.x;
		particles[i].y  -= com.y;
		particles[i].z  -= com.z;
		particles[i].vx -= com.vx;
		particles[i].vy -= com.vy;
		particles[i].vz -= com.vz;
	}
}
void rebx_modify_orbits_forces(struct reb_simulation* const sim, struct rebx_effect* const effect){
    const struct rebx_params_modify_orbits_forces* const params = effect->paramsPtr;
    const int N_real = sim->N - sim->N_var;

    struct reb_particle com;
    switch(params->coordinates){
    case JACOBI:
        com = reb_get_jacobi_com(&sim->particles[N_real-1]);    // We start with outermost particle, so get its jacobi COM
        break;
    case BARYCENTRIC:
        com = reb_get_com(sim);                           // COM of whole system
        break;
    case HELIOCENTRIC:
        com = sim->particles[0];                    // Use the central body as the reference
        break;
    default:
        fprintf(stderr, "coordinates in parameters for modify_orbits_forces are not supported.\n");
        exit(1);
    }

    struct reb_particle* p0 = &sim->particles[0];

    for(int i=N_real-1;i>0;--i){
        struct reb_particle* p = &sim->particles[i];
        double tau_a = rebx_get_param_double(p, "tau_a");
        double tau_e = rebx_get_param_double(p, "tau_e");
        double tau_inc = rebx_get_param_double(p, "tau_inc");

        if(isnan(tau_a)){
            rebx_set_param_double(p, "tau_a", INFINITY);
            tau_a = INFINITY;
        }
        if(isnan(tau_e)){
            rebx_set_param_double(p, "tau_e", INFINITY);
            tau_e = INFINITY;
        }
        if(isnan(tau_inc)){
            rebx_set_param_double(p, "tau_inc", INFINITY);
            tau_inc = INFINITY;
        }

        const double dvx = p->vx - com.vx;
        const double dvy = p->vy - com.vy;
        const double dvz = p->vz - com.vz;

        double ax = 0.;
        double ay = 0.;
        double az = 0.;

        ax =  dvx/(2.*tau_a);
        ay =  dvy/(2.*tau_a);
        az =  dvz/(2.*tau_a);

        if (tau_e < INFINITY || tau_inc < INFINITY){   // need h and e vectors for both types
            const double dx = p->x-com.x;
            const double dy = p->y-com.y;
            const double dz = p->z-com.z;
            const double r = sqrt ( dx*dx + dy*dy + dz*dz );
            const double vr = (dx*dvx + dy*dvy + dz*dvz)/r;
            const double prefac = 2*vr/r;
            ax += prefac*dx/tau_e;
            ay += prefac*dy/tau_e;
            az += prefac*dz/tau_e + 2.*dvz/tau_inc;
        }
        p->ax += ax;
        p->ay += ay;
        p->az += az;
        p0->ax -= p->m/p0->m*ax;    // add back reactions onto central body 
        p0->ay -= p->m/p0->m*ay;
        p0->az -= p->m/p0->m*az;

        if(params->coordinates == JACOBI){
            rebxtools_update_com_without_particle(&com, p);
        }
    }
}