Exemple #1
0
struct rebx_param* rebx_attach_param_node(void* const object, struct rebx_param* param){
    void* ptr = rebx_get_param(object, param->name);
    if (ptr != NULL){
        char str[300];
        sprintf(str, "REBOUNDx Error: Parameter '%s' passed to rebx_add_param already exists.\n", param->name);
        reb_error(rebx_get_sim(object), str);
        return NULL;
    }
    
    switch(rebx_get_object_type(object)){
        case REBX_OBJECT_TYPE_EFFECT:
        {
            struct rebx_effect* effect = (struct rebx_effect*)object;
            param->next = effect->ap;
            effect->ap = param;
            break;
        }
        case REBX_OBJECT_TYPE_PARTICLE:
        {
            struct reb_particle* p = (struct reb_particle*)object;
            param->next = p->ap;
            p->ap = param;
            break;
        }
    }
    
    return param;
}
Exemple #2
0
void rebx_integrate(struct reb_simulation* const sim, const double dt, struct rebx_effect* const effect){
    if (effect->force == NULL){
        char str[300];
        sprintf(str, "REBOUNDx Error: rebx_integrate called with non-force effect '%s'.\n", effect->name);
        reb_error(sim, str);
    }
    struct rebx_extras* rebx = sim->extras;
    rebx_reset_accelerations(sim->particles, sim->N);
    
    switch(rebx->integrator){
        case REBX_INTEGRATOR_IMPLICIT_MIDPOINT:
            rebx_integrator_implicit_midpoint_integrate(sim, dt, effect);
            break;
        case REBX_INTEGRATOR_RK2:
            rebx_integrator_rk2_integrate(sim, dt, effect);
            break;
        case REBX_INTEGRATOR_RK4:
            rebx_integrator_rk4_integrate(sim, dt, effect);
            break;
        case REBX_INTEGRATOR_EULER:
            rebx_integrator_euler_integrate(sim, dt, effect);
            break;
        case REBX_INTEGRATOR_NONE:
            break;
        default:
            break;
    }
}
Exemple #3
0
int reb_remove_by_hash(struct reb_simulation* const r, uint32_t hash, int keepSorted){
    struct reb_particle* p = reb_get_particle_by_hash(r, hash);
    if(p == NULL){
		reb_error(r,"Particle to be removed not found in simulation.  Did not remove particle.");
        return 0;
    }
    else{
        int index = reb_get_particle_index(p);
        return reb_remove(r, index, keepSorted);
    }
}
Exemple #4
0
struct rebx_effect* rebx_add(struct rebx_extras* rebx, const char* name){
    struct rebx_effect* effect = rebx_add_effect(rebx, name);
    struct reb_simulation* sim = rebx->sim;
    
    if (effect->hash == reb_hash("modify_orbits_direct")){
        effect->operator = rebx_modify_orbits_direct;
    }
    else if (effect->hash == reb_hash("modify_orbits_forces")){
        sim->force_is_velocity_dependent = 1;
        effect->force = rebx_modify_orbits_forces;
    }
    else if(effect->hash == reb_hash("gr")){
        sim->force_is_velocity_dependent = 1;
        effect->force = rebx_gr;
    }
    else if (effect->hash == reb_hash("gr_full")){
        sim->force_is_velocity_dependent = 1;
        effect->force = rebx_gr_full;
    }
    else if (effect->hash == reb_hash("gr_potential")){
        effect->force = rebx_gr_potential;
    }
    else if (effect->hash == reb_hash("modify_mass")){
        effect->operator = rebx_modify_mass;
    }
    else if (effect->hash == reb_hash("radiation_forces")){
        sim->force_is_velocity_dependent = 1;
        effect->force = rebx_radiation_forces;
    }
    else if (effect->hash == reb_hash("tides_precession")){
        effect->force = rebx_tides_precession;
    }
    else if (effect->hash == reb_hash("central_force")){
        effect->force = rebx_central_force;
    }
    else if (effect->hash == reb_hash("track_min_distance")){
        effect->operator = rebx_track_min_distance;
    }
    else if (effect->hash == reb_hash("tides_synchronous_ecc_damping")){
        sim->force_is_velocity_dependent = 1;
        effect->force = rebx_tides_synchronous_ecc_damping;
    }
    else if (effect->hash == reb_hash("gravitational_harmonics")){
        effect->force = rebx_gravitational_harmonics;
    }
    else{
        char str[100]; 
        sprintf(str, "Effect '%s' passed to rebx_add not found.\n", name);
        reb_error(sim, str);
    }
    
