openPMD-api
 
Loading...
Searching...
No Matches
Iteration.hpp
1/* Copyright 2017-2025 Fabian Koller, Axel Huebl, Franz Poeschel, Luca Fedeli
2 *
3 * This file is part of openPMD-api.
4 *
5 * openPMD-api is free software: you can redistribute it and/or modify
6 * it under the terms of of either the GNU General Public License or
7 * the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * openPMD-api is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License and the GNU Lesser General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * and the GNU Lesser General Public License along with openPMD-api.
19 * If not, see <http://www.gnu.org/licenses/>.
20 */
21#pragma once
22
23#include "openPMD/IterationEncoding.hpp"
24#include "openPMD/Mesh.hpp"
25#include "openPMD/ParticleSpecies.hpp"
26#include "openPMD/Streaming.hpp"
27#include "openPMD/auxiliary/Variant.hpp"
28#include "openPMD/backend/Attributable.hpp"
29#include "openPMD/backend/Container.hpp"
30
31#include <cstdint>
32#include <deque>
33#include <optional>
34#include <set>
35#include <tuple>
36
37namespace openPMD
38{
39namespace internal
40{
45 enum class CloseStatus
46 {
47 ParseAccessDeferred,
48 Open,
49 ClosedInFrontend,
51 Closed,
53 };
54
55 namespace BeginStepTypes
56 {
58 {};
60 {};
62 {
63 size_t step;
64 };
65 } // namespace BeginStepTypes
66
67 using BeginStep = std::variant<
71
72 namespace BeginStepTypes
73 {
74 template <typename T, typename... Args>
75 constexpr auto make(Args &&...args) -> BeginStep
76 {
77 return BeginStep{T{std::forward<Args>(args)...}};
78 }
79 } // namespace BeginStepTypes
80
82 {
88 std::string path;
92 uint64_t iteration = 0;
97 bool fileBased = false;
98 BeginStep beginStep = BeginStepTypes::DontBeginStep{};
99 };
100
101 class IterationData : public AttributableData
102 {
103 public:
104 /*
105 * An iteration may be logically closed in the frontend,
106 * but not necessarily yet in the backend.
107 * Will be propagated to the backend upon next flush.
108 * Store the current status.
109 * Once an iteration has been closed, no further flushes shall be
110 * performed. If flushing a closed file, the old file may otherwise be
111 * overwritten.
112 */
113 CloseStatus m_closed = CloseStatus::Open;
114 /*
115 * While parsing a file-based Series, each file is opened, read, then
116 * closed again. Explicitly `Iteration::open()`ing a file should only be
117 * necessary after having explicitly closed it (or in
118 * defer_iteration_parsing mode). So, the parsing procedures will set
119 * this flag as true when closing an Iteration.
120 */
121 bool allow_reopening_implicitly = false;
122
130 StepStatus m_stepStatus = StepStatus::NoStep;
131
136 std::optional<DeferredParseAccess> m_deferredParseAccess{};
137 };
138} // namespace internal
145class Iteration : public Attributable
146{
147 template <typename T, typename T_key, typename T_container>
148 friend class Container;
149 friend class Series;
150 friend class internal::AttributableData;
151 template <typename T>
152 friend T &internal::makeOwning(T &self, Series);
153 friend class Writable;
154 friend class StatefulIterator;
155 friend class StatefulSnapshotsContainer;
156
157public:
158 Iteration(Iteration const &) = default;
159 Iteration(Iteration &&) = default;
160 Iteration &operator=(Iteration const &) = default;
161 Iteration &operator=(Iteration &&) = default;
162
163 using IterationIndex_t = uint64_t;
164
170 template <typename T>
171 T time() const;
179 template <typename T>
180 Iteration &setTime(T newTime);
181
187 template <typename T>
188 T dt() const;
196 template <typename T>
197 Iteration &setDt(T newDt);
198
202 double timeUnitSI() const;
208 Iteration &setTimeUnitSI(double newTimeUnitSI);
209
219 /*
220 * Note: If the API is changed in future to allow reopening closed
221 * iterations, measures should be taken to prevent this in the streaming
222 * API. Currently, disallowing to reopen closed iterations satisfies
223 * the requirements of the streaming API.
224 */
225 Iteration &close(bool flush = true);
226
240 Iteration &open();
241
247 bool closed() const;
248
255 bool parsed() const;
256
268 [[deprecated("This attribute is no longer set by the openPMD-api.")]] bool
269 closedByWriter() const;
270
271 Container<Mesh> meshes{};
272 Container<ParticleSpecies> particles{}; // particleSpecies?
273
274 virtual ~Iteration() = default;
275
276private:
277 Iteration();
278
279 using Data_t = internal::IterationData;
280 std::shared_ptr<Data_t> m_iterationData;
281
282 inline Data_t const &get() const
283 {
284 return *m_iterationData;
285 }
286
287 inline Data_t &get()
288 {
289 return *m_iterationData;
290 }
291
292 inline std::shared_ptr<Data_t> getShared()
293 {
294 return m_iterationData;
295 }
296
297 inline void setData(std::shared_ptr<Data_t> data)
298 {
299 m_iterationData = std::move(data);
300 Attributable::setData(m_iterationData);
301 }
302
303 void flushFileBased(
304 std::string const &, IterationIndex_t, internal::FlushParams const &);
305 void flushGroupBased(IterationIndex_t, internal::FlushParams const &);
306 void flushVariableBased(IterationIndex_t, internal::FlushParams const &);
307 void flush(internal::FlushParams const &);
308 void deferParseAccess(internal::DeferredParseAccess);
309 /*
310 * Control flow for runDeferredParseAccess(), readFileBased(),
311 * readGroupBased() and read_impl():
312 * runDeferredParseAccess() is called as the entry point.
313 * File-based and group-based
314 * iteration layouts need to be parsed slightly differently:
315 * In file-based iteration layout, each iteration's file also contains
316 * attributes for the /data group. In group-based layout, those have
317 * already been parsed during opening of the Series.
318 * Hence, runDeferredParseAccess() will call either readFileBased() or
319 * readGroupBased() to
320 * allow for those different control flows.
321 * Finally, read_impl() is called which contains the common parsing
322 * logic for an iteration.
323 *
324 * reread() reads again an Iteration that has been previously read.
325 * Calling it on an Iteration not yet parsed is an error.
326 *
327 */
328 void reread(std::string const &path);
329 void readFileBased(
330 IterationIndex_t,
331 std::string const &filePath,
332 std::string const &groupPath,
333 bool beginStep);
334 void readGorVBased(
335 std::string const &groupPath, internal::BeginStep const &beginStep);
336 void read_impl(std::string const &groupPath);
337 void readMeshes(std::string const &meshesPath);
338 void readParticles(std::string const &particlesPath);
339
345 struct BeginStepStatus
346 {
347 using AvailableIterations_t = std::vector<IterationIndex_t>;
348
349 AdvanceStatus stepStatus{};
350 /*
351 * If the iteration attribute `snapshot` is present, the value of that
352 * attribute. Otherwise empty.
353 */
354 AvailableIterations_t iterationsInOpenedStep;
355
356 /*
357 * Most of the time, the AdvanceStatus part of this struct is what we
358 * need, so let's make it easy to access.
359 */
360 inline operator AdvanceStatus() const
361 {
362 return stepStatus;
363 }
364
365 /*
366 * Support for std::tie()
367 */
368 inline operator std::tuple<AdvanceStatus &, AvailableIterations_t &>()
369 {
370 return std::tuple<AdvanceStatus &, AvailableIterations_t &>{
371 stepStatus, iterationsInOpenedStep};
372 }
373 };
374
382 BeginStepStatus beginStep(bool reread);
383
384 /*
385 * Iteration-independent variant for beginStep().
386 * Useful in group-based iteration encoding where the Iteration will only
387 * be known after opening the step.
388 */
389 static BeginStepStatus
390 beginStep(std::optional<Iteration> thisObject, Series &series, bool reread);
391
397 void endStep();
398
407 StepStatus getStepStatus();
408
417 void setStepStatus(StepStatus);
418
424 virtual void linkHierarchy(Writable &w);
425
431 void runDeferredParseAccess();
432}; // Iteration
433
434extern template float Iteration::time<float>() const;
435
436extern template double Iteration::time<double>() const;
437
438extern template long double Iteration::time<long double>() const;
439
440template <typename T>
441inline T Iteration::time() const
442{
443 return this->readFloatingpoint<T>("time");
444}
445
446extern template float Iteration::dt<float>() const;
447
448extern template double Iteration::dt<double>() const;
449
450extern template long double Iteration::dt<long double>() const;
451
452template <typename T>
453inline T Iteration::dt() const
454{
455 return this->readFloatingpoint<T>("dt");
456}
457
462class IndexedIteration : public Iteration
463{
464 friend class StatefulIterator;
465 friend class LegacyIteratorAdaptor;
466
467public:
468 using index_t = Iteration::IterationIndex_t;
469 index_t const iterationIndex;
470
471 inline IndexedIteration(std::pair<index_t const, Iteration> pair)
472 : Iteration(std::move(pair.second)), iterationIndex(pair.first)
473 {}
474
475private:
476 template <typename Iteration_t>
477 IndexedIteration(Iteration_t &&it, index_t index)
478 : Iteration(std::forward<Iteration_t>(it)), iterationIndex(index)
479 {}
480};
481} // namespace openPMD
T readFloatingpoint(std::string const &key) const
Retrieve the value of a floating point Attribute of user-defined precision with ensured type-safety.
Definition Attributable.hpp:658
Iteration & setTimeUnitSI(double newTimeUnitSI)
Set the conversion factor to convert time and dt to seconds.
Definition Iteration.cpp:89
bool parsed() const
Has the iteration been parsed yet?
Definition Iteration.cpp:202
double timeUnitSI() const
Definition Iteration.cpp:84
Iteration & setTime(T newTime)
Set the global reference time for this iteration.
Definition Iteration.cpp:63
bool closedByWriter() const
Has the iteration been closed by the writer?
Definition Iteration.cpp:216
T time() const
Definition Iteration.hpp:441
bool closed() const
Has the iteration been closed?
Definition Iteration.cpp:183
T dt() const
Definition Iteration.hpp:453
Iteration & open()
Open an iteration.
Definition Iteration.cpp:146
Iteration & close(bool flush=true)
Close an iteration.
Definition Iteration.cpp:97
Iteration & setDt(T newDt)
Set the time step used to reach this iteration.
Definition Iteration.cpp:74
Definition Attributable.hpp:107
Definition Iteration.hpp:102
StepStatus m_stepStatus
Whether a step is currently active for this iteration.
Definition Iteration.hpp:130
std::optional< DeferredParseAccess > m_deferredParseAccess
Information on a parsing request that has not yet been executed.
Definition Iteration.hpp:136
Public definitions of openPMD-api.
Definition Date.cpp:29
StepStatus
Used in step-based mode (i.e.
Definition Streaming.hpp:57
AdvanceStatus
In step-based mode (i.e.
Definition Streaming.hpp:32
@ T
time
Definition UnitDimension.hpp:41
Definition Iteration.hpp:82
uint64_t iteration
The iteration index as accessed by the user in series.iterations[i].
Definition Iteration.hpp:92
std::string path
The group path within /data containing this iteration.
Definition Iteration.hpp:88
bool fileBased
If this iteration is part of a Series with file-based layout.
Definition Iteration.hpp:97
Parameters recursively passed through the openPMD hierarchy when flushing.
Definition AbstractIOHandler.hpp:106