void init_field(int n_d, int *n, double *L, field_info *FFT) { ptrdiff_t n_x_local; ptrdiff_t i_x_start_local; ptrdiff_t n_y_transpose_local; ptrdiff_t i_y_start_transpose_local; ptrdiff_t *n_x_rank; int flag_active; int n_active; int min_size, max_size; SID_log("Initializing ", SID_LOG_OPEN); for(ptrdiff_t i_d = 0; i_d < n_d; i_d++) { if(i_d < (n_d - 1)) SID_log("%dx", SID_LOG_CONTINUE, n[i_d]); else SID_log("%d element %d-d FFT ", SID_LOG_CONTINUE, n[i_d], n_d); } SID_log("(%d byte precision)...", SID_LOG_CONTINUE, (int)sizeof(GBPREAL)); // Initialize FFT sizes FFT->n_d = n_d; FFT->n = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d); FFT->L = (double *)SID_calloc(sizeof(double) * FFT->n_d); FFT->n_k_local = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d); FFT->n_R_local = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d); FFT->i_R_start_local = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d); FFT->i_k_start_local = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d); FFT->i_R_stop_local = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d); FFT->i_k_stop_local = (ptrdiff_t *)SID_calloc(sizeof(ptrdiff_t) * FFT->n_d); for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) { FFT->n[i_d] = n[i_d]; FFT->L[i_d] = L[i_d]; FFT->i_R_start_local[i_d] = 0; FFT->i_k_start_local[i_d] = 0; FFT->n_R_local[i_d] = FFT->n[i_d]; FFT->n_k_local[i_d] = FFT->n[i_d]; } FFT->n_k_local[FFT->n_d - 1] = FFT->n[FFT->n_d - 1] / 2 + 1; // Initialize FFTW // Create an integer version of FFT->n[] to pass to ..._create_plan int *n_int=(int *)SID_malloc(sizeof(int)*FFT->n_d); for(int i_d=0;i_d<FFT->n_d;i_d++) n_int[i_d]=(int)FFT->n[i_d]; #if FFTW_V2 #if USE_MPI int total_local_size_int; int n_x_local_int; int i_x_start_local_int; int n_y_transpose_local_int; int i_y_start_transpose_local_int; FFT->plan = rfftwnd_mpi_create_plan(SID.COMM_WORLD->comm, FFT->n_d, n_int, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); FFT->iplan = rfftwnd_mpi_create_plan(SID.COMM_WORLD->comm, FFT->n_d, n_int, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE); rfftwnd_mpi_local_sizes(FFT->plan, &(n_x_local_int), &(i_x_start_local_int), &(n_y_transpose_local_int), &(i_y_start_transpose_local_int), &total_local_size_int); n_x_local = (ptrdiff_t)n_x_local_int; i_x_start_local = (ptrdiff_t)i_x_start_local_int; n_y_transpose_local = (ptrdiff_t)n_y_transpose_local_int; i_y_start_transpose_local = (ptrdiff_t)i_y_start_transpose_local_int; FFT->total_local_size = (size_t)total_local_size_int; #else FFT->total_local_size = 1; for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) { if(i_d < FFT->n_d - 1) FFT->total_local_size *= FFT->n[i_d]; else FFT->total_local_size *= 2 * (FFT->n[i_d] / 2 + 1); } #if USE_DOUBLE FFT->plan = fftwnd_create_plan(FFT->n_d, n_int, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE | FFTW_IN_PLACE); FFT->iplan = fftwnd_create_plan(FFT->n_d, n_int, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE | FFTW_IN_PLACE); #else FFT->plan = rfftwnd_create_plan(FFT->n_d, n_int, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE | FFTW_IN_PLACE); FFT->iplan = rfftwnd_create_plan(FFT->n_d, n_int, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE | FFTW_IN_PLACE); #endif #endif #else #if USE_MPI #if USE_DOUBLE fftw_mpi_init(); FFT->total_local_size = fftw_mpi_local_size_many_transposed(FFT->n_d, FFT->n, 1, FFTW_MPI_DEFAULT_BLOCK, FFTW_MPI_DEFAULT_BLOCK, SID_COMM_WORLD->comm, &(n_x_local), &(i_x_start_local), &(n_y_transpose_local), &(i_y_start_transpose_local)); FFT->plan = fftw_mpi_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE); FFT->iplan = fftw_mpi_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE); #else fftwf_mpi_init(); FFT->total_local_size = fftwf_mpi_local_size_many_transposed(FFT->n_d, FFT->n, 1, FFTW_MPI_DEFAULT_BLOCK, FFTW_MPI_DEFAULT_BLOCK, SID_COMM_WORLD->comm, &(n_x_local), &(i_x_start_local), &(n_y_transpose_local), &(i_y_start_transpose_local)); FFT->plan = fftwf_mpi_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE); FFT->iplan = fftwf_mpi_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, SID_COMM_WORLD->comm, FFTW_ESTIMATE); #endif #else FFT->total_local_size = 1; for(ptrdiff_t i_d=0; i_d < FFT->n_d; i_d++) { if(i_d < FFT->n_d - 1) FFT->total_local_size *= FFT->n[i_d]; else FFT->total_local_size *= 2 * (FFT->n[i_d] / 2 + 1); } #if USE_DOUBLE FFT->plan = fftw_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, FFTW_ESTIMATE); FFT->iplan = fftw_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, FFTW_ESTIMATE); #else FFT->plan = fftwf_plan_dft_r2c(FFT->n_d, FFT->n, FFT->field_local, FFT->cfield_local, FFTW_ESTIMATE); FFT->iplan = fftwf_plan_dft_c2r(FFT->n_d, FFT->n, FFT->cfield_local, FFT->field_local, FFTW_ESTIMATE); #endif #endif #endif SID_free(SID_FARG n_int); // Set empty slabs to start at 0 to make ignoring them simple. if(n_x_local == 0) i_x_start_local = 0; if(n_y_transpose_local == 0) i_y_start_transpose_local = 0; // Modify the local slab dimensions according to what FFTW chose. FFT->i_R_start_local[0] = i_x_start_local; FFT->n_R_local[0] = n_x_local; if(FFT->n_d > 1) { FFT->i_k_start_local[1] = i_y_start_transpose_local; FFT->n_k_local[1] = n_y_transpose_local; } // Allocate field #if USE_FFTW3 FFT->field_local = (gbpFFT_real *)fftwf_alloc_real(FFT->total_local_size); #else FFT->field_local = (gbpFFT_real *)SID_malloc(sizeof(gbpFFT_real)*FFT->total_local_size); #endif FFT->cfield_local = (gbpFFT_complex *)FFT->field_local; // Upper limits of slab decomposition for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) { FFT->i_R_stop_local[i_d] = FFT->i_R_start_local[i_d] + FFT->n_R_local[i_d] - 1; FFT->i_k_stop_local[i_d] = FFT->i_k_start_local[i_d] + FFT->n_k_local[i_d] - 1; } // FFTW padding sizes if(FFT->n_d > 1) { FFT->pad_size_R = 2 * (FFT->n_R_local[FFT->n_d - 1] / 2 + 1) - FFT->n_R_local[FFT->n_d - 1]; FFT->pad_size_k = 0; } else { FFT->pad_size_R = 0; FFT->pad_size_k = 0; } // Number of elements (global and local) in the FFT ptrdiff_t i_d = 0; for(FFT->n_field = 1, FFT->n_field_R_local = 1, FFT->n_field_k_local = 1; i_d < FFT->n_d; i_d++) { FFT->n_field *= (size_t)FFT->n[i_d]; FFT->n_field_R_local *= (size_t)FFT->n_R_local[i_d]; FFT->n_field_k_local *= (size_t)FFT->n_k_local[i_d]; } // Clear the field clear_field(FFT); // Initialize the FFT's real-space grid FFT->R_field = (double **)SID_malloc(sizeof(double *) * FFT->n_d); FFT->dR = (double *)SID_malloc(sizeof(double *) * FFT->n_d); for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) { FFT->R_field[i_d] = (double *)SID_malloc(sizeof(double) * (FFT->n[i_d] + 1)); FFT->dR[i_d] = FFT->L[i_d] / (double)(FFT->n[i_d]); for(ptrdiff_t i_i = 0; i_i < FFT->n[i_d]; i_i++) FFT->R_field[i_d][i_i] = FFT->L[i_d] * ((double)i_i / (double)(FFT->n[i_d])); FFT->R_field[i_d][FFT->n[i_d]] = FFT->L[i_d]; } // Initialize the FFT's k-space grid FFT->k_field = (double **)SID_malloc(sizeof(double *) * FFT->n_d); FFT->dk = (double *)SID_malloc(sizeof(double *) * FFT->n_d); FFT->k_Nyquist = (double *)SID_malloc(sizeof(double *) * FFT->n_d); for(ptrdiff_t i_d = 0; i_d < FFT->n_d; i_d++) { FFT->k_field[i_d] = (double *)SID_malloc(sizeof(double) * FFT->n[i_d]); FFT->dk[i_d] = TWO_PI / FFT->L[i_d]; FFT->k_Nyquist[i_d] = TWO_PI * (double)(FFT->n[i_d]) / FFT->L[i_d] / 2.; for(ptrdiff_t i_i = 0; i_i < FFT->n[i_d]; i_i++) { if(i_i >= FFT->n[i_d] / 2) FFT->k_field[i_d][i_i] = TWO_PI * (double)(i_i - FFT->n[i_d]) / FFT->L[i_d]; else FFT->k_field[i_d][i_i] = TWO_PI * (double)(i_i) / FFT->L[i_d]; } } // Flags FFT->flag_padded = GBP_FALSE; // Slab info FFT->slab.n_x_local = FFT->n_R_local[0]; FFT->slab.i_x_start_local = FFT->i_R_start_local[0]; FFT->slab.i_x_stop_local = FFT->i_R_stop_local[0]; FFT->slab.x_min_local = FFT->R_field[0][FFT->i_R_start_local[0]]; if(FFT->slab.n_x_local > 0) FFT->slab.x_max_local = FFT->R_field[0][FFT->i_R_stop_local[0] + 1]; else FFT->slab.x_max_local = FFT->slab.x_min_local; SID_Allreduce(&(FFT->slab.x_max_local), &(FFT->slab.x_max), 1, SID_DOUBLE, SID_MAX, SID_COMM_WORLD); #if USE_MPI // All ranks are not necessarily assigned any slices, so // we need to figure out what ranks are to the right and the left for // buffer exchanges n_x_rank = (ptrdiff_t *)SID_malloc(sizeof(ptrdiff_t) * SID.n_proc); n_x_rank[SID.My_rank] = (ptrdiff_t)FFT->slab.n_x_local; if(n_x_rank[SID.My_rank] > 0) flag_active = GBP_TRUE; else flag_active = GBP_FALSE; SID_Allreduce(&flag_active, &n_active, 1, SID_INT, SID_SUM, SID_COMM_WORLD); SID_Allreduce(&n_x_rank[SID.My_rank], &min_size, 1, SID_INT, SID_MIN, SID_COMM_WORLD); SID_Allreduce(&n_x_rank[SID.My_rank], &max_size, 1, SID_INT, SID_MAX, SID_COMM_WORLD); for(int i_rank = 0; i_rank < SID.n_proc; i_rank++) SID_Bcast(&(n_x_rank[i_rank]), 1, SID_INT, i_rank, SID_COMM_WORLD); FFT->slab.rank_to_right = -1; for(int i_rank = SID.My_rank + 1; i_rank < SID.My_rank + SID.n_proc && FFT->slab.rank_to_right < 0; i_rank++) { int j_rank = i_rank % SID.n_proc; if(n_x_rank[j_rank] > 0) FFT->slab.rank_to_right = j_rank; } if(FFT->slab.rank_to_right < 0) FFT->slab.rank_to_right = SID.My_rank; FFT->slab.rank_to_left = -1; for(int i_rank = SID.My_rank - 1; i_rank > SID.My_rank - SID.n_proc && FFT->slab.rank_to_left < 0; i_rank--) { int j_rank = i_rank; if(i_rank < 0) j_rank = i_rank + SID.n_proc; if(n_x_rank[j_rank] > 0) FFT->slab.rank_to_left = j_rank; } if(FFT->slab.rank_to_left < 0) FFT->slab.rank_to_left = SID.My_rank; free(n_x_rank); SID_log("(%d cores unused, min/max slab size=%d/%d)...", SID_LOG_CONTINUE, SID.n_proc - n_active, min_size, max_size); #else FFT->slab.rank_to_right = SID.My_rank; FFT->slab.rank_to_left = SID.My_rank; if(FFT->slab.n_x_local > 0) { flag_active = GBP_TRUE; n_active = 1; min_size = FFT->slab.n_x_local; max_size = FFT->slab.n_x_local; } else { flag_active = GBP_FALSE; n_active = 0; min_size = 0; max_size = 0; } #endif SID_log("Done.", SID_LOG_CLOSE); }
void init_cfunc(cfunc_info *cfunc,const char *filename_cosmology,int n_data, int n_random,int n_bits_PHK, double redshift, double box_size,int n_jack, double r_min_l1D, double r_max_1D,double dr_1D, double r_min_2D, double r_max_2D,double dr_2D){ SID_log("Initializing correlation function...",SID_LOG_OPEN); // Initialize flags cfunc->initialized =TRUE; cfunc->flag_compute_RR=TRUE; // Initialize constants cfunc->n_data =n_data; cfunc->n_random =n_random; cfunc->F_random =(double)n_random/(double)n_data; cfunc->redshift =redshift; cfunc->box_size =box_size; cfunc->n_jack =n_jack; cfunc->r_min_l1D =r_min_l1D; cfunc->lr_min_l1D=take_log10(r_min_l1D); cfunc->r_max_1D =r_max_1D; cfunc->r_min_2D =r_min_2D; cfunc->r_max_2D =r_max_2D; cfunc->r_max =MAX(cfunc->r_max_1D,cfunc->r_max_2D); cfunc->dr_1D =dr_1D; cfunc->dr_2D =dr_2D; // Decide on PHK boundary widths cfunc->n_bits_PHK=n_bits_PHK; for(cfunc->PHK_width=1;cfunc->PHK_width<20 && (double)cfunc->PHK_width*(cfunc->box_size/pow(2.,(double)(cfunc->n_bits_PHK)))<cfunc->r_max;) cfunc->PHK_width++; // Initialize the number of bins cfunc->n_1D =(int)(0.5+(cfunc->r_max_1D)/cfunc->dr_1D); cfunc->n_2D =(int)(0.5+(cfunc->r_max_2D-cfunc->r_min_2D)/cfunc->dr_2D); cfunc->n_2D_total =cfunc->n_2D*cfunc->n_2D; cfunc->n_jack_total=cfunc->n_jack*cfunc->n_jack*cfunc->n_jack; SID_log("keys =%d-bit", SID_LOG_COMMENT,cfunc->n_bits_PHK); SID_log("boundries =%d keys",SID_LOG_COMMENT,cfunc->PHK_width); SID_log("# of 1D bins=%d", SID_LOG_COMMENT,cfunc->n_1D); SID_log("# of 2D bins=%d", SID_LOG_COMMENT,cfunc->n_2D); // Initialize logarythmic bin sizes cfunc->dr_l1D=(take_log10(cfunc->r_max_1D)-cfunc->lr_min_l1D)/(double)cfunc->n_1D; // Initialize arrays cfunc->CFUNC_l1D =(double **)SID_malloc(sizeof(double *)*4); cfunc->dCFUNC_l1D=(double **)SID_malloc(sizeof(double *)*4); cfunc->COVMTX_l1D=(double **)SID_malloc(sizeof(double *)*4); cfunc->CFUNC_1D =(double **)SID_malloc(sizeof(double *)*4); cfunc->dCFUNC_1D =(double **)SID_malloc(sizeof(double *)*4); cfunc->COVMTX_1D =(double **)SID_malloc(sizeof(double *)*4); cfunc->CFUNC_2D =(double **)SID_malloc(sizeof(double *)*4); cfunc->dCFUNC_2D =(double **)SID_malloc(sizeof(double *)*4); cfunc->COVMTX_2D =(double **)SID_malloc(sizeof(double *)*4); int i_run; for(i_run=0;i_run<4;i_run++){ cfunc->CFUNC_l1D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D)); cfunc->dCFUNC_l1D[i_run]=(double *)SID_malloc(sizeof(double)*(cfunc->n_1D)); cfunc->COVMTX_l1D[i_run]=(double *)SID_malloc(sizeof(double)*(cfunc->n_1D*cfunc->n_1D)); cfunc->CFUNC_1D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D)); cfunc->dCFUNC_1D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D)); cfunc->COVMTX_1D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_1D*cfunc->n_1D)); cfunc->CFUNC_2D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_2D)*(cfunc->n_2D)); cfunc->dCFUNC_2D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_2D)*(cfunc->n_2D)); cfunc->COVMTX_2D[i_run] =(double *)SID_malloc(sizeof(double)*(cfunc->n_2D_total*cfunc->n_2D_total)); } cfunc->DD_l1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->DR_l1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->RR_l1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->DD_1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->DR_1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->RR_1D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->DD_2D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->DR_2D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); cfunc->RR_2D =(long long **)SID_malloc(sizeof(long long *)*(cfunc->n_jack_total+1)); int i_jack; for(i_jack=0;i_jack<=cfunc->n_jack_total;i_jack++){ cfunc->DD_l1D[i_jack]=(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->DR_l1D[i_jack]=(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->RR_l1D[i_jack]=(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->DD_1D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->DR_1D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->RR_1D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_1D); cfunc->DD_2D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_2D*cfunc->n_2D); cfunc->DR_2D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_2D*cfunc->n_2D); cfunc->RR_2D[i_jack] =(long long *)SID_calloc(sizeof(long long)*cfunc->n_2D*cfunc->n_2D); } // Initialize the cosmology if(filename_cosmology==NULL) init_cosmo_default(&(cfunc->cosmo)); else read_gbpCosmo_file(&(cfunc->cosmo),filename_cosmology); SID_log("Done.",SID_LOG_CLOSE); }
void map_to_grid(size_t n_particles_local, GBPREAL * x_particles_local, GBPREAL * y_particles_local, GBPREAL * z_particles_local, GBPREAL * v_particles_local, GBPREAL * w_particles_local, cosmo_info *cosmo, double redshift, int distribution_scheme, double normalization_constant, field_info *field, field_info *field_norm, int mode) { size_t i_p; int i_k; size_t i_b; size_t i_grid; int i_coord; int i_i[3]; int j_i[3]; int k_i[3]; size_t n_particles; double v_p; double w_p; int flag_valued_particles; int flag_weight_particles; int flag_weight; int flag_active; int flag_viable; double k_mag; double dk; int n_powspec; int mode_powspec; size_t * n_mode_powspec; double * k_powspec; double * kmin_powspec; double * kmax_powspec; double * k_powspec_bin; double * P_powspec; double * dP_powspec; double k_min; double k_max; double norm_local; double normalization; GBPREAL x_i; GBPREAL x_particle_i; GBPREAL y_particle_i; GBPREAL z_particle_i; double kernal_offset; int W_search_lo; int W_search_hi; size_t receive_left_size = 0; size_t receive_right_size = 0; size_t index_best; int n_buffer[3]; size_t n_send_left; size_t n_send_right; size_t send_size_left; size_t send_size_right; GBPREAL * send_left = NULL; GBPREAL * send_right = NULL; GBPREAL * receive_left = NULL; GBPREAL * receive_right = NULL; GBPREAL * send_left_norm = NULL; GBPREAL * send_right_norm = NULL; GBPREAL * receive_left_norm = NULL; GBPREAL * receive_right_norm = NULL; double r_i, r_min, r_i_max = 0; double W_i; int index_i; interp_info *P_k_interp; double * r_Daub; double * W_Daub; double h_Hubble; int n_Daub; interp_info *W_r_Daub_interp = NULL; int i_rank; size_t buffer_index; int i_test; double accumulator; // Compute the total poulation size and print a status message calc_sum_global(&n_particles_local, &n_particles, 1, SID_SIZE_T, CALC_MODE_DEFAULT, SID_COMM_WORLD); SID_log("Distributing %zu items onto a %dx%dx%d grid...", SID_LOG_OPEN, n_particles, field->n[0], field->n[1], field->n[2]); // If we've been given a normalization field, make sure it's got the same geometry as the results field if(field_norm != NULL) { if(field->n_d != field_norm->n_d) SID_exit_error("grid dimension counts don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_d, field_norm->n_d); int i_d; for(i_d = 0; i_d < field->n_d; i_d++) { if(field->n[i_d] != field_norm->n[i_d]) SID_exit_error("grid dimension No. %d's sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, i_d, field->n[i_d], field_norm->n[i_d]); if(field->n_R_local[i_d] != field_norm->n_R_local[i_d]) SID_exit_error("grid dimension No. %d's slab sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, i_d, field->n_R_local[i_d], field_norm->n_R_local[i_d]); if(field->i_R_start_local[i_d] != field_norm->i_R_start_local[i_d]) SID_exit_error("grid dimension No. %d's start positions don't match (ie. %le!=%le)", SID_ERROR_LOGIC, i_d, field->i_R_start_local[i_d], field_norm->i_R_start_local[i_d]); if(field->i_R_stop_local[i_d] != field_norm->i_R_stop_local[i_d]) SID_exit_error("grid dimension No. %d's stop positions don't match (ie. %le!=%le)", SID_ERROR_LOGIC, i_d, field->i_R_stop_local[i_d], field_norm->i_R_stop_local[i_d]); } if(field->n_field != field_norm->n_field) SID_exit_error("grid field sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_field, field_norm->n_field); if(field->n_field_R_local != field_norm->n_field_R_local) SID_exit_error("grid local field sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->n_field_R_local, field_norm->n_field_R_local); if(field->total_local_size != field_norm->total_local_size) SID_exit_error("grid total local sizes don't match (ie. %d!=%d)", SID_ERROR_LOGIC, field->total_local_size, field_norm->total_local_size); } // Set some variables if(v_particles_local != NULL) flag_valued_particles = GBP_TRUE; else { flag_valued_particles = GBP_FALSE; v_p = 1.; } if(w_particles_local != NULL) flag_weight_particles = GBP_TRUE; else { flag_weight_particles = GBP_FALSE; w_p = 1.; } h_Hubble = ((double *)ADaPS_fetch(cosmo, "h_Hubble"))[0]; // Initializing the mass assignment scheme switch(distribution_scheme) { case MAP2GRID_DIST_DWT20: W_search_lo = 2; W_search_hi = 7; kernal_offset = 2.5; compute_Daubechies_scaling_fctns(20, 5, &r_Daub, &W_Daub, &n_Daub); init_interpolate(r_Daub, W_Daub, n_Daub, gsl_interp_cspline, &W_r_Daub_interp); SID_free(SID_FARG r_Daub); SID_free(SID_FARG W_Daub); SID_log("(using D20 scale function kernal)...", SID_LOG_CONTINUE); break; case MAP2GRID_DIST_DWT12: W_search_lo = 1; W_search_hi = 6; kernal_offset = 1.75; compute_Daubechies_scaling_fctns(12, 5, &r_Daub, &W_Daub, &n_Daub); init_interpolate(r_Daub, W_Daub, (size_t)n_Daub, gsl_interp_cspline, &W_r_Daub_interp); SID_free(SID_FARG r_Daub); SID_free(SID_FARG W_Daub); SID_log("(using D12 scale function kernal)...", SID_LOG_CONTINUE); break; case MAP2GRID_DIST_TSC: W_search_lo = 2; W_search_hi = 2; SID_log("(using triangular shaped function kernal)...", SID_LOG_CONTINUE); break; case MAP2GRID_DIST_CIC: SID_log("(using cloud-in-cell kernal)...", SID_LOG_CONTINUE); case MAP2GRID_DIST_NGP: default: W_search_lo = 1; W_search_hi = 1; SID_log("(using nearest grid point kernal)...", SID_LOG_CONTINUE); break; } // Initializing slab buffers n_send_left = (size_t)(field->n[0] * field->n[1] * W_search_lo); n_send_right = (size_t)(field->n[0] * field->n[1] * W_search_hi); send_size_left = n_send_left * sizeof(GBPREAL); send_size_right = n_send_right * sizeof(GBPREAL); send_left = (GBPREAL *)SID_calloc(send_size_left); send_right = (GBPREAL *)SID_calloc(send_size_right); receive_left = (GBPREAL *)SID_calloc(send_size_right); receive_right = (GBPREAL *)SID_calloc(send_size_left); if(field_norm != NULL) { send_left_norm = (GBPREAL *)SID_calloc(send_size_left); send_right_norm = (GBPREAL *)SID_calloc(send_size_right); receive_left_norm = (GBPREAL *)SID_calloc(send_size_right); receive_right_norm = (GBPREAL *)SID_calloc(send_size_left); } // Clear the field if(!SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_NOCLEAN)) { SID_log("Clearing fields...", SID_LOG_OPEN); clear_field(field); if(field_norm != NULL) clear_field(field); SID_log("Done.", SID_LOG_CLOSE); } // It is essential that we not pad the field for the simple way that we add-in the boundary buffers below set_FFT_padding_state(field, GBP_FALSE); if(field_norm != NULL) set_FFT_padding_state(field_norm, GBP_FALSE); // Create the mass distribution SID_log("Performing grid assignment...", SID_LOG_OPEN | SID_LOG_TIMER); // Loop over all the objects pcounter_info pcounter; SID_Init_pcounter(&pcounter, n_particles_local, 10); for(i_p = 0, norm_local = 0.; i_p < n_particles_local; i_p++) { double norm_i; double value_i; if(flag_valued_particles) v_p = (double)(v_particles_local[i_p]); if(flag_weight_particles) w_p = (double)(w_particles_local[i_p]); norm_i = w_p; value_i = v_p * norm_i; // Particle's position x_particle_i = (GBPREAL)x_particles_local[i_p]; y_particle_i = (GBPREAL)y_particles_local[i_p]; z_particle_i = (GBPREAL)z_particles_local[i_p]; // Quantize it onto the grid x_particle_i /= (GBPREAL)field->dR[0]; y_particle_i /= (GBPREAL)field->dR[1]; z_particle_i /= (GBPREAL)field->dR[2]; i_i[0] = (int)x_particle_i; // position in grid-coordinates i_i[1] = (int)y_particle_i; // position in grid-coordinates i_i[2] = (int)z_particle_i; // position in grid-coordinates // Apply the kernel flag_viable = GBP_TRUE; double x_i_effective; for(j_i[0] = -W_search_lo; j_i[0] <= W_search_hi; j_i[0]++) { for(j_i[1] = -W_search_lo; j_i[1] <= W_search_hi; j_i[1]++) { for(j_i[2] = -W_search_lo; j_i[2] <= W_search_hi; j_i[2]++) { // Compute distance to each grid point being searched against ... flag_active = GBP_TRUE; for(i_coord = 0, W_i = 1.; i_coord < 3; i_coord++) { switch(i_coord) { case 0: x_i = (GBPREAL)(i_i[0] + j_i[0]) - x_particle_i; break; case 1: x_i = (GBPREAL)(i_i[1] + j_i[1]) - y_particle_i; break; case 2: x_i = (GBPREAL)(i_i[2] + j_i[2]) - z_particle_i; break; } switch(distribution_scheme) { // Distribute with a Daubechies wavelet transform of 12th or 20th order a la Cui et al '08 case MAP2GRID_DIST_DWT12: case MAP2GRID_DIST_DWT20: x_i_effective = x_i + kernal_offset; if(x_i_effective > 0.) W_i *= interpolate(W_r_Daub_interp, x_i_effective); else flag_active = GBP_FALSE; break; // Distribute using the triangular shaped cloud (TSC) method case MAP2GRID_DIST_TSC: if(x_i < 0.5) W_i *= (0.75 - x_i * x_i); else if(x_i < 1.5) W_i *= 0.5 * (1.5 - fabs(x_i)) * (1.5 - fabs(x_i)); else flag_active = GBP_FALSE; break; // Distribute using the cloud-in-cell (CIC) method case MAP2GRID_DIST_CIC: if(fabs(x_i) < 1.) W_i *= (1. - fabs(x_i)); else flag_active = GBP_FALSE; break; // Distribute using "nearest grid point" (NGP; ie. the simplest and default) method case MAP2GRID_DIST_NGP: default: if(fabs(x_i) <= 0.5 && flag_viable) W_i *= 1.; else flag_active = GBP_FALSE; break; } } if(flag_active) { // This flags-out regions of the kernal with no support to save some time // Set the grid indices (enforce periodic BCs; do x-coordinate last) ... // ... y-coordinate ... k_i[1] = (i_i[1] + j_i[1]); if(k_i[1] < 0) k_i[1] += field->n[1]; else k_i[1] = k_i[1] % field->n[1]; // ... z-coordinate ... k_i[2] = i_i[2] + j_i[2]; if(k_i[2] < 0) k_i[2] += field->n[2]; else k_i[2] = k_i[2] % field->n[2]; // ... x-coordinate ... // Depending on x-index, add contribution to the // local array or to the slab buffers. k_i[0] = (i_i[0] + j_i[0]); if(k_i[0] < field->i_R_start_local[0]) { k_i[0] -= (field->i_R_start_local[0] - W_search_lo); if(k_i[0] < 0) SID_exit_error("Left slab buffer limit exceeded by %d element(s).", SID_ERROR_LOGIC, -k_i[0]); send_left[index_FFT_R(field, k_i)] += W_i * value_i; if(field_norm != NULL) send_left_norm[index_FFT_R(field_norm, k_i)] += W_i * norm_i; } else if(k_i[0] > field->i_R_stop_local[0]) { k_i[0] -= (field->i_R_stop_local[0] + 1); if(k_i[0] >= W_search_hi) SID_exit_error("Right slab buffer limit exceeded by %d element(s).", SID_ERROR_LOGIC, k_i[0] - W_search_hi + 1); else { send_right[index_FFT_R(field, k_i)] += W_i * value_i; if(field_norm != NULL) send_right_norm[index_FFT_R(field_norm, k_i)] += W_i * norm_i; } } else { field->field_local[index_local_FFT_R(field, k_i)] += W_i * value_i; if(field_norm != NULL) field_norm->field_local[index_local_FFT_R(field_norm, k_i)] += W_i * norm_i; } flag_viable = GBP_FALSE; } } } } // Report the calculation's progress SID_check_pcounter(&pcounter, i_p); } SID_log("Done.", SID_LOG_CLOSE); // Perform exchange of slab buffers and add them to the local mass distribution. // Note: it's important that the FFT field not be padded (see above, where // this is set) for this to work the way it's done. SID_log("Adding-in the slab buffers...", SID_LOG_OPEN | SID_LOG_TIMER); // Numerator first ... exchange_slab_buffer_left(send_left, send_size_left, receive_right, &receive_right_size, &(field->slab)); exchange_slab_buffer_right(send_right, send_size_right, receive_left, &receive_left_size, &(field->slab)); for(i_b = 0; i_b < n_send_right; i_b++) field->field_local[i_b] += receive_left[i_b]; for(i_b = 0; i_b < n_send_left; i_b++) field->field_local[field->n_field_R_local - n_send_left + i_b] += receive_right[i_b]; // ... then denominator (if it's being used) if(field_norm != NULL) { exchange_slab_buffer_left(send_left_norm, send_size_left, receive_right_norm, &receive_right_size, &(field_norm->slab)); exchange_slab_buffer_right(send_right_norm, send_size_right, receive_left_norm, &receive_left_size, &(field_norm->slab)); for(i_b = 0; i_b < n_send_right; i_b++) field_norm->field_local[i_b] += receive_left_norm[i_b]; for(i_b = 0; i_b < n_send_left; i_b++) field_norm->field_local[field_norm->n_field_R_local - n_send_left + i_b] += receive_right[i_b]; } SID_free(SID_FARG send_left); SID_free(SID_FARG send_right); SID_free(SID_FARG receive_left); SID_free(SID_FARG receive_right); if(field_norm != NULL) { SID_free(SID_FARG send_left_norm); SID_free(SID_FARG send_right_norm); SID_free(SID_FARG receive_left_norm); SID_free(SID_FARG receive_right_norm); } SID_log("Done.", SID_LOG_CLOSE); // Recompute local normalization (more accurate for large sample sizes) if(!SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_NONORM)) { SID_log("Applying normalization...", SID_LOG_OPEN); if(field_norm != NULL) { for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++) { if(field_norm->field_local[i_grid] != 0) field->field_local[i_grid] /= field_norm->field_local[i_grid]; } } if(SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_APPLYFACTOR)) { for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++) field->field_local[i_grid] *= normalization_constant; } if(SID_CHECK_BITFIELD_SWITCH(mode, MAP2GRID_MODE_FORCENORM)) { norm_local = 0; for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++) norm_local += (double)field->field_local[i_grid]; calc_sum_global(&norm_local, &normalization, 1, SID_DOUBLE, CALC_MODE_DEFAULT, SID_COMM_WORLD); double normalization_factor; normalization_factor = normalization_constant / normalization; for(i_grid = 0; i_grid < field->n_field_R_local; i_grid++) field->field_local[i_grid] *= normalization_factor; } SID_log("Done.", SID_LOG_CLOSE, normalization); } if(W_r_Daub_interp != NULL) free_interpolate(SID_FARG W_r_Daub_interp, NULL); SID_log("Done.", SID_LOG_CLOSE); }
void compute_trees_horizontal(char *filename_halo_root_in, char *filename_cat_root_in, char *filename_snap_list_in, char *filename_root_matches, char *filename_output_dir, cosmo_info **cosmo, int i_read_start, int i_read_stop, int i_read_step, int n_search, int flag_fix_bridges, int *flag_clean){ char group_text_prefix[5]; FILE *fp; char *line=NULL; int line_length=0; int n_strays; int n_strays_drop; int n_strays_bridge; int i_stray; int n_match; int n_match_halos; int n_back_match; int i_match; int j_match; int k_match; int n_groups_1; int n_groups_2; int n_groups_3; int i_group; int j_group; int k_group; int l_group; int n_subgroups_1; int n_subgroups_2; int i_subgroup; int j_subgroup; int i_drop; int j_drop; int k_drop; int i_bridge; int j_bridge; int n_lines; int i_file; int j_file; int i_write; int j_write; int l_write; int l_read; int j_file_1; int j_file_2; int i_read; int j_read; int j_read_1; int j_read_2; int n_descendant; int n_progenitor; int descendant_index; int progenitor_index; int my_descendant_index,my_descendant_id,my_descendant_list,my_index; int index; int max_id =0; int max_id_group =0; int max_id_subgroup=0; int *my_descendant; int *n_particles; int *n_particles_groups; int *n_particles_subgroups; int my_trunk; double expansion_factor; int n_found; int n_found_bridge; double delta_r; double delta_M; double R_vir_p; double R_vir_d; int i_find,n_find; int flag_continue; int flag_drop; int *match_id=NULL; int *search_id=NULL; int n_progenitors_max; int i_search; int flag_dropped; int flag_first; int n_particles_max; int trunk_index; int *n_groups=NULL; int *n_subgroups=NULL; int max_tree_id_group; int max_tree_id_subgroup; int max_tree_id; int **n_subgroups_group=NULL; int *n_subgroups_group_1=NULL; size_t **sort_id=NULL; size_t **sort_group_id=NULL; size_t **sort_subgroup_id=NULL; size_t *match_index=NULL; size_t *bridge_index=NULL; size_t *search_index=NULL; float *match_score=NULL; char *match_flag_two_way=NULL; int *bridge_keep=NULL; int flag_match_subgroups; int flag_keep_strays=FALSE; int n_k_match=2; int n_snap; tree_horizontal_info **subgroups; tree_horizontal_info **groups; tree_horizontal_info **halos; tree_horizontal_info *halos_i; match_info **back_matches_groups; match_info **back_matches_subgroups; match_info **back_matches; int n_files; int n_subgroups_max; int n_groups_max; int *n_halos; int n_halos_max; int n_halos_i; int i_halo; int n_halos_1_matches; int n_halos_2_matches; int j_halo; int k_halo; int l_halo; int n_list; int k_file; int l_file; int k_index; int k_file_temp; int k_index_temp; int n_wrap; int i_file_start; char filename_output_dir_horizontal[MAX_FILENAME_LENGTH]; char filename_output_dir_horizontal_cases[MAX_FILENAME_LENGTH]; char filename_output_file_root[MAX_FILENAME_LENGTH]; char filename_matching_out[MAX_FILENAME_LENGTH]; FILE *fp_matching_out; int i_column; SID_log("Constructing horizontal merger trees for snapshots #%d->#%d (step=%d)...",SID_LOG_OPEN|SID_LOG_TIMER,i_read_start,i_read_stop,i_read_step); if(n_search<1) SID_trap_error("n_search=%d but must be at least 1",ERROR_LOGIC,n_search); int flag_compute_fragmented=TRUE; int flag_compute_ghosts =FALSE; if(!flag_fix_bridges) SID_log("Bridge-fixing is turned off.",SID_LOG_COMMENT); if(!flag_compute_fragmented) SID_log("Fragmented-halo propagation is turned off.",SID_LOG_COMMENT); if(!flag_compute_ghosts) SID_log("Ghost-populated tree construction is turned off.",SID_LOG_COMMENT); // Create the output directory mkdir(filename_output_dir,02755); // Create snapshot expansion factor list double *a_list=NULL; int n_a_list_in; write_a_list(filename_snap_list_in, filename_output_dir, i_read_start, i_read_stop, i_read_step); read_a_list(filename_output_dir, &a_list, &n_a_list_in); write_tree_run_parameters(filename_output_dir, i_read_start, i_read_stop, i_read_step, n_search, flag_fix_bridges, flag_compute_fragmented, flag_compute_ghosts); // Validate existing matching files &/or perfrom matching //if(!compute_trees_matches(filename_halo_root_in, // filename_root_matches, // i_read_start, // i_read_stop, // i_read_step, // n_search, // WRITE_MATCHES_MODE_TREES|WRITE_MATCHES_PERFORM_CHECK)) // SID_trap_error("Matching could not be completed. Terminating.",ERROR_LOGIC); read_matches_header(filename_root_matches, i_read_start, i_read_stop, i_read_step, &n_files, &n_subgroups, &n_groups, &n_subgroups_max, &n_groups_max, &n_halos_max); // We need these for allocating arrays calc_max(n_subgroups,&n_subgroups_max,n_files,SID_INT,CALC_MODE_DEFAULT); calc_max(n_groups, &n_groups_max, n_files,SID_INT,CALC_MODE_DEFAULT); n_halos_max=MAX(n_subgroups_max,n_groups_max); // We need enough indices to allow us to hold-on to descendants until outputing // and for the current and last i_file as well n_wrap =2*n_search+2; i_file_start=n_files-1; // Initialize arrays SID_log("Creating arrays...",SID_LOG_OPEN); n_particles_groups =(int *)SID_malloc(sizeof(int) *n_halos_max); n_particles_subgroups =(int *)SID_malloc(sizeof(int) *n_halos_max); match_id =(int *)SID_malloc(sizeof(int) *n_halos_max); match_score =(float *)SID_malloc(sizeof(float) *n_halos_max); match_index =(size_t *)SID_malloc(sizeof(size_t)*n_halos_max); match_flag_two_way =(char *)SID_malloc(sizeof(char) *n_halos_max); subgroups =(tree_horizontal_info **)SID_malloc(sizeof(tree_horizontal_info *)*n_wrap); groups =(tree_horizontal_info **)SID_malloc(sizeof(tree_horizontal_info *)*n_wrap); n_subgroups_group =(int **)SID_malloc(sizeof(int *)*n_wrap); back_matches_subgroups=(match_info **)SID_malloc(sizeof(match_info *) *n_wrap); back_matches_groups =(match_info **)SID_malloc(sizeof(match_info *) *n_wrap); for(i_search=0;i_search<n_wrap;i_search++){ subgroups[i_search] =(tree_horizontal_info *)SID_calloc(sizeof(tree_horizontal_info)*n_subgroups_max); groups[i_search] =(tree_horizontal_info *)SID_calloc(sizeof(tree_horizontal_info)*n_groups_max); n_subgroups_group[i_search] =(int *)SID_calloc(sizeof(int) *n_groups_max); back_matches_subgroups[i_search]=NULL; back_matches_groups[i_search] =NULL; } SID_log("Done.",SID_LOG_CLOSE); // Process the first file separately // (just give everything ids from a running index. Also adds MMS flags.) ... init_trees_horizontal_roots(groups, subgroups, match_id, match_score, match_index, match_flag_two_way, n_particles_groups, n_particles_subgroups, n_subgroups_group, n_groups_max, n_subgroups_max, filename_root_matches, i_read_start, i_read_stop, i_read_step, i_file_start, n_wrap, n_halos_max, &max_id_group, &max_tree_id_group, &max_id_subgroup, &max_tree_id_subgroup); // The first snapshot is done now (set to defaults as the roots of trees) ... now loop over all other snapshots ... // There are a bunch of counters at work here. Because we aren't necessarily using every // snapshot (if i_read_step>1), we need counters to keep track of which snapshots we // are working with (i_read_*,j_read_*, etc), counters to keep track of which // files's we're dealing with as far as the trees indices are concerned (i_file_*,j_file_*,etc), and // counters to keep track of which files are being/have been written (i_write_*,j_write_* etc). // We can't write files right away because previously processed snapshots can be changed // when we deal with dropped and bridged halos. for(i_read =i_read_stop-i_read_step, i_file =i_file_start-1, j_file =1, i_write=i_file_start, j_write=i_read_stop, l_write=0; i_read>=i_read_start; i_read-=i_read_step, i_file--, j_file++){ SID_log("Processing snapshot #%d...",SID_LOG_OPEN|SID_LOG_TIMER,i_read); // Loop twice (1st to process subgroups, 2nd to process groups) for(k_match=0;k_match<n_k_match;k_match++){ // Initialize a bunch of stuff which depends on whether // we are processing groups or subgroups. // Do the groups first, so that we have access to n_subgroups_group, // which we need for setting MOST_MASSIVE flags, etc switch(k_match){ case 0: sprintf(group_text_prefix,""); flag_match_subgroups=MATCH_GROUPS; halos =groups; back_matches =back_matches_groups; n_halos =n_groups; n_halos_max =n_groups_max; max_id =max_id_group; max_tree_id =max_tree_id_group; n_particles =n_particles_groups; break; case 1: sprintf(group_text_prefix,"sub"); flag_match_subgroups=MATCH_SUBGROUPS; halos =subgroups; back_matches =back_matches_subgroups; n_halos =n_subgroups; n_halos_max =n_subgroups_max; max_id =max_id_subgroup; max_tree_id =max_tree_id_subgroup; n_particles =n_particles_subgroups; break; } halos_i =halos[i_file%n_wrap]; n_halos_i=n_halos[j_file]; SID_log("Processing %d %sgroups...",SID_LOG_OPEN|SID_LOG_TIMER,n_halos_i,group_text_prefix); // Initialize tree pointer-arrays with dummy values init_trees_horizontal_snapshot(halos_i, &(back_matches[i_file%n_wrap]), i_read, i_file, n_groups[j_file], n_groups_max, n_subgroups[j_file], n_subgroups_max, flag_match_subgroups); // Identify matches that will be used for progenitor building (and read halo sizes) if(flag_fix_bridges) identify_back_matches(halos, halos_i, &(back_matches[i_file%n_wrap]), n_halos_i, match_id, match_score, match_index, match_flag_two_way, n_particles, i_file, i_read, i_read_start, i_read_stop, i_read_step, n_search, n_wrap, n_halos_max, n_files, filename_root_matches, flag_match_subgroups); // Perform forward-matching identify_progenitors(halos, halos_i, n_subgroups_group, n_halos_i, match_id, match_score, match_index, match_flag_two_way, n_particles, i_file, i_read, i_read_start, i_read_stop, i_read_step, n_search, n_wrap, n_halos_max, n_files, flag_fix_bridges, &max_id, &n_halos_1_matches, &n_halos_2_matches, filename_root_matches, group_text_prefix, flag_match_subgroups); // Add MOST_MASSIVE substructure flags if(flag_match_subgroups==MATCH_SUBGROUPS) add_substructure_info(subgroups[i_file%n_wrap], n_subgroups_group[i_file%n_wrap], n_particles_groups, n_groups[j_file], n_subgroups[j_file], flag_match_subgroups); // Finalize matches to unprocessed halos. In particular, // resolve matches to bridged halos that were not matched // to any emerged candidates. finalize_trees_horizontal(n_halos_1_matches, n_halos_i, halos, halos_i, i_file, n_search, n_wrap, &max_id, &max_tree_id); // Now that we know which halos are main progenitors, we // can set the n_partices_largest_descendant values. set_largest_descendants(halos_i,n_halos_i); // Now that we know which halos are the main progenitors of this // snapshot's bridged halos, we can mark any other back matches // as candidate emerged halos and identify bridges. if(flag_fix_bridges) identify_bridges(halos_i,n_halos_i,n_search); // Report some statistics // n.b.: This is only an estimate in some cases, since subsequent snapshots may alter this snapshot. // See the final written log.txt file for accurate numbers. write_trees_horizontal_report(n_halos_i,n_halos_max,halos_i); // Update the max_id variables switch(flag_match_subgroups){ case MATCH_SUBGROUPS: max_id_subgroup=max_id; max_tree_id_subgroup=max_tree_id; break; case MATCH_GROUPS: max_id_group =max_id; max_tree_id_group=max_tree_id; break; } SID_log("Done.",SID_LOG_CLOSE); } // k_match // Write trees once a few files have been processed // and no more dropped groups etc. need to be given ids if(j_file>n_search){ int mode_write; if(flag_compute_ghosts || flag_compute_fragmented) mode_write=TREE_HORIZONTAL_WRITE_EXTENDED|TREE_HORIZONTAL_WRITE_ALLCASES|TREE_HORIZONTAL_WRITE_CHECK_FRAGMENTED; else mode_write=TREE_HORIZONTAL_WRITE_ALLCASES|TREE_HORIZONTAL_WRITE_CHECK_FRAGMENTED; write_trees_horizontal((void **)groups, (void **)subgroups, n_groups[l_write], n_groups_max, n_subgroups[l_write],n_subgroups_max, n_subgroups_group, max_tree_id_subgroup, max_tree_id_group, i_write, j_write, l_write, i_read_step, n_search, n_wrap, i_file_start, filename_cat_root_in, filename_output_dir, a_list, cosmo, n_k_match, l_write==0, mode_write); i_write--; l_write++; j_write-=i_read_step; } SID_log("Done.",SID_LOG_CLOSE); } // loop over snaps // Write the remaining snapshots for(;j_write>=i_read_start;i_write--,j_write-=i_read_step,l_write++){ int mode_write; if(flag_compute_ghosts || flag_compute_fragmented) mode_write=TREE_HORIZONTAL_WRITE_EXTENDED|TREE_HORIZONTAL_WRITE_ALLCASES|TREE_HORIZONTAL_WRITE_CHECK_FRAGMENTED; else mode_write=TREE_HORIZONTAL_WRITE_ALLCASES|TREE_HORIZONTAL_WRITE_CHECK_FRAGMENTED; write_trees_horizontal((void **)groups, (void **)subgroups, n_groups[l_write], n_groups_max, n_subgroups[l_write],n_subgroups_max, n_subgroups_group, max_tree_id_subgroup, max_tree_id_group, i_write, j_write, l_write, i_read_step, n_search, n_wrap, i_file_start, filename_cat_root_in, filename_output_dir, a_list, cosmo, n_k_match, l_write==0, mode_write); } int i_write_last; int l_write_last; int j_write_last; i_write_last=i_write+1; j_write_last=j_write+i_read_step; l_write_last=l_write-1; // Clean-up SID_log("Freeing arrays...",SID_LOG_OPEN); for(i_search=0;i_search<n_wrap;i_search++){ // Free subgroup information SID_free(SID_FARG subgroups[i_search]); SID_free(SID_FARG back_matches_subgroups[i_search]); // Free group information SID_free(SID_FARG groups[i_search]); SID_free(SID_FARG back_matches_groups[i_search]); } SID_free(SID_FARG subgroups); SID_free(SID_FARG groups); SID_free(SID_FARG back_matches_subgroups); SID_free(SID_FARG back_matches_groups); SID_free(SID_FARG match_id); SID_free(SID_FARG match_score); SID_free(SID_FARG match_index); SID_free(SID_FARG match_flag_two_way); SID_free(SID_FARG n_particles_groups); SID_free(SID_FARG n_particles_subgroups); SID_log("Done.",SID_LOG_CLOSE); // Any information that needs to be communicated up the trees from the // roots will be done here. This includes any information needed // for tracking mergers and fragmented halos. // Because fragmented halos might persist longer than the search interval, we have to // walk the trees forward in time to propagate the TREE_CASE_FRAGMENTED_* flags. // At this point, fragmented halos are only labeled when they appear. // This will propagate the fragmented halo flags forward in time. propagate_progenitor_info(n_groups, n_subgroups, n_subgroups_group, i_file_start, i_write_last, j_write_last, l_write_last, i_read_stop, i_read_step, max_tree_id_subgroup, max_tree_id_group, n_subgroups_max, n_groups_max, n_search, n_files, n_wrap, n_k_match, a_list, cosmo, filename_output_dir, flag_compute_fragmented); // If extended horizontal tree files were written for fragmented // halo propagation or ghost tree construction, remove them. if(flag_compute_ghosts || flag_compute_fragmented){ SID_log("Removing temporary tree files...",SID_LOG_OPEN); for(j_write=i_read_stop;j_write>=i_read_start;j_write-=i_read_step){ char filename_output_dir_horizontal[MAX_FILENAME_LENGTH]; char filename_output_dir_horizontal_trees[MAX_FILENAME_LENGTH]; char filename_remove[MAX_FILENAME_LENGTH]; sprintf(filename_output_dir_horizontal, "%s/horizontal",filename_output_dir); sprintf(filename_output_dir_horizontal_trees,"%s/trees", filename_output_dir_horizontal); sprintf(filename_remove,"%s/horizontal_trees_tmp_%03d.dat",filename_output_dir_horizontal_trees,j_write); remove(filename_remove); } SID_log("Done.",SID_LOG_CLOSE); } // Some final clean-up SID_log("Cleaning up...",SID_LOG_OPEN); SID_free(SID_FARG n_groups); SID_free(SID_FARG n_subgroups); for(i_search=0;i_search<n_wrap;i_search++) SID_free(SID_FARG n_subgroups_group[i_search]); SID_free(SID_FARG n_subgroups_group); SID_free(SID_FARG a_list); SID_log("Done.",SID_LOG_CLOSE); // Force the forest construction to use all snapshots int n_search_forests=i_read_stop; // Construct tree->forest mappings compute_forests(filename_output_dir,n_search_forests); SID_log("Done.",SID_LOG_CLOSE); }
void average_tree_branches(const char *catalog_name){ SID_log("Processing tree tracks in catalog {%s}...",SID_LOG_OPEN,catalog_name); // Master Rank does all the work FILE *fp_tracks_in=NULL; if(SID.I_am_Master){ // Create and open the output files char filename_tracks_in[MAX_FILENAME_LENGTH]; sprintf(filename_tracks_in,"%s_tracks.dat",catalog_name); SID_log("Processing {%s}...",SID_LOG_OPEN,filename_tracks_in); fp_tracks_in=fopen(filename_tracks_in,"r"); // Write header for tracks file int n_list; int n_snaps; fread_verify(&n_list, sizeof(int),1,fp_tracks_in); fread_verify(&n_snaps,sizeof(int),1,fp_tracks_in); int *snap_list=(int *)SID_malloc(sizeof(int) *n_snaps); double *z_list =(double *)SID_malloc(sizeof(double)*n_snaps); double *t_list =(double *)SID_malloc(sizeof(double)*n_snaps); fread_verify(snap_list,sizeof(int), n_snaps,fp_tracks_in); fread_verify(z_list, sizeof(double),n_snaps,fp_tracks_in); fread_verify(t_list, sizeof(double),n_snaps,fp_tracks_in); // Allocate some temporary arrays for the tracks double M_min = 6.; double M_max =16.; int n_M_bins=200; double dM =(M_max-M_min)/(double)n_M_bins; double inv_dM =1./dM; int **M_hist =(int **)SID_malloc(sizeof(int *)*n_snaps); for(int i_snap=0;i_snap<n_snaps;i_snap++) M_hist[i_snap]=(int *)SID_calloc(sizeof(int)*n_M_bins); int *i_z_track=(int *)SID_malloc(sizeof(int)*n_snaps);; int *idx_track=(int *)SID_malloc(sizeof(int)*n_snaps);; double *M_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *x_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *y_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *z_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *vx_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *vy_track =(double *)SID_malloc(sizeof(double)*n_snaps); double *vz_track =(double *)SID_malloc(sizeof(double)*n_snaps); // Process each track in turn for(int i_list=0;i_list<n_list;i_list++){ int n_track; // Read track fread_verify(&n_track, sizeof(int), 1, fp_tracks_in); fread_verify(i_z_track,sizeof(int), n_track,fp_tracks_in); fread_verify(idx_track,sizeof(int), n_track,fp_tracks_in); fread_verify(x_track, sizeof(double),n_track,fp_tracks_in); fread_verify(y_track, sizeof(double),n_track,fp_tracks_in); fread_verify(z_track, sizeof(double),n_track,fp_tracks_in); fread_verify(vx_track, sizeof(double),n_track,fp_tracks_in); fread_verify(vy_track, sizeof(double),n_track,fp_tracks_in); fread_verify(vz_track, sizeof(double),n_track,fp_tracks_in); fread_verify(M_track, sizeof(double),n_track,fp_tracks_in); // Build the M-histograms for(int i_track=0;i_track<n_track;i_track++){ int i_bin=(int)((take_log10(M_track[i_track])-M_min)*inv_dM); if(i_bin>=0 && i_bin<n_M_bins) M_hist[i_z_track[i_track]][i_bin]++; } } // for i_list fclose(fp_tracks_in); // Build confidence intervals for M-track int *n_i =(int *)SID_calloc(sizeof(int)*n_snaps); double *M_peak =(double *)SID_calloc(sizeof(double)*n_snaps); double *M_68_lo=(double *)SID_calloc(sizeof(double)*n_snaps); double *M_68_hi=(double *)SID_calloc(sizeof(double)*n_snaps); for(int i_snap=0;i_snap<n_snaps;i_snap++){ size_t *M_hist_index=NULL; for(int i_bin=0;i_bin<n_M_bins;i_bin++) n_i[i_snap]+=M_hist[i_snap][i_bin]; if(n_i[i_snap]>0){ merge_sort(M_hist[i_snap],(size_t)n_M_bins,&M_hist_index,SID_INT,SORT_COMPUTE_INDEX,FALSE); int i_peak =M_hist_index[n_M_bins-1]; int i_68_lo=M_hist_index[n_M_bins-1]; int i_68_hi=M_hist_index[n_M_bins-1]; int target =(int)(0.68*(double)n_i[i_snap]); int accum =0; int i_bin =0; while(accum<=target && i_bin<n_M_bins){ size_t idx_i=M_hist_index[n_M_bins-i_bin-1]; if(idx_i<i_68_lo) i_68_lo=idx_i; if(idx_i>i_68_hi) i_68_hi=idx_i; accum+=M_hist[i_snap][idx_i]; i_bin++; } M_peak[i_snap] =M_min+((double)i_peak +0.5)*dM; M_68_lo[i_snap]=M_min+((double)i_68_lo+0.5)*dM; M_68_hi[i_snap]=M_min+((double)i_68_hi+0.5)*dM; SID_free(SID_FARG M_hist_index); } else{ M_peak[i_snap] =-1; M_68_lo[i_snap]=-1; M_68_hi[i_snap]=-1; } } // Write results char filename_out[MAX_FILENAME_LENGTH]; FILE *fp_out; sprintf(filename_out,"%s_tracks.txt",catalog_name); fp_out=fopen(filename_out,"w"); for(int i_snap=0;i_snap<n_snaps;i_snap++) fprintf(fp_out,"%le %le %d %le %le %le\n", z_list[i_snap], t_list[i_snap]/S_PER_YEAR, n_i[i_snap], M_peak[i_snap], M_68_lo[i_snap], M_68_hi[i_snap]); fclose(fp_out); // Clean-up for(int i_snap=0;i_snap<n_snaps;i_snap++) SID_free(SID_FARG M_hist[i_snap]); SID_free(SID_FARG M_hist); SID_free(SID_FARG n_i); SID_free(SID_FARG M_peak); SID_free(SID_FARG M_68_lo); SID_free(SID_FARG M_68_hi); SID_free(SID_FARG i_z_track); SID_free(SID_FARG idx_track); SID_free(SID_FARG M_track); SID_free(SID_FARG x_track); SID_free(SID_FARG y_track); SID_free(SID_FARG z_track); SID_free(SID_FARG vx_track); SID_free(SID_FARG vy_track); SID_free(SID_FARG vz_track); SID_free(SID_FARG snap_list); SID_free(SID_FARG z_list); SID_free(SID_FARG t_list); SID_log("Done.",SID_LOG_CLOSE); } // if I_am_Master SID_Barrier(SID.COMM_WORLD); SID_log("Done.",SID_LOG_CLOSE); }
void compute_treenode_list_marker_stats(tree_info *trees,treenode_list_info *list,tree_markers_info **markers_all,tree_markers_stats_info *stats,int **n_hist_count,int *n_hist){ int n_stats=3; int n_M =2; (*n_hist) =n_stats+n_M; // Allocate histogram arrays -- stats int i_hist=0; int **hist =(int **)SID_calloc(sizeof(int *)*(*n_hist)); int *n_bins=(int *)SID_calloc(sizeof(int)*(*n_hist)); for(int i_stat=0;i_stat<n_stats;i_stat++){ n_bins[i_hist]=trees->n_snaps; hist[i_hist++]=(int *)SID_calloc(sizeof(int)*n_bins[i_hist]); } // Allocate histogram arrays -- mass double logM_min=7.; int n_M_bins=90; double dlogM =0.1; for(int i_M=0;i_M<n_M;i_M++){ n_bins[i_hist]=n_M_bins; hist[i_hist++]=(int *)SID_calloc(sizeof(int)*n_bins[i_hist]); } // Allocate histogram counts if((*n_hist_count)==NULL) (*n_hist_count)=(int *)SID_calloc(sizeof(int)*(*n_hist)); else{ for(i_hist=0;i_hist<(*n_hist);i_hist++) (*n_hist_count)[i_hist]=0; } // Work with a precompiled markers array if it's been given tree_markers_info *markers; if(markers_all==NULL) markers=(tree_markers_info *)SID_malloc(sizeof(tree_markers_info)); // Create histograms for(int i_list=0;i_list<list->n_list_local;i_list++){ markers=fetch_treenode_precomputed_markers(trees,list->list[i_list]); // Build histogram int i_bin; for(int i_hist=0;i_hist<(*n_hist);i_hist++){ i_bin=-1; if(i_hist<n_stats){ tree_node_info *marker=NULL; if(i_hist==0) marker=markers->half_peak_mass; else if(i_hist==1) marker=markers->merger_33pc_remnant; else if(i_hist==2) marker=markers->merger_10pc_remnant; else SID_trap_error("Behaviour undefined in compute_treenode_list_marker_stats()",ERROR_LOGIC); if(marker!=NULL) i_bin=marker->snap_tree; else i_bin=-1; } else{ if(i_hist==(n_stats+0)){ halo_properties_info *properties=fetch_treenode_properties(trees,list->list[i_list]); i_bin=(take_log10(properties->M_vir)-logM_min)/dlogM; } else if(i_hist==(n_stats+1)) i_bin=(take_log10(markers->M_peak)-logM_min)/dlogM; else SID_trap_error("Behaviour undefined in compute_treenode_list_marker_stats()",ERROR_LOGIC); } if(i_bin>=0 && i_bin<n_bins[i_hist]){ hist[i_hist][i_bin]++; (*n_hist_count)[i_hist]++; } } } if(markers_all==NULL) SID_free(SID_FARG markers); for(int i_hist=0;i_hist<(*n_hist);i_hist++){ SID_Allreduce(SID_IN_PLACE,hist[i_hist],n_bins[i_hist],SID_INT,SID_SUM,SID.COMM_WORLD); SID_Allreduce(SID_IN_PLACE,&((*n_hist_count)[i_hist]),1,SID_INT,SID_SUM,SID.COMM_WORLD); } // Find 68 and 95 percent confidence ranges for(int i_hist=0;i_hist<(*n_hist);i_hist++){ int sum=0; for(int i_bin=0;i_bin<n_bins[i_hist];i_bin++) sum+=hist[i_hist][i_bin]; size_t *hist_index=NULL; merge_sort(hist[i_hist],(size_t)(n_bins[i_hist]),&hist_index,SID_INT,SORT_COMPUTE_INDEX,FALSE); int i_peak =hist_index[n_bins[i_hist]-1]; int i_68_lo=hist_index[n_bins[i_hist]-1]; int i_68_hi=hist_index[n_bins[i_hist]-1]; int target =(int)(0.68*(double)sum); int accum =0; int i_bin =0; while(accum<=target && i_bin<n_bins[i_hist]){ size_t idx_i=hist_index[n_bins[i_hist]-i_bin-1]; if(idx_i<i_68_lo) i_68_lo=idx_i; if(idx_i>i_68_hi) i_68_hi=idx_i; accum+=hist[i_hist][idx_i]; i_bin++; } int i_95_lo=i_68_lo; int i_95_hi=i_68_hi; target=(int)(0.95*(double)sum); while(accum<=target && i_bin<n_bins[i_hist]){ size_t idx_i=hist_index[n_bins[i_hist]-i_bin-1]; if(idx_i<i_95_lo) i_95_lo=idx_i; if(idx_i>i_95_hi) i_95_hi=idx_i; accum+=hist[i_hist][idx_i]; i_bin++; } SID_free(SID_FARG hist_index); if(i_hist==0){ stats->t_half_peak_mass_ranges[0][0]=trees->t_list[i_68_lo]; stats->t_half_peak_mass_ranges[0][1]=trees->t_list[i_68_hi]; stats->t_half_peak_mass_ranges[1][0]=trees->t_list[i_95_lo]; stats->t_half_peak_mass_ranges[1][1]=trees->t_list[i_95_hi]; stats->t_half_peak_mass_peak =trees->t_list[i_peak]; } else if(i_hist==1){ stats->t_merger_33pc_ranges[0][0]=trees->t_list[i_68_lo]; stats->t_merger_33pc_ranges[0][1]=trees->t_list[i_68_hi]; stats->t_merger_33pc_ranges[1][0]=trees->t_list[i_95_lo]; stats->t_merger_33pc_ranges[1][1]=trees->t_list[i_95_hi]; stats->t_merger_33pc_peak =trees->t_list[i_peak]; } else if(i_hist==2){ stats->t_merger_10pc_ranges[0][0]=trees->t_list[i_68_lo]; stats->t_merger_10pc_ranges[0][1]=trees->t_list[i_68_hi]; stats->t_merger_10pc_ranges[1][0]=trees->t_list[i_95_lo]; stats->t_merger_10pc_ranges[1][1]=trees->t_list[i_95_hi]; stats->t_merger_10pc_peak =trees->t_list[i_peak]; } else if(i_hist==3){ stats->M_peak_ranges[0][0]=logM_min+(double)(i_68_lo)*dlogM; stats->M_peak_ranges[0][1]=logM_min+(double)(i_68_hi)*dlogM; stats->M_peak_ranges[1][0]=logM_min+(double)(i_95_lo)*dlogM; stats->M_peak_ranges[1][1]=logM_min+(double)(i_95_hi)*dlogM; stats->M_peak_peak =logM_min+(double)( i_peak)*dlogM; } else if(i_hist==4){ stats->M_vir_ranges[0][0]=logM_min+(double)(i_68_lo)*dlogM; stats->M_vir_ranges[0][1]=logM_min+(double)(i_68_hi)*dlogM; stats->M_vir_ranges[1][0]=logM_min+(double)(i_95_lo)*dlogM; stats->M_vir_ranges[1][1]=logM_min+(double)(i_95_hi)*dlogM; stats->M_vir_peak =logM_min+(double)( i_peak)*dlogM; } else SID_trap_error("Behaviour undefined in compute_treenode_list_marker_stats()",ERROR_LOGIC); } // Clean-up for(int i_hist=0;i_hist<(*n_hist);i_hist++) SID_free(SID_FARG hist[i_hist]); SID_free(SID_FARG hist); SID_free(SID_FARG n_bins); }
int main(int argc, char *argv[]){ double redshift; char filename_in[MAX_FILENAME_LENGTH]; char filename_out[MAX_FILENAME_LENGTH]; char filename_cosmology[MAX_FILENAME_LENGTH]; double box_size; double lM_min,dlM; char *line=NULL; size_t line_length=0; int M_column; int n_bins; int flag_log; // Initialization -- MPI etc. SID_init(&argc,&argv,NULL,NULL); if(argc!=11) SID_trap_error("Incorrect syntax.",ERROR_SYNTAX); // Parse arguments strcpy(filename_in, argv[1]); strcpy(filename_out,argv[2]); redshift=(double)atof(argv[3]); strcpy(filename_cosmology,argv[4]); box_size=(double)atof(argv[5]); M_column=(int) atoi(argv[6]); flag_log=(int) atoi(argv[7]); lM_min =(double)atof(argv[8]); dlM =(double)atof(argv[9]); n_bins =(int) atoi(argv[10]); SID_log("Producing a mass function for ascii file {%s}...",SID_LOG_OPEN|SID_LOG_TIMER,filename_in); // Initialize cosmology cosmo_info *cosmo; read_gbpCosmo_file(&cosmo,filename_cosmology); double h_Hubble=((double *)ADaPS_fetch(cosmo,"h_Hubble"))[0]; // Open file FILE *fp_in; if((fp_in=fopen(filename_in,"r"))==NULL) SID_trap_error("Could not open {%s} for reading.",ERROR_IO_OPEN,filename_in); // Allocate memory for the data. Read it and sort it in ascending order SID_log("Reading data...",SID_LOG_OPEN|SID_LOG_TIMER); int n_data_in=count_lines_data(fp_in); SID_log("(%d items)...",SID_LOG_CONTINUE,n_data_in); double *data =(double *)malloc(sizeof(double)*n_data_in); int n_data=0; for(int i=0;i<n_data_in;i++){ double data_in; grab_next_line_data(fp_in,&line,&line_length); grab_double(line,M_column,&data_in); if(!flag_log) data_in=take_log10(data_in); if(data_in>=lM_min) data[n_data++]=data_in; } SID_log("(%d will be used)...",SID_LOG_CONTINUE,n_data); fclose(fp_in); SID_free(SID_FARG line); SID_log("Done.",SID_LOG_CLOSE); // Perform sort SID_log("Sorting data...",SID_LOG_OPEN|SID_LOG_TIMER); merge_sort(data,n_data,NULL,SID_DOUBLE,SORT_INPLACE_ONLY,SORT_COMPUTE_INPLACE); SID_log("Done.",SID_LOG_CLOSE); // Compile histogram SID_log("Computing mass function...",SID_LOG_OPEN|SID_LOG_TIMER); double *bin =(double *)SID_malloc(sizeof(double)*(n_bins+1)); double *bin_median=(double *)SID_malloc(sizeof(double)*n_bins); int *hist =(int *)SID_calloc(sizeof(int) *n_bins); double lM_bin_min=lM_min; double lM_bin_max=lM_min; int i_data_lo=-1; int i_data_hi=-1; int i_bin =0; int i_data=0; for(i_bin=0;i_bin<n_bins;i_bin++){ lM_bin_min=lM_bin_max; lM_bin_max=lM_min+((double)(i_bin+1))*dlM; bin[i_bin]=lM_bin_min; i_data_lo=i_data; i_data_hi=i_data; while(data[i_data]<lM_bin_max && i_data<n_data){ hist[i_bin]++; i_data_hi=i_data; i_data++; if(i_data>=n_data) break; } int i_data_mid=(i_data_lo+i_data_hi)/2; if(hist[i_bin]>0){ if(hist[i_bin]%2) bin_median[i_bin]=data[i_data_mid]; else bin_median[i_bin]=0.5*(data[i_data_mid]+data[i_data_mid+1]); } else bin_median[i_bin]=0.5*(lM_bin_max+lM_bin_min); } bin[i_bin]=lM_bin_max; SID_log("Done.",SID_LOG_CLOSE); // Write mass function FILE *fp_out; if((fp_out=fopen(filename_out,"w"))==NULL){ fprintf(stderr,"Error opening output file {%s}.\n",filename_out); SID_free(SID_FARG data); return(1); } SID_log("Writing results to {%s}...",SID_LOG_OPEN|SID_LOG_TIMER,filename_out); double box_volume=box_size*box_size*box_size; fprintf(fp_out,"# Mass function for column %d in {%s}\n",M_column,filename_in); fprintf(fp_out,"# Column (01): M_lo [source units]\n"); fprintf(fp_out,"# (02): M_median [source units]\n"); fprintf(fp_out,"# (03): M_hi [source units]\n"); fprintf(fp_out,"# (04): No. in bin\n"); fprintf(fp_out,"# (05): MFn (per unit volume, per dlogM)\n"); fprintf(fp_out,"# (06): +/- MFn\n"); fprintf(fp_out,"# (07): Sheth & Tormen MFn\n"); fprintf(fp_out,"# (08): Watson MFn\n"); fprintf(fp_out,"# (09): No. w/ M>M_lo\n"); fprintf(fp_out,"# (10): Cumulative MFn (per unit volume)\n"); fprintf(fp_out,"# (11): +/- Cumulative MFn\n"); fprintf(fp_out,"# (12): Sheth & Tormen Cumulative MFn\n"); fprintf(fp_out,"# (13): Watson Cumulative MFn\n"); double M_sol_inv_h=M_SOL/h_Hubble; double Mpc_inv_h =M_PER_MPC/h_Hubble; for(int i=0;i<n_bins;i++){ double dn_dlogM_theory_1=mass_function(take_alog10(bin_median[i])*M_sol_inv_h, redshift, &cosmo, MF_ST)*pow(Mpc_inv_h,3.0); double n_theory_1=mass_function_cumulative(take_alog10(bin[i])*M_sol_inv_h, redshift, &cosmo, MF_ST)*pow(Mpc_inv_h,3.0); double dn_dlogM_theory_2=mass_function(take_alog10(bin_median[i])*M_sol_inv_h, redshift, &cosmo, MF_WATSON)*pow(Mpc_inv_h,3.0); double n_theory_2=mass_function_cumulative(take_alog10(bin[i])*M_sol_inv_h, redshift, &cosmo, MF_WATSON)*pow(Mpc_inv_h,3.0); // Compute cumulative histogram int cumulative_hist=0; for(int j_bin=i;j_bin<n_bins;j_bin++) cumulative_hist+=hist[j_bin]; fprintf(fp_out,"%11.4le %11.4le %11.4le %6d %11.4le %11.4le %10.4le %10.4le %6d %10.4le %10.4le %10.4le %10.4le\n", bin[i], bin_median[i], bin[i+1], hist[i], (double)(hist[i])/(box_volume*dlM), sqrt((double)(hist[i]))/(box_volume*dlM), dn_dlogM_theory_1,dn_dlogM_theory_2, cumulative_hist, (double)(cumulative_hist)/box_volume, sqrt((double)(cumulative_hist))/box_volume, n_theory_1,n_theory_2); } fclose(fp_out); SID_log("Done.",SID_LOG_CLOSE); // Free allocated memory SID_free(SID_FARG data); SID_free(SID_FARG bin); SID_free(SID_FARG bin_median); SID_free(SID_FARG hist); SID_log("Done.",SID_LOG_CLOSE); SID_exit(ERROR_NONE); }
int main(int argc, char *argv[]){ int n_species; int n_load; int n_used; int flag_used[N_GADGET_TYPE]; char species_name[256]; double h_Hubble; double n_spec; double redshift; int i_species; char n_string[64]; int n[3]; double L[3]; FILE *fp_1D; FILE *fp_2D; cosmo_info *cosmo; field_info *field[N_GADGET_TYPE]; field_info *field_norm[N_GADGET_TYPE]; plist_info plist_header; plist_info plist; FILE *fp; int i_temp; int n_temp; double *k_temp; double *kmin_temp; double *kmax_temp; double *P_temp; size_t *n_mode_temp; double *sigma_P_temp; double *shot_noise_temp; double *dP_temp; int snapshot_number; int i_compute; int distribution_scheme; double k_min_1D; double k_max_1D; double k_min_2D; double k_max_2D; int n_k_1D; int n_k_2D; double *k_1D; double *P_k_1D; double *dP_k_1D; int *n_modes_1D; double *P_k_2D; double *dP_k_2D; int *n_modes_2D; int n_groups=1; double dk_1D; double dk_2D; char *grid_identifier; // Initialization -- MPI etc. SID_init(&argc,&argv,NULL,NULL); // Parse arguments int grid_size; char filename_in_root[MAX_FILENAME_LENGTH]; char filename_out_root[MAX_FILENAME_LENGTH]; strcpy(filename_in_root, argv[1]); snapshot_number=(int)atoi(argv[2]); strcpy(filename_out_root, argv[3]); grid_size =(int)atoi(argv[4]); if(!strcmp(argv[5],"ngp") || !strcmp(argv[5],"NGP")) distribution_scheme=MAP2GRID_DIST_NGP; else if(!strcmp(argv[5],"cic") || !strcmp(argv[5],"CIC")) distribution_scheme=MAP2GRID_DIST_CIC; else if(!strcmp(argv[5],"tsc") || !strcmp(argv[5],"TSC")) distribution_scheme=MAP2GRID_DIST_TSC; else if(!strcmp(argv[5],"d12") || !strcmp(argv[5],"D12")) distribution_scheme=MAP2GRID_DIST_DWT12; else if(!strcmp(argv[5],"d20") || !strcmp(argv[5],"D20")) distribution_scheme=MAP2GRID_DIST_DWT20; else SID_trap_error("Invalid distribution scheme {%s} specified.",ERROR_SYNTAX,argv[5]); SID_log("Smoothing Gadget file {%s;snapshot=#%d} to a %dx%dx%d grid with %s kernel...",SID_LOG_OPEN|SID_LOG_TIMER, filename_in_root,snapshot_number,grid_size,grid_size,grid_size,argv[5]); // Initialization -- fetch header info SID_log("Reading Gadget header...",SID_LOG_OPEN); gadget_read_info fp_gadget; int flag_filefound=init_gadget_read(filename_in_root,snapshot_number,&fp_gadget); int flag_multifile=fp_gadget.flag_multifile; int flag_file_type=fp_gadget.flag_file_type; gadget_header_info header =fp_gadget.header; double box_size =(double)(header.box_size); size_t *n_all =(size_t *)SID_calloc(sizeof(size_t)*N_GADGET_TYPE); size_t n_total; if(flag_filefound){ if(SID.I_am_Master){ FILE *fp_in; char filename[MAX_FILENAME_LENGTH]; int block_length_open; int block_length_close; set_gadget_filename(&fp_gadget,0,filename); fp_in=fopen(filename,"r"); fread_verify(&block_length_open, sizeof(int),1,fp_in); fread_verify(&header, sizeof(gadget_header_info),1,fp_in); fread_verify(&block_length_close,sizeof(int),1,fp_in); fclose(fp_in); if(block_length_open!=block_length_close) SID_trap_error("Block lengths don't match (ie. %d!=%d).",ERROR_LOGIC,block_length_open,block_length_close); } SID_Bcast(&header,sizeof(gadget_header_info),MASTER_RANK,SID.COMM_WORLD); redshift=header.redshift; h_Hubble=header.h_Hubble; box_size=header.box_size; if(SID.n_proc>1) n_load=1; else n_load=header.n_files; for(i_species=0,n_total=0,n_used=0;i_species<N_GADGET_TYPE;i_species++){ n_all[i_species]=(size_t)header.n_all_lo_word[i_species]+((size_t)header.n_all_hi_word[i_species])<<32; n_total+=n_all[i_species]; if(n_all[i_species]>0){ n_used++; flag_used[i_species]=TRUE; } else flag_used[i_species]=FALSE; } // Initialize cosmology double box_size =((double *)ADaPS_fetch(plist.data,"box_size"))[0]; double h_Hubble =((double *)ADaPS_fetch(plist.data,"h_Hubble"))[0]; double redshift =((double *)ADaPS_fetch(plist.data,"redshift"))[0]; double expansion_factor=((double *)ADaPS_fetch(plist.data,"expansion_factor"))[0]; double Omega_M =((double *)ADaPS_fetch(plist.data,"Omega_M"))[0]; double Omega_Lambda =((double *)ADaPS_fetch(plist.data,"Omega_Lambda"))[0]; double Omega_k =1.-Omega_Lambda-Omega_M; double Omega_b=0.; // not needed, so doesn't matter double f_gas =Omega_b/Omega_M; double sigma_8=0.; // not needed, so doesn't matter double n_spec =0.; // not needed, so doesn't matter char cosmo_name[16]; sprintf(cosmo_name,"Gadget file's"); init_cosmo(&cosmo, cosmo_name, Omega_Lambda, Omega_M, Omega_k, Omega_b, f_gas, h_Hubble, sigma_8, n_spec); } SID_log("Done.",SID_LOG_CLOSE); grid_identifier=(char *)SID_calloc(GRID_IDENTIFIER_SIZE*sizeof(char)); // Only process if there are >0 particles present if(n_used>0){ // Loop over ithe real-space and 3 redshift-space frames int i_write; int i_run; int n_run; int n_grids_total; n_grids_total=4; // For now, hard-wire real-space density and velocity grids only n_run=1; // For now, hard-wire real-space calculation only for(i_run=0,i_write=0;i_run<n_run;i_run++){ // Read catalog int n_grid; char i_run_identifier[8]; switch(i_run){ case 0: SID_log("Processing real-space ...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_run_identifier,"r"); n_grid=4; break; case 1: SID_log("Processing v_x redshift space...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_run_identifier,"x"); n_grid=1; break; case 2: SID_log("Processing v_y redshift space...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_run_identifier,"y"); n_grid=1; break; case 3: SID_log("Processing v_z redsift space...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_run_identifier,"z"); n_grid=1; break; } // For each i_run case, loop over the fields we want to produce int i_grid; for(i_grid=0;i_grid<n_grid;i_grid++){ char i_grid_identifier[8]; switch(i_grid){ case 0: SID_log("Processing density grid ...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_grid_identifier,"rho"); break; case 1: SID_log("Processing v_x velocity grid...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_grid_identifier,"v_x"); break; case 2: SID_log("Processing v_y velocity grid...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_grid_identifier,"v_y"); break; case 3: SID_log("Processing v_z velocity grid...",SID_LOG_OPEN|SID_LOG_TIMER); sprintf(i_grid_identifier,"v_z"); break; } // Initialize the field that will hold the grid int n[]={grid_size,grid_size,grid_size}; double L[]={box_size, box_size, box_size}; int i_init; for(i_species=0;i_species<N_GADGET_TYPE;i_species++){ if(flag_used[i_species]){ field[i_species] =(field_info *)SID_malloc(sizeof(field_info)); field_norm[i_species]=(field_info *)SID_malloc(sizeof(field_info)); init_field(3,n,L,field[i_species]); init_field(3,n,L,field_norm[i_species]); i_init=i_species; } else{ field[i_species] =NULL; field_norm[i_species]=NULL; } } // Loop over all the files that this rank will read int i_load; for(i_load=0;i_load<n_load;i_load++){ if(n_load>1) SID_log("Processing file No. %d of %d...",SID_LOG_OPEN|SID_LOG_TIMER,i_load+1,n_load); // Initialization -- read gadget file GBPREAL mass_array[N_GADGET_TYPE]; init_plist(&plist,&((field[i_init])->slab),GADGET_LENGTH,GADGET_MASS,GADGET_VELOCITY); char filename_root[MAX_FILENAME_LENGTH]; read_gadget_binary_local(filename_in_root, snapshot_number, i_run, i_load, n_load, mass_array, &(field[i_init]->slab), cosmo, &plist); // Generate power spectra for(i_species=0;i_species<plist.n_species;i_species++){ // Determine how many particles of species i_species there are if(n_all[i_species]>0){ // Fetch the needed information size_t n_particles; size_t n_particles_local; int flag_alloc_m; GBPREAL *x_particles_local; GBPREAL *y_particles_local; GBPREAL *z_particles_local; GBPREAL *vx_particles_local; GBPREAL *vy_particles_local; GBPREAL *vz_particles_local; GBPREAL *m_particles_local; GBPREAL *v_particles_local; GBPREAL *w_particles_local; n_particles =((size_t *)ADaPS_fetch(plist.data,"n_all_%s",plist.species[i_species]))[0]; n_particles_local=((size_t *)ADaPS_fetch(plist.data,"n_%s", plist.species[i_species]))[0]; x_particles_local= (GBPREAL *)ADaPS_fetch(plist.data,"x_%s", plist.species[i_species]); y_particles_local= (GBPREAL *)ADaPS_fetch(plist.data,"y_%s", plist.species[i_species]); z_particles_local= (GBPREAL *)ADaPS_fetch(plist.data,"z_%s", plist.species[i_species]); vx_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"vx_%s", plist.species[i_species]); vy_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"vy_%s", plist.species[i_species]); vz_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"vz_%s", plist.species[i_species]); if(ADaPS_exist(plist.data,"M_%s",plist.species[i_species])){ flag_alloc_m=FALSE; m_particles_local=(GBPREAL *)ADaPS_fetch(plist.data,"M_%s",plist.species[i_species]); } else{ flag_alloc_m=TRUE; m_particles_local=(GBPREAL *)SID_malloc(n_particles_local*sizeof(GBPREAL)); int i_particle; for(i_particle=0;i_particle<n_particles_local;i_particle++) m_particles_local[i_particle]=mass_array[i_species]; } // Decide the map_to_grid() mode int mode; if(n_load==1) mode=MAP2GRID_MODE_DEFAULT; else if(i_load==0 || n_load==1) mode=MAP2GRID_MODE_DEFAULT|MAP2GRID_MODE_NONORM; else if(i_load==(n_load-1)) mode=MAP2GRID_MODE_NOCLEAN; else mode=MAP2GRID_MODE_NOCLEAN|MAP2GRID_MODE_NONORM; // Set the array that will weight the grid field_info *field_i; field_info *field_norm_i; double factor; switch(i_grid){ case 0: v_particles_local=m_particles_local; w_particles_local=NULL; field_i =field[i_species]; field_norm_i =NULL; mode|=MAP2GRID_MODE_APPLYFACTOR; factor=pow((double)grid_size/box_size,3.); break; case 1: v_particles_local=vx_particles_local; w_particles_local=m_particles_local; field_i =field[i_species]; field_norm_i =field_norm[i_species]; factor=1.; break; case 2: v_particles_local=vy_particles_local; w_particles_local=m_particles_local; field_i =field[i_species]; field_norm_i =field_norm[i_species]; factor=1.; break; case 3: v_particles_local=vz_particles_local; w_particles_local=m_particles_local; field_i =field[i_species]; field_norm_i =field_norm[i_species]; factor=1.; break; } // Generate grid map_to_grid(n_particles_local, x_particles_local, y_particles_local, z_particles_local, v_particles_local, w_particles_local, cosmo, redshift, distribution_scheme, factor, field_i, field_norm_i, mode); if(flag_alloc_m) SID_free(SID_FARG m_particles_local); } } // Clean-up free_plist(&plist); if(n_load>1) SID_log("Done.",SID_LOG_CLOSE); } // loop over i_load // Write results to disk char filename_out_species[MAX_FILENAME_LENGTH]; init_plist(&plist,NULL,GADGET_LENGTH,GADGET_MASS,GADGET_VELOCITY); for(i_species=0;i_species<plist.n_species;i_species++){ if(flag_used[i_species]){ sprintf(grid_identifier,"%s_%s_%s",i_grid_identifier,i_run_identifier,plist.species[i_species]); sprintf(filename_out_species,"%s_%s",filename_out_root,plist.species[i_species]); write_grid(field[i_species], filename_out_species, i_write, n_grids_total, distribution_scheme, grid_identifier, header.box_size); free_field(field[i_species]); free_field(field_norm[i_species]); SID_free(SID_FARG field[i_species]); SID_free(SID_FARG field_norm[i_species]); i_write++; } } // Clean-up free_plist(&plist); SID_log("Done.",SID_LOG_CLOSE); } // loop over i_grid SID_log("Done.",SID_LOG_CLOSE); } // loop over i_run } // if n_used>0 // Clean-up free_cosmo(&cosmo); SID_free(SID_FARG grid_identifier); SID_free(SID_FARG n_all); SID_log("Done.",SID_LOG_CLOSE); SID_exit(ERROR_NONE); }
void read_smooth(plist_info *plist, char *filename_root_in, int snapshot_number, int mode){ char filename[256]; size_t n_particles_all_mem; size_t n_particles_local; size_t n_particles_total; int i_quantity; int n_quantities=3; int *used; char *species_name; char var_name[256]; char unit_name[256]; double unit_factor; int i_file; size_t *ids; size_t *ids_index; int n_particles_file; int offset; int n_files; void *id_buf; size_t *id_buf_index=NULL; int *id_buf_i; long long *id_buf_L; long long *mark; size_t i_particle; size_t j_particle; void *buffer; float *local_array; int n_mark; float *r_smooth_array; float *rho_array; float *sigma_v_array; char *read_array; double expansion_factor; double h_Hubble; int flag_filefound=FALSE; int flag_multifile=FALSE; int flag_file_type; int flag_LONGIDs; int read_rank=MASTER_RANK; int flag_log_sigma=FALSE; int flag_log_rho=FALSE; FILE *fp; SID_log("Reading smooth file {%s}...",SID_LOG_OPEN|SID_LOG_TIMER,filename_root_in); // Read header info SID_log("Reading header information...",SID_LOG_OPEN); smooth_header_info header; flag_filefound =init_smooth_read(filename_root_in,snapshot_number,&flag_multifile,&flag_file_type,&header); SID_log("n_files =%d", SID_LOG_COMMENT,header.n_files); SID_log("n_particles=%lld",SID_LOG_COMMENT,header.n_particles_total); SID_log("Done.",SID_LOG_CLOSE); // Interpret the mode passed to this function int flag_logs_used =FALSE; int flag_log_quantity=FALSE; if(check_mode_for_flag(mode,READ_SMOOTH_LOG_SIGMA)){ flag_log_sigma=TRUE; flag_logs_used=TRUE; } else flag_log_sigma=FALSE; if(check_mode_for_flag(mode,READ_SMOOTH_LOG_RHO)){ flag_log_rho =TRUE; flag_logs_used=TRUE; } else flag_log_rho=FALSE; // A file was found ... if(flag_filefound){ // Communicate the header n_particles_file =header.n_particles_file; offset =header.offset; n_particles_total=header.n_particles_total; n_files =MAX(1,header.n_files); SID_Bcast(&n_particles_file, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&offset, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD); SID_Bcast(&n_files, (int)sizeof(int), read_rank,SID.COMM_WORLD); // Fetch the number of particles and their ids species_name =plist->species[GADGET_TYPE_DARK]; n_particles_local=((size_t *)ADaPS_fetch(plist->data,"n_%s", species_name))[0]; n_particles_all_mem =((size_t *)ADaPS_fetch(plist->data,"n_all_%s",species_name))[0]; ids = (size_t *)ADaPS_fetch(plist->data,"id_%s", species_name); expansion_factor =((double *)ADaPS_fetch(plist->data,"expansion_factor"))[0]; h_Hubble =((double *)ADaPS_fetch(plist->data,"h_Hubble"))[0]; // Check if we are dealing with LONG IDs or not if(ADaPS_exist(plist->data,"flag_LONGIDs")) flag_LONGIDs=TRUE; else flag_LONGIDs=FALSE; // Sort particle IDs SID_log("Sorting particle IDs...",SID_LOG_OPEN|SID_LOG_TIMER); merge_sort(ids,(size_t)n_particles_local,&ids_index,SID_SIZE_T,SORT_COMPUTE_INDEX,FALSE); SID_log("Done.",SID_LOG_CLOSE); // Allocate arrays SID_log("Allocating arrays...",SID_LOG_OPEN); read_array=(char *)SID_calloc(sizeof(char)*n_particles_local); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ switch(i_quantity){ case 0: r_smooth_array=(float *)SID_malloc(sizeof(float)*n_particles_local); ADaPS_store(&(plist->data),r_smooth_array,"r_smooth_%s",ADaPS_DEFAULT,species_name); break; case 1: rho_array=(float *)SID_malloc(sizeof(float)*n_particles_local); ADaPS_store(&(plist->data),rho_array,"rho_%s",ADaPS_DEFAULT,species_name); break; case 2: sigma_v_array=(float *)SID_malloc(sizeof(float)*n_particles_local); ADaPS_store(&(plist->data),sigma_v_array,"sigma_v_%s",ADaPS_DEFAULT,species_name); break; } } SID_log("Done.",SID_LOG_CLOSE); // Read each file in turn pcounter_info pcounter; size_t n_particles_read=0; SID_log("Performing read...",SID_LOG_OPEN|SID_LOG_TIMER); SID_init_pcounter(&pcounter,n_particles_total,10); for(i_file=0;i_file<n_files;i_file++){ set_smooth_filename(filename_root_in,snapshot_number,i_file,flag_multifile,flag_file_type,filename); if((fp=fopen(filename,"r"))!=NULL){ fread_verify(&(header.n_particles_file), sizeof(int), 1,fp); fread_verify(&(header.offset), sizeof(int), 1,fp); fread_verify(&(header.n_particles_total),sizeof(long long),1,fp); fread_verify(&(header.n_files), sizeof(int), 1,fp); } else SID_trap_error("Could not open smooth file {%s}",ERROR_IO_OPEN,filename); n_particles_file =header.n_particles_file; offset =header.offset; n_particles_total=header.n_particles_total; n_files =MAX(1,header.n_files); SID_Bcast(&n_particles_file, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&offset, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD); SID_Bcast(&n_files, (int)sizeof(int), read_rank,SID.COMM_WORLD); // Read IDs if(flag_LONGIDs){ if(i_file==0) SID_log("(long long) IDs...",SID_LOG_CONTINUE); id_buf =SID_malloc(sizeof(long long)*n_particles_file); id_buf_L=(long long *)id_buf; if(SID.My_rank==read_rank){ fseeko(fp,(size_t)(3*n_particles_file*sizeof(float)),SEEK_CUR); fread_verify(id_buf,sizeof(long long),n_particles_file,fp); } SID_Barrier(SID.COMM_WORLD); SID_Bcast(id_buf_L,(int)(n_particles_file*sizeof(long long)),read_rank,SID.COMM_WORLD); merge_sort(id_buf_L,(size_t)n_particles_file,&id_buf_index,SID_SIZE_T,SORT_COMPUTE_INDEX,FALSE); } else{ if(i_file==0) SID_log("(int) IDs...",SID_LOG_CONTINUE); id_buf =SID_malloc(sizeof(int)*n_particles_file); id_buf_i=(int *)id_buf; if(SID.My_rank==read_rank){ fseeko(fp,(size_t)(3*n_particles_file*sizeof(float)),SEEK_CUR); fread_verify(id_buf,sizeof(int),n_particles_file,fp); } SID_Barrier(SID.COMM_WORLD); SID_Bcast(id_buf_i,(int)(n_particles_file*sizeof(int)),read_rank,SID.COMM_WORLD); merge_sort(id_buf_i,(size_t)n_particles_file,&id_buf_index,SID_INT,SORT_COMPUTE_INDEX,FALSE); } // Create local particle mapping int n_mark_i=0; mark=(long long *)SID_malloc(sizeof(long long)*n_particles_file); for(i_particle=0;i_particle<n_particles_file;i_particle++) mark[i_particle]=-1; if(flag_LONGIDs){ for(i_particle=0,j_particle=0,n_mark=0;i_particle<n_particles_file && j_particle<n_particles_local;i_particle++){ while(j_particle<n_particles_local-1 && ids[ids_index[j_particle]]<id_buf_L[id_buf_index[i_particle]]) j_particle++; if(ids[ids_index[j_particle]]==id_buf_L[id_buf_index[i_particle]]){ mark[id_buf_index[i_particle]]=(long long)ids_index[j_particle]; n_mark++; n_mark_i++; } } } else{ for(i_particle=0,j_particle=0,n_mark=0;i_particle<n_particles_file && j_particle<n_particles_local;i_particle++){ while(j_particle<n_particles_local-1 && ids[ids_index[j_particle]]<id_buf_i[id_buf_index[i_particle]]) j_particle++; if(ids[ids_index[j_particle]]==id_buf_i[id_buf_index[i_particle]]){ mark[id_buf_index[i_particle]]=(long long)ids_index[j_particle]; n_mark++; n_mark_i++; } } } SID_free(SID_FARG id_buf); SID_free(SID_FARG id_buf_index); // Move to the start of the particle quantities if(SID.My_rank==read_rank){ rewind(fp); fread_verify(&n_particles_file, sizeof(int), 1,fp); fread_verify(&offset, sizeof(int), 1,fp); fread_verify(&n_particles_total,sizeof(long long),1,fp); fread_verify(&n_files, sizeof(int), 1,fp); n_files=MAX(1,n_files); } SID_Bcast(&n_particles_file, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&offset, (int)sizeof(int), read_rank,SID.COMM_WORLD); SID_Bcast(&n_particles_total,(int)sizeof(long long),read_rank,SID.COMM_WORLD); SID_Bcast(&n_files, (int)sizeof(int), read_rank,SID.COMM_WORLD); buffer=SID_malloc(sizeof(float)*n_particles_file); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ int flag_log_quantity; switch(i_quantity){ case 0: sprintf(var_name,"r_smooth_%s",species_name); sprintf(unit_name,"Mpc"); unit_factor=plist->length_unit/h_Hubble; local_array=r_smooth_array; break; case 1: sprintf(var_name,"rho_%s",species_name); sprintf(unit_name,"Msol/Mpc^3"); unit_factor=h_Hubble*h_Hubble*plist->mass_unit/pow(plist->length_unit,3.); local_array=rho_array; break; case 2: sprintf(var_name,"sigma_v_%s",species_name); sprintf(unit_name,"km/s"); unit_factor=sqrt(expansion_factor)*plist->velocity_unit; local_array=sigma_v_array; break; } // Read next quantity if(SID.My_rank==read_rank) fread_verify(buffer,sizeof(float),n_particles_file,fp); SID_Barrier(SID.COMM_WORLD); SID_Bcast(buffer,(int)(n_particles_file*sizeof(float)),read_rank,SID.COMM_WORLD); // Place in final array if(n_mark_i>0){ if(i_quantity==0){ for(i_particle=0;i_particle<n_particles_file;i_particle++) if(mark[i_particle]>=0) read_array[mark[i_particle]]=TRUE; } for(i_particle=0;i_particle<n_particles_file;i_particle++) if(mark[i_particle]>=0) local_array[mark[i_particle]]=((float *)buffer)[i_particle]*unit_factor; } } SID_free(SID_FARG mark); SID_free(SID_FARG buffer); if(SID.My_rank==read_rank) fclose(fp); n_particles_read+=n_particles_file; if(n_files>1) SID_check_pcounter(&pcounter,n_particles_read); } // i_file SID_free(SID_FARG ids_index); SID_Barrier(SID.COMM_WORLD); SID_log("Done.",SID_LOG_CLOSE); // Check that all particles have been treated size_t sum_check=0; for(i_particle=0;i_particle<n_particles_local;i_particle++) sum_check+=(size_t)read_array[i_particle]; SID_Allreduce(SID_IN_PLACE,&sum_check,1,SID_SIZE_T,SID_SUM,SID.COMM_WORLD); if(sum_check!=n_particles_all_mem) SID_trap_error("Only %lld of %lld particles were set.",ERROR_LOGIC,sum_check,n_particles_all_mem); SID_free(SID_FARG read_array); SID_log("Summary...",SID_LOG_OPEN); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ char var_name[32]; switch(i_quantity){ case 0: sprintf(var_name,"Lengths: "); sprintf(unit_name,"Mpc"); unit_factor=1./M_PER_MPC; local_array=r_smooth_array; break; case 1: sprintf(var_name,"Densities: "); sprintf(unit_name,"Msol/Mpc^3"); unit_factor=M_PER_MPC*M_PER_MPC*M_PER_MPC/M_SOL; local_array=rho_array; break; case 2: sprintf(var_name,"sigmas_v's:"); sprintf(unit_name,"km/s"); unit_factor=1e-3; local_array=sigma_v_array; break; } // Report some stats float var_min,var_max,var_mean; calc_min_global(local_array, &var_min, n_particles_local, SID_FLOAT, CALC_MODE_DEFAULT, SID.COMM_WORLD); calc_max_global(local_array, &var_max, n_particles_local, SID_FLOAT, CALC_MODE_DEFAULT, SID.COMM_WORLD); calc_mean_global(local_array, &var_mean, n_particles_local, SID_FLOAT, CALC_MODE_DEFAULT, SID.COMM_WORLD); // Remove NaN's from sigma_v's if needed size_t n_NaN=0; for(i_particle=0;i_particle<n_particles_local;i_particle++){ if(isnan(local_array[i_particle])){ local_array[i_particle]=1000.*0.5*(var_min+var_max); n_NaN++; } } if(n_NaN>0) SID_log("%s min=%e max=%e mean=%e [%s] (%lld are NaN)", SID_LOG_COMMENT, var_name, var_min*unit_factor, var_max*unit_factor, var_mean*unit_factor, unit_name, n_NaN); else SID_log("%s min=%e max=%e mean=%e [%s]", SID_LOG_COMMENT, var_name, var_min*unit_factor, var_max*unit_factor, var_mean*unit_factor, unit_name); } SID_log("",SID_LOG_CLOSE|SID_LOG_NOPRINT); if(flag_logs_used){ SID_log("Taking needed logs of quantities...",SID_LOG_OPEN|SID_LOG_TIMER); for(i_quantity=0;i_quantity<n_quantities;i_quantity++){ switch(i_quantity){ case 0: unit_factor=1./M_PER_MPC; local_array=r_smooth_array; flag_log_quantity=FALSE; break; case 1: unit_factor=M_PER_MPC*M_PER_MPC*M_PER_MPC/M_SOL; local_array=rho_array; flag_log_quantity=flag_log_rho; break; case 2: unit_factor=1e-3; local_array=sigma_v_array; flag_log_quantity=flag_log_sigma; break; } if(flag_log_quantity){ for(i_particle=0;i_particle<n_particles_local;i_particle++) local_array[i_particle]=take_log10(local_array[i_particle]); } } SID_log("Done.",SID_LOG_CLOSE); } SID_Barrier(SID.COMM_WORLD); SID_log("Done.",SID_LOG_CLOSE); } else SID_trap_error("Could not find file with root {%s}",ERROR_IO_OPEN,filename_root_in); }
void analyze_halos_and_N_subhalos(tree_info *trees, const char *filename_out_root, const char *catalog_root, double z_select_exact, double M_cut_lo, double M_cut_hi, int n_subgroups_track_max){ // Compute merger rates ... SID_log("Constructing catalogs...",SID_LOG_OPEN|SID_LOG_TIMER); // Fetch halo properties halo_properties_info **group_properties =(halo_properties_info **)ADaPS_fetch(trees->data,"properties_groups"); halo_properties_info **subgroup_properties=(halo_properties_info **)ADaPS_fetch(trees->data,"properties_subgroups"); // Determine the best z_select snapshot int i_z_select=find_treesnap_z(trees,z_select_exact); int i_z_0 =trees->n_snaps-1; double z_select =trees->z_list[i_z_select]; double t_select =trees->t_list[i_z_select]; SID_log("The snapshot corresponding best to z=%4.2f is #%03d (z=%4.2f).",SID_LOG_COMMENT,z_select_exact,trees->snap_list[i_z_select],z_select); // Allocate the list arrays tree_node_info **list_groups =(tree_node_info **)SID_malloc(sizeof(tree_node_info *)*trees->n_groups_snap_local[i_z_select]); tree_node_info **list_subgroups_all=(tree_node_info **)SID_malloc(sizeof(tree_node_info *)*trees->n_groups_snap_local[i_z_select]); tree_node_info ***list_subgroups =(tree_node_info ***)SID_malloc(sizeof(tree_node_info **)*n_subgroups_track_max); for(int i_track=0;i_track<n_subgroups_track_max;i_track++) list_subgroups[i_track]=(tree_node_info **)SID_malloc(sizeof(tree_node_info *)*trees->n_groups_snap_local[i_z_select]); // Select z_select systems tree_node_info *current_group; int n_list_groups =0; int n_list_subgroups_all=0; int *n_list_subgroups =(int *)SID_calloc(sizeof(int)*n_subgroups_track_max); SID_log("Selecting z=%4.2f systems...",SID_LOG_OPEN,trees->z_list[i_z_select]); current_group=trees->first_neighbour_groups[i_z_select]; while(current_group!=NULL){ halo_properties_info *current_group_properties=&(group_properties[current_group->snap_tree][current_group->neighbour_index]); if(current_group_properties->M_vir>=M_cut_lo && current_group_properties->M_vir<=M_cut_hi){ list_groups[n_list_groups++]=current_group; tree_node_info *current_subgroup=current_group->substructure_first; int i_subgroup =0; int i_subgroups_track=0; while(current_subgroup!=NULL && i_subgroups_track<n_subgroups_track_max){ if(!check_treenode_if_fragmented(current_subgroup)){ if(i_subgroup>0) list_subgroups_all[n_list_subgroups_all++]=current_subgroup; list_subgroups[i_subgroups_track][n_list_subgroups[i_subgroups_track]++]=current_subgroup; i_subgroups_track++; } i_subgroup++; current_subgroup=current_subgroup->substructure_next; } } current_group=current_group->next_neighbour; } SID_log("%d groups found...",SID_LOG_CONTINUE,n_list_groups); SID_log("Done.",SID_LOG_CLOSE); // Write properties and tracks for selected z_select groups and subgroups char catalog_name[32]; sprintf(catalog_name,"%s_groups",catalog_root); write_tree_branches(trees,list_groups,n_list_groups,TRUE,filename_out_root,catalog_name); average_tree_branches(catalog_name); for(int i_track=0;i_track<n_subgroups_track_max;i_track++){ if(i_track==0){ sprintf(catalog_name,"%s_subgroups_all",catalog_root); write_tree_branches(trees,list_subgroups_all,n_list_subgroups_all,FALSE,filename_out_root,catalog_name); average_tree_branches(catalog_name); } sprintf(catalog_name,"%s_subgroups_%02d",catalog_root,i_track); write_tree_branches(trees,list_subgroups[i_track],n_list_subgroups[i_track],FALSE,filename_out_root,catalog_name); average_tree_branches(catalog_name); } // Clean-up SID_free(SID_FARG n_list_subgroups); for(int i_track=0;i_track<n_subgroups_track_max;i_track++) SID_free(SID_FARG list_subgroups[i_track]); SID_free(SID_FARG list_subgroups); SID_free(SID_FARG list_subgroups_all); SID_free(SID_FARG list_groups); SID_log("Done.",SID_LOG_CLOSE); }