EllipsoidForceField.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_ELLIPSOIDFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_ELLIPSOIDFORCEFIELD_INL
00027 
00028 #include <sofa/core/componentmodel/behavior/ForceField.inl>
00029 #include "EllipsoidForceField.h"
00030 #include <sofa/helper/system/config.h>
00031 #include <sofa/helper/rmath.h>
00032 #include <sofa/helper/system/gl.h>
00033 #include <sofa/helper/system/glut.h>
00034 #include <assert.h>
00035 #include <iostream>
00036 
00037 namespace sofa
00038 {
00039 
00040 namespace component
00041 {
00042 
00043 namespace forcefield
00044 {
00045 
00046 // v = sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2)-1
00047 // dv/dxj = xj/rj^2 * 1/sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2)
00048 
00049 // f  = -stiffness * v * (dv/dp) / norm(dv/dp)
00050 
00051 // fi = -stiffness * (sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2)-1) * (xi/ri^2) / sqrt(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4)
00052 
00053 // dfi/dxj = -stiffness * [ d(sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2)-1)/dxj *   (xi/ri^2) / sqrt(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4)
00054 //                          +  (sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2)-1)     * d(xi/ri^2)/dxj / sqrt(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4)
00055 //                          +  (sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2)-1)     *  (xi/ri^2) * d(1/sqrt(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4))/dxj ]
00056 // dfi/dxj = -stiffness * [ xj/rj^2 * 1/sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2) * (xi/ri^2) / sqrt(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4)
00057 //                          +  (sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2)-1)       * (i==j)/ri^2 / sqrt(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4)
00058 //                          +  (sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2)-1)       * (xi/ri^2) * (-1/2*2xj/rj^4*1/(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4) ]
00059 // dfi/dxj = -stiffness * [ xj/rj^2 * 1/sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2) * (xi/ri^2) / sqrt(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4)
00060 //                          +  (sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2)-1)       * (i==j)/ri^2 / sqrt(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4)
00061 //                          +  (sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2)-1)       * (xi/ri^2) * (-xj/rj^4*1/(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4) ]
00062 
00063 // dfi/dxj = -stiffness * [ (xj/rj^2) * (xi/ri^2) * 1/(sqrt(x0^2/r0^2+x1^2/r1^2+x2^2/r2^2) * sqrt(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4))
00064 //                          +  v       * (i==j) / (ri^2*sqrt(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4))
00065 //                          +  v       * (xi/ri^2) * (xj/rj^2) * 1/(rj^2*(x0^2/r0^4+x1^2/r1^4+x2^2/r2^4) ]
00066 
00067 
00068 template<class DataTypes>
00069 void EllipsoidForceField<DataTypes>::addForce(VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1)
00070 {
00071     const Coord center = this->center.getValue();
00072     const Coord r = this->vradius.getValue();
00073     const Real stiffness = this->stiffness.getValue();
00074     const Real stiffabs = helper::rabs(stiffness);
00075     //const Real s2 = (stiff < 0 ? - stiff*stiff : stiff*stiff );
00076     Coord inv_r2;
00077     for (int j=0; j<N; j++) inv_r2[j] = 1/(r[j]*r[j]);
00078     sofa::helper::vector<Contact>* contacts = this->contacts.beginEdit();
00079     contacts->clear();
00080     f1.resize(p1.size());
00081     for (unsigned int i=0; i<p1.size(); i++)
00082     {
00083         Coord dp = p1[i] - center;
00084         Real norm2 = 0;
00085         for (int j=0; j<N; j++) norm2 += (dp[j]*dp[j])*inv_r2[j];
00086         //Real d = (norm2-1)*s2;
00087         if ((norm2-1)*stiffness<0)
00088         {
00089         Real norm = helper::rsqrt(norm2);
00090             Real v = norm-1;
00091             Coord grad;
00092             for (int j=0; j<N; j++) grad[j] = dp[j]*inv_r2[j];
00093             Real gnorm2 = grad.norm2();
00094             Real gnorm = helper::rsqrt(gnorm2);
00095             //grad /= gnorm; //.normalize();
00096             Real forceIntensity = -stiffabs*v/gnorm;
00097             Real dampingIntensity = this->damping.getValue()*helper::rabs(v);
00098             Deriv force = forceIntensity*grad - v1[i]*dampingIntensity;
00099             f1[i]+=force;
00100             Contact c;
00101             c.index = i;
00102             Real fact1 = -stiffabs / (norm * gnorm);
00103             Real fact2 = -stiffabs*v / gnorm;
00104             Real fact3 = -stiffabs*v / gnorm2;
00105             for (int ci = 0; ci < N; ++ci)
00106             {
00107                 for (int cj = 0; cj < N; ++cj)
00108                     c.m[ci][cj] = grad[ci]*grad[cj] * (fact1 + fact3*inv_r2[cj]);
00109                 c.m[ci][ci] += fact2*inv_r2[ci];
00110             }
00111             contacts->push_back(c);
00112         }
00113     }
00114     this->contacts.endEdit();
00115 }
00116 
00117 template<class DataTypes>
00118 void EllipsoidForceField<DataTypes>::addDForce(VecDeriv& df1, const VecDeriv& dx1, double kFactor, double /*bFactor*/)
00119 {
00120     df1.resize(dx1.size());
00121     const sofa::helper::vector<Contact>& contacts = this->contacts.getValue();
00122     for (unsigned int i=0; i<contacts.size(); i++)
00123     {
00124         const Contact& c = contacts[i];
00125         assert((unsigned)c.index<dx1.size());
00126         Deriv du = dx1[c.index];
00127         Deriv dforce = c.m * du;
00128     dforce *= kFactor;
00129         df1[c.index] += dforce;
00130     }
00131 }
00132 
00133 template <class DataTypes> 
00134     double EllipsoidForceField<DataTypes>::getPotentialEnergy(const VecCoord&)
00135 {
00136     std::cerr<<"EllipsoidForceField::getPotentialEnergy-not-implemented !!!"<<std::endl;
00137     return 0;
00138 }
00139 
00140 template<class DataTypes>
00141 void EllipsoidForceField<DataTypes>::draw()
00142 {
00143     if (!getContext()->getShowForceFields()) return;
00144     if (!bDraw.getValue()) return;
00145 
00146     Real cx=0, cy=0, cz=0;
00147     DataTypes::get(cx, cy, cz, center.getValue());
00148     Real rx=1, ry=1, rz=1;
00149     DataTypes::get(rx, ry, rz, vradius.getValue());
00150     glEnable(GL_CULL_FACE);
00151     glEnable(GL_LIGHTING);
00152     glEnable(GL_COLOR_MATERIAL);
00153     glColor3f(color.getValue()[0],color.getValue()[1],color.getValue()[2]);
00154     glPushMatrix();
00155     glTranslated(cx, cy, cz);
00156     glScaled(rx, ry, (stiffness.getValue()>0?rz:-rz));
00157     glutSolidSphere(1,32,16);
00158     glPopMatrix();
00159     glDisable(GL_CULL_FACE);
00160     glDisable(GL_LIGHTING);
00161     glDisable(GL_COLOR_MATERIAL);
00162 }
00163 
00164 
00165 } // namespace forcefield
00166 
00167 } // namespace component
00168 
00169 } // namespace sofa
00170 
00171 #endif

Generated on Sun Nov 23 02:55:36 2008 for Sofa by  doxygen 1.5.7.1