Skip to content

Commit b17ebc1

Browse files
committed
Adhere to the standard changes more closely
1 parent 2a03187 commit b17ebc1

9 files changed

+63
-22
lines changed

include/openPMD/RecordComponent.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,8 @@ class RecordComponent : public BaseRecordComponent
488488
static constexpr char const *const SCALAR = "\vScalar";
489489

490490
protected:
491-
void flush(std::string const &, internal::FlushParams const &);
491+
void
492+
flush(std::string const &, internal::FlushParams const &, bool is_scalar);
492493
void read(bool require_unit_si);
493494

494495
private:

include/openPMD/backend/MeshRecordComponent.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ class MeshRecordComponent : public RecordComponent
4747
MeshRecordComponent();
4848
MeshRecordComponent(NoInit);
4949
void read();
50-
void flush(std::string const &, internal::FlushParams const &);
50+
void
51+
flush(std::string const &, internal::FlushParams const &, bool is_scalar);
5152

5253
public:
5354
~MeshRecordComponent() override = default;

src/Iteration.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,10 +592,14 @@ void Iteration::readMeshes(std::string const &meshesPath)
592592
IOHandler()->enqueue(IOTask(&m, aList));
593593
IOHandler()->flush(internal::defaultFlushParams);
594594

595+
// Find constant scalar meshes. shape generally required for meshes,
596+
// shape also required for scalars.
597+
// https://github.com/openPMD/openPMD-standard/pull/289
595598
auto att_begin = aList.attributes->begin();
596599
auto att_end = aList.attributes->end();
597600
auto value = std::find(att_begin, att_end, "value");
598-
if (value != att_end)
601+
auto shape = std::find(att_begin, att_end, "shape");
602+
if (value != att_end && shape != att_end)
599603
{
600604
MeshRecordComponent &mrc = m;
601605
IOHandler()->enqueue(IOTask(&mrc, pOpen));

src/Mesh.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,14 @@ void Mesh::flush_impl(
222222
auto &m = get();
223223
if (m.m_datasetDefined)
224224
{
225-
T_RecordComponent::flush(SCALAR, flushParams);
225+
T_RecordComponent::flush(
226+
SCALAR, flushParams, /* is_scalar = */ true);
226227
}
227228
else
228229
{
229230
for (auto &comp : *this)
230-
comp.second.flush(comp.first, flushParams);
231+
comp.second.flush(
232+
comp.first, flushParams, /* is_scalar = */ false);
231233
}
232234
}
233235
else
@@ -237,7 +239,7 @@ void Mesh::flush_impl(
237239
if (scalar())
238240
{
239241
MeshRecordComponent &mrc = *this;
240-
mrc.flush(name, flushParams);
242+
mrc.flush(name, flushParams, /* is_scalar = */ true);
241243
}
242244
else
243245
{
@@ -247,20 +249,23 @@ void Mesh::flush_impl(
247249
for (auto &comp : *this)
248250
{
249251
comp.second.parent() = &this->writable();
250-
comp.second.flush(comp.first, flushParams);
252+
comp.second.flush(
253+
comp.first, flushParams, /* is_scalar = */ false);
251254
}
252255
}
253256
}
254257
else
255258
{
256259
if (scalar())
257260
{
258-
T_RecordComponent::flush(name, flushParams);
261+
T_RecordComponent::flush(
262+
name, flushParams, /* is_scalar = */ true);
259263
}
260264
else
261265
{
262266
for (auto &comp : *this)
263-
comp.second.flush(comp.first, flushParams);
267+
comp.second.flush(
268+
comp.first, flushParams, /* is_scalar = */ false);
264269
}
265270
}
266271
flushAttributes(flushParams);

src/ParticleSpecies.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,13 @@ void ParticleSpecies::read()
7676
auto att_begin = aList.attributes->begin();
7777
auto att_end = aList.attributes->end();
7878
auto value = std::find(att_begin, att_end, "value");
79-
if (value != att_end)
79+
auto shape = std::find(att_begin, att_end, "shape");
80+
// Find constant scalar particle components.
81+
// shape required for constant scalar components, since a shape is
82+
// by standard required to be written for at least one component,
83+
// but there is only one.
84+
// https://github.com/openPMD/openPMD-standard/pull/289
85+
if (value != att_end && shape != att_end)
8086
{
8187
RecordComponent &rc = r;
8288
IOHandler()->enqueue(IOTask(&rc, pOpen));

src/Record.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,14 @@ void Record::flush_impl(
5050
{
5151
if (scalar())
5252
{
53-
T_RecordComponent::flush(SCALAR, flushParams);
53+
T_RecordComponent::flush(
54+
SCALAR, flushParams, /* is_scalar = */ true);
5455
}
5556
else
5657
{
5758
for (auto &comp : *this)
58-
comp.second.flush(comp.first, flushParams);
59+
comp.second.flush(
60+
comp.first, flushParams, /* is_scalar = */ false);
5961
}
6062
}
6163
else
@@ -65,7 +67,7 @@ void Record::flush_impl(
6567
if (scalar())
6668
{
6769
RecordComponent &rc = *this;
68-
rc.flush(name, flushParams);
70+
rc.flush(name, flushParams, /* is_scalar = */ true);
6971
}
7072
else
7173
{
@@ -75,7 +77,8 @@ void Record::flush_impl(
7577
for (auto &comp : *this)
7678
{
7779
comp.second.parent() = getWritable(this);
78-
comp.second.flush(comp.first, flushParams);
80+
comp.second.flush(
81+
comp.first, flushParams, /* is_scalar = */ false);
7982
}
8083
}
8184
}
@@ -84,12 +87,14 @@ void Record::flush_impl(
8487

8588
if (scalar())
8689
{
87-
T_RecordComponent::flush(name, flushParams);
90+
T_RecordComponent::flush(
91+
name, flushParams, /* is_scalar = */ true);
8892
}
8993
else
9094
{
9195
for (auto &comp : *this)
92-
comp.second.flush(comp.first, flushParams);
96+
comp.second.flush(
97+
comp.first, flushParams, /* is_scalar = */ false);
9398
}
9499
}
95100

src/RecordComponent.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,9 @@ bool RecordComponent::empty() const
241241
}
242242

243243
void RecordComponent::flush(
244-
std::string const &name, internal::FlushParams const &flushParams)
244+
std::string const &name,
245+
internal::FlushParams const &flushParams,
246+
bool is_scalar)
245247
{
246248
auto &rc = get();
247249
if (flushParams.flushLevel == FlushLevel::SkeletonOnly)
@@ -285,6 +287,21 @@ void RecordComponent::flush(
285287
setUnitSI(1);
286288
}
287289
auto constant_component_write_shape = [&]() {
290+
if (is_scalar)
291+
{
292+
// Must write shape in any case:
293+
// 1. Non-scalar constant components can be distinguished from
294+
// normal components by checking if the backend reports a
295+
// group or a dataset. This does not work for scalar constant
296+
// components, so the parser needs to check if the attributes
297+
// value and shape are there. If they're not, the group is
298+
// not considered as a constant component.
299+
// 2. Scalar constant components are required to write the shape
300+
// by standard anyway since the standard requires that at
301+
// least one component in a record have a shape. For scalars,
302+
// there is only one component, so it must have a shape.
303+
return true;
304+
}
288305
auto extent = getExtent();
289306
return !extent.empty() &&
290307
std::none_of(extent.begin(), extent.end(), [](auto val) {

src/backend/MeshRecordComponent.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,16 @@ void MeshRecordComponent::read()
6868
}
6969

7070
void MeshRecordComponent::flush(
71-
std::string const &name, internal::FlushParams const &params)
71+
std::string const &name,
72+
internal::FlushParams const &params,
73+
bool is_scalar)
7274
{
7375
if (access::write(IOHandler()->m_frontendAccess) &&
7476
!containsAttribute("position"))
7577
{
7678
setPosition(std::vector<double>{0});
7779
}
78-
RecordComponent::flush(name, params);
80+
RecordComponent::flush(name, params, is_scalar);
7981
}
8082

8183
template <typename T>

src/backend/PatchRecord.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,17 @@ PatchRecord::setUnitDimension(std::map<UnitDimension, double> const &udim)
4141
void PatchRecord::flush_impl(
4242
std::string const &path, internal::FlushParams const &flushParams)
4343
{
44-
if (!this->datasetDefined())
44+
if (!this->scalar())
4545
{
4646
if (IOHandler()->m_frontendAccess != Access::READ_ONLY)
4747
Container<PatchRecordComponent>::flush(
4848
path, flushParams); // warning (clang-tidy-10):
4949
// bugprone-parent-virtual-call
5050
for (auto &comp : *this)
51-
comp.second.flush(comp.first, flushParams);
51+
comp.second.flush(comp.first, flushParams, /* is_scalar = */ false);
5252
}
5353
else
54-
T_RecordComponent::flush(path, flushParams);
54+
T_RecordComponent::flush(path, flushParams, /* is_scalar = */ true);
5555
if (flushParams.flushLevel != FlushLevel::SkeletonOnly)
5656
{
5757
setDirty(false);

0 commit comments

Comments
 (0)