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_MECHANICALMATRIXVISITOR_H
00026 #define SOFA_SIMULATION_MECHANICALMATRIXVISITOR_H
00027
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 #include <sofa/defaulttype/BaseMatrix.h>
00042 #include <sofa/defaulttype/BaseVector.h>
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 MechanicalMatrixVisitor : 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_PRUNE;
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
00166
00167
00170 virtual const char* getCategoryName() const
00171 {
00172 return "animate";
00173 }
00174
00175 unsigned int offsetOnEnter, offsetOnExit;
00176 };
00177
00178
00180 class MechanicalGetMatrixDimensionVisitor : public MechanicalMatrixVisitor
00181 {
00182 public:
00183 unsigned int * const nbRow;
00184 unsigned int * const nbCol;
00185 MechanicalGetMatrixDimensionVisitor(unsigned int * const _nbRow, unsigned int * const _nbCol)
00186 : nbRow(_nbRow), nbCol(_nbCol)
00187 {}
00188
00189 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* ms)
00190 {
00191 ms->contributeToMatrixDimension(nbRow, nbCol);
00192 return RESULT_CONTINUE;
00193 }
00194 };
00195
00196
00198 class MechanicalAddMBK_ToMatrixVisitor : public MechanicalMatrixVisitor
00199 {
00200 public:
00201 BaseMatrix *mat;
00202 double m, b, k;
00203
00204
00205 MechanicalAddMBK_ToMatrixVisitor(BaseMatrix *_mat, double _m=0.0, double _b=0.0, double _k=0.0, unsigned int _offset=0)
00206 : mat(_mat),m(_m),b(_b),k(_k)
00207 {
00208 offsetOnEnter = _offset;
00209 offsetOnExit = _offset;
00210 }
00211
00212 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* ms)
00213 {
00214 ms->setOffset(offsetOnExit);
00215 return RESULT_CONTINUE;
00216 }
00217
00218 virtual Result fwdForceField(simulation::Node* , core::componentmodel::behavior::BaseForceField* ff)
00219 {
00220 if ((mat != NULL)&&(k!=0.0))
00221 {
00222
00223 ff->addMBKToMatrix(mat,m,b,k,offsetOnEnter);
00224 }
00225
00226 return RESULT_CONTINUE;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 virtual Result fwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c)
00244 {
00245 if (mat != NULL)
00246 {
00247
00248 c->applyConstraint(mat, offsetOnEnter);
00249 }
00250
00251 return RESULT_CONTINUE;
00252 }
00253 };
00254
00255 #if 0 // deprecated: as dx is stored in MechanicalState, compute df there and then convert to BaseVector using MechanicalMultiVector2BaseVectorVisitor
00256
00257 class MechanicalAddMBKdx_ToVectorVisitor : public MechanicalMatrixVisitor
00258 {
00259 public:
00260 BaseVector *vect;
00261 VecId dx;
00262 double m, b, k;
00263
00264
00265 MechanicalAddMBKdx_ToVectorVisitor(BaseVector *_vect, VecId _dx, double _m=0.0, double _b=0.0, double _k=0.0, unsigned int _offset=0)
00266 : vect(_vect), dx(_dx), m(_m),b(_b),k(_k)
00267 {
00268 offsetOnEnter = _offset;
00269 offsetOnExit = _offset;
00270 }
00271
00272 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00273 {
00274 mm->setOffset(offsetOnExit);
00275
00276 if (!dx.isNull())
00277 mm->setDx(dx);
00278 return RESULT_CONTINUE;
00279 }
00280
00281 virtual Result fwdForceField(simulation::Node* , core::componentmodel::behavior::BaseForceField* ff)
00282 {
00283 if ((vect != NULL)&&(k != 0.0))
00284 {
00285
00286 ff->addKDxToVector(vect,k,offsetOnEnter);
00287 }
00288
00289 return RESULT_CONTINUE;
00290 }
00291
00292 virtual Result fwdMass(simulation::Node* , core::componentmodel::behavior::BaseMass* mass)
00293 {
00294 if ((vect != NULL)&&(m != 0.0))
00295 {
00296
00297 if (dx.isNull())
00298 std::cout << "Dx Null\n";
00299 else
00300 std::cout << "Dx Not Null\n";
00301
00302 mass->addMDxToVector(vect,m,offsetOnEnter,dx.isNull());
00303 }
00304
00305 return RESULT_CONTINUE;
00306 }
00307
00308 virtual Result fwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c)
00309 {
00310 if (vect != NULL)
00311 {
00312
00313 c->applyConstraint(vect, offsetOnEnter);
00314 }
00315
00316 return RESULT_CONTINUE;
00317 }
00318 };
00319 #endif
00320
00321 class MechanicalMultiVector2BaseVectorVisitor : public MechanicalMatrixVisitor
00322 {
00323 public:
00324 VecId src;
00325 BaseVector *vect;
00326 unsigned int offset;
00327
00328 MechanicalMultiVector2BaseVectorVisitor(VecId _src, defaulttype::BaseVector * _vect, unsigned int _offset=0)
00329 : src(_src),vect(_vect),offset(_offset)
00330 {
00331 }
00332
00333 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00334 {
00335 if (vect!= NULL)
00336 {
00337 mm->loadInBaseVector(vect, src, offset);
00338 }
00339
00340 return RESULT_CONTINUE;
00341 }
00342 };
00343
00344 class MechanicalMultiVectorPeqBaseVectorVisitor : public MechanicalMatrixVisitor
00345 {
00346 public:
00347 BaseVector *src;
00348 VecId dest;
00349 unsigned int offset;
00350
00351 MechanicalMultiVectorPeqBaseVectorVisitor(VecId _dest, defaulttype::BaseVector * _src, unsigned int _offset=0)
00352 : src(_src),dest(_dest),offset(_offset)
00353 {
00354 }
00355
00356 virtual Result fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00357 {
00358 if (src!= NULL)
00359 {
00360 mm->addBaseVectorToState(dest, src, offset);
00361 }
00362
00363 return RESULT_CONTINUE;
00364 }
00365 };
00366
00367 }
00368
00369 }
00370
00371 #endif