TetrahedralTensorMassForceField.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 #include <sofa/component/forcefield/TetrahedralTensorMassForceField.h>
00026 #include <fstream> // for reading the file
00027 #include <iostream> //for debugging
00028 #include <sofa/helper/gl/template.h>
00029 #include <sofa/component/topology/TetrahedronData.inl>
00030 #include <sofa/component/topology/EdgeData.inl>
00031 
00032 
00033 namespace sofa
00034 {
00035 
00036 namespace component
00037 {
00038 
00039 namespace forcefield
00040 {
00041 
00042 using namespace sofa::defaulttype;
00043 using namespace sofa::component::topology;
00044 using namespace core::componentmodel::topology;
00045 
00046 using std::cerr;
00047 using std::cout;
00048 using std::endl;
00049 
00050 using core::componentmodel::topology::BaseMeshTopology;
00051 
00052 typedef BaseMeshTopology::Tetra             Tetra;
00053 typedef BaseMeshTopology::TetraEdges        TetraEdges;
00054 
00055 typedef Tetra           Tetrahedron;
00056 typedef TetraEdges      TetrahedronEdges;
00057 
00058 
00059 template< class DataTypes>
00060 void TetrahedralTensorMassForceField<DataTypes>::TetrahedralTMEdgeCreationFunction(int /*edgeIndex*/, void* param, EdgeRestInformation &ei,
00061                                                                                  const Edge& ,  const helper::vector< unsigned int > &,
00062                                                                                  const helper::vector< double >&)
00063 {
00064     TetrahedralTensorMassForceField<DataTypes> *ff= (TetrahedralTensorMassForceField<DataTypes> *)param;
00065     if (ff) {
00066 
00067         unsigned int u,v;
00069         for (u=0;u<3;++u) {
00070             for (v=0;v<3;++v) {
00071                 ei.DfDx[u][v]=0;
00072             }
00073         }
00074 
00075     }
00076 }
00077 
00078 template< class DataTypes>
00079 void TetrahedralTensorMassForceField<DataTypes>::TetrahedralTMTetrahedronCreationFunction (const helper::vector<unsigned int> &tetrahedronAdded, 
00080                                                                                         void* param, helper::vector<EdgeRestInformation> &edgeData)
00081 {
00082     TetrahedralTensorMassForceField<DataTypes> *ff= (TetrahedralTensorMassForceField<DataTypes> *)param;
00083     if (ff) {
00084 
00085         unsigned int i,j,k,l,u,v;
00086 
00087         typename DataTypes::Real val1,volume;
00088         typename DataTypes::Real lambda=ff->getLambda();
00089         typename DataTypes::Real mu=ff->getMu();
00090         typename DataTypes::Real lambdastar, mustar;
00091         typename DataTypes::Coord point[4],shapeVector[4];
00092         
00093         const typename DataTypes::VecCoord *restPosition=ff->mstate->getX0();
00094 
00095         for (i=0;i<tetrahedronAdded.size();++i) {
00096 
00098             const TetrahedronEdges &te= ff->_topology->getEdgeTetraShell(tetrahedronAdded[i]);
00100             const Tetrahedron &t= ff->_topology->getTetra(tetrahedronAdded[i]);
00101             // store points
00102             for(j=0;j<4;++j)
00103                 point[j]=(*restPosition)[t[j]];
00105             volume=dot(cross(point[1]-point[0],point[2]-point[0]),point[0]-point[3]);
00106             // store shape vectors
00107             for(j=0;j<4;++j) {
00108                 if ((j%2)==0)
00109                     shapeVector[j]=cross(point[(j+2)%4] - point[(j+1)%4],point[(j+3)%4] - point[(j+1)%4])/volume;
00110                 else 
00111                     shapeVector[j]= -cross(point[(j+2)%4] - point[(j+1)%4],point[(j+3)%4] - point[(j+1)%4])/volume;
00112             }
00113             
00114             lambdastar=lambda*fabs(volume)/6;
00115             mustar=mu*fabs(volume)/6;
00116 
00117 
00118             for(j=0;j<6;++j){
00120                 k = ff->_topology->getLocalTetrahedronEdges(j)[0];
00121                 l = ff->_topology->getLocalTetrahedronEdges(j)[1];
00122 
00123                 Mat3 &m=edgeData[te[j]].DfDx;
00124 
00125                 val1= dot(shapeVector[k],shapeVector[l])*mustar;
00126                 // print if obtuse tetrahedron along that edge
00127                 if (ff->f_printLog.getValue()) {
00128                     if (val1<0) 
00129                         std::cerr<<"negative cotangent["<<tetrahedronAdded[i]<<"]["<<j<<"]"<<std::endl;
00130                 }
00131 
00132                 if (ff->_topology->getEdge(te[j])[0]!=t[l]) {
00133                     for (u=0;u<3;++u) {
00134                         for (v=0;v<3;++v) {
00135                             m[u][v]+= lambdastar*shapeVector[l][u]*shapeVector[k][v]+mustar*shapeVector[k][u]*shapeVector[l][v];
00136                         }
00137                         m[u][u]+=val1;
00138                     }
00139                 } else {
00140                     for (u=0;u<3;++u) {
00141                         for (v=0;v<3;++v) {
00142                             m[v][u]+= lambdastar*shapeVector[l][u]*shapeVector[k][v]+mustar*shapeVector[k][u]*shapeVector[l][v];
00143                         }
00144                         m[u][u]+=val1;
00145                     }
00146                 }
00147 
00148 
00149             }
00150         }
00151 
00152     }
00153 }
00154 
00155 template< class DataTypes>
00156 void TetrahedralTensorMassForceField<DataTypes>::TetrahedralTMTetrahedronDestructionFunction (const helper::vector<unsigned int> &tetrahedronRemoved, 
00157                                                                                            void* param, helper::vector<EdgeRestInformation> &edgeData)
00158 {
00159     TetrahedralTensorMassForceField<DataTypes> *ff= (TetrahedralTensorMassForceField<DataTypes> *)param;
00160     if (ff) {
00161         
00162         unsigned int i,j,k,l,u,v;
00163 
00164         typename DataTypes::Real val1,volume;
00165         typename DataTypes::Real lambda=ff->getLambda();
00166         typename DataTypes::Real mu=ff->getMu();
00167         typename DataTypes::Real lambdastar, mustar;
00168         typename DataTypes::Coord point[4],shapeVector[4];      
00169         
00170         const typename DataTypes::VecCoord *restPosition=ff->mstate->getX0();
00171 
00172         for (i=0;i<tetrahedronRemoved.size();++i) {
00173 
00175             const TetrahedronEdges &te= ff->_topology->getEdgeTetraShell(tetrahedronRemoved[i]);
00177             const Tetrahedron &t= ff->_topology->getTetra(tetrahedronRemoved[i]);
00178             // store points
00179             for(j=0;j<4;++j)
00180                 point[j]=(*restPosition)[t[j]];
00182             volume=dot(cross(point[1]-point[0],point[2]-point[0]),point[0]-point[3]);
00183             // store shape vectors
00184             for(j=0;j<4;++j) {
00185                 if ((j%2)==0)
00186                     shapeVector[j]=cross(point[(j+2)%4] - point[(j+1)%4],point[(j+3)%4] - point[(j+1)%4])/volume;
00187                 else 
00188                     shapeVector[j]= -cross(point[(j+2)%4] - point[(j+1)%4],point[(j+3)%4] - point[(j+1)%4])/volume;
00189             }
00190             
00191             lambdastar=lambda*fabs(volume)/6;
00192             mustar=mu*fabs(volume)/6;
00193 
00194 
00195             for(j=0;j<6;++j){
00197                 k = ff->_topology->getLocalTetrahedronEdges(j)[0];
00198                 l = ff->_topology->getLocalTetrahedronEdges(j)[1];
00199 
00200                 Mat3 &m=edgeData[te[j]].DfDx;
00201 
00202                 val1= dot(shapeVector[k],shapeVector[l])*mustar;
00203                 // print if obtuse tetrahedron along that edge
00204                 if (ff->f_printLog.getValue()) {
00205                     if (val1<0) 
00206                         std::cerr<<"negative cotangent["<<tetrahedronRemoved[i]<<"]["<<j<<"]"<<std::endl;
00207                 }
00208 
00209                 if (ff->_topology->getEdge(te[j])[0]!=t[l]) {
00210                     for (u=0;u<3;++u) {
00211                         for (v=0;v<3;++v) {
00212                             m[u][v]-= lambdastar*shapeVector[l][u]*shapeVector[k][v]+mustar*shapeVector[k][u]*shapeVector[l][v];
00213                         }
00214                         m[u][u]-=val1;
00215                     }
00216                 } else {
00217                     for (u=0;u<3;++u) {
00218                         for (v=0;v<3;++v) {
00219                             m[v][u]-= lambdastar*shapeVector[l][u]*shapeVector[k][v]+mustar*shapeVector[k][u]*shapeVector[l][v];
00220                         }
00221                         m[u][u]-=val1;
00222                     }
00223                 }
00224 
00225 
00226             }
00227 
00228         }
00229 
00230     }
00231 }
00232 
00233 
00234 template <class DataTypes> TetrahedralTensorMassForceField<DataTypes>::TetrahedralTensorMassForceField() 
00235 : _initialPoints(0) 
00236 , updateMatrix(true)
00237 , f_poissonRatio(initData(&f_poissonRatio,(Real)0.3,"poissonRatio","Poisson ratio in Hooke's law"))
00238 , f_youngModulus(initData(&f_youngModulus,(Real)1000.,"youngModulus","Young modulus in Hooke's law"))
00239 , lambda(0)
00240 , mu(0)
00241     {
00242     }
00243 
00244 template <class DataTypes> void TetrahedralTensorMassForceField<DataTypes>::handleTopologyChange()
00245 {
00246     std::list<const TopologyChange *>::const_iterator itBegin=_topology->firstChange();
00247     std::list<const TopologyChange *>::const_iterator itEnd=_topology->lastChange();
00248 
00249     edgeInfo.handleTopologyEvents(itBegin,itEnd);
00250 }
00251 
00252 template <class DataTypes> TetrahedralTensorMassForceField<DataTypes>::~TetrahedralTensorMassForceField()
00253 {
00254 
00255 }
00256 
00257 template <class DataTypes> void TetrahedralTensorMassForceField<DataTypes>::init()
00258 {
00259     std::cerr << "initializing TetrahedralTensorMassForceField" << std::endl;
00260     this->Inherited::init();
00261 
00262     _topology = getContext()->getMeshTopology();
00263 
00264     if (_topology->getNbTetras()==0)
00265     {
00266         std::cerr << "ERROR(TetrahedralTensorMassForceField): object must have a Tetrahedral Set Topology.\n";
00267         return;
00268     }
00269     updateLameCoefficients();
00270 
00272     edgeInfo.resize(_topology->getNbEdges());
00273 
00274     if (_initialPoints.size() == 0)
00275     {
00276     // get restPosition
00277       VecCoord& p = *this->mstate->getX0();
00278       _initialPoints=p;
00279     }
00280 
00281     int i;
00282     // set edge tensor to 0
00283     for (i=0;i<_topology->getNbEdges();++i) {
00284         TetrahedralTMEdgeCreationFunction(i, (void*) this, edgeInfo[i],
00285             _topology->getEdge(i),  (const std::vector< unsigned int > )0,
00286             (const std::vector< double >)0);
00287     }
00288     // create edge tensor by calling the tetrahedron creation function
00289     std::vector<unsigned int> tetrahedronAdded;
00290     for (i=0;i<_topology->getNbTetras();++i)
00291         tetrahedronAdded.push_back(i);
00292     TetrahedralTMTetrahedronCreationFunction(tetrahedronAdded,(void*) this,
00293         edgeInfo);
00294 
00295 
00296     edgeInfo.setCreateFunction(TetrahedralTMEdgeCreationFunction);
00297     edgeInfo.setCreateTetrahedronFunction(TetrahedralTMTetrahedronCreationFunction);
00298     edgeInfo.setDestroyTetrahedronFunction(TetrahedralTMTetrahedronDestructionFunction);
00299     edgeInfo.setCreateParameter( (void *) this );
00300     edgeInfo.setDestroyParameter( (void *) this );
00301 
00302 }
00303 
00304 
00305 template <class DataTypes> 
00306     double TetrahedralTensorMassForceField<DataTypes>::getPotentialEnergy(const VecCoord& /*x*/)
00307 {
00308     std::cerr<<"TetrahedralTensorMassForceField::getPotentialEnergy-not-implemented !!!"<<endl;
00309     return 0;
00310 }
00311 template <class DataTypes> 
00312 void TetrahedralTensorMassForceField<DataTypes>::addForce(VecDeriv& f, const VecCoord& x, const VecDeriv& /*v*/)
00313 {
00314     unsigned int v0,v1;
00315     int nbEdges=_topology->getNbEdges();
00316 
00317     EdgeRestInformation *einfo;
00318 
00319     Deriv force;
00320     Coord dp0,dp1,dp;
00321 
00322 
00323     for(int i=0; i<nbEdges; i++ )
00324     {
00325         einfo=&edgeInfo[i];
00326         v0=_topology->getEdge(i)[0];
00327         v1=_topology->getEdge(i)[1];
00328         dp0=x[v0]-_initialPoints[v0];
00329         dp1=x[v1]-_initialPoints[v1];
00330         dp = dp1-dp0;
00331 
00332         f[v1]+=einfo->DfDx*dp;
00333         f[v0]-=einfo->DfDx.transposeMultiply(dp);
00334     }
00335 
00336 }
00337 
00338 
00339 template <class DataTypes> 
00340 void TetrahedralTensorMassForceField<DataTypes>::addDForce(VecDeriv& df, const VecDeriv& dx)
00341 {
00342     unsigned int v0,v1;
00343     int nbEdges=_topology->getNbEdges();
00344 
00345     EdgeRestInformation *einfo;
00346 
00347 
00348     Deriv force;
00349     Coord dp0,dp1,dp;
00350 
00351     for(int i=0; i<nbEdges; i++ )
00352     {
00353         einfo=&edgeInfo[i];
00354         v0=_topology->getEdge(i)[0];
00355         v1=_topology->getEdge(i)[1];
00356         dp0=dx[v0];
00357         dp1=dx[v1];
00358         dp = dp1-dp0;
00359 
00360         df[v1]+=einfo->DfDx*dp;
00361         df[v0]-=einfo->DfDx.transposeMultiply(dp);
00362     }
00363 
00364 }
00365 
00366 
00367 template<class DataTypes>
00368 void TetrahedralTensorMassForceField<DataTypes>::updateLameCoefficients()
00369 {
00370     lambda= f_youngModulus.getValue()*f_poissonRatio.getValue()/((1-2*f_poissonRatio.getValue())*(1+f_poissonRatio.getValue()));
00371     mu = f_youngModulus.getValue()/(2*(1+f_poissonRatio.getValue()));
00372 //  std::cerr << "initialized Lame coef : lambda=" <<lambda<< " mu="<<mu<<std::endl;
00373 }
00374 
00375 
00376 template<class DataTypes>
00377 void TetrahedralTensorMassForceField<DataTypes>::draw()
00378 {
00379     if (!getContext()->getShowForceFields()) return;
00380     if (!this->mstate) return;
00381 
00382     if (getContext()->getShowWireFrame())
00383         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00384 
00385 //  VecCoord& x = *this->mstate->getX();
00386 //  int nbTriangles=_topology->getNbTriangles();
00387 
00388 /*
00389     glDisable(GL_LIGHTING);
00390 
00391     glBegin(GL_TRIANGLES);
00392     for(i=0;i<nbTriangles; ++i)
00393     {
00394         int a = _topology->getTriangle(i)[0];
00395         int b = _topology->getTriangle(i)[1];
00396         int c = _topology->getTriangle(i)[2];
00397 
00398         glColor4f(0,1,0,1);
00399         helper::gl::glVertexT(x[a]);
00400         glColor4f(0,0.5,0.5,1);
00401         helper::gl::glVertexT(x[b]);
00402         glColor4f(0,0,1,1);
00403         helper::gl::glVertexT(x[c]);
00404     }
00405     glEnd();
00406 
00407 */
00408     if (getContext()->getShowWireFrame())
00409         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00410 }
00411 
00412 } // namespace forcefield
00413 
00414 } // namespace Components
00415 
00416 } // namespace Sofa

Generated on Sun Nov 23 03:13:50 2008 for Sofa by  doxygen 1.5.7.1