aboutsummaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/Diagnostics/FieldIO.cpp12
-rw-r--r--Source/Diagnostics/WarpXIO.cpp19
-rw-r--r--Source/Diagnostics/WarpXOpenPMD.cpp72
-rw-r--r--Source/Evolve/WarpXEvolveEM.cpp10
-rw-r--r--Source/Parallelization/GuardCellManager.cpp4
-rw-r--r--Source/Utils/WarpXMovingWindow.cpp2
6 files changed, 81 insertions, 38 deletions
diff --git a/Source/Diagnostics/FieldIO.cpp b/Source/Diagnostics/FieldIO.cpp
index 43f204da0..be0e719cc 100644
--- a/Source/Diagnostics/FieldIO.cpp
+++ b/Source/Diagnostics/FieldIO.cpp
@@ -352,7 +352,7 @@ AverageAndPackVectorField( MultiFab& mf_avg,
}
}
-/** \brief Takes the specified component of the three fields and
+/** \brief Takes all of the components of the three fields and
* averages and packs them into the MultiFab mf_avg.
*/
void
@@ -363,14 +363,10 @@ AverageAndPackVectorFieldComponents (MultiFab& mf_avg,
{
if (vector_field[0]->nComp() > 1) {
std::array<std::unique_ptr<MultiFab>,3> vector_field_component;
- vector_field_component[0].reset(new MultiFab(vector_field[0]->boxArray(), dm, 1, vector_field[0]->nGrowVect()));
- vector_field_component[1].reset(new MultiFab(vector_field[1]->boxArray(), dm, 1, vector_field[1]->nGrowVect()));
- vector_field_component[2].reset(new MultiFab(vector_field[2]->boxArray(), dm, 1, vector_field[2]->nGrowVect()));
for (int icomp=0 ; icomp < vector_field[0]->nComp() ; icomp++) {
- // This is a bit inefficient since it copies the data. Can this be done with pointers?
- MultiFab::Copy(*vector_field_component[0], *vector_field[0], icomp, 0, 1, vector_field[0]->nGrowVect());
- MultiFab::Copy(*vector_field_component[1], *vector_field[1], icomp, 0, 1, vector_field[1]->nGrowVect());
- MultiFab::Copy(*vector_field_component[2], *vector_field[2], icomp, 0, 1, vector_field[2]->nGrowVect());
+ vector_field_component[0].reset(new MultiFab(*vector_field[0], amrex::make_alias, icomp, 1));
+ vector_field_component[1].reset(new MultiFab(*vector_field[1], amrex::make_alias, icomp, 1));
+ vector_field_component[2].reset(new MultiFab(*vector_field[2], amrex::make_alias, icomp, 1));
AverageAndPackVectorField(mf_avg, vector_field_component, dm, dcomp, ngrow);
dcomp += 3;
}
diff --git a/Source/Diagnostics/WarpXIO.cpp b/Source/Diagnostics/WarpXIO.cpp
index 31a5f700d..d7a46f7b7 100644
--- a/Source/Diagnostics/WarpXIO.cpp
+++ b/Source/Diagnostics/WarpXIO.cpp
@@ -527,13 +527,17 @@ WarpX::WritePlotFile () const
}
#ifdef WARPX_USE_OPENPMD
- m_OpenPMDPlotWriter->SetStep(istep[0]);
- if (dump_openpmd)
- m_OpenPMDPlotWriter->WriteOpenPMDFields(varnames,
- *output_mf[0], output_geom[0], istep[0], t_new[0] );
+ if (dump_openpmd) {
+ m_OpenPMDPlotWriter->SetStep(istep[0]);
+ // fields: only dumped for coarse level
+ m_OpenPMDPlotWriter->WriteOpenPMDFields(
+ varnames, *output_mf[0], output_geom[0], istep[0], t_new[0]);
+ // particles: all (reside only on locally finest level)
+ m_OpenPMDPlotWriter->WriteOpenPMDParticles(mypc);
+ }
#endif
- if (dump_plotfiles || dump_openpmd) {
+ if (dump_plotfiles) {
// Write the fields contained in `mf_avg`, and corresponding to the
// names `varnames`, into a plotfile.
@@ -616,11 +620,6 @@ WarpX::WritePlotFile () const
}
}
-#ifdef WARPX_USE_OPENPMD
- // Write openPMD format: only for level 0
- if (dump_openpmd)
- m_OpenPMDPlotWriter->WriteOpenPMDParticles(mypc);
-#endif
// leaving the option of binary output through AMREx around
// regardless of openPMD. This can be adjusted later
{
diff --git a/Source/Diagnostics/WarpXOpenPMD.cpp b/Source/Diagnostics/WarpXOpenPMD.cpp
index 05c2066de..2f1ff7719 100644
--- a/Source/Diagnostics/WarpXOpenPMD.cpp
+++ b/Source/Diagnostics/WarpXOpenPMD.cpp
@@ -1,6 +1,32 @@
#include "WarpXOpenPMD.H"
#include "FieldIO.H" // for getReversedVec
+#include <tuple>
+#include <utility>
+
+
+namespace detail
+{
+ /** Unclutter a real_names to openPMD record
+ *
+ * @param fullName name as in real_names variable
+ * @return pair of openPMD record and component name
+ */
+ inline std::pair< std::string, std::string >
+ name2openPMD( std::string const& fullName )
+ {
+ std::string record_name = fullName;
+ std::string component_name = openPMD::RecordComponent::SCALAR;
+ std::size_t startComp = fullName.find_last_of("_");
+
+ if( startComp != std::string::npos ) { // non-scalar
+ record_name = fullName.substr(0, startComp);
+ component_name = fullName.substr(startComp + 1u);
+ }
+ return make_pair(record_name, component_name);
+ }
+}
+
WarpXOpenPMDPlot::WarpXOpenPMDPlot(bool oneFilePerTS,
std::string& openPMDFileType)
:m_Series(nullptr),
@@ -74,8 +100,14 @@ WarpXOpenPMDPlot::Init(openPMD::AccessType accessType)
else
m_Series = std::make_unique<openPMD::Series>(filename, accessType);
- // actually default is "particles" by openPMD.
- m_Series->setParticlesPath("particles");
+ // more natural naming for PIC
+ m_Series->setMeshesPath("fields");
+ // TODO conform to ED-PIC extension of openPMD
+ // uint32_t const openPMD_ED_PIC = 1u;
+ // m_Series->setOpenPMDextension(openPMD_ED_PIC);
+ // meta info
+ m_Series->setSoftware("WarpX");
+ m_Series->setSoftwareVersion(WARPX_GIT_VERSION);
}
@@ -93,19 +125,22 @@ WarpXOpenPMDPlot::WriteOpenPMDParticles(const std::unique_ptr<MultiParticleConta
amrex::Vector<std::string> int_names;
amrex::Vector<int> int_flags;
- real_names.push_back("weight");
+ // see openPMD ED-PIC extension for namings
+ // note: an underscore separates the record name from its component
+ // for non-scalar records
+ real_names.push_back("weighting");
real_names.push_back("momentum_x");
real_names.push_back("momentum_y");
real_names.push_back("momentum_z");
- real_names.push_back("Ex");
- real_names.push_back("Ey");
- real_names.push_back("Ez");
+ real_names.push_back("E_x");
+ real_names.push_back("E_y");
+ real_names.push_back("E_z");
- real_names.push_back("Bx");
- real_names.push_back("By");
- real_names.push_back("Bz");
+ real_names.push_back("B_x");
+ real_names.push_back("B_y");
+ real_names.push_back("B_z");
#ifdef WARPX_DIM_RZ
real_names.push_back("theta");
@@ -224,8 +259,11 @@ WarpXOpenPMDPlot::SetupRealProperties(openPMD::ParticleSpecies& currSpecies,
auto counter = std::min(write_real_comp.size(), real_comp_names.size());
for (int i = 0; i < counter; ++i)
if (write_real_comp[i]) {
- auto& particleVar = currSpecies[real_comp_names[i]];
- auto& particleVarComp = particleVar[openPMD::RecordComponent::SCALAR];
+ // handle scalar and non-scalar records by name
+ std::string record_name, component_name;
+ std::tie(record_name, component_name) = detail::name2openPMD(real_comp_names[i]);
+
+ auto& particleVarComp = currSpecies[record_name][component_name];
particleVarComp.resetDataset(particlesLineup);
}
}
@@ -253,7 +291,11 @@ WarpXOpenPMDPlot::SaveRealProperty(WarpXParIter& pti,
{
for (auto idx=0; idx<m_NumAoSRealAttributes; idx++) {
if (write_real_comp[idx]) {
- auto& currVar = currSpecies[real_comp_names[idx]][openPMD::RecordComponent::SCALAR];
+ // handle scalar and non-scalar records by name
+ std::string record_name, component_name;
+ std::tie(record_name, component_name) = detail::name2openPMD(real_comp_names[idx]);
+
+ auto& currVar = currSpecies[record_name][component_name];
typename amrex::ParticleReal *d =
static_cast<typename amrex::ParticleReal*> (malloc(sizeof(typename amrex::ParticleReal) * numParticleOnTile));
@@ -272,7 +314,11 @@ WarpXOpenPMDPlot::SaveRealProperty(WarpXParIter& pti,
for (auto idx=0; idx<m_NumSoARealAttributes; idx++) {
auto ii = m_NumAoSRealAttributes + idx;
if (write_real_comp[ii]) {
- auto& currVar = currSpecies[real_comp_names[ii]][openPMD::RecordComponent::SCALAR];
+ // handle scalar and non-scalar records by name
+ std::string record_name, component_name;
+ std::tie(record_name, component_name) = detail::name2openPMD(real_comp_names[ii]);
+
+ auto& currVar = currSpecies[record_name][component_name];
currVar.storeChunk(openPMD::shareRaw(soa.GetRealData(idx)),
{offset}, {static_cast<unsigned long long>(numParticleOnTile)});
}
diff --git a/Source/Evolve/WarpXEvolveEM.cpp b/Source/Evolve/WarpXEvolveEM.cpp
index 1831a87bf..1cb17287b 100644
--- a/Source/Evolve/WarpXEvolveEM.cpp
+++ b/Source/Evolve/WarpXEvolveEM.cpp
@@ -355,6 +355,7 @@ WarpX::OneStep_nosub (Real cur_time)
FillBoundaryF(guard_cells.ng_alloc_F);
DampPML();
FillBoundaryE(guard_cells.ng_MovingWindow, IntVect::TheZeroVector());
+ FillBoundaryF(guard_cells.ng_MovingWindow);
FillBoundaryB(guard_cells.ng_MovingWindow, IntVect::TheZeroVector());
}
// E and B are up-to-date in the domain, but all guard cells are
@@ -383,7 +384,6 @@ void
WarpX::OneStep_sub1 (Real curtime)
{
// TODO: we could save some charge depositions
-
// Loop over species. For each ionizable species, create particles in
// product species.
mypc->doFieldIonization();
@@ -505,12 +505,12 @@ WarpX::OneStep_sub1 (Real curtime)
EvolveF(coarse_lev, PatchType::fine, 0.5*dt[coarse_lev], DtType::SecondHalf);
if (do_pml) {
- if (do_moving_window & field_gathering_algo == GatheringAlgo::MomentumConserving){
+ if (do_moving_window){
// Exchance guard cells of PMLs only (0 cells are exchanged for the
- // regular B field MultiFab). This is required as B has just been
- // evolved and one guard cell is needed for the averaging
- // in momentum-conserving gather.
+ // regular B field MultiFab). This is required as B and F have just been
+ // evolved.
FillBoundaryB(coarse_lev, PatchType::fine, IntVect::TheZeroVector());
+ FillBoundaryF(coarse_lev, PatchType::fine, IntVect::TheZeroVector());
}
DampPML(coarse_lev, PatchType::fine);
}
diff --git a/Source/Parallelization/GuardCellManager.cpp b/Source/Parallelization/GuardCellManager.cpp
index 7f72553b6..a275f4c00 100644
--- a/Source/Parallelization/GuardCellManager.cpp
+++ b/Source/Parallelization/GuardCellManager.cpp
@@ -128,7 +128,9 @@ guardCellManager::Init(
ng_FieldSolverF = ng_alloc_F;
ng_FieldGather = ng_alloc_EB;
ng_UpdateAux = ng_alloc_EB;
- ng_MovingWindow = ng_alloc_EB;
+ if (do_moving_window){
+ ng_MovingWindow = ng_alloc_EB;
+ }
} else {
ng_FieldSolver = ng_FieldSolver.min(ng_alloc_EB);
diff --git a/Source/Utils/WarpXMovingWindow.cpp b/Source/Utils/WarpXMovingWindow.cpp
index 8c22f7700..3f607615b 100644
--- a/Source/Utils/WarpXMovingWindow.cpp
+++ b/Source/Utils/WarpXMovingWindow.cpp
@@ -238,7 +238,7 @@ WarpX::shiftMF (MultiFab& mf, const Geometry& geom, int num_shift, int dir,
MultiFab tmpmf(ba, dm, nc, ng);
MultiFab::Copy(tmpmf, mf, 0, 0, nc, ng);
- IntVect ng_mw = IntVect::TheZeroVector();
+ IntVect ng_mw = IntVect::TheUnitVector();
// Enough guard cells in the MW direction
ng_mw[dir] = num_shift;
// Add the extra cell (if momentum-conserving gather with staggered field solve)