LennardJonesForceField.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 #ifndef SOFA_COMPONENT_FORCEFIELD_LENNARDJONESFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_LENNARDJONESFORCEFIELD_INL
00027
00028 #include <sofa/component/forcefield/LennardJonesForceField.h>
00029 #include <sofa/helper/system/config.h>
00030 #include <sofa/helper/gl/template.h>
00031 #include <math.h>
00032 #include <iostream>
00033
00034 using std::cerr;
00035 using std::endl;
00036
00037 namespace sofa
00038 {
00039
00040 namespace component
00041 {
00042
00043 namespace forcefield
00044 {
00045
00046
00047 template<class DataTypes>
00048 void LennardJonesForceField<DataTypes>::init()
00049 {
00050 this->Inherit::init();
00051
00052 assert( this->mstate );
00053
00054 a = (p0.getValue() * (Real)pow(d0.getValue(),alpha.getValue())) / (1-alpha.getValue()/beta.getValue());
00055 b = (p0.getValue() * (Real)pow(d0.getValue(),beta.getValue())) / (beta.getValue()/alpha.getValue()-1);
00056 std::cout << "Lennard-Jones initialized: alpha="<<alpha.getValue()<<" beta="<<beta.getValue()<<" d0="<<d0.getValue()<<" p0="<<p0.getValue()<<" a="<<a<<" b="<<b<<std::endl;
00057
00058 Real f0 = a*alpha.getValue()*(Real)pow(d0.getValue(),-alpha.getValue()-1)-b*beta.getValue()*(Real)pow(d0.getValue(),-beta.getValue()-1);
00059 if (fabs(f0)>0.001)
00060 std::cerr << "Lennard-Jones initialization failed: f0="<<f0<<std::endl;
00061 Real cp0 = (a*(Real)pow(d0.getValue(),-alpha.getValue())-b*(Real)pow(d0.getValue(),-beta.getValue()));
00062 if (fabs(cp0/p0.getValue()-1)>0.001)
00063 std::cerr << "Lennard-Jones initialization failed: cp0="<<cp0<<std::endl;
00064
00065 for (Real d = 0; d<dmax.getValue(); d+= dmax.getValue()/60)
00066 {
00067 Real f = a*alpha.getValue()*(Real)pow(d,-alpha.getValue()-1)-b*beta.getValue()*(Real)pow(d,-beta.getValue()-1);
00068 std::cout << "f("<<d<<")="<<f<<std::endl;
00069 }
00070 }
00071
00072 template<class DataTypes>
00073 void LennardJonesForceField<DataTypes>::addForce(VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1)
00074 {
00075 Real dmax2 = dmax.getValue()*dmax.getValue();
00076 this->dforces.clear();
00077 f1.resize(p1.size());
00078 for (unsigned int ib=1; ib<p1.size(); ib++)
00079 {
00080 const Coord pb = p1[ib];
00081 for (unsigned int ia=0; ia<ib; ia++)
00082 {
00083 const Coord pa = p1[ia];
00084 const Deriv u = pb-pa;
00085 const Real d2 = u.norm2();
00086 if (d2 >= dmax2) continue;
00087 const Real d = (Real)sqrt(d2);
00088 const Real fa = a*alpha.getValue()*(Real)pow(d,-alpha.getValue()-1);
00089 const Real fb = b*beta.getValue()*(Real)pow(d,-beta.getValue()-1);
00090 Real forceIntensity = fa - fb;
00091
00092 DForce df;
00093 df.a = ia;
00094 df.b = ib;
00095 if (forceIntensity > fmax.getValue())
00096 {
00097 forceIntensity = fmax.getValue();
00098 df.df = 0;
00099 }
00100 else
00101 {
00102 df.df = ((-alpha.getValue()-1)*fa - (-beta.getValue()-1)*fb)/(d*d2);
00103 }
00104 this->dforces.push_back(df);
00105 Deriv force = u*(forceIntensity/d);
00106
00107
00108 force += (v1[ib]-v1[ia])*damping.getValue();
00109
00110 f1[ia]+=force;
00111 f1[ib]-=force;
00112 }
00113 }
00114 }
00115
00116 template<class DataTypes>
00117 void LennardJonesForceField<DataTypes>::addDForce(VecDeriv& f1, const VecDeriv& dx1)
00118 {
00119 const VecCoord& p1 = *this->mstate->getX();
00120 f1.resize(dx1.size());
00121 for (unsigned int i=0; i<this->dforces.size(); i++)
00122 {
00123 const DForce& df = this->dforces[i];
00124 const unsigned int ia = df.a;
00125 const unsigned int ib = df.b;
00126 const Deriv u = p1[ib]-p1[ia];
00127 const Deriv du = dx1[ib]-dx1[ia];
00128 const Deriv dforce = u * (df.df * (du*u));
00129 f1[ia] += dforce;
00130 f1[ib] -= dforce;
00131 }
00132 }
00133
00134 template <class DataTypes>
00135 double LennardJonesForceField<DataTypes>::getPotentialEnergy(const VecCoord& )
00136 {
00137 cerr<<"LennardJonesForceField::getPotentialEnergy-not-implemented !!!"<<endl;
00138 return 0;
00139 }
00140
00141
00142 template<class DataTypes>
00143 void LennardJonesForceField<DataTypes>::draw()
00144 {
00145 if (!getContext()->getShowForceFields()) return;
00146 const VecCoord& p1 = *this->mstate->getX();
00147 glDisable(GL_LIGHTING);
00148 glBegin(GL_LINES);
00149 const Real d02 = this->d0.getValue()*this->d0.getValue();
00150 for (unsigned int i=0; i<this->dforces.size(); i++)
00151 {
00152 const DForce& df = this->dforces[i];
00153 if ((p1[df.b]-p1[df.a]).norm2() < d02)
00154 glColor4f(1,1,1,1);
00155 else
00156 glColor4f(0,0,1,1);
00157 helper::gl::glVertexT(p1[df.a]);
00158 helper::gl::glVertexT(p1[df.b]);
00159 }
00160 glEnd();
00161 }
00162
00163 }
00164
00165 }
00166
00167 }
00168
00169 #endif