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); }
int main(int argc, char *argv[]) { SID_Init(&argc, &argv, NULL); // Parse command line select_gadget_ids_params_info params; int snapshot; int halo_index; int halo_type; int n_files_out; int select_mode; char filename_SSimPL_root[SID_MAX_FILENAME_LENGTH]; char filename_halo_version[SID_MAX_FILENAME_LENGTH]; char filename_in_root[SID_MAX_FILENAME_LENGTH]; char filename_out_root[SID_MAX_FILENAME_LENGTH]; GBPREAL cen_select[3]; GBPREAL select_size; strcpy(filename_SSimPL_root, argv[1]); strcpy(filename_halo_version, argv[2]); snapshot = atoi(argv[3]); halo_index = atoi(argv[4]); halo_type = atoi(argv[5]); strcpy(filename_out_root, argv[6]); n_files_out = atoi(argv[7]); SID_log("Writing halo particles to ascii file {%s;snapshot=%d;halo_index=%d}...", SID_LOG_OPEN | SID_LOG_TIMER, filename_SSimPL_root, snapshot, halo_index); // Initialize the plist data structure plist_info plist; params.plist = &plist; init_plist(&plist, NULL, GADGET_LENGTH, GADGET_MASS, GADGET_VELOCITY); // Read the halo ID list. Generate sort indicies and copy the // list to a duplicate array. Make sure this is the one added // to params. Pass this to write_gadget_ascii below, so that // the particles get written in the same order that they are // in the halo catalog. char filename_halos[SID_MAX_FILENAME_LENGTH]; if(halo_type == 0) sprintf(filename_halos, "%s/halos/%s_%03d.catalog_groups", filename_SSimPL_root, filename_halo_version, snapshot); else sprintf(filename_halos, "%s/halos/%s_%03d.catalog_subgroups", filename_SSimPL_root, filename_halo_version, snapshot); FILE * fp_groups = fopen(filename_halos, "r"); int n_groups; int offset_size; int halo_length; size_t halo_offset; SID_fread_verify(&n_groups, sizeof(int), 1, fp_groups); SID_fread_verify(&offset_size, sizeof(int), 1, fp_groups); fseeko(fp_groups, (off_t)(2 * sizeof(int) + halo_index * sizeof(int)), SEEK_SET); SID_fread_verify(&halo_length, sizeof(int), 1, fp_groups); fseeko(fp_groups, (off_t)(2 * sizeof(int) + n_groups * sizeof(int) + halo_index * offset_size), SEEK_SET); if(offset_size == sizeof(int)) { int halo_offset_i; SID_fread_verify(&halo_offset_i, offset_size, 1, fp_groups); halo_offset = (size_t)halo_offset_i; } else SID_fread_verify(&halo_offset, offset_size, 1, fp_groups); fclose(fp_groups); char filename_ids[SID_MAX_FILENAME_LENGTH]; sprintf(filename_ids, "%s/halos/%s_%03d.catalog_particles", filename_SSimPL_root, filename_halo_version, snapshot); FILE * fp_ids = fopen(filename_ids, "r"); int id_byte_size; size_t n_ids; SID_fread_verify(&id_byte_size, sizeof(int), 1, fp_ids); SID_log("%d %d-byte IDs to be read (offset=%d)", SID_LOG_COMMENT, halo_length, id_byte_size, halo_offset); if(id_byte_size == sizeof(int)) { int n_ids_i; SID_fread_verify(&n_ids_i, sizeof(int), 1, fp_ids); n_ids = (size_t)n_ids_i; } else SID_fread_verify(&n_ids, sizeof(size_t), 1, fp_ids); fseeko(fp_ids, (off_t)(sizeof(int) + id_byte_size + halo_offset * id_byte_size), SEEK_SET); params.n_ids = halo_length; params.id_list = (size_t *)SID_malloc(sizeof(size_t) * halo_length); size_t *id_list_unsorted = (size_t *)SID_malloc(sizeof(size_t) * halo_length); int flag_long_ids = GBP_TRUE; if(id_byte_size == sizeof(int)) { flag_long_ids = GBP_FALSE; int *id_list_i = (int *)SID_malloc(sizeof(int) * halo_length); SID_fread_verify(id_list_i, id_byte_size, halo_length, fp_ids); for(int i_p = 0; i_p < halo_length; i_p++) id_list_unsorted[i_p] = (size_t)id_list_i[i_p]; SID_free(SID_FARG id_list_i); } else SID_fread_verify(id_list_unsorted, id_byte_size, halo_length, fp_ids); fclose(fp_ids); memcpy(params.id_list, id_list_unsorted, sizeof(size_t) * halo_length); merge_sort(params.id_list, halo_length, NULL, SID_SIZE_T, SORT_INPLACE_ONLY, SORT_COMPUTE_INPLACE); // Count the particles size_t n_particles_type_local[N_GADGET_TYPE]; size_t n_particles_type[N_GADGET_TYPE]; int flag_long_IDs; sprintf(filename_in_root, "%s/snapshots/snapshot", filename_SSimPL_root); process_gadget_file("Counting particles in selection...", filename_in_root, snapshot, select_gadget_all, process_gadget_file_fctn_null, ¶ms, n_particles_type_local, n_particles_type, &flag_long_IDs, PROCESS_GADGET_BINARY_DEFAULT); // Allocate RAM for the particles allocate_gadget_particles(&plist, n_particles_type_local, n_particles_type, flag_long_IDs); // Read the particles process_gadget_file("Performing read...", filename_in_root, snapshot, select_gadget_all, store_gadget_particles, ¶ms, NULL, NULL, &flag_long_IDs, PROCESS_GADGET_BINARY_DEFAULT); // Write the snapshot if(SID.I_am_Master) { char filename_out[SID_MAX_FILENAME_LENGTH]; sprintf(filename_out, "%s_%03d_%08d.ascii", filename_out_root, snapshot, halo_index); FILE *fp = fopen(filename_out, "w"); fprintf(fp, "#Columns:\n"); fprintf(fp, "# 1) Gadget particle type\n"); fprintf(fp, "# 2) x [Mpc/h]\n"); fprintf(fp, "# 3) y [Mpc/h]\n"); fprintf(fp, "# 4) z [Mpc/h]\n"); fprintf(fp, "# 5) v_x [km/s]\n"); fprintf(fp, "# 6) v_y [km/s]\n"); fprintf(fp, "# 7) v_z [km/s]\n"); fprintf(fp, "# 8) id\n"); int i_species = GADGET_TYPE_DARK; size_t n_p = ((size_t *)ADaPS_fetch(plist.data, "n_%s", plist.species[i_species]))[0]; GBPREAL *x = (GBPREAL *)ADaPS_fetch(plist.data, "x_%s", plist.species[i_species]); GBPREAL *y = (GBPREAL *)ADaPS_fetch(plist.data, "y_%s", plist.species[i_species]); GBPREAL *z = (GBPREAL *)ADaPS_fetch(plist.data, "z_%s", plist.species[i_species]); GBPREAL *vx = (GBPREAL *)ADaPS_fetch(plist.data, "vx_%s", plist.species[i_species]); GBPREAL *vy = (GBPREAL *)ADaPS_fetch(plist.data, "vy_%s", plist.species[i_species]); GBPREAL *vz = (GBPREAL *)ADaPS_fetch(plist.data, "vz_%s", plist.species[i_species]); size_t * id = (size_t *)ADaPS_fetch(plist.data, "id_%s", plist.species[i_species]); size_t * id_indices = NULL; SID_log("Sorting IDs...", SID_LOG_OPEN); merge_sort(id, n_p, &id_indices, SID_SIZE_T, SORT_COMPUTE_INDEX, SORT_COMPUTE_NOT_INPLACE); SID_log("Done.", SID_LOG_CLOSE); SID_log("Writing particles...", SID_LOG_OPEN); pcounter_info pcounter; SID_Init_pcounter(&pcounter, halo_length, 10); int n_unfound = 0; for(int i_p = 0; i_p < halo_length; i_p++) { size_t k_p = id_indices[find_index(id, id_list_unsorted[i_p], n_p, id_indices)]; if(id[k_p] != id_list_unsorted[i_p]) n_unfound++; else fprintf(fp, "%1d %11.4e %11.4e %11.4e %11.4e %11.4e %11.4e %7zd\n", i_species, (double)(x[k_p]), (double)(y[k_p]), (double)(z[k_p]), (double)(vx[k_p]), (double)(vy[k_p]), (double)(vz[k_p]), id[k_p]); SID_check_pcounter(&pcounter, i_p); } fclose(fp); if(n_unfound != 0) SID_log("(%d unfound)...", SID_LOG_CONTINUE, n_unfound); SID_log("Done.", SID_LOG_CLOSE); SID_free(SID_FARG id_indices); } // Clean-up SID_free(SID_FARG id_list_unsorted); SID_free(SID_FARG params.id_list); free_plist(&plist); SID_log("Done.", SID_LOG_CLOSE); SID_Finalize(); }
int main(int argc, char *argv[]){ SID_init(&argc,&argv,NULL,NULL); char filename_cosmology[MAX_FILENAME_LENGTH]; char paramterization[MAX_FILENAME_LENGTH]; double log_M_min =atof(argv[1]); double log_M_max =atof(argv[2]); int n_M_bins =atoi(argv[3]); double redshift =atof(argv[4]); strcpy(filename_cosmology,argv[5]); strcpy(paramterization, argv[6]); SID_log("Constructing mass function between log(M)=%5.3lf->%5.3lf at z=%5.3lf...",SID_LOG_OPEN,log_M_min,log_M_max,redshift); // Initialize cosmology cosmo_info *cosmo=NULL; read_gbpCosmo_file(&cosmo,filename_cosmology); // Decide which parameterization we are going to use int select_flag; char mfn_text[32]; if(!strcmp(paramterization,"JENKINS")){ sprintf(mfn_text,"Jenkins"); select_flag=MF_JENKINS; } else if(!strcmp(paramterization,"PS")){ sprintf(mfn_text,"Press & Schechter"); select_flag=MF_PS; } else if(!strcmp(paramterization,"ST")){ sprintf(mfn_text,"Sheth & Tormen"); select_flag=MF_ST; } else SID_trap_error("Invalid parameterization selected {%s}. Should be {JENKINS,PS or ST}.",ERROR_SYNTAX,paramterization); // Create output filename char filename_out[MAX_FILENAME_LENGTH]; char redshift_text[64]; char *cosmology_name=(char *)ADaPS_fetch(cosmo,"name"); float_to_text(redshift,3,redshift_text); sprintf(filename_out,"mass_function_z%s_%s_%s.txt",redshift_text,cosmology_name,paramterization); // Open file and write header FILE *fp_out=NULL; fp_out=fopen(filename_out,"w"); int i_column=1; fprintf(fp_out,"# Mass function (%s) for %s cosmology at z=%lf\n",mfn_text,filename_cosmology,redshift); fprintf(fp_out,"# \n"); fprintf(fp_out,"# Column (%02d): log M [h^-1 M_sol]\n", i_column++); fprintf(fp_out,"# (%02d): Mass function [(h^{-1} Mpc]^{-3} per dlogM]\n", i_column++); fprintf(fp_out,"# (%02d): Cumulative Mass function(>M) [(h^{-1} Mpc]^{-3}]\n",i_column++); // Create the mass function SID_log("Writing results to {%s}...",SID_LOG_OPEN|SID_LOG_TIMER,filename_out); pcounter_info pcounter; SID_init_pcounter(&pcounter,n_M_bins,10); double h_Hubble =((double *)ADaPS_fetch(cosmo,"h_Hubble"))[0]; double mass_factor=M_SOL/h_Hubble; double MFct_factor=pow(M_PER_MPC,3.0); for(int i_bin=0;i_bin<n_M_bins;i_bin++){ double log_M; if(i_bin==0) log_M=log_M_min; else if(i_bin==(n_M_bins-1)) log_M=log_M_max; else log_M=log_M_min+(((double)(i_bin))/((double)(n_M_bins-1)))*(log_M_max-log_M_min); fprintf(fp_out,"%le %le %le\n",log_M, MFct_factor*mass_function (mass_factor*take_alog10(log_M),redshift,&cosmo,select_flag), MFct_factor*mass_function_cumulative(mass_factor*take_alog10(log_M),redshift,&cosmo,select_flag)); SID_check_pcounter(&pcounter,i_bin); } fclose(fp_out); SID_log("Done.",SID_LOG_CLOSE); // Clean-up free_cosmo(&cosmo); 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); }