示例#1
0
文件: particle.c 项目: ridlo/rebound
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);
    }
}
示例#2
0
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;
}
示例#3
0
文件: particle.c 项目: ridlo/rebound
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;
}
示例#4
0
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;
	}
}