HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GAS_SPH.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GAS_SPH.h ( GSA Library, C++)
7  *
8  * COMMENTS:
9  * Defines a spherical particle hydronymics search structure.
10  * This provides a toolbox of things to do with SPH weighting functions.
11  */
12 
13 #ifndef __GAS_SPH__
14 #define __GAS_SPH__
15 
16 #include "GAS_API.h"
17 
18 #include <GA/GA_Handle.h>
19 
20 #include <UT/UT_FloatArray.h>
21 #include <UT/UT_IntArray.h>
22 #include <UT/UT_ValArray.h>
23 #include <UT/UT_Array.h>
24 #include <UT/UT_Vector3Array.h>
25 #include <UT/UT_HashGrid.h>
26 
27 class GAS_SubSolver;
28 
29 class GA_PointGroup;
30 
31 class GEO_PointTree;
32 
33 class GU_Detail;
34 class GU_NeighbourList;
35 
36 class SIM_Engine;
37 
38 class UT_String;
39 
41 {
42 public:
43  GAS_SPH();
44  ~GAS_SPH();
45 
46  enum sphWeight
47  {
54  SPIKY_UNSCALED
55  };
56 
58 
59  // A static function which builds an appropriate warning message
60  // for missing particle fluid attributes
61  static void missingAttribWarning(SIM_Engine &engine, GAS_SubSolver *solver,
62  const UT_String &objName,
63  const UT_String &geometryName,
64  const UT_String &attribName);
65 
66  // Returns false if initalization failed, due to missing attributes,
67  // etc. If fullinit == true, then we initialize cells by adding the
68  // indices of all points in the cell and all points in neighbour cells.
69  // If not, then on each query we have to examine multiple neighbour cells.
70  // radiusScale is used to force an increase of the radius size used for
71  // density queries and such. needVolume indicates whether or not mass
72  // and density attributes are required. They are not need, for intance,
73  // when surfacing a particle fluid.
74  bool initialize(const GU_Detail *gdp, bool fullinit = true,
75  const GA_PointGroup *excludegroup = NULL,
76  fpreal radiusScale = 1.0, bool needVolume = true);
77 
78  // Builds the neighbour list, required for the accessors that
79  // take a neighbour list to run.
80  // This is independent of initialize!
81  bool buildNeighbours(const GU_Detail *gdp,
82  fpreal radiusScale = 1.0,
83  bool needVolume = true);
84 
85  // Borrows the provided neighbour list and uses it for all lookups
86  bool setNeighbours(const GU_Detail *gdp, GU_NeighbourList *list,
87  fpreal radScale = 1.0,
88  bool needVolume = true);
89 
90 
91  // Perform a simple sampling operation.
92  // The color variable, if present, will be set to the total weight
93  // of the kernels without taking the attribute into account.
94  // This is useful for efficiently calculating (pi+pj)/2, for example,
95  // as the constant term can be pulled out and multiplied by the color.
96  fpreal sampleF(const UT_Vector3 &p,
97  const GA_ROHandleF &attrib,
98  sphWeight wfunc,
99  fpreal *color = 0,
100  bool normalize = false,
101  bool volumeScale = true) const;
102  fpreal sampleF(const UT_Vector3 &p,
103  const gas_PointList &point_list,
104  const GA_ROHandleF &attrib,
105  sphWeight wfunc,
106  fpreal *color = 0,
107  bool normalize = false,
108  bool volumeScale = true) const;
109 
110  fpreal sampleF(const UT_Vector3 &p,
111  UT_FloatArray &floats,
112  sphWeight wfunc,
113  bool volumescale = true,
114  bool normalize = false) const;
115  fpreal sampleF(const UT_Vector3 &p,
116  const gas_PointList &point_list,
117  UT_FloatArray &floats,
118  sphWeight wfunc,
119  bool volumescale = true,
120  bool normalize = false) const;
121 
122  UT_Vector3 sampleV3(const UT_Vector3 &p,
123  const GA_ROHandleV3 &attrib,
124  sphWeight wfunc,
125  fpreal *color = 0,
126  bool normalize = false) const;
127  UT_Vector3 sampleV3(const UT_Vector3 &p,
128  const gas_PointList &point_list,
129  const GA_ROHandleV3 &attrib,
130  sphWeight wfunc,
131  fpreal *color = 0,
132  bool normalize = false) const;
133 
134  // A threadsafe velocity sampling function. This assumes that
135  // initVelocityData has been invoked on this sph object.
136  // excludePoint is a point to exclude from the velocity
137  // calculation (in case we want to sample the velocity around
138  // a point, but ignore the contribution of that point).
139  UT_Vector3 sampleVelocity(const UT_Vector3 &p,
140  sphWeight wfunc,
141  int excludePoint = -1) const;
142  UT_Vector3 sampleVelocity(const UT_Vector3 &p,
143  const gas_PointList &ptlist,
144  sphWeight wfunc,
145  int excludePoint = -1) const;
146 
147  // Find the XSPH velocity for the given point. We take "velocities"
148  // in an input array in order to support a more general notion
149  // of velocity.
150  UT_Vector3 xsphVelocity(int ptnum, sphWeight wfunc,
151  const UT_Vector3Array &velocities,
152  fpreal xsph_constant) const;
153 
154  // Calculates the density field at a point. This is special
155  // because it ignores particle density and just sums the mass
156  // weighting...
157  fpreal sampleDensity(const UT_Vector3 &p,
158  sphWeight wfunc,
159  const bool massScale = true) const;
160  fpreal sampleDensity(const UT_Vector3 &p,
161  const gas_PointList &ptlist,
162  sphWeight wfunc,
163  const bool massScale = true) const;
164 
165  // A convenience function which samples two densities (using the
166  // two given kernels)
167  void sampleDoubleDensity(const UT_Vector3 &p,
168  const gas_PointList &ptlist,
169  UT_FloatArray &rad2list,
170  sphWeight wfunc1,
171  sphWeight wfunc2,
172  fpreal &density1,
173  fpreal &density2,
174  const bool massScale = true) const;
175 
176  // Calculate the surface density at a point using the given
177  // surface distance attribute. This uses the surface definition
178  // from the "Adaptively Sampled Particle Fluids" paper.
179  fpreal sampleSurfaceDensity(const UT_Vector3 &p,
180  const GA_ROHandleF &distanceattrib) const;
181  fpreal sampleSurfaceDensity(const UT_Vector3 &p,
182  const gas_PointList &ptlist,
183  const GA_ROHandleF &distanceattrib) const;
184 
185  // This function is similar to the one above, but uses a fixed
186  // distance from each particle. If distanceModifier is true then
187  // the given surface distance is just treated as a multiplier of
188  // each particles interaction radius.
189  fpreal sampleSurfaceDensity(const UT_Vector3 &p,
190  fpreal surfaceDistance,
191  const bool distanceModifier = false) const;
192  fpreal sampleSurfaceDensity(const UT_Vector3 &p,
193  const gas_PointList &ptlist,
194  fpreal surfaceDistance,
195  const bool distanceModifier = false) const;
196 
197  // Calculate the gradient of the surface density field at
198  // the given point.
199  UT_Vector3 sampleSurfaceDensityGrad(const UT_Vector3 &p,
200  const GA_ROHandleF &distanceattrib) const;
201  UT_Vector3 sampleSurfaceDensityGrad(const UT_Vector3 &p,
202  const gas_PointList &ptlist,
203  const GA_ROHandleF &distanceattrib) const;
204 
205  // This function is similar to the one above, but since a fixed
206  // distance from each particle is used, the vector ends up being
207  // somewhat different.
208  UT_Vector3 sampleSurfaceDensityGrad(const UT_Vector3 &p) const;
209  UT_Vector3 sampleSurfaceDensityGrad(const UT_Vector3 &p,
210  const gas_PointList &ptlist) const;
211 
212  // Computes the color field - 1 inside the area handled by
213  // particles, 0 outside. This uses an implied attribute that
214  // is 1 wherever particles are and zero everywhere else.
215  fpreal sampleColor(const UT_Vector3 &p,
216  sphWeight wfunc) const;
217  fpreal sampleColor(const UT_Vector3 &p,
218  const gas_PointList &ptlist,
219  sphWeight wfunc) const;
220 
221  // Functions to compute the gradient and laplacian of the
222  // color field. Used in the calculation of surface tension
223  // forces.
224  UT_Vector3 colorGradient(const UT_Vector3 &p,
225  sphWeight wfunc) const;
226  UT_Vector3 colorGradient(const UT_Vector3 &p,
227  const gas_PointList &ptlist,
228  sphWeight wfunc) const;
229 
230  // Computes an unscaled color gradient (eg. no scaling by
231  // particle size, density, mass, etc.)
232  UT_Vector3 colorGradientUnscaled(const UT_Vector3 &p,
233  bool scale = false) const;
234  UT_Vector3 colorGradientUnscaled(const UT_Vector3 &p,
235  const gas_PointList &ptlist,
236  bool scale = false) const;
237 
238  // Laplacian of the color field
239  fpreal colorLaplacian(const UT_Vector3 &p,
240  sphWeight wfunc,
241  const GA_ROHandleR &scaleattrib = GA_ROHandleR(),
242  fpreal point_scale = 1.0) const;
243  fpreal colorLaplacian(const UT_Vector3 &p,
244  const gas_PointList &ptlist,
245  sphWeight wfunc,
246  const GA_ROHandleR &scaleattrib = GA_ROHandleR(),
247  fpreal point_scale = 1.0) const;
248 
249  // Gradient of a given attribute field
250  UT_Vector3 gradient(const UT_Vector3 &p,
251  const GA_ROHandleR &attrib,
252  sphWeight wfunc,
253  UT_Vector3 *color = 0,
254  bool debugprint = false,
255  const GA_ROHandleR &scaleattrib = GA_ROHandleR(),
256  fpreal point_scale = 1.0) const;
257  UT_Vector3 gradient(const UT_Vector3 &p,
258  const gas_PointList &ptlist,
259  const GA_ROHandleR &attrib,
260  sphWeight wfunc,
261  UT_Vector3 *color = 0,
262  bool debugprint = false,
263  const GA_ROHandleR &scaleattrib = GA_ROHandleR(),
264  fpreal point_scale = 1.0) const;
265 
266  // This function takes the gradient of a Vector3 attribute
267  // along the given axis.
268  UT_Vector3 gradient(const UT_Vector3 &p,
269  const GA_ROHandleV3 &attrib,
270  sphWeight wfunc,
271  int axis, UT_Vector3 *color = 0,
272  bool normalize = false) const;
273  UT_Vector3 gradient(const UT_Vector3 &p,
274  const gas_PointList &ptlist,
275  const GA_ROHandleV3 &attrib,
276  sphWeight wfunc,
277  int axis, UT_Vector3 *color = 0,
278  bool normalize = false) const;
279 
280  // Samples the laplacian of a float[1] attribute.
281  fpreal laplacian(const UT_Vector3 &p,
282  const GA_ROHandleR &attrib,
283  sphWeight wfunc,
284  fpreal *color = 0) const;
285  fpreal laplacian(const UT_Vector3 &p,
286  const gas_PointList &ptlist,
287  const GA_ROHandleR &attrib,
288  sphWeight wfunc,
289  fpreal *color = 0) const;
290 
291  // Samples the laplacian of a float[n] attribute
292  // where 1 <= n <= 4.
293  UT_FloatArray laplacianF(const UT_Vector3 &p,
294  const GA_ROHandleR &attrib,
295  sphWeight wfunc, int size,
296  fpreal *color = 0) const;
297  UT_FloatArray laplacianF(const UT_Vector3 &p,
298  const gas_PointList &ptlist,
299  const GA_ROHandleR &attrib,
300  sphWeight wfunc, int size,
301  fpreal *color = 0) const;
302 
303  UT_Vector3 laplacianV3(const UT_Vector3 &p,
304  const GA_ROHandleV3 &attrib,
305  sphWeight wfunc,
306  fpreal *color = 0,
307  const GA_ROHandleR &scale_attrib = GA_ROHandleR(),
308  fpreal point_scale = 1.0) const;
309  UT_Vector3 laplacianV3(const UT_Vector3 &p,
310  const gas_PointList &ptlist,
311  const GA_ROHandleV3 &attrib,
312  sphWeight wfunc,
313  fpreal *color = 0,
314  const GA_ROHandleR &scale_attrib = GA_ROHandleR(),
315  fpreal point_scale = 1.0) const;
316 
317  // Computes a damping term from the particle field, as
318  // in [Becker and Teschner, 07].
319  // gah can be any vector3 field, but is presumably velocity.
320  UT_Vector3 dampingValue(const UT_Vector3 &p,
321  const GA_ROHandleV3 &attrib,
322  sphWeight wfunc,
323  UT_Vector3 &point_velocity,
324  fpreal point_density,
325  const GA_ROHandleR &scale_attrib = GA_ROHandleR(),
326  fpreal point_scale = 1.0) const;
327  UT_Vector3 dampingValue(const UT_Vector3 &p,
328  const gas_PointList &ptlist,
329  const GA_ROHandleV3 &attrib,
330  sphWeight wfunc,
331  UT_Vector3 &point_velocity,
332  fpreal point_density,
333  const GA_ROHandleR &scale_attrib = GA_ROHandleR(),
334  fpreal point_scale = 1.0) const;
335 
336  /// Returns all points close to the given point.
337  /// Does a search using the points current positions
338  void findClosePoints(const UT_Vector3 &p,
339  gas_PointList &ptlist) const;
340 
341  /// Finds all points close to the given point number.
342  /// If the neighbourlist is built, that will be retrieved directly
343  /// If it hasn't been built, the point's position will be searched
344  /// using findClosePoints(Vector)
345  void findClosePoints(int ptidx,
346  gas_PointList &ptlist) const;
347 
348  // Initializes information to allow fast velocity queries to
349  // be made to this structure (without having to pass an
350  // attribute handle in). Also has the option of initializing
351  // a KD tree of the points in the structure's gdp. The purpose
352  // of this is so that if no close points can be found during
353  // a velocity query, the velocity of the nearest neighbour can
354  // be taken instead.
355  bool initVelocityData(bool initKD = false);
356 
357  // Get the width of a particle cell.
358  fpreal getCellWidth() const { return myCellWidth; }
359 
360  UT_HashGrid<GA_Offset> *getGrid() const { return myGrid; }
361 
362 protected:
363  // These take the radius squared and determine the weight
364  // or gradient of the weight for the given function.
365  // h is the radius of the kernel to sample.
366  fpreal64 weight(fpreal64 r2, fpreal64 h, sphWeight wfunc) const;
367  fpreal64 dweight(fpreal64 r, fpreal64 h, sphWeight wfunc) const;
368  fpreal64 d2weight(fpreal64 r, fpreal64 h, sphWeight wfunc) const;
369  fpreal64 scaleddweight(fpreal64 r, fpreal64 h, sphWeight wfunc) const;
370 
372 
375 
376  const GU_Detail *myGdp;
377 
381 
382  // We can optionally store a list of the mass, density and
383  // velocity at each point in our geometry. We do this to
384  // allow multithreaded sampling of the same sph structure.
389 
390  // Also store a point tree to be used for velocity evaluations.
391  // We need this so that a velocity can be computed regardless of
392  // the given point in space.
394 
395  // Radius scale used for weight queries
397 
398  // A data structure storing lists of point neighbours for
399  // fast lookup.
402 };
403 
404 #endif
405 
UT_HashGrid< GA_Offset > * getGrid() const
Definition: GAS_SPH.h:360
UT_Vector3Array myVelocities
Definition: GAS_SPH.h:388
fpreal myCellWidth
Definition: GAS_SPH.h:373
GEO_PointTree * myPointTree
Definition: GAS_SPH.h:393
GA_ROHandleF myDensityAttrib
Definition: GAS_SPH.h:380
#define GAS_API
Definition: GAS_API.h:10
const GU_Detail * myGdp
Definition: GAS_SPH.h:376
UT_HashGrid< GA_Offset > * myGrid
Definition: GAS_SPH.h:371
GA_ROHandleF myRadAttrib
Definition: GAS_SPH.h:378
UT_Array< GA_Offset > gas_PointList
Definition: GAS_SPH.h:57
double fpreal64
Definition: SYS_Types.h:201
ImageBuf OIIO_API laplacian(const ImageBuf &src, ROI roi={}, int nthreads=0)
bool myOwnNeighbours
Definition: GAS_SPH.h:401
GA_API const UT_StringHolder scale
sphWeight
Definition: GAS_SPH.h:46
UT_FloatArray myMasses
Definition: GAS_SPH.h:385
fpreal myCellWidth2
Definition: GAS_SPH.h:374
fpreal myRadiusScale
Definition: GAS_SPH.h:396
UT_FloatArray myDensities
Definition: GAS_SPH.h:386
OPENVDB_API void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types. Also initializes blosc (if enabled).
Definition: logging.h:294
GLsizeiptr size
Definition: glcorearb.h:664
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
GA_ROHandleT< fpreal > GA_ROHandleR
Definition: GA_Handle.h:1348
GA_ROHandleF myMassAttrib
Definition: GAS_SPH.h:379
GU_NeighbourList * myNeighbourList
Definition: GAS_SPH.h:400
GLuint color
Definition: glcorearb.h:1261
UT_FloatArray myRadii
Definition: GAS_SPH.h:387
fpreal getCellWidth() const
Definition: GAS_SPH.h:358
fpreal64 fpreal
Definition: SYS_Types.h:277
ScalarToVectorConverter< GridType >::Type::Ptr gradient(const GridType &grid, bool threaded, InterruptT *interrupt)
Compute the gradient of the given scalar grid.
GLboolean r
Definition: glcorearb.h:1222
constexpr T normalize(UT_FixedVector< T, D > &a) noexcept