00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __GAS_Integrator__
00022 #define __GAS_Integrator__
00023
00024 #include "GAS_API.h"
00025
00026 #include "GAS_SubSolver.h"
00027 #include "GAS_Utils.h"
00028
00029 #include <UT/UT_RefArray.h>
00030 #include <UT/UT_Quaternion.h>
00031 #include <UT/UT_Vector.h>
00032 #include <UT/UT_ThreadedAlgorithm.h>
00033
00034 class GU_Detail;
00035
00036 class SIM_GeometryCopy;
00037 class SIM_Impacts;
00038
00039 class UT_DMatrix4;
00040 class UT_Vector3Array;
00041
00042
00043 #define GAS_RK_45_NUMSTEPS 6
00044 #define GAS_RK_4_NUMSTEPS 4
00045 #define GAS_RK_21_NUMSTEPS 3
00046 #define GAS_RK_32_NUMSTEPS 4
00047
00048 class GAS_API GAS_Integrator : public GAS_SubSolver
00049 {
00050 public:
00051 GETSET_DATA_FUNCS_I(SIM_NAME_PRIMARYSOLVER, PrimarySolver);
00052 GET_DATA_FUNC_S(GAS_NAME_GEOMETRY, GeometryName);
00053 GET_DATA_FUNC_I("integratetype", IntegrateType);
00054 GET_DATA_FUNC_I("advecttype", AdvectType);
00055 GET_DATA_FUNC_F("xsphconstant", XsphConstant);
00056 GET_DATA_FUNC_B("docollision", DoCollision);
00057 GET_DATA_FUNC_B("collisionuv", CollisionUV);
00058 GET_DATA_FUNC_I("scaletype", ScaleType);
00059 GET_DATA_FUNC_B("doincremental", IncrementalForce);
00060 GET_DATA_FUNC_B("integrateorientation", IntegrateOrientation);
00061 GET_DATA_FUNC_F("errortolerance", ErrorTolerance);
00062 GET_DATA_FUNC_F("repetitiontolerance", RepTolerance);
00063 GET_DATA_FUNC_F("minsubstep", MinSubstep);
00064 GET_DATA_FUNC_F("maxsubstep", MaxSubstep);
00065
00066
00067 enum IntegrateMethod {
00068 EULER,
00069 MIDPOINT,
00070 RUNGE_KUTTA,
00071 #if 0
00072 NEW_RUNGE_KUTTA,
00073 #endif
00074 RUNGE_KUTTA_FEHLBERG,
00075 RUNGE_KUTTA_21,
00076 RUNGE_KUTTA_32
00077 };
00078
00079
00080 enum ScaleMethod {
00081 MASS,
00082 DENSITY
00083 };
00084
00085
00086 enum AdvectionMethod {
00087 STANDARD = 0,
00088 XSPH
00089 };
00090
00091
00092
00093
00094 virtual SIM_Result solveObjectsSubclass(SIM_Engine &engine,
00095 SIM_ObjectArray &objects,
00096 SIM_ObjectArray &newobjects,
00097 SIM_ObjectArray &feedbacktoobjects,
00098 const SIM_Time ×tep);
00099
00100 bool shouldMultiThread() { return true; }
00101
00102 protected:
00103 explicit GAS_Integrator(const SIM_DataFactory *factory);
00104 virtual ~GAS_Integrator();
00105
00106 virtual bool solveGasSubclass(SIM_Engine &engine,
00107 SIM_Object *obj,
00108 SIM_Time time,
00109 SIM_Time timestep)
00110 {
00111 return true;
00112 }
00113
00114 virtual void getImpulseMassMatrixSubclass(
00115 const SIM_Object &object,
00116 const UT_Vector3 &impulseworldpos,
00117 UT_DMatrix3 &immatrix) const;
00118 virtual void getPointImpulseMassMatrixSubclass(
00119 const SIM_Object &object,
00120 int ptnum, UT_DMatrix3 &immatrix) const;
00121
00122 private:
00123
00124
00125 struct ObjectInfo {
00126 UT_Vector3Array myInitialPositions;
00127 UT_Vector3Array myInitialVelocities;
00128 UT_RefArray<UT_Quaternion> myInitialOrientations;
00129 UT_Vector3Array myInitialAngularVelocities;
00130
00131 UT_Vector3Array myCurrentPositions;
00132 UT_Vector3Array myCurrentVelocities;
00133 UT_RefArray<UT_Quaternion> myCurrentOrientations;
00134 UT_Vector3Array myCurrentAngularVelocities;
00135
00136 UT_Vector3Array myTotalPositions;
00137 UT_Vector3Array myTotalVelocities;
00138 UT_RefArray<UT_Quaternion> myTotalOrientations;
00139 UT_Vector3Array myTotalAngularVelocities;
00140 };
00141
00142 typedef UT_RefArray<UT_Quaternion> gas_QuatArray;
00143
00144
00145
00146 struct RungeKuttaDataTable {
00147
00148
00149
00150
00151 UT_RefArray<UT_Vector3Array> myPositionStepData;
00152 UT_RefArray<UT_Vector3Array> myVelocityStepData;
00153 UT_RefArray<UT_Vector3Array> myOrientationStepData;
00154 UT_RefArray<UT_Vector3Array> myAngVelocityStepData;
00155 int myNumSteps;
00156
00157 RungeKuttaDataTable() : myNumSteps(0) {}
00158
00159
00160 UT_Vector3Array &getPositionStep(int i)
00161 {
00162 return myPositionStepData(i);
00163 }
00164
00165 UT_Vector3Array &getVelocityStep(int i)
00166 {
00167 return myVelocityStepData(i);
00168 }
00169
00170 UT_Vector3Array &getOrientationStep(int i)
00171 {
00172 return myOrientationStepData(i);
00173 }
00174
00175 UT_Vector3Array &getAngVelocityStep(int i)
00176 {
00177 return myAngVelocityStepData(i);
00178 }
00179
00180 void resizeIfNeeded(int npts, bool doangular = false)
00181 {
00182 for (int i = 0; i < myNumSteps; i++)
00183 {
00184 myPositionStepData(i).resizeIfNeeded(npts);
00185 myVelocityStepData(i).resizeIfNeeded(npts);
00186
00187 if (doangular)
00188 {
00189 myOrientationStepData(i).resizeIfNeeded(npts);
00190 myAngVelocityStepData(i).resizeIfNeeded(npts);
00191 }
00192
00193 myPositionStepData(i).entries(npts);
00194 myVelocityStepData(i).entries(npts);
00195 myOrientationStepData(i).entries(npts);
00196 myAngVelocityStepData(i).entries(npts);
00197 }
00198 }
00199
00200 void addStepsIfNeeded(int numsteps)
00201 {
00202 while (myNumSteps < numsteps)
00203 {
00204 myPositionStepData.append();
00205 myVelocityStepData.append();
00206 myOrientationStepData.append();
00207 myAngVelocityStepData.append();
00208
00209 myNumSteps++;
00210 }
00211 }
00212 };
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 void solveRungeKuttaSteps(SIM_Engine &engine,
00225 SIM_ObjectArray &objects,
00226 SIM_ObjectArray &newobjects,
00227 SIM_ObjectArray &feedbacktoobjects,
00228 const SIM_Time ×tep,
00229 int numsteps,
00230 const fpreal64 *coefficients,
00231 const fpreal64 *timecoefficients,
00232 bool cplUpdate=true);
00233
00234
00235
00236
00237
00238
00239
00240
00241 void reinitializeSystems(SIM_ObjectArray &objects,
00242 int numsteps, int stepnum,
00243 const SIM_Time ×tep,
00244 const fpreal64 *coefficients,
00245 bool cplUpdate=true);
00246
00247
00248
00249 void reinitializeSystem(GU_Detail *gdp,
00250 RungeKuttaDataTable &data,
00251 ObjectInfo &inf,
00252 int numsteps, int stepnum,
00253 const SIM_Time ×tep,
00254 const fpreal64 *coefficients,
00255 bool cplUpdate=true);
00256
00257
00258
00259
00260 void computeFinalStates(SIM_ObjectArray &objects,
00261 int numsteps, const fpreal64 *coefficients);
00262
00263
00264
00265 void computeFinalState(GU_Detail *gdp,
00266 RungeKuttaDataTable &data,
00267 ObjectInfo &inf, int numsteps,
00268 const fpreal64 *coefficients);
00269
00270
00271
00272 void resetInitialStates(SIM_ObjectArray &objects);
00273
00274
00275 void resetInitialState(GU_Detail *gdp, ObjectInfo &inf);
00276
00277
00278
00279 void cacheSystemStates(SIM_ObjectArray &objects);
00280
00281
00282 void cacheSystemState(GU_Detail *gdp, ObjectInfo &inf);
00283
00284
00285
00286
00287 fpreal64 getMaxDistance(SIM_ObjectArray &objects);
00288
00289
00290 fpreal64 getDistance(GU_Detail *gdp, ObjectInfo &inf);
00291
00292
00293
00294
00295
00296
00297
00298 bool RKF45succeeded(SIM_ObjectArray &objects,
00299 const SIM_Time ×tep);
00300
00301
00302
00303
00304 bool RKF45succeeded(GU_Detail *gdp, ObjectInfo &inf,
00305 const SIM_Time ×tep, fpreal tolerance,
00306 fpreal reptolerance, fpreal minsubstep,
00307 fpreal maxsubstep);
00308
00309
00310
00311
00312
00313
00314
00315 bool embeddedRKsucceeded(SIM_ObjectArray &objects,
00316 const SIM_Time ×tep,
00317 fpreal64 toleranceCoefficient);
00318
00319
00320
00321
00322 bool embeddedRKsucceeded(GU_Detail *gdp, ObjectInfo &inf,
00323 const SIM_Time ×tep, fpreal tolerance,
00324 fpreal reptolerance, fpreal minsubstep,
00325 fpreal maxsubstep,
00326 fpreal64 toleranceCoefficient);
00327
00328
00329
00330
00331 bool integrationSucceeded(SIM_ObjectArray &objects,
00332 const SIM_Time ×tep);
00333
00334
00335
00336
00337 bool integrationSucceeded(GU_Detail *gdp, ObjectInfo &inf,
00338 const SIM_Time ×tep, fpreal tolerance,
00339 fpreal reptolerance, fpreal minsubstep,
00340 fpreal maxsubstep);
00341
00342
00343
00344 SIM_Result doEuler(SIM_Engine &engine,
00345 SIM_ObjectArray &objects,
00346 SIM_ObjectArray &newobjects,
00347 SIM_ObjectArray &feedbacktoobjects,
00348 const SIM_Time ×tep);
00349
00350
00351
00352 void doMidpoint(SIM_Engine &engine,
00353 SIM_ObjectArray &objects,
00354 SIM_ObjectArray &newobjects,
00355 SIM_ObjectArray &feedbacktoobjects,
00356 const SIM_Time ×tep);
00357
00358
00359
00360 void doRungeKutta(SIM_Engine &engine,
00361 SIM_ObjectArray &objects,
00362 SIM_ObjectArray &newobjects,
00363 SIM_ObjectArray &feedbacktoobjects,
00364 const SIM_Time ×tep);
00365
00366
00367
00368
00369 SIM_Result doRungeKuttaFehlberg(SIM_Engine &engine,
00370 SIM_ObjectArray &objects,
00371 SIM_ObjectArray &newobjects,
00372 SIM_ObjectArray &feedbacktoobjects,
00373 const SIM_Time ×tep);
00374
00375
00376
00377
00378 SIM_Result doRungeKutta21(SIM_Engine &engine,
00379 SIM_ObjectArray &objects,
00380 SIM_ObjectArray &newobjects,
00381 SIM_ObjectArray &feedbacktoobjects,
00382 const SIM_Time ×tep);
00383
00384
00385
00386
00387 SIM_Result doRungeKutta32(SIM_Engine &engine,
00388 SIM_ObjectArray &objects,
00389 SIM_ObjectArray &newobjects,
00390 SIM_ObjectArray &feedbacktoobjects,
00391 const SIM_Time ×tep);
00392
00393
00394
00395 void doLeapfrog(SIM_Engine &engine,
00396 SIM_ObjectArray &objects,
00397 SIM_ObjectArray &newobjects,
00398 SIM_ObjectArray &feedbacktoobjects,
00399 const SIM_Time ×tep);
00400
00401
00402
00403
00404 void leapfrogAdvectObjs(SIM_ObjectArray &objects,
00405 const SIM_Time ×tep);
00406
00407 void leapfrogAdvect(GU_Detail *gdp,
00408 const SIM_Time ×tep);
00409
00410 void leapfrogIntegrateObjs(SIM_ObjectArray &objects,
00411 const SIM_Time ×tep);
00412
00413 void leapfrogIntegrate(GU_Detail *gdp,
00414 const SIM_Time ×tep);
00415
00416 #if 0
00417
00418
00419
00420
00421
00422
00423
00424 void doNewRungeKutta(SIM_Engine &engine,
00425 SIM_ObjectArray &objects,
00426 SIM_ObjectArray &newobjects,
00427 SIM_ObjectArray &feedbacktoobjects,
00428 const SIM_Time ×tep);
00429 #endif
00430
00431
00432
00433 void initObjectInfoArray(SIM_ObjectArray &objects,
00434 int numRungeKuttaSteps = 0);
00435
00436
00437
00438
00439 void applyAllSolvers(SIM_Engine &engine,
00440 SIM_ObjectArray &objects,
00441 SIM_ObjectArray &newobjects,
00442 SIM_ObjectArray &feedbacktoobjects,
00443 const SIM_Time ×tep,
00444 fpreal64 timescale,
00445 bool incremental = false);
00446
00447 #if 0
00448
00449
00450 void applyPositionSolver(SIM_Engine &engine,
00451 SIM_ObjectArray &objects,
00452 SIM_ObjectArray &newobjects,
00453 SIM_ObjectArray &feedbacktoobjects,
00454 const SIM_Time ×tep,
00455 fpreal64 timescale);
00456 #endif
00457
00458
00459 void clearAllForces(SIM_ObjectArray &objects);
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 void applyCurrentDeltas(GU_Detail *gdp,
00470 const SIM_Time ×tep,
00471 ObjectInfo &inf,
00472 fpreal64 currentscale,
00473 fpreal64 totalscale,
00474 fpreal64 currentvscale,
00475 fpreal64 totalvscale);
00476
00477
00478
00479 void applyDeltasToObjs(SIM_ObjectArray &objects,
00480 const SIM_Time ×tep,
00481 fpreal64 currentscale,
00482 fpreal64 totalscale,
00483 fpreal64 currentvscale,
00484 fpreal64 totalvscale);
00485
00486
00487
00488
00489
00490
00491
00492
00493 void applyVelocityChanges(GU_Detail *gdp,
00494 const SIM_Time ×tep,
00495 ObjectInfo &inf,
00496 fpreal64 posscale = 1.0,
00497 bool predict = true,
00498 fpreal64 velscale = 1.0);
00499
00500 void applyVelocityChangesToObjs(SIM_ObjectArray &objects,
00501 const SIM_Time ×tep,
00502 fpreal64 posscale = 1.0,
00503 bool predict = true,
00504 fpreal64 velscale = 1.0);
00505
00506
00507
00508
00509 void applyVelocityIncrements(GU_Detail *gdp,
00510 const SIM_Time ×tep,
00511 ObjectInfo &inf);
00512
00513 void applyVelocityIncrementsToObjs(SIM_ObjectArray &objects,
00514 const SIM_Time ×tep);
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 THREADED_METHOD4(GAS_Integrator, shouldMultiThread(), advectParticles,
00525 GU_Detail *, gdp,
00526 const SIM_Time &, timestep,
00527 const UT_Vector3Array &, velocities,
00528 UT_Vector3Array &, positions)
00529 void advectParticlesPartial(GU_Detail *gdp,
00530 const SIM_Time ×tep,
00531 const UT_Vector3Array &velocities,
00532 UT_Vector3Array &positions,
00533 const UT_JobInfo &info);
00534
00535
00536 void resetObjectStates(SIM_ObjectArray &objects);
00537
00538
00539 void resetState(GU_Detail *gdp, ObjectInfo &inf);
00540
00541
00542
00543
00544 void setFinalValues(SIM_ObjectArray &objects);
00545
00546
00547
00548 void bounceParticleFromImpact(GU_Detail *gdp,
00549 ObjectInfo &inf,
00550 const SIM_Time &starttime,
00551 const SIM_Time &endtime,
00552 const SIM_Time ×tep,
00553 const UT_DMatrix4 &xform,
00554 const UT_DMatrix4 &ixform,
00555 const SIM_Impacts *impacts,
00556 int impactidx, int ptnum);
00557
00558
00559 void respondToCollisions(SIM_Engine &engine,
00560 SIM_Object &object,
00561 ObjectInfo &inf,
00562 const SIM_ObjectArray &affectors,
00563 const UT_DMatrix4 &xform,
00564 const UT_DMatrix4 &ixform,
00565 const UT_DMatrix4 &posxform,
00566 const SIM_Time &starttime,
00567 const SIM_Time &endtime,
00568 const SIM_Time ×tep,
00569 const char *impactdataname,
00570 bool clearimpacts = false);
00571
00572
00573 void handleObjectImpacts(SIM_Engine &engine,
00574 SIM_Object &object,
00575 ObjectInfo &inf,
00576 const SIM_Time &starttime,
00577 const SIM_Time &endtime,
00578 const SIM_Time ×tep,
00579 bool clearimpacts = false);
00580
00581
00582 void handleAllImpacts(SIM_Engine &engine,
00583 SIM_ObjectArray &objects,
00584 const SIM_Time &starttime,
00585 const SIM_Time &endtime,
00586 const SIM_Time ×tep,
00587 bool clearimpacts = false);
00588
00589
00590 void doPostSolveUpdates( SIM_Engine &engine,
00591 SIM_ObjectArray &objects,
00592 SIM_ObjectArray &newobjects,
00593 SIM_ObjectArray &feedbacktoobjects,
00594 const SIM_Time ×tep );
00595
00596 static const SIM_DopDescription *getDopDescription();
00597
00598
00599 const SIM_Solver *getCurrentSolver() const;
00600
00601
00602
00603
00604 UT_RefArray<ObjectInfo> myObjectInfoArray;
00605
00606
00607
00608
00609
00610
00611 UT_RefArray<RungeKuttaDataTable> myRungeKuttaData;
00612
00613
00614
00615 SIM_Engine *myEngine;
00616
00617
00618
00619 static const fpreal64 RK_45_COEFS[][GAS_RK_45_NUMSTEPS-1];
00620 static const fpreal64 RK_45_TIME_COEFS[GAS_RK_45_NUMSTEPS-1];
00621 static const fpreal64 RK_45_TOTAL_COEFS4[GAS_RK_45_NUMSTEPS];
00622 static const fpreal64 RK_45_TOTAL_COEFS5[GAS_RK_45_NUMSTEPS];
00623
00624 static const fpreal64 RK_4_COEFS[][GAS_RK_4_NUMSTEPS-1];
00625 static const fpreal64 RK_4_TIME_COEFS[GAS_RK_4_NUMSTEPS-1];
00626 static const fpreal64 RK_4_TOTAL_COEFS[GAS_RK_4_NUMSTEPS];
00627
00628 static const fpreal64 RK_21_COEFS[][GAS_RK_21_NUMSTEPS-1];
00629 static const fpreal64 RK_21_TIME_COEFS[GAS_RK_21_NUMSTEPS-1];
00630 static const fpreal64 RK_21_TOTAL_COEFS1[GAS_RK_21_NUMSTEPS];
00631 static const fpreal64 RK_21_TOTAL_COEFS2[GAS_RK_21_NUMSTEPS];
00632 static const fpreal64 RK_21_TOLERANCE_COEF;
00633
00634 static const fpreal64 RK_32_COEFS[][GAS_RK_32_NUMSTEPS-1];
00635 static const fpreal64 RK_32_TIME_COEFS[GAS_RK_32_NUMSTEPS-1];
00636 static const fpreal64 RK_32_TOTAL_COEFS2[GAS_RK_32_NUMSTEPS];
00637 static const fpreal64 RK_32_TOTAL_COEFS3[GAS_RK_32_NUMSTEPS];
00638
00639 SIM_Solver *myCurrentSolver;
00640
00641 DECLARE_STANDARD_GETCASTTOTYPE();
00642 DECLARE_DATAFACTORY(GAS_Integrator,
00643 GAS_SubSolver,
00644 "GAS Integrator",
00645 getDopDescription());
00646 };
00647
00648 #endif
00649