double linear_growth_factor(double z, cosmo_info **cosmo) { // Repeat the integral only if we change // redshift from the last call. static double b_z = 1.; static double z_last = -42.; if(z != z_last) { double Dplus_a = Dplus(a_of_z(z), cosmo); double Dplus_1 = Dplus(1., cosmo); b_z = Dplus_a / Dplus_1; z_last = z; } return (b_z); }
double fetch_treenode_x_off(tree_info *trees,tree_node_info *halo){ if(halo!=NULL){ halo_properties_info *properties; if(halo->parent==NULL){ if(trees->group_properties!=NULL) properties=&(trees->group_properties[halo->snap_tree][halo->neighbour_index]); else SID_trap_error("Group properties are not defined. They probably have not been read.",ERROR_LOGIC); } else{ if(trees->subgroup_properties!=NULL) properties=&(trees->subgroup_properties[halo->snap_tree][halo->neighbour_index]); else SID_trap_error("Subgroup properties are not defined. They probably have not been read.",ERROR_LOGIC); } double expansion_factor=a_of_z(trees->z_list[halo->snap_tree]); return(sqrt(pow(properties->position_COM[0]-properties->position_MBP[0],2.)+ pow(properties->position_COM[1]-properties->position_MBP[1],2.)+ pow(properties->position_COM[2]-properties->position_MBP[2],2.))/(properties->R_vir/expansion_factor)); } return(1.); }
double n_dyn_ztoz(double redshift_1, double redshift_2, cosmo_info *cosmo) { double redshift_lo = GBP_MIN(redshift_1, redshift_2); double redshift_hi = GBP_MAX(redshift_1, redshift_2); return (delta_n_dyn_local(a_of_z(redshift_hi), a_of_z(redshift_lo), &cosmo)); }
double dDplus_dz(double z, cosmo_info **cosmo) { double a = a_of_z(z); return (-dDplus_da(a, cosmo) * (a * a)); // = dD/da * da/dz }
void read_gadget_binary_local(char *filename_root_in, int snapshot_number, int i_coord, int i_load, int n_load, GBPREAL mass_array[N_GADGET_TYPE], slab_info *slab, cosmo_info *cosmo, plist_info *plist){ size_t n_of_type_local[N_GADGET_TYPE]; size_t n_of_type[N_GADGET_TYPE]; size_t type_counter[N_GADGET_TYPE]; GBPREAL *x_array[N_GADGET_TYPE]; GBPREAL *y_array[N_GADGET_TYPE]; GBPREAL *z_array[N_GADGET_TYPE]; GBPREAL *vx_array[N_GADGET_TYPE]; GBPREAL *vy_array[N_GADGET_TYPE]; GBPREAL *vz_array[N_GADGET_TYPE]; int i_type; // Determine file format and read the header gadget_read_info fp_gadget; int flag_filefound=init_gadget_read(filename_root_in,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; // A file was found ... if(flag_filefound){ char **pname; SID_log("Reading GADGET binary file...",SID_LOG_OPEN|SID_LOG_TIMER); pname=plist->species; // Expansion factor (or time) ADaPS_store(&(plist->data),(void *)(&(header.time)),"expansion_factor",ADaPS_SCALAR_DOUBLE); ADaPS_store(&(plist->data),(void *)(&(header.time)),"time", ADaPS_SCALAR_DOUBLE); // Redshift double d_value; d_value=(double)header.redshift; ADaPS_store(&(plist->data),(void *)(&d_value),"redshift",ADaPS_SCALAR_DOUBLE); // Number of particles and masses for each species in all files size_t n_all[N_GADGET_TYPE]; for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ n_all[i_type] =(size_t)header.n_all_lo_word[i_type]+((size_t)header.n_all_hi_word[i_type])<<32; mass_array[i_type]=(GBPREAL)header.mass_array[i_type]; } // Number of files in this snapshot int n_files; ADaPS_store(&(plist->data),(void *)(&(header.n_files)),"n_files",ADaPS_SCALAR_INT); n_files=header.n_files; // Cosmology // Omega_o d_value=(double)header.Omega_M; ADaPS_store(&(plist->data),(void *)(&d_value),"Omega_M",ADaPS_SCALAR_DOUBLE); // Omega_Lambda d_value=(double)header.Omega_Lambda; ADaPS_store(&(plist->data),(void *)(&d_value),"Omega_Lambda",ADaPS_SCALAR_DOUBLE); // Hubble parameter double h_Hubble; double redshift; h_Hubble=(double)header.h_Hubble; if(h_Hubble<1e-10) h_Hubble=1.; ADaPS_store(&(plist->data),(void *)(&h_Hubble),"h_Hubble",ADaPS_SCALAR_DOUBLE); redshift=header.redshift; ADaPS_store(&(plist->data),(void *)(&redshift),"redshift",ADaPS_SCALAR_DOUBLE); // Count and report the total number of particles size_t n_particles_all; int n_non_zero; n_particles_all=0; for(i_type=0,n_non_zero=0;i_type<N_GADGET_TYPE;i_type++){ if(n_all[i_type]>0){ n_particles_all+=n_all[i_type]; n_non_zero++; } } SID_log("%zd",SID_LOG_CONTINUE,n_particles_all); if(n_non_zero>0) SID_log(" (",SID_LOG_CONTINUE,n_particles_all); for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ if(n_all[i_type]>0){ if(i_type==n_non_zero-1){ if(n_non_zero>1) SID_log("and %lld %s",SID_LOG_CONTINUE,n_all[i_type],pname[i_type]); else SID_log("%lld %s",SID_LOG_CONTINUE,n_all[i_type],pname[i_type]); } else{ if(n_non_zero>1) SID_log("%lld %s, ",SID_LOG_CONTINUE,n_all[i_type],pname[i_type]); else SID_log("%lld %s",SID_LOG_CONTINUE,n_all[i_type],pname[i_type]); } } } if(n_non_zero>0) SID_log(") particles...",SID_LOG_CONTINUE); else SID_log(" particles...",SID_LOG_CONTINUE); // Count the number of particles that will be scattered to each rank char filename[MAX_FILENAME_LENGTH]; size_t k_particle; int i_file; int record_length_open; int record_length_close; size_t i_particle; size_t i_buffer; size_t i_step; int i_type; size_t index; GBPREAL *pos_buffer; GBPREAL *vel_buffer; double pos_test; // Initialize some arrays pos_buffer=(GBPREAL *)SID_malloc(sizeof(GBPREAL)*READ_BUFFER_ALLOC_LOCAL); vel_buffer=(GBPREAL *)SID_malloc(sizeof(GBPREAL)*READ_BUFFER_ALLOC_LOCAL); for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ n_of_type_local[i_type]=0; n_of_type[i_type] =0; type_counter[i_type] =0; } // Determine how many particles of each type will end-up on each core SID_log("Performing domain decomposition...",SID_LOG_OPEN|SID_LOG_TIMER); int n_read; if(n_load<n_files) n_read=n_files; else n_read=1; for(i_file=i_load;i_file<(i_load+n_read);i_file++){ set_gadget_filename(&fp_gadget,i_file,filename); // Read header and move to the positions FILE *fp_pos; FILE *fp_vel; fp_pos=fopen(filename,"r"); fread_verify(&record_length_open,4,1,fp_pos); fread_verify(&header,sizeof(gadget_header_info),1,fp_pos); fread_verify(&record_length_close,4,1,fp_pos); if(record_length_open!=record_length_close) SID_log_warning("Problem with GADGET record size (close of header)",ERROR_LOGIC); fread_verify(&record_length_open,4,1,fp_pos); // Create a file pointer to the velocities fp_vel=fopen(filename,"r"); fread_verify(&record_length_open,4,1,fp_vel); fseeko(fp_vel,(off_t)(record_length_open),SEEK_CUR); fread_verify(&record_length_close,4,1,fp_vel); fread_verify(&record_length_open,4,1,fp_vel); fseeko(fp_vel,(off_t)(record_length_open),SEEK_CUR); fread_verify(&record_length_close,4,1,fp_vel); if(record_length_open!=record_length_close) SID_log_warning("Problem with GADGET record size (close of positons)",ERROR_LOGIC); fread_verify(&record_length_open,4,1,fp_vel); // We only have to worry about z-space effects for domain decomposition in this one case. if(i_coord==1){ for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ for(i_particle=0;i_particle<header.n_file[i_type];i_particle+=i_step){ i_step=MIN(READ_BUFFER_SIZE_LOCAL,header.n_file[i_type]-i_particle); if(SID.I_am_Master){ fread_verify(pos_buffer,sizeof(GBPREAL),3*i_step,fp_pos); fread_verify(vel_buffer,sizeof(GBPREAL),3*i_step,fp_vel); } SID_Bcast(pos_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); SID_Bcast(vel_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); for(i_buffer=0;i_buffer<i_step;i_buffer++){ index=3*i_buffer; pos_test =(double)(pos_buffer[index]); pos_test+=(double)(1e3*h_Hubble*((double)vel_buffer[index])/(a_of_z(redshift)*M_PER_MPC*H_convert(H_z(redshift,cosmo)))); if(pos_test<0) pos_test+=header.box_size; if(pos_test>=header.box_size) pos_test-=header.box_size; if(pos_test>=slab->x_min_local && pos_test<slab->x_max_local) n_of_type_local[i_type]++; } } } } else{ for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ for(i_particle=0;i_particle<header.n_file[i_type];i_particle+=i_step){ i_step=MIN(READ_BUFFER_SIZE_LOCAL,header.n_file[i_type]-i_particle); if(SID.I_am_Master){ fread_verify(pos_buffer,sizeof(GBPREAL),3*i_step,fp_pos); fread_verify(vel_buffer,sizeof(GBPREAL),3*i_step,fp_vel); } SID_Bcast(pos_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); SID_Bcast(vel_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); for(i_buffer=0;i_buffer<i_step;i_buffer++){ pos_test=pos_buffer[3*i_buffer]; if(pos_test>=slab->x_min_local && pos_test<slab->x_max_local) n_of_type_local[i_type]++; } } i_step=MIN(READ_BUFFER_SIZE_LOCAL,header.n_file[i_type]-i_particle); } } fclose(fp_pos); fclose(fp_vel); } SID_log("Done.",SID_LOG_CLOSE); // Allocate arrays for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ if(n_all[i_type]>0){ x_array[i_type] =(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); y_array[i_type] =(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); z_array[i_type] =(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); vx_array[i_type]=(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); vy_array[i_type]=(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); vz_array[i_type]=(GBPREAL *)SID_malloc(sizeof(GBPREAL)*n_of_type_local[i_type]); } } // Perform read SID_log("Performing read...",SID_LOG_OPEN|SID_LOG_TIMER); for(i_file=i_load;i_file<(i_load+n_read);i_file++){ set_gadget_filename(&fp_gadget,i_file,filename); // Read header and move to the positions FILE *fp_pos; FILE *fp_vel; fp_pos=fopen(filename,"r"); fread_verify(&record_length_open,4,1,fp_pos); fread_verify(&header,sizeof(gadget_header_info),1,fp_pos); fread_verify(&record_length_close,4,1,fp_pos); if(record_length_open!=record_length_close) SID_log_warning("Problem with GADGET record size (close of header)",ERROR_LOGIC); fread_verify(&record_length_open,4,1,fp_pos); // Create a file pointer to the velocities fp_vel=fopen(filename,"r"); fread_verify(&record_length_open,4,1,fp_vel); fseeko(fp_vel,(off_t)(record_length_open),SEEK_CUR); fread_verify(&record_length_close,4,1,fp_vel); fread_verify(&record_length_open,4,1,fp_vel); fseeko(fp_vel,(off_t)(record_length_open),SEEK_CUR); fread_verify(&record_length_close,4,1,fp_vel); if(record_length_open!=record_length_close) SID_log_warning("Problem with GADGET record size (close of positions)",ERROR_LOGIC); fread_verify(&record_length_open,4,1,fp_vel); // Perform the read and populate the local position arrays size_t i_particle; size_t i_step; int i_type; for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ for(i_particle=0;i_particle<header.n_file[i_type];i_particle+=i_step){ i_step=MIN(READ_BUFFER_SIZE_LOCAL,header.n_file[i_type]-i_particle); if(SID.I_am_Master){ fread_verify(pos_buffer,sizeof(GBPREAL),3*i_step,fp_pos); fread_verify(vel_buffer,sizeof(GBPREAL),3*i_step,fp_vel); } SID_Bcast(pos_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); SID_Bcast(vel_buffer,sizeof(GBPREAL)*3*i_step,MASTER_RANK,SID.COMM_WORLD); for(i_buffer=0;i_buffer<i_step;i_buffer++){ double x_test; double y_test; double z_test; double vx_test; double vy_test; double vz_test; index=3*i_buffer; x_test =(double)pos_buffer[index+0]; y_test =(double)pos_buffer[index+1]; z_test =(double)pos_buffer[index+2]; vx_test=(double)vel_buffer[index+0]; vy_test=(double)vel_buffer[index+1]; vz_test=(double)vel_buffer[index+2]; switch(i_coord){ case 1: x_test+=(1e3*h_Hubble*vx_test/(a_of_z(redshift)*M_PER_MPC*H_convert(H_z(redshift,cosmo)))); if(x_test<0) x_test+=header.box_size; if(x_test>=header.box_size) x_test-=header.box_size; break; case 2: y_test+=(1e3*h_Hubble*vy_test/(a_of_z(redshift)*M_PER_MPC*H_convert(H_z(redshift,cosmo)))); if(y_test<0) y_test+=header.box_size; if(y_test>=header.box_size) y_test-=header.box_size; break; case 3: z_test+=(1e3*h_Hubble*vz_test/(a_of_z(redshift)*M_PER_MPC*H_convert(H_z(redshift,cosmo)))); if(z_test<0) z_test+=header.box_size; if(z_test>=header.box_size) z_test-=header.box_size; break; } if(x_test>=slab->x_min_local && x_test<slab->x_max_local){ x_array[i_type][type_counter[i_type]] =x_test; y_array[i_type][type_counter[i_type]] =y_test; z_array[i_type][type_counter[i_type]] =z_test; vx_array[i_type][type_counter[i_type]]=vx_test; vy_array[i_type][type_counter[i_type]]=vy_test; vz_array[i_type][type_counter[i_type]]=vz_test; type_counter[i_type]++; } } } } // Close file pointers fclose(fp_pos); fclose(fp_vel); } SID_free(SID_FARG pos_buffer); SID_free(SID_FARG vel_buffer); SID_log("Done.",SID_LOG_CLOSE); // Sanity checks size_t n_particles_local; size_t n_particles_read; size_t n_particles_test; for(i_type=0,n_particles_local=0,n_particles_test=0;i_type<N_GADGET_TYPE;i_type++){ n_particles_local+=n_of_type_local[i_type]; n_particles_test +=n_all[i_type]; } SID_Allreduce(&n_particles_local,&n_particles_read,1,SID_SIZE_T,SID_SUM,SID.COMM_WORLD); if(n_particles_read!=n_particles_test && n_load==1) SID_trap_error("Total particle counts don't make sense after read_gadget (ie. %zd!=%zd).",ERROR_LOGIC,n_particles_read,n_particles_test); for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ SID_Allreduce(&(n_of_type_local[i_type]),&(n_of_type[i_type]),1,SID_SIZE_T,SID_SUM,SID.COMM_WORLD); if(n_of_type[i_type]!=n_all[i_type] && n_load==1) SID_trap_error("Particle counts don't make sense after read_gadget (ie. %zd!=%zd).",ERROR_LOGIC,n_of_type[i_type],n_all[i_type]); } // Store results for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ if(n_of_type[i_type]>0){ ADaPS_store(&(plist->data),(void *)(&(n_of_type_local[i_type])),"n_%s", ADaPS_SCALAR_SIZE_T,pname[i_type]); ADaPS_store(&(plist->data),(void *)(&(n_of_type[i_type])), "n_all_%s", ADaPS_SCALAR_SIZE_T,pname[i_type]); } } ADaPS_store(&(plist->data),(void *)(&n_particles_all),"n_particles_all",ADaPS_SCALAR_SIZE_T); for(i_type=0;i_type<N_GADGET_TYPE;i_type++){ if(n_of_type_local[i_type]>0){ ADaPS_store(&(plist->data),(void *)x_array[i_type], "x_%s", ADaPS_DEFAULT, pname[i_type]); ADaPS_store(&(plist->data),(void *)y_array[i_type], "y_%s", ADaPS_DEFAULT, pname[i_type]); ADaPS_store(&(plist->data),(void *)z_array[i_type], "z_%s", ADaPS_DEFAULT, pname[i_type]); ADaPS_store(&(plist->data),(void *)vx_array[i_type],"vx_%s",ADaPS_DEFAULT,pname[i_type]); ADaPS_store(&(plist->data),(void *)vy_array[i_type],"vy_%s",ADaPS_DEFAULT,pname[i_type]); ADaPS_store(&(plist->data),(void *)vz_array[i_type],"vz_%s",ADaPS_DEFAULT,pname[i_type]); } } SID_log("Done.",SID_LOG_CLOSE); } }
int main(int argc, char *argv[]) { SID_Init(&argc, &argv, NULL); // Parse arguments and initialize double z; if(argc < 2 || argc > 3) { fprintf(stderr, "\n Syntax: %s z [gbpCosmo_file.txt]\n", argv[0]); fprintf(stderr, " ------\n\n"); return (SID_ERROR_SYNTAX); } else z = (double)atof(argv[1]); SID_log("Computing cosmology information for z=%.2lf...", SID_LOG_OPEN, z); // Initialize cosmology ADaPS *cosmo = NULL; if(argc == 2) init_cosmo_default(&cosmo); else if(argc == 3) read_gbpCosmo_file(&cosmo, argv[2]); // Output results double h_Hubble = ((double *)ADaPS_fetch(cosmo, "h_Hubble"))[0]; SID_log("R_NL(z) = %10.3lf Mpc", SID_LOG_COMMENT, R_NL_z(z, &cosmo) / M_PER_MPC); SID_log("rho_crit = %13.6le Msol/(Mpc^3)", SID_LOG_COMMENT, rho_crit_z(z, cosmo) * (M_PER_MPC / M_SOL) * M_PER_MPC * M_PER_MPC); SID_log("D_angular = %10.3lf Mpc", SID_LOG_COMMENT, D_angular(z, cosmo) / M_PER_MPC); SID_log("D_luminosity = %10.3lf Mpc", SID_LOG_COMMENT, D_luminosity(z, cosmo) / M_PER_MPC); SID_log("D_comoving = %10.3lf Mpc", SID_LOG_COMMENT, D_comove(z, cosmo) / M_PER_MPC); SID_log("D_horizon = %10.3lf Mpc", SID_LOG_COMMENT, C_VACUUM * deltat_a(&cosmo, 0., a_of_z(z)) / M_PER_MPC); SID_log("D_V = %10.3lf Mpc", SID_LOG_COMMENT, pow((1 + z) * D_angular(z, cosmo) * (1 + z) * D_angular(z, cosmo) * z * C_VACUUM / H_convert(H_z(z, cosmo)), ONE_THIRD) / M_PER_MPC); SID_log("H(z) = %10.3lf km/s/Mpc", SID_LOG_COMMENT, H_z(z, cosmo)); SID_log("t_age(z) = %10.3le years", SID_LOG_COMMENT, t_age_z(z, &cosmo) / S_PER_YEAR); SID_log("t_Hubble(z) = %10.3le years", SID_LOG_COMMENT, t_Hubble_z(z, cosmo) / S_PER_YEAR); SID_log("t_dyn(z) = %10.3le years", SID_LOG_COMMENT, t_dyn_z(z, cosmo) / S_PER_YEAR); SID_log("n_dyn(<z) = %10.3le", SID_LOG_COMMENT, n_dyn_ztoz(0., z, cosmo)); SID_log("Done.", SID_LOG_CLOSE); // Clean-up free_cosmo(&cosmo); SID_Finalize(); }