aboutsummaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/Diagnostics/BoostedFrameDiagnostic.H26
-rw-r--r--Source/Diagnostics/BoostedFrameDiagnostic.cpp596
-rw-r--r--Source/Initialization/WarpXInitData.cpp2
-rw-r--r--Source/Make.WarpX11
4 files changed, 609 insertions, 26 deletions
diff --git a/Source/Diagnostics/BoostedFrameDiagnostic.H b/Source/Diagnostics/BoostedFrameDiagnostic.H
index 17f2b161c..e35d307a6 100644
--- a/Source/Diagnostics/BoostedFrameDiagnostic.H
+++ b/Source/Diagnostics/BoostedFrameDiagnostic.H
@@ -6,6 +6,7 @@
#include <AMReX_VisMF.H>
#include <AMReX_PlotFileUtil.H>
#include <AMReX_ParallelDescriptor.H>
+#include <AMReX_Geometry.H>
#include "MultiParticleContainer.H"
#include "WarpXConst.H"
@@ -36,9 +37,13 @@ class BoostedFrameDiagnostic {
amrex::Real current_z_lab;
amrex::Real current_z_boost;
int file_num;
+ int initial_i;
+ const BoostedFrameDiagnostic& my_bfd;
- LabSnapShot(amrex::Real t_lab_in, amrex::Real zmin_lab_in,
- amrex::Real zmax_lab_in, int file_num_in);
+ LabSnapShot(amrex::Real t_lab_in, amrex::Real t_boost,
+ amrex::Real zmin_lab_in,
+ amrex::Real zmax_lab_in, int file_num_in,
+ const BoostedFrameDiagnostic& bfd);
///
/// This snapshot is at time t_lab, and the simulation is at time t_boost.
@@ -64,11 +69,13 @@ class BoostedFrameDiagnostic {
amrex::Real dt_snapshots_lab_;
amrex::Real dt_boost_;
int N_snapshots_;
- int Nz_lab_;
+ unsigned Nx_lab_;
+ unsigned Ny_lab_;
+ unsigned Nz_lab_;
int boost_direction_;
amrex::Vector<std::unique_ptr<amrex::MultiFab> > data_buffer_;
- amrex::Vector<amrex::Vector<WarpXParticleContainer::DiagnosticParticleData> > particles_buffer_;
+ amrex::Vector<amrex::Vector<WarpXParticleContainer::DiagnosticParticleData> > particles_buffer_;
int num_buffer_ = 256;
int max_box_size_ = 256;
amrex::Vector<int> buff_counter_;
@@ -77,13 +84,18 @@ class BoostedFrameDiagnostic {
void writeParticleData(const WarpXParticleContainer::DiagnosticParticleData& pdata,
const std::string& name, const int i_lab);
-
-public:
+#ifdef WARPX_USE_HDF5
+ void writeParticleDataHDF5(const WarpXParticleContainer::DiagnosticParticleData& pdata,
+ const std::string& name, const std::string& species_name);
+#endif
+public:
+
BoostedFrameDiagnostic(amrex::Real zmin_lab, amrex::Real zmax_lab,
amrex::Real v_window_lab, amrex::Real dt_snapshots_lab,
int N_snapshots, amrex::Real gamma_boost,
- amrex::Real t_boost, amrex::Real dt_boost, int boost_direction);
+ amrex::Real t_boost, amrex::Real dt_boost, int boost_direction,
+ const amrex::Geometry& geom);
void Flush(const amrex::Geometry& geom);
diff --git a/Source/Diagnostics/BoostedFrameDiagnostic.cpp b/Source/Diagnostics/BoostedFrameDiagnostic.cpp
index 6c3e3c58a..13972075d 100644
--- a/Source/Diagnostics/BoostedFrameDiagnostic.cpp
+++ b/Source/Diagnostics/BoostedFrameDiagnostic.cpp
@@ -1,15 +1,456 @@
-#include "BoostedFrameDiagnostic.H"
#include <AMReX_MultiFabUtil.H>
+
+#include "BoostedFrameDiagnostic.H"
#include "WarpX_f.H"
#include "WarpX.H"
using namespace amrex;
+#ifdef WARPX_USE_HDF5
+
+#include <hdf5.h>
+
+/*
+ Helper functions for doing the HDF5 IO.
+
+ */
+namespace
+{
+ const std::vector<std::string> particle_field_names = {"w", "x", "y", "z", "ux", "uy", "uz"};
+ const std::vector<std::string> mesh_field_names =
+ {"Ex", "Ey", "Ez", "Bx", "By", "Bz", "jx", "jy", "jz", "rho"};
+
+ /*
+ Creates the HDF5 file in truncate mode and closes it.
+ Should be run only by the root process.
+ */
+ void output_create(const std::string& file_path) {
+ BL_PROFILE("output_create");
+ hid_t file = H5Fcreate(file_path.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ if (file < 0) {
+ amrex::Abort("Error: could not create file at " + file_path);
+ }
+ H5Fclose(file);
+ }
+
+ /*
+ Writes a single string attribute to the given group.
+ Should only be called by the root process.
+ */
+ void write_string_attribute(hid_t& group, const std::string& key, const std::string& val)
+ {
+ hid_t str_type = H5Tcopy(H5T_C_S1);
+ hid_t scalar_space = H5Screate(H5S_SCALAR);
+
+ // Fix the str_type length for the format string.
+ H5Tset_size(str_type, strlen(val.c_str()));
+
+ hid_t attr = H5Acreate(group, key.c_str(), str_type, scalar_space, H5P_DEFAULT, H5P_DEFAULT);
+ H5Awrite(attr, str_type, val.c_str());
+
+ H5Aclose(attr);
+ H5Sclose(scalar_space);
+ H5Tclose(str_type);
+ }
+
+ /*
+ Writes a single double attribute to the given group.
+ Should only be called by the root process.
+ */
+ void write_double_attribute(hid_t& group, const std::string& key, const double val)
+ {
+ hid_t scalar_space = H5Screate(H5S_SCALAR);
+
+ hid_t attr = H5Acreate(group, key.c_str(), H5T_IEEE_F32LE, scalar_space,
+ H5P_DEFAULT, H5P_DEFAULT);
+ H5Awrite(attr, H5T_NATIVE_DOUBLE, &val);
+
+ H5Aclose(attr);
+ H5Sclose(scalar_space);
+ }
+
+ /*
+ Opens the output file and writes all of metadata attributes.
+ Should be run only by the root process.
+ */
+ void output_write_metadata(const std::string& file_path,
+ const int istep, const Real time, const Real dt)
+ {
+ BL_PROFILE("output_write_metadata");
+ hid_t file = H5Fopen(file_path.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
+
+ write_string_attribute(file, "software", "warpx");
+ write_string_attribute(file, "softwareVersion", "0.0.0");
+ write_string_attribute(file, "meshesPath", "fields/");
+ write_string_attribute(file, "iterationEncoding", "fileBased");
+ write_string_attribute(file, "iterationFormat", "data%T.h5");
+ write_string_attribute(file, "openPMD", "1.1.0");
+ write_string_attribute(file, "basePath", "/data/%T/");
+
+ hid_t group = H5Gcreate(file, "data", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ group = H5Gcreate(group, std::to_string(istep).c_str(),
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+
+ write_double_attribute(group, "time", time);
+ write_double_attribute(group, "timeUnitSI", 1.0);
+ write_double_attribute(group, "dt", dt);
+
+ // Field groups
+ group = H5Gcreate(group, "fields", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+
+ // Close all resources.
+ H5Gclose(group);
+ H5Fclose(file);
+ H5close();
+ }
+
+ /*
+ Creates a dataset with the given cell dimensions, at the path
+ "/native_fields/(field_name)".
+ Should be run only by the master rank.
+ */
+ void output_create_field(const std::string& file_path, const std::string& field_path,
+ const unsigned nx, const unsigned ny, const unsigned nz)
+ {
+ BL_PROFILE("output_create_field");
+
+ // Open the output.
+ hid_t file = H5Fopen(file_path.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
+ // Create a 3D, nx x ny x nz dataspace.
+#if (AMREX_SPACEDIM == 3)
+ hsize_t dims[3] = {nx, ny, nz};
+#else
+ hsize_t dims[3] = {nx, nz};
+#endif
+ hid_t grid_space = H5Screate_simple(AMREX_SPACEDIM, dims, NULL);
+
+ // Create the dataset.
+ hid_t dataset = H5Dcreate(file, field_path.c_str(), H5T_IEEE_F64LE,
+ grid_space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+
+ if (dataset < 0)
+ {
+ amrex::Abort("Error: could not create dataset. H5 returned "
+ + std::to_string(dataset) + "\n");
+ }
+
+ // Close resources.
+ H5Dclose(dataset);
+ H5Sclose(grid_space);
+ H5Fclose(file);
+ }
+
+ /*
+ Creates a group associated with a single particle species.
+ Should be run by all processes collectively.
+ */
+ void output_create_species_group(const std::string& file_path, const std::string& species_name)
+ {
+ MPI_Comm comm = MPI_COMM_WORLD;
+ MPI_Info info = MPI_INFO_NULL;
+ int mpi_rank;
+ MPI_Comm_rank(comm, &mpi_rank);
+
+ // Create the file access prop list.
+ hid_t pa_plist = H5Pcreate(H5P_FILE_ACCESS);
+ H5Pset_fapl_mpio(pa_plist, comm, info);
+
+ // Open the output.
+ hid_t file = H5Fopen(file_path.c_str(), H5F_ACC_RDWR, pa_plist);
+
+ hid_t group = H5Gcreate(file, species_name.c_str(),
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ H5Gclose(group);
+ H5Fclose(file);
+
+ }
+
+ /*
+ Resize an extendible dataset, suitable for storing particle data.
+ Should be run only by the master rank.
+ */
+ long output_resize_particle_field(const std::string& file_path, const std::string& field_path,
+ const long num_to_add)
+ {
+ BL_PROFILE("output_resize_particle_field");
+
+ // Open the output.
+ hid_t file = H5Fopen(file_path.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
+
+ int rank;
+ hsize_t dims[1];
+
+ hid_t dataset = H5Dopen2 (file, field_path.c_str(), H5P_DEFAULT);
+ hid_t filespace = H5Dget_space (dataset);
+ rank = H5Sget_simple_extent_ndims (filespace);
+ herr_t status = H5Sget_simple_extent_dims (filespace, dims, NULL);
+
+ // set new size
+ hsize_t new_size[1];
+ new_size[0] = dims[0] + num_to_add;
+ status = H5Dset_extent (dataset, new_size);
+
+ if (status < 0)
+ {
+ amrex::Abort("Error: set extent filed on dataset "
+ + std::to_string(dataset) + "\n");
+ }
+
+ // Close resources.
+ H5Sclose(filespace);
+ H5Dclose(dataset);
+ H5Fclose(file);
+
+ return dims[0];
+ }
+
+ /*
+ Writes to a dataset that has been extended to the proper size. Suitable for writing particle data.
+ Should be run on all ranks collectively.
+ */
+ void output_write_particle_field(const std::string& file_path, const std::string& field_path,
+ const Real* data_ptr, const long count, const long index)
+ {
+ BL_PROFILE("output_write_particle_field");
+
+ MPI_Comm comm = MPI_COMM_WORLD;
+ MPI_Info info = MPI_INFO_NULL;
+ int mpi_rank;
+ MPI_Comm_rank(comm, &mpi_rank);
+
+ // Create the file access prop list.
+ hid_t pa_plist = H5Pcreate(H5P_FILE_ACCESS);
+ H5Pset_fapl_mpio(pa_plist, comm, info);
+
+ // Open the output.
+ hid_t file = H5Fopen(file_path.c_str(), H5F_ACC_RDWR, pa_plist);
+
+ int RANK = 1;
+ hsize_t offset[1];
+ hsize_t dims[1];
+ herr_t status;
+
+ hid_t dataset = H5Dopen (file, field_path.c_str(), H5P_DEFAULT);
+
+ // Make sure the dataset is there.
+ if (dataset < 0)
+ {
+ amrex::Abort("Error on rank " + std::to_string(mpi_rank) +
+ ". Count not find dataset " + field_path + "\n");
+ }
+
+ hid_t filespace = H5Dget_space (dataset);
+
+ offset[0] = index;
+ dims[0] = count;
+
+ // Create collective io prop list.
+ hid_t collective_plist = H5Pcreate(H5P_DATASET_XFER);
+ H5Pset_dxpl_mpio(collective_plist, H5FD_MPIO_INDEPENDENT);
+
+ if (count > 0) {
+
+ /* Define memory space */
+ hid_t memspace = H5Screate_simple (RANK, dims, NULL);
+
+ status = H5Sselect_hyperslab (filespace, H5S_SELECT_SET, offset, NULL,
+ dims, NULL);
+
+ if (status < 0)
+ {
+ amrex::Abort("Error on rank " + std::to_string(ParallelDescriptor::MyProc()) +
+ " could not select hyperslab.\n");
+ }
+
+ /* Write the data to the extended portion of dataset */
+ status = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, memspace,
+ filespace, collective_plist, data_ptr);
+
+ if (status < 0)
+ {
+ amrex::Abort("Error on rank " + std::to_string(ParallelDescriptor::MyProc()) +
+ " could not write hyperslab.\n");
+ }
+
+ status = H5Sclose (memspace);
+ }
+
+ ParallelDescriptor::Barrier();
+
+ // Close resources.
+ H5Pclose(collective_plist);
+ H5Sclose(filespace);
+ H5Dclose(dataset);
+ H5Fclose(file);
+ H5Pclose(pa_plist);
+ }
+
+ /*
+ Creates an extendible dataset, suitable for storing particle data.
+ Should be run on all ranks collectively.
+ */
+ void output_create_particle_field(const std::string& file_path, const std::string& field_path)
+ {
+ BL_PROFILE("output_create_particle_field");
+
+ MPI_Comm comm = MPI_COMM_WORLD;
+ MPI_Info info = MPI_INFO_NULL;
+ int mpi_rank;
+ MPI_Comm_rank(comm, &mpi_rank);
+
+ // Create the file access prop list.
+ hid_t pa_plist = H5Pcreate(H5P_FILE_ACCESS);
+ H5Pset_fapl_mpio(pa_plist, comm, info);
+
+ // Open the output.
+ hid_t file = H5Fopen(file_path.c_str(), H5F_ACC_RDWR, pa_plist);
+
+ constexpr int RANK = 1;
+ hsize_t dims[1] = {0};
+ hsize_t maxdims[1] = {H5S_UNLIMITED};
+ hsize_t chunk_dims[2] = {4};
+
+ hid_t dataspace = H5Screate_simple (RANK, dims, maxdims);
+
+ // Enable chunking
+ hid_t prop = H5Pcreate (H5P_DATASET_CREATE);
+ herr_t status = H5Pset_chunk (prop, RANK, chunk_dims);
+
+ hid_t dataset = H5Dcreate2 (file, field_path.c_str(), H5T_NATIVE_DOUBLE, dataspace,
+ H5P_DEFAULT, prop, H5P_DEFAULT);
+
+ if (dataset < 0)
+ {
+ amrex::Abort("Error: could not create dataset. H5 returned "
+ + std::to_string(dataset) + "\n");
+ }
+
+ // Close resources.
+ H5Dclose(dataset);
+ H5Pclose(prop);
+ H5Sclose(dataspace);
+ H5Fclose(file);
+ }
+
+ /*
+ Write the only component in the multifab to the dataset given by field_name.
+ Uses hdf5-parallel.
+ */
+ void output_write_field(const std::string& file_path,
+ const std::string& field_path,
+ const MultiFab& mf, const int comp)
+ {
+
+ BL_PROFILE("output_write_field");
+
+ MPI_Comm comm = MPI_COMM_WORLD;
+ MPI_Info info = MPI_INFO_NULL;
+ int mpi_rank;
+ MPI_Comm_rank(comm, &mpi_rank);
+
+ // Create the file access prop list.
+ hid_t pa_plist = H5Pcreate(H5P_FILE_ACCESS);
+ H5Pset_fapl_mpio(pa_plist, comm, info);
+
+ // Open the file, and the group.
+ hid_t file = H5Fopen(file_path.c_str(), H5F_ACC_RDWR, pa_plist);
+ // Open the field dataset.
+ hid_t dataset = H5Dopen(file, field_path.c_str(), H5P_DEFAULT);
+
+ // Make sure the dataset is there.
+ if (dataset < 0)
+ {
+ amrex::Abort("Error on rank " + std::to_string(mpi_rank) +
+ ". Count not find dataset " + field_path + "\n");
+ }
+
+ // Grab the dataspace of the field dataset from file.
+ hid_t file_dataspace = H5Dget_space(dataset);
+
+ // Create collective io prop list.
+ hid_t collective_plist = H5Pcreate(H5P_DATASET_XFER);
+ H5Pset_dxpl_mpio(collective_plist, H5FD_MPIO_INDEPENDENT);
+
+ // Iterate over Fabs, select matching hyperslab and write.
+ hid_t status;
+ // slab lo index and shape.
+#if (AMREX_SPACEDIM == 3)
+ hsize_t slab_offsets[3], slab_dims[3];
+#else
+ hsize_t slab_offsets[2], slab_dims[2];
+#endif
+ hid_t slab_dataspace;
+
+ int write_count = 0;
+
+ std::vector<Real> transposed_data;
+
+ for (MFIter mfi(mf); mfi.isValid(); ++mfi)
+ {
+ const Box& box = mfi.validbox();
+ const int *lo_vec = box.loVect();
+ const int *hi_vec = box.hiVect();
+
+ transposed_data.resize(box.numPts(), 0.0);
+
+ // Set slab offset and shape.
+ for (int idim = 0; idim < AMREX_SPACEDIM; ++idim)
+ {
+ AMREX_ASSERT(lo_vec[idim] >= 0);
+ AMREX_ASSERT(hi_vec[idim] > lo_vec[idim]);
+ slab_offsets[idim] = lo_vec[idim];
+ slab_dims[idim] = hi_vec[idim] - lo_vec[idim] + 1;
+ }
+
+ int cnt = 0;
+ AMREX_D_TERM(
+ for (int i = lo_vec[0]; i <= hi_vec[0]; ++i),
+ for (int j = lo_vec[1]; j <= hi_vec[1]; ++j),
+ for (int k = lo_vec[2]; k <= hi_vec[2]; ++k))
+ transposed_data[cnt++] = mf[mfi](IntVect(AMREX_D_DECL(i, j, k)), comp);
+
+ // Create the slab space.
+ slab_dataspace = H5Screate_simple(AMREX_SPACEDIM, slab_dims, NULL);
+
+ // Select the hyperslab matching this fab.
+ status = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET,
+ slab_offsets, NULL, slab_dims, NULL);
+ if (status < 0)
+ {
+ amrex::Abort("Error on rank " + std::to_string(mpi_rank) +
+ " could not select hyperslab.\n");
+ }
+
+ // Write this pencil.
+ status = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, slab_dataspace,
+ file_dataspace, collective_plist, transposed_data.data());
+ if (status < 0)
+ {
+ amrex::Abort("Error on rank " + std::to_string(mpi_rank) +
+ " could not write hyperslab.\n");
+ }
+
+ H5Sclose(slab_dataspace);
+ write_count++;
+ }
+
+ ParallelDescriptor::Barrier();
+
+ // Close HDF5 resources.
+ H5Pclose(collective_plist);
+ H5Sclose(file_dataspace);
+ H5Dclose(dataset);
+ H5Fclose(file);
+ H5Pclose(pa_plist);
+ }
+}
+#endif
+
BoostedFrameDiagnostic::
BoostedFrameDiagnostic(Real zmin_lab, Real zmax_lab, Real v_window_lab,
Real dt_snapshots_lab, int N_snapshots,
Real gamma_boost, Real t_boost, Real dt_boost,
- int boost_direction)
+ int boost_direction, const Geometry& geom)
: gamma_boost_(gamma_boost),
dt_snapshots_lab_(dt_snapshots_lab),
dt_boost_(dt_boost),
@@ -28,17 +469,23 @@ BoostedFrameDiagnostic(Real zmin_lab, Real zmax_lab, Real v_window_lab,
dz_lab_ = PhysConst::c * dt_boost_ * inv_beta_boost_ * inv_gamma_boost_;
inv_dz_lab_ = 1.0 / dz_lab_;
- Nz_lab_ = static_cast<int>((zmax_lab - zmin_lab) * inv_dz_lab_);
-
+ Nx_lab_ = geom.Domain().length(0);
+#if (AMREX_SPACEDIM == 3)
+ Ny_lab_ = geom.Domain().length(1);
+#else
+ Ny_lab_ = 1;
+#endif
+ Nz_lab_ = static_cast<unsigned>((zmax_lab - zmin_lab) * inv_dz_lab_);
+
writeMetaData();
if (WarpX::do_boosted_frame_fields) data_buffer_.resize(N_snapshots);
if (WarpX::do_boosted_frame_particles) particles_buffer_.resize(N_snapshots);
for (int i = 0; i < N_snapshots; ++i) {
Real t_lab = i * dt_snapshots_lab_;
- LabSnapShot snapshot(t_lab, zmin_lab + v_window_lab * t_lab,
- zmax_lab + v_window_lab * t_lab, i);
- snapshot.updateCurrentZPositions(t_boost, inv_gamma_boost_, inv_beta_boost_);
+ LabSnapShot snapshot(t_lab, t_boost,
+ zmin_lab + v_window_lab * t_lab,
+ zmax_lab + v_window_lab * t_lab, i, *this);
snapshots_.push_back(snapshot);
buff_counter_.push_back(0);
if (WarpX::do_boosted_frame_fields) data_buffer_[i].reset( nullptr );
@@ -80,17 +527,28 @@ void BoostedFrameDiagnostic::Flush(const Geometry& geom)
MultiFab tmp(buff_ba, buff_dm, ncomp, 0);
tmp.copy(*data_buffer_[i], 0, 0, ncomp);
-
+
+#ifdef WARPX_USE_HDF5
+ for (int comp = 0; comp < ncomp; ++comp)
+ output_write_field(snapshots_[i].file_name, mesh_field_names[comp], tmp, comp);
+#else
std::stringstream ss;
ss << snapshots_[i].file_name << "/Level_0/" << Concatenate("buffer", i_lab, 5);
VisMF::Write(tmp, ss.str());
+#endif
}
if (WarpX::do_boosted_frame_particles) {
for (int j = 0; j < mypc.nSpecies(); ++j) {
+#ifdef WARPX_USE_HDF5
+ writeParticleDataHDF5(particles_buffer_[i][j],
+ snapshots_[i].file_name,
+ species_names[j]);
+#else
std::stringstream part_ss;
part_ss << snapshots_[i].file_name + "/" + species_names[j] + "/";
writeParticleData(particles_buffer_[i][j], part_ss.str(), i_lab);
+#endif
}
particles_buffer_[i].clear();
}
@@ -196,16 +654,28 @@ writeLabFrameData(const MultiFab* cell_centered_data,
if (buff_counter_[i] == num_buffer_) {
if (WarpX::do_boosted_frame_fields) {
+#ifdef WARPX_USE_HDF5
+ for (int comp = 0; comp < data_buffer_[i]->nComp(); ++comp)
+ output_write_field(snapshots_[i].file_name, mesh_field_names[comp],
+ *data_buffer_[i], comp);
+#else
std::stringstream mesh_ss;
mesh_ss << snapshots_[i].file_name << "/Level_0/" << Concatenate("buffer", i_lab, 5);
VisMF::Write(*data_buffer_[i], mesh_ss.str());
+#endif
}
if (WarpX::do_boosted_frame_particles) {
for (int j = 0; j < mypc.nSpecies(); ++j) {
+#ifdef WARPX_USE_HDF5
+ writeParticleDataHDF5(particles_buffer_[i][j],
+ snapshots_[i].file_name,
+ species_names[j]);
+#else
std::stringstream part_ss;
part_ss << snapshots_[i].file_name + "/" + species_names[j] + "/";
writeParticleData(particles_buffer_[i][j], part_ss.str(), i_lab);
+#endif
}
particles_buffer_[i].clear();
}
@@ -216,10 +686,57 @@ writeLabFrameData(const MultiFab* cell_centered_data,
VisMF::SetHeaderVersion(current_version);
}
+#ifdef WARPX_USE_HDF5
void
BoostedFrameDiagnostic::
-writeParticleData(const WarpXParticleContainer::DiagnosticParticleData& pdata, const std::string& name,
- const int i_lab)
+writeParticleDataHDF5(const WarpXParticleContainer::DiagnosticParticleData& pdata,
+ const std::string& name, const std::string& species_name)
+{
+ auto np = pdata.GetRealData(DiagIdx::w).size();
+
+ Vector<long> particle_counts(ParallelDescriptor::NProcs(), 0);
+ Vector<long> particle_offsets(ParallelDescriptor::NProcs(), 0);
+
+ ParallelAllGather::AllGather(np, particle_counts.data(), ParallelContext::CommunicatorAll());
+
+ long total_np = 0;
+ for (int i = 0; i < ParallelDescriptor::NProcs(); ++i) {
+ particle_offsets[i] = total_np;
+ total_np += particle_counts[i];
+ }
+
+ if (total_np == 0) return;
+
+ long old_np = 0;
+ if (ParallelDescriptor::IOProcessor())
+ {
+ for (int k = 0; k < static_cast<int>(particle_field_names.size()); ++k)
+ {
+ std::string field_path = species_name + "/" + particle_field_names[k];
+ old_np = output_resize_particle_field(name, field_path, total_np);
+ }
+ }
+
+ // Note, this has the effect of an MPI Barrier between the above resize operation
+ // and the below write.
+ ParallelDescriptor::ReduceLongMax(old_np);
+
+ // Write data here
+ for (int k = 0; k < static_cast<int>(particle_field_names.size()); ++k)
+ {
+ std::string field_path = species_name + "/" + particle_field_names[k];
+ output_write_particle_field(name, field_path,
+ pdata.GetRealData(k).data(),
+ particle_counts[ParallelDescriptor::MyProc()],
+ particle_offsets[ParallelDescriptor::MyProc()] + old_np);
+ }
+}
+#endif
+
+void
+BoostedFrameDiagnostic::
+writeParticleData(const WarpXParticleContainer::DiagnosticParticleData& pdata,
+ const std::string& name, const int i_lab)
{
BL_PROFILE("BoostedFrameDiagnostic::writeParticleData");
@@ -230,7 +747,7 @@ writeParticleData(const WarpXParticleContainer::DiagnosticParticleData& pdata, c
auto np = pdata.GetRealData(DiagIdx::w).size();
if (np == 0) return;
-
+
field_name = name + Concatenate("w_", i_lab, 5) + "_" + std::to_string(MyProc);
ofs.open(field_name.c_str(), std::ios::out|std::ios::binary);
writeRealData(pdata.GetRealData(DiagIdx::w).data(), np, ofs);
@@ -264,12 +781,12 @@ writeParticleData(const WarpXParticleContainer::DiagnosticParticleData& pdata, c
field_name = name + Concatenate("uz_", i_lab, 5) + "_" + std::to_string(MyProc);
ofs.open(field_name.c_str(), std::ios::out|std::ios::binary);
writeRealData(pdata.GetRealData(DiagIdx::uz).data(), np, ofs);
- ofs.close();
+ ofs.close();
}
void
BoostedFrameDiagnostic::
-writeMetaData()
+writeMetaData ()
{
BL_PROFILE("BoostedFrameDiagnostic::writeMetaData");
@@ -301,17 +818,58 @@ writeMetaData()
}
BoostedFrameDiagnostic::LabSnapShot::
-LabSnapShot(Real t_lab_in, Real zmin_lab_in,
- Real zmax_lab_in, int file_num_in)
+LabSnapShot(Real t_lab_in, Real t_boost, Real zmin_lab_in,
+ Real zmax_lab_in, int file_num_in, const BoostedFrameDiagnostic& bfd)
: t_lab(t_lab_in),
zmin_lab(zmin_lab_in),
zmax_lab(zmax_lab_in),
- file_num(file_num_in)
+ file_num(file_num_in),
+ my_bfd(bfd)
{
current_z_lab = 0.0;
current_z_boost = 0.0;
+ updateCurrentZPositions(t_boost, my_bfd.inv_gamma_boost_, my_bfd.inv_beta_boost_);
+ initial_i = (current_z_lab - zmin_lab) / my_bfd.dz_lab_;
file_name = Concatenate("lab_frame_data/snapshot", file_num, 5);
+
+#ifdef WARPX_USE_HDF5
+ if (ParallelDescriptor::IOProcessor())
+ {
+ output_create(file_name);
+ }
+
+ ParallelDescriptor::Barrier();
+ if (ParallelDescriptor::IOProcessor())
+ {
+ if (WarpX::do_boosted_frame_fields)
+ {
+ for (int comp = 0; comp < static_cast<int>(mesh_field_names.size()); ++comp) {
+ output_create_field(file_name, mesh_field_names[comp],
+ my_bfd.Nx_lab_,
+ my_bfd.Ny_lab_,
+ my_bfd.Nz_lab_+1);
+ }
+ }
+ }
+
+ ParallelDescriptor::Barrier();
+
+ if (WarpX::do_boosted_frame_particles)
+ {
+ auto & mypc = WarpX::GetInstance().GetPartContainer();
+ const std::vector<std::string> species_names = mypc.GetSpeciesNames();
+ for (int j = 0; j < mypc.nSpecies(); ++j)
+ {
+ output_create_species_group(file_name, species_names[j]);
+ for (int k = 0; k < static_cast<int>(particle_field_names.size()); ++k)
+ {
+ std::string field_path = species_names[j] + "/" + particle_field_names[k];
+ output_create_particle_field(file_name, field_path);
+ }
+ }
+ }
+#else
if (ParallelDescriptor::IOProcessor()) {
if (!UtilCreateDirectory(file_name, 0755))
@@ -335,10 +893,10 @@ LabSnapShot(Real t_lab_in, Real zmin_lab_in,
CreateDirectoryFailed(fullpath);
}
}
-
+#endif
ParallelDescriptor::Barrier();
- if (ParallelDescriptor::IOProcessor()) writeSnapShotHeader();
+ writeSnapShotHeader();
}
void
@@ -351,6 +909,7 @@ updateCurrentZPositions(Real t_boost, Real inv_gamma, Real inv_beta) {
void
BoostedFrameDiagnostic::LabSnapShot::
writeSnapShotHeader() {
+#ifndef WARPX_USE_HDF5
if (ParallelDescriptor::IOProcessor()) {
VisMF::IO_Buffer io_buffer(VisMF::IO_Buffer_Size);
std::ofstream HeaderFile;
@@ -368,4 +927,5 @@ writeSnapShotHeader() {
HeaderFile << zmin_lab << "\n";
HeaderFile << zmax_lab << "\n";
}
+#endif
}
diff --git a/Source/Initialization/WarpXInitData.cpp b/Source/Initialization/WarpXInitData.cpp
index 9190b5a61..23637ec97 100644
--- a/Source/Initialization/WarpXInitData.cpp
+++ b/Source/Initialization/WarpXInitData.cpp
@@ -97,7 +97,7 @@ WarpX::InitDiagnostics () {
moving_window_v, dt_snapshots_lab,
num_snapshots_lab, gamma_boost,
t_new[0], dt_boost,
- moving_window_dir));
+ moving_window_dir, geom[0]));
}
}
diff --git a/Source/Make.WarpX b/Source/Make.WarpX
index 232d559e6..73d4e4cc5 100644
--- a/Source/Make.WarpX
+++ b/Source/Make.WarpX
@@ -100,6 +100,17 @@ ifeq ($(DO_ELECTROSTATIC),TRUE)
DEFINES += -DWARPX_DO_ELECTROSTATIC
endif
+ifeq ($(USE_HDF5),TRUE)
+ HDF5_HOME ?= NOT_SET
+ ifneq ($(HDF5_HOME),NOT_SET)
+ VPATH_LOCATIONS += $(HDF5_HOME)/include
+ INCLUDE_LOCATIONS += $(HDF5_HOME)/include
+ LIBRARY_LOCATIONS += $(HDF5_HOME)/lib
+ endif
+ DEFINES += -DWARPX_USE_HDF5
+ LIBRARIES += -lhdf5 -lz
+endif
+
# job_info support
CEXE_sources += AMReX_buildInfo.cpp
CEXE_headers += $(AMREX_HOME)/Tools/C_scripts/AMReX_buildInfo.H