GADGET-4
snap_io.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * \copyright This file is part of the GADGET4 N-body/SPH code developed
3  * \copyright by Volker Springel. Copyright (C) 2014-2020 by Volker Springel
4  * \copyright (vspringel@mpa-garching.mpg.de) and all contributing authors.
5  *******************************************************************************/
6 
12 #ifndef SNAP_READ_WRITE_H
13 #define SNAP_READ_WRITE_H
14 
15 #include "gadgetconfig.h"
16 
17 #include "../data/intposconvert.h"
18 #include "../data/simparticles.h"
19 #include "../io/io.h"
20 #include "../mergertree/mergertree.h"
21 
22 class snap_io : public IO_Def
23 {
24  public:
25  void init_basic(simparticles *Sp_ptr);
26 
27  snap_io(simparticles *Sp_ptr, MPI_Comm comm, int format) : IO_Def(comm, format) { init_basic(Sp_ptr); }
28 
29 #if defined(REARRANGE_OPTION) && defined(MERGERTREE)
30  void init_extra(simparticles *Sp_ptr, mergertree *MergerTree_ptr);
31  snap_io(simparticles *Sp_ptr, mergertree *MergerTree_ptr, MPI_Comm comm, int format) : IO_Def(comm, format)
32  {
33  init_basic(Sp_ptr);
34  init_extra(Sp_ptr, MergerTree_ptr);
35  }
36 #endif
37 
38  void write_snapshot(int num, mysnaptype snap_type);
39  void read_snapshot(int num, mysnaptype snap_type);
40 
41  int acquire_basic_treeinfo(int num, mysnaptype loc_snap_type);
42  void free_basic_treeinfo(void);
43  long long load_orphans(int num, long long treenr, int num_files);
44  void free_orphans(void);
45 
46  void read_ic(const char *fname);
47 
48  /* supplied virtual functions */
49  void fill_file_header(int writeTask, int lastTask, long long *nloc_part, long long *npart);
50  void read_file_header(const char *fname, int filenr, int readTask, int lastTask, long long *nloc_part, long long *npart,
51  int *nstart);
52  void get_datagroup_name(int grnr, char *gname);
53  void write_header_fields(hid_t);
54  void read_header_fields(const char *fname);
55  void read_increase_numbers(int type, int n_for_this_task);
56  int get_filenr_from_header(void);
57  void set_filenr_in_header(int);
58  void *get_base_address_of_structure(enum arrays array, int index);
59  int get_type_of_element(int index);
60  void set_type_of_element(int index, int type);
61 
64 #ifdef GADGET2_HEADER
65 
66  struct io_header
67  {
68  int npart[NTYPES_HEADER];
69  double mass[NTYPES_HEADER];
71  double time;
72  double redshift;
73  int flag_sfr;
74  int flag_feedback;
75  unsigned int npartTotalLowWord[NTYPES_HEADER];
77  int flag_cooling;
78  int num_files;
79  double BoxSize;
80  double Omega0;
81  double OmegaLambda;
82 #if defined(REARRANGE_OPTION) && defined(MERGERTREE)
83  long long Ntrees; // this replaces the storage space for HubbleParam
84  long long TotNtrees; // this replaces the storage space for Hubble
85 #else
86  double HubbleParam;
87  double Hubble;
88 #endif
89  unsigned int npartTotalHighWord[NTYPES_HEADER];
90  int flag_entropy_instead_u;
91  int flag_doubleprecision;
92  int flag_ic_info;
100  float lpt_scalingfactor;
102  long long npartTotal[NTYPES_HEADER];
103  };
104 
105 #else
106  /* new simplified header format */
107  struct io_header
108  {
109  long long npart[NTYPES_HEADER];
112  double mass[NTYPES_HEADER];
114  double time;
115  double redshift;
116  double BoxSize;
117  int num_files;
119  long long Ntrees;
120  long long TotNtrees;
121  };
122 
123 #endif
124 
127  private:
128  simparticles *Sp;
129 #ifdef MERGERTREE
130  mergertree *MergerTree;
131 #endif
132 
133  mysnaptype snap_type;
134 
135  long long ntot_type_all[NTYPES];
137 #ifndef OUTPUT_COORDINATES_AS_INTEGERS
138  struct ptmp_data
139  {
140  MyDouble Pos[3];
141  };
142  ptmp_data *Ptmp;
143 #endif
144 
145  void snap_init_domain_mapping(void);
146  void read_increase_particle_numbers(int type, int n_for_this_task);
147 
148  /*
149  * special input/output functions for certain fields
150  */
151 #ifndef OUTPUT_COORDINATES_AS_INTEGERS
152  static void io_func_pos(IO_Def *ptr, int particle, int components, void *buffer, int mode)
153  {
154  /* note: we know that components==3 here */
155  snap_io *thisobj = (snap_io *)ptr;
156 
157  if(mode == 0)
158  {
159  MyDouble *out_buffer = (MyDouble *)buffer;
160 
161  /* converts the integer coordinates to floating point */
162  thisobj->Sp->intpos_to_pos(thisobj->Sp->P[particle].IntPos, out_buffer);
163  }
164  else
165  {
166  MyDouble *in_buffer = (MyDouble *)buffer;
167 
168  /* note: for non-periodic positions, the conversion to integer coordinates is undefined only after the initial read.
169  * We therefore store the coordinates first in a temporary array */
170 
171  for(int k = 0; k < 3; k++)
172  thisobj->Ptmp[particle].Pos[k] = in_buffer[k];
173 
174 #ifdef SQUASH_TEST
175  thisobj->Ptmp[particle].Pos[1] *= 1.0 / 4;
176  thisobj->Ptmp[particle].Pos[2] *= 1.0 / 16;
177 #endif
178  }
179  }
180 #endif
181 
182  static void io_func_intpos(IO_Def *ptr, int particle, int components, void *buffer, int mode)
183  {
184  /* note: we know that components==3 here */
185  snap_io *thisobj = (snap_io *)ptr;
186 
187  if(mode == 0)
188  {
189  MyIntPosType *out_buffer = (MyIntPosType *)buffer;
190 
191  /* converts the integer coordinates to integer by subtracting a possible randomization shift */
192  thisobj->Sp->intpos_to_intpos(thisobj->Sp->P[particle].IntPos, out_buffer);
193  }
194  else
195  {
196  MyIntPosType *in_buffer = (MyIntPosType *)buffer;
197 
198  for(int k = 0; k < 3; k++)
199  thisobj->Sp->P[particle].IntPos[k] = in_buffer[k];
200  }
201  }
202 
203  static void io_func_vel(IO_Def *ptr, int particle, int components, void *buffer, int mode)
204  {
205  snap_io *thisobj = (snap_io *)ptr;
206 
207  if(mode == 0)
208  {
209  MyFloat *out_buffer = (MyFloat *)buffer;
210  for(int k = 0; k < 3; k++)
211  {
212  out_buffer[k] = thisobj->Sp->P[particle].Vel[k];
213 
214  /* we are using p = a^2 * xdot internally as velocity unit. Convert to legacy Gadget velocity units */
215  out_buffer[k] *= sqrt(All.cf_a3inv);
216  }
217  }
218  else
219  {
220  MyFloat *in_buffer = (MyFloat *)buffer;
221  for(int k = 0; k < components; k++)
222  {
223  thisobj->Sp->P[particle].Vel[k] = in_buffer[k];
224  }
225  }
226  }
227 
228  static void io_func_id(IO_Def *ptr, int particle, int components, void *buffer, int mode)
229  {
230  snap_io *thisobj = (snap_io *)ptr;
231 
232  if(mode == 0)
233  {
234  MyIDType *out_buffer = (MyIDType *)buffer;
235  out_buffer[0] = thisobj->Sp->P[particle].ID.get();
236  }
237  else
238  {
239  MyIDType *in_buffer = (MyIDType *)buffer;
240  thisobj->Sp->P[particle].ID.set(in_buffer[0]);
241  }
242  }
243 
244  static void io_func_mass(IO_Def *ptr, int particle, int components, void *buffer, int mode)
245  {
246  snap_io *thisobj = (snap_io *)ptr;
247 
248  if(mode == 0)
249  {
250  MyDouble *out_buffer = (MyDouble *)buffer;
251  out_buffer[0] = thisobj->Sp->P[particle].getMass();
252  }
253  else
254  {
255  MyDouble *in_buffer = (MyDouble *)buffer;
256  thisobj->Sp->P[particle].setMass(in_buffer[0]);
257  }
258  }
259 
260  static void io_func_u(IO_Def *ptr, int particle, int components, void *buffer, int mode)
261  {
262  snap_io *thisobj = (snap_io *)ptr;
263 
264  if(mode == 0)
265  {
266  MyFloat *out_buffer = (MyFloat *)buffer;
267  out_buffer[0] = thisobj->Sp->get_utherm_from_entropy(particle);
268  }
269  else
270  {
271  MyFloat *in_buffer = (MyFloat *)buffer;
272  thisobj->Sp->SphP[particle].Entropy = in_buffer[0];
273  }
274  }
275 
276 #ifdef STARFORMATION
277  static void io_func_sfr(IO_Def *ptr, int particle, int components, void *buffer, int mode)
278  {
279  snap_io *thisobj = (snap_io *)ptr;
280 
281  if(mode == 0)
282  {
283  MyFloat *out_buffer = (MyFloat *)buffer;
284  out_buffer[0] = thisobj->Sp->SphP[particle].Sfr;
285  }
286  else
287  {
288  MyFloat *in_buffer = (MyFloat *)buffer;
289  thisobj->Sp->SphP[particle].Sfr = in_buffer[0];
290  }
291  }
292 
293  static void io_func_metallicity(IO_Def *ptr, int particle, int components, void *buffer, int mode)
294  {
295  snap_io *thisobj = (snap_io *)ptr;
296 
297  if(mode == 0)
298  {
299  MyFloat *out_buffer = (MyFloat *)buffer;
300  if(thisobj->Sp->P[particle].getType() == 0)
301  {
302  out_buffer[0] = thisobj->Sp->SphP[particle].Metallicity;
303  }
304  else
305  {
306  out_buffer[0] = thisobj->Sp->P[particle].Metallicity;
307  }
308  }
309  else
310  {
311  MyFloat *in_buffer = (MyFloat *)buffer;
312  thisobj->Sp->P[particle].Metallicity = in_buffer[0];
313  }
314  }
315 #endif
316 
317 #ifdef OUTPUT_ACCELERATION
318  static void io_func_accel(IO_Def *ptr, int particle, int components, void *buffer, int mode)
319  {
320  snap_io *thisobj = (snap_io *)ptr;
321 
322  if(mode == 0) // writing
323  {
324  MyFloat *out_buffer = (MyFloat *)buffer;
326  for(int k = 0; k < 3; k++)
327  out_buffer[k] = All.cf_a2inv * thisobj->Sp->P[particle].GravAccel[k];
328  else
329  for(int k = 0; k < 3; k++)
330  out_buffer[k] = thisobj->Sp->P[particle].GravAccel[k];
331 #if defined(PMGRID) && defined(PERIODIC) && !defined(TREEPM_NOTIMESPLIT)
333  for(int k = 0; k < 3; k++)
334  out_buffer[k] += All.cf_a2inv * thisobj->Sp->P[particle].GravPM[k];
335  else
336  for(int k = 0; k < 3; k++)
337  out_buffer[k] += thisobj->Sp->P[particle].GravPM[k];
338 #endif
339 
340  for(int k = 0; k < 3; k++)
341  out_buffer[k] /= All.accel_normalize_fac;
342  }
343  else // reading
344  {
345  MyFloat *in_buffer = (MyFloat *)buffer;
346  for(int k = 0; k < components; k++)
347  thisobj->Sp->P[particle].GravAccel[k] = All.accel_normalize_fac * in_buffer[k];
348  }
349  }
350 
351 #endif
352 
353 #ifdef OUTPUT_PRESSURE
354  static void io_func_pressure(IO_Def *ptr, int particle, int components, void *buffer, int mode)
355  {
356  snap_io *thisobj = (snap_io *)ptr;
357  MyFloat *out_buffer = (MyFloat *)buffer;
358 
359  out_buffer[0] = thisobj->Sp->SphP[particle].get_pressure();
360  }
361 #endif
362 
363 #ifdef OUTPUT_TIMESTEP
364  static void io_func_timestep(IO_Def *ptr, int particle, int components, void *buffer, int mode)
365  {
366  snap_io *thisobj = (snap_io *)ptr;
367  MyFloat *out_buffer = (MyFloat *)buffer;
368 
369  out_buffer[0] = (thisobj->Sp->P[particle].TimeBinGrav ? (((integertime)1) << thisobj->Sp->P[particle].TimeBinGrav) : 0) *
371  }
372 
373  static void io_func_timestephydro(IO_Def *ptr, int particle, int components, void *buffer, int mode)
374  {
375  snap_io *thisobj = (snap_io *)ptr;
376  MyFloat *out_buffer = (MyFloat *)buffer;
377 
378  out_buffer[0] =
379  (thisobj->Sp->P[particle].getTimeBinHydro() ? (((integertime)1) << thisobj->Sp->P[particle].getTimeBinHydro()) : 0) *
381  }
382 #endif
383 };
384 
385 #endif /* SNAP_READ_WRITE_H */
global_data_all_processes All
Definition: main.cc:40
Definition: io.h:129
MyIDType get(void) const
Definition: idstorage.h:87
void set(MyIDType ID)
Definition: idstorage.h:96
void intpos_to_intpos(MyIntPosType *intpos, MyIntPosType *xyz)
void intpos_to_pos(MyIntPosType *intpos, T *posdiff)
double get_utherm_from_entropy(int i)
Definition: simparticles.h:238
particle_data * P
Definition: simparticles.h:54
sph_particle_data * SphP
Definition: simparticles.h:59
int get_filenr_from_header(void)
Definition: snap_io.cc:961
void read_header_fields(const char *fname)
This function reads the snapshot header in case of hdf5 files (i.e. format 3)
Definition: snap_io.cc:909
void * get_base_address_of_structure(enum arrays array, int index)
Definition: snap_io.cc:522
void read_increase_numbers(int type, int n_for_this_task)
Definition: snap_io.cc:965
int acquire_basic_treeinfo(int num, mysnaptype loc_snap_type)
void read_snapshot(int num, mysnaptype snap_type)
Definition: snap_io.cc:244
void fill_file_header(int writeTask, int lastTask, long long *nloc_part, long long *npart)
Definition: snap_io.cc:643
void read_file_header(const char *fname, int filenr, int readTask, int lastTask, long long *nloc_part, long long *npart, int *nstart)
Definition: snap_io.cc:752
void set_type_of_element(int index, int type)
Definition: snap_io.cc:516
void write_header_fields(hid_t)
Write the fields contained in the header group of the HDF5 snapshot file.
Definition: snap_io.cc:880
void free_orphans(void)
void get_datagroup_name(int grnr, char *gname)
Definition: snap_io.cc:974
void read_ic(const char *fname)
This function reads initial conditions that are in on of the default file formats of Gadget.
Definition: snap_io.cc:289
void set_filenr_in_header(int)
Definition: snap_io.cc:963
void init_basic(simparticles *Sp_ptr)
Function for field registering.
Definition: snap_io.cc:50
void free_basic_treeinfo(void)
io_header header
Definition: snap_io.h:125
snap_io(simparticles *Sp_ptr, MPI_Comm comm, int format)
Definition: snap_io.h:27
long long load_orphans(int num, long long treenr, int num_files)
int get_type_of_element(int index)
Definition: snap_io.cc:495
void write_snapshot(int num, mysnaptype snap_type)
Save snapshot to disk.
Definition: snap_io.cc:559
#define NTYPES
Definition: constants.h:308
int integertime
Definition: constants.h:331
float MyDouble
Definition: dtypes.h:87
float MyFloat
Definition: dtypes.h:86
mysnaptype
Definition: dtypes.h:305
uint32_t MyIntPosType
Definition: dtypes.h:35
@ RST_CONVERTSNAP
Definition: dtypes.h:318
unsigned int MyIDType
Definition: dtypes.h:68
arrays
Definition: io.h:30
#define NTYPES_HEADER
Definition: io.h:268
expr sqrt(half arg)
Definition: half.hpp:2777
enum restart_options RestartFlag
Definition: allvars.h:68
MyDouble getMass(void)
void setMass(MyDouble mass)
unsigned char getTimeBinHydro(void)
MyFloat Vel[3]
Definition: particle_data.h:54
MyIDStorage ID
Definition: particle_data.h:70
signed char TimeBinGrav
Definition: particle_data.h:71
unsigned char getType(void)
vector< MyFloat > GravAccel
Definition: particle_data.h:55
MyIntPosType IntPos[3]
Definition: particle_data.h:53
long long TotNtrees
Definition: snap_io.h:120
double mass[NTYPES_HEADER]
Definition: snap_io.h:112
long long npartTotal[NTYPES_HEADER]
Definition: snap_io.h:110
long long npart[NTYPES_HEADER]
Definition: snap_io.h:109
long long Ntrees
Definition: snap_io.h:119
MyFloat get_pressure(void)