LennardJonesForceField.inl

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
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     // Validity check: compute force and potential at d0
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     // Debug
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             //std::cout << ia<<"-"<<ib<<" d="<<d<<" f="<<forceIntensity<<std::endl;
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             // Add damping
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 } // namespace forcefield
00164 
00165 } // namespace component
00166 
00167 } // namespace sofa
00168 
00169 #endif

Generated on Sun Nov 23 03:00:58 2008 for Sofa by  doxygen 1.5.7.1