185 const std::string& dir,
const std::string& name,
190 const std::string& compression,
191 F&& f,
bool is_checkpoint)
196 AMREX_ASSERT(
sizeof(
typename PC::ParticleType::RealType) == 4 ||
197 sizeof(
typename PC::ParticleType::RealType) == 8);
199 constexpr int NStructReal = PC::NStructReal;
200 constexpr int NStructInt = PC::NStructInt;
206 int nrc = PC::ParticleType::is_soa_particle ?
207 pc.NumRealComps() + NStructReal - AMREX_SPACEDIM : pc.NumRealComps() + NStructReal;
212#ifdef AMREX_USE_HDF5_ASYNC
215 async_vol_es_wait_particle();
218 es_par_g = H5EScreate();
222 std::string pdir = dir;
223 if ( ! pdir.empty() && pdir[pdir.size()-1] !=
'/') { pdir +=
'/'; }
226 if ( ! pc.GetLevelDirectoriesCreated()) {
238 hid_t fid, grp, fapl, comp_dtype;
244 comp_dtype = H5Tcreate (H5T_COMPOUND, 2 * AMREX_SPACEDIM *
sizeof(
int));
245 if (1 == AMREX_SPACEDIM) {
246 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
247 H5Tinsert (comp_dtype,
"hi_i", 1 *
sizeof(
int), H5T_NATIVE_INT);
249 else if (2 == AMREX_SPACEDIM) {
250 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
251 H5Tinsert (comp_dtype,
"lo_j", 1 *
sizeof(
int), H5T_NATIVE_INT);
252 H5Tinsert (comp_dtype,
"hi_i", 2 *
sizeof(
int), H5T_NATIVE_INT);
253 H5Tinsert (comp_dtype,
"hi_j", 3 *
sizeof(
int), H5T_NATIVE_INT);
255 else if (3 == AMREX_SPACEDIM) {
256 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
257 H5Tinsert (comp_dtype,
"lo_j", 1 *
sizeof(
int), H5T_NATIVE_INT);
258 H5Tinsert (comp_dtype,
"lo_k", 2 *
sizeof(
int), H5T_NATIVE_INT);
259 H5Tinsert (comp_dtype,
"hi_i", 3 *
sizeof(
int), H5T_NATIVE_INT);
260 H5Tinsert (comp_dtype,
"hi_j", 4 *
sizeof(
int), H5T_NATIVE_INT);
261 H5Tinsert (comp_dtype,
"hi_k", 5 *
sizeof(
int), H5T_NATIVE_INT);
266 particle_io_flags(pc.GetParticles().size());
267 for (
int lev = 0; lev < std::ssize(pc.GetParticles()); lev++)
269 const auto& pmap = pc.GetParticles(lev);
270 for (
const auto& kv : pmap)
272 auto& flags = particle_io_flags[lev][kv.first];
273 particle_detail::fillFlags(flags, kv.second, f);
279 if(pc.GetUsePrePost())
281 nparticles = pc.GetNParticlesPrePost();
282 maxnextid = pc.GetMaxNextIDPrePost();
286 nparticles = particle_detail::countFlags(particle_io_flags, pc);
287 maxnextid = PC::ParticleType::NextID();
289 PC::ParticleType::NextID(maxnextid);
293 std::string HDF5FileName = pdir;
294 if ( ! HDF5FileName.empty() && HDF5FileName[HDF5FileName.size()-1] !=
'/')
297 HDF5FileName += name;
298 HDF5FileName +=
".h5";
299 pc.HdrFileNamePrePost = HDF5FileName;
306 char setstripe[1024];
307 int stripe_count = 128;
309 char *stripe_count_str = getenv(
"HDF5_STRIPE_COUNT");
310 char *stripe_size_str = getenv(
"HDF5_STRIPE_SIZE");
311 if (stripe_count_str) {
312 stripe_count = atoi(stripe_count_str);
315 if (stripe_size_str) {
316 stripe_size = atoi(stripe_size_str);
319 if (set_stripe == 1) {
320 snprintf(setstripe,
sizeof setstripe,
"lfs setstripe -c %d -S %dm %s", stripe_count, stripe_size, pdir.c_str());
321 std::cout <<
"Setting stripe parameters for HDF5 output: " << setstripe << std::endl;
325 fid = H5Fcreate(HDF5FileName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
334 std::string versionName = is_checkpoint ? PC::CheckpointVersion() : PC::PlotfileVersion();
335 if (
sizeof(
typename PC::ParticleType::RealType) == 4) {
336 versionName +=
"_single";
338 versionName +=
"_double";
343 int num_output_real = 0;
344 for (
int i = 0; i < std::ssize(write_real_comp); ++i) {
345 if (write_real_comp[i]) { ++num_output_real; }
348 int num_output_int = 0;
349 for (
int i = 0; i < pc.NumIntComps() + NStructInt; ++i) {
350 if (write_int_comp[i]) { ++num_output_int; }
354 int ndim = AMREX_SPACEDIM;
355 grp = H5Gcreate(fid,
"Chombo_global", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
360 int ncomp = num_output_real + num_output_int;
367 int real_comp_count = AMREX_SPACEDIM;
369 for (
int i = 0; i < std::ssize(write_real_comp); ++i ) {
370 if (write_real_comp[i]) {
372 snprintf(comp_name,
sizeof comp_name,
"real_component_%d", real_comp_count);
382 int int_comp_count = 2;
384 for (
int i = 0; i < NStructInt + pc.NumIntComps(); ++i ) {
385 if (write_int_comp[i]) {
386 snprintf(comp_name,
sizeof comp_name,
"int_component_%d", int_comp_count);
399 int finest_level = pc.finestLevel();
402 char level_name[128];
405 hid_t dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
406 H5Pset_fill_time(dcpl_id, H5D_FILL_TIME_NEVER);
408 for (
int lev = 0; lev <= finest_level; ++lev) {
409 snprintf(level_name,
sizeof level_name,
"level_%d", lev);
411 grp = H5Gcreate(fid, level_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
413 std::cout <<
"H5Gcreate [" << level_name <<
"] failed!" << std::endl;
418 ngrids = pc.ParticleBoxArray(lev).size();
424 int mfs_size = 2 * AMREX_SPACEDIM;
425 hsize_t mfs_dim = (hsize_t)ngrids;
427 hid_t mfs_dset_space = H5Screate_simple(1, &mfs_dim, NULL);
428 hid_t mfs_dset= H5Dcreate(grp,
"boxes", comp_dtype, mfs_dset_space, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
431 for(
int j = 0; j < pc.ParticleBoxArray(lev).size(); ++j) {
432 for(
int i = 0; i < AMREX_SPACEDIM; ++i) {
433 vbox[(j * mfs_size) + i] = pc.ParticleBoxArray(lev)[j].smallEnd(i);
434 vbox[(j * mfs_size) + i + AMREX_SPACEDIM] = pc.ParticleBoxArray(lev)[j].bigEnd(i);
438 status = H5Dwrite(mfs_dset, comp_dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(vbox[0]));
440 std::string msg(
"ParticleContainer::WriteHDF5ParticleDataSync(): unable to write boxes dataset");
444 H5Sclose(mfs_dset_space);
461 pp.
query(
"particles_nfiles",nOutFiles);
462 if(nOutFiles == -1) nOutFiles = NProcs;
464 pc.nOutFilesPrePost = nOutFiles;
466 fapl = H5Pcreate (H5P_FILE_ACCESS);
473#ifdef AMREX_USE_HDF5_ASYNC
474 fid = H5Fopen_async(HDF5FileName.c_str(), H5F_ACC_RDWR, fapl, es_par_g);
476 fid = H5Fopen(HDF5FileName.c_str(), H5F_ACC_RDWR, fapl);
483 for (
int lev = 0; lev <= pc.finestLevel(); lev++)
485 snprintf(level_name,
sizeof level_name,
"level_%d", lev);
486#ifdef AMREX_USE_HDF5_ASYNC
487 grp = H5Gopen_async(fid, level_name, H5P_DEFAULT, es_par_g);
489 grp = H5Gopen(fid, level_name, H5P_DEFAULT);
494 gotsome = (pc.nParticlesAtLevelPrePost[lev] > 0);
496 gotsome = (pc.NumberOfParticlesAtLevel(lev) > 0);
501 MultiFab state(pc.ParticleBoxArray(lev),
502 pc.ParticleDistributionMap(lev),
512 pc.filePrefixPrePost[lev] = HDF5FileName;
517 pc.WriteParticlesHDF5(lev, grp, which, count, where,
518 write_real_comp, write_int_comp,
520 particle_io_flags, is_checkpoint);
523 pc.whichPrePost[lev] = which;
524 pc.countPrePost[lev] = count;
525 pc.wherePrePost[lev] = where;
533#ifdef AMREX_USE_HDF5_ASYNC
534 H5Gclose_async(grp, es_par_g);
540 H5Tclose(comp_dtype);
543#ifdef AMREX_USE_HDF5_ASYNC
544 H5Fclose_async(fid, es_par_g);