Skip to content

Commit d2b2304

Browse files
gujJunmin GuJunmin Guax3l
authored
Added new option <diag>.openpmd_encoding (#1979)
* Added new option <diag>.openpmd_encoding, which can be either file/group/variable With the encoding being group/variable, there will be one file generated for all iterations. * fixed tab * fixed style * backward compatibility for openpmd-api versions < 0.14 * eol * Update Docs/source/usage/parameters.rst Co-authored-by: Axel Huebl <[email protected]> * used inline instead of lamba, encoding decision is moved up at FlushFormatOpenPMD * making file based the default so scripts can work as is * Update Docs/source/usage/parameters.rst Co-authored-by: Axel Huebl <[email protected]> * Unify defaults of variables Co-authored-by: Junmin Gu <[email protected]> Co-authored-by: Junmin Gu <[email protected]> Co-authored-by: Axel Huebl <[email protected]>
1 parent 6255858 commit d2b2304

File tree

4 files changed

+81
-20
lines changed

4 files changed

+81
-20
lines changed

Docs/source/usage/parameters.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,8 +1597,10 @@ In-situ capabilities can be used by turning on Sensei or Ascent (provided they a
15971597
``json`` only works with serial/single-rank jobs.
15981598
When WarpX is compiled with openPMD support, the first available backend in the order given above is taken.
15991599

1600-
* ``<diag_name>.openpmd_tspf`` (`bool`, optional, default ``true``) only read if ``<diag_name>.format = openpmd``.
1601-
Whether to write one file per timestep.
1600+
* ``<diag_name>.openpmd_encoding`` (optional, ``v`` (variable based), ``f`` (file based) or ``g`` (group based) ) only read if ``<diag_name>.format = openpmd``.
1601+
openPMD file output encoding (file based will write one file per timestep).
1602+
`variable based` is not supported for back-transformed diagnostics.
1603+
Default: ``f`` (full diagnostics)
16021604

16031605
* ``<diag_name>.fields_to_plot`` (list of `strings`, optional)
16041606
Fields written to output.

Source/Diagnostics/FlushFormats/FlushFormatOpenPMD.cpp

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,49 @@ FlushFormatOpenPMD::FlushFormatOpenPMD (const std::string& diag_name)
1212
// Which backend to use (ADIOS, ADIOS2 or HDF5). Default depends on what is available
1313
std::string openpmd_backend {"default"};
1414
// one file per timestep (or one file for all steps)
15-
bool openpmd_tspf = true;
15+
std::string openpmd_encoding {"f"};
1616
pp_diag_name.query("openpmd_backend", openpmd_backend);
17-
pp_diag_name.query("openpmd_tspf", openpmd_tspf);
18-
auto & warpx = WarpX::GetInstance();
19-
m_OpenPMDPlotWriter = std::make_unique<WarpXOpenPMDPlot>(
20-
openpmd_tspf, openpmd_backend, warpx.getPMLdirections()
21-
);
17+
bool encodingDefined = pp_diag_name.query("openpmd_encoding", openpmd_encoding);
18+
19+
openPMD::IterationEncoding encoding = openPMD::IterationEncoding::groupBased;
20+
if ( 0 == openpmd_encoding.compare("v") )
21+
#if OPENPMDAPI_VERSION_GE(0, 14, 0)
22+
encoding = openPMD::IterationEncoding::variableBased;
23+
#else
24+
encoding = openPMD::IterationEncoding::groupBased;
25+
#endif
26+
else if ( 0 == openpmd_encoding.compare("f") )
27+
encoding = openPMD::IterationEncoding::fileBased;
28+
29+
std::string diag_type_str;
30+
pp_diag_name.get("diag_type", diag_type_str);
31+
if (diag_type_str == "BackTransformed")
32+
{
33+
if ( ( openPMD::IterationEncoding::fileBased != encoding ) &&
34+
( openPMD::IterationEncoding::groupBased != encoding ) )
35+
{
36+
std::string warnMsg = diag_name+" Unable to support BTD with streaming. Using GroupBased ";
37+
amrex::Warning(warnMsg);
38+
encoding = openPMD::IterationEncoding::groupBased;
39+
}
40+
}
41+
42+
//
43+
// if no encoding is defined, then check to see if tspf is defined.
44+
// (backward compatibility)
45+
//
46+
if ( !encodingDefined )
47+
{
48+
bool openpmd_tspf = false;
49+
bool tspfDefined = pp_diag_name.query("openpmd_tspf", openpmd_tspf);
50+
if ( tspfDefined && openpmd_tspf )
51+
encoding = openPMD::IterationEncoding::fileBased;
52+
}
53+
54+
auto & warpx = WarpX::GetInstance();
55+
m_OpenPMDPlotWriter = std::make_unique<WarpXOpenPMDPlot>(
56+
encoding, openpmd_backend, warpx.getPMLdirections()
57+
);
2258
}
2359

2460
void

Source/Diagnostics/WarpXOpenPMD.H

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ public:
9393

9494
/** Initialize openPMD I/O routines
9595
*
96-
* @param oneFilePerTS write one file per timestep
96+
* @param ie iteration encoding from openPMD: "group, file, variable"
9797
* @param filetype file backend, e.g. "bp" or "h5"
9898
* @param fieldPMLdirections PML field solver, @see WarpX::getPMLdirections()
9999
*/
100-
WarpXOpenPMDPlot (bool oneFilePerTS, std::string filetype, std::vector<bool> fieldPMLdirections);
100+
WarpXOpenPMDPlot (openPMD::IterationEncoding ie, std::string filetype, std::vector<bool> fieldPMLdirections);
101101

102102
~WarpXOpenPMDPlot ();
103103

@@ -129,6 +129,23 @@ public:
129129
private:
130130
void Init (openPMD::Access access, bool isBTD);
131131

132+
133+
inline openPMD::Iteration& GetIteration(int iteration) const
134+
{
135+
// so BTD will be able to revisit previous steps, so we do not use steps with these two encodings,
136+
if ( (openPMD::IterationEncoding::fileBased == m_Encoding ) ||
137+
(openPMD::IterationEncoding::groupBased == m_Encoding ) )
138+
{
139+
openPMD::Iteration& it = m_Series->iterations[iteration];
140+
return it;
141+
} else {
142+
auto iterations = m_Series->writeIterations();
143+
openPMD::Iteration& it = iterations[iteration];
144+
return it;
145+
}
146+
};
147+
148+
132149
/** This function does initial setup for the fields when interation is newly created
133150
* @param[in] meshes The meshes in a series
134151
* @param[in] full_geom The geometry
@@ -243,7 +260,7 @@ private:
243260
//int m_NumSoAIntAttributes = PIdx::nattribs; //! WarpX' additional int particle attributes in SoA
244261
int m_NumAoSIntAttributes = 0; //! WarpX definition: no additional int attributes in particle AoS
245262

246-
bool m_OneFilePerTS = true; //! write in openPMD fileBased manner for individual time steps
263+
openPMD::IterationEncoding m_Encoding = openPMD::IterationEncoding::fileBased;
247264
std::string m_OpenPMDFileType = "bp"; //! MPI-parallel openPMD backend: bp or h5
248265
int m_CurrentStep = -1;
249266

Source/Diagnostics/WarpXOpenPMD.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,10 @@ namespace detail
195195
}
196196

197197
#ifdef WARPX_USE_OPENPMD
198-
WarpXOpenPMDPlot::WarpXOpenPMDPlot(bool oneFilePerTS,
198+
WarpXOpenPMDPlot::WarpXOpenPMDPlot(openPMD::IterationEncoding ie,
199199
std::string openPMDFileType, std::vector<bool> fieldPMLdirections)
200200
:m_Series(nullptr),
201-
m_OneFilePerTS(oneFilePerTS),
201+
m_Encoding(ie),
202202
m_OpenPMDFileType(std::move(openPMDFileType)),
203203
m_fieldPMLdirections(std::move(fieldPMLdirections))
204204
{
@@ -232,7 +232,7 @@ WarpXOpenPMDPlot::GetFileName (std::string& filepath)
232232
//
233233
// OpenPMD supports timestepped names
234234
//
235-
if (m_OneFilePerTS)
235+
if (m_Encoding == openPMD::IterationEncoding::fileBased)
236236
filename = filename.append("_%06T");
237237
filename.append(".").append(m_OpenPMDFileType);
238238
filepath.append(filename);
@@ -256,6 +256,7 @@ void WarpXOpenPMDPlot::SetStep (int ts, const std::string& dirPrefix,
256256
amrex::Warning(warnMsg);
257257
}
258258
}
259+
259260
m_CurrentStep = ts;
260261
Init(openPMD::Access::CREATE, isBTD);
261262
}
@@ -267,8 +268,9 @@ void WarpXOpenPMDPlot::CloseStep (bool isBTD, bool isLastBTDFlush)
267268
// close BTD file only when isLastBTDFlush is true
268269
if (isBTD and !isLastBTDFlush) callClose = false;
269270
if (callClose) {
270-
if (m_Series)
271-
m_Series->iterations[m_CurrentStep].close();
271+
if (m_Series) {
272+
GetIteration(m_CurrentStep).close();
273+
}
272274

273275
// create a little helper file for ParaView 5.9+
274276
if (amrex::ParallelDescriptor::IOProcessor())
@@ -297,7 +299,10 @@ WarpXOpenPMDPlot::Init (openPMD::Access access, bool isBTD)
297299

298300
// close a previously open series before creating a new one
299301
// see ADIOS1 limitation: https://github.com/openPMD/openPMD-api/pull/686
300-
m_Series = nullptr;
302+
if ( m_Encoding == openPMD::IterationEncoding::fileBased )
303+
m_Series = nullptr;
304+
else if ( m_Series != nullptr )
305+
return;
301306

302307
if (amrex::ParallelDescriptor::NProcs() > 1) {
303308
#if defined(AMREX_USE_MPI)
@@ -316,6 +321,8 @@ WarpXOpenPMDPlot::Init (openPMD::Access access, bool isBTD)
316321
m_MPIRank = 1;
317322
}
318323

324+
m_Series->setIterationEncoding( m_Encoding );
325+
319326
// input file / simulation setup author
320327
if( WarpX::authors.size() > 0u )
321328
m_Series->setAuthor( WarpX::authors );
@@ -429,8 +436,7 @@ WarpXOpenPMDPlot::DumpToFile (ParticleContainer* pc,
429436
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_Series != nullptr, "openPMD: series must be initialized");
430437

431438
WarpXParticleCounter counter(pc);
432-
433-
openPMD::Iteration currIteration = m_Series->iterations[iteration];
439+
openPMD::Iteration& currIteration = GetIteration(iteration);
434440

435441
openPMD::ParticleSpecies currSpecies = currIteration.particles[name];
436442
// meta data for ED-PIC extension
@@ -938,7 +944,7 @@ WarpXOpenPMDPlot::WriteOpenPMDFieldsAll ( //const std::string& filename,
938944
bool const first_write_to_iteration = ! m_Series->iterations.contains( iteration );
939945

940946
// meta data
941-
openPMD::Iteration series_iteration = m_Series->iterations[iteration];
947+
openPMD::Iteration& series_iteration = GetIteration(m_CurrentStep);
942948

943949
auto meshes = series_iteration.meshes;
944950
if (first_write_to_iteration) {

0 commit comments

Comments
 (0)