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_TRIANGULARFEMFORCEFIELD_H
00026 #define SOFA_COMPONENT_FORCEFIELD_TRIANGULARFEMFORCEFIELD_H
00027
00028 #if !defined(__GNUC__) || (__GNUC__ > 3 || (_GNUC__ == 3 && __GNUC_MINOR__ > 3))
00029 #pragma once
00030 #endif
00031
00032 #include <sofa/core/componentmodel/behavior/ForceField.h>
00033 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00034 #include <sofa/defaulttype/Vec.h>
00035 #include <sofa/defaulttype/Mat.h>
00036 #include <sofa/component/topology/TriangleData.h>
00037 #include <sofa/component/topology/EdgeData.h>
00038 #include <sofa/component/topology/PointData.h>
00039 #include <newmat/newmat.h>
00040 #include <newmat/newmatap.h>
00041
00042
00043
00044 namespace sofa
00045 {
00046
00047 namespace component
00048 {
00049
00050 namespace forcefield
00051 {
00052
00053 using namespace sofa::defaulttype;
00054 using sofa::helper::vector;
00055 using namespace sofa::component::topology;
00056
00057
00070 template<class DataTypes>
00071 class TriangularFEMForceField : public core::componentmodel::behavior::ForceField<DataTypes>, public virtual core::objectmodel::BaseObject
00072 {
00073 public:
00074 typedef core::componentmodel::behavior::ForceField<DataTypes> Inherited;
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 sofa::core::componentmodel::topology::BaseMeshTopology::index_type Index;
00084 typedef sofa::core::componentmodel::topology::BaseMeshTopology::Triangle Element;
00085 typedef sofa::core::componentmodel::topology::BaseMeshTopology::SeqTriangles VecElement;
00086
00087 static const int SMALL = 1;
00088 static const int LARGE = 0;
00089
00090
00091 protected:
00092
00093
00094 typedef Vec<6, Real> Displacement;
00095 typedef Mat<3, 3, Real> MaterialStiffness;
00096 typedef sofa::helper::vector<MaterialStiffness> VecMaterialStiffness;
00097 typedef Mat<6, 3, Real> StrainDisplacement;
00098 typedef sofa::helper::vector<StrainDisplacement> VecStrainDisplacement;
00099 typedef Mat<3, 3, Real > Transformation;
00100
00101 class TriangleInformation
00102 {
00103 public:
00105 MaterialStiffness materialMatrix;
00107 StrainDisplacement strainDisplacementMatrix;
00108
00109 helper::fixed_array<Coord,3> rotatedInitialElements;
00110 Transformation rotation;
00112 Transformation initialTransformation;
00113
00114 Coord principalStrainDirection;
00115 double eigenValue;
00116
00117 TriangleInformation() {
00118 }
00119 };
00120
00121 class EdgeInformation
00122 {
00123 public:
00124 EdgeInformation()
00125 :fracturable(false){};
00126
00127 bool fracturable;
00128 };
00129
00130 class VertexInformation
00131 {
00132 public:
00133 VertexInformation()
00134 :sumEigenValues(0.0){};
00135
00136 Coord meanStrainDirection;
00137 double sumEigenValues;
00138 };
00139
00140 TriangleData<TriangleInformation> triangleInfo;
00141 PointData<VertexInformation> vertexInfo;
00142 EdgeData<EdgeInformation> edgeInfo;
00143
00144 sofa::core::componentmodel::topology::BaseMeshTopology* _topology;
00145
00146
00147 VecCoord* _initialPoints;
00148
00149
00150
00151
00152
00153 bool updateMatrix;
00154 int lastFracturedEdgeIndex;
00155
00156 public:
00157
00158 TriangularFEMForceField();
00159
00160
00161
00162 virtual ~TriangularFEMForceField();
00163 virtual void init();
00164 virtual void reinit();
00165 virtual void addForce (VecDeriv& f, const VecCoord& x, const VecDeriv& v);
00166 virtual void addDForce (VecDeriv& df, const VecDeriv& dx);
00167 virtual double getPotentialEnergy(const VecCoord& x);
00168 virtual void handleTopologyChange();
00169
00170 void draw();
00171
00172 int method;
00173 Data<std::string> f_method;
00174 Data<Real> f_poisson;
00175 Data<Real> f_young;
00176 Data<Real> f_damping;
00177 Data<bool> f_fracturable;
00178
00179 Data<bool> showStressValue;
00180 Data<bool> showStressVector;
00181
00182 Real getPoisson() { return f_poisson.getValue(); }
00183 void setPoisson(Real val) { f_poisson.setValue(val); }
00184 Real getYoung() { return f_young.getValue(); }
00185 void setYoung(Real val) { f_young.setValue(val); }
00186 Real getDamping() { return f_damping.getValue(); }
00187 void setDamping(Real val) { f_damping.setValue(val); }
00188 int getMethod() { return method; }
00189 void setMethod(int val) { method = val; }
00190 int getFracturedEdge();
00191
00192 protected :
00193
00194 void computeEigenStrain( Coord &v, StrainDisplacement &J, Displacement &Depl , double &maxEigenValue);
00195
00196
00197
00198
00199
00200
00201
00202
00203 static void TRQSTriangleCreationFunction (int , void* ,
00204 TriangleInformation &,
00205 const Triangle& , const sofa::helper::vector< unsigned int > &, const sofa::helper::vector< double >&);
00206
00207
00208
00209
00211 virtual void applyStiffness( VecCoord& f, Real h, const VecCoord& x );
00212 virtual void computeMaterialStiffness(int i, Index& a, Index& b, Index& c);
00213 void computeStrainDisplacement( StrainDisplacement &J, Coord a, Coord b, Coord c);
00214 void computeForce( Displacement &F, const Displacement &Depl, const MaterialStiffness &K, const StrainDisplacement &J );
00215
00217 void initSmall(void);
00218 void accumulateForceSmall( VecCoord& f, const VecCoord & p, Index elementIndex, bool implicit = false );
00219 void accumulateDampingSmall( VecCoord& f, Index elementIndex );
00220 void applyStiffnessSmall( VecCoord& f, Real h, const VecCoord& x );
00221
00223
00224
00225 void initLarge(int i, Index&a, Index&b, Index&c);
00226 void computeRotationLarge( Transformation &r, const VecCoord &p, const Index &a, const Index &b, const Index &c);
00227 void accumulateForceLarge( VecCoord& f, const VecCoord & p, Index elementIndex, bool implicit=false );
00228 void accumulateDampingLarge( VecCoord& f, Index elementIndex );
00229 void applyStiffnessLarge( VecCoord& f, Real h, const VecCoord& x );
00230 };
00231
00232
00233 }
00234
00235 }
00236
00237 }
00238
00239 #endif