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_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
00036
00037
00038
00039
00040
00041
00042
00043
00044
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
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 }
00264
00265 }
00266
00267 }
00268
00269 #endif