HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GAS_SubSolver.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_SubSolver.h ( GAS Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GAS_SubSolver__
12 #define __GAS_SubSolver__
13 
14 #include "GAS_API.h"
15 
16 #include <PRM/PRM_Name.h>
17 #include <PRM/PRM_ChoiceList.h>
18 
19 #include <UT/UT_StringArray.h>
20 #include <SIM/SIM_Data.h>
21 #include <SIM/SIM_DataUtils.h>
22 #include <SIM/SIM_Utils.h>
23 #include <SIM/SIM_OptionsUser.h>
24 #include <SIM/SIM_Solver.h>
25 #include <SIM/SIM_Time.h>
26 #include <SIM/SIM_RawField.h>
27 
28 #include "GAS_Utils.h"
29 
30 class SIM_Engine;
31 class SIM_Object;
32 class SIM_Geometry;
33 class SIM_Position;
34 class SIM_GeometryCopy;
35 class SIM_ScalarField;
36 class SIM_VectorField;
37 class SIM_MatrixField;
38 class SIM_IndexField;
39 class SIM_RawIndexField;
40 class GU_SDF;
41 class GAS_SPH;
42 class GOP_Manager;
43 
44 ///
45 /// Captures all OCL errors during the life of this object.
46 /// When it is done, dumps any reported to the specified solver/object.
47 ///
48 class GAS_SubSolver;
49 
50 GAS_API void
52  const PRM_SpareData *, const PRM_Parm *);
53 
55 {
56 public:
59 
60  void addError(const char *msg,
62 
63 private:
64  SIM_Object *myObj;
65  GAS_SubSolver *mySolver;
66  UT_StringArray myErrors;
67  UT_Array<UT_ErrorSeverity> mySeverities;
68 };
69 
71  public SIM_OptionsUser
72 {
73 public:
74  /// Merely calls solve on each object.
76  SIM_ObjectArray &objects,
77  SIM_ObjectArray &newobjects,
78  SIM_ObjectArray &feedbacktoobjects,
79  const SIM_Time &timestep) override;
80 
81  /// Merely calls postSolve on each object.
83  SIM_ObjectArray &objects,
84  SIM_ObjectArray &newobjects,
85  SIM_ObjectArray &feedbacktoobjects,
86  const SIM_Time &timestep) override;
87 
88  /// Adds the flags to the description suitable for microsolvers.
89  /// pure apply data, bypass data is a multisolver, and unique
90  /// datanames.
91  static void setGasDescription(SIM_DopDescription &descr);
92 
93  /// Applies this subsolver for a single timestep.
94  /// Returns true on success
95  virtual bool solveGas(SIM_Engine &engine,
96  SIM_Object *obj,
97  SIM_Time time,
98  SIM_Time timestep);
99 
100  /// Retrieves the SIM_DATA specified by the
101  /// *option* given by the name. Ie, look up in our options,
102  /// find the data name, look up a data matching the name,
103  /// return resulting data
104  /// Reports message if a field is missing unless silent is set.
105  const SIM_Geometry *getGeometry(const SIM_Object *obj, const char *name, bool silent=false);
106  SIM_Geometry *getGeometryNonConst(SIM_Object *obj, const char *name, bool silent=false);
107 
108  const GA_PointGroup *getPointGroup(const GU_Detail *gdp, GOP_Manager &mgr, const char *parmname = GAS_NAME_PTGROUP);
109  SIM_GeometryCopy *getGeometryCopy(SIM_Object *obj, const char *name, bool silent=false);
110  SIM_GeometryCopy *getGeometryCopyByDataName(SIM_Object *obj, const char *dataname, bool silent=false);
111  SIM_ScalarField *getScalarField(SIM_Object *obj, const char *name, bool silent=false);
112  SIM_VectorField *getVectorField(SIM_Object *obj, const char *name, bool silent=false);
113  SIM_MatrixField *getMatrixField(SIM_Object *obj, const char *name, bool silent=false);
114  SIM_IndexField *getIndexField(SIM_Object *obj, const char *name, bool silent=false);
115  const SIM_ScalarField *getConstScalarField(const SIM_Object *obj, const char *name, bool silent=false);
116  const SIM_VectorField *getConstVectorField(const SIM_Object *obj, const char *name, bool silent=false);
117  const SIM_MatrixField *getConstMatrixField(const SIM_Object *obj, const char *name, bool silent=false);
118  const SIM_IndexField *getConstIndexField(const SIM_Object *obj, const char *name, bool silent=false);
119 
120  const SIM_Position *getConstPosFromField(const SIM_Object *obj, const char *name);
121 
122  /// Builds the transform mapping world -> geo
123  void getWorldToGeometry(UT_DMatrix4 &xform, SIM_Object *obj, const char *geopath);
124  /// Builds the transform mapping geo -> world
125  void getGeometryToWorld(UT_DMatrix4 &xform, SIM_Object *obj, const char *geopath);
126 
127  /// Returns the matching SIM_Data. If it doesn't exist,
128  /// creates a new one.
129  /// The resulting data is not guaranteed to exist - a bad name
130  /// could end up prohibitting creation.
131  SIM_GeometryCopy *getOrCreateGeometry(SIM_Object *obj, const char *name);
132  SIM_ScalarField *getOrCreateScalarField(SIM_Object *obj, const char *name);
133  SIM_VectorField *getOrCreateVectorField(SIM_Object *obj, const char *name);
134  SIM_MatrixField *getOrCreateMatrixField(SIM_Object *obj, const char *name);
135  SIM_IndexField *getOrCreateIndexField(SIM_Object *obj, const char *name);
136 
137  /// Retrieves all of the SIM_DATAs that match the pattern stored
138  /// in the option given by name.
139  void getMatchingData(SIM_DataArray &data,
140  SIM_Object *obj, const char *name, bool silent=false);
141  void getMatchingData(SIM_DataArray &data,
142  UT_StringArray &datanames,
143  SIM_Object *obj, const char *name, bool silent=false);
144  void getMatchingDataByName(SIM_DataArray &data,
145  SIM_Object *obj, const char *name, bool silent=false);
146  void getMatchingDataByName(SIM_DataArray &data,
147  UT_StringArray &datanames,
148  SIM_Object *obj, const char *name, bool silent=false);
149  void getMatchingConstData(SIM_ConstDataArray &data,
150  UT_StringArray &datanames,
151  SIM_Object *obj, const char *name, bool silent=false);
152 
153  /// Fetches matching data, but promotes any SIM_Geometry into
154  /// SIM_GeometryCopy
155  void getMatchingGeoCopy(SIM_DataArray &data,
156  SIM_Object *obj, const char *name, bool silent=false);
157  void getMatchingGeoCopyByName(SIM_DataArray &data,
158  SIM_Object *obj, const char *name, bool silent=false);
159 
160 
161  /// Makes the given field match the reference field in terms of
162  /// bounding box & voxel count.
163  /// A no-op if reffield or field is null.
164  void matchField(SIM_ScalarField *field, const SIM_ScalarField *reffield);
165  void matchField(SIM_VectorField *field, const SIM_ScalarField *reffield);
166  void matchField(SIM_MatrixField *field, const SIM_ScalarField *reffield);
167  void matchField(SIM_IndexField *field, const SIM_ScalarField *reffield);
168 
169  /// Builds a relationship field, storing distance to each object
170  /// in the destination field, along with the OBJID and object velocity
171  /// in the optional index and vector fields. If a stencil is provided,
172  /// the mask is built only where this field is greater than 0.5.
173  /// The negate flag controls the sign of the generated fields,
174  /// collision have "inside object" as negative so have a negate of true.
175  /// Mask should already be initialized as we only write to
176  /// new values that are more-in the relevant object.
177  /// To trigger a bandwidth, initialize mask to the max dist you
178  /// want to write.
179  /// The given fields must all be aligned.
180  /// Bandwidth is how many voxels to border particles by for our
181  /// lookup.
182  void buildRelationshipField(
184  SIM_VectorField *vel,
186  const SIM_ScalarField *stencil,
187  UT_DMatrix4 masktoworld,
188  const SIM_Object *srcobj,
189  bool usepoint, bool usesdf,
190  bool allownonsdf,
191  bool negate,
192  fpreal particlebandwidth,
193  fpreal bandwidth,
194  fpreal velscale = 1);
195 
196  /// Looks up the data referred to by the parameter (parameter name,
197  /// NOT data name here!) and finds its bounding box. Handles
198  /// fields and geometry. xform is set to the toworld transform
199  /// of the box, the box is in local space.
200  /// Returns false if no reference found. The size & center
201  /// will be left alone in that case.
202  /// The groupparmname will be referenced if it isn't null and
203  /// it is a geometry - then it will be a point group to use
204  /// for the limiting.
205  bool findReferenceBBox(
206  const SIM_Object *,
207  const char *parmname,
208  const char *groupparmname,
210  UT_Vector3 &size,
211  UT_DMatrix4 &xform);
212 
213  void reportCLError(SIM_Object *obj, int err, const char *msg) const;
214 
215 protected:
216  explicit GAS_SubSolver(const SIM_DataFactory *factory);
217  ~GAS_SubSolver() override;
218 
219  /// Applies this subsolver for a single timestep.
220  /// Returns true on success
221  virtual bool solveGasSubclass(SIM_Engine &engine,
222  SIM_Object *obj,
223  SIM_Time time,
224  SIM_Time timestep) = 0;
225 
226  // Applies postSolve tasks if exists
227  virtual bool postSolveGasSubclass(SIM_Engine &engine,
228  SIM_Object *obj,
229  SIM_Time time,
230  SIM_Time timestep){ return true; };
231 
232  /// Get a property value by looking at the Physical Parms of an object.
233  fpreal getPropertyFromState(const SIM_Object &object,
234  const SIM_Property &property) const;
235 
236  /// Evaluates property at a given position
238  const UT_Vector3 &worldspacepos,
239  const SIM_Property &property) const override;
241  int ptnum, const SIM_Property &property
242  ) const override;
243 
245  const SIM_Property &property) const override;
246 
247  /// Determines the appropriate timestep dependent on the velocity
248  /// field. If provided, maxvel will contain the maximum velocity on output.
249  fpreal calculateTimestep(SIM_Engine &engine,
250  const SIM_VectorField *velocity,
251  fpreal cflcond,
252  UT_Vector3 *maxvel = 0) const;
253 
254  /// Determines the appropriate timestep dependent on the geometry
255  /// data. The size of the particles is used as the limitting factor
256  /// for CFL condition.
257  /// If no particle scale or velocity exists, returns infinite.
258  /// If provided, maxspeed and minradius will contain the maximum speed
259  /// and minimum radius on output.
260  fpreal calculateTimestep(GU_ConstDetailHandle gdh,
261  fpreal cflcond,
262  fpreal *maxspeed = 0,
263  fpreal *minradius = 0) const;
264 
266  {
273 
275  bool isdensity;
281  const GU_Detail *gdp;
282  const GU_SDF *sdf;
283 
286  bool negate;
290  };
291  /// Builds a relationship field after most stuff has been setup
292  THREADED_METHOD1(GAS_SubSolver, parms.mask->shouldMultiThread(),
293  buildRelationshipFieldInternal,
294  const RelationshipParms &, parms)
295  void buildRelationshipFieldInternalPartial(
296  const RelationshipParms &parms,
297  const UT_JobInfo &info);
298 
299 public:
300  enum MIX_NAMES {
309  NUM_MIX
310  };
311 
313  {
320  NUM_TIMESCALE
321  };
322 
324  {
329  NUM_LENGTHSCALE
330  };
331 
332  /// Performs the requires mixing.
334  float d, float s)
335  {
336  switch (mixtype)
337  {
338  case MIX_COPY:
339  d = s;
340  break;
341  case MIX_ADD:
342  d += s;
343  break;
344  case MIX_SUB:
345  d -= s;
346  break;
347  case MIX_MUL:
348  d *= s;
349  break;
350  case MIX_DIV:
351  d = SYSsafediv(d, s);
352  break;
353  case MIX_MAX:
354  d = SYSmax(d, s);
355  break;
356  case MIX_MIN:
357  d = SYSmin(d, s);
358  break;
359  case MIX_AVERAGE:
360  d = d + s;
361  d *= 0.5f;
362  break;
363  case NUM_MIX:
364  UT_ASSERT(!"Invalid mix value");
365  break;
366  }
367 
368  return d;
369  }
370 
371  /// Scales value exponentially for timestep t.
372  /// v' = e ^ (ln(v) * t)
373  static float applyTimeScalePow(float value, float t);
374 
375  /// Applies the effect of TIMESCALE_NAMES to the additive
376  /// and multiplicative values.
377  static void applyTimeScale(float &add, float &mul,
378  float timestep, int timescale);
379 
380  /// Applies the effect of the given LENGTHSCALE_NAMES to
381  /// the quantitity given
382  static float applyLengthScale(float val, float width,
383  int scaletype);
384 
385 
386  /// Zeros out the force and optionaly torque attributes.
387  void clearForces(GU_Detail *gdp, bool cleartorque = false) const;
388  void clearForces(GU_Detail *gdp, const GA_PointGroup *grp, bool cleartorque) const;
389 
390 
391  /// Integrates the force into the velocity/angvel. Optionally
392  /// also adjusts the position by the effect of the acceleration
393  /// (*not* the effect of the velocity!)
395  applyForces,
396  GU_Detail *, gdp,
397  const GA_PointGroup *, ptgrp,
398  SIM_Time, timestep,
399  bool, densityscale,
400  bool, doorient,
401  bool, updatepos)
402  void applyForcesPartial(GU_Detail *gdp,
403  const GA_PointGroup *ptgrp,
404  SIM_Time timestep,
405  bool densityscale,
406  bool doorient,
407  bool updatepos,
408  const UT_JobInfo &info) const;
409 
410 
411  /// Builds the GAS_SPH data structure, either directly
412  /// from the given SIM_Geometry or by using any SIM_PointNeighbourList
413  /// attached as NeighbourList.
414  /// The object version looks for Geometry/NeighbourList
415  /// Returns false if failed, either due to null geometry or missing
416  /// vital attributes.
417  bool buildSPH(GAS_SPH &sph, const SIM_Geometry *geo) const;
418  bool buildSPH(GAS_SPH &sph, const SIM_Object *obj) const;
419 
420 protected:
421 
422  /// Holds the parm names for our mix methods.
423  static PRM_Name ourMixMethods[NUM_MIX+1];
425 
426  static PRM_Name ourTimeScaleMethods[NUM_TIMESCALE+1];
428 
429  static PRM_Name ourLengthScaleMethods[NUM_LENGTHSCALE+1];
431 
432 private:
435 };
436 
437 #endif
438 
#define SYSmax(a, b)
Definition: SYS_Math.h:1513
#define DECLARE_STANDARD_GETCASTTOTYPE()
Definition: SIM_DataUtils.h:50
#define DECLARE_CLASSNAME(DataClass, SuperClass)
Definition: SIM_DataUtils.h:20
#define THREADED_METHOD6_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6)
GAS_API void GASfillRelationshipMenu(void *, PRM_Name *names, int size, const PRM_SpareData *, const PRM_Parm *)
virtual SIM_PropertyResolver * getPropertyResolverSubclass(const SIM_Object &object, const SIM_Property &property) const
Builds a resolver for evaluating properties swiftly.
GT_API const UT_StringHolder time
#define THREADED_METHOD1(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1)
#define GAS_API
Definition: GAS_API.h:10
SIM_PropertyResolver * vel_lookup
static PRM_ChoiceList ourTimeScaleMenu
UT_ErrorSeverity
Definition: UT_Error.h:25
This class holds a three dimensional scalar field.
GLuint const GLchar * name
Definition: glcorearb.h:786
Definition: GU_SDF.h:302
GLdouble GLdouble t
Definition: glew.h:1403
static PRM_ChoiceList ourLengthScaleMenu
GLsizeiptr size
Definition: glcorearb.h:664
const SIM_RawField * stencil
GLint GLuint mask
Definition: glcorearb.h:124
Holds pointers to a number of SIM_Object objects.
GLhandleARB obj
Definition: glew.h:6266
INT property
Definition: wglew.h:145
long long int64
Definition: SYS_Types.h:116
#define SYS_STATIC_FORCE_INLINE
Definition: SYS_Inline.h:48
static PRM_ChoiceList ourMixMethodMenu
GLuint const GLuint * names
Definition: glew.h:2695
GLenum GLenum severity
Definition: glcorearb.h:2539
This class holds a three dimensional tensor field.
GLint GLsizei width
Definition: glcorearb.h:103
virtual SIM_Result solveObjectsSubclass(SIM_Engine &engine, SIM_ObjectArray &objects, SIM_ObjectArray &newobjects, SIM_ObjectArray &feedbacktoobjects, const SIM_Time &timestep)=0
virtual fpreal getPropertyAtPositionSubclass(const SIM_Object &object, const UT_Vector3 &worldpos, const SIM_Property &property) const
const GEO_PrimVolume * volume
GLuint GLfloat * val
Definition: glcorearb.h:1608
virtual SIM_Result postSolveObjectsSubclass(SIM_Engine &engine, SIM_ObjectArray &objects, SIM_ObjectArray &newobjects, SIM_ObjectArray &feedbacktoobjects, const SIM_Time &timestep)
Definition: SIM_Solver.h:176
fpreal64 fpreal
Definition: SYS_Types.h:277
GLuint index
Definition: glcorearb.h:786
This class holds a three dimensional scalar field.
#define GAS_NAME_PTGROUP
Definition: GAS_Utils.h:34
virtual bool postSolveGasSubclass(SIM_Engine &engine, SIM_Object *obj, SIM_Time time, SIM_Time timestep)
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:153
Definition: core.h:1131
ImageBuf OIIO_API add(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLint GLfloat GLint stencil
Definition: glcorearb.h:1278
#define SYSmin(a, b)
Definition: SYS_Math.h:1514
This class holds a three dimensional vector field.
GLdouble s
Definition: glew.h:1395
const SIM_RawField * surface
SYS_STATIC_FORCE_INLINE float mixValues(MIX_NAMES mixtype, float d, float s)
Performs the requires mixing.
SIM_Property
Definition: format.h:895
virtual fpreal getPropertyAtPointSubclass(const SIM_Object &object, int ptnum, const SIM_Property &property) const
ImageBuf OIIO_API mul(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
SYS_FORCE_INLINE GA_Size getNumPoints() const
Return the number of points.
Definition: GA_Detail.h:333
This implements a SIM_Geometry that copies the source geometry.