12#include "gadgetconfig.h"
14#if defined(LIGHTCONE) && defined(LIGHTCONE_PARTICLES)
16#include <gsl/gsl_rng.h>
27#include "../data/allvars.h"
28#include "../data/dtypes.h"
29#include "../data/mymalloc.h"
30#include "../io/hdf5_util.h"
32#include "../lightcone/lightcone.h"
33#include "../lightcone/lightcone_particle_io.h"
34#include "../main/simulation.h"
35#include "../mpi_utils/mpi_utils.h"
36#include "../system/system.h"
45lightcone_particle_io::lightcone_particle_io(lcparticles *Lp_ptr, lightcone *LightCone_ptr, mergertree *MergerTree_ptr, MPI_Comm comm,
49lightcone_particle_io::lightcone_particle_io(lcparticles *Lp_ptr, lightcone *LightCone_ptr, MPI_Comm comm, int format)
54 LightCone = LightCone_ptr;
56 MergerTree = MergerTree_ptr;
59 this->N_IO_Fields = 0;
60 this->N_DataGroups =
NTYPES + 2;
64 this->header_size =
sizeof(header);
65 this->header_buf = &header;
67 sprintf(this->info,
"LIGHTCONE: writing particle lightcone data");
69 init_field(
"POS ",
"Coordinates",
MEM_MY_DOUBLE,
FILE_MY_IO_FLOAT,
READ_IF_PRESENT, 3,
A_LC, NULL, io_func_pos,
ALL_TYPES, 1, 1.,
72#ifdef OUTPUT_VELOCITIES_IN_HALF_PRECISION
73 init_field(
"VEL ",
"Velocities",
MEM_MY_FLOAT,
FILE_HALF,
READ_IF_PRESENT, 3,
A_LC, &Lp->P[0].Vel[0], NULL,
ALL_TYPES, 1, 0.5, 0.,
76 init_field(
"VEL ",
"Velocities",
MEM_MY_FLOAT,
FILE_MY_IO_FLOAT,
READ_IF_PRESENT, 3,
A_LC, &Lp->P[0].Vel[0], NULL,
ALL_TYPES, 1, 0.5,
80#ifdef LIGHTCONE_OUTPUT_ACCELERATIONS
81#ifdef OUTPUT_ACCELERATIONS_IN_HALF_PRECISION
83 init_field(
"ACCE",
"Acceleration",
MEM_MY_FLOAT,
FILE_HALF,
READ_IF_PRESENT, 3,
A_LC, NULL, io_func_accel,
ALL_TYPES, 1, -2.0, 1, -1,
86 init_field(
"ACCE",
"Acceleration",
MEM_MY_FLOAT,
FILE_MY_IO_FLOAT,
READ_IF_PRESENT, 3,
A_LC, &Lp->P[0].GravAccel[0], NULL,
ALL_TYPES,
91 init_field(
"ID ",
"ParticleIDs",
MEM_MY_ID_TYPE,
FILE_MY_ID_TYPE,
READ_IF_PRESENT, 1,
A_LC, NULL, io_func_id,
ALL_TYPES, 0, 0, 0, 0,
95 init_field(
"MASS",
"Masses",
MEM_MY_DOUBLE,
FILE_MY_IO_FLOAT,
READ_IF_PRESENT, 1,
A_LC, NULL, io_func_mass,
MASS_BLOCK, 1, 0., -1.,
100 init_field(
"ASCL",
"Ascale",
MEM_MY_FLOAT,
FILE_MY_IO_FLOAT,
READ_IF_PRESENT, 1,
A_LC, &Lp->P[0].Ascale, NULL,
ALL_TYPES, 0, 0, 0, 0,
104#ifdef REARRANGE_OPTION
105 init_field(
"MTRI",
"TreeID",
MEM_INT64,
FILE_INT64,
SKIP_ON_READ, 1,
A_LC, &Lp->P[0].TreeID, NULL,
ALL_TYPES, 0, 0, 0, 0, 0, 0, 0);
108#if defined(SUBFIND) && defined(SUBFIND_STORE_LOCAL_DENSITY)
123 init_field(
"MTRL",
"ParticleCount",
MEM_INT,
FILE_INT,
SKIP_ON_READ, 1,
A_TT, &MergerTree->TreeTable[0].HaloCount, NULL,
TREETABLE,
124 0, 0, 0, 0, 0, 0, 0,
true);
127 init_field(
"MTRI",
"TreeID",
MEM_INT64,
FILE_INT64,
SKIP_ON_READ, 1,
A_TT, &MergerTree->TreeTable[0].TreeID, NULL,
TREETABLE, 0, 0,
128 0, 0, 0, 0, 0,
true);
131 init_field(
"HPHT",
"ParticleCount",
MEM_INT,
FILE_INT,
SKIP_ON_READ, 1,
A_MM, &Lp->HealPixTab_PartCount[0], NULL,
HEALPIXTAB, 0, 0,
132 0, 0, 0, 0, 0,
true);
135void lightcone_particle_io::lightcone_read(
int num,
int conenr)
144 sprintf(fname,
"%s/lightcone_%02d/conedir_%04d/%s_%04d",
All.
OutputDir, conenr, num,
"conesnap", num);
146 sprintf(fname,
"%s/lightcone_%02d/%s_%04d",
All.
OutputDir, conenr,
"conesnap", num);
148 int num_files = find_files(fname, fname);
150 reset_io_byte_count();
152 for(
int rep = 0; rep < 2; rep++)
156 read_files_driver(fname, rep, num_files);
161 Lp->MaxPart = Lp->NumPart;
162 Lp->allocate_memory();
166 MPI_Barrier(Communicator);
168 long long byte_count = get_io_byte_count(), byte_count_all;
169 sumup_longs(1, &byte_count, &byte_count_all, Communicator);
173 mpi_printf(
"LIGHTCONE-READ: reading done. Took %g sec, total size %g MB, corresponds to effective I/O rate of %g MB/sec\n",
174 Logs.
timediff(t0, t1), byte_count_all / (1024.0 * 1024.0), byte_count_all / (1024.0 * 1024.0) /
Logs.
timediff(t0, t1));
176 mpi_printf(
"\nLIGHTCONE-READ: Total number of particles : %lld\n\n", Lp->TotNumPart);
179void lightcone_particle_io::lightcone_save(
int num,
int conenr,
bool reordered_flag)
184 reorder_flag = reordered_flag;
191 for(
int n = 0; n <
NTYPES; n++)
194 for(
int n = 0; n < Lp->NumPart; n++)
196 if(reorder_flag || LightCone->lightcone_is_cone_member(n, cone))
197 n_type[Lp->P[n].getType()]++;
205 Lp->Npix = nside2npix(LIGHTCONE_ORDER_NSIDE);
209 Lp->HealPixTab_PartCount = (
int *)
Mem.mymalloc(
"HealPixTab_PartCount", Lp->NpixLoc *
sizeof(
int));
211 int *tmp_PartCount = (
int *)
Mem.mymalloc_clear(
"tmp_PartCount", Lp->Npix *
sizeof(
int));
212 for(
int n = 0; n < Lp->NumPart; n++)
214 if(LightCone->lightcone_is_cone_member(n, cone))
215 tmp_PartCount[Lp->P[n].ipnest]++;
218 MPI_Allreduce(MPI_IN_PLACE, tmp_PartCount, Lp->Npix, MPI_INT, MPI_SUM, Communicator);
220 memcpy(Lp->HealPixTab_PartCount, tmp_PartCount + Lp->FirstPix, Lp->NpixLoc *
sizeof(
int));
222 Mem.myfree(tmp_PartCount);
225 Lp->Npix = Lp->NpixLoc = 0;
227 mpi_printf(
"\nLIGHTCONE: writing cone=%d\n", conenr);
231 sprintf(lname,
"lightcone_treeorder");
233 sprintf(lname,
"lightcone");
243 MPI_Barrier(Communicator);
249 sprintf(buf,
"%s/%s_%02d/conedir_%04d",
All.
OutputDir, lname, cone, num);
252 MPI_Barrier(Communicator);
255 sprintf(buf,
"%s/%s_%02d/conedir_%04d/%s_%04d",
All.
OutputDir, lname, cone, num,
"conesnap", num);
257 sprintf(buf,
"%s/%s_%02d/%s_%04d",
All.
OutputDir, lname, cone,
"conesnap", num);
263 Mem.myfree(Lp->HealPixTab_PartCount);
264 Lp->HealPixTab_PartCount = NULL;
268void lightcone_particle_io::fill_file_header(
int writeTask,
int lastTask,
long long *n_type,
long long *ntot_type)
271 for(
int n = 0; n <
NTYPES + 2; n++)
274 for(
int n = 0; n < Lp->NumPart; n++)
275 if(reorder_flag || LightCone->lightcone_is_cone_member(n, cone))
276 if(Lp->P[n].getType() <
NTYPES)
277 n_type[Lp->P[n].getType()]++;
280 n_type[
NTYPES + 0] = MergerTree->Ntrees;
285 n_type[
NTYPES + 1] = Lp->NpixLoc;
288 if(ThisTask == writeTask)
290 for(
int n = 0; n <
NTYPES + 2; n++)
291 ntot_type[n] = n_type[n];
293 for(
int task = writeTask + 1; task <= lastTask; task++)
296 MPI_Recv(&nn[0],
NTYPES + 2, MPI_LONG_LONG, task,
TAG_LOCALN, Communicator, MPI_STATUS_IGNORE);
297 for(
int n = 0; n <
NTYPES + 2; n++)
298 ntot_type[n] += nn[n];
301 for(
int task = writeTask + 1; task <= lastTask; task++)
302 MPI_Send(&ntot_type[0],
NTYPES + 2, MPI_LONG_LONG, task,
TAG_N, Communicator);
306 MPI_Send(&n_type[0],
NTYPES + 2, MPI_LONG_LONG, writeTask,
TAG_LOCALN, Communicator);
307 MPI_Recv(&ntot_type[0],
NTYPES + 2, MPI_LONG_LONG, writeTask,
TAG_N, Communicator, MPI_STATUS_IGNORE);
312 for(
int n = 0; n <
NTYPES; n++)
314 header.npart[n] = ntot_type[n];
315 header.npartTotal[n] = ntot_type_all[n];
320 header.Ntrees = ntot_type[
NTYPES];
322 header.TotNtrees = MergerTree->TotNtrees;
324 header.TotNtrees = 0;
332 header.TotNtrees = 0;
334 header.Npix = ntot_type[
NTYPES + 1];
335 header.TotNpix = Lp->Npix;
341void lightcone_particle_io::write_header_fields(hid_t handle)
347 if(header.TotNtrees > 0)
353 if(header.TotNpix > 0)
360void lightcone_particle_io::set_filenr_in_header(
int numfiles) { header.num_files = numfiles; }
362void lightcone_particle_io::get_datagroup_name(
int type,
char *buf)
365 sprintf(buf,
"/PartType%d", type);
367 sprintf(buf,
"/TreeTable");
368 else if(type ==
NTYPES + 1)
369 sprintf(buf,
"/HealPixHashTable");
374void *lightcone_particle_io::get_base_address_of_structure(
enum arrays array,
int index)
379 return (
void *)(Lp->P + index);
382 return (
void *)(Lp->PS + index);
386 return (
void *)(MergerTree->TreeTable + index);
390 return (
void *)(Lp->HealPixTab_PartCount + index);
393 Terminate(
"we don't expect to get here");
399void lightcone_particle_io::read_file_header(
const char *fname,
int filenr,
int readTask,
int lastTask,
long long *n_type,
400 long long *ntot_type,
int *nstart)
405 ntot_type[
NTYPES + 1] = 0;
407 if(Lp->TotNumPart == 0)
409 if(header.num_files <= 1)
410 for(
int i = 0; i <
NTYPES; i++)
411 header.npartTotal[i] = header.npart[i];
415 for(
int i = 0; i <
NTYPES; i++)
416 Lp->TotNumPart += header.npartTotal[i];
419 if(ThisTask == readTask)
421 if(filenr == 0 && nstart == NULL)
423 for(
int type = 0; type <
NTYPES; type++)
425 mpi_printf(
"READ-LIGHTCONE: Type %d: %8lld (tot=%15lld)\n", type, (
long long)header.npart[type],
426 (
long long)header.npartTotal[type]);
437 for(
int type = 0; type <
NTYPES; type++)
439 ntot_type[type] = header.npart[type];
441 long long n_in_file = header.npart[type];
442 int ntask = lastTask - readTask + 1;
443 int n_for_this_task = n_in_file / ntask;
444 if((ThisTask - readTask) < (n_in_file % ntask))
447 n_type[type] = n_for_this_task;
449 nall += n_for_this_task;
454 memmove(&Lp->P[nall], &Lp->P[0], Lp->NumPart *
sizeof(lightcone_particle_data));
460void lightcone_particle_io::read_header_fields(
const char *fname)
462 for(
int i = 0; i <
NTYPES; i++)
465 header.npartTotal[i] = 0;
469 header.TotNtrees = 0;
473 hid_t hdf5_file =
my_H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
474 hid_t handle =
my_H5Gopen(hdf5_file,
"/Header");
478 hid_t space = H5Aget_space(hdf5_attribute);
480 H5Sget_simple_extent_dims(space, &dims, &len);
482 if(len != (
size_t)ntypes)
483 Terminate(
"Length of NumPart_ThisFile attribute (%d) does not match NTYPES(ICS) (%d)", (
int)len, ntypes);
495void lightcone_particle_io::read_increase_numbers(
int type,
int n_for_this_task) { Lp->NumPart += n_for_this_task; }
497int lightcone_particle_io::get_filenr_from_header(
void) {
return header.num_files; }
499int lightcone_particle_io::get_type_of_element(
int index)
501 if(index < 0 || index >= Lp->NumPart)
502 Terminate(
"index = %d Lp->NumPart=%d", index, Lp->NumPart);
504 if(reorder_flag || LightCone->lightcone_is_cone_member(index, cone))
505 return Lp->P[index].getType();
510void lightcone_particle_io::set_type_of_element(
int index,
int type)
513 Lp->P[index].setType(type);
global_data_all_processes All
double timediff(double t0, double t1)
void write_vector_attribute(hid_t handle, const char *attr_name, const void *buf, hid_t mem_type_id, int length)
hid_t my_H5Gopen(hid_t loc_id, const char *groupname)
hid_t my_H5Fopen(const char *fname, unsigned int flags, hid_t fapl_id)
herr_t my_H5Gclose(hid_t group_id, const char *groupname)
void read_vector_attribute(hid_t handle, const char *attr_name, void *buf, hid_t mem_type_id, int length)
herr_t my_H5Fclose(hid_t file_id, const char *fname)
hid_t my_H5Aopen_name(hid_t loc_id, const char *attr_name)
herr_t my_H5Aclose(hid_t attr_id, const char *attr_name)
void write_scalar_attribute(hid_t handle, const char *attr_name, const void *buf, hid_t mem_type_id)
void read_scalar_attribute(hid_t handle, const char *attr_name, void *buf, hid_t mem_type_id)
void sumup_large_ints(int n, int *src, long long *res, MPI_Comm comm)
void sumup_longs(int n, long long *src, long long *res, MPI_Comm comm)
double UnitVelocity_in_cm_per_s
enum restart_options RestartFlag
double UnitDensity_in_cgs
char OutputDir[MAXLEN_PATH]
double accel_normalize_fac
void subdivide_evenly(long long N, int pieces, int index_bin, long long *first, int *count)