GADGET-4
subfind_readid_io.cc
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#include "gadgetconfig.h"
13
14#ifdef SUBFIND_ORPHAN_TREATMENT
15
16#include <errno.h>
17#include <hdf5.h>
18#include <math.h>
19#include <mpi.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <sys/stat.h>
24
25#include "../cooling_sfr/cooling.h"
26#include "../data/allvars.h"
27#include "../data/dtypes.h"
28#include "../data/mymalloc.h"
29#include "../data/particle_data.h"
30#include "../fof/fof.h"
31#include "../io/hdf5_util.h"
32#include "../io/io.h"
33#include "../logs/timer.h"
34#include "../main/main.h"
35#include "../main/simulation.h"
36#include "../mergertree/io_readsnap.h"
37#include "../mergertree/mergertree.h"
38#include "../mpi_utils/mpi_utils.h"
39#include "../subfind/subfind_readid_io.h"
40#include "../system/system.h"
41
42subreadid_io::subreadid_io(idstoredata *IdStore_ptr, MPI_Comm comm, int format) : IO_Def(comm, format)
43{
44 IdStore = IdStore_ptr;
45
46 this->N_IO_Fields = 0;
47 this->N_DataGroups = NTYPES;
48 this->header_size = sizeof(header);
49 this->header_buf = &header;
50 this->type_of_file = FILE_IS_SNAPSHOT;
51 sprintf(this->info, "MERGERTREE: reading snapshot IDs");
52
53 init_field("ID ", "ParticleIDs", MEM_MY_ID_TYPE, FILE_MY_ID_TYPE, READ_IF_PRESENT, 1, A_IDS, IdStore->ID, NULL, ALL_TYPES, 0, 0, 0,
54 0, 0, 0, 0);
55}
56
78void subreadid_io::previously_bound_read_snap_ids(int num)
79{
80 if(All.ICFormat < 1 || All.ICFormat > 4)
81 Terminate("ICFormat=%d not supported.\n", All.ICFormat);
82
83 char fname[MAXLEN_PATH_EXTRA], fname_multiple[MAXLEN_PATH_EXTRA];
84 sprintf(fname_multiple, "%s/snapdir_%03d/%s-prevmostboundonly_%03d", All.OutputDir, num, All.SnapshotFileBase, num);
85 sprintf(fname, "%s%s_%03d", All.OutputDir, All.SnapshotFileBase, num);
86
87 TIMER_START(CPU_SNAPSHOT);
88
89 int num_files = find_files(fname, fname_multiple);
90
91 if(num_files > 1)
92 strcpy(fname, fname_multiple);
93
94 /* we repeat reading the headers of the files two times. In the first iteration, only the
95 * particle numbers ending up on each processor are assembled, followed by memory allocation.
96 * In the second iteration, the data is actually read in.
97 */
98 for(int rep = 0; rep < 2; rep++)
99 {
100 IdStore->NumPart = 0;
101
102 read_files_driver(fname, rep, num_files);
103
104 /* now do the memory allocation */
105 if(rep == 0)
106 {
107 IdStore->ID = (MyIDType *)Mem.mymalloc_movable_clear(&IdStore->ID, "IdStore->ID", IdStore->NumPart * sizeof(MyIDType));
108 }
109 }
110
111 MPI_Barrier(Communicator);
112
113 mpi_printf("READSNAPID: reading done.\n");
114
115 TIMER_STOP(CPU_SNAPSHOT);
116}
117
118void subreadid_io::fill_file_header(int writeTask, int lastTask, long long *n_type, long long *ntot_type)
119{ /* empty */
120}
121
122void subreadid_io::read_file_header(const char *fname, int filenr, int readTask, int lastTask, long long *n_type, long long *ntot_type,
123 int *nstart)
124{
125 if(ThisTask == readTask)
126 {
127 if(filenr == 0 && nstart == NULL)
128 {
129 mpi_printf(
130 "\nREADSNAPID: filenr=%d, '%s' contains:\n"
131 "READSNAPID: Type 0 (gas): %8lld (tot=%15lld) masstab= %g\n",
132 filenr, fname, (long long)header.npart[0], (long long)header.npartTotal[0], All.MassTable[0]);
133
134 for(int type = 1; type < NTYPES; type++)
135 {
136 mpi_printf("READSNAPID: Type %d: %8lld (tot=%15lld) masstab= %g\n", type, (long long)header.npart[type],
137 (long long)header.npartTotal[type], All.MassTable[type]);
138 }
139 mpi_printf("\n");
140 }
141 }
142
143 /* to collect the gas particles all at the beginning (in case several
144 snapshot files are read on the current CPU) we move the collisionless
145 particles such that a gap of the right size is created */
146
147 long long nall = 0;
148 for(int type = 0; type < NTYPES; type++)
149 {
150 ntot_type[type] = header.npart[type];
151
152 long long n_in_file = header.npart[type];
153 int ntask = lastTask - readTask + 1;
154 int n_for_this_task = n_in_file / ntask;
155 if((ThisTask - readTask) < (n_in_file % ntask))
156 n_for_this_task++;
157
158 n_type[type] = n_for_this_task;
159
160 nall += n_for_this_task;
161 }
162
163 if(nstart)
164 {
165 memmove(&IdStore->ID[nall], &IdStore->ID[0], IdStore->NumPart * sizeof(MyIDType));
166
167 *nstart = 0;
168 }
169}
170
171void subreadid_io::write_header_fields(hid_t handle)
172{ /* empty */
173}
174
179void subreadid_io::read_header_fields(const char *fname)
180{
181 for(int i = 0; i < NTYPES; i++)
182 {
183 header.npart[i] = 0;
184 header.npartTotal[i] = 0;
185 header.mass[i] = 0;
186 }
187
188 hsize_t ntypes = NTYPES;
189
190 hid_t hdf5_file = my_H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
191 hid_t handle = my_H5Gopen(hdf5_file, "/Header");
192
193 /* check if the file in question actually has this number of types */
194 hid_t hdf5_attribute = my_H5Aopen_name(handle, "NumPart_ThisFile");
195 hid_t space = H5Aget_space(hdf5_attribute);
196 hsize_t dims, len;
197 H5Sget_simple_extent_dims(space, &dims, &len);
198 H5Sclose(space);
199 if(len != ntypes)
200 Terminate("Length of NumPart_ThisFile attribute (%d) does not match NTYPES(ICS) (%d)", (int)len, (int)ntypes);
201 my_H5Aclose(hdf5_attribute, "NumPart_ThisFile");
202
203 /* now read the header fields */
204
205#ifdef GADGET2_HEADER
206 read_vector_attribute(handle, "NumPart_ThisFile", header.npart, H5T_NATIVE_UINT, ntypes);
207 read_vector_attribute(handle, "NumPart_Total", header.npartTotal, H5T_NATIVE_UINT, ntypes);
208 read_scalar_attribute(handle, "Omega0", &header.Omega0, H5T_NATIVE_DOUBLE);
209 read_scalar_attribute(handle, "OmegaLambda", &header.OmegaLambda, H5T_NATIVE_DOUBLE);
210 read_scalar_attribute(handle, "HubbleParam", &header.HubbleParam, H5T_NATIVE_DOUBLE);
211 read_scalar_attribute(handle, "Hubble", &header.Hubble, H5T_NATIVE_DOUBLE);
212 read_scalar_attribute(handle, "Flag_Sfr", &header.flag_sfr, H5T_NATIVE_INT);
213 read_scalar_attribute(handle, "Flag_Cooling", &header.flag_cooling, H5T_NATIVE_INT);
214 read_scalar_attribute(handle, "Flag_Feedback", &header.flag_feedback, H5T_NATIVE_INT);
215 read_scalar_attribute(handle, "Flag_DoublePrecision", &header.flag_doubleprecision, H5T_NATIVE_INT);
216#else
217 read_vector_attribute(handle, "NumPart_ThisFile", header.npart, H5T_NATIVE_UINT64, ntypes);
218 read_vector_attribute(handle, "NumPart_Total", header.npartTotal, H5T_NATIVE_UINT64, ntypes);
219#endif
220
221 read_scalar_attribute(handle, "BoxSize", &header.BoxSize, H5T_NATIVE_DOUBLE);
222 read_vector_attribute(handle, "MassTable", header.mass, H5T_NATIVE_DOUBLE, ntypes);
223 read_scalar_attribute(handle, "Time", &header.time, H5T_NATIVE_DOUBLE);
224 read_scalar_attribute(handle, "Redshift", &header.redshift, H5T_NATIVE_DOUBLE);
225 read_scalar_attribute(handle, "NumFilesPerSnapshot", &header.num_files, H5T_NATIVE_INT);
226
227 my_H5Gclose(handle, "/Header");
228 my_H5Fclose(hdf5_file, fname);
229}
230
231int subreadid_io::get_filenr_from_header(void) { return header.num_files; }
232
233void subreadid_io::set_filenr_in_header(int numfiles) { header.num_files = numfiles; }
234
235void subreadid_io::read_increase_numbers(int type, int n_for_this_task) { IdStore->NumPart += n_for_this_task; }
236
237void subreadid_io::get_datagroup_name(int type, char *buf) { sprintf(buf, "/PartType%d", type); }
238
239int subreadid_io::get_type_of_element(int index) { return 0; /* empty */ }
240
241void subreadid_io::set_type_of_element(int index, int type)
242{ /* empty */
243}
244
245void *subreadid_io::get_base_address_of_structure(enum arrays array, int index)
246{
247 switch(array)
248 {
249 case A_IDS:
250 return (void *)(IdStore->ID + index);
251 default:
252 Terminate("we don't expect to get here");
253 }
254
255 return NULL;
256}
257#endif
global_data_all_processes All
Definition: main.cc:40
Definition: io.h:129
#define MAXLEN_PATH_EXTRA
Definition: constants.h:301
#define NTYPES
Definition: constants.h:308
unsigned int MyIDType
Definition: dtypes.h:68
hid_t my_H5Gopen(hid_t loc_id, const char *groupname)
Definition: hdf5_util.cc:311
hid_t my_H5Fopen(const char *fname, unsigned int flags, hid_t fapl_id)
Definition: hdf5_util.cc:297
herr_t my_H5Gclose(hid_t group_id, const char *groupname)
Definition: hdf5_util.cc:457
void read_vector_attribute(hid_t handle, const char *attr_name, void *buf, hid_t mem_type_id, int length)
Definition: hdf5_util.cc:614
herr_t my_H5Fclose(hid_t file_id, const char *fname)
Definition: hdf5_util.cc:482
hid_t my_H5Aopen_name(hid_t loc_id, const char *attr_name)
Definition: hdf5_util.cc:371
herr_t my_H5Aclose(hid_t attr_id, const char *attr_name)
Definition: hdf5_util.cc:429
void read_scalar_attribute(hid_t handle, const char *attr_name, void *buf, hid_t mem_type_id)
Definition: hdf5_util.cc:589
@ READ_IF_PRESENT
Definition: io.h:124
@ ALL_TYPES
Definition: io.h:103
arrays
Definition: io.h:30
@ A_IDS
Definition: io.h:47
@ FILE_MY_ID_TYPE
Definition: io.h:71
@ MEM_MY_ID_TYPE
Definition: io.h:81
@ FILE_IS_SNAPSHOT
Definition: io.h:53
#define TIMER_START(counter)
Starts the timer counter.
Definition: logs.h:197
#define TIMER_STOP(counter)
Stops the timer counter.
Definition: logs.h:220
#define Terminate(...)
Definition: macros.h:15
memory Mem
Definition: main.cc:44
double MassTable[NTYPES]
Definition: allvars.h:269
char OutputDir[MAXLEN_PATH]
Definition: allvars.h:272
char SnapshotFileBase[MAXLEN_PATH]
Definition: allvars.h:272