Пример #1
0
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 */
Пример #2
0
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;
	}
}
Пример #3
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, 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;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
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 */