SPH
LogWriter.cpp
Go to the documentation of this file.
1 #include "io/LogWriter.h"
2 #include "io/Logger.h"
3 #include "objects/geometry/Box.h"
4 #include "quantities/Storage.h"
5 #include "quantities/Iterate.h"
6 #include "system/Statistics.h"
7 #include "system/Timer.h"
9 
11 
12 ILogWriter::ILogWriter(const SharedPtr<ILogger>& logger, const Float period)
13  : PeriodicTrigger(period, 0._f)
14  , logger(logger) {
15  SPH_ASSERT(this->logger);
16 }
17 
19  this->write(storage, stats);
20  return nullptr;
21 }
22 
23 template <typename T>
24 void printStat(ILogger& logger,
25  const Statistics& stats,
26  const StatisticsId id,
27  const std::string& message,
28  const std::string& unit = "",
29  const std::string& emptyValue = "") {
30  if (stats.has(id)) {
31  logger.write(message, stats.get<T>(id), unit);
32  } else if (!emptyValue.empty()) {
33  logger.write(message, emptyValue);
34  }
35 }
36 
38  : ILogWriter(logger, 0._f) {
39  name = settings.get<std::string>(RunSettingsId::RUN_NAME);
40 }
41 
42 void StandardLogWriter::write(const Storage& storage, const Statistics& stats) {
43  // Timestep number and current run time
44  const int index = stats.get<int>(StatisticsId::INDEX);
45  const Float time = stats.get<Float>(StatisticsId::RUN_TIME);
46  const int wallclock = stats.get<int>(StatisticsId::WALLCLOCK_TIME);
47  const std::string formattedWallclock = getFormattedTime(wallclock);
48  logger->write(name, " #", index, " time = ", time, " wallclock time: ", formattedWallclock);
49 
51  const Float progress = stats.get<Float>(StatisticsId::RELATIVE_PROGRESS);
52  logger->write(" - progress: ", int(progress * 100), "%");
53  if (progress > 0.05_f) {
54  const std::string formattedEta = getFormattedTime(int64_t(wallclock * (1._f / progress - 1._f)));
55  logger->write(" - ETA: ", formattedEta);
56  } else {
57  logger->write(" - ETA: N/A");
58  }
59  }
60 
61  // Timestepping info
63  std::stringstream ss;
64  if (id == CriterionId::DERIVATIVE) {
66  } else {
67  ss << id;
68  }
69  const Float dt = stats.get<Float>(StatisticsId::TIMESTEP_VALUE);
70  logger->write(" - timestep: ", dt, " (set by ", ss.str(), ")");
71 
72  // clang-format off
73  printStat<int>(*logger, stats, StatisticsId::TIMESTEP_ELAPSED, " - time spent: ", "ms");
74  printStat<int>(*logger, stats, StatisticsId::SPH_EVAL_TIME, " * SPH evaluation: ", "ms");
75  printStat<int>(*logger, stats, StatisticsId::GRAVITY_EVAL_TIME, " * gravity evaluation: ", "ms");
76  printStat<int>(*logger, stats, StatisticsId::COLLISION_EVAL_TIME, " * collision evaluation: ", "ms");
77  printStat<int>(*logger, stats, StatisticsId::GRAVITY_BUILD_TIME, " * tree construction: ", "ms");
78  printStat<int>(*logger, stats, StatisticsId::POSTPROCESS_EVAL_TIME, " * visualization: ", "ms");
79  logger->write( " - particles: ", storage.getParticleCnt());
80  printStat<MinMaxMean>(*logger, stats, StatisticsId::NEIGHBOUR_COUNT, " - neighbors: ");
81  printStat<int>(*logger, stats, StatisticsId::TOTAL_COLLISION_COUNT, " - collisions: ");
82  printStat<int>(*logger, stats, StatisticsId::BOUNCE_COUNT, " * bounces: ");
83  printStat<int>(*logger, stats, StatisticsId::MERGER_COUNT, " * mergers: ");
84  printStat<int>(*logger, stats, StatisticsId::BREAKUP_COUNT, " * breakups: ");
85  printStat<int>(*logger, stats, StatisticsId::OVERLAP_COUNT, " - overlaps: ");
86  printStat<int>(*logger, stats, StatisticsId::AGGREGATE_COUNT, " - aggregates: ");
87  printStat<int>(*logger, stats, StatisticsId::SOLVER_SUMMATION_ITERATIONS, " - iteration #: ");
88  // clang-format on
89 }
90 
91 void VerboseLogWriter::write(const Storage& storage, const Statistics& stats) {
92  StandardLogWriter::write(storage, stats);
93 
94  Box bbox;
96  for (std::size_t i = 0; i < r.size(); ++i) {
97  bbox.extend(r[i]);
98  }
99 
100  logger->write(" - bounding box: ", bbox);
101  logger->write(" - min/max values:");
102  iterate<VisitorEnum::FIRST_ORDER>(storage, [&](QuantityId id, const auto& v, const auto& dv) {
103  Interval range, drange;
104  for (Size i = 0; i < v.size(); ++i) {
105  range.extend(Interval(minElement(v[i]), maxElement(v[i])));
106  drange.extend(Interval(minElement(dv[i]), maxElement(dv[i])));
107  }
108  std::string name = lowercase(getMetadata(id).quantityName);
109  logger->write(" * ", name, ": ", range, " (derivative ", drange, ")");
110  });
111  iterate<VisitorEnum::SECOND_ORDER>(storage, [&](QuantityId id, const auto& v, const auto&, const auto& d2v) {
112  Interval range, drange;
113  for (Size i = 0; i < v.size(); ++i) {
114  range.extend(Interval(minElement(v[i]), maxElement(v[i])));
115  drange.extend(Interval(minElement(d2v[i]), maxElement(d2v[i])));
116  }
117  std::string name = lowercase(getMetadata(id).quantityName);
118  logger->write(" * ", name, ": ", range, " (derivative ", drange, ")");
119  });
124  Interval divvRange, gradvRange;
125  for (Size i = 0; i < divv.size(); ++i) {
126  divvRange.extend(divv[i]);
127  gradvRange.extend(Interval(minElement(gradv[i]), maxElement(gradv[i])));
128  }
129  logger->write(" * velocity divergence: ", divvRange);
130  logger->write(" * velocity gradient: ", gradvRange);
131 
132  // clang-format on
133 }
134 
136  : ILogWriter(logger, 0._f) {
137  name = settings.get<std::string>(RunSettingsId::RUN_NAME);
138 }
139 
140 void BriefLogWriter::write(const Storage& UNUSED(storage), const Statistics& stats) {
141  // Timestep number and current run time
142  const int index = stats.get<int>(StatisticsId::INDEX);
143  const Float time = stats.get<Float>(StatisticsId::RUN_TIME);
144  const Float dt = stats.get<Float>(StatisticsId::TIMESTEP_VALUE);
145  logger->write(name, " #", index, ", time = ", time, ", step = ", dt);
146 }
147 
148 
150  : IntegralsLogWriter(makeAuto<FileLogger>(path), period) {}
151 
153  : ILogWriter(logger, period) {}
154 
155 void IntegralsLogWriter::write(const Storage& storage, const Statistics& stats) {
156  const Float time = stats.get<Float>(StatisticsId::RUN_TIME);
157  logger->write(time,
158  " ",
159  momentum.evaluate(storage),
160  " ",
161  energy.evaluate(storage),
162  " ",
163  angularMomentum.evaluate(storage));
164 }
165 
166 
169 
170 void NullLogWriter::write(const Storage& UNUSED(storage), const Statistics& UNUSED(stats)) {}
171 
INLINE Float minElement(const AntisymmetricTensor &t)
Returns the minimal element of the tensor.
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
INLINE AutoPtr< T > makeAuto(TArgs &&... args)
Definition: AutoPtr.h:124
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
Object representing a three-dimensional axis-aligned box.
INLINE Float maxElement(const T &value)
Returns maximum element, simply the value iself by default.
Definition: Generic.h:29
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Definition: Globals.h:13
Functions for iterating over individual quantities in Storage.
void printStat(ILogger &logger, const Statistics &stats, const StatisticsId id, const std::string &message, const std::string &unit="", const std::string &emptyValue="")
Definition: LogWriter.cpp:24
Logging routines of the run.
constexpr Float LARGE
Definition: MathUtils.h:34
#define UNUSED(x)
Definition: Object.h:37
#define NAMESPACE_SPH_END
Definition: Object.h:12
QuantityMetadata getMetadata(const QuantityId key)
Returns the quantity information using quantity ID.
Definition: QuantityIds.cpp:27
QuantityId
Unique IDs of basic quantities of SPH particles.
Definition: QuantityIds.h:19
@ VELOCITY_DIVERGENCE
Velocity divergence.
@ VELOCITY_GRADIENT
Velocity gradient.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
INLINE SharedPtr< T > makeShared(TArgs &&... args)
Definition: SharedPtr.h:410
Statistics gathered and periodically displayed during the run.
StatisticsId
List of values that are computed and displayed every timestep.
Definition: Statistics.h:108
@ NEIGHBOUR_COUNT
Number of neighbours (min, max, mean)
@ COLLISION_EVAL_TIME
Wallclock duration of collision evaluation.
@ WALLCLOCK_TIME
Current wallclock duration of the simulation.
@ SPH_EVAL_TIME
Wallclock duration of evaluation of SPH derivatives.
@ BREAKUP_COUNT
Number of fragmentation collisions.
@ LIMITING_QUANTITY
Quantity that currently limits the timestep.
@ POSTPROCESS_EVAL_TIME
Wallclock spent on data dump, particle visualization, etc.
@ RUN_TIME
Current time of the simulation in code units. Does not necessarily have to be 0 when run starts.
@ TIMESTEP_VALUE
Current value of timestep.
@ AGGREGATE_COUNT
Number of aggregates in the simulation (single particles are not counted as aggregates).
@ SOLVER_SUMMATION_ITERATIONS
Number of iterations used to compute density and smoothing length in summation solver.
@ TIMESTEP_CRITERION
Criterion that currently limits the timestep.
@ TOTAL_COLLISION_COUNT
Number of collisions in the timestep.
@ INDEX
Current number of time step, indexed from 0.
@ OVERLAP_COUNT
Number of particle overlaps detected during collision evaluation.
@ TIMESTEP_ELAPSED
Wallclock time spend on computing last timestep.
@ GRAVITY_BUILD_TIME
Wallclock duration of gravity tree building.
@ MERGER_COUNT
Number of mergers in the timestep.
@ GRAVITY_EVAL_TIME
Wallclock duration of gravity evaluation.
@ BOUNCE_COUNT
Number of bounce collisions.
Container for storing particle quantities and materials.
std::string lowercase(const std::string &s)
Converts all uppercase characters to their lowercase variants. Other characters are unchanged.
Definition: StringUtils.cpp:94
String getFormattedTime(const String &format)
Utility functions.
Definition: String.cpp:128
Criteria for computing the time step.
CriterionId
@ DERIVATIVE
Timestep based on value-to-derivative ratio.
Measuring time intervals and executing periodic events.
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
INLINE TCounter size() const
Definition: ArrayView.h:101
Wrapper of pointer that deletes the resource from destructor.
Definition: AutoPtr.h:15
Helper object defining three-dimensional interval (box).
Definition: Box.h:17
INLINE void extend(const Vector &v)
Enlarges the box to contain the vector.
Definition: Box.h:49
virtual void write(const Storage &storage, const Statistics &stats) override
Writes to the log using provided storage and statistics.
Definition: LogWriter.cpp:140
BriefLogWriter(const SharedPtr< ILogger > &logger, const RunSettings &settings)
Definition: LogWriter.cpp:135
File output logger.
Definition: Logger.h:160
Base class for objects logging run statistics.
Definition: LogWriter.h:10
SharedPtr< ILogger > logger
Definition: LogWriter.h:12
virtual AutoPtr< ITrigger > action(Storage &storage, Statistics &stats) override final
Writes to the log using provided storage and statistics.
Definition: LogWriter.cpp:18
ILogWriter(const SharedPtr< ILogger > &logger, const Float period=0._f)
Constructs the log file.
Definition: LogWriter.cpp:12
virtual void write(const Storage &storage, const Statistics &stats)=0
Writes to the log using provided storage and statistics.
Interface providing generic (text, human readable) output of the program.
Definition: Logger.h:22
void write(TArgs &&... args)
Creates and logs a message by concatenating arguments.
Definition: Logger.h:37
Writer logging selected integrals of motion.
Definition: LogWriter.h:75
virtual void write(const Storage &storage, const Statistics &stats) override
Writes to the log using provided storage and statistics.
Definition: LogWriter.cpp:155
IntegralsLogWriter(const Path &path, const Size interval)
Creates a writer that writes the output into given file.
Definition: LogWriter.cpp:149
Object representing a 1D interval of real numbers.
Definition: Interval.h:17
INLINE void extend(const Float &value)
Extends the interval to contain given value.
Definition: Interval.h:41
virtual void write(const Storage &storage, const Statistics &stats) override
Writes to the log using provided storage and statistics.
Definition: LogWriter.cpp:170
Helper logger that does not write anything.
Definition: Logger.h:218
Object representing a path on a filesystem.
Definition: Path.h:17
Trigger executing given action every period.
Definition: Trigger.h:37
TValue get(const TEnum idx, std::enable_if_t<!std::is_enum< std::decay_t< TValue >>::value, int >=0) const
Returns a value of given type from the settings.
Definition: Settings.h:326
virtual void write(const Storage &storage, const Statistics &stats) override
Writes to the log using provided storage and statistics.
Definition: LogWriter.cpp:42
StandardLogWriter(const SharedPtr< ILogger > &logger, const RunSettings &settings)
Definition: LogWriter.cpp:37
Object holding various statistics about current run.
Definition: Statistics.h:22
TValue get(const StatisticsId idx) const
Returns value of a statistic.
Definition: Statistics.h:88
bool has(const StatisticsId idx) const
Checks if the object contains a statistic with given ID.
Definition: Statistics.h:44
Container storing all quantities used within the simulations.
Definition: Storage.h:230
Size getParticleCnt() const
Returns the number of particles.
Definition: Storage.cpp:445
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Definition: Storage.cpp:191
Symmetric tensor of 2nd order.
virtual Vector evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:40
virtual Float evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:69
virtual Vector evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:24
virtual void write(const Storage &storage, const Statistics &stats) override
Writes to the log using provided storage and statistics.
Definition: LogWriter.cpp:91
@ RUN_NAME
User-specified name of the run, used in some output files.