SPH
Plots.cpp
Go to the documentation of this file.
1 #include "gui/objects/Plots.h"
3 #include "io/Path.h"
4 #include "post/Point.h"
5 #include <fstream>
6 
8 
9 class SelectedParticleIntegral : public IIntegral<Float> {
10 private:
11  SharedPtr<IColorizer> colorizer;
12  Size selectedIdx;
13 
14 public:
16  : colorizer(colorizer)
17  , selectedIdx(idx) {}
18 
19  virtual Float evaluate(const Storage& UNUSED(storage)) const override {
20  SPH_ASSERT(colorizer->isInitialized(), colorizer->name());
21  return colorizer->evalScalar(selectedIdx).valueOr(0.f);
22  }
23 
24  virtual std::string getName() const override {
25  return colorizer->name() + " " + std::to_string(selectedIdx);
26  }
27 };
28 
30  : initialPeriod(initialPeriod) {}
31 
33 
35  if (selectedIdx.valueOr(-1) == idx.valueOr(-1)) {
36  // either the same particle or deselecting when nothing was selected; do nothing
37  return;
38  }
39  if (selectedIdx && currentPlot) {
40  // save the current plot to cache
41  plotCache.insert(selectedIdx.value(), currentPlot);
42  }
43  selectedIdx = idx;
44 
45  if (idx) {
46  // try to get the plot from the cache
47  Optional<SharedPtr<TemporalPlot>&> cachedPlot = plotCache.tryGet(idx.value());
48  if (cachedPlot) {
49  // reuse the cached plot
50  currentPlot = cachedPlot.value();
51  return;
52  }
53  }
54  // either deselecting or no cached plot found; clear the plot
55  this->clear();
56 }
57 
59  if (colorizer != newColorizer) {
60  colorizer = newColorizer;
61  this->clear();
62  plotCache.clear();
63  }
64 }
65 
66 std::string SelectedParticlePlot::getCaption() const {
67  if (currentPlot) {
68  return currentPlot->getCaption();
69  } else {
70  return "Selected particle";
71  }
72 }
73 
74 void SelectedParticlePlot::onTimeStep(const Storage& storage, const Statistics& stats) {
75  if (selectedIdx && currentPlot) {
76  currentPlot->onTimeStep(storage, stats);
77  } else {
78  currentPlot.reset();
79  }
80  // also do onTimeStep for all cached plots
81  for (auto& plot : plotCache) {
82  plot.value->onTimeStep(storage, stats);
83  }
84  this->syncRanges();
85 }
86 
88  if (selectedIdx) {
90  makeAuto<SelectedParticleIntegral>(colorizer, selectedIdx.value());
91  TemporalPlot::Params params;
92  params.minRangeY = EPS;
93  params.shrinkY = false;
94  params.period = initialPeriod;
95  params.maxPointCnt = 1000;
96  currentPlot = makeAuto<TemporalPlot>(std::move(integral), params);
97  } else {
98  currentPlot.reset();
99  }
100  this->syncRanges();
101 }
102 
104  if (currentPlot) {
105  currentPlot->plot(dc);
106  }
107 }
108 
109 class RelativeEnergyChange : public IIntegral<Float> {
110 private:
111  TotalEnergy energy;
112  mutable Optional<Float> E_0 = NOTHING;
113 
114 public:
115  RelativeEnergyChange() = default;
116 
117  virtual Float evaluate(const Storage& storage) const override {
118  const Float E = energy.evaluate(storage);
119  if (!E_0 || E_0.value() == 0._f) {
120  E_0 = E;
121  }
122  return E / E_0.value() - 1._f;
123  }
124 
125  virtual std::string getName() const override {
126  return "Relative energy change";
127  }
128 };
129 
131  Array<PlotData> list;
132 
133  TemporalPlot::Params params;
134  params.minRangeY = 1.4_f;
135  params.shrinkY = false;
137 
138  PlotData data;
139  IntegralWrapper integral;
141 
142  if (flags.has(PlotEnum::TOTAL_ENERGY)) {
143  integral = makeAuto<TotalEnergy>();
144  data.plot = makeLocking<TemporalPlot>(integral, params);
145  data.color = Rgba(wxColour(240, 255, 80));
146  list.push(data);
147  }
148 
150  TemporalPlot::Params actParams = params;
151  actParams.minRangeY = 0.001_f;
152  integral = makeAuto<RelativeEnergyChange>();
153  data.plot = makeLocking<TemporalPlot>(integral, actParams);
154  data.color = Rgba(wxColour(240, 255, 80));
155  list.push(data);
156  }
157 
158  if (flags.has(PlotEnum::KINETIC_ENERGY)) {
159  integral = makeAuto<TotalKineticEnergy>();
160  data.plot = makeLocking<TemporalPlot>(integral, params);
161  data.color = Rgba(wxColour(200, 0, 0));
162  list.push(data);
163  }
164 
165  if (flags.has(PlotEnum::INTERNAL_ENERGY)) {
166  integral = makeAuto<TotalInternalEnergy>();
167  data.plot = makeLocking<TemporalPlot>(integral, params);
168  data.color = Rgba(wxColour(255, 50, 50));
169  list.push(data);
170  }
171 
172  if (flags.has(PlotEnum::TOTAL_MOMENTUM)) {
173  integral = makeAuto<TotalMomentum>();
174  // params.minRangeY = 1.e6_f;
175  data.plot = makeLocking<TemporalPlot>(integral, params);
176  data.color = Rgba(wxColour(100, 200, 0));
177  list.push(data);
178  }
179 
181  integral = makeAuto<TotalAngularMomentum>();
182  data.plot = makeLocking<TemporalPlot>(integral, params);
183  data.color = Rgba(wxColour(130, 80, 255));
184  list.push(data);
185  }
186 
187  std::string overplotSfd = gui.get<std::string>(GuiSettingsId::PLOT_OVERPLOT_SFD);
188 
189  if (flags.has(PlotEnum::CURRENT_SFD)) {
190  Array<AutoPtr<IPlot>> multiplot;
191  multiplot.emplaceBack(makeAuto<SfdPlot>(Post::ComponentFlag::OVERLAP, params.period));
192  if (!overplotSfd.empty()) {
193  multiplot.emplaceBack(getDataPlot(Path(overplotSfd), "Overplot"));
194  }
195  data.plot = makeLocking<MultiPlot>(std::move(multiplot));
196  data.color = Rgba(wxColour(255, 40, 255));
197  list.push(data);
198  }
199 
200  if (flags.has(PlotEnum::PREDICTED_SFD)) {
202  Array<AutoPtr<IPlot>> multiplot;
203  multiplot.emplaceBack(makeAuto<SfdPlot>(Post::ComponentFlag::ESCAPE_VELOCITY, params.period));
204  if (!overplotSfd.empty()) {
205  multiplot.emplaceBack(getDataPlot(Path(overplotSfd), "overplot"));
206  }
207  data.plot = makeLocking<MultiPlot>(std::move(multiplot));
208  data.color = Rgba(wxColour(80, 150, 255));
209  list.push(data);
210  }
211 
212  if (flags.has(PlotEnum::SPEED_HISTOGRAM)) {
213  data.plot = makeLocking<HistogramPlot>(
214  Post::HistogramId::VELOCITIES, NOTHING, params.period, "Speed histogram");
215  data.color = Rgba(wxColour(40, 100, 150));
216  list.push(data);
217  }
218 
220  data.plot = makeLocking<AngularHistogramPlot>(params.period);
221  data.color = Rgba(wxColour(250, 100, 50));
222  list.push(data);
223  }
224 
225 
226  /*if (flags.has(PlotEnum::PERIOD_HISTOGRAM)) {
227  data.plot = makeLocking<HistogramPlot>(
228  Post::HistogramId::ROTATIONAL_PERIOD, Interval(0._f, 10._f), "Rotational periods");
229  plots.push(data.plot);
230  data.color = Rgba(wxColour(255, 255, 0));
231  list->push(data);
232  }
233 
234  if (flags.has(PlotEnum::LARGEST_REMNANT_ROTATION)) {
235  class LargestRemnantRotation : public IIntegral<Float> {
236  public:
237  virtual Float evaluate(const Storage& storage) const override {
238  ArrayView<const Float> m = storage.getValue<Float>(QuantityId::MASS);
239  if (!storage.has(QuantityId::ANGULAR_FREQUENCY)) {
240  return 0._f;
241  }
242  ArrayView<const Vector> omega = storage.getValue<Vector>(QuantityId::ANGULAR_FREQUENCY);
243 
244  const Size largestRemnantIdx = std::distance(m.begin(), std::max_element(m.begin(),
245  m.end())); const Float w = getLength(omega[largestRemnantIdx]); if (w == 0._f) { return 0._f; } else {
246  return 2._f * PI / (3600._f * w);
247  }
248  }
249 
250  virtual std::string getName() const override {
251  return "Largest remnant period";
252  }
253  };
254  integral = makeAuto<LargestRemnantRotation>();
255  auto clonedParams = params;
256  clonedParams.minRangeY = 1.e-2_f;
257  data.plot = makeLocking<TemporalPlot>(integral, clonedParams);
258  plots.push(data.plot);
259  data.color = Rgba(wxColour(255, 0, 255));
260  list->push(data);
261  }*/
262 
263  /* if (flags.has(PlotEnum::SELECTED_PARTICLE)) {
264  selectedParticlePlot = makeLocking<SelectedParticlePlot>(params.period);
265  data.plot = selectedParticlePlot;
266  //plots.push(data.plot);
267  data.color = Rgba(wxColour(255, 255, 255));
268  list.push(data);
269  } else {
270  selectedParticlePlot.reset();
271  }*/
272  return list;
273 }
274 
275 AutoPtr<IPlot> getDataPlot(const Path& path, const std::string& name) {
276  std::ifstream is(path.native());
277  Array<Post::HistPoint> points;
278  while (true) {
279  float x, y;
280  is >> x >> y;
281  if (!is) {
282  break;
283  }
284  points.emplaceBack(Post::HistPoint{ x, Size(y) });
285  };
286  return makeAuto<DataPlot>(points, AxisScaleEnum::LOG_X | AxisScaleEnum::LOG_Y, name);
287 }
288 
289 
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
Object converting quantity values of particles into colors.
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
constexpr Float EPS
Definition: MathUtils.h:30
constexpr Float E
Definition: MathUtils.h:365
#define UNUSED(x)
Definition: Object.h:37
#define NAMESPACE_SPH_END
Definition: Object.h:12
const NothingType NOTHING
Definition: Optional.h:16
Object representing a path on a filesystem, similar to std::filesystem::path in c++17.
Array< PlotData > getPlotList(const GuiSettings &gui)
Definition: Plots.cpp:130
AutoPtr< IPlot > getDataPlot(const Path &path, const std::string &name)
Definition: Plots.cpp:275
Generic dynamically allocated resizable storage.
Definition: Array.h:43
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
Definition: Array.h:306
StorageType & emplaceBack(TArgs &&... args)
Constructs a new element at the end of the array in place, using the provided arguments.
Definition: Array.h:332
Wrapper of pointer that deletes the resource from destructor.
Definition: AutoPtr.h:15
Wrapper of an integral value providing functions for reading and modifying individual bits.
Definition: Flags.h:20
constexpr INLINE bool has(const TEnum flag) const
Checks if the object has a given flag.
Definition: Flags.h:77
INLINE TValue & insert(const TKey &key, const TValue &value)
Adds a new element into the map or sets new value of element with the same key.
Definition: FlatMap.h:65
INLINE void clear()
Removes all elements from the map.
Definition: FlatMap.h:111
INLINE Optional< TValue & > tryGet(const TKey &key)
Returns a reference to the value matching the given key, or NOTHING if no such value exists.
Definition: FlatMap.h:118
INLINE TValue get(const GuiSettingsId id) const
Definition: Settings.h:245
virtual std::string name() const =0
Returns the name of the colorizer.
virtual Optional< float > evalScalar(const Size UNUSED(idx)) const
Returns the scalar representation of the colorized quantity for idx-th particle.
Definition: Colorizer.h:57
virtual bool isInitialized() const =0
Checks if the colorizer has been initialized.
Abstraction of a drawing context.
Definition: Plot.h:34
Interface for classes computing integral quantities from storage.
Definition: Integrals.h:27
Helper integral wrapping another integral and converting the returned value to scalar.
Definition: Integrals.h:228
INLINE Type & value()
Returns the reference to the stored value.
Definition: Optional.h:172
INLINE Type valueOr(const TOther &other) const
Returns the stored value if the object has been initialized, otherwise returns provided parameter.
Definition: Optional.h:188
Object representing a path on a filesystem.
Definition: Path.h:17
std::string native() const
Returns the native version of the path.
Definition: Path.cpp:71
virtual Float evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Plots.cpp:117
RelativeEnergyChange()=default
virtual std::string getName() const override
Returns the name of the integral.
Definition: Plots.cpp:125
Definition: Color.h:8
virtual Float evaluate(const Storage &UNUSED(storage)) const override
Definition: Plots.cpp:19
SelectedParticleIntegral(SharedPtr< IColorizer > colorizer, const Size idx)
Definition: Plots.cpp:15
virtual std::string getName() const override
Returns the name of the integral.
Definition: Plots.cpp:24
void selectParticle(const Optional< Size > idx)
Definition: Plots.cpp:34
virtual void onTimeStep(const Storage &storage, const Statistics &stats) override
Updates the plot with new data.
Definition: Plots.cpp:74
SelectedParticlePlot(const Float initialPeriod)
Definition: Plots.cpp:29
virtual void plot(IDrawingContext &dc) const override
Draws the plot into the drawing context.
Definition: Plots.cpp:103
virtual std::string getCaption() const override
Returns the caption of the plot.
Definition: Plots.cpp:66
virtual void clear() override
Clears all cached data, prepares for next run.
Definition: Plots.cpp:87
void setColorizer(const SharedPtr< IColorizer > &newColorizer)
Definition: Plots.cpp:58
Flags< TValue > getFlags(const TEnum idx) const
Returns Flags from underlying value stored in settings.
Definition: Settings.h:348
INLINE void reset()
Definition: SharedPtr.h:227
Object holding various statistics about current run.
Definition: Statistics.h:22
Container storing all quantities used within the simulations.
Definition: Storage.h:230
virtual void plot(IDrawingContext &dc) const override
Draws the plot into the drawing context.
Definition: Plot.cpp:149
virtual std::string getCaption() const override
Returns the caption of the plot.
Definition: Plot.h:223
virtual void onTimeStep(const Storage &storage, const Statistics &stats) override
Updates the plot with new data.
Definition: Plot.cpp:85
Returns the total energy of all particles.
Definition: Integrals.h:132
virtual Float evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:69
2D point and other primitives for 2D geometry
PlotEnum
Definition: Settings.h:42
@ TOTAL_MOMENTUM
Evolution of the total momentum in time.
@ SPEED_HISTOGRAM
Speed histogram.
@ INTERNAL_ENERGY
Evolution of the total internal energy in time.
@ TOTAL_ANGULAR_MOMENTUM
Evolution of the total angular momentum in time.
@ KINETIC_ENERGY
Evolution of the total kinetic energy in time.
@ RELATIVE_ENERGY_CHANGE
Relative change of total energy.
@ CURRENT_SFD
Current size-frequency distribution.
@ ANGULAR_HISTOGRAM_OF_VELOCITIES
Angular histogram (in x-y plane) of velocity directions.
@ PREDICTED_SFD
Predicted size-frequency distribution.
@ OVERLAP
Specifies that overlapping particles belong into the same component.
@ VELOCITIES
Particle velocities.
Definition: Plots.h:12
Point in the histogram.
Definition: Analysis.h:277
Parameters of the plot.
Definition: Plot.h:176
Float minRangeY
Minimal size of the y-range.
Definition: Plot.h:184
Float period
Time that needs to pass before a new point is added.
Definition: Plot.h:194
bool shrinkY
When discarting points out of plotted range, shrink y-axis to fit currently visible points.
Definition: Plot.h:187