HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GAS_AdaptiveViscosity.h
Go to the documentation of this file.
1 #ifndef _GAS_AdaptiveViscosity_
2 #define _GAS_AdaptiveViscosity_
3 
4 #include "GAS_SubSolver.h"
5 #include "GAS_Utils.h"
6 
7 #include <SIM/SIM_RawField.h>
9 #include <SIM/SIM_ScalarField.h>
10 #include <SIM/SIM_VectorField.h>
11 
13 #include <UT/UT_SparseMatrix.h>
14 #include <UT/UT_VoxelArray.h>
15 #include <SYS/SYS_Types.h>
16 
17 
19 {
22 
23 public:
24 
25  // The valid faces can in one of three states:
26  // 1. active --> the face is present in the octree AND inside the simulation domain.
27  // Represented with an OctreeFaceLabel of ACTIVE
28  // 2. inactive -> the face is present in the octree but outside of the simulation domain
29  // Represented with an OctreeFaceLabel of INACTIVE
30  // 3. unassigned -> the face is not present in the octree.
31  // Represented with an OctreeFaceLabel of UNASSIGNED
32 
34  const UT_Array<UT_Array<SIM_RawField>> &staggered_velocity,
35  const UT_Array<UT_Array<SIM_RawIndexField>> &octree_velocity_indices);
36 
37  fpreal getValue(const UT_Vector3 &sample_point, const int axis) const;
38 
39 private:
40 
41  void findOccupiedNodeTiles(UT_Array<bool> &occupied_tile_list,
42  const UT_VoxelArray<int> &octree_labels,
43  const int level) const;
44 
45  void setActiveNodes(const int level);
46 
47  void sampleActiveNodes(UT_Array<SIM_RawField> &node_weights,
48  SIM_RawIndexField &node_flags,
49  const int level);
50 
51  void bubbleActiveNodeValues(UT_Array<UT_Array<SIM_RawField>> &node_weights,
52  UT_Array<SIM_RawIndexField> &node_flags,
53  const int level);
54 
55  void finishIncompleteNodes(UT_Array<UT_Array<SIM_RawField>> &node_weights,
56  UT_Array<SIM_RawIndexField> &node_flags,
57  const int level);
58 
59  void normalizeActiveNodes(UT_Array<SIM_RawField> &node_weights,
60  UT_Array<SIM_RawIndexField> &node_flags,
61  const int level);
62 
63  void distributeNodeValuesDown(const int level);
64 
65  UT_Array<SIM_RawField> m_node_labels;
66  UT_Array<UT_Array<SIM_RawField>> m_node_values;
67 
68  const UT_FaceGradedOctreeLabels &m_octree_labels;
69  const UT_Array<UT_Array<SIM_RawField>> &m_velocity;
70  const UT_Array<UT_Array<SIM_RawIndexField>> &m_velocity_indices;
71 };
72 
74 {
76 
77 public:
78 
80  {
81  StressStencilFace(exint face_index, fpreal coefficient)
82  : m_face_index(face_index)
83  , m_coefficient(coefficient)
84  {}
85 
88  };
89 
90  static constexpr exint UNLABELED_FACE = -1;
91  static constexpr exint OUTSIDE_FACE = -2;
92  static constexpr exint COLLISION_FACE = -3;
93  static constexpr exint FLUID_FACE = -4;
94  static constexpr exint BOUNDARY_FACE = -5;
95 
96  static constexpr exint OUTSIDE_STRESS = -1;
97  static constexpr exint ACTIVE_STRESS = -2;
98  static constexpr exint INACTIVE_STRESS = -3;
99 
100  GET_DATA_FUNC_F(SIM_NAME_SCALE, ViscosityScale);
101  GET_DATA_FUNC_F("minviscosity", MinViscosity);
102 
103  GET_DATA_FUNC_F(SIM_NAME_TOLERANCE, SolverTolerance);
104  GET_DATA_FUNC_I("maxiterations", MaxIterations);
105  GET_DATA_FUNC_I("numbersupersamples", NumberSuperSamples);
106 
107  GET_DATA_FUNC_I("floatprecision", FloatPrecision);
108 
109  GET_DATA_FUNC_I("octreelevels", OctreeLevels);
110  GET_DATA_FUNC_I("finebandwidth", FineBandwidth);
111 
112  GET_DATA_FUNC_B("applysolidweights", DoApplySolidWeights);
113 
114  GET_DATA_FUNC_B("generateoctree", GenerateOctree);
115  GET_DATA_FUNC_B("onlygenerateoctree", OnlyGenerateOctree);
116 
117  GET_DATA_FUNC_F("waterline",Waterline);
118  GET_DATA_FUNC_B("usewaterline",UseWaterline);
119  GET_DATA_FUNC_V3("waterlinedirection",WaterlineDirection);
120 
121  GET_DATA_FUNC_F("extrapolation", Extrapolation);
122 
125 
126 protected:
127  explicit GAS_AdaptiveViscosity(const SIM_DataFactory *factory);
128  ~GAS_AdaptiveViscosity() override;
129 
130  // The overloaded callback that GAS_SubSolver will invoke to
131  // perform our actual computation. We are giving a single object
132  // at a time to work on.
133 
134  bool
135  solveGasSubclass(SIM_Engine &engine, SIM_Object *obj,
136  SIM_Time time, SIM_Time timestep) override;
137 
138  void initializeSubclass() override;
139 
140 private:
141  // We define this to be a DOP_Auto node which means we do not
142  // need to implement a DOP_Node derivative for this data. Instead,
143  // this description is used to define the interface.
144  static const SIM_DopDescription *getDopDescription();
145  /// These macros are necessary to bind our node to the factory and
146  /// ensure useful constants like BaseClass are defined.
149  "Gas Adaptive Viscosity", getDopDescription());
150 
151  void
152  buildIntegrationWeights(UT_Array<SIM_RawField> &face_volume_weights,
153  SIM_RawField &center_volume_weights,
154  UT_Array<SIM_RawField> &edge_volume_weights,
155  const SIM_RawField &surface,
156  const SIM_RawField &collision,
157  const SIM_BoundaryLine &world_boundary_line,
158  const SIM_VectorField &velocity,
159  const fpreal extrapolation,
160  const bool do_apply_collision_weights) const;
161 
162  //
163  // Helper methods to build the layer of fine cells along the liquid boundary
164  //
165 
166  // TODO: consider just putting these as a function inside the C file?
167 
168  void
169  setFineCellMaskInterior(UT_Array<UT_Array<UT_Vector3I>> &parallel_boundary_cell_list,
170  UT_VoxelArrayF &fine_cell_mask,
171  const SIM_RawField &surface,
172  const SIM_RawField &collision,
173  const SIM_RawField &center_volume_weights,
174  const fpreal extrapolation) const;
175 
176  void
177  findOccupiedFineTiles(UT_Array<bool> &is_tile_occupied_list,
178  const UT_Array<UT_Vector3I> &fine_cell_list,
179  const UT_VoxelArrayF &fine_cell_mask) const;
180 
181  void
182  uncompressFineTiles(UT_VoxelArrayF &fine_cell_mask,
183  const UT_Array<bool> &is_tile_occupied_list) const;
184 
185  void
186  setFineCells(UT_VoxelArrayF &fine_cell_mask,
187  const UT_Array<UT_Vector3I> &fine_cell_list) const;
188 
189  void
190  loadNextOutsideFineCellLayer(UT_Array<UT_Array<UT_Vector3I>> &parallel_next_cell_list,
191  const UT_Array<UT_Vector3I> &old_cell_list,
192  const UT_VoxelArrayF &fine_cell_mask,
193  const SIM_RawField &center_volume_weights) const;
194 
195  void
196  loadNextInsideFineCellLayer(UT_Array<UT_Array<UT_Vector3I>> &parallel_next_cell_list,
197  const UT_Array<UT_Vector3I> &old_cell_list,
198  const UT_VoxelArrayF &fine_cell_mask,
199  const SIM_RawField &center_volume_weights) const;
200 
201  void
202  setCustomFineCells(UT_VoxelArrayF &fine_cell_mask,
203  const SIM_RawField &custom_fine_cells) const;
204 
205  void
206  buildOctreeCellLabels(UT_FaceGradedOctreeLabels &octree_labels,
207  const SIM_RawField &surface,
208  const SIM_RawField &collision,
209  const SIM_RawField &center_volume_weights,
210  const SIM_RawField *custom_fine_cells,
211  const int octree_levels,
212  const fpreal extrapolation,
213  const int inside_fine_cell_width,
214  const int outside_fine_cell_width) const;
215 
216  //
217  // Helper methods for building regular grid velocity labels
218  //
219 
220  void
221  findOccupiedRegularVelocityTiles(UT_Array<bool> &is_tile_occupied_list,
222  const SIM_RawField &surface,
223  const SIM_RawIndexField &regular_velocity_labels,
224  const int axis) const;
225 
226  void
227  classifyRegularVelocityFaces(SIM_RawIndexField &regular_velocity_labels,
228  const SIM_RawField &surface,
229  const SIM_RawField &collision,
230  const SIM_RawField &center_volume_weights,
231  const UT_Array<SIM_RawField> &edge_volume_weights,
232  const SIM_RawField &face_volume_weights,
233  const SIM_VectorField &velocity,
234  const SIM_BoundaryLine &index_boundary_line,
235  const int axis,
236  const fpreal extrapolation) const;
237 
238  void
239  buildRegularVelocityLabels(UT_Array<SIM_RawIndexField> &regular_velocity_labels,
240  const SIM_RawField &surface,
241  const SIM_RawField &collision,
242  const SIM_RawField &center_volume_weights,
243  const UT_Array<SIM_RawField> &edge_volume_weights,
244  const UT_Array<SIM_RawField> &face_volume_weights,
245  const SIM_VectorField &velocity,
246  const SIM_BoundaryLine &world_boundary_line,
247  const fpreal extrapolation) const;
248 
249  //
250  // Helper methods for building octree velocity indices
251  //
252 
253  void
254  findOccupiedOctreeVelocityTiles(UT_Array<bool> &is_tile_occupied_list,
255  const UT_VoxelArray<int> &octree_labels,
256  const SIM_RawIndexField &octree_velocity_indices,
257  const int axis) const;
258 
259  void
260  classifyOctreeVelocityFaces(SIM_RawIndexField &octree_velocity_indices,
261  const UT_FaceGradedOctreeLabels &octree_labels,
262  const SIM_RawField &surface,
263  const SIM_RawField &collision,
264  const SIM_RawField &center_volume_weights,
265  const UT_Array<SIM_RawField> &edge_volume_weights,
266  const SIM_RawField &face_volume_weights,
267  const SIM_VectorField &velocity,
268  const SIM_BoundaryLine &world_boundary_line,
269  const int axis, const int level,
270  const fpreal extrapolation) const;
271 
272  exint
273  buildOctreeVelocityIndices(UT_Array<UT_Array<SIM_RawIndexField>> &octree_velocity_indices,
274  const SIM_RawField &surface,
275  const SIM_RawField &collision,
276  const UT_FaceGradedOctreeLabels &octree_labels,
277  const SIM_RawField &center_volume_weights,
278  const UT_Array<SIM_RawField> &edge_volume_weights,
279  const UT_Array<SIM_RawField> &face_volume_weights,
280  const SIM_VectorField &velocity,
281  const SIM_BoundaryLine &world_boundary_line,
282  const fpreal extrapolation) const;
283 
284  //
285  // Helper methods for building edge stress stencil indices
286  //
287 
288  void
289  findOccupiedEdgeStressTiles(UT_Array<bool> &is_tile_occupied_list,
290  const UT_VoxelArray<int> &octree_labels,
291  const SIM_RawIndexField &edge_stress_indices,
292  const int axis) const;
293 
294  void
295  classifyEdgeStresses(SIM_RawIndexField &edge_stress_indices,
296  const UT_FaceGradedOctreeLabels &octree_labels,
297  const SIM_RawField &surface,
298  const SIM_RawField &edge_volume_weights,
299  const int axis, const int level) const;
300 
301  exint
302  buildEdgeStressIndices(UT_Array<UT_Array<SIM_RawIndexField>> &edge_stress_indices,
303  const SIM_RawField &surface,
304  const UT_FaceGradedOctreeLabels &octree_labels,
305  const UT_Array<SIM_RawField> &edge_volume_weights) const;
306 
307  //
308  // Helper methods for building center stress stencils
309  //
310 
311  void
312  classifyCenterStresses(SIM_RawIndexField &center_stress_indices,
313  const UT_VoxelArray<int> &octree_labels,
314  const SIM_RawField &center_volume_weights,
315  const int level) const;
316 
317  exint
318  buildCenterStressIndices(UT_Array<SIM_RawIndexField> &center_stress_indices,
319  const UT_FaceGradedOctreeLabels &octree_labels,
320  const SIM_RawField &center_volume_weights) const;
321 
322  //
323  // Help methods to build edge stress stencils
324  //
325 
326  void
327  getEdgeStressFaces(UT_Array<GAS_AdaptiveViscosity::StressStencilFace> &stencil_faces,
328  UT_Array<fpreal> &boundary_faces,
329  const UT_Vector3I &edge,
330  const UT_Array<UT_Array<SIM_RawIndexField>> &octree_velocity_indices,
331  const UT_Array<UT_Array<SIM_RawIndexField>> &edge_stress_indices,
332  const UT_FaceGradedOctreeLabels &octree_labels,
333  const SIM_VectorField *collision_velocity,
334  const int axis, const int level) const;
335 
336  fpreal
337  edgeOctreeVolumes(const UT_Vector3I &edge,
338  const UT_Array<UT_Array<SIM_RawIndexField>> &octree_velocity_indices,
339  const UT_Array<UT_Array<SIM_RawIndexField>> &edge_stress_indices,
340  const UT_FaceGradedOctreeLabels &octree_labels,
341  const int axis, const int level) const;
342 
343  struct EdgeStressStencilParms
344  {
345  EdgeStressStencilParms(const UT_Array<UT_Array<SIM_RawIndexField>> &octree_velocity_indices,
346  const UT_Array<UT_Array<SIM_RawIndexField>> &edge_stress_indices,
347  const UT_FaceGradedOctreeLabels &octree_labels,
348  const SIM_VectorField *collision_velocity,
349  const UT_Array<SIM_RawField> &edge_volume_weights,
350  const SIM_RawField &viscosity,
351  const fpreal viscosity_scale,
352  const fpreal min_viscosity,
353  const fpreal dt)
354  : m_octree_velocity_indices(octree_velocity_indices),
355  m_edge_stress_indices(edge_stress_indices),
356  m_octree_labels(octree_labels),
357  m_collision_velocity(collision_velocity),
358  m_edge_volume_weights(edge_volume_weights),
359  m_viscosity(viscosity),
360  m_viscosity_scale(viscosity_scale),
361  m_min_viscosity(min_viscosity),
362  m_dt(dt)
363  {
364  }
365 
366  const UT_Array<UT_Array<SIM_RawIndexField>> &m_octree_velocity_indices;
367  const UT_Array<UT_Array<SIM_RawIndexField>> &m_edge_stress_indices;
368  const UT_FaceGradedOctreeLabels &m_octree_labels;
369  const SIM_VectorField *m_collision_velocity;
370  const UT_Array<SIM_RawField> &m_edge_volume_weights;
371  const SIM_RawField &m_viscosity;
372  const fpreal m_viscosity_scale;
373  const fpreal m_min_viscosity;
374  const fpreal m_dt;
375  };
376 
377  void
378  buildEdgeStressStencils(UT_Array<UT_Array<StressStencilFace>> &edge_stress_stencils,
379  UT_Array<UT_Array<fpreal>> &edge_stress_boundary_stencils,
380  UT_Array<fpreal> &edge_stress_weights,
381  const EdgeStressStencilParms &parms,
382  const int axis, const int level) const;
383 
384  //
385  // Helper methods to build cell centered stress stencils
386  //
387 
388  void
389  getCenterStressFaces(UT_Array<GAS_AdaptiveViscosity::StressStencilFace> &stencil_faces,
390  UT_Array<fpreal> &boundary_faces,
391  const UT_Vector3I &cell,
392  const UT_Array<UT_Array<SIM_RawIndexField>> &octree_velocity_indices,
393  const UT_FaceGradedOctreeLabels &octree_labels,
394  const SIM_VectorField *collision_velocity,
395  const int axis, const int level) const;
396 
397  struct CenterStressStencilParms
398  {
399  CenterStressStencilParms(const UT_Array<UT_Array<SIM_RawIndexField>> &octree_velocity_indices,
400  const UT_Array<SIM_RawIndexField> &center_stress_indices,
401  const UT_FaceGradedOctreeLabels &octree_labels,
402  const SIM_VectorField *collision_velocity)
403  : m_octree_velocity_indices(octree_velocity_indices),
404  m_center_stress_indices(center_stress_indices),
405  m_octree_labels(octree_labels),
406  m_collision_velocity(collision_velocity)
407  {
408  }
409 
410  const UT_Array<UT_Array<SIM_RawIndexField>> &m_octree_velocity_indices;
411  const UT_Array<SIM_RawIndexField> &m_center_stress_indices;
412  const UT_FaceGradedOctreeLabels &m_octree_labels;
413  const SIM_VectorField *m_collision_velocity;
414  };
415 
416  void
417  buildCenterStressStencils(UT_Array<UT_Array<StressStencilFace>> &center_stress_stencils,
418  UT_Array<UT_Array<fpreal>> &center_stress_boundary_stencils,
419  const CenterStressStencilParms &parms,
420  const int axis, const int level,
421  const exint center_stress_count) const;
422 
423  void
424  buildCenterStressWeights(UT_Array<fpreal> &center_stress_weights,
425  const SIM_RawIndexField &center_stress_indices,
426  const SIM_RawField &center_volume_weights,
427  const SIM_RawField &viscosity,
428  const fpreal viscosity_scale,
429  const fpreal min_viscosity,
430  const fpreal dt,
431  const int level) const;
432 
433  //
434  // Helper method to update regular grid velocities with interpolated solution from the octree
435  //
436 
437  void
438  applyVelocitiesToRegularGrid(SIM_RawField &regular_velocity,
439  const GAS_OctreeFaceVectorFieldInterpolator &interpolator,
440  const SIM_RawIndexField &octree_velocity_indices,
441  const SIM_RawIndexField &regular_velocity_labels,
442  const SIM_RawField &collision,
443  const SIM_VectorField *collision_velocity,
444  const UT_Array<SIM_RawField> &octree_velocity,
445  const int axis) const;
446 
447  //
448  // Helper methods to unit test adaptivity
449  //
450 
451  bool
452  octreeVelocityGradingUnitTest(const UT_Array<UT_Array<SIM_RawIndexField>> &octree_velocity_indices,
453  const UT_FaceGradedOctreeLabels &octree_labels) const;
454 
455  bool
456  edgeStressUnitTest(const UT_Array<UT_Array<SIM_RawIndexField>> &edge_stress_indices,
457  const UT_Array<UT_Array<SIM_RawIndexField>> &octree_velocity_indices,
458  const SIM_RawField &surface,
459  const UT_FaceGradedOctreeLabels &octree_labels) const;
460 
461  bool
462  centerStresUnitTest(const UT_Array<SIM_RawIndexField> &center_stress_indices,
463  const UT_Array<UT_Array<SIM_RawIndexField>> &edge_stress_indices,
464  const UT_Array<UT_Array<SIM_RawIndexField>> &octree_velocity_indices,
465  const UT_FaceGradedOctreeLabels &octree_labels) const;
466 };
467 
468 #endif
#define DECLARE_STANDARD_GETCASTTOTYPE()
Definition: SIM_DataUtils.h:50
#define SIM_NAME_TOLERANCE
Definition: SIM_Names.h:202
#define GET_DATA_FUNC_V3(DataName, FuncName)
GT_API const UT_StringHolder time
#define GAS_NAME_USETIMESTEP
Definition: GAS_Utils.h:39
#define GAS_API
Definition: GAS_API.h:10
GAS_OctreeFaceVectorFieldInterpolator(const UT_FaceGradedOctreeLabels &octree_labels, const UT_Array< UT_Array< SIM_RawField >> &staggered_velocity, const UT_Array< UT_Array< SIM_RawIndexField >> &octree_velocity_indices)
StressStencilFace(exint face_index, fpreal coefficient)
int64 exint
Definition: SYS_Types.h:125
GLint level
Definition: glcorearb.h:108
virtual bool solveGasSubclass(SIM_Engine &engine, SIM_Object *obj, SIM_Time time, SIM_Time timestep)=0
fpreal getValue(const UT_Vector3 &sample_point, const int axis) const
#define DECLARE_DATAFACTORY(DataClass, SuperClass, Description, DopParms)
Definition: SIM_DataUtils.h:63
#define GET_DATA_FUNC_I(DataName, FuncName)
GA_API const UT_StringHolder parms
fpreal64 fpreal
Definition: SYS_Types.h:283
#define GET_DATA_FUNC_B(DataName, FuncName)
#define SIM_NAME_SCALE
Definition: SIM_Names.h:183
#define GET_DATA_FUNC_F(DataName, FuncName)
#define GAS_NAME_TIMESCALE
Definition: GAS_Utils.h:40
This class holds a three dimensional vector field.
virtual void initializeSubclass()