183 const std::string& dir,
const std::string& name,
188 const std::string& compression,
189 F&& f,
bool is_checkpoint)
194 AMREX_ASSERT(
sizeof(
typename PC::ParticleType::RealType) == 4 ||
195 sizeof(
typename PC::ParticleType::RealType) == 8);
197 constexpr int NStructReal = PC::NStructReal;
198 constexpr int NStructInt = PC::NStructInt;
204 int nrc = PC::ParticleType::is_soa_particle ?
205 pc.NumRealComps() + NStructReal - AMREX_SPACEDIM : pc.NumRealComps() + NStructReal;
210#ifdef AMREX_USE_HDF5_ASYNC
213 async_vol_es_wait_particle();
216 es_par_g = H5EScreate();
220 std::string pdir = dir;
221 if ( ! pdir.empty() && pdir[pdir.size()-1] !=
'/') { pdir +=
'/'; }
224 if ( ! pc.GetLevelDirectoriesCreated()) {
236 hid_t fid, grp, fapl, comp_dtype;
242 comp_dtype = H5Tcreate (H5T_COMPOUND, 2 * AMREX_SPACEDIM *
sizeof(
int));
243 if (1 == AMREX_SPACEDIM) {
244 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
245 H5Tinsert (comp_dtype,
"hi_i", 1 *
sizeof(
int), H5T_NATIVE_INT);
247 else if (2 == AMREX_SPACEDIM) {
248 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
249 H5Tinsert (comp_dtype,
"lo_j", 1 *
sizeof(
int), H5T_NATIVE_INT);
250 H5Tinsert (comp_dtype,
"hi_i", 2 *
sizeof(
int), H5T_NATIVE_INT);
251 H5Tinsert (comp_dtype,
"hi_j", 3 *
sizeof(
int), H5T_NATIVE_INT);
253 else if (3 == AMREX_SPACEDIM) {
254 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
255 H5Tinsert (comp_dtype,
"lo_j", 1 *
sizeof(
int), H5T_NATIVE_INT);
256 H5Tinsert (comp_dtype,
"lo_k", 2 *
sizeof(
int), H5T_NATIVE_INT);
257 H5Tinsert (comp_dtype,
"hi_i", 3 *
sizeof(
int), H5T_NATIVE_INT);
258 H5Tinsert (comp_dtype,
"hi_j", 4 *
sizeof(
int), H5T_NATIVE_INT);
259 H5Tinsert (comp_dtype,
"hi_k", 5 *
sizeof(
int), H5T_NATIVE_INT);
264 particle_io_flags(pc.GetParticles().size());
265 for (
int lev = 0; lev < pc.GetParticles().size(); lev++)
267 const auto& pmap = pc.GetParticles(lev);
268 for (
const auto& kv : pmap)
270 auto& flags = particle_io_flags[lev][kv.first];
271 particle_detail::fillFlags(flags, kv.second, f);
277 if(pc.GetUsePrePost())
279 nparticles = pc.GetNParticlesPrePost();
280 maxnextid = pc.GetMaxNextIDPrePost();
284 nparticles = particle_detail::countFlags(particle_io_flags, pc);
285 maxnextid = PC::ParticleType::NextID();
287 PC::ParticleType::NextID(maxnextid);
291 std::string HDF5FileName = pdir;
292 if ( ! HDF5FileName.empty() && HDF5FileName[HDF5FileName.size()-1] !=
'/')
295 HDF5FileName += name;
296 HDF5FileName +=
".h5";
297 pc.HdrFileNamePrePost = HDF5FileName;
304 char setstripe[1024];
305 int stripe_count = 128;
307 char *stripe_count_str = getenv(
"HDF5_STRIPE_COUNT");
308 char *stripe_size_str = getenv(
"HDF5_STRIPE_SIZE");
309 if (stripe_count_str) {
310 stripe_count = atoi(stripe_count_str);
313 if (stripe_size_str) {
314 stripe_size = atoi(stripe_size_str);
317 if (set_stripe == 1) {
318 snprintf(setstripe,
sizeof setstripe,
"lfs setstripe -c %d -S %dm %s", stripe_count, stripe_size, pdir.c_str());
319 std::cout <<
"Setting stripe parameters for HDF5 output: " << setstripe << std::endl;
323 fid = H5Fcreate(HDF5FileName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
332 std::string versionName = is_checkpoint ? PC::CheckpointVersion() : PC::PlotfileVersion();
333 if (
sizeof(
typename PC::ParticleType::RealType) == 4) {
334 versionName +=
"_single";
336 versionName +=
"_double";
341 int num_output_real = 0;
342 for (
int i = 0; i < static_cast<int>(write_real_comp.
size()); ++i) {
343 if (write_real_comp[i]) { ++num_output_real; }
346 int num_output_int = 0;
347 for (
int i = 0; i < pc.NumIntComps() + NStructInt; ++i) {
348 if (write_int_comp[i]) { ++num_output_int; }
352 int ndim = AMREX_SPACEDIM;
353 grp = H5Gcreate(fid,
"Chombo_global", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
358 int ncomp = num_output_real + num_output_int;
365 int real_comp_count = AMREX_SPACEDIM;
367 for (
int i = 0; i < static_cast<int>(write_real_comp.
size()); ++i ) {
368 if (write_real_comp[i]) {
370 snprintf(comp_name,
sizeof comp_name,
"real_component_%d", real_comp_count);
380 int int_comp_count = 2;
382 for (
int i = 0; i < NStructInt + pc.NumIntComps(); ++i ) {
383 if (write_int_comp[i]) {
384 snprintf(comp_name,
sizeof comp_name,
"int_component_%d", int_comp_count);
397 int finest_level = pc.finestLevel();
400 char level_name[128];
403 hid_t dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
404 H5Pset_fill_time(dcpl_id, H5D_FILL_TIME_NEVER);
406 for (
int lev = 0; lev <= finest_level; ++lev) {
407 snprintf(level_name,
sizeof level_name,
"level_%d", lev);
409 grp = H5Gcreate(fid, level_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
411 std::cout <<
"H5Gcreate [" << level_name <<
"] failed!" << std::endl;
416 ngrids = pc.ParticleBoxArray(lev).size();
422 int mfs_size = 2 * AMREX_SPACEDIM;
423 hsize_t mfs_dim = (hsize_t)ngrids;
425 hid_t mfs_dset_space = H5Screate_simple(1, &mfs_dim, NULL);
426 hid_t mfs_dset= H5Dcreate(grp,
"boxes", comp_dtype, mfs_dset_space, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
429 for(
int j = 0; j < pc.ParticleBoxArray(lev).size(); ++j) {
430 for(
int i = 0; i < AMREX_SPACEDIM; ++i) {
431 vbox[(j * mfs_size) + i] = pc.ParticleBoxArray(lev)[j].smallEnd(i);
432 vbox[(j * mfs_size) + i + AMREX_SPACEDIM] = pc.ParticleBoxArray(lev)[j].bigEnd(i);
436 status = H5Dwrite(mfs_dset, comp_dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(vbox[0]));
438 std::string msg(
"ParticleContainer::WriteHDF5ParticleDataSync(): unable to write boxes dataset");
442 H5Sclose(mfs_dset_space);
459 pp.
query(
"particles_nfiles",nOutFiles);
460 if(nOutFiles == -1) nOutFiles = NProcs;
462 pc.nOutFilesPrePost = nOutFiles;
464 fapl = H5Pcreate (H5P_FILE_ACCESS);
471#ifdef AMREX_USE_HDF5_ASYNC
472 fid = H5Fopen_async(HDF5FileName.c_str(), H5F_ACC_RDWR, fapl, es_par_g);
474 fid = H5Fopen(HDF5FileName.c_str(), H5F_ACC_RDWR, fapl);
481 for (
int lev = 0; lev <= pc.finestLevel(); lev++)
483 snprintf(level_name,
sizeof level_name,
"level_%d", lev);
484#ifdef AMREX_USE_HDF5_ASYNC
485 grp = H5Gopen_async(fid, level_name, H5P_DEFAULT, es_par_g);
487 grp = H5Gopen(fid, level_name, H5P_DEFAULT);
492 gotsome = (pc.nParticlesAtLevelPrePost[lev] > 0);
494 gotsome = (pc.NumberOfParticlesAtLevel(lev) > 0);
499 MultiFab state(pc.ParticleBoxArray(lev),
500 pc.ParticleDistributionMap(lev),
510 pc.filePrefixPrePost[lev] = HDF5FileName;
515 pc.WriteParticlesHDF5(lev, grp, which, count, where,
516 write_real_comp, write_int_comp,
518 particle_io_flags, is_checkpoint);
521 pc.whichPrePost[lev] = which;
522 pc.countPrePost[lev] = count;
523 pc.wherePrePost[lev] = where;
531#ifdef AMREX_USE_HDF5_ASYNC
532 H5Gclose_async(grp, es_par_g);
538 H5Tclose(comp_dtype);
541#ifdef AMREX_USE_HDF5_ASYNC
542 H5Fclose_async(fid, es_par_g);