StiffSpringForceField.inl
Go to the documentation of this file.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
00026
00027
00028 #ifndef SOFA_COMPONENT_FORCEFIELD_STIFFSPRINGFORCEFIELD_INL
00029 #define SOFA_COMPONENT_FORCEFIELD_STIFFSPRINGFORCEFIELD_INL
00030
00031 #include <sofa/component/forcefield/StiffSpringForceField.h>
00032 #include <sofa/component/forcefield/SpringForceField.inl>
00033 #include <assert.h>
00034
00035 namespace sofa
00036 {
00037
00038 namespace component
00039 {
00040
00041 namespace forcefield
00042 {
00043
00044 template<class DataTypes>
00045 void StiffSpringForceField<DataTypes>::init()
00046 {
00047 this->SpringForceField<DataTypes>::init();
00048 }
00049
00050 template<class DataTypes>
00051 void StiffSpringForceField<DataTypes>::addSpringForce( double& potentialEnergy, VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1, VecDeriv& f2, const VecCoord& p2, const VecDeriv& v2, int i, const Spring& spring)
00052 {
00053 int a = spring.m1;
00054 int b = spring.m2;
00055 Coord u = p2[b]-p1[a];
00056 Real d = u.norm();
00057 if( d>1.0e-4 )
00058 {
00059 Real inverseLength = 1.0f/d;
00060 u *= inverseLength;
00061 Real elongation = (Real)(d - spring.initpos);
00062 potentialEnergy += elongation * elongation * spring.ks / 2;
00063
00064
00065
00066 Deriv relativeVelocity = v2[b]-v1[a];
00067 Real elongationVelocity = dot(u,relativeVelocity);
00068 Real forceIntensity = (Real)(spring.ks*elongation+spring.kd*elongationVelocity);
00069 Deriv force = u*forceIntensity;
00070 f1[a]+=force;
00071 f2[b]-=force;
00072
00073
00074 Mat& m = this->dfdx[i];
00075 Real tgt = forceIntensity * inverseLength;
00076 for( int j=0; j<N; ++j )
00077 {
00078 for( int k=0; k<N; ++k )
00079 {
00080 m[j][k] = ((Real)spring.ks-tgt) * u[j] * u[k];
00081 }
00082 m[j][j] += tgt;
00083 }
00084 }
00085 else
00086 {
00087 Mat& m = this->dfdx[i];
00088 for( int j=0; j<N; ++j )
00089 {
00090 for( int k=0; k<N; ++k )
00091 {
00092 m[j][k] = 0;
00093 }
00094 }
00095 }
00096 }
00097
00098 template<class DataTypes>
00099 void StiffSpringForceField<DataTypes>::addSpringDForce(VecDeriv& f1, const VecDeriv& dx1, VecDeriv& f2, const VecDeriv& dx2, int i, const Spring& spring, double kFactor, double )
00100 {
00101 const int a = spring.m1;
00102 const int b = spring.m2;
00103 const Coord d = dx2[b]-dx1[a];
00104 Deriv dforce = this->dfdx[i]*d;
00105 dforce *= kFactor;
00106 f1[a]+=dforce;
00107 f2[b]-=dforce;
00108
00109 }
00110
00111 template<class DataTypes>
00112 void StiffSpringForceField<DataTypes>::addForce(VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& v1, const VecDeriv& v2)
00113 {
00114 const helper::vector<Spring>& springs= this->springs.getValue();
00115 this->dfdx.resize(springs.size());
00116 f1.resize(x1.size());
00117 f2.resize(x2.size());
00118 m_potentialEnergy = 0;
00119
00120 for (unsigned int i=0; i<springs.size(); i++)
00121 {
00122
00123 this->addSpringForce(m_potentialEnergy,f1,x1,v1,f2,x2,v2, i, springs[i]);
00124 }
00125 }
00126
00127 template<class DataTypes>
00128 void StiffSpringForceField<DataTypes>::addDForce(VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2, double kFactor, double bFactor)
00129 {
00130 df1.resize(dx1.size());
00131 df2.resize(dx2.size());
00132
00133
00134 const helper::vector<Spring>& springs = this->springs.getValue();
00135 for (unsigned int i=0; i<springs.size(); i++)
00136 {
00137 this->addSpringDForce(df1,dx1,df2,dx2, i, springs[i], kFactor, bFactor);
00138 }
00139
00140
00141 }
00142
00143 }
00144
00145 }
00146
00147 }
00148
00149 #endif
00150