    return effect;
}
Exemple #5
0
void* rebx_get_param_check(const void* const object, const char* const param_name, enum rebx_param_type param_type){
    struct rebx_param* node = rebx_get_param_node(object, param_name);
    if (node == NULL){
        return NULL;
    }
    
    if (node->param_type != param_type){
        char str[300];
        sprintf(str, "REBOUNDx Error: Parameter '%s' passed to rebx_get_param_check was found but was of wrong type.  See documentation for your particular effect.  In python, you might need to add a dot at the end of the number when assigning a parameter that REBOUNDx expects as a float.\n", param_name);
        reb_error(rebx_get_sim(object), str);
        return NULL;
    }

    return node->contents;
}
Exemple #6
0
static void reb_add_local(struct reb_simulation* const r, struct reb_particle pt){
	if (reb_boundary_particle_is_in_box(r, pt)==0){
		// reb_particle has left the box. Do not add.
		reb_error(r,"Particle outside of box boundaries. Did not add particle.");
		return;
	}
	while (r->allocatedN<=r->N){
		r->allocatedN += 128;
		r->particles = realloc(r->particles,sizeof(struct reb_particle)*r->allocatedN);
	}

	r->particles[r->N] = pt;
	r->particles[r->N].sim = r;
	if (r->gravity==REB_GRAVITY_TREE || r->collision==REB_COLLISION_TREE){
		reb_tree_add_particle_to_tree(r, r->N);
	}
	(r->N)++;
}
Exemple #7
0
void rebx_radiation_forces(struct reb_simulation* const sim, struct rebx_effect* const radiation_forces){ 
    double* c = rebx_get_param_check(radiation_forces, "c", REBX_TYPE_DOUBLE);
    if (c == NULL){
        reb_error(sim, "Need to set speed of light in radiation_forces effect.  See examples in documentation.\n");
    }
    const int N_real = sim->N - sim->N_var;
    struct reb_particle* const particles = sim->particles;
    int source_found=0;
    for (int i=0; i<N_real; i++){
        if (rebx_get_param_check(&particles[i], "radiation_source", REBX_TYPE_INT) != NULL){
            source_found = 1;
            rebx_calculate_radiation_forces(sim, *c, i);
        }
    }
    if (!source_found){
        rebx_calculate_radiation_forces(sim, *c, 0);    // default source to index 0 if "radiation_source" not found on any particle
    }
}
Exemple #8
0
struct reb_simulation* reb_create_simulation_from_binary(char* filename){
    enum reb_input_binary_messages warnings = REB_INPUT_BINARY_WARNING_NONE;
    struct reb_simulation* r = reb_create_simulation_from_binary_with_messages(filename,&warnings);
    if (warnings & REB_INPUT_BINARY_WARNING_VERSION){
        reb_warning(r,"Binary file was saved with a different version of REBOUND. Binary format might have changed.");
    }
    if (warnings & REB_INPUT_BINARY_WARNING_PARTICLES){
        reb_warning(r,"Binary file might be corrupted. Number of particles found does not match expected number.");
    }
    if (warnings & REB_INPUT_BINARY_WARNING_VARCONFIG){
        reb_warning(r,"Binary file might be corrupted. Number of variational config structs found does not match number of variational config structs expected.");
    }
    if (warnings & REB_INPUT_BINARY_WARNING_POINTERS){
        reb_warning(r,"You have to reset function pointers after creating a reb_simulation struct with a binary file.");
    }
    if (warnings & REB_INPUT_BINARY_ERROR_NOFILE){
        reb_error(r,"Cannot read binary file. Check filename and file contents.");
    }
    return r;
}
Exemple #9
0
struct rebx_param* rebx_add_param_node(void* const object, const char* const param_name, enum rebx_param_type param_type, const int ndim, const int* const shape){
    struct rebx_param* newparam = rebx_create_param();
    newparam->name = malloc(strlen(param_name) + 1); // +1 for \0 at end
    if (newparam->name != NULL){
        strcpy(newparam->name, param_name);
    }
    newparam->hash = reb_hash(param_name);
    newparam->param_type = param_type;
    newparam->python_type = -1; // not used by C
    newparam->ndim = ndim;
    newparam->shape = NULL;
    newparam->size = 1;
    if (ndim > 0){
	    size_t shapesize = sizeof(int)*ndim;
	    newparam->shape = malloc(shapesize);
        newparam->strides = malloc(shapesize);
	    memcpy(newparam->shape, shape, shapesize);
	    for(int i=ndim-1;i>=0;i--){ // going backward allows us to calculate strides at the same time
            newparam->strides[i] = newparam->size;  // stride[i] is equal to the product of the shapes for all indices > i
		    newparam->size *= shape[i];
	    }
    }
    size_t element_size = rebx_sizeof(param_type);
    if (element_size){
        newparam->contents = malloc(element_size*newparam->size); // newparam->size = number of elements in array (1 if scalar)
    }

