00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef SOFA_SIMULATION_MECHANICALACTION_H
00026 #define SOFA_SIMULATION_MECHANICALACTION_H
00027 #define SOFA_SUPPORT_MAPPED_MASS
00028 #if !defined(__GNUC__) || (__GNUC__ > 3 || (_GNUC__ == 3 && __GNUC_MINOR__ > 3))
00029 #pragma once
00030 #endif
00031
00032
00033 #include <sofa/simulation/common/Visitor.h>
00034 #include <sofa/core/componentmodel/behavior/BaseMechanicalState.h>
00035 #include <sofa/core/componentmodel/behavior/BaseMechanicalMapping.h>
00036 #include <sofa/core/componentmodel/behavior/Mass.h>
00037 #include <sofa/core/componentmodel/behavior/ForceField.h>
00038 #include <sofa/core/componentmodel/behavior/InteractionForceField.h>
00039 #include <sofa/core/componentmodel/behavior/InteractionConstraint.h>
00040 #include <sofa/core/componentmodel/behavior/Constraint.h>
00041
00042
00043 #include <iostream>
00044 using std::cerr;
00045 using std::endl;
00046
00047 namespace sofa
00048 {
00049
00050 namespace simulation
00051 {
00052
00053
00054 using namespace sofa::defaulttype;
00064 class MechanicalVisitor : public Visitor
00065 {
00066 public:
00067 typedef sofa::core::componentmodel::behavior::BaseMechanicalState::VecId VecId;
00068
00075
00076
00078 virtual Result processNodeTopDown(simulation::Node* node);
00079
00081 virtual Result fwdOdeSolver(simulation::Node* , core::componentmodel::behavior::OdeSolver* )
00082 {
00083 return RESULT_CONTINUE;
00084 }
00085
00087 virtual Result fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* )
00088 {
00089 return RESULT_CONTINUE;
00090 }
00091
00093 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* )
00094 {
00095 return RESULT_CONTINUE;
00096 }
00097
00099 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* )
00100 {
00101 return RESULT_CONTINUE;
00102 }
00103
00105 virtual Result fwdMass(simulation::Node* , core::componentmodel::behavior::BaseMass* )
00106 {
00107 return RESULT_CONTINUE;
00108 }
00109
00111 virtual Result fwdForceField(simulation::Node* , core::componentmodel::behavior::BaseForceField* )
00112 {
00113 return RESULT_CONTINUE;
00114 }
00115
00116
00118 virtual Result fwdInteractionForceField(simulation::Node* node, core::componentmodel::behavior::InteractionForceField* ff)
00119 {
00120 return fwdForceField(node, ff);
00121 }
00122
00124 virtual Result fwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* )
00125 {
00126 return RESULT_CONTINUE;
00127 }
00128
00130 virtual Result fwdInteractionConstraint(simulation::Node* node, core::componentmodel::behavior::InteractionConstraint* c)
00131 {
00132 return fwdConstraint(node, c);
00133 }
00134
00136
00144
00145
00147 virtual void processNodeBottomUp(simulation::Node* node);
00148
00150 virtual void bwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* )
00151 {}
00152
00154 virtual void bwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* )
00155 {}
00156
00158 virtual void bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* )
00159 {}
00160
00162 virtual void bwdOdeSolver(simulation::Node* , core::componentmodel::behavior::OdeSolver* )
00163 {}
00164
00165
00167 virtual void bwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* )
00168 {}
00169
00171
00172
00175 virtual const char* getCategoryName() const
00176 {
00177 return "animate";
00178 }
00179 };
00180
00183 class MechanicalVAvailVisitor : public MechanicalVisitor
00184 {
00185 public:
00186 VecId& v;
00187 MechanicalVAvailVisitor(VecId& v) : v(v)
00188 {}
00189 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00190
00192 virtual bool isThreadSafe() const
00193 {
00194 return false;
00195 }
00196 };
00197
00200 class MechanicalVAllocVisitor : public MechanicalVisitor
00201 {
00202 public:
00203 VecId v;
00204 MechanicalVAllocVisitor(VecId v) : v(v)
00205 {}
00206 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00207
00209 virtual bool isThreadSafe() const
00210 {
00211 return true;
00212 }
00213 };
00214
00216 class MechanicalVFreeVisitor : public MechanicalVisitor
00217 {
00218 public:
00219 VecId v;
00220 MechanicalVFreeVisitor(VecId v) : v(v)
00221 {}
00222 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00224 virtual bool isThreadSafe() const
00225 {
00226 return true;
00227 }
00228 };
00229
00232 class MechanicalVOpVisitor : public MechanicalVisitor
00233 {
00234 public:
00235 VecId v;
00236 VecId a;
00237 VecId b;
00238 double f;
00239 MechanicalVOpVisitor(VecId v, VecId a = VecId::null(), VecId b = VecId::null(), double f=1.0)
00240 : v(v), a(a), b(b), f(f)
00241 {}
00242
00243 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00244 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* );
00245
00246
00247
00249 virtual bool isThreadSafe() const
00250 {
00251 return true;
00252 }
00253 };
00254
00260 class MechanicalVMultiOpVisitor : public MechanicalVisitor
00261 {
00262 public:
00263 typedef core::componentmodel::behavior::BaseMechanicalState::VMultiOp VMultiOp;
00264 VMultiOp ops;
00265 MechanicalVMultiOpVisitor()
00266 {}
00267 MechanicalVMultiOpVisitor(const VMultiOp& o)
00268 : ops(o)
00269 {}
00270
00271 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00272 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* );
00273
00274
00275
00277 virtual bool isThreadSafe() const
00278 {
00279 return true;
00280 }
00281 };
00282
00284 class MechanicalVDotVisitor : public MechanicalVisitor
00285 {
00286 public:
00287 VecId a;
00288 VecId b;
00289 double* total;
00290 MechanicalVDotVisitor(VecId a, VecId b, double* t) : a(a), b(b), total(t)
00291 {}
00292
00294 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00295
00297 virtual bool isThreadSafe() const
00298 {
00299 return true;
00300 }
00302 virtual Result processNodeTopDown(simulation::Node* node, LocalStorage* stack);
00303
00305 virtual void processNodeBottomUp(simulation::Node* , LocalStorage* stack);
00306
00307 };
00308
00314 class MechanicalPropagateDxVisitor : public MechanicalVisitor
00315 {
00316 public:
00317 VecId dx;
00318 MechanicalPropagateDxVisitor(VecId dx) : dx(dx)
00319 {}
00320 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00321 virtual Result fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map);
00323 virtual bool isThreadSafe() const
00324 {
00325 return true;
00326 }
00327 };
00328
00329
00332 class MechanicalPropagateDxAndResetForceVisitor : public MechanicalVisitor
00333 {
00334 public:
00335 VecId dx,f;
00336 MechanicalPropagateDxAndResetForceVisitor(VecId dx, VecId f) : dx(dx), f(f)
00337 {}
00338 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00339 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00340 virtual Result fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map);
00342 virtual bool isThreadSafe() const
00343 {
00344 return true;
00345 }
00346 };
00347
00348
00349 class MechanicalPropagateAndAddDxVisitor : public MechanicalVisitor
00350 {
00351 public:
00352 VecId dx;
00353 MechanicalPropagateAndAddDxVisitor(VecId dx = VecId::dx()) : dx(dx)
00354 {}
00355
00356
00357
00358
00359
00360
00361 virtual Result fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map);
00362 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00363
00365 virtual bool isThreadSafe() const
00366 {
00367 return true;
00368 }
00369 };
00370
00371
00376 class MechanicalAddMDxVisitor : public MechanicalVisitor
00377 {
00378 public:
00379 VecId res;
00380 VecId dx;
00381 double factor;
00382 MechanicalAddMDxVisitor(VecId res, VecId dx=VecId(), double factor = 1.0)
00383 : res(res), dx(dx), factor(factor)
00384 {}
00385 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00386 virtual Result fwdMass(simulation::Node* , core::componentmodel::behavior::BaseMass* mass);
00387
00388 #ifdef SOFA_SUPPORT_MAPPED_MASS
00389 virtual Result fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00390 {
00391 if (!dx.isNull())
00392 map->propagateDx();
00393 return RESULT_CONTINUE;
00394 }
00395 #else
00396 virtual Result fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* )
00397 {
00398 return RESULT_PRUNE;
00399 }
00400 #endif
00401 #ifdef SOFA_SUPPORT_MAPPED_MASS
00402 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00403 {
00404 mm->resetForce();
00405 return RESULT_CONTINUE;
00406 }
00407 #else
00408 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* )
00409 {
00410 return RESULT_PRUNE;
00411 }
00412 #endif
00413 #ifdef SOFA_SUPPORT_MAPPED_MASS
00414 virtual void bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00415 {
00416 map->accumulateForce();
00417 }
00418 #endif
00419
00421 virtual bool isThreadSafe() const
00422 {
00423 return true;
00424 }
00425 };
00426
00429 class MechanicalAccFromFVisitor : public MechanicalVisitor
00430 {
00431 public:
00432 VecId a;
00433 VecId f;
00434 MechanicalAccFromFVisitor(VecId a, VecId f) : a(a), f(f)
00435 {}
00436 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00437 virtual Result fwdMass(simulation::Node* , core::componentmodel::behavior::BaseMass* mass);
00438
00440 virtual bool isThreadSafe() const
00441 {
00442 return true;
00443 }
00444 };
00445
00451 class MechanicalPropagatePositionAndVelocityVisitor : public MechanicalVisitor
00452 {
00453 public:
00454 double t;
00455 VecId x;
00456 VecId v;
00457 MechanicalPropagatePositionAndVelocityVisitor(double time=0, VecId x = VecId::position(), VecId v = VecId::velocity());
00458 virtual Result processNodeTopDown(simulation::Node* node);
00459 virtual void processNodeBottomUp(simulation::Node* node);
00460
00461 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00462 virtual Result fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map);
00463 virtual Result fwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c);
00464
00465
00467 virtual bool isThreadSafe() const
00468 {
00469 return true;
00470 }
00471 };
00472
00473
00479 class MechanicalPropagateFreePositionVisitor : public MechanicalVisitor
00480 {
00481 public:
00482 double t;
00483 VecId x;
00484 VecId v;
00485
00486
00487
00488 MechanicalPropagateFreePositionVisitor(double time=0, VecId x = VecId::position(), VecId v = VecId::velocity()): t(time), x(x), v(v)
00489 {
00490 }
00491 virtual Result processNodeTopDown(simulation::Node* node);
00492 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00493 virtual Result fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map);
00494 virtual Result fwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c);
00495
00497 virtual bool isThreadSafe() const
00498 {
00499 return true;
00500 }
00501 };
00502
00503
00507 class MechanicalResetForceVisitor : public MechanicalVisitor
00508 {
00509 public:
00510 VecId res;
00511 bool onlyMapped;
00512 MechanicalResetForceVisitor(VecId res, bool onlyMapped = false) : res(res), onlyMapped(onlyMapped)
00513 {}
00514 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00515 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00516
00518 virtual bool isThreadSafe() const
00519 {
00520 return true;
00521 }
00522 };
00523
00527 class MechanicalComputeForceVisitor : public MechanicalVisitor
00528 {
00529 public:
00530 VecId res;
00531 bool accumulate;
00532 MechanicalComputeForceVisitor(VecId res, bool accumulate = true) : res(res), accumulate(accumulate)
00533 {}
00534 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00535 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00536 virtual Result fwdForceField(simulation::Node* , core::componentmodel::behavior::BaseForceField* ff);
00537 virtual void bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map);
00538
00539
00541 virtual bool isThreadSafe() const
00542 {
00543 return true;
00544 }
00545 };
00546
00550 class MechanicalComputeDfVisitor : public MechanicalVisitor
00551 {
00552 public:
00553 VecId res;
00554 bool useV;
00555 bool accumulate;
00556 MechanicalComputeDfVisitor(VecId res, bool useV=false, bool accumulate=true) : res(res), useV(useV), accumulate(accumulate)
00557 {}
00558 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00559 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00560 virtual Result fwdForceField(simulation::Node* , core::componentmodel::behavior::BaseForceField* ff);
00561 virtual void bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map);
00562
00564 virtual bool isThreadSafe() const
00565 {
00566 return true;
00567 }
00568 };
00569
00570
00576 class MechanicalAddMBKdxVisitor : public MechanicalVisitor
00577 {
00578 public:
00579 VecId res;
00580 double mFactor;
00581 double bFactor;
00582 double kFactor;
00583 bool useV;
00584 bool accumulate;
00585 MechanicalAddMBKdxVisitor(VecId res, double mFactor, double bFactor, double kFactor, bool useV=false, bool accumulate = true)
00586 : res(res), mFactor(mFactor), bFactor(bFactor), kFactor(kFactor), useV(useV), accumulate(accumulate)
00587 {}
00588 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00589 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00590 virtual Result fwdForceField(simulation::Node* , core::componentmodel::behavior::BaseForceField* ff);
00591 virtual void bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map);
00592
00594 virtual bool isThreadSafe() const
00595 {
00596 return true;
00597 }
00598 };
00599
00600 class MechanicalResetConstraintVisitor : public MechanicalVisitor
00601 {
00602 public:
00603
00604 MechanicalResetConstraintVisitor()
00605 {}
00606
00607 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00608 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00609
00610
00612 virtual bool isThreadSafe() const
00613 {
00614 return true;
00615 }
00616 };
00617
00618
00619 class MechanicalAccumulateConstraint : public MechanicalVisitor
00620 {
00621 public:
00622 MechanicalAccumulateConstraint(unsigned int &_contactId, double &_mu)
00623 :contactId(_contactId), mu(_mu)
00624 {}
00625
00626 virtual Result fwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c);
00627 virtual void bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map);
00628
00629
00630 virtual bool isThreadSafe() const
00631 {
00632 return false;
00633 }
00634
00635 protected:
00636 unsigned int &contactId;
00637 double μ
00638 };
00639
00643 class MechanicalApplyConstraintsVisitor : public MechanicalVisitor
00644 {
00645 public:
00646 VecId res;
00647 double **W;
00648 MechanicalApplyConstraintsVisitor(VecId res, double **W = NULL) : res(res), W(W)
00649 {}
00650 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00651 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* );
00652 virtual void bwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c);
00653
00655 virtual bool isThreadSafe() const
00656 {
00657 return true;
00658 }
00659 };
00660
00663 class MechanicalBeginIntegrationVisitor : public MechanicalVisitor
00664 {
00665 public:
00666 double dt;
00667 MechanicalBeginIntegrationVisitor (double dt)
00668 : dt(dt)
00669 {}
00670 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00671 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00672
00674 virtual bool isThreadSafe() const
00675 {
00676 return true;
00677 }
00678 };
00679
00682 class MechanicalEndIntegrationVisitor : public MechanicalVisitor
00683 {
00684 public:
00685 double dt;
00686 MechanicalEndIntegrationVisitor (double dt)
00687 : dt(dt)
00688 {}
00689 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00690 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00691
00693 virtual bool isThreadSafe() const
00694 {
00695 return true;
00696 }
00697 };
00698
00701 class MechanicalIntegrationVisitor : public MechanicalVisitor
00702 {
00703 public:
00704 double dt;
00705 MechanicalIntegrationVisitor (double dt)
00706 : dt(dt)
00707 {}
00708 virtual Result fwdOdeSolver(simulation::Node* node, core::componentmodel::behavior::OdeSolver* obj);
00709 virtual void bwdOdeSolver(simulation::Node* , core::componentmodel::behavior::OdeSolver* )
00710 {
00711 }
00712
00714 virtual bool isThreadSafe() const
00715 {
00716 return true;
00717 }
00718 };
00719
00720
00721
00722
00723 class MechanicalComputeComplianceVisitor : public MechanicalVisitor
00724 {
00725 public:
00726 MechanicalComputeComplianceVisitor( double **W):_W(W)
00727 {
00728 }
00729 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* ms);
00730 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* ms);
00731
00732 private:
00733 double **_W;
00734 };
00735
00736
00740 class MechanicalComputeContactForceVisitor : public MechanicalVisitor
00741 {
00742 public:
00743 VecId res;
00744 MechanicalComputeContactForceVisitor(VecId res) : res(res)
00745 {}
00746 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00747 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm);
00748 virtual void bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map);
00749
00751 virtual bool isThreadSafe() const
00752 {
00753 return true;
00754 }
00755 };
00756
00760 class MechanicalAddSeparateGravityVisitor : public MechanicalVisitor
00761 {
00762 public:
00763
00764 double dt;
00765 MechanicalAddSeparateGravityVisitor(double dt) : dt(dt)
00766 {}
00767
00769 virtual Result fwdMass(simulation::Node* , core::componentmodel::behavior::BaseMass* mass);
00770
00771 };
00772
00773
00774
00775 }
00776
00777 }
00778
00779 #endif