ScalarGrid.hpp
Go to the documentation of this file.
1 // This code is based on Jet framework.
2 // Copyright (c) 2018 Doyub Kim
3 // CubbyFlow is voxel-based fluid simulation engine for computer games.
4 // Copyright (c) 2020 CubbyFlow Team
5 // Core Part: Chris Ohk, Junwoo Hwang, Jihong Sin, Seungwoo Yoo
6 // AI Part: Dongheon Cho, Minseo Kim
7 // We are making my contributions/submissions to this project solely in our
8 // personal capacity and are not conveying any rights to any intellectual
9 // property of any third parties.
10 
11 #ifndef CUBBYFLOW_SCALAR_GRID_HPP
12 #define CUBBYFLOW_SCALAR_GRID_HPP
13 
14 #include <Core/Array/Array.hpp>
16 #include <Core/Array/ArrayView.hpp>
18 #include <Core/Grid/Grid.hpp>
19 
20 namespace CubbyFlow
21 {
23 template <size_t N>
24 class ScalarGrid : public ScalarField<N>, public Grid<N>
25 {
26  public:
29 
32 
33  // Import Grid members
35  using Grid<N>::Origin;
36  using Grid<N>::Resolution;
37 
39  ScalarGrid();
40 
42  ~ScalarGrid() override = default;
43 
45  ScalarGrid(const ScalarGrid& other);
46 
48  ScalarGrid(ScalarGrid&& other) noexcept;
49 
51  ScalarGrid& operator=(const ScalarGrid& other);
52 
54  ScalarGrid& operator=(ScalarGrid&& other) noexcept;
55 
62  [[nodiscard]] virtual Vector<size_t, N> DataSize() const = 0;
63 
71  [[nodiscard]] virtual Vector<double, N> DataOrigin() const = 0;
72 
74  [[nodiscard]] virtual std::shared_ptr<ScalarGrid> Clone() const = 0;
75 
77  void Clear();
78 
80  void Resize(const Vector<size_t, N>& resolution,
81  const Vector<double, N>& gridSpacing =
83  const Vector<double, N>& origin = Vector<double, N>{},
84  double initialValue = 0.0);
85 
87  void Resize(const Vector<double, N>& gridSpacing,
88  const Vector<double, N>& origin);
89 
91  const double& operator()(const Vector<size_t, N>& idx) const;
92 
94  double& operator()(const Vector<size_t, N>& idx);
95 
97  template <typename... Indices>
98  const double& operator()(size_t i, Indices... indices) const
99  {
100  return (*this)(Vector<size_t, N>(i, indices...));
101  }
102 
104  template <typename... Indices>
105  double& operator()(size_t i, Indices... indices)
106  {
107  return (*this)(Vector<size_t, N>(i, indices...));
108  }
109 
112  const Vector<size_t, N>& idx) const;
113 
115  template <typename... Indices>
117  size_t i, Indices... indices) const
118  {
119  return GradientAtDataPoint(Vector<size_t, N>(i, indices...));
120  }
121 
123  [[nodiscard]] double LaplacianAtDataPoint(
124  const Vector<size_t, N>& idx) const;
125 
127  template <typename... Indices>
128  [[nodiscard]] double LaplacianAtDataPoint(size_t i,
129  Indices... indices) const
130  {
131  return LaplacianAtDataPoint(Vector<size_t, N>(i, indices...));
132  }
133 
135  [[nodiscard]] ScalarDataView DataView();
136 
138  [[nodiscard]] ConstScalarDataView DataView() const;
139 
141  [[nodiscard]] GridDataPositionFunc<N> DataPosition() const;
142 
144  void Fill(double value, ExecutionPolicy policy = ExecutionPolicy::Parallel);
145 
147  void Fill(const std::function<double(const Vector<double, N>&)>& func,
149 
158  const std::function<void(const Vector<size_t, N>&)>& func) const;
159 
160  template <size_t M = N>
161  std::enable_if_t<M == 2, void> ForEachDataPointIndex(
162  const std::function<void(size_t, size_t)>& func) const
163  {
165  [&func](const Vector2UZ& idx) { func(idx.x, idx.y); });
166  }
167 
168  template <size_t M = N>
169  std::enable_if_t<M == 3, void> ForEachDataPointIndex(
170  const std::function<void(size_t, size_t, size_t)>& func) const
171  {
173  [&func](const Vector3UZ& idx) { func(idx.x, idx.y, idx.z); });
174  }
175 
186  const std::function<void(const Vector<size_t, N>&)>& func) const;
187 
188  template <size_t M = N>
189  std::enable_if_t<M == 2, void> ParallelForEachDataPointIndex(
190  const std::function<void(size_t, size_t)>& func) const
191  {
193  [&func](const Vector2UZ& idx) { func(idx.x, idx.y); });
194  }
195 
196  template <size_t M = N>
197  std::enable_if_t<M == 3, void> ParallelForEachDataPointIndex(
198  const std::function<void(size_t, size_t, size_t)>& func) const
199  {
201  [&func](const Vector3UZ& idx) { func(idx.x, idx.y, idx.z); });
202  }
203 
210  [[nodiscard]] double Sample(const Vector<double, N>& x) const override;
211 
218  [[nodiscard]] std::function<double(const Vector<double, N>&)> Sampler()
219  const override;
220 
222  [[nodiscard]] Vector<double, N> Gradient(
223  const Vector<double, N>& x) const override;
224 
226  [[nodiscard]] double Laplacian(const Vector<double, N>& x) const override;
227 
229  void Serialize(std::vector<uint8_t>* buffer) const override;
230 
232  void Deserialize(const std::vector<uint8_t>& buffer) override;
233 
234  protected:
236  using Grid<N>::SwapGrid;
237  using Grid<N>::SetGrid;
238 
240  void SwapScalarGrid(ScalarGrid* other);
241 
243  void SetScalarGrid(const ScalarGrid& other);
244 
246  void GetData(Array1<double>& data) const override;
247 
249  void SetData(const ConstArrayView1<double>& data) override;
250 
251  private:
252  void ResetSampler();
253 
254  Array<double, N> m_data;
255  LinearArraySampler<double, N> m_linearSampler;
256  std::function<double(const Vector<double, N>&)> m_sampler;
257 };
258 
261 
264 
266 using ScalarGrid2Ptr = std::shared_ptr<ScalarGrid2>;
267 
269 using ScalarGrid3Ptr = std::shared_ptr<ScalarGrid3>;
270 
272 template <size_t N>
274 {
275  public:
277  ScalarGridBuilder() = default;
278 
280  virtual ~ScalarGridBuilder() = default;
281 
283  ScalarGridBuilder(const ScalarGridBuilder& other) = delete;
284 
286  ScalarGridBuilder(ScalarGridBuilder&& other) noexcept = delete;
287 
289  ScalarGridBuilder& operator=(const ScalarGridBuilder& other) = delete;
290 
292  ScalarGridBuilder& operator=(ScalarGridBuilder&& other) noexcept = delete;
293 
295  virtual std::shared_ptr<ScalarGrid<N>> Build(
296  const Vector<size_t, N>& resolution,
297  const Vector<double, N>& gridSpacing,
298  const Vector<double, N>& gridOrigin, double initialVal) const = 0;
299 };
300 
303 
306 
308 using ScalarGridBuilder2Ptr = std::shared_ptr<ScalarGridBuilder2>;
309 
311 using ScalarGridBuilder3Ptr = std::shared_ptr<ScalarGridBuilder3>;
312 } // namespace CubbyFlow
313 
314 #endif
void SwapScalarGrid(ScalarGrid *other)
Swaps the data storage and predefined samplers with given grid.
virtual Vector< size_t, N > DataSize() const =0
Returns the size of the grid data.
std::enable_if_t< M==3, void > ParallelForEachDataPointIndex(const std::function< void(size_t, size_t, size_t)> &func) const
Definition: ScalarGrid.hpp:197
std::enable_if_t< M==2, void > ParallelForEachDataPointIndex(const std::function< void(size_t, size_t)> &func) const
Definition: ScalarGrid.hpp:189
void ParallelForEachDataPointIndex(const std::function< void(const Vector< size_t, N > &)> &func) const
Invokes the given function func for each data point in parallel.
void Resize(const Vector< size_t, N > &resolution, const Vector< double, N > &gridSpacing=Vector< double, N >::MakeConstant(1), const Vector< double, N > &origin=Vector< double, N >{}, double initialValue=0.0)
Resizes the grid using given parameters.
double Sample(const Vector< double, N > &x) const override
Returns the sampled value at given position x.
void SetData(const ConstArrayView1< double > &data) override
Sets the data from a continuous linear array.
Abstract base class for N-D scalar grid structure.
Definition: ScalarGrid.hpp:24
Abstract base class for N-D cartesian grid structure.
Definition: Grid.hpp:58
const double & operator()(const Vector< size_t, N > &idx) const
Returns the grid data at given data point.
double & operator()(size_t i, Indices... indices)
Returns the grid data at given data point.
Definition: ScalarGrid.hpp:105
Abstract base class for N-D scalar field.
Definition: ScalarField.hpp:24
double Laplacian(const Vector< double, N > &x) const override
Returns the Laplacian at given position x.
void GetData(Array1< double > &data) const override
Fetches the data into a continuous linear array.
void SetScalarGrid(const ScalarGrid &other)
Sets the data storage and predefined samplers with given grid.
std::shared_ptr< ScalarGrid3 > ScalarGrid3Ptr
Shared pointer for the ScalarGrid3 type.
Definition: ScalarGrid.hpp:269
virtual Vector< double, N > DataOrigin() const =0
Returns the origin of the grid data.
void Fill(double value, ExecutionPolicy policy=ExecutionPolicy::Parallel)
Fills the grid with given value.
ScalarGrid & operator=(const ScalarGrid &other)
Copy assignment operator.
std::function< double(const Vector< double, N > &)> Sampler() const override
Returns the sampler function.
Definition: Matrix.hpp:27
Vector< double, N > Gradient(const Vector< double, N > &x) const override
Returns the gradient vector at given position x.
GridDataPositionFunc< N > DataPosition() const
Returns the function that maps data point to its position.
double LaplacianAtDataPoint(const Vector< size_t, N > &idx) const
Returns the Laplacian at given data point.
Vector< double, N > GradientAtDataPoint(size_t i, Indices... indices) const
Returns the gradient vector at given data point.
Definition: ScalarGrid.hpp:116
Definition: pybind11Utils.hpp:20
Definition: Array-Impl.hpp:19
std::shared_ptr< ScalarGrid2 > ScalarGrid2Ptr
Shared pointer for the ScalarGrid2 type.
Definition: ScalarGrid.hpp:266
std::shared_ptr< ScalarGridBuilder3 > ScalarGridBuilder3Ptr
Shared pointer for the ScalarGridBuilder3 type.
Definition: ScalarGrid.hpp:311
~ScalarGrid() override=default
Default virtual destructor.
Definition: Grid.hpp:23
void Deserialize(const std::vector< uint8_t > &buffer) override
Deserializes the input buffer to the grid instance.
Abstract base class for N-D scalar grid builder.
Definition: ScalarGrid.hpp:273
ScalarDataView DataView()
Returns the read-write data array accessor.
Generic N-dimensional array class interface.
Definition: Array.hpp:32
void Serialize(std::vector< uint8_t > *buffer) const override
Serializes the grid instance to the output buffer.
ScalarGrid()
Constructs an empty grid.
std::shared_ptr< ScalarGridBuilder2 > ScalarGridBuilder2Ptr
Shared pointer for the ScalarGridBuilder2 type.
Definition: ScalarGrid.hpp:308
void Clear()
Clears the contents of the grid.
double LaplacianAtDataPoint(size_t i, Indices... indices) const
Returns the Laplacian at given data point.
Definition: ScalarGrid.hpp:128
Vector< double, N > GradientAtDataPoint(const Vector< size_t, N > &idx) const
Returns the gradient vector at given data point.
ExecutionPolicy
Execution policy tag.
Definition: Parallel.hpp:17
void ForEachDataPointIndex(const std::function< void(const Vector< size_t, N > &)> &func) const
Invokes the given function func for each data point.
const double & operator()(size_t i, Indices... indices) const
Returns the grid data at given data point.
Definition: ScalarGrid.hpp:98
std::enable_if_t< M==2, void > ForEachDataPointIndex(const std::function< void(size_t, size_t)> &func) const
Definition: ScalarGrid.hpp:161
virtual std::shared_ptr< ScalarGrid > Clone() const =0
Returns the copy of the grid instance.
std::enable_if_t< M==3, void > ForEachDataPointIndex(const std::function< void(size_t, size_t, size_t)> &func) const
Definition: ScalarGrid.hpp:169