    else{
        char str[300];
        sprintf(str, "REBOUNDx Error: Parameter type '%d' passed to rebx_add_param_node not supported.\n", param_type);
        reb_error(rebx_get_sim(object), str);
    }

    newparam = rebx_attach_param_node(object, newparam);
    return newparam;
}
Exemple #10
0
int reb_remove(struct reb_simulation* const r, int index, int keepSorted){
    if (r->ri_hermes.global){
        // This is a mini simulation. Need to remove particle from two simulations.
        struct reb_simulation* global = r->ri_hermes.global;
        
        //remove from global and update global arrays
        int global_index = global->ri_hermes.global_index_from_mini_index[index];
        reb_remove(global,global_index,1);
        
        //Shifting array values (filled with 0/1)
        for(int k=global_index;k<global->N;k++){
            global->ri_hermes.is_in_mini[k] = global->ri_hermes.is_in_mini[k+1];
        }
        
        //Shifting array values (filled with index values)
        global->ri_hermes.global_index_from_mini_index_N--;
        for(int k=index;k<global->ri_hermes.global_index_from_mini_index_N;k++){
            global->ri_hermes.global_index_from_mini_index[k] = global->ri_hermes.global_index_from_mini_index[k+1];
        }
        
        //Depreciating all index values larger than global_index
        for(int k=0;k<global->ri_hermes.global_index_from_mini_index_N;k++){
            if(global->ri_hermes.global_index_from_mini_index[k] > global_index){
                global->ri_hermes.global_index_from_mini_index[k]--;
            }
        }
    }
    if (r->integrator == REB_INTEGRATOR_MERCURIUS && r->ri_mercurius.mode==1){
        struct reb_simulation_integrator_mercurius* rim = &(r->ri_mercurius);
        struct reb_simulation_integrator_whfast* riw = &(r->ri_whfast);
        //remove from global and update global arrays
        int global_index = -1;
        int count = -1;
        for(int k=0;k<rim->globalN;k++){
            if (rim->encounterIndicies[k]){
                count++;
            }
            if (count==index){
                global_index = k;
                break;
            }
        }
        if (global_index==-1){
            reb_error(r, "Error finding particle in global simulation.");
        }
	    rim->globalN--;
        if(global_index<rim->globalNactive){
            rim->globalNactive--;
        }
		for(int j=global_index; j<rim->globalN; j++){
			rim->encounterParticles[j] = rim->encounterParticles[j+1];  // These are the global particles
			riw->p_jh[j] = riw->p_jh[j+1];
			rim->p_hold[j] = rim->p_hold[j+1];
			rim->encounterIndicies[j] = rim->encounterIndicies[j+1];
			rim->rhill[j] = rim->rhill[j+1];
		}
        // Update additional parameter for local 
		for(int j=index; j<r->N-1; j++){
			rim->encounterRhill[j] = rim->encounterRhill[j+1];
		}
    }
	if (r->N==1){
	    r->N = 0;
        if(r->free_particle_ap){
            r->free_particle_ap(&r->particles[index]);
        }
		reb_warning(r, "Last particle removed.");
		return 1;
	}
	if (index >= r->N){
		char warning[1024];
        sprintf(warning, "Index %d passed to particles_remove was out of range (N=%d).  Did not remove particle.", index, r->N);
		reb_error(r, warning);
		return 0;
	}
	if (r->N_var){
		reb_error(r, "Removing particles not supported when calculating MEGNO.  Did not remove particle.");
		return 0;
	}
	if(keepSorted){
	    r->N--;
        if(r->free_particle_ap){
            r->free_particle_ap(&r->particles[index]);
        }
        if(index<r->N_active){
            r->N_active--;
        }
		for(int j=index; j<r->N; j++){
			r->particles[j] = r->particles[j+1];
		}
        if (r->tree_root){
		    reb_error(r, "REBOUND cannot remove a particle a tree and keep the particles sorted. Did not remove particle.");
		    return 0;
        }
	}else{
        if (r->tree_root){
            // Just flag particle, will be removed in tree_update.
            r->particles[index].y = nan("");
            if(r->free_particle_ap){
                r->free_particle_ap(&r->particles[index]);
            }
        }else{
	        r->N--;
            if(r->free_particle_ap){
                r->free_particle_ap(&r->particles[index]);
            }
		    r->particles[index] = r->particles[r->N];
        }
	}

	return 1;
}