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); } }
int reb_remove_by_id(struct reb_simulation* const r, int id, int keepSorted){ int success = 0; for(int i=0;i<r->N;i++){ if(r->particles[i].id == id){ success = reb_remove(r, i, keepSorted); break; } } if(!success){ fprintf(stderr, "\nIndex passed to particles_remove_id (id = %d) not found in particles array. Did not remove particle.\n", id); } return success; }
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; }
void reb_boundary_check(struct reb_simulation* const r){ struct reb_particle* const particles = r->particles; int N = r->N; const struct reb_vec3d boxsize = r->boxsize; switch(r->boundary){ case REB_BOUNDARY_OPEN: for (int i=0;i<N;i++){ // run through loop backwards so we don't have to recheck same index after removing int removep = 0; if(particles[i].x>boxsize.x/2.){ removep = 1; } if(particles[i].x<-boxsize.x/2.){ removep = 1; } if(particles[i].y>boxsize.y/2.){ removep = 1; } if(particles[i].y<-boxsize.y/2.){ removep = 1; } if(particles[i].z>boxsize.z/2.){ removep = 1; } if(particles[i].z<-boxsize.z/2.){ removep = 1; } if (removep==1){ reb_remove(r, i,0); // keepSorted=0 by default in C version if (r->tree_root==NULL){ i--; // need to recheck the particle that replaced the removed one N--; // This is the local N }else{ // particle just marked, will be removed later r->tree_needs_update= 1; } } } break; case REB_BOUNDARY_SHEAR: { // The offset of ghostcell is time dependent. const double OMEGA = r->ri_sei.OMEGA; const double offsetp1 = -fmod(-1.5*OMEGA*boxsize.x*r->t+boxsize.y/2.,boxsize.y)-boxsize.y/2.; const double offsetm1 = -fmod( 1.5*OMEGA*boxsize.x*r->t-boxsize.y/2.,boxsize.y)+boxsize.y/2.; struct reb_particle* const particles = r->particles; #pragma omp parallel for schedule(guided) for (int i=0;i<N;i++){ // Radial while(particles[i].x>boxsize.x/2.){ particles[i].x -= boxsize.x; particles[i].y += offsetp1; particles[i].vy += 3./2.*OMEGA*boxsize.x; } while(particles[i].x<-boxsize.x/2.){ particles[i].x += boxsize.x; particles[i].y += offsetm1; particles[i].vy -= 3./2.*OMEGA*boxsize.x; } // Azimuthal while(particles[i].y>boxsize.y/2.){ particles[i].y -= boxsize.y; } while(particles[i].y<-boxsize.y/2.){ particles[i].y += boxsize.y; } // Vertical (there should be no boundary, but periodic makes life easier) while(particles[i].z>boxsize.z/2.){ particles[i].z -= boxsize.z; } while(particles[i].z<-boxsize.z/2.){ particles[i].z += boxsize.z; } } } break; case REB_BOUNDARY_PERIODIC: #pragma omp parallel for schedule(guided) for (int i=0;i<N;i++){ while(particles[i].x>boxsize.x/2.){ particles[i].x -= boxsize.x; } while(particles[i].x<-boxsize.x/2.){ particles[i].x += boxsize.x; } while(particles[i].y>boxsize.y/2.){ particles[i].y -= boxsize.y; } while(particles[i].y<-boxsize.y/2.){ particles[i].y += boxsize.y; } while(particles[i].z>boxsize.z/2.){ particles[i].z -= boxsize.z; } while(particles[i].z<-boxsize.z/2.){ particles[i].z += boxsize.z; } } break; default: break; } }