/* Load the rule and keyd file into our private data. Return 0 on success */ static int load_special_files(sc_card_t * card) { sc_context_t *ctx = card->ctx; int r, recno; struct df_info_s *dfi; struct rule_record_s *rule; struct keyd_record_s *keyd; /* First check whether we already cached it. */ dfi = get_df_info(card); if (dfi && dfi->rule_file) return 0; /* yes. */ clear_special_files(dfi); if (!dfi) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); /* Read rule file. Note that we bypass our cache here. */ r = select_part(card, MCRD_SEL_EF, EF_Rule, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "selecting EF_Rule failed"); for (recno = 1;; recno++) { u8 recbuf[256]; r = sc_read_record(card, recno, recbuf, sizeof(recbuf), SC_RECORD_BY_REC_NR); if (r == SC_ERROR_RECORD_NOT_FOUND) break; else if (r < 0) { SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); } else { rule = malloc(sizeof *rule + r); if (!rule) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); rule->recno = recno; rule->datalen = r; memcpy(rule->data, recbuf, r); rule->next = dfi->rule_file; dfi->rule_file = rule; } } sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "new EF_Rule file loaded (%d records)\n", recno - 1); /* Read the KeyD file. Note that we bypass our cache here. */ r = select_part(card, MCRD_SEL_EF, EF_KeyD, NULL); if (r == SC_ERROR_FILE_NOT_FOUND) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no EF_KeyD file available\n"); return 0; /* That is okay. */ } SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "selecting EF_KeyD failed"); for (recno = 1;; recno++) { u8 recbuf[256]; r = sc_read_record(card, recno, recbuf, sizeof(recbuf), SC_RECORD_BY_REC_NR); if (r == SC_ERROR_RECORD_NOT_FOUND) break; else if (r < 0) { SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); } else { keyd = malloc(sizeof *keyd + r); if (!keyd) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); keyd->recno = recno; keyd->datalen = r; memcpy(keyd->data, recbuf, r); keyd->next = dfi->keyd_file; dfi->keyd_file = keyd; } } sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "new EF_KeyD file loaded (%d records)\n", recno - 1); /* FIXME: Do we need to restore the current DF? I guess it is not required, but we could try to do so by selecting 3fff? */ 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; }
void tetris(void) { char c, part_no; byte i, stop, start; show_splashscreen(); io_write(5, 42); io_write(6, 15); draw_playfield(); start_song(); start = 1; while (1) { if (start) { next_part_no = rand() % 7; lines = 0; curr_y = 10; remove_complete_lines(); clear_next_part(); while (io_read(128) != 255); do { vputs(95, 65, "GET READY"); buf2screen(); delay_ms(300); vputs(95, 65, " "); buf2screen(); delay_ms(300); } while (io_read(128) == 255); start = 0; } stop = 0; curr_x = 5; curr_y = 1; clear_next_part(); part_no = next_part_no; next_part_no = rand() % 7; draw_next_part(); select_part(part_no); draw_curr_part(); buf2screen(); while (!stop) { for (i = 0; i < 20 && !stop; i++) { if (lines < 20) delay_ms(35); else if (lines < 50) delay_ms(25); else if (lines < 70) delay_ms(18); else if (lines < 100) delay_ms(12); else delay_ms(8); if (!stop) { c = io_read(128); if (c == ' ') { // rotate part rotate_curr_part(); buf2screen(); } else if (c == 0) { // left, right, down c = io_read(128); if (c == 75) { // left move_left(); buf2screen(); } else if (c == 77) { // right move_right(); buf2screen(); } else if (c == 80) { // down while (!move_down()) buf2screen(); buf2screen(); stop = 1; } } else if (c == 27) return; } // if (!stop) } if (!stop) { stop = move_down(); buf2screen(); } } remove_complete_lines(); if (curr_y <= 2) { clear_playfield(); vputs(95, 65, "GAME OVER"); buf2screen(); getchar(); vputs(95, 65, " "); start = 1; } } }