FaceCenteredGrid.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_FACE_CENTERED_GRID_HPP
12 #define CUBBYFLOW_FACE_CENTERED_GRID_HPP
13 
14 #include <Core/Array/Array.hpp>
16 #include <Core/Grid/VectorGrid.hpp>
17 
18 #include <array>
19 
20 namespace CubbyFlow
21 {
30 template <size_t N>
31 class FaceCenteredGrid final : public VectorGrid<N>
32 {
33  public:
35 
36  class Builder;
37 
41 
44 
47 
50 
53  const Vector<size_t, N>& resolution,
54  const Vector<double, N>& gridSpacing =
56  const Vector<double, N>& origin = Vector<double, N>{},
57  const Vector<double, N>& initialValue = Vector<double, N>{});
58 
60  ~FaceCenteredGrid() override = default;
61 
63  FaceCenteredGrid(const FaceCenteredGrid& other);
64 
66  FaceCenteredGrid(FaceCenteredGrid&& other) noexcept;
67 
70 
72  FaceCenteredGrid& operator=(FaceCenteredGrid&& other) noexcept;
73 
80  void Swap(Grid<N>* other) override;
81 
83  void Set(const FaceCenteredGrid& other);
84 
86  [[nodiscard]] double& U(const Vector<size_t, N>& idx);
87 
89  template <typename... Indices>
90  [[nodiscard]] double& U(size_t i, Indices... indices)
91  {
92  return U(Vector<size_t, N>(i, indices...));
93  }
94 
96  [[nodiscard]] const double& U(const Vector<size_t, N>& idx) const;
97 
99  template <typename... Indices>
100  [[nodiscard]] const double& U(size_t i, Indices... indices) const
101  {
102  return U(Vector<size_t, N>(i, indices...));
103  }
104 
106  [[nodiscard]] double& V(const Vector<size_t, N>& idx);
107 
109  template <typename... Indices>
110  [[nodiscard]] double& V(size_t i, Indices... indices)
111  {
112  return V(Vector<size_t, N>(i, indices...));
113  }
114 
116  [[nodiscard]] const double& V(const Vector<size_t, N>& idx) const;
117 
119  template <typename... Indices>
120  [[nodiscard]] const double& V(size_t i, Indices... indices) const
121  {
122  return V(Vector<size_t, N>(i, indices...));
123  }
124 
126  template <size_t M = N>
127  [[nodiscard]] std::enable_if_t<M == 3, double&> W(
128  const Vector<size_t, N>& idx)
129  {
130  return m_data[2](idx);
131  }
132 
134  template <size_t M = N, typename... Indices>
135  [[nodiscard]] std::enable_if_t<M == 3, double&> W(size_t i,
136  Indices... indices)
137  {
138  return W(Vector<size_t, N>(i, indices...));
139  }
140 
142  template <size_t M = N>
143  std::enable_if_t<M == 3, const double&> W(
144  const Vector<size_t, N>& idx) const
145  {
146  return m_data[2](idx);
147  }
148 
150  template <size_t M = N, typename... Indices>
151  [[nodiscard]] std::enable_if_t<M == 3, const double&> W(
152  size_t i, Indices... indices) const
153  {
154  return W(Vector<size_t, N>(i, indices...));
155  }
156 
158  [[nodiscard]] Vector<double, N> ValueAtCellCenter(
159  const Vector<size_t, N>& idx) const;
160 
162  template <typename... Indices>
163  [[nodiscard]] Vector<double, N> ValueAtCellCenter(size_t i,
164  Indices... indices) const
165  {
166  return ValueAtCellCenter(Vector<size_t, N>(i, indices...));
167  }
168 
170  [[nodiscard]] double DivergenceAtCellCenter(
171  const Vector<size_t, N>& idx) const;
172 
174  template <typename... Indices>
175  [[nodiscard]] double DivergenceAtCellCenter(size_t i,
176  Indices... indices) const
177  {
178  return DivergenceAtCellCenter(Vector<size_t, N>(i, indices...));
179  }
180 
182  [[nodiscard]] typename GetCurl<N>::Type CurlAtCellCenter(
183  const Vector<size_t, N>& idx) const;
184 
186  template <typename... Indices>
187  [[nodiscard]] typename GetCurl<N>::Type CurlAtCellCenter(
188  size_t i, Indices... indices) const
189  {
190  return CurlAtCellCenter(Vector<size_t, N>(i, indices...));
191  }
192 
194  [[nodiscard]] ScalarDataView UView();
195 
197  [[nodiscard]] ConstScalarDataView UView() const;
198 
200  [[nodiscard]] ScalarDataView VView();
201 
203  [[nodiscard]] ConstScalarDataView VView() const;
204 
206  template <size_t M = N>
207  [[nodiscard]] std::enable_if_t<M == 3, ScalarDataView> WView()
208  {
209  return DataView(2);
210  }
211 
213  template <size_t M = N>
214  [[nodiscard]] std::enable_if_t<M == 3, ConstScalarDataView> WView() const
215  {
216  return DataView(2);
217  }
218 
220  [[nodiscard]] ScalarDataView DataView(size_t i);
221 
223  [[nodiscard]] ConstScalarDataView DataView(size_t i) const;
224 
226  [[nodiscard]] GridDataPositionFunc<N> UPosition() const;
227 
229  [[nodiscard]] GridDataPositionFunc<N> VPosition() const;
230 
232  template <size_t M = N>
233  [[nodiscard]] std::enable_if_t<M == 3, GridDataPositionFunc<N>> WPosition()
234  const
235  {
236  return DataPosition(2);
237  }
238 
240  [[nodiscard]] GridDataPositionFunc<N> DataPosition(size_t i) const;
241 
243  [[nodiscard]] Vector<size_t, N> USize() const;
244 
246  [[nodiscard]] Vector<size_t, N> VSize() const;
247 
249  template <size_t M = N>
250  [[nodiscard]] std::enable_if_t<M == 3, Vector<size_t, N>> WSize() const
251  {
252  return DataSize(2);
253  }
254 
256  [[nodiscard]] Vector<size_t, N> DataSize(size_t i) const;
257 
264  [[nodiscard]] Vector<double, N> UOrigin() const;
265 
272  [[nodiscard]] Vector<double, N> VOrigin() const;
273 
280  template <size_t M = N>
281  [[nodiscard]] std::enable_if_t<M == 3, Vector<double, N>> WOrigin() const
282  {
283  return DataOrigin(2);
284  }
285 
292  [[nodiscard]] Vector<double, N> DataOrigin(size_t i) const;
293 
295  void Fill(const Vector<double, N>& value,
296  ExecutionPolicy policy = ExecutionPolicy::Parallel) override;
297 
299  void Fill(
300  const std::function<Vector<double, N>(const Vector<double, N>&)>& func,
301  ExecutionPolicy policy = ExecutionPolicy::Parallel) override;
302 
304  [[nodiscard]] std::shared_ptr<VectorGrid<N>> Clone() const override;
305 
313  void ForEachUIndex(
314  const std::function<void(const Vector<size_t, N>&)>& func) const;
315 
326  const std::function<void(const Vector<size_t, N>&)>& func) const;
327 
335  void ForEachVIndex(
336  const std::function<void(const Vector<size_t, N>&)>& func) const;
337 
348  const std::function<void(const Vector<size_t, N>&)>& func) const;
349 
357  template <size_t M = N>
358  std::enable_if_t<M == 3, void> ForEachWIndex(
359  const std::function<void(const Vector<size_t, N>&)>& func) const
360  {
362  }
363 
373  template <size_t M = N>
374  std::enable_if_t<M == 3, void> ParallelForEachWIndex(
375  const std::function<void(const Vector<size_t, N>&)>& func) const
376  {
378  }
379 
381  [[nodiscard]] Vector<double, N> Sample(
382  const Vector<double, N>& x) const override;
383 
385  [[nodiscard]] double Divergence(const Vector<double, N>& x) const override;
386 
388  [[nodiscard]] typename GetCurl<N>::Type Curl(
389  const Vector<double, N>& x) const override;
390 
397  [[nodiscard]] std::function<Vector<double, N>(const Vector<double, N>&)>
398  Sampler() const override;
399 
401  static Builder GetBuilder();
402 
403  protected:
406 
407  void OnResize(const Vector<size_t, N>& resolution,
408  const Vector<double, N>& gridSpacing,
409  const Vector<double, N>& origin,
410  const Vector<double, N>& initialValue) final;
411 
413  void GetData(Array1<double>& data) const override;
414 
416  void SetData(const ConstArrayView1<double>& data) override;
417 
418  private:
419  std::array<Array<double, N>, N> m_data;
420  std::array<Vector<double, N>, N> m_dataOrigins;
421  std::array<LinearArraySampler<double, N>, N> m_linearSamplers;
422  std::function<Vector<double, N>(const Vector<double, N>&)> m_sampler;
423 
424  void ResetSampler();
425 };
426 
429 
432 
434 using FaceCenteredGrid2Ptr = std::shared_ptr<FaceCenteredGrid2>;
435 
437 using FaceCenteredGrid3Ptr = std::shared_ptr<FaceCenteredGrid3>;
438 
442 template <size_t N>
443 class FaceCenteredGrid<N>::Builder final : public VectorGridBuilder<N>
444 {
445  public:
447  Builder& WithResolution(const Vector<size_t, N>& resolution);
448 
450  Builder& WithGridSpacing(const Vector<double, N>& gridSpacing);
451 
453  Builder& WithOrigin(const Vector<double, N>& gridOrigin);
454 
456  Builder& WithInitialValue(const Vector<double, N>& initialVal);
457 
459  FaceCenteredGrid Build() const;
460 
462  std::shared_ptr<FaceCenteredGrid> MakeShared() const;
463 
469  std::shared_ptr<VectorGrid<N>> Build(
470  const Vector<size_t, N>& resolution,
471  const Vector<double, N>& gridSpacing,
472  const Vector<double, N>& gridOrigin,
473  const Vector<double, N>& initialVal) const override;
474 
475  private:
478  Vector<double, N> m_gridOrigin;
479  Vector<double, N> m_initialVal;
480 };
481 } // namespace CubbyFlow
482 
483 #endif
std::enable_if_t< M==3, double & > W(const Vector< size_t, N > &idx)
Returns w-value at given data point.
Definition: FaceCenteredGrid.hpp:127
Vector< size_t, N > USize() const
Returns data size of the u component.
void Fill(const Vector< double, N > &value, ExecutionPolicy policy=ExecutionPolicy::Parallel) override
Fills the grid with given value.
#define CUBBYFLOW_GRID_TYPE_NAME(DerivedClassName, N)
Definition: Grid.hpp:195
ScalarDataView UView()
Returns u data view.
double & V(size_t i, Indices... indices)
Returns v-value at given data point.
Definition: FaceCenteredGrid.hpp:110
Vector< size_t, N > VSize() const
Returns data size of the v component.
double DivergenceAtCellCenter(const Vector< size_t, N > &idx) const
Returns divergence at cell-center location.
Vector< double, N > UOrigin() const
Returns u-data position for the grid point at (0, 0, ...).
Vector< size_t, N > DataSize(size_t i) const
Returns data size of the i-th component.
void OnResize(const Vector< size_t, N > &resolution, const Vector< double, N > &gridSpacing, const Vector< double, N > &origin, const Vector< double, N > &initialValue) final
Invoked when the resizing happens.
std::enable_if_t< M==3, ScalarDataView > WView()
Returns w data view.
Definition: FaceCenteredGrid.hpp:207
Vector< double, N > VOrigin() const
Returns v-data position for the grid point at (0, 0, ...).
std::function< Vector< double, N >const Vector< double, N > &)> Sampler() const override
Returns the sampler function.
double DivergenceAtCellCenter(size_t i, Indices... indices) const
Returns divergence at cell-center location.
Definition: FaceCenteredGrid.hpp:175
static Builder GetBuilder()
Returns builder fox FaceCenteredGrid.
Abstract base class for N-D cartesian grid structure.
Definition: Grid.hpp:58
std::enable_if_t< M==3, ConstScalarDataView > WView() const
Returns read-only w data view.
Definition: FaceCenteredGrid.hpp:214
Front-end to create FaceCenteredGrid objects step by step.
Definition: FaceCenteredGrid.hpp:443
double & V(const Vector< size_t, N > &idx)
Returns v-value at given data point.
std::shared_ptr< VectorGrid< N > > Clone() const override
Returns the copy of the grid instance.
GetCurl< N >::Type CurlAtCellCenter(const Vector< size_t, N > &idx) const
Returns curl at cell-center location.
double & U(const Vector< size_t, N > &idx)
Returns u-value at given data point.
Definition: IterationUtils.hpp:92
void ParallelForEachUIndex(const std::function< void(const Vector< size_t, N > &)> &func) const
Invokes the given function func for each u-data point in parallel.
Abstract base class for N-D vector grid builder.
Definition: VectorGrid.hpp:117
std::shared_ptr< FaceCenteredGrid3 > FaceCenteredGrid3Ptr
Shared pointer type for the FaceCenteredGrid3.
Definition: FaceCenteredGrid.hpp:437
std::enable_if_t< M==3, double & > W(size_t i, Indices... indices)
Returns w-value at given data point.
Definition: FaceCenteredGrid.hpp:135
void Swap(Grid< N > *other) override
Swaps the contents with the given other grid.
std::enable_if_t< M==3, Vector< size_t, N > > WSize() const
Returns data size of the w component.
Definition: FaceCenteredGrid.hpp:250
Definition: Matrix.hpp:27
std::enable_if_t< M==3, const double & > W(const Vector< size_t, N > &idx) const
Returns w-value at given data point.
Definition: FaceCenteredGrid.hpp:143
std::enable_if_t< M==3, GridDataPositionFunc< N > > WPosition() const
Returns function object that maps w data point to its actual position.
Definition: FaceCenteredGrid.hpp:233
static std::enable_if_t< IsMatrixSizeStatic< Rows, Cols >), D > MakeConstant(ValueType val)
Makes a static matrix with constant entries.
Definition: MatrixDenseBase-Impl.hpp:152
const double & U(size_t i, Indices... indices) const
Returns u-value at given data point.
Definition: FaceCenteredGrid.hpp:100
GridDataPositionFunc< N > DataPosition(size_t i) const
Returns function object that maps data point to its actual position.
Definition: pybind11Utils.hpp:20
void ForEachUIndex(const std::function< void(const Vector< size_t, N > &)> &func) const
Invokes the given function func for each u-data point.
std::enable_if_t< M==3, void > ParallelForEachWIndex(const std::function< void(const Vector< size_t, N > &)> &func) const
Invokes the given function func for each w-data point parallelly.
Definition: FaceCenteredGrid.hpp:374
Definition: Array-Impl.hpp:19
std::enable_if_t< M==3, const double & > W(size_t i, Indices... indices) const
Returns w-value at given data point.
Definition: FaceCenteredGrid.hpp:151
double & U(size_t i, Indices... indices)
Returns u-value at given data point.
Definition: FaceCenteredGrid.hpp:90
Abstract base class for N-D vector grid structure.
Definition: VectorGrid.hpp:22
void ForEachVIndex(const std::function< void(const Vector< size_t, N > &)> &func) const
Invokes the given function func for each v-data point.
void GetData(Array1< double > &data) const override
Fetches the data into a continuous linear array.
GetCurl< N >::Type CurlAtCellCenter(size_t i, Indices... indices) const
Returns curl at cell-center location.
Definition: FaceCenteredGrid.hpp:187
GridDataPositionFunc< N > UPosition() const
Returns function object that maps u data point to its actual position.
N-D face-centered (a.k.a MAC or staggered) grid.
Definition: FaceCenteredGrid.hpp:31
Definition: Grid.hpp:23
void ParallelForEachIndex(const Vector< IndexType, N > &begin, const Vector< IndexType, N > &end, const Func &func, ExecutionPolicy policy)
Definition: IterationUtils-Impl.hpp:98
std::enable_if_t< M==3, Vector< double, N > > WOrigin() const
Returns w-data position for the grid point at (0, 0, ...).
Definition: FaceCenteredGrid.hpp:281
std::shared_ptr< FaceCenteredGrid2 > FaceCenteredGrid2Ptr
Shared pointer type for the FaceCenteredGrid2.
Definition: FaceCenteredGrid.hpp:434
void Set(const FaceCenteredGrid &other)
Sets the contents with the given other grid.
void SetData(const ConstArrayView1< double > &data) override
Sets the data from a continuous linear array.
Generic N-dimensional array class interface.
Definition: Array.hpp:32
void ParallelForEachVIndex(const std::function< void(const Vector< size_t, N > &)> &func) const
Invokes the given function func for each v-data point in parallel.
std::enable_if_t< M==3, void > ForEachWIndex(const std::function< void(const Vector< size_t, N > &)> &func) const
Invokes the given function func for each w-data point.
Definition: FaceCenteredGrid.hpp:358
Vector< double, N > DataOrigin(size_t i) const
Returns i-th data position for the grid point at (0, 0, ...).
ScalarDataView DataView(size_t i)
Returns i-th data view.
const double & V(size_t i, Indices... indices) const
Returns v-value at given data point.
Definition: FaceCenteredGrid.hpp:120
GridDataPositionFunc< N > VPosition() const
Returns function object that maps v data point to its actual position.
ExecutionPolicy
Execution policy tag.
Definition: Parallel.hpp:17
~FaceCenteredGrid() override=default
Default virtual destructor.
ScalarDataView VView()
Returns v data view.
void ForEachIndex(const Vector< IndexType, N > &begin, const Vector< IndexType, N > &end, const Func &func)
Definition: IterationUtils-Impl.hpp:51
Vector< double, N > Sample(const Vector< double, N > &x) const override
Returns sampled value at given position x.
Vector< double, N > ValueAtCellCenter(size_t i, Indices... indices) const
Returns interpolated value at cell center.
Definition: FaceCenteredGrid.hpp:163
GetCurl< N >::Type Curl(const Vector< double, N > &x) const override
Returns curl at given position x.
Vector< double, N > ValueAtCellCenter(const Vector< size_t, N > &idx) const
Returns interpolated value at cell center.
Definition: VectorField.hpp:23
FaceCenteredGrid & operator=(const FaceCenteredGrid &other)
Copy assignment operator.
FaceCenteredGrid()
Constructs empty grid.
double Divergence(const Vector< double, N > &x) const override
Returns divergence at given position x.