MasterContactSolver.h
Go to the documentation of this file.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_COMPONENT_ODESOLVER_MASTERCONTACTSOLVER_H
00026 #define SOFA_COMPONENT_ODESOLVER_MASTERCONTACTSOLVER_H
00027
00028 #include <sofa/core/componentmodel/behavior/OdeSolver.h>
00029 #include <sofa/simulation/common/MasterSolverImpl.h>
00030 #include <sofa/simulation/tree/GNode.h>
00031 #include <sofa/simulation/common/MechanicalVisitor.h>
00032 #include <sofa/core/componentmodel/behavior/BaseConstraintCorrection.h>
00033 #include <sofa/core/componentmodel/behavior/OdeSolver.h>
00034 #include <sofa/simulation/common/OdeSolverImpl.h>
00035 #include <sofa/component/linearsolver/FullMatrix.h>
00036
00037 namespace sofa
00038 {
00039
00040 namespace component
00041 {
00042
00043 namespace odesolver
00044 {
00045
00046 using namespace sofa::defaulttype;
00047 using namespace sofa::component::linearsolver;
00048 using namespace helper::system::thread;
00049
00050 class LCP
00051 {
00052 public:
00053 int maxConst;
00054 LPtrFullMatrix<double> W, A;
00055 FullVector<double> dFree, f;
00056 double tol;
00057 int numItMax;
00058 unsigned int nbConst;
00059 bool useInitialF;
00060 double mu;
00061 int dim;
00062 private:
00063 bool lok;
00064
00065 public:
00066 LCP(unsigned int maxConstraint);
00067 ~LCP();
00068 void reset(void);
00069
00070 inline double** getW(void) {return W.lptr();};
00071 inline double& getMu(void) { return mu;};
00072 inline double* getDfree(void) {return dFree.ptr();};
00073 inline int getDfreeSize(void) {return dFree.size();};
00074 inline double getTolerance(void) {return tol;};
00075 inline void setTol(double t) {tol = t;};
00076 inline double getMaxIter(void) {return numItMax;};
00077 inline double* getF(void) {return f.ptr();};
00078 inline bool useInitialGuess(void) {return useInitialF;};
00079 inline unsigned int getNbConst(void) {return nbConst;};
00080 inline void setNbConst(unsigned int nbC) {nbConst = nbC;};
00081 inline unsigned int getMaxConst(void) {return maxConst;};
00082
00083 inline bool isLocked(void) {return false;};
00084 inline void lock(void) {lok = true;};
00085 inline void unlock(void) {lok = false;};
00086 inline void wait(void) {while(lok) ; }
00087 };
00088
00089
00090
00091 class MechanicalResetContactForceVisitor : public simulation::MechanicalVisitor
00092 {
00093 public:
00094 VecId force;
00095 MechanicalResetContactForceVisitor()
00096 {
00097 }
00098
00099 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* ms)
00100 {
00101 ms->resetContactForce();
00102 return RESULT_CONTINUE;
00103 }
00104
00105 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* ms)
00106 {
00107 ms->resetForce();
00108 return RESULT_CONTINUE;
00109 }
00110 };
00111
00112
00113 class MechanicalApplyContactForceVisitor : public simulation::MechanicalVisitor
00114 {
00115 public:
00116 VecId force;
00117 MechanicalApplyContactForceVisitor(double *f):_f(f)
00118 {
00119 }
00120 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* ms)
00121 {
00122 ms->applyContactForce(_f);
00123 return RESULT_CONTINUE;
00124 }
00125
00126 virtual Result fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* ms)
00127 {
00128 ms->applyContactForce(_f);
00129 return RESULT_CONTINUE;
00130 }
00131
00132 private:
00133 double *_f;
00134
00135
00136 };
00137
00138
00139
00140 class MechanicalGetConstraintValueVisitor : public simulation::MechanicalVisitor
00141 {
00142 public:
00143
00144 MechanicalGetConstraintValueVisitor(double *v): _v(v)
00145 {
00146 }
00147
00148 virtual Result fwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c)
00149 {
00150
00151 c->getConstraintValue(_v );
00152 return RESULT_CONTINUE;
00153 }
00154 private:
00155 double* _v;
00156
00157 };
00158
00159
00160 class MechanicalGetContactIDVisitor : public simulation::MechanicalVisitor
00161 {
00162 public:
00163 MechanicalGetContactIDVisitor(long *id, unsigned int offset = 0)
00164 : _id(id),_offset(offset)
00165 {
00166 }
00167
00168 virtual Result fwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c)
00169 {
00170 c->getConstraintId(_id, _offset);
00171 return RESULT_CONTINUE;
00172 }
00173
00174 private:
00175 long *_id;
00176 unsigned int _offset;
00177 };
00178
00179
00180
00181 class MasterContactSolver : public sofa::simulation::MasterSolverImpl
00182 {
00183 public:
00184 Data<bool> initial_guess;
00185 Data < double > tol;
00186 Data < int > maxIt;
00187 Data < double > mu;
00188
00189 MasterContactSolver();
00190
00191
00192 void step (double dt);
00193
00194
00195
00196 virtual void init();
00197 LCP* getLCP(void) {return (lcp == &lcp1) ? &lcp2 : &lcp1;};
00198
00199 private:
00200 std::vector<core::componentmodel::behavior::BaseConstraintCorrection*> constraintCorrections;
00201 void computeInitialGuess();
00202 void keepContactForcesValue();
00203
00204 void build_LCP();
00205
00206 unsigned int _numConstraints;
00207 double _mu;
00208 simulation::tree::GNode *context;
00209 LCP lcp1, lcp2;
00210 LPtrFullMatrix<double> *_A, *_W;
00211 FullVector<double> *_dFree, *_result;
00212 LCP* lcp;
00213
00214 typedef struct {
00215 Vector3 n;
00216 Vector3 t;
00217 Vector3 s;
00218 Vector3 F;
00219 long id;
00220
00221 } contactBuf;
00222
00223 contactBuf *_PreviousContactList;
00224 unsigned int _numPreviousContact;
00225 long *_cont_id_list;
00226 };
00227
00228 }
00229
00230 }
00231
00232 }
00233
00234 #endif