static int search(int max_constrained, int depth) { int id; BOOL go; int rc = check_time_memory(); if (rc != SEARCH_GO_NO_MODELS) return rc; else { id = select_cell(max_constrained); if (id == -1) { rc = possible_model(); return rc; } else { int i, last; /* we'll do 0 .. last */ int x = Cells[id].max_index; max_constrained = MAX(max_constrained, x); Mstats.selections++; if (flag(Opt->trace)) { printf("select: "); p_model(FALSE); /* p_possible_values(); */ } if (Cells[id].symbol->type == RELATION) last = 1; else if (flag(Opt->lnh)) last = MIN(max_constrained+1, Domain_size-1); else last = Domain_size-1; for (i = 0, go = TRUE; i <= last && go; i++) { Estack stk; Mstats.assignments++; if (flag(Opt->trace)) { printf("assign: "); fwrite_term(stdout, Cells[id].eterm); printf("=%d (%d) depth=%d\n", i, last, depth); } stk = assign_and_propagate(id, Domain[i]); if (stk != NULL) { /* no contradiction found during propagation, so we recurse */ rc = search(MAX(max_constrained, i), depth+1); /* undo assign_and_propagate changes */ restore_from_stack(stk); if (rc == SEARCH_GO_MODELS) go = mace4_skolem_check(id); else go = (rc == SEARCH_GO_NO_MODELS); } } return rc; } } } /* search */
void veta_handleevent(event_t *event){ switch(event->type){ case QUIT: uk_log("Quit"); ui_quit(); break; case RESET: uk_log("Reset"); clear_selection(root_cell); veta_render(); break; case SELECT_CELL: uk_log("select cell %i",event->cell); // debug_print_tree(root); select_cell(root_cell,event->cell); symbol *sym; if(NULL!=(sym=get_selected_symbol(root_cell))){ clear_selection(root_cell); if(ui2_onselect_symbol(sym)) break; sendkey(sym->data,1,0); } refresh(); break; case UNDEFINED: uk_log("got event UNDEFINED\n"); break; default: uk_log("WARNING undefined event type"); break; } }
//place_halos(): // //Takes a list of halo masses (Nhalos, HaloMass), a list of particles // (NTotPart,PartX,PartY,PartZ), some simulation parameters (L, mp), and // user-defined parameters (Nlin,rho_ref,alpha,Malpha,Nalpha,seed) //and returns a list of halo positions and radii (HaloX,HaloY,HaloZ,HaloR) int place_halos(long Nend, float *HaloMass, long Nlin, long NTotPart, float *PartX, float *PartY, float *PartZ, float *PartVX, float *PartVY, float *PartVZ, float L, float rho_ref, long seed, float mp, int nthreads, double *alpha, double *beta, double *Malpha, long Nalpha,float recalc_frac, float *HaloX, float *HaloY, float *HaloZ, float *HaloVX, float *HaloVY, float *HaloVZ,float *HaloR,long **ListOfPart, long *NPartPerCell,double *RemMass, float *dens){ fprintf(stderr,"\tThis is place_halos.c v12\n"); //Initiallising ------------------------------------------------- long i,j,k,lin_ijk, Nmin; long *count,trials; long ihalo, ipart,i_alpha; double invL = 1./L; float Mcell,Mhalo,Mchange; float R; time_t t0,tI,tII; int check; double mpart; double exponent,beta_now; double TotProb; double prob_repicked = 0.0; double *MassLeft; double *CumulativeProb; long *ListOfHalos, *NHalosPerCellStart, *NHalosPerCellEnd; long Nhalos; int recalc; float *copyof_dens; int beta_type; float diff; time_t t5; #ifdef VERB time_t t1,t3,t4,t4_5; #endif long n_recalc =0; NCells = Nlin; Lbox = L; t0=time(NULL); NTotCells = NCells*NCells*NCells; //Allocate memory for the arrays #ifndef NGP MassLeft = (double *) calloc(NTotCells,sizeof(double)); if(MassLeft == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for MassLeft[]\nABORTING",NTotCells); exit(-1); } for (i=0;i<NTotCells;i++) MassLeft[i]=RemMass[i]; // fprintf(stderr,"Mleft[0],Mleft[last]: %e, %e\n",MassLeft[0],MassLeft[Nlin*Nlin*Nlin-1]); #else MassLeft = (double *) calloc(NTotCells,sizeof(double)); if(MassLeft == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for MassLeft[]\nABORTING",NTotCells); exit(-1); } #endif copyof_dens = (float *) calloc(NTotPart,sizeof(float)); if(copyof_dens == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for copyof_dens[]\nABORTING",NTotPart); exit(-1); } for (i=0;i<NTotPart;i++) copyof_dens[i]=dens[i]; NHalosPerCellStart = (long *) calloc(NTotCells,sizeof(long)); if(NHalosPerCellStart == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for NHalosPerCell[]\nABORTING",NTotCells); exit(-1); } NHalosPerCellEnd = (long *) calloc(NTotCells,sizeof(long)); if(NHalosPerCellEnd == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for NHalosPerCell[]\nABORTING",NTotCells); exit(-1); } count = (long *) calloc(NTotCells,sizeof(long)); if(count == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for NTotCells[]\nABORTING",NTotCells); exit(-1); } CumulativeProb = (double *) calloc(NTotCells, sizeof(double)); if(CumulativeProb == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for CumulativeProb[]\nABORTING",NTotCells); exit(-1); } if (nthreads<1){ NTHREADS = omp_get_max_threads(); }else{ NTHREADS = nthreads; } #ifdef VERB fprintf(stderr,"\tUsing OMP with %d threads\n",NTHREADS); #endif #ifdef MASS_OF_PARTS Nexcluded = (long *) calloc(NTotCells,sizeof(long)); if(Nexcluded == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for Nexcluded[]\nABORTING",NTotCells); exit(-1); } excluded = (int *) calloc(NTotPart, sizeof(long)); if(excluded == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for excluded[]\nABORTING",NTotPart); exit(-1); } #endif //Initiallise random numbers #ifdef VERB fprintf(stderr,"\tinput seed: %ld. time0: %f.",seed, t0); #endif if (seed>=0){ srand(seed); #ifdef VERB fprintf(stderr,"Used: %ld \n",seed); #endif } else { srand(t0); #ifdef VERB fprintf(stderr,"Seed Used: %ld \n",t0); #endif } mpart = (double) mp; Nmin = (long)ceil(HaloMass[Nend-1]*0.9/mpart); lcell = (float) L/NCells; #ifdef VERB fprintf(stderr,"\n\tParticles and Halos placed in %ld^3 cells\n",NCells); fprintf(stderr,"\tBOX = %f lcell =%f rho_ref = %e invL %f\n",L,L/NCells,rho_ref,invL); fprintf(stderr,"\tNhalostart = %d,Nhalosend = %ld, NPart = %ld\n",0, Nend, NTotPart); fprintf(stderr,"\n\tMinimmum mass= %e. Minimum part per halo = %ld. mpart %e\n",HaloMass[Nend-1],Nmin,mpart); #endif #ifdef DEBUG fprintf(stderr,"\n\tRAND_MAX=%d\n",RAND_MAX); fprintf(stderr,"\tX[0] = %f Y[0] = %f Z[0] = %f\n",PartX[0],PartY[0],PartZ[0]); fprintf(stderr,"\tX[1] = %f Y[1] = %f Z[1] = %f\n",PartX[1],PartY[1],PartZ[1]); fprintf(stderr,"\tM[0] = %e \n",HaloMass[0]); fprintf(stderr,"\tM[1] = %e \n",HaloMass[1]); fprintf(stderr,"\tM[%ld] = %e \n",Nend-1,HaloMass[Nend-1]); #endif if (L/NCells<R_from_mass(HaloMass[0],rho_ref)){ fprintf(stderr,"ERROR: cell size is smaller than the radius of the biggest halo. Please, change the number of cells\n"); exit(0); } int r = (int) (R_from_mass(HaloMass[0],rho_ref)/(L/NCells)); #ifdef VERB fprintf(stderr,"R_max=%f, lcell=%f, r=%d\n",R_from_mass(HaloMass[0],rho_ref),(L/NCells),r); t1=time(NULL); diff = difftime(t1,t0); fprintf(stderr,"\ttime of initialisation %f\n",diff); #endif // ------------------------------------------------- Initiallised fprintf(stderr,"\t aaa \n"); //Alloc Enough Memory Nhalos=0; for (i=0;i<NCells;i++){ for (j=0;j<NCells;j++){ for (k=0;k<NCells;k++){ lin_ijk = k+j*NCells+i*NCells*NCells; NHalosPerCellStart[lin_ijk] = Nhalos; NHalosPerCellEnd[lin_ijk] = Nhalos; Nhalos += (long) floor(NPartPerCell[lin_ijk]/Nmin+1); #ifdef NGP MassLeft[lin_ijk] = (double) NPartPerCell[lin_ijk]*mpart; #endif #ifdef ULTRADEBUG if (lin_ijk<10 || lin_ijk > (NCells*NCells*NCells) - 10){ fprintf(stderr,"\tAllocated %ld (longs) in ListOfPart(%ld=[%ld,%ld,%ld])\n",NPartPerCell[lin_ijk],lin_ijk,i,j,k); } #endif } } } fprintf(stderr,"\t bbb \n"); ListOfHalos = (long *) calloc(Nhalos,sizeof(long )); if(ListOfHalos == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for ListOfHalos[]\nABORTING",Nhalos); exit(-1); } fprintf(stderr,"\t ccc \n"); #ifdef VERB fprintf(stderr,"\tAllocated %ld (longs) in ListOfHalos\n",Nhalos); fprintf(stderr,"\t... memory allocated ...\n"); t3=time(NULL); diff = difftime(t3,t1); fprintf(stderr,"\ttime allocating %f\n",diff); fprintf(stderr,"\tComputing probabilities...\n"); #endif #ifdef DEBUG fprintf(stderr,"\tMass_cell[0]=%e",MassLeft[0]); fprintf(stderr,"\t Mass Function\n"); for (ihalo=0;ihalo<15;ihalo++){ fprintf(stderr,"\thalo %ld: ",ihalo); fprintf(stderr,"M=%e\n",HaloMass[ihalo]); } #endif //----------------------------------- Particles and haloes assigned to grid //Computing Cumulative Probability ----------------------------- //find the right alpha Mhalo = HaloMass[0]; i_alpha = 0; while(Mhalo<Malpha[i_alpha]) { i_alpha++; if (i_alpha==Nalpha){ fprintf(stderr,"\tERROR: No M_alpha low enough found\n"); fprintf(stderr,"\tERROR: N_alpha = %ld, Mh=%e, Ma= %e\n",Nalpha,Mhalo,Malpha[i_alpha-1]); exit(0); } } Mchange = Malpha[i_alpha]; exponent = alpha[i_alpha]; beta_now = beta[i_alpha]; if (beta_now== (double) 0.) beta_type = 0; else if (beta_now== (double) 1.) beta_type = 1; else if (beta_now<0) beta_type = 2; else beta_type = 3; //compute the probability switch (beta_type){ case 0: fprintf(stderr,"- Using beta0 !\n"); break; case 1: fprintf(stderr,"- Using beta1 !\n"); break; case 2: fprintf(stderr,"- Using beta=inf !\n"); break; case 3: fprintf(stderr,"- Using beta= %f\n",beta_now); break; default: fprintf(stderr,"ERROR: unkown beta type %d, with beta=%f\n",beta_type,beta_now); return -1; break; } TotProb = ComputeCumulative(exponent, mpart, MassLeft, CumulativeProb); fprintf(stderr,"\ncase 0, TotProb=%e\n",TotProb); // TotProb_real=TotProb; #ifdef VERB fprintf(stderr,"\tNumber of alphas: %ld\n",Nalpha); fprintf(stderr,"\tUsing alpha_%ld=%f for M>%e\n",i_alpha,exponent,Mchange); t4_5=time(NULL); diff = difftime(t4_5,t4); fprintf(stderr,"\tprobabilty computed in %f secods\n",diff); #endif // ----------------------------------------- Computed Probability //Actually placing the haloes----------------------------------- #ifdef VERB fprintf(stderr,"\n\tPlacing Halos...\n\n"); #endif //Place one by one all the haloes (assumed to be ordered from the most massive to the least massive) for (ihalo=0;ihalo<Nend;ihalo++){ #ifdef DEBUG fprintf(stderr,"\n\t- Halo %ld ",ihalo); #endif #ifdef VERB if (ihalo%(Nend/10)==0 && ihalo>0){ //TEMPORARY fprintf(stderr,"FRAC, TOTPROB: %e, %e",(pow(Mcell/mpart,exponent)/TotProb),TotProb); fprintf(stderr,"\t%ld%% done\n",(ihalo/(Nend/100))); } #endif //Check whether or not, a change of alpha is needed for this halo mass Mhalo= HaloMass[ihalo]; recalc = 0; while (Mhalo < Mchange){//if so search the right alpha, and recompute probabilities i_alpha++; if (i_alpha==Nalpha){ fprintf(stderr,"\tERROR: No M_alpha low enough found: %e <%e\n",Mhalo,Malpha[Nalpha-1]); exit(0); } Mchange = Malpha[i_alpha]; exponent = alpha[i_alpha]; beta_now = beta[i_alpha]; if (beta_now== (double) 0.) beta_type = 0; else if (beta_now== (double) 1.) beta_type = 1; else if (beta_now<0) beta_type = 2; else beta_type = 3; switch (beta_type) { case 0: fprintf(stderr,"- Using beta0 !\n"); break; case 1: fprintf(stderr,"- Using beta1 !\n"); break; case 2: fprintf(stderr,"- Using beta=inf !\n"); break; case 3: fprintf(stderr,"- Using beta= %f\n",beta_now); break; default: fprintf(stderr,"ERROR: unkown beta type %d, with beta=%f\n",beta_type,beta_now); return -1; break; } #ifdef VERB fprintf(stderr,"\n\tUsing alpha_%ld=%f for M>%e\n",i_alpha,exponent,Mchange); #endif recalc = 1; } // recalc if different alpha, OR there's a significant chance of choosing the same cell again. if(ihalo>0){ //v0.7.2 /* if(pow(Mcell/mpart,exponent)/TotProb > recalc_frac){ recalc = 1; n_recalc += 1; fprintf(stderr,"RECALCULATING: %ld, %e, %e\n",n_recalc,pow(Mcell/mpart,exponent)/TotProb,TotProb); } */ // if(prob_repicked>=recalc_frac){ recalc = 1; n_recalc += 1; fprintf(stderr,"RECALCULATING: %ld, %e, ihalo=%ld\n",n_recalc,prob_repicked,ihalo); } } if (recalc==1){ tI=time(NULL); fprintf(stderr,"case 1, TotProb_bef=%e",TotProb); TotProb=ComputeCumulative(exponent, mpart, MassLeft, CumulativeProb); fprintf(stderr," TotProb_aft=%e ihalo=%ld\n\n",TotProb,ihalo); prob_repicked=0.0; #ifdef VERB tII=time(NULL); diff = difftime(tII,tI); fprintf(stderr,"\tProbabilty recomputed in %f secods\n",diff); #endif recalc = 0; } do { //First, choose a cell #ifndef RANKED trials=0; do{ if (trials==MAXTRIALS){ fprintf(stderr,"MAXTRIALS=%d times picked an empty cell, recomputing Probs...\n",MAXTRIALS); fprintf(stderr,"\ncase 2, TotProb_bef=%e",TotProb); TotProb=ComputeCumulative(exponent, mpart, MassLeft, CumulativeProb); fprintf(stderr," TotProb_aft=%e ihalo=%ld\n",TotProb,ihalo); prob_repicked = 0.0; trials=0; } lin_ijk = select_cell(TotProb, CumulativeProb); trials++; }while (MassLeft[lin_ijk]==0.); k=lin_ijk%(NCells); j=((lin_ijk-k)/NCells)%NCells; i=(lin_ijk-k-j*NCells)/(NCells*NCells); #else lin_ijk=select_heaviest_cell(&i,&j,&k); #endif trials=0; //Second, choose a particle in that cell do { switch (beta_type){ case 0: ipart = select_part_beta_0(lin_ijk,ListOfPart, NPartPerCell,copyof_dens); break; case 1: ipart = select_part_beta_1(lin_ijk,ListOfPart, NPartPerCell,copyof_dens); break; case 2: ipart = select_part_beta_inf(lin_ijk,ListOfPart, NPartPerCell,copyof_dens); break; case 3: ipart = select_part_beta(lin_ijk,ListOfPart, NPartPerCell,copyof_dens,beta_now); break; default: fprintf(stderr,"ERROR: unkown beta type %d, with beta=%f\n",beta_type,beta_now); return -1; break; } if (ipart<0){ fprintf(stderr,"WARNING: Picked up an completely empty cell (ihalo %ld) lin_ijk=%ld \n",ihalo,lin_ijk); MassLeft[lin_ijk]=0.; check=1; //Choose another cell break; } if (beta_now>=1.){ if (copyof_dens[ipart] == 0.){ fprintf(stderr,"WARNING: No particles left (d[%ld]=%f). Removing cell lin_ijk=%ld (halo %ld)\n",ipart,copyof_dens[ipart],lin_ijk,ihalo); MassLeft[lin_ijk]=0.; //TotProb=ComputeCumulative(exponent, mpart, MassLeft, CumulativeProb); check=1; //Choose another cell break; } } copyof_dens[ipart] = 0.; HaloX[ihalo] = PartX[ipart]; HaloY[ihalo] = PartY[ipart]; HaloZ[ihalo] = PartZ[ipart]; #ifndef FITTING HaloVX[ihalo] = PartVX[ipart]; HaloVY[ihalo] = PartVY[ipart]; HaloVZ[ihalo] = PartVZ[ipart]; #endif R=R_from_mass(HaloMass[ihalo],rho_ref); HaloR[ihalo]= R; // if (ihalo<=-1) // fprintf(stderr,"\thalo: [[%f,%f,%f],[%f,%f,%f],%f]\n",HaloX[ihalo],HaloY[ihalo],HaloZ[ihalo],HaloVX[ihalo],HaloVY[ihalo],HaloVZ[ihalo],HaloR[ihalo]); #ifdef NO_EXCLUSION check = 0; //Should check not the same particle fprintf(stderr,"No exclusion: to be reimplemented!\n"); #else //Third, check that is not overlapping a previous halo check = check_HaloR_in_mesh(ihalo,HaloX,HaloY,HaloZ,HaloR,i,j,k,ListOfHalos,NHalosPerCellStart,NHalosPerCellEnd,r); #endif if (check==1){ #ifdef DEBUG fprintf(stderr,"Refused part : %ld\n",ipart); #endif trials++; } if (trials == MAXTRIALS){ //in order to avoid infinite loop, we will exit this loop, after MAXTRIALS trials #ifdef VERB fprintf(stderr,"MAXTRIALS=%d reached, removing cell [%ld,%ld,%ld]\n",MAXTRIALS,i,j,k); #endif MassLeft[lin_ijk]=0.; fprintf(stderr,"\ncase 3, TotProb_bef=%e",TotProb); TotProb=ComputeCumulative(exponent, mpart, MassLeft, CumulativeProb); fprintf(stderr," TotProb_aft=%e ihalo=%ld\n",TotProb,ihalo); prob_repicked=0.0; break; } } while (check==1);//If the particle was excluded, try another one in the same cell } while(check==1); //if reached MAXTRIALS, select another cell //Particle chosen! //mass in cell before assignment Mcell=MassLeft[lin_ijk]; #ifndef MASS_OF_PARTS if (Mcell>HaloMass[ihalo]) MassLeft[lin_ijk] -= Mhalo; else MassLeft[lin_ijk] = 0.; #else exclude(ipart,R,PartX,PartY,PartZ,i,j,k); #endif prob_repicked += pow(Mcell/mpart,exponent)/TotProb; #ifdef DEBUG fprintf(stderr," After: Mcell=%e, CProbCell=%e, TotProb=%e. , Mhalo=%e. CProb[last]=%e\n",MassLeft[lin_ijk],CumulativeProb[lin_ijk],TotProb,Mhalo,CumulativeProb[NTotCells-1]); #endif #ifdef DEBUG fprintf(stderr,"\thalo %ld assigned to particle %ld at [%f,%f,%f]. R= %f, M= %e\n",ihalo,ipart,HaloX[ihalo],HaloY[ihalo],HaloZ[ihalo],R,Mhalo); #endif ListOfHalos[NHalosPerCellEnd[lin_ijk]]=ihalo; NHalosPerCellEnd[lin_ijk]++; }//for(ihalo=Nstart:Nend) //----------------------------------- Haloes Placed #ifdef VERB t5=time(NULL); diff = difftime(t5,t4_5); fprintf(stderr,"\ttime placing %f\n",diff); fprintf(stderr,"\tfreeing...\n"); #endif free(NHalosPerCellStart); free(NHalosPerCellEnd); free(count); free(CumulativeProb); free(MassLeft); free(copyof_dens); free(ListOfHalos); #ifdef VERB diff = difftime(t5,t0); fprintf(stderr,"\ttotal time in place_halos.c %f\n",diff); fprintf(stderr,"\n\tPlacement done!!!\n"); #endif #ifdef MASS_OF_PARTS // free(excluded); free(Nexcluded); #endif fprintf(stderr,"TOTAL NUMBER OF RE-CALCULATIONS: %ld\n",n_recalc); return 0; }
//place_halos(): // //Takes a list of halo masses (Nhalos, HaloMass), a list of particles (NTotPart,PartX,PartY,PartZ), some simulation parameters (L, mp), and user-defined parameters (Nlin,rho_ref,alpha,Malpha,Nalpha,seed) //and returns a list of halo positions and radii (HaloX,HaloY,HaloZ,HaloR) int place_halos(long Nend, float *HaloMass, long Nlin, long NTotPart, float *PartX, float *PartY, float *PartZ, float *PartVX, float *PartVY, float *PartVZ,float L, float rho_ref, long seed, float mp, double *alpha, double *Malpha,long Nalpha,float *HaloX, float *HaloY, float *HaloZ, float *HaloVX, float *HaloVY, float *HaloVZ,float *HaloR,long **ListOfPart, long *NPartPerCell){ fprintf(stderr,"\tThis is place_halos.c v11\n"); //Initiallising ------------------------------------------------- long i,j,k,lin_ijk, Nmin; long *count,trials; long ihalo,ilong, ipart,i_alpha; double invL = 1./L; float Mcell,Mhalo,Mchange; float R; time_t t0; int check; double mpart; double exponent; double TotProb; double *MassLeft; double *CumulativeProb; long **ListOfHalos, *NHalosPerCell; long Nstart=0,Nhalos; #ifdef VERB time_t t1,t2,t3,t4,t4_5,t5; float diff; #endif NCells = Nlin; Lbox = L; t0=time(NULL); NTotCells = NCells*NCells*NCells; MassLeft = malloc(NTotCells*sizeof(double)); //Allocate memory for the arrays //NPartPerCell = (long *) calloc(NTotCells,sizeof(long)); /* if( NPartPerCell == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for NPartPerCell[]\nABORTING",NTotCells); exit(-1); }*/ NHalosPerCell = (long *) calloc(NTotCells,sizeof(long)); if(NHalosPerCell == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for NHalosPerCell[]\nABORTING",NTotCells); exit(-1); } count = (long *) calloc(NTotCells,sizeof(long)); if(count == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for NTotCells[]\nABORTING",NTotCells); exit(-1); } CumulativeProb = (double *) calloc(NTotCells, sizeof(double)); if(CumulativeProb == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for CumulativeProb[]\nABORTING",NTotCells); exit(-1); } fprintf(stderr,"\tUsing OMP with %d threads\n",omp_get_max_threads()); #ifdef MASS_OF_PARTS Nexcluded = (long *) calloc(NTotCells,sizeof(long)); if(Nexcluded == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for Nexcluded[]\nABORTING",NTotCells); exit(-1); } excluded = (int *) calloc(NTotPart, sizeof(long)); if(excluded == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for excluded[]\nABORTING",NTotPart); exit(-1); } #endif //Initiallise random numbers #ifdef VERB fprintf(stderr,"\tinput seed: %ld. time0: %ld.",seed,t0); #endif if (seed>=0){ srand(seed); #ifdef VERB fprintf(stderr,"Used: %ld \n",seed); #endif } else { srand(t0); fprintf(stderr,"Seed Used: %ld \n",t0); } mpart = (double) mp; //Nmin = (long)ceil(HaloMass[Nhalos-1]/mpart); Nmin = (long)ceil(HaloMass[Nend-1]*0.8/mpart); lcell = (float) L/NCells; #ifdef VERB fprintf(stderr,"\n\tParticles and Halos placed in %ld^3 cells\n",NCells); fprintf(stderr,"\tBOX = %f lcell =%f rho_ref = %e invL %f\n",L,L/NCells,rho_ref,invL); fprintf(stderr,"\tNhalostart = %ld,Nhalosend = %ld, NPart = %ld\n",Nstart, Nend, NTotPart); #endif #ifdef DEBUG fprintf(stderr,"\n\tRAND_MAX=%d\n",RAND_MAX); fprintf(stderr,"\tX[0] = %f Y[0] = %f Z[0] = %f\n",PartX[0],PartY[0],PartZ[0]); fprintf(stderr,"\tX[1] = %f Y[1] = %f Z[1] = %f\n",PartX[1],PartY[1],PartZ[1]); fprintf(stderr,"\tM[0] = %e \n",HaloMass[0]); fprintf(stderr,"\tM[1] = %e \n",HaloMass[1]); fprintf(stderr,"\tM[%ld] = %e \n",Nend-1,HaloMass[Nend-1]); fprintf(stderr,"\n\tMinimmum mass= %e. Minimum part per halo = %ld. mpart %e\n",HaloMass[Nend-1],Nmin,mpart); #endif if (L/NCells<R_from_mass(HaloMass[0],rho_ref)){ fprintf(stderr,"ERROR: cell size is smaller than the radius of the biggest halo. Please, change the number of cells\n"); exit(0); } #ifdef VERB t1=time(NULL); diff = difftime(t1,t0); fprintf(stderr,"\ttime of initialisation %f\n",diff); #endif // ------------------------------------------------- Initiallised #ifdef VERB fprintf(stderr,"\tAssigning particles to grid ...\n"); #endif //Assign particles to grid ------------------------------------ //count particles per cell /*for (ilong=0;ilong<NTotPart;ilong++) { if (PartX[ilong]==Lbox) PartX[ilong]=0.; if (PartY[ilong]==Lbox) PartY[ilong]=0.; if (PartZ[ilong]==Lbox) PartZ[ilong]=0.; i = (long) (invL * PartX[ilong]*NCells); j = (long) (invL * PartY[ilong]*NCells); k = (long) (invL * PartZ[ilong]*NCells); if (i<0 || i>=NCells || j<0 || j>=NCells || k<0 || k>=NCells){ fprintf(stderr,"\tERROR: Particle %ld at [%f,%f,%f] seems to be out of the right box interval [0.,%f)",ilong,PartX[ilong],PartY[ilong],PartZ[ilong],L); } lin_ijk = k+j*NCells+i*NCells*NCells; // NPartPerCell[lin_ijk]++; #ifdef DEBUG if(ilong<10 || ilong > NTotPart -10 || ilong==243666) fprintf(stderr,"\tipart=%ld cell: %ld=[%ld,%ld,%ld] Parts in cell=%ld, Pos= [%f,%f,%f]\n",ilong,lin_ijk,i,j,k,NPartPerCell[lin_ijk],PartX[ilong],PartY[ilong],PartZ[ilong]); #endif }*/ #ifdef VERB fprintf(stderr,"\t... particles counted ...\n"); t2=time(NULL); diff = difftime(t2,t1); fprintf(stderr,"\ttime counting %f\n",diff); #endif //Alloc Enough Memory //ListOfPart = (long **) calloc(NCells*NCells*NCells,sizeof(long *)); ListOfHalos = (long **) calloc(NCells*NCells*NCells,sizeof(long *)); for (i=0;i<NCells;i++){ for (j=0;j<NCells;j++){ for (k=0;k<NCells;k++){ lin_ijk = k+j*NCells+i*NCells*NCells; //ListOfPart[lin_ijk] = (long *) calloc(NPartPerCell[lin_ijk],sizeof(long)); Nhalos = (long) (NPartPerCell[lin_ijk]/Nmin); ListOfHalos[lin_ijk] = (long *) calloc(Nhalos,sizeof(long)); if (Nstart==0) MassLeft[lin_ijk] = (double) NPartPerCell[lin_ijk]*mpart; #ifdef ULTRADEBUG if (lin_ijk<10 || lin_ijk > (NCells*NCells*NCells) - 10){ fprintf(stderr,"\tAllocated %ld (longs) in ListOfPart(%ld=[%ld,%ld,%ld])\n",NPartPerCell[lin_ijk],lin_ijk,i,j,k); fprintf(stderr,"\tAllocated %ld (longs) in ListOfHalos(%ld=[%ld,%ld,%ld])\n",Nhalos,lin_ijk,i,j,k); } #endif } } } #ifdef VERB fprintf(stderr,"\t... memory allocated ...\n"); t3=time(NULL); diff = difftime(t3,t2); fprintf(stderr,"\ttime allocating %f\n",diff); #endif /* #pragma omp parallel for private(ilong,i,k,j,lin_ijk) shared(NTotPart,invL,NCells,ListOfPart,count,PartZ,PartX,PartY,L,stderr) default(none) for (ilong=0;ilong<NTotPart;ilong++) { i = (long) (invL * PartX[ilong]*NCells); j = (long) (invL * PartY[ilong]*NCells); k = (long) (invL * PartZ[ilong]*NCells); if (i<0 || i>=NCells || j<0 || j>=NCells || k<0 || k>=NCells){ fprintf(stderr,"\tERROR: Particle %ld at [%f,%f,%f] seems to be out of the right box interval [0.,%f)",ilong,PartX[ilong],PartY[ilong],PartZ[ilong],L); } lin_ijk = k+j*NCells+i*NCells*NCells; ListOfPart[lin_ijk][count[lin_ijk]] = ilong; count[lin_ijk]++; } #ifdef VERB fprintf(stderr,"\t...particles assigned, now haloes...\n"); #endif */ for (ihalo=0;ihalo<Nstart;ihalo++){ i = (long) (invL * HaloX[ihalo]*NCells); j = (long) (invL * HaloY[ihalo]*NCells); k = (long) (invL * HaloZ[ihalo]*NCells); i=check_limit(i,NCells); j=check_limit(j,NCells); k=check_limit(k,NCells); lin_ijk = k+j*NCells+i*NCells*NCells; ListOfHalos[lin_ijk][NHalosPerCell[lin_ijk]] = ihalo; NHalosPerCell[lin_ijk]++; } #ifdef DEBUG fprintf(stderr,"\tMass_cell[0]=%e",MassLeft[0]); fprintf(stderr,"\t Mass Function\n"); for (ihalo=0;ihalo<15;ihalo++){ fprintf(stderr,"\thalo %ld: ",ihalo); fprintf(stderr,"M=%e\n",HaloMass[ihalo]); } #endif #ifdef VERB fprintf(stderr,"\t ...done\n\n"); t4=time(NULL); diff = difftime(t4,t3); fprintf(stderr,"\ttime of the actual assignment %f\n",diff); fprintf(stderr,"\tComputing probabilities...\n"); #endif //----------------------------------- Particles and haloes assigned to grid //Computing Cumulative Probability ----------------------------- //find the right alpha Mhalo = HaloMass[Nstart]; i_alpha = 0; while(Mhalo<Malpha[i_alpha]) { i_alpha++; if (i_alpha==Nalpha){ fprintf(stderr,"\tERROR: No M_alpha low enough found\n"); fprintf(stderr,"\tERROR: N_alpha = %ld, Mh=%e, Ma= %e\n",Nalpha,Mhalo,Malpha[i_alpha-1]); exit(0); } } Mchange = Malpha[i_alpha]; exponent = alpha[i_alpha]; //compute the probability TotProb = ComputeCumulative(exponent, mpart, MassLeft, CumulativeProb); #ifdef VERB fprintf(stderr,"\tNumber of alphas: %ld\n",Nalpha); fprintf(stderr,"\tUsing alpha_%ld=%f for M>%e\n",i_alpha,exponent,Mchange); t4_5=time(NULL); diff = difftime(t4_5,t4); fprintf(stderr,"\tprobabilty computed in %f secods\n",diff); #endif // ----------------------------------------- Computed Probability //Actually placing the haloes----------------------------------- #ifdef VERB fprintf(stderr,"\n\tPlacing Halos...\n\n"); #endif //Place one by one all the haloes (assumed to be ordered from the most massive to the least massive) for (ihalo=Nstart;ihalo<Nend;ihalo++){ #ifdef DEBUG fprintf(stderr,"\n\t- Halo %ld ",ihalo); #endif #ifdef VERB if ((ihalo%1000000)==0) fprintf(stderr,"\t%ld million haloes done\n",(ihalo/1000000)); #endif //Check whether or not, a change of alpha is needed for this halo mass Mhalo= HaloMass[ihalo]; // if (ihalo<=-1) // fprintf(stderr,"\tMhalo=%e\n",Mhalo); while (Mhalo < Mchange){//if so search the right alpha, and recompute probabilities i_alpha++; if (i_alpha==Nalpha){ fprintf(stderr,"\tERROR: No M_alpha low enough found\n"); exit(0); } Mchange = Malpha[i_alpha]; exponent = alpha[i_alpha]; TotProb=ComputeCumulative(exponent, mpart, MassLeft, CumulativeProb); #ifdef VERB fprintf(stderr,"\n\tUsing alpha_%ld=%f for M>%e\n",i_alpha,exponent,Mchange); #endif } // if (ihalo<=-1) // fprintf(stderr,"\talpha=%f\n",exponent); do { //First, choose a cell #ifndef RANKED lin_ijk = select_cell(TotProb, CumulativeProb); // if (ihalo<=-1) // fprintf(stderr,"\tlin_ijk=%ld ",lin_ijk); k=lin_ijk%(NCells); j=((lin_ijk-k)/NCells)%NCells; i=(lin_ijk-k-j*NCells)/(NCells*NCells); if (ihalo<=-1) fprintf(stderr," = [%ld,%ld,%ld]\n",i,j,k); #else lin_ijk=select_heaviest_cell(&i,&j,&k); #endif trials=0; //Second, choose a particle in that cell do { ipart = select_part(lin_ijk,ListOfPart, NPartPerCell); // if (ihalo<=-1) // fprintf(stderr,"\tipart=%ld\n",ipart); HaloX[ihalo] = PartX[ipart]; HaloY[ihalo] = PartY[ipart]; HaloZ[ihalo] = PartZ[ipart]; HaloVX[ihalo] = PartVX[ipart]; HaloVY[ihalo] = PartVY[ipart]; HaloVZ[ihalo] = PartVZ[ipart]; R=R_from_mass(HaloMass[ihalo],rho_ref); HaloR[ihalo]= R; // if (ihalo<=-1) // fprintf(stderr,"\thalo: [[%f,%f,%f],[%f,%f,%f],%f]\n",HaloX[ihalo],HaloY[ihalo],HaloZ[ihalo],HaloVX[ihalo],HaloVY[ihalo],HaloVZ[ihalo],HaloR[ihalo]); #ifdef NO_EXCLUSION check = 0; #else //Third, check that is not overlapping a previous halo check = check_HaloR_in_mesh(ihalo,HaloX,HaloY,HaloZ,HaloR,i,j,k,ListOfHalos,NHalosPerCell); #endif // if (ihalo<=-1) // fprintf(stderr,"\tCHECK=%d\n",check); if (check==1){ #ifdef DEBUG fprintf(stderr,"Refused part : %ld\n",ipart); #endif trials++; } if (trials == MAXTRIALS){ //in order to avoid infinite loop, we will exit this loop, after MAXTRIALS trials #ifdef VERB fprintf(stderr,"MAXTRIALS=%d reached, removing cell [%ld,%ld,%ld]\n",MAXTRIALS,i,j,k); #endif MassLeft[lin_ijk]=0.; TotProb=ComputeCumulative(exponent, mpart, MassLeft, CumulativeProb); break; } } while (check==1);//If the particle was excluded, try another one in the same cell } while(check==1); //if reached MAXTRIALS, select another cell //Particle chosen! //mass in cell before assignment Mcell=MassLeft[lin_ijk]; // if (ihalo<=-1) // fprintf(stderr,"\tMbefore=%e\n",Mcell); #ifndef MASS_OF_PARTS if (Mcell>HaloMass[ihalo]) MassLeft[lin_ijk] -= Mhalo; else MassLeft[lin_ijk] = 0.; #else exclude(ipart,R,PartX,PartY,PartZ,i,j,k); #endif //// if (ihalo<=-1) // fprintf(stderr,"\tMafter=%e\n",MassLeft[lin_ijk]); #ifndef NO_MASS_CONSERVATION if (ihalo<=-1) fprintf(stderr,"\tOld version!\n"); double ProbDiff = pow(MassLeft[lin_ijk]/mpart,exponent)-pow(Mcell/mpart,exponent); #ifdef DEBUG fprintf(stderr,"\n \tassigned to cell %ld=[%ld,%ld,%ld]\n\t Before: Mcell=%e, CProbCell=%e, TotProb=%e. ",lin_ijk,i,j,k,Mcell,CumulativeProb[lin_ijk],TotProb); #endif #ifndef MASS_OF_PARTS long icell; //Substract the Probability difference from the array (only affected those cells after the selected one) #pragma omp parallel for private(icell) shared(CumulativeProb,robDiff,NTotCells,lin_ijk) default(none) for(icell=lin_ijk;icell<NTotCells;icell++){ CumulativeProb[icell]+=ProbDiff; } //TotProb+=ProbDiff; TotProb=CumulativeProb[NCells*NCells*NCells-1]; #endif #endif #ifdef DEBUG fprintf(stderr," After: Mcell=%e, CProbCell=%e, TotProb=%e. , Mhalo=%e. CProb[last]=%e\n",MassLeft[lin_ijk],CumulativeProb[lin_ijk],TotProb,Mhalo,CumulativeProb[NTotCells-1]); #endif #ifdef DEBUG fprintf(stderr,"\thalo %ld assigned to particle %ld at [%f,%f,%f]. R= %f, M= %e\n",ihalo,ipart,HaloX[ihalo],HaloY[ihalo],HaloZ[ihalo],R,Mhalo); #endif // if (ihalo<=-1) // fprintf(stderr,"\tplace ihalo=%ld",ihalo); ListOfHalos[lin_ijk][NHalosPerCell[lin_ijk]]=ihalo; // if (ihalo<=-1) // fprintf(stderr,"\t check: %ld\n",ListOfHalos[lin_ijk][NHalosPerCell[lin_ijk]]); NHalosPerCell[lin_ijk]++; // if (ihalo<=-1) // fprintf(stderr,"\t Nhalospercell[%ld]= %ld\n",lin_ijk,NHalosPerCell[lin_ijk]); }//for(ihalo=Nstart:Nend) //----------------------------------- Haloes Placed #ifdef VERB t5=time(NULL); diff = difftime(t5,t4_5); fprintf(stderr,"\ttime placing %f\n",diff); diff = difftime(t5,t0); fprintf(stderr,"\ttotal time in place_halos.c %f\n",diff); fprintf(stderr,"\n\tPlacement done!!!\n"); #endif free(NHalosPerCell); free(count); //free(NPartPerCell); free(CumulativeProb); free(MassLeft); for (i=0;i<NCells;i++){ for (j=0;j<NCells;j++){ for (k=0;k<NCells;k++){ lin_ijk = k+j*NCells+i*NCells*NCells; //free(ListOfPart[lin_ijk]); //free(ListOfHalos[lin_ijk]); } } } //free(ListOfPart); free(ListOfHalos); #ifdef MASS_OF_PARTS free(excluded); free(Nexcluded); #endif fprintf(stderr," e "); return 0; }
int place_halos(long NHalosTot, double *HaloMass, long Nlin, long NTotPart, float *PartX, float *PartY, float *PartZ, float L, float mp, float rho_ref, long seed, double *alpha, double *Malpha,long Nalpha,float *HaloX, float *HaloY, float *HaloZ){ fprintf(stderr,"Hi! This is place_halos.c v9.2\n"); fprintf(stdout,"Hi! This is place_halos.c v9.2\n"); //Initiallising ------------------------------------------------- long i,j,k,lin_ijk,check, icell, Nmin; long *count,trials; long ihalo,ilong, ipart, Nhalos,i_alpha; double invL = 1./L,diff,ProbDiff,Mcell,Mhalo,Mchange,exp; float R; double Mmin; time_t t0,t1,t2,t3,t4,t5; NCells = Nlin; lcell=L/NCells; Lbox = L; t0=time(NULL); NTotCells = NCells*NCells*NCells; //temp float *HaloR; //Allocate memory for the arrays excluded = (long *) calloc(NTotPart, sizeof(long)); NPartPerCell = (long *) calloc(NCells*NCells*NCells,sizeof(long)); NHalosPerCell = (long *) calloc(NCells*NCells*NCells,sizeof(long)); MassLeft = (double *) calloc(NCells*NCells*NCells,sizeof(double)); count = (long *) calloc(NCells*NCells*NCells,sizeof(long)); Nexcluded = (long *) calloc(NTotCells,sizeof(long)); HaloR = (float *) calloc(NHalosTot,sizeof(float)); CumulativeProb = (double *) calloc(NTotCells, sizeof(double)); if(CumulativeProb == NULL) { fprintf(stderr,"place_halos(): could not allocate %ld array for CumulativeProb[]\nABORTING",NTotCells); exit(-1); } fprintf(stderr,"Using OMP with %d threads\n",omp_get_max_threads()); //Initiallise random numbers if (seed>=0) srand(seed); else srand(t0); fprintf(stderr,"input seed: %ld. time0: %ld\n",seed,t0); mpart = (double) mp; #ifdef _VERB fprintf(stderr,"#def _VERB\n"); #endif #ifdef _DEBUG fprintf(stderr,"#def _DEBUG \n"); #endif #ifdef _ULTRADEBUG fprintf(stderr,"#def _ULTRADEBUG \n"); #endif #ifdef _PERIODIC fprintf(stderr,"#def _PERIODIC\n"); #endif #ifdef _ONLYBIG fprintf(stderr,"#def _ONLYBIG\n"); #endif Mmin = HaloMass[NHalosTot-1]; Nmin = (long)ceil(HaloMass[NHalosTot-1]/mp); #ifdef _VERB fprintf(stderr,"\nMassFunction computed globally with hmf. Particles and Halos placed in %ld^3 cells\n",NCells); fprintf(stderr,"Exclusion done only with haloes.\n"); fprintf(stderr,"BOX = %f lcell =%f rho_ref = %e invL %f\n",L,lcell,rho_ref,invL); fprintf(stderr,"Nhalos = %ld NPart = %ld\n",NHalosTot, NTotPart); fprintf(stderr,"\nRAND_MAX=%d\n",RAND_MAX); fprintf(stderr,"X[0] = %f Y[0] = %f Z[0] = %f\n",PartX[0],PartY[0],PartZ[0]); fprintf(stderr,"X[1] = %f Y[1] = %f Z[1] = %f\n",PartX[1],PartY[1],PartZ[1]); fprintf(stderr,"M[0] = %e \n",HaloMass[0]); fprintf(stderr,"M[1] = %e \n",HaloMass[1]); fprintf(stderr,"\nExclusion done only with haloes. Minimmum mass= %e. Minimum part per halo = %ld. Effective mp (not the real one) %e\n",HaloMass[NHalosTot-1],Nmin,mp); #endif t1=time(NULL); diff = difftime(t1,t0); fprintf(stderr,"time of initialisation %f\n",diff); // ------------------------------------------------- Initiallised #ifdef _VERB fprintf(stderr,"Assigning particles to grid ...\n"); #endif //Assign particles to grid ------------------------------------ //count particles per cell for (ilong=0;ilong<NTotPart;ilong++) { i = (long) (invL * PartX[ilong]*NCells); j = (long) (invL * PartY[ilong]*NCells); k = (long) (invL * PartZ[ilong]*NCells); if (i<0 || i>=NCells || j<0 || j>=NCells || k<0 || k>=NCells){ fprintf(stderr,"WARNING: Particle %ld at [%f,%f,%f] seems to be out of the right box interval [0.,%f)",ilong,PartX[ilong],PartY[ilong],PartZ[ilong],L); i=check_limit(i,NCells); j=check_limit(j,NCells); k=check_limit(k,NCells); fprintf(stderr,", placed at cell [%ld,%ld,%ld]\n",i,j,k); } lin_ijk = k+j*NCells+i*NCells*NCells; NPartPerCell[lin_ijk]++; #ifdef _DEBUG if(ilong<10 || ilong > NTotPart -10 || ilong==243666) fprintf(stderr,"ipart=%ld cell: %ld=[%ld,%ld,%ld] Parts in cell=%ld, Pos= [%f,%f,%f]\n",ilong,lin_ijk,i,j,k,NPartPerCell[lin_ijk],PartX[ilong],PartY[ilong],PartZ[ilong]); #endif } #ifdef _DEBUG fprintf(stderr,"... particles counted ...\n"); t2=time(NULL); diff = difftime(t2,t1); fprintf(stderr,"time counting %f\n",diff); #endif //Alloc Enough Memory ListOfPart = (long **) calloc(NCells*NCells*NCells,sizeof(long *)); ListOfHalos = (long **) calloc(NCells*NCells*NCells,sizeof(long *)); for (i=0;i<NCells;i++){ for (j=0;j<NCells;j++){ for (k=0;k<NCells;k++){ lin_ijk = k+j*NCells+i*NCells*NCells; ListOfPart[lin_ijk] = (long *) calloc(NPartPerCell[lin_ijk],sizeof(long)); Nhalos = (long) (NPartPerCell[lin_ijk]/Nmin); ListOfHalos[lin_ijk] = (long *) calloc(Nhalos,sizeof(long)); MassLeft[lin_ijk] = (double) NPartPerCell[lin_ijk]*mpart; #ifdef _ULTRADEBUG if (lin_ijk<10 || lin_ijk > (NCells*NCells*NCells) - 10){ fprintf(stderr,"Allocated %ld (longs) in ListOfPart(%ld=[%ld,%ld,%ld])\n",NPartPerCell[lin_ijk],lin_ijk,i,j,k); fprintf(stderr,"Allocated %ld (longs) in ListOfHalos(%ld=[%ld,%ld,%ld])\n",Nhalos,lin_ijk,i,j,k); } #endif } } } #ifdef _DEBUG fprintf(stderr,"... memory allocated ...\n"); t3=time(NULL); diff = difftime(t3,t2); fprintf(stderr,"time allocating %f\n",diff); #endif for (ilong=0;ilong<NTotPart;ilong++) { i = (long) (invL * PartX[ilong]*NCells); j = (long) (invL * PartY[ilong]*NCells); k = (long) (invL * PartZ[ilong]*NCells); i=check_limit(i,NCells); j=check_limit(j,NCells); k=check_limit(k,NCells); lin_ijk = k+j*NCells+i*NCells*NCells; ListOfPart[lin_ijk][count[lin_ijk]] = ilong; count[lin_ijk]++; } fprintf(stderr,"Mass_cell[0]=%e",MassLeft[0]); fprintf(stderr," TotProb=%e\n",TotProb); Mhalo = HaloMass[0]; i_alpha = 0; while(Mhalo<Malpha[i_alpha]) { i_alpha++; if (i_alpha==Nalpha){ fprintf(stderr,"ERROR: No alpha low enough found\n"); exit(0); } } Mchange = Malpha[i_alpha]; exp = alpha[i_alpha]; ComputeCumulative(exp); //----------------------------------- Particles assigned to grid #ifdef _VERB fprintf(stderr," ...done\n\n"); t4=time(NULL); diff = difftime(t4,t3); fprintf(stderr,"time of the actual assignment %f\n",diff); #endif #ifdef _DEBUG fprintf(stderr," Mass Function\n"); for (ihalo=0;ihalo<15;ihalo++){ fprintf(stderr,"halo %ld: ",ihalo); fprintf(stderr,"M=%e\n",HaloMass[ihalo]); } #endif #ifdef _VERB fprintf(stderr,"\nPlacing Halos...\n\n"); #endif for (ihalo=0;ihalo<NHalosTot;ihalo++){ #ifdef _DEBUG fprintf(stderr,"\n- Halo %ld ",ihalo); #endif lin_ijk = select_cell(); if(lin_ijk<0) { fprintf(stderr,"Maximum Mass cell was %e\n",MassLeft[select_heaviest_cell(&i,&j,&k,MassLeft,NCells,HaloMass[ihalo])]); break; } k=lin_ijk%(NCells); j=((lin_ijk-k)/NCells)%NCells; i=(lin_ijk-k-j*NCells)/(NCells*NCells); Mcell=MassLeft[lin_ijk]; Mhalo= HaloMass[ihalo]; while (Mhalo < Mchange){ i_alpha++; Mchange = Malpha[i_alpha]; exp = alpha[i_alpha]; ComputeCumulative(exp); } if (Mcell>HaloMass[ihalo]) MassLeft[lin_ijk] -= Mhalo; else MassLeft[lin_ijk] = 0.; ProbDiff = pow(MassLeft[lin_ijk]/mpart,exp)-pow(Mcell/mpart,exp); #ifdef _DEBUG fprintf(stderr,"\n assigned to cell %ld=[%ld,%ld,%ld]\n Before: Mcell=%e, TotProb=%e. ",lin_ijk,i,j,k,Mcell,TotProb); #endif #pragma omp parallel for private(icell) shared(CumulativeProb,ProbDiff,NTotCells,lin_ijk) default(none) for(icell=lin_ijk;icell<NTotCells;icell++){ CumulativeProb[icell]+=ProbDiff; } TotProb+=ProbDiff; #ifdef _DEBUG fprintf(stderr," After: Mcell=%e, TotProb=%e. ProbDiff=%e, Mhalo=%e\n",MassLeft[lin_ijk],TotProb,ProbDiff,Mhalo); #endif trials=0; do { ipart = select_part(lin_ijk); HaloX[ihalo] = PartX[ipart]; HaloY[ihalo] = PartY[ipart]; HaloZ[ihalo] = PartZ[ipart]; R=R_from_mass(HaloMass[ihalo],rho_ref); HaloR[ihalo]=R; check = check_HaloR_in_mesh(ihalo,HaloX,HaloY,HaloZ,HaloR,i,j,k); if (check==0){ #ifdef _DEBUG fprintf(stderr,"Refused part : %ld\n",ipart); #endif trials++; } if (trials ==20) exit(-1); } while (check==0); #ifdef _DEBUG fprintf(stderr,"halo %ld assigned to particle %ld at [%f,%f,%f]. R= %f, M= %e\n",ihalo,ipart,HaloX[ihalo],HaloY[ihalo],HaloZ[ihalo],R,Mhalo); #endif ListOfHalos[lin_ijk][NHalosPerCell[lin_ijk]]=ihalo; NHalosPerCell[lin_ijk]++; } #ifdef _VERB t5=time(NULL); diff = difftime(t5,t4); fprintf(stderr,"time placing %f\n",diff); diff = difftime(t5,t0); fprintf(stderr,"total time in .c %f\n",diff); fprintf(stderr,"\nEverything done!!!\n"); #endif free(count); free(NPartPerCell); free(ListOfPart); free(excluded); free(CumulativeProb); return 0; }
int place_halos(long NHalosTot, float *HaloMass, long Nlin, long NTotPart, float *PartX, float *PartY, float *PartZ, float L, float rho_ref, long seed, float mp, double *alpha, double *Malpha,long Nalpha,float *HaloX, float *HaloY, float *HaloZ, float *HaloR){ fprintf(stderr,"\tThis is place_halos.c v9.2\n"); //Initiallising ------------------------------------------------- long i,j,k,lin_ijk,check, icell, Nmin; long *count,trials; long ihalo,ilong, ipart, Nhalos,i_alpha; double invL = 1./L, ProbDiff; float Mcell,Mhalo,Mchange,exp; float R; time_t t0; #ifdef VERB time_t t1,t2,t3,t4,t5; float diff; #endif NCells = Nlin; Lbox = L; t0=time(NULL); NTotCells = NCells*NCells*NCells; //Allocate memory for the arrays NPartPerCell = (long *) calloc(NCells*NCells*NCells,sizeof(long)); NHalosPerCell = (long *) calloc(NCells*NCells*NCells,sizeof(long)); MassLeft = (double *) calloc(NCells*NCells*NCells,sizeof(double)); count = (long *) calloc(NCells*NCells*NCells,sizeof(long)); CumulativeProb = (double *) calloc(NTotCells, sizeof(double)); if(CumulativeProb == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for CumulativeProb[]\nABORTING",NTotCells); exit(-1); } fprintf(stderr,"\tUsing OMP with %d threads\n",omp_get_max_threads()); //Initiallise random numbers #ifdef VERB fprintf(stderr,"\tinput seed: %ld. time0: %ld. Used: ",seed,t0); #endif if (seed>=0){ srand(seed); #ifdef VERB fprintf(stderr,"%ld \n",seed); #endif } else { srand(t0); #ifdef VERB fprintf(stderr,"%ld \n",t0); #endif } mpart = (double) mp; Nmin = (long)ceil(HaloMass[NHalosTot-1]/mpart); #ifdef VERB fprintf(stderr,"\n\tParticles and Halos placed in %ld^3 cells\n",NCells); fprintf(stderr,"\tBOX = %f lcell =%f rho_ref = %e invL %f\n",L,L/NCells,rho_ref,invL); fprintf(stderr,"\tNhalos = %ld NPart = %ld\n",NHalosTot, NTotPart); #endif #ifdef DEBUG fprintf(stderr,"\n\tRAND_MAX=%d\n",RAND_MAX); fprintf(stderr,"\tX[0] = %f Y[0] = %f Z[0] = %f\n",PartX[0],PartY[0],PartZ[0]); fprintf(stderr,"\tX[1] = %f Y[1] = %f Z[1] = %f\n",PartX[1],PartY[1],PartZ[1]); fprintf(stderr,"\tM[0] = %e \n",HaloMass[0]); fprintf(stderr,"\tM[1] = %e \n",HaloMass[1]); fprintf(stderr,"\tM[%ld] = %e \n",NHalosTot-1,HaloMass[NHalosTot-1]); fprintf(stderr,"\n\tMinimmum mass= %e. Minimum part per halo = %ld. mpart %e\n",HaloMass[NHalosTot-1],Nmin,mpart); #endif #ifdef VERB t1=time(NULL); diff = difftime(t1,t0); fprintf(stderr,"\ttime of initialisation %f\n",diff); #endif // ------------------------------------------------- Initiallised #ifdef VERB fprintf(stderr,"\tAssigning particles to grid ...\n"); #endif //Assign particles to grid ------------------------------------ //count particles per cell for (ilong=0;ilong<NTotPart;ilong++) { i = (long) (invL * PartX[ilong]*NCells); j = (long) (invL * PartY[ilong]*NCells); k = (long) (invL * PartZ[ilong]*NCells); if (i<0 || i>=NCells || j<0 || j>=NCells || k<0 || k>=NCells){ fprintf(stderr,"\tWARNING: Particle %ld at [%f,%f,%f] seems to be out of the right box interval [0.,%f)",ilong,PartX[ilong],PartY[ilong],PartZ[ilong],L); i=check_limit(i,NCells); j=check_limit(j,NCells); k=check_limit(k,NCells); fprintf(stderr,", placed at cell [%ld,%ld,%ld]\n",i,j,k); } lin_ijk = k+j*NCells+i*NCells*NCells; NPartPerCell[lin_ijk]++; #ifdef DEBUG if(ilong<10 || ilong > NTotPart -10 || ilong==243666) fprintf(stderr,"\tipart=%ld cell: %ld=[%ld,%ld,%ld] Parts in cell=%ld, Pos= [%f,%f,%f]\n",ilong,lin_ijk,i,j,k,NPartPerCell[lin_ijk],PartX[ilong],PartY[ilong],PartZ[ilong]); #endif } #ifdef VERB fprintf(stderr,"\t... particles counted ...\n"); t2=time(NULL); diff = difftime(t2,t1); fprintf(stderr,"\ttime counting %f\n",diff); #endif //Alloc Enough Memory ListOfPart = (long **) calloc(NCells*NCells*NCells,sizeof(long *)); ListOfHalos = (long **) calloc(NCells*NCells*NCells,sizeof(long *)); for (i=0;i<NCells;i++){ for (j=0;j<NCells;j++){ for (k=0;k<NCells;k++){ lin_ijk = k+j*NCells+i*NCells*NCells; ListOfPart[lin_ijk] = (long *) calloc(NPartPerCell[lin_ijk],sizeof(long)); Nhalos = (long) (NPartPerCell[lin_ijk]/Nmin); ListOfHalos[lin_ijk] = (long *) calloc(Nhalos,sizeof(long)); MassLeft[lin_ijk] = (double) NPartPerCell[lin_ijk]*mpart; #ifdef ULTRADEBUG if (lin_ijk<10 || lin_ijk > (NCells*NCells*NCells) - 10){ fprintf(stderr,"\tAllocated %ld (longs) in ListOfPart(%ld=[%ld,%ld,%ld])\n",NPartPerCell[lin_ijk],lin_ijk,i,j,k); fprintf(stderr,"\tAllocated %ld (longs) in ListOfHalos(%ld=[%ld,%ld,%ld])\n",Nhalos,lin_ijk,i,j,k); } #endif } } } #ifdef VERB fprintf(stderr,"\t... memory allocated ...\n"); t3=time(NULL); diff = difftime(t3,t2); fprintf(stderr,"\ttime allocating %f\n",diff); #endif for (ilong=0;ilong<NTotPart;ilong++) { i = (long) (invL * PartX[ilong]*NCells); j = (long) (invL * PartY[ilong]*NCells); k = (long) (invL * PartZ[ilong]*NCells); i=check_limit(i,NCells); j=check_limit(j,NCells); k=check_limit(k,NCells); lin_ijk = k+j*NCells+i*NCells*NCells; ListOfPart[lin_ijk][count[lin_ijk]] = ilong; count[lin_ijk]++; } #ifdef DEBUG fprintf(stderr,"\tMass_cell[0]=%e",MassLeft[0]); #endif Mhalo = HaloMass[0]; i_alpha = 0; while(Mhalo<Malpha[i_alpha]) { i_alpha++; if (i_alpha==Nalpha){ fprintf(stderr,"\tERROR: No alpha low enough found\n"); exit(0); } } Mchange = Malpha[i_alpha]; exp = alpha[i_alpha]; ComputeCumulative(exp); #ifdef VERB fprintf(stderr,"\tNumber of alphas: %ld\n",Nalpha); fprintf(stderr,"\tUsing alpha_%ld=%f for M>%e\n",i_alpha,exp,Mchange); #endif //----------------------------------- Particles assigned to grid #ifdef VERB fprintf(stderr,"\t ...done\n\n"); t4=time(NULL); diff = difftime(t4,t3); fprintf(stderr,"\ttime of the actual assignment %f\n",diff); #endif #ifdef DEBUG fprintf(stderr,"\t Mass Function\n"); for (ihalo=0;ihalo<15;ihalo++){ fprintf(stderr,"\thalo %ld: ",ihalo); fprintf(stderr,"M=%e\n",HaloMass[ihalo]); } #endif #ifdef VERB fprintf(stderr,"\n\tPlacing Halos...\n\n"); #endif for (ihalo=0;ihalo<NHalosTot;ihalo++){ #ifdef DEBUG fprintf(stderr,"\n\t- Halo %ld ",ihalo); #endif do { #ifndef RANKED lin_ijk = select_cell(); k=lin_ijk%(NCells); j=((lin_ijk-k)/NCells)%NCells; i=(lin_ijk-k-j*NCells)/(NCells*NCells); #else lin_ijk=select_heaviest_cell(&i,&j,&k); #endif trials=0; do { ipart = select_part(lin_ijk); HaloX[ihalo] = PartX[ipart]; HaloY[ihalo] = PartY[ipart]; HaloZ[ihalo] = PartZ[ipart]; R=R_from_mass(HaloMass[ihalo],rho_ref); HaloR[ihalo]= R; #ifdef NO_EXCLUSION check = 1; #else check = check_HaloR_in_mesh(ihalo,HaloX,HaloY,HaloZ,HaloR,i,j,k); #endif if (check==0){ #ifdef DEBUG fprintf(stderr,"Refused part : %ld\n",ipart); #endif trials++; } if (trials == MAXTRIALS){ #ifdef DEBUG fprintf(stderr,"MAXTRIALS=%d reached, selecting another cell\n",MAXTRIALS); #endif break; } } while (check==0);//PART excluded } while(check==0); //if reached MAXTRIALS, select another cell Mcell=MassLeft[lin_ijk]; Mhalo= HaloMass[ihalo]; while (Mhalo < Mchange){ i_alpha++; Mchange = Malpha[i_alpha]; exp = alpha[i_alpha]; ComputeCumulative(exp); #ifdef VERB fprintf(stderr,"\n\tUsing alpha_%ld=%f for M>%e\n",i_alpha,exp,Mchange); #endif } #ifndef NO_MASS_CONSERVATION if (Mcell>HaloMass[ihalo]) MassLeft[lin_ijk] -= Mhalo; else MassLeft[lin_ijk] = 0.; #endif ProbDiff = pow(MassLeft[lin_ijk]/mpart,exp)-pow(Mcell/mpart,exp); #ifdef DEBUG fprintf(stderr,"\n \tassigned to cell %ld=[%ld,%ld,%ld]\n\t Before: Mcell=%e, TotProb=%e. ",lin_ijk,i,j,k,Mcell,TotProb); #endif #pragma omp parallel for private(icell) shared(CumulativeProb,ProbDiff,NTotCells,lin_ijk) default(none) for(icell=lin_ijk;icell<NTotCells;icell++){ CumulativeProb[icell]+=ProbDiff; } TotProb+=ProbDiff; #ifdef DEBUG fprintf(stderr," After: Mcell=%e, TotProb=%e. ProbDiff=%e, Mhalo=%e\n",MassLeft[lin_ijk],TotProb,ProbDiff,Mhalo); #endif #ifdef DEBUG fprintf(stderr,"\thalo %ld assigned to particle %ld at [%f,%f,%f]. R= %f, M= %e\n",ihalo,ipart,HaloX[ihalo],HaloY[ihalo],HaloZ[ihalo],R,Mhalo); #endif ListOfHalos[lin_ijk][NHalosPerCell[lin_ijk]]=ihalo; NHalosPerCell[lin_ijk]++; } #ifdef VERB t5=time(NULL); diff = difftime(t5,t4); fprintf(stderr,"\ttime placing %f\n",diff); diff = difftime(t5,t0); fprintf(stderr,"\ttotal time in .c %f\n",diff); fprintf(stderr,"\n\tPlacement done!!!\n"); #endif free(count); free(NPartPerCell); free(ListOfPart); free(CumulativeProb); return 0; }
//place_halos(): // //Takes a list of halo masses (Nhalos, HaloMass), a list of particles (NTotPart,PartX,PartY,PartZ), some simulation parameters (L, mp), and user-defined parameters (Nlin,rho_ref,alpha,Malpha,Nalpha,seed) //and returns a list of halo positions and radii (HaloX,HaloY,HaloZ,HaloR) int place_halos(long Nend, float *HaloMass, long Nlin, long NTotPart, float *PartX, float *PartY, float *PartZ, float *PartVX, float *PartVY, float *PartVZ,float L, float rho_ref, long seed, float mp, double *alpha, int *Nhalosbin,long Nalpha,float *HaloX, float *HaloY, float *HaloZ, float *HaloVX, float *HaloVY, float *HaloVZ,float *HaloR,long **ListOfPart, long *NPartPerCell){ fprintf(stderr,"\tThis is place_halos.c v11\n"); //Initiallising ------------------------------------------------- long i,j,k,lin_ijk,check, Nmin; long *count,trials; long ihalo, ipart,Halos_done; double invL = 1./L; float Mcell,Mhalo; float R; time_t t0; int i_alpha; long icell; double mpart; double exponent; double TotProb; double *MassLeft; double *CumulativeProb; long **ListOfHalos, *NHalosPerCell; long Nstart=0,Nhalos; #ifdef VERB time_t t1,t2,t3,t4,t5,tI,tII; float diff; #endif NCells = Nlin; Lbox = L; t0=time(NULL); NTotCells = NCells*NCells*NCells; MassLeft = malloc(NTotCells*sizeof(double)); fprintf(stderr,"N[0]=%ld, N[1]=%ld, N[2]=%ld, \n",NPartPerCell[0],NPartPerCell[1],NPartPerCell[2]); //Allocate memory for the arrays //NPartPerCell = (long *) calloc(NTotCells,sizeof(long)); /* if( NPartPerCell == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for NPartPerCell[]\nABORTING",NTotCells); exit(-1); }*/ NHalosPerCell = (long *) calloc(NTotCells,sizeof(long)); if(NHalosPerCell == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for NHalosPerCell[]\nABORTING",NTotCells); exit(-1); } count = (long *) calloc(NTotCells,sizeof(long)); if(count == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for NTotCells[]\nABORTING",NTotCells); exit(-1); } CumulativeProb = (double *) calloc(NTotCells, sizeof(double)); if(CumulativeProb == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for CumulativeProb[]\nABORTING",NTotCells); exit(-1); } fprintf(stderr,"\tUsing OMP with %d threads\n",omp_get_max_threads()); #ifdef MASS_OF_PARTS Nexcluded = (long *) calloc(NTotCells,sizeof(long)); if(Nexcluded == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for Nexcluded[]\nABORTING",NTotCells); exit(-1); } excluded = (int *) calloc(NTotPart, sizeof(long)); if(excluded == NULL) { fprintf(stderr,"\tplace_halos(): could not allocate %ld array for excluded[]\nABORTING",NTotPart); exit(-1); } #endif //Initiallise random numbers #ifdef VERB fprintf(stderr,"\tinput seed: %ld. time0: %ld.",seed,t0); #endif if (seed>=0){ srand(seed); #ifdef VERB fprintf(stderr,"Used: %ld \n",seed); #endif } else { srand(t0); fprintf(stderr,"Seed Used: %ld \n",t0); } mpart = (double) mp; //Nmin = (long)ceil(HaloMass[Nhalos-1]/mpart); Nmin = (long)ceil(HaloMass[Nend-1]*0.8/mpart); lcell = (float) L/NCells; #ifdef VERB fprintf(stderr,"\n\tParticles and Halos placed in %ld^3 cells\n",NCells); fprintf(stderr,"\tBOX = %f lcell =%f rho_ref = %e invL %f\n",L,L/NCells,rho_ref,invL); fprintf(stderr,"\tNhalostart = %ld,Nhalosend = %ld, NPart = %ld\n",Nstart, Nend, NTotPart); #endif #ifdef DEBUG fprintf(stderr,"\n\tRAND_MAX=%d\n",RAND_MAX); fprintf(stderr,"\tX[0] = %f Y[0] = %f Z[0] = %f\n",PartX[0],PartY[0],PartZ[0]); fprintf(stderr,"\tX[1] = %f Y[1] = %f Z[1] = %f\n",PartX[1],PartY[1],PartZ[1]); fprintf(stderr,"\tM[0] = %e \n",HaloMass[0]); fprintf(stderr,"\tM[1] = %e \n",HaloMass[1]); fprintf(stderr,"\tM[%ld] = %e \n",Nend-1,HaloMass[Nend-1]); fprintf(stderr,"\n\tMinimmum mass= %e. Minimum part per halo = %ld. mpart %e\n",HaloMass[Nend-1],Nmin,mpart); #endif if (L/NCells<R_from_mass(HaloMass[0],rho_ref)){ fprintf(stderr,"WARNING!!!: cell size is smaller than the radius of the biggest halo. Please, change the number of cells\n"); //exit(0); } #ifdef VERB t1=time(NULL); diff = difftime(t1,t0); fprintf(stderr,"\ttime of initialisation %f\n",diff); #endif // ------------------------------------------------- Initiallised #ifdef VERB fprintf(stderr,"\tAssigning particles to grid ...\n"); #endif #ifdef VERB fprintf(stderr,"\t... particles counted ...\n"); t2=time(NULL); diff = difftime(t2,t1); fprintf(stderr,"\ttime counting %f\n",diff); #endif //Alloc Enough Memory //ListOfPart = (long **) calloc(NCells*NCells*NCells,sizeof(long *)); ListOfHalos = (long **) calloc(NCells*NCells*NCells,sizeof(long *)); for (i=0;i<NCells;i++){ for (j=0;j<NCells;j++){ for (k=0;k<NCells;k++){ lin_ijk = k+j*NCells+i*NCells*NCells; //ListOfPart[lin_ijk] = (long *) calloc(NPartPerCell[lin_ijk],sizeof(long)); Nhalos = (long) (NPartPerCell[lin_ijk]/Nmin); ListOfHalos[lin_ijk] = (long *) calloc(Nhalos,sizeof(long)); if (Nstart==0) MassLeft[lin_ijk] = (double) NPartPerCell[lin_ijk]*mpart; #ifdef ULTRADEBUG if (lin_ijk<10 || lin_ijk > (NCells*NCells*NCells) - 10){ fprintf(stderr,"\tAllocated %ld (longs) in ListOfPart(%ld=[%ld,%ld,%ld])\n",NPartPerCell[lin_ijk],lin_ijk,i,j,k); fprintf(stderr,"\tAllocated %ld (longs) in ListOfHalos(%ld=[%ld,%ld,%ld])\n",Nhalos,lin_ijk,i,j,k); } #endif } } } #ifdef VERB fprintf(stderr,"\t... memory allocated ...\n"); t3=time(NULL); diff = difftime(t3,t2); fprintf(stderr,"\ttime allocating %f\n",diff); #endif for (ihalo=0;ihalo<Nstart;ihalo++){ i = (long) (invL * HaloX[ihalo]*NCells); j = (long) (invL * HaloY[ihalo]*NCells); k = (long) (invL * HaloZ[ihalo]*NCells); i=check_limit(i,NCells); j=check_limit(j,NCells); k=check_limit(k,NCells); lin_ijk = k+j*NCells+i*NCells*NCells; ListOfHalos[lin_ijk][NHalosPerCell[lin_ijk]] = ihalo; NHalosPerCell[lin_ijk]++; } #ifdef DEBUG fprintf(stderr,"\tMass_cell[0]=%e",MassLeft[0]); fprintf(stderr,"\t Mass Function\n"); for (ihalo=0;ihalo<15;ihalo++){ fprintf(stderr,"\thalo %ld: ",ihalo); fprintf(stderr,"M=%e\n",HaloMass[ihalo]); } #endif #ifdef VERB fprintf(stderr,"\t ...done\n\n"); t4=time(NULL); diff = difftime(t4,t3); fprintf(stderr,"\ttime of the actual assignment %f\n",diff); fprintf(stderr,"\tComputing probabilities...\n"); #endif //----------------------------------- Particles and haloes assigned to grid //Actually placing the haloes----------------------------------- Halos_done =0; for(i_alpha=0;i_alpha<Nalpha;i_alpha++){ exponent = alpha[i_alpha]; tI=time(NULL); TotProb=ComputeCumulative(exponent, mpart, MassLeft, CumulativeProb); tII=time(NULL); diff = difftime(tII,tI); fprintf(stderr,"\t\t alpha[%d]=%f. time computing prob: %f\n",i_alpha,exponent,diff); Nstart = Halos_done; Nend = Halos_done + Nhalosbin[i_alpha]; fprintf(stderr,"\tNstart=%ld, Nend=%ld\n",Nstart,Nend); #ifndef NO_HALOS_PARALLEL #pragma omp parallel for private(Mhalo,ihalo,Mcell,R,i,j,k,lin_ijk,check,trials,ipart,icell) shared(rho_ref,HaloMass,NCells,TotProb,Nend,Nstart,stderr,ListOfHalos,ListOfPart,NHalosPerCell,NPartPerCell,MassLeft,PartX,PartY,PartZ,PartVX,PartVY,PartVZ,HaloX,HaloY,HaloZ,HaloVX,HaloVY,HaloVZ,HaloR,CumulativeProb,stdout) default(none) #endif for (ihalo=Nstart;ihalo<Nend;ihalo++){ #ifdef DEBUG fprintf(stderr,"\n\t- Halo %ld \n",ihalo); #endif #ifdef VERB if ((ihalo%1000000)==0) fprintf(stderr,"\t%ld million haloes done\n",(ihalo/1000000)); #endif Mhalo= HaloMass[ihalo]; do { //First, choose a cell trials=0; #ifndef RANKED do{ lin_ijk = select_cell(TotProb, CumulativeProb); if (trials == MAXTRIALS){ fprintf(stderr,"WARNING: MAXTRIALS=%d reached and selected a complete cell\n",MAXTRIALS); break; } trials++; } while (MassLeft[lin_ijk]==0.); k=lin_ijk%(NCells); j=((lin_ijk-k)/NCells)%NCells; i=(lin_ijk-k-j*NCells)/(NCells*NCells); #else lin_ijk=select_heaviest_cell(&i,&j,&k); #endif trials=0; //Second, choose a particle in that cell do { ipart = select_part(lin_ijk,ListOfPart, NPartPerCell); HaloX[ihalo] = PartX[ipart]; HaloY[ihalo] = PartY[ipart]; HaloZ[ihalo] = PartZ[ipart]; HaloVX[ihalo] = PartVX[ipart]; HaloVY[ihalo] = PartVY[ipart]; HaloVZ[ihalo] = PartVZ[ipart]; R=R_from_mass(HaloMass[ihalo],rho_ref); HaloR[ihalo]= R; #ifdef NO_EXCLUSION check = 0; #else //Third, check that is not overlapping a previous halo //check = check_HaloR_in_mesh(ihalo,HaloX,HaloY,HaloZ,HaloR,i,j,k,ListOfHalos,NHalosPerCell); fprintf(stderr,"Shouldnt be here!\n"); #endif if (check==1){ #ifdef DEBUG fprintf(stderr,"Refused part : %ld\n",ipart); #endif trials++; } if (trials == MAXTRIALS){ //in order to avoid infinite loop, we will exit this loop, after MAXTRIALS trials //#ifdef VERB fprintf(stderr,"MAXTRIALS=%d reached, removing cell [%ld,%ld,%ld]\n",MAXTRIALS,i,j,k); //#endif MassLeft[lin_ijk]=0.; //TotProb=ComputeCumulative(exponent, mpart, MassLeft, CumulativeProb); break; } } while (check==1);//If the particle was excluded, try another one in the same cell } while(check==1); //if reached MAXTRIALS, select another cell //Particle chosen! //mass in cell before assignment Mcell=MassLeft[lin_ijk]; #ifndef MASS_OF_PARTS if (Mcell>HaloMass[ihalo]) MassLeft[lin_ijk] -= Mhalo; else MassLeft[lin_ijk] = 0.; #else exclude(ipart,R,PartX,PartY,PartZ,i,j,k); #endif #ifndef NO_MASS_CONSERVATION double ProbDiff = pow(MassLeft[lin_ijk]/mpart,exponent)-pow(Mcell/mpart,exponent); #ifdef DEBUG fprintf(stderr,"\n \tassigned to cell %ld=[%ld,%ld,%ld]\n\t Before: Mcell=%e, CProbCell=%e, TotProb=%e. ",lin_ijk,i,j,k,Mcell,CumulativeProb[lin_ijk],TotProb); #endif #ifndef MASS_OF_PARTS //Substract the Probability difference from the array (only affected those cells after the selected one) #pragma omp parallel for private(icell) shared(CumulativeProb,ProbDiff,NTotCells,lin_ijk) default(none) for(icell=lin_ijk;icell<NTotCells;icell++){ CumulativeProb[icell]+=ProbDiff; } TotProb=CumulativeProb[NCells*NCells*NCells-1]; #endif #endif #ifdef DEBUG fprintf(stderr," After: Mcell=%e, CProbCell=%e, TotProb=%e. ProbDiff=, Mhalo=%e. CProb[last]=%e\n",MassLeft[lin_ijk],CumulativeProb[lin_ijk],TotProb,Mhalo,CumulativeProb[NCells*NCells*NCells-1]); fprintf(stderr,"\thalo %ld assigned to particle %ld at [%f,%f,%f]. R= %f, M= %e\n",ihalo,ipart,HaloX[ihalo],HaloY[ihalo],HaloZ[ihalo],R,Mhalo); #endif ListOfHalos[lin_ijk][NHalosPerCell[lin_ijk]]=ihalo; NHalosPerCell[lin_ijk]++; }//for(ihalo=Halos_done + Nalpha) Halos_done += Nhalosbin[i_alpha]; } //----------------------------------- Haloes Placed #ifdef VERB t5=time(NULL); diff = difftime(t5,t4); fprintf(stderr,"\ttime placing %f\n",diff); diff = difftime(t5,t0); fprintf(stderr,"\ttotal time in place_halos.c %f\n",diff); fprintf(stderr,"\n\tPlacement done!!!\n"); #endif free(NHalosPerCell); free(count); free(CumulativeProb); free(MassLeft); /* for (i=0;i<NCells;i++){ for (j=0;j<NCells;j++){ for (k=0;k<NCells;k++){ lin_ijk = k+j*NCells+i*NCells*NCells; free(ListOfHalos[lin_ijk]); } } } */ free(ListOfHalos); #ifdef MASS_OF_PARTS free(excluded); free(Nexcluded); #endif fprintf(stderr," e "); return 0; }
int main(int argc, char *argv[]) { /* definitions */ int nocells; /* number of cells */ int nonets; /* number of nets */ int nopins; /* number of pins */ int noparts; /* number of partitions */ int totsize; /* total net weight of the partition */ int totcellsize; /* total cell weight of the partition */ int cutsize; /* cutsize of the partition */ int max_gain; /* max gain of a cell */ int max_density; /* max density of a cell */ int max_cweight; /* max cell weight */ int max_nweight; /* max net weight */ int bucketsize; /* max size of a bucket array */ int msize; /* index to mcells */ if (argc < 5) { printf("\nUsage: %s InputFileName NoParts InCount OutCount [Seed]\n", argv[0]); printf("\t#cells moved per phase = incount * nocells / 4\n"); printf("\t\tUse 1, 2, 3, or 4 for incount.\n"); printf("\t#cells moved per pass = nocells if outcount = 1,\n"); printf("\t#cells moved per pass = nocells * noparts if outcount = 2, and\n"); printf("\t#cells moved per pass = nocells * noparts * noparts if outcount = 3.\n"); exit(1); } /* if */ char fname[STR_SIZE]; sprintf(fname, "%s", argv[1]); noparts = atoi(argv[2]); int incount = atoi(argv[3]); int outcount = atoi(argv[4]); long seed; if (argc > 5) { seed = (long) atoi(argv[5]); } else { seed = (long) -1; } seed = randomize((long) seed); printf("SEED = %ld fname = %s\n", seed, fname); read_graph_size(fname, &nocells, &nonets); nopins = 2 * nonets; /* determine what in- & out-count imply */ int max_moved_cells = incount * nocells / 4; switch (outcount) { case 1 : outcount = nocells; break; case 2 : outcount = nocells * noparts; break; case 3 : outcount = nocells * noparts * noparts; break; default : break; } /* max_noiter = outcount / max_moved_cells;*/ /* do that many iterations */ int max_noiter = outcount; /* alloc memory for all data structures */ cells_t *cells = (cells_t *) calloc(nocells, sizeof(cells_t)); assert(cells != NULL); cells_info_t *cells_info = (cells_info_t *) calloc(nocells, sizeof(cells_info_t)); assert(cells_info != NULL); for (int i = 0; i < nocells; i++) { cells_info[i].mgain = (int *) calloc(noparts, sizeof(int)); cells_info[i].partb_ptr = (bnode_ptr_t *) calloc(noparts - 1, sizeof(bnode_ptr_t)); cells_info[i].partb_gain_inx = (int *) calloc(noparts - 1, sizeof(int)); } nets_t *nets = (nets_t *) calloc(nonets, sizeof(nets_t)); assert(nets != NULL); /* cells of nets */ corn_t *cnets = (corn_t *) calloc(nopins, sizeof(corn_t)); assert(cnets != NULL); /* partition buckets */ partb_t partb[noparts][noparts - 1]; parts_info_t parts_info[noparts]; /* population (w/ one individual!) */ ind_t pop[MAX_POP]; for (int i = 0; i < MAX_POP; i++) { pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); } /* selected cell */ selected_cell_t scell[1]; /* moved cells */ mcells_t *mcells = (mcells_t *) calloc(2 * max_noiter, sizeof(mcells_t)); assert(mcells != NULL); /* temp chrom */ allele *tchrom = (allele *) calloc(nocells, sizeof(allele)); assert(tchrom != NULL); read_graph(fname, nocells, nonets, noparts, &totsize, &totcellsize, &max_density, &max_cweight, &max_nweight, cells, nets, cnets); max_gain = max_density * max_nweight; bucketsize = 2 * max_gain + 1; /* alloc memory (statically if possible) */ for (int i = 0; i < noparts; i++) { for (int j = 0; j < noparts - 1; ++j) { partb[i][j].bnode_ptr = (bnode_ptr_t *) calloc(bucketsize, sizeof(bnode_ptr_t)); } } create_partition(nocells, noparts, totcellsize, cells, &pop[0]); #ifdef DEBUG printf("Initial : Part_no min_size curr_size max_size\n"); for (int i = 0; i < noparts; i++) { printf("II %d %d %d %d\n", i, pop[0].parts[i].pmin_size, pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); } #endif init_buckets(noparts, bucketsize, partb); cutsize = find_cut_size(nonets, totsize, nets, &pop[0]); #ifdef DEBUG printf("Totalsize = %d Initial cutsize = %d\n", totsize, cutsize); #endif int gain_sum; int glob_inx = 0; int pass_no = 0; do { copy_partition(noparts, parts_info, &pop[0]); for (int i = 0; i < nocells; i++) { tchrom[i] = pop[0].chrom[i]; } msize = 0; int noiter = 0; while (noiter < max_noiter) { compute_gains(nocells, noparts, tchrom, cells, nets, cnets, cells_info); create_buckets(nocells, noparts, max_gain, tchrom, partb, cells_info); /* max_moved_cells = nocells / 2; */ int nlocked = 0; do { int move_possible = select_cell(noparts, scell, parts_info, cells, partb, cells_info); delete_partb_nodes_of_cell(noparts, scell[0].mov_cell_no, scell[0].from_part, partb, cells_info); /* lock cell */ cells_info[scell[0].mov_cell_no].locked = True; if (move_possible == True) { move_cell(mcells, msize, scell, tchrom); msize++; update_gains(noparts, max_gain, scell, tchrom, cells, nets, cnets, partb, cells_info); } /* if */ nlocked++; noiter++; } while ((nlocked < max_moved_cells) && (noiter < max_noiter)); free_nodes(noparts, bucketsize, partb); } /* while */ int max_mcells_inx; gain_sum = find_move_set(mcells, msize, &max_mcells_inx); #ifdef DEBUG printf("gain_sum=%d max_mcells_inx=%d msize = %d\n", gain_sum, max_mcells_inx, msize); #endif if (gain_sum > 0) { int cut_gain = move_cells(False, mcells, max_mcells_inx, cutsize, &glob_inx, &pop[0], cells); cutsize -= cut_gain; } /* if */ pass_no++; #ifdef DEBUG printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", pass_no, cutsize, find_cut_size(nonets, totsize, nets, &pop[0])); #endif } while ((gain_sum > 0) && (cutsize > 0)); printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", pass_no, cutsize, find_cut_size(nonets, totsize, nets, &pop[0])); free_nodes(noparts, bucketsize, partb); #ifdef DEBUG printf("Final : Part_no min_size curr_size max_size\n"); for (int i = 0; i < noparts; i++) { printf("FF %d %d %d %d\n", i, pop[0].parts[i].pmin_size, pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); } #endif /* free memory for all data structures */ cfree(cells); for (int i = 0; i < nocells; i++) { cfree(cells_info[i].mgain); cfree(cells_info[i].partb_ptr); cfree(cells_info[i].partb_gain_inx); } cfree(cells_info); cfree(nets); cfree(cnets); for (int i = 0; i < noparts; i++) { for (int j = 0; j < noparts - 1; ++j) { cfree(partb[i][j].bnode_ptr); } } for (int i = 0; i < MAX_POP; i++) { cfree(pop[i].chrom); cfree(pop[i].parts); } cfree(mcells); cfree(tchrom); return (0); } /* main-plm */