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_HEXAHEDRALFEMFORCEFIELD_H
00026 #define SOFA_COMPONENT_FORCEFIELD_HEXAHEDRALFEMFORCEFIELD_H
00027
00028 #include <sofa/core/componentmodel/behavior/ForceField.h>
00029 #include <sofa/component/MechanicalObject.h>
00030 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00031 #include <sofa/component/topology/SparseGridTopology.h>
00032 #include <sofa/helper/vector.h>
00033 #include <sofa/defaulttype/Vec.h>
00034 #include <sofa/defaulttype/Mat.h>
00035
00036 #include <sofa/component/topology/HexahedronData.h>
00037
00038 namespace sofa
00039 {
00040
00041 namespace component
00042 {
00043
00044 namespace forcefield
00045 {
00046
00047 using namespace sofa::defaulttype;
00048 using sofa::helper::vector;
00049
00050 using namespace sofa::component::topology;
00051
00077 template<class DataTypes>
00078 class HexahedralFEMForceField : virtual public core::componentmodel::behavior::ForceField<DataTypes>, public virtual core::objectmodel::BaseObject
00079 {
00080 public:
00081 typedef typename DataTypes::VecCoord VecCoord;
00082 typedef typename DataTypes::VecDeriv VecDeriv;
00083 typedef VecCoord Vector;
00084 typedef typename DataTypes::Coord Coord;
00085 typedef typename DataTypes::Deriv Deriv;
00086 typedef typename Coord::value_type Real;
00087
00088 typedef core::componentmodel::topology::BaseMeshTopology::index_type Index;
00089 #ifdef SOFA_NEW_HEXA
00090 typedef core::componentmodel::topology::BaseMeshTopology::Hexa Element;
00091 typedef core::componentmodel::topology::BaseMeshTopology::SeqHexas VecElement;
00092 #else
00093 typedef core::componentmodel::topology::BaseMeshTopology::Cube Element;
00094 typedef core::componentmodel::topology::BaseMeshTopology::SeqCubes VecElement;
00095 #endif
00096 static const int LARGE = 0;
00097 static const int POLAR = 1;
00098
00099 protected:
00100
00101
00102 typedef Vec<24, Real> Displacement;
00103
00104 typedef Mat<6, 6, Real> MaterialStiffness;
00105 typedef vector<MaterialStiffness> VecMaterialStiffness;
00106
00107
00108 typedef Mat<24, 24, Real> ElementStiffness;
00109 typedef vector<ElementStiffness> VecElementStiffness;
00110
00111
00112 typedef Mat<3, 3, Real> Mat33;
00113 typedef Mat33 Transformation;
00114
00116 class HexahedronInformation
00117 {
00118 public:
00120 MaterialStiffness materialMatrix;
00122
00123
00124 helper::fixed_array<Coord,8> rotatedInitialElements;
00125
00126 Transformation rotation;
00127 ElementStiffness stiffness;
00129
00130
00131 HexahedronInformation() {
00132 }
00133 };
00135 HexahedronData<HexahedronInformation> hexahedronInfo;
00136
00137
00138 typedef std::pair<int,Real> Col_Value;
00139 typedef vector< Col_Value > CompressedValue;
00140 typedef vector< CompressedValue > CompressedMatrix;
00141
00142 double m_potentialEnergy;
00143
00144 sofa::core::componentmodel::topology::BaseMeshTopology* _topology;
00145
00146
00147
00148
00149
00150
00151
00152 Mat<8,3,int> _coef;
00153
00154 public:
00155
00156 int method;
00157 Data<std::string> f_method;
00158 Data<Real> f_poissonRatio;
00159 Data<Real> f_youngModulus;
00160
00161 Data<bool> f_assembling;
00162
00163
00164 HexahedralFEMForceField()
00165 : f_method(initData(&f_method,std::string("large"),"method","\"large\" or \"polar\" displacements"))
00166 , f_poissonRatio(initData(&f_poissonRatio,(Real)0.45f,"poissonRatio",""))
00167 , f_youngModulus(initData(&f_youngModulus,(Real)5000,"youngModulus",""))
00168
00169 , f_assembling(initData(&f_assembling,false,"assembling",""))
00170 {
00171 _coef[0][0]=-1;
00172 _coef[1][0]=1;
00173 _coef[2][0]=1;
00174 _coef[3][0]=-1;
00175 _coef[4][0]=-1;
00176 _coef[5][0]=1;
00177 _coef[6][0]=1;
00178 _coef[7][0]=-1;
00179 _coef[0][1]=-1;
00180 _coef[1][1]=-1;
00181 _coef[2][1]=1;
00182 _coef[3][1]=1;
00183 _coef[4][1]=-1;
00184 _coef[5][1]=-1;
00185 _coef[6][1]=1;
00186 _coef[7][1]=1;
00187 _coef[0][2]=-1;
00188 _coef[1][2]=-1;
00189 _coef[2][2]=-1;
00190 _coef[3][2]=-1;
00191 _coef[4][2]=1;
00192 _coef[5][2]=1;
00193 _coef[6][2]=1;
00194 _coef[7][2]=1;
00195
00196 _alreadyInit=false;
00197 }
00198
00199 void parse(core::objectmodel::BaseObjectDescription* arg);
00200
00201 void setPoissonRatio(Real val) { this->f_poissonRatio.setValue(val); }
00202
00203 void setYoungModulus(Real val) { this->f_youngModulus.setValue(val); }
00204
00205 void setMethod(int val) { method = val; }
00206
00207
00208
00209 void setComputeGlobalMatrix(bool val) { this->f_assembling.setValue(val); }
00210
00211
00212
00213 virtual void init();
00214 virtual void reinit();
00215
00216 virtual void addForce (VecDeriv& f, const VecCoord& x, const VecDeriv& v);
00217
00218 virtual void addDForce (VecDeriv& df, const VecDeriv& dx);
00219
00220 virtual double getPotentialEnergy(const VecCoord& x);
00221
00222
00223 virtual void handleTopologyChange();
00224
00225 void draw();
00226
00227 protected:
00228
00229
00230 virtual void computeElementStiffness( ElementStiffness &K, const MaterialStiffness &M, const Vec<8,Coord> &nodes, const int elementIndice);
00231 Mat33 integrateStiffness( int signx0, int signy0, int signz0, int signx1, int signy1, int signz1, const Real u, const Real v, const Real w, const Mat33& J_1 );
00232
00233 void computeMaterialStiffness(int i);
00234
00235 void computeForce( Displacement &F, const Displacement &Depl, const ElementStiffness &K );
00236
00237
00239
00240
00241 void initLarge(int i);
00242 void computeRotationLarge( Transformation &r, Coord &edgex, Coord &edgey);
00243 virtual void accumulateForceLarge( Vector& f, const Vector & p, int i);
00244
00246 void initPolar(int i);
00247 void computeRotationPolar( Transformation &r, Vec<8,Coord> &nodes);
00248 virtual void accumulateForcePolar( Vector& f, const Vector & p, int i);
00249
00250 bool _alreadyInit;
00251
00253 static void FHexahedronCreationFunction (int , void* ,
00254 HexahedronInformation &,
00255 const Hexahedron& , const helper::vector< unsigned int > &, const helper::vector< double >&);
00256
00257 };
00258
00259 }
00260
00261 }
00262
00263 }
00264
00265 #endif