TetrahedronFEMForceField.h

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #ifndef SOFA_COMPONENT_FORCEFIELD_TETRAHEDRONFEMFORCEFIELD_H
00026 #define SOFA_COMPONENT_FORCEFIELD_TETRAHEDRONFEMFORCEFIELD_H
00027 
00028 #include <sofa/core/componentmodel/behavior/ForceField.h>
00029 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00030 #include <sofa/helper/vector.h>
00031 #include <sofa/defaulttype/Vec.h>
00032 #include <sofa/defaulttype/Mat.h>
00033 
00034 
00035 // corotational tetrahedron from
00036 // @InProceedings{NPF05,
00037 //   author       = "Nesme, Matthieu and Payan, Yohan and Faure, Fran\c{c}ois",
00038 //   title        = "Efficient, Physically Plausible Finite Elements",
00039 //   booktitle    = "Eurographics (short papers)",
00040 //   month        = "august",
00041 //   year         = "2005",
00042 //   editor       = "J. Dingliana and F. Ganovelli",
00043 //   keywords     = "animation, physical model, elasticity, finite elements",
00044 //   url          = "http://www-evasion.imag.fr/Publications/2005/NPF05"
00045 // }
00046 
00047 
00048 namespace sofa
00049 {
00050 
00051 namespace component
00052 {
00053 
00054 namespace forcefield
00055 {
00056 
00057 using namespace sofa::defaulttype;
00058 using sofa::helper::vector;
00059 
00060 
00062 template<class DataTypes>
00063 class TetrahedronFEMForceFieldInternalData
00064 {
00065 public:
00066 };
00067 
00068 
00071 template<class DataTypes>
00072 class TetrahedronFEMForceField : public core::componentmodel::behavior::ForceField<DataTypes>, public virtual core::objectmodel::BaseObject
00073 {
00074 public:
00075     typedef typename DataTypes::VecCoord VecCoord;
00076     typedef typename DataTypes::VecDeriv VecDeriv;
00077     typedef typename DataTypes::VecReal VecReal;
00078     typedef VecCoord Vector;
00079     typedef typename DataTypes::Coord Coord;
00080     typedef typename DataTypes::Deriv Deriv;
00081     typedef typename Coord::value_type Real;
00082 
00083     typedef core::componentmodel::topology::BaseMeshTopology::index_type Index;
00084     typedef core::componentmodel::topology::BaseMeshTopology::Tetra Element;
00085     typedef core::componentmodel::topology::BaseMeshTopology::SeqTetras VecElement;
00086 
00087     enum { SMALL = 0,   
00088            LARGE = 1,   
00089            POLAR = 2 }; 
00090 
00091 protected:
00092 
00095 
00097     typedef VecNoInit<12, Real> Displacement;
00098 
00100     typedef Mat<6, 6, Real> MaterialStiffness;
00101 
00103     typedef Mat<12, 6, Real> StrainDisplacement;
00104 
00106     typedef MatNoInit<3, 3, Real> Transformation; 
00107 
00109     typedef Mat<12, 12, Real> StiffnessMatrix;
00110 
00112 
00114     typedef vector<MaterialStiffness> VecMaterialStiffness;
00115     typedef vector<StrainDisplacement> VecStrainDisplacement;  
00116 
00118     VecMaterialStiffness _materialsStiffnesses;
00119     VecStrainDisplacement _strainDisplacements;   
00120 
00123 
00124     typedef std::pair<int,Real> Col_Value;
00125     typedef vector< Col_Value > CompressedValue;
00126     typedef vector< CompressedValue > CompressedMatrix;
00127 
00128     CompressedMatrix _stiffnesses;
00130 
00131     SReal m_potentialEnergy;
00132 
00133     core::componentmodel::topology::BaseMeshTopology* _mesh;
00134     const VecElement *_indexedElements;
00135     VecCoord _initialPoints; 
00136 
00137     bool needUpdateTopology;
00138     
00139     TetrahedronFEMForceFieldInternalData<DataTypes> data;
00140     friend class TetrahedronFEMForceFieldInternalData<DataTypes>;
00141 
00142 public:
00143     //For a faster contact handling with simplified compliance
00144     void getRotation(Transformation& R, unsigned int nodeIdx);
00145 
00146 
00147     DataPtr< VecCoord > f_initialPoints; 
00148     int method;
00149     Data<std::string> f_method; 
00150             Real   _poissonRatio;
00151     DataPtr<Real> f_poissonRatio;
00152             Real   _youngModulus;
00153     DataPtr<Real> f_youngModulus;
00154             VecReal   _localStiffnessFactor;
00155     DataPtr<VecReal> f_localStiffnessFactor;
00156             bool   _updateStiffnessMatrix;
00157     DataPtr<bool> f_updateStiffnessMatrix;
00158             bool   _assembling;
00159     DataPtr<bool> f_assembling;
00160 
00161     TetrahedronFEMForceField()
00162     : _mesh(NULL)
00163     , _indexedElements(NULL)
00164     , needUpdateTopology(false)
00165     , f_initialPoints(initDataPtr(&f_initialPoints, &_initialPoints, "initialPoints", "Initial Position"))
00166     , f_method(initData(&f_method,std::string("large"),"method","\"small\", \"large\" (by QR) or \"polar\" displacements"))
00167     ,  _poissonRatio((Real)0.45f)
00168     , f_poissonRatio(initDataPtr(&f_poissonRatio,&_poissonRatio,"poissonRatio","FEM Poisson Ratio"))
00169     ,  _youngModulus((Real)5000)
00170     , f_youngModulus(initDataPtr(&f_youngModulus,&_youngModulus,"youngModulus","FEM Young Modulus"))
00171     , f_localStiffnessFactor(initDataPtr(&f_localStiffnessFactor,&_localStiffnessFactor,"localStiffnessFactor","Allow specification of different stiffness per element. If there are N element and M values are specified, the youngModulus factor for element i would be localStiffnessFactor[i*M/N]"))
00172     ,  _updateStiffnessMatrix(false)
00173     , f_updateStiffnessMatrix(initDataPtr(&f_updateStiffnessMatrix,&_updateStiffnessMatrix,"updateStiffnessMatrix",""))
00174     ,  _assembling(false)
00175     , f_assembling(initDataPtr(&f_assembling,&_assembling,"assembling",""))
00176     {}
00177 
00178     void parse(core::objectmodel::BaseObjectDescription* arg);
00179 
00180     void setPoissonRatio(Real val) { this->f_poissonRatio.setValue(val); }
00181 
00182     void setYoungModulus(Real val) { this->f_youngModulus.setValue(val); }
00183 
00184     void setMethod(std::string methodName)
00185     {     
00186       if (methodName == "small")    this->setMethod(SMALL);
00187       else if (methodName  == "polar")  this->setMethod(POLAR);
00188       else  
00189       {
00190     if (methodName != "large") 
00191       std::cerr << "unknown method: large method will be used. Remark: Available method are \"small\", \"polar\", \"large\" \n";
00192     this->setMethod(LARGE);
00193       }     
00194     }
00195     
00196     void setMethod(int val) 
00197     { 
00198       method = val; 
00199       switch(val)
00200       {
00201         case SMALL: f_method.setValue("small"); break;    
00202         case POLAR: f_method.setValue("polar"); break;
00203         default   : f_method.setValue("large"); 
00204       };
00205     }
00206 
00207     void setUpdateStiffnessMatrix(bool val) { this->f_updateStiffnessMatrix.setValue(val); }
00208 
00209     void setComputeGlobalMatrix(bool val) { this->f_assembling.setValue(val); }
00210 
00211     virtual void init();
00212     virtual void reinit();
00213 
00214     virtual void addForce (VecDeriv& f, const VecCoord& x, const VecDeriv& v);
00215 
00216     virtual void addDForce (VecDeriv& df, const VecDeriv& dx, double kFactor, double bFactor);
00217 
00218     virtual double getPotentialEnergy(const VecCoord& x);
00219 
00220     virtual void addKToMatrix(sofa::defaulttype::BaseMatrix *, SReal, unsigned int &);
00221 
00222     void draw();
00223 
00224   protected:
00225 
00226     void computeStrainDisplacement( StrainDisplacement &J, Coord a, Coord b, Coord c, Coord d );
00227     Real peudo_determinant_for_coef ( const Mat<2, 3, Real>&  M );
00228 
00229     void computeStiffnessMatrix( StiffnessMatrix& S,StiffnessMatrix& SR,const MaterialStiffness &K, const StrainDisplacement &J, const Transformation& Rot );
00230 
00231     void computeMaterialStiffness(int i, Index&a, Index&b, Index&c, Index&d);
00232 
00233     void computeForce( Displacement &F, const Displacement &Depl, const MaterialStiffness &K, const StrainDisplacement &J );
00234     void computeForce( Displacement &F, const Displacement &Depl, const MaterialStiffness &K, const StrainDisplacement &J, double fact );
00235 
00237     void initSmall(int i, Index&a, Index&b, Index&c, Index&d);
00238     void accumulateForceSmall( Vector& f, const Vector & p, typename VecElement::const_iterator elementIt, Index elementIndex );
00239     void applyStiffnessSmall( Vector& f, const Vector& x, int i=0, Index a=0,Index b=1,Index c=2,Index d=3, double fact=1.0  );
00240 
00242     vector<helper::fixed_array<Coord,4> > _rotatedInitialElements;   
00243     vector<Transformation> _rotations;
00244     vector<Transformation> _initialRotations;
00245     void initLarge(int i, Index&a, Index&b, Index&c, Index&d);
00246     void computeRotationLarge( Transformation &r, const Vector &p, const Index &a, const Index &b, const Index &c);
00247     void accumulateForceLarge( Vector& f, const Vector & p, typename VecElement::const_iterator elementIt, Index elementIndex );
00248     void applyStiffnessLarge( Vector& f, const Vector& x, int i=0, Index a=0,Index b=1,Index c=2,Index d=3, double fact=1.0 );
00249 
00251     vector<Transformation>  _initialTransformation;
00252     vector<unsigned int> _rotationIdx;
00253     void initPolar(int i, Index&a, Index&b, Index&c, Index&d);
00254     void accumulateForcePolar( Vector& f, const Vector & p, typename VecElement::const_iterator elementIt, Index elementIndex );
00255     void applyStiffnessPolar( Vector& f, const Vector& x, int i=0, Index a=0,Index b=1,Index c=2,Index d=3, double fact=1.0  );
00256     
00257     void handleTopologyChange()
00258     {
00259         needUpdateTopology = true;
00260     }
00261 };
00262 
00263 } // namespace forcefield
00264 
00265 } // namespace component
00266 
00267 } // namespace sofa
00268 
00269 #endif

Generated on Sun Nov 23 03:14:06 2008 for Sofa by  doxygen 1.5.7.1