HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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
51 GASfillRelationshipMenu(void *, PRM_Name *names, int size,
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);
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);
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.
172  /// The negate flag controls the sign of the generated fields,
173  /// collision have "inside object" as negative so have a negate of true.
174  /// Mask should already be initialized as we only write to
175  /// new values that are more-in the relevant object.
176  /// To trigger a bandwidth, initialize mask to the max dist you
177  /// want to write.
178  /// The given fields must all be aligned.
179  /// Bandwidth is how many voxels to border particles by for our
180  /// lookup.
181  void buildRelationshipField(
183  SIM_VectorField *vel,
185  UT_DMatrix4 masktoworld,
186  const SIM_Object *srcobj,
187  bool usepoint, bool usesdf,
188  bool allownonsdf,
189  bool negate,
190  fpreal particlebandwidth,
191  fpreal bandwidth,
192  fpreal velscale = 1);
193 
194  /// Looks up the data referred to by the parameter (parameter name,
195  /// NOT data name here!) and finds its bounding box. Handles
196  /// fields and geometry. xform is set to the toworld transform
197  /// of the box, the box is in local space.
198  /// Returns false if no reference found. The size & center
199  /// will be left alone in that case.
200  /// The groupparmname will be referenced if it isn't null and
201  /// it is a geometry - then it will be a point group to use
202  /// for the limiting.
203  bool findReferenceBBox(
204  const SIM_Object *,
205  const char *parmname,
206  const char *groupparmname,
207  UT_Vector3 &center,
208  UT_Vector3 &size,
209  UT_DMatrix4 &xform);
210 
211  void reportCLError(SIM_Object *obj, int err, const char *msg) const;
212 
213 protected:
214  explicit GAS_SubSolver(const SIM_DataFactory *factory);
215  virtual ~GAS_SubSolver();
216 
217  /// Applies this subsolver for a single timestep.
218  /// Returns true on success
219  virtual bool solveGasSubclass(SIM_Engine &engine,
220  SIM_Object *obj,
221  SIM_Time time,
222  SIM_Time timestep) = 0;
223 
224  // Applies postSolve tasks if exists
225  virtual bool postSolveGasSubclass(SIM_Engine &engine,
226  SIM_Object *obj,
227  SIM_Time time,
228  SIM_Time timestep){ return true; };
229 
230  /// Get a property value by looking at the Physical Parms of an object.
231  fpreal getPropertyFromState(const SIM_Object &object,
232  const SIM_Property &property) const;
233 
234  /// Evaluates property at a given position
235  virtual fpreal getPropertyAtPositionSubclass(const SIM_Object &object,
236  const UT_Vector3 &worldspacepos,
237  const SIM_Property &property) const;
238  virtual fpreal getPropertyAtPointSubclass(const SIM_Object &object,
239  int ptnum, const SIM_Property &property) const;
240 
241  virtual SIM_PropertyResolver *getPropertyResolverSubclass(const SIM_Object &object, const SIM_Property &property) const;
242 
243  /// Determines the appropriate timestep dependent on the velocity
244  /// field. If provided, maxvel will contain the maximum velocity on output.
245  fpreal calculateTimestep(SIM_Engine &engine,
246  const SIM_VectorField *velocity,
247  fpreal cflcond,
248  UT_Vector3 *maxvel = 0) const;
249 
250  /// Determines the appropriate timestep dependent on the geometry
251  /// data. The size of the particles is used as the limitting factor
252  /// for CFL condition.
253  /// If no particle scale or velocity exists, returns infinite.
254  /// If provided, maxspeed and minradius will contain the maximum speed
255  /// and minimum radius on output.
256  fpreal calculateTimestep(GU_ConstDetailHandle gdh,
257  fpreal cflcond,
258  fpreal *maxspeed = 0,
259  fpreal *minradius = 0) const;
260 
262  {
268 
270  bool isdensity;
276  const GU_Detail *gdp;
277  const GU_SDF *sdf;
278 
281  bool negate;
285  };
286  /// Builds a relationship field after most stuff has been setup
287  THREADED_METHOD1(GAS_SubSolver, parms.mask->shouldMultiThread(),
288  buildRelationshipFieldInternal,
289  const RelationshipParms &, parms)
290  void buildRelationshipFieldInternalPartial(
291  const RelationshipParms &parms,
292  const UT_JobInfo &info);
293 
294 public:
295  enum MIX_NAMES {
304  NUM_MIX
305  };
306 
308  {
315  NUM_TIMESCALE
316  };
317 
319  {
324  NUM_LENGTHSCALE
325  };
326 
327  /// Performs the requires mixing.
329  float d, float s)
330  {
331  switch (mixtype)
332  {
333  case MIX_COPY:
334  d = s;
335  break;
336  case MIX_ADD:
337  d += s;
338  break;
339  case MIX_SUB:
340  d -= s;
341  break;
342  case MIX_MUL:
343  d *= s;
344  break;
345  case MIX_DIV:
346  d = SYSsafediv(d, s);
347  break;
348  case MIX_MAX:
349  d = SYSmax(d, s);
350  break;
351  case MIX_MIN:
352  d = SYSmin(d, s);
353  break;
354  case MIX_AVERAGE:
355  d = d + s;
356  d *= 0.5f;
357  break;
358  case NUM_MIX:
359  UT_ASSERT(!"Invalid mix value");
360  break;
361  }
362 
363  return d;
364  }
365 
366  /// Scales value exponentially for timestep t.
367  /// v' = e ^ (ln(v) * t)
368  static float applyTimeScalePow(float value, float t);
369 
370  /// Applies the effect of TIMESCALE_NAMES to the additive
371  /// and multiplicative values.
372  static void applyTimeScale(float &add, float &mul,
373  float timestep, int timescale);
374 
375  /// Applies the effect of the given LENGTHSCALE_NAMES to
376  /// the quantitity given
377  static float applyLengthScale(float val, float width,
378  int scaletype);
379 
380 
381  /// Zeros out the force and optionaly torque attributes.
382  void clearForces(GU_Detail *gdp, bool cleartorque = false) const;
383  void clearForces(GU_Detail *gdp, const GA_PointGroup *grp, bool cleartorque) const;
384 
385 
386  /// Integrates the force into the velocity/angvel. Optionally
387  /// also adjusts the position by the effect of the acceleration
388  /// (*not* the effect of the velocity!)
390  applyForces,
391  GU_Detail *, gdp,
392  const GA_PointGroup *, ptgrp,
393  SIM_Time, timestep,
394  bool, densityscale,
395  bool, doorient,
396  bool, updatepos)
397  void applyForcesPartial(GU_Detail *gdp,
398  const GA_PointGroup *ptgrp,
399  SIM_Time timestep,
400  bool densityscale,
401  bool doorient,
402  bool updatepos,
403  const UT_JobInfo &info) const;
404 
405 
406  /// Builds the GAS_SPH data structure, either directly
407  /// from the given SIM_Geometry or by using any SIM_PointNeighbourList
408  /// attached as NeighbourList.
409  /// The object version looks for Geometry/NeighbourList
410  /// Returns false if failed, either due to null geometry or missing
411  /// vital attributes.
412  bool buildSPH(GAS_SPH &sph, const SIM_Geometry *geo) const;
413  bool buildSPH(GAS_SPH &sph, const SIM_Object *obj) const;
414 
415 protected:
416 
417  /// Holds the parm names for our mix methods.
418  static PRM_Name ourMixMethods[NUM_MIX+1];
420 
421  static PRM_Name ourTimeScaleMethods[NUM_TIMESCALE+1];
423 
424  static PRM_Name ourLengthScaleMethods[NUM_LENGTHSCALE+1];
426 
427 private:
430 };
431 
432 #endif
433 
#define SYSmax(a, b)
Definition: SYS_Math.h:1365
#define DECLARE_STANDARD_GETCASTTOTYPE()
Definition: SIM_DataUtils.h:45
#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.
#define THREADED_METHOD1(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1)
#define GAS_API
Definition: GAS_API.h:10
SIM_PropertyResolver * vel_lookup
static PRM_ChoiceList ourTimeScaleMenu
GLint GLuint mask
Definition: glcorearb.h:123
UT_ErrorSeverity
Definition: UT_Error.h:25
This class holds a three dimensional scalar field.
Definition: GU_SDF.h:289
GLsizeiptr size
Definition: glcorearb.h:663
static PRM_ChoiceList ourLengthScaleMenu
GLint GLsizei width
Definition: glcorearb.h:102
long long int64
Definition: SYS_Types.h:100
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:102
Holds pointers to a number of SIM_Object objects.
#define SYS_STATIC_FORCE_INLINE
Definition: SYS_Inline.h:48
static PRM_ChoiceList ourMixMethodMenu
GLenum GLenum severity
Definition: glcorearb.h:2538
GLboolean * data
Definition: glcorearb.h:130
GLuint const GLchar * name
Definition: glcorearb.h:785
This class holds a three dimensional tensor field.
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
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:263
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
GLuint index
Definition: glcorearb.h:785
GLuint GLfloat * val
Definition: glcorearb.h:1607
This class holds a three dimensional scalar field.
#define GAS_NAME_PTGROUP
Definition: GAS_Utils.h:32
virtual bool postSolveGasSubclass(SIM_Engine &engine, SIM_Object *obj, SIM_Time time, SIM_Time timestep)
#define SYSmin(a, b)
Definition: SYS_Math.h:1366
This class holds a three dimensional vector field.
const SIM_RawField * surface
SYS_STATIC_FORCE_INLINE float mixValues(MIX_NAMES mixtype, float d, float s)
Performs the requires mixing.
SIM_Property
virtual fpreal getPropertyAtPointSubclass(const SIM_Object &object, int ptnum, const SIM_Property &property) const
SYS_FORCE_INLINE GA_Size getNumPoints() const
Return the number of points.
Definition: GA_Detail.h:281
This implements a SIM_Geometry that copies the source geometry.