struct rebx_param* rebx_get_param_node(const void* const object, const char* const param_name){ struct rebx_param* current; switch(rebx_get_object_type(object)){ case REBX_OBJECT_TYPE_EFFECT: { struct rebx_effect* effect = (struct rebx_effect*)object; current = effect->ap; break; } case REBX_OBJECT_TYPE_PARTICLE: { struct reb_particle* p = (struct reb_particle*)object; current = p->ap; break; } } uint32_t hash = reb_hash(param_name); while(current != NULL){ if(current->hash == hash){ return current; } current = current->next; } if (current == NULL){ // param_name not found. Return immediately. return NULL; } return current; }
static struct rebx_effect* rebx_add_effect(struct rebx_extras* rebx, const char* name){ struct rebx_effect* effect = malloc(sizeof(*effect)); effect->hash = reb_hash(name); effect->ap = NULL; effect->force = NULL; effect->operator = NULL; effect->rebx = rebx; effect->operator_order = 1; effect->force_as_operator = 0; effect->name = malloc(strlen(name) + 1); // +1 for \0 at end if (effect->name != NULL){ strcpy(effect->name, name); } effect->next = rebx->effects; effect->prev = NULL; rebx->effects = effect; if (effect->next){ effect->next->prev = effect; } struct reb_particle* p = (struct reb_particle*)effect; p->ap = (void*)REBX_OBJECT_TYPE_EFFECT; return effect; }
struct rebx_effect* rebx_get_effect(struct rebx_extras* const rebx, const char* const effect_name){ struct rebx_effect* current = rebx->effects; uint32_t hash = reb_hash(effect_name); while(current != NULL){ if(current->hash == hash){ return current; } current = current->next; } if (current == NULL){ // effect_name not found. Return immediately. return NULL; } return current; }
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; }
/********************************************************************************* User interface for parameters ********************************************************************************/ int rebx_remove_param(const void* const object, const char* const param_name){ // TODO free memory for deleted node uint32_t hash = reb_hash(param_name); struct rebx_param* current; switch(rebx_get_object_type(object)){ case REBX_OBJECT_TYPE_EFFECT: { struct rebx_effect* effect = (struct rebx_effect*)object; current = effect->ap; if(current->hash == hash){ effect->ap = current->next; return 1; } break; } case REBX_OBJECT_TYPE_PARTICLE: { struct reb_particle* p = (struct reb_particle*)object; current = p->ap; if(current->hash == hash){ p->ap = current->next; return 1; } break; } } while(current->next != NULL){ if(current->next->hash == hash){ current->next = current->next->next; return 1; } current = current->next; } return 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); }
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; }