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