186 const std::string& dir,
const std::string& name,
191 const std::string& compression,
192 F&& f,
bool is_checkpoint)
197 AMREX_ASSERT(
sizeof(
typename PC::ParticleType::RealType) == 4 ||
198 sizeof(
typename PC::ParticleType::RealType) == 8);
200 constexpr int NStructReal = PC::NStructReal;
201 constexpr int NStructInt = PC::NStructInt;
207 int nrc = PC::ParticleType::is_soa_particle ?
208 pc.NumRealComps() + NStructReal - AMREX_SPACEDIM : pc.NumRealComps() + NStructReal;
213#ifdef AMREX_USE_HDF5_ASYNC
216 async_vol_es_wait_particle();
219 es_par_g = H5EScreate();
223 std::string pdir = dir;
224 if ( ! pdir.empty() && pdir[pdir.size()-1] !=
'/') { pdir +=
'/'; }
227 if ( ! pc.GetLevelDirectoriesCreated()) {
239 hid_t fid, grp, fapl, comp_dtype;
245 comp_dtype = H5Tcreate (H5T_COMPOUND, 2 * AMREX_SPACEDIM *
sizeof(
int));
246 if (1 == AMREX_SPACEDIM) {
247 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
248 H5Tinsert (comp_dtype,
"hi_i", 1 *
sizeof(
int), H5T_NATIVE_INT);
250 else if (2 == AMREX_SPACEDIM) {
251 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
252 H5Tinsert (comp_dtype,
"lo_j", 1 *
sizeof(
int), H5T_NATIVE_INT);
253 H5Tinsert (comp_dtype,
"hi_i", 2 *
sizeof(
int), H5T_NATIVE_INT);
254 H5Tinsert (comp_dtype,
"hi_j", 3 *
sizeof(
int), H5T_NATIVE_INT);
256 else if (3 == AMREX_SPACEDIM) {
257 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
258 H5Tinsert (comp_dtype,
"lo_j", 1 *
sizeof(
int), H5T_NATIVE_INT);
259 H5Tinsert (comp_dtype,
"lo_k", 2 *
sizeof(
int), H5T_NATIVE_INT);
260 H5Tinsert (comp_dtype,
"hi_i", 3 *
sizeof(
int), H5T_NATIVE_INT);
261 H5Tinsert (comp_dtype,
"hi_j", 4 *
sizeof(
int), H5T_NATIVE_INT);
262 H5Tinsert (comp_dtype,
"hi_k", 5 *
sizeof(
int), H5T_NATIVE_INT);
267 particle_io_flags(pc.GetParticles().size());
268 for (
int lev = 0; lev < std::ssize(pc.GetParticles()); lev++)
270 const auto& pmap = pc.GetParticles(lev);
271 for (
const auto& kv : pmap)
273 auto& flags = particle_io_flags[lev][kv.first];
274 if constexpr (PC::has_polymorphic_allocator) {
275 flags.setArena(pc.arena());
277 particle_detail::fillFlags(flags, kv.second, f);
283 if(pc.GetUsePrePost())
285 nparticles = pc.GetNParticlesPrePost();
286 maxnextid = pc.GetMaxNextIDPrePost();
290 nparticles = particle_detail::countFlags(particle_io_flags, pc);
291 maxnextid = PC::ParticleType::NextID();
293 PC::ParticleType::NextID(maxnextid);
297 std::string HDF5FileName = pdir;
298 if ( ! HDF5FileName.empty() && HDF5FileName[HDF5FileName.size()-1] !=
'/')
301 HDF5FileName += name;
302 HDF5FileName +=
".h5";
303 pc.HdrFileNamePrePost = HDF5FileName;
310 char setstripe[1024];
311 int stripe_count = 128;
313 char *stripe_count_str = getenv(
"HDF5_STRIPE_COUNT");
314 char *stripe_size_str = getenv(
"HDF5_STRIPE_SIZE");
315 if (stripe_count_str) {
316 stripe_count = atoi(stripe_count_str);
319 if (stripe_size_str) {
320 stripe_size = atoi(stripe_size_str);
323 if (set_stripe == 1) {
324 snprintf(setstripe,
sizeof setstripe,
"lfs setstripe -c %d -S %dm %s", stripe_count, stripe_size, pdir.c_str());
325 std::cout <<
"Setting stripe parameters for HDF5 output: " << setstripe << std::endl;
329 fid = H5Fcreate(HDF5FileName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
338 std::string versionName = is_checkpoint ? PC::CheckpointVersion() : PC::PlotfileVersion();
339 if (
sizeof(
typename PC::ParticleType::RealType) == 4) {
340 versionName +=
"_single";
342 versionName +=
"_double";
347 int num_output_real = 0;
348 for (
int i = 0; i < std::ssize(write_real_comp); ++i) {
349 if (write_real_comp[i]) { ++num_output_real; }
352 int num_output_int = 0;
353 for (
int i = 0; i < pc.NumIntComps() + NStructInt; ++i) {
354 if (write_int_comp[i]) { ++num_output_int; }
358 int ndim = AMREX_SPACEDIM;
359 grp = H5Gcreate(fid,
"Chombo_global", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
364 int ncomp = num_output_real + num_output_int;
371 int real_comp_count = AMREX_SPACEDIM;
373 for (
int i = 0; i < std::ssize(write_real_comp); ++i ) {
374 if (write_real_comp[i]) {
376 snprintf(comp_name,
sizeof comp_name,
"real_component_%d", real_comp_count);
386 int int_comp_count = 2;
388 for (
int i = 0; i < NStructInt + pc.NumIntComps(); ++i ) {
389 if (write_int_comp[i]) {
390 snprintf(comp_name,
sizeof comp_name,
"int_component_%d", int_comp_count);
403 int finest_level = pc.finestLevel();
406 char level_name[128];
409 hid_t dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
410 H5Pset_fill_time(dcpl_id, H5D_FILL_TIME_NEVER);
412 for (
int lev = 0; lev <= finest_level; ++lev) {
413 snprintf(level_name,
sizeof level_name,
"level_%d", lev);
415 grp = H5Gcreate(fid, level_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
417 std::cout <<
"H5Gcreate [" << level_name <<
"] failed!" << std::endl;
422 ngrids = pc.ParticleBoxArray(lev).size();
428 int mfs_size = 2 * AMREX_SPACEDIM;
429 hsize_t mfs_dim = (hsize_t)ngrids;
431 hid_t mfs_dset_space = H5Screate_simple(1, &mfs_dim, NULL);
432 hid_t mfs_dset= H5Dcreate(grp,
"boxes", comp_dtype, mfs_dset_space, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
435 for(
int j = 0; j < pc.ParticleBoxArray(lev).size(); ++j) {
436 for(
int i = 0; i < AMREX_SPACEDIM; ++i) {
437 vbox[(j * mfs_size) + i] = pc.ParticleBoxArray(lev)[j].smallEnd(i);
438 vbox[(j * mfs_size) + i + AMREX_SPACEDIM] = pc.ParticleBoxArray(lev)[j].bigEnd(i);
442 status = H5Dwrite(mfs_dset, comp_dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(vbox[0]));
444 std::string msg(
"ParticleContainer::WriteHDF5ParticleDataSync(): unable to write boxes dataset");
448 H5Sclose(mfs_dset_space);
465 pp.
query(
"particles_nfiles",nOutFiles);
466 if(nOutFiles == -1) nOutFiles = NProcs;
468 pc.nOutFilesPrePost = nOutFiles;
470 fapl = H5Pcreate (H5P_FILE_ACCESS);
477#ifdef AMREX_USE_HDF5_ASYNC
478 fid = H5Fopen_async(HDF5FileName.c_str(), H5F_ACC_RDWR, fapl, es_par_g);
480 fid = H5Fopen(HDF5FileName.c_str(), H5F_ACC_RDWR, fapl);
487 for (
int lev = 0; lev <= pc.finestLevel(); lev++)
489 snprintf(level_name,
sizeof level_name,
"level_%d", lev);
490#ifdef AMREX_USE_HDF5_ASYNC
491 grp = H5Gopen_async(fid, level_name, H5P_DEFAULT, es_par_g);
493 grp = H5Gopen(fid, level_name, H5P_DEFAULT);
498 gotsome = (pc.nParticlesAtLevelPrePost[lev] > 0);
500 gotsome = (pc.NumberOfParticlesAtLevel(lev) > 0);
505 MultiFab state(pc.ParticleBoxArray(lev),
506 pc.ParticleDistributionMap(lev),
516 pc.filePrefixPrePost[lev] = HDF5FileName;
521 pc.WriteParticlesHDF5(lev, grp, which, count, where,
522 write_real_comp, write_int_comp,
524 particle_io_flags, is_checkpoint);
527 pc.whichPrePost[lev] = which;
528 pc.countPrePost[lev] = count;
529 pc.wherePrePost[lev] = where;
537#ifdef AMREX_USE_HDF5_ASYNC
538 H5Gclose_async(grp, es_par_g);
544 H5Tclose(comp_dtype);
547#ifdef AMREX_USE_HDF5_ASYNC
548 H5Fclose_async(fid, es_par_g);