TriangularAnisotropicFEMForceField.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 1       *
00003 *                (c) 2006-2007 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 the *
00007 * Free Software Foundation; either version 2.1 of the License, or (at your     *
00008 * 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 * Contact information: contact@sofa-framework.org                              *
00020 *                                                                              *
00021 * Authors: J. Allard, P-J. Bensoussan, S. Cotin, C. Duriez, H. Delingette,     *
00022 * F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza, M. Nesme, P. Neumann,        *
00023 * and F. Poyer                                                                 *
00024 *******************************************************************************/
00025 #include <sofa/component/forcefield/TriangularAnisotropicFEMForceField.h>
00026 #include <sofa/core/ObjectFactory.h>
00027 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00028 #include <sofa/helper/gl/template.h>
00029 #include <sofa/component/topology/TriangleData.inl>
00030 #include <sofa/component/topology/EdgeData.inl>
00031 #include <sofa/component/topology/PointData.inl>
00032 #include <sofa/helper/system/gl.h>
00033 #include <fstream> // for reading the file
00034 #include <iostream> //for debugging
00035 #include <vector>
00036 #include <algorithm>
00037 #include <sofa/defaulttype/Vec3Types.h>
00038 #include <assert.h>
00039 
00040 #ifdef _WIN32
00041 #include <windows.h>
00042 #endif
00043 
00044 
00045 // #define DEBUG_TRIANGLEFEM
00046 
00047 namespace sofa
00048 {
00049 
00050 namespace component
00051 {
00052 
00053 namespace forcefield
00054 {
00055 
00056 using namespace sofa::defaulttype;
00057 using namespace sofa::component::topology;
00058 using namespace core::componentmodel::topology;
00059 
00060 using std::cerr;
00061 using std::cout;
00062 using std::endl;
00063 
00064 SOFA_DECL_CLASS(TriangularAnisotropicFEMForceField)
00065 
00066 template <class DataTypes>
00067 TriangularAnisotropicFEMForceField<DataTypes>::TriangularAnisotropicFEMForceField()
00068 : f_young2(initData(&f_young2,(Real)(0.5*Inherited::f_young.getValue()),"transverseYoungModulus","Young modulus along transverse direction"))
00069 , f_theta(initData(&f_theta,(Real)(0.0),"fiberAngle","Fiber angle in global reference frame (in degrees)"))
00070 , f_fiberCenter(initData(&f_fiberCenter,"fiberCenter","Concentric fiber center in global reference frame"))
00071 , showFiber(initData(&showFiber,true,"showFiber","Flag activating rendering of fiber directions within each triangle"))
00072 {
00073 
00074 }
00075 
00076 template< class DataTypes>
00077 void TriangularAnisotropicFEMForceField<DataTypes>::TRQSTriangleCreationFunction (int triangleIndex, void* param, 
00078                                           TriangleInformation &/*tinfo*/,
00079                                           const Triangle& /*t*/, 
00080                             const sofa::helper::vector< unsigned int > &,
00081                             const sofa::helper::vector< double >&)
00082 {
00083     TriangularAnisotropicFEMForceField<DataTypes> *ff= (TriangularAnisotropicFEMForceField<DataTypes> *)param;
00084     if (ff) {
00085         
00086         const Triangle &t = ff->_topology->getTriangle(triangleIndex);
00087 
00088         Index a = t[0];
00089         Index b = t[1];
00090         Index c = t[2];
00091 
00092         switch(ff->method)
00093         {
00094         case SMALL :
00095             ff->computeMaterialStiffness(triangleIndex, a, b, c);
00096             ff->initSmall();
00097             break;
00098         case LARGE :
00099             ff->computeMaterialStiffness(triangleIndex, a, b, c);
00100             ff->initLarge(triangleIndex,a,b,c);
00101             break;
00102         }
00103     }
00104 }
00105 
00106 template< class DataTypes>
00107 void TriangularAnisotropicFEMForceField<DataTypes>::init()
00108 {
00109     Inherited::init();
00110 
00111     _topology = getContext()->getMeshTopology();
00112 
00113     //reinit();
00114 }
00115 
00116 template <class DataTypes>void TriangularAnisotropicFEMForceField<DataTypes>::reinit()
00117 {
00118     f_poisson2.setValue(Inherited::f_poisson.getValue()*(f_young2.getValue()/Inherited::f_young.getValue()));
00119     Inherited::reinit();
00120 }
00121 
00122 template <class DataTypes>
00123 void TriangularAnisotropicFEMForceField<DataTypes>::computeMaterialStiffness(int i, Index& v1, Index& v2, Index& v3)
00124 {
00125     TriangleInformation *tinfo = &Inherited::triangleInfo[i];
00126 
00127     Real Q11, Q12, Q22, Q66;
00128     Q11 = Inherited::f_young.getValue()/(1-Inherited::f_poisson.getValue()*f_poisson2.getValue());
00129     Q12 = Inherited::f_poisson.getValue()*f_young2.getValue()/(1-Inherited::f_poisson.getValue()*f_poisson2.getValue());
00130     Q22 = f_young2.getValue()/(1-Inherited::f_poisson.getValue()*f_poisson2.getValue());
00131     Q66 = (Real)(Inherited::f_young.getValue() / (2.0*(1 + Inherited::f_poisson.getValue())));
00132     
00133     Mat<3,3,Real> bary,baryInv;
00134     bary[0] = (*Inherited::_initialPoints)[v2]-(*Inherited::_initialPoints)[v1];
00135     bary[1] = (*Inherited::_initialPoints)[v3]-(*Inherited::_initialPoints)[v1];
00136     bary[2] = cross(bary[0],bary[1]);
00137     Coord fiberDir;
00138     if (!f_fiberCenter.getValue().empty())
00139     {
00140         Coord tcenter = ((*Inherited::_initialPoints)[v1]+(*Inherited::_initialPoints)[v2]+(*Inherited::_initialPoints)[v3])*(Real)(1.0/3.0);
00141         Coord fcenter = f_fiberCenter.getValue()[0];
00142         fiberDir = cross(bary[2],fcenter-tcenter);
00143     }
00144     else
00145     {
00146         double theta = (double)f_theta.getValue()*M_PI/180.0;
00147         //double theta_ref;
00148     
00149         fiberDir = Coord((Real)cos(theta), (Real)sin(theta), 0);
00150     }
00151     bary.transpose();
00152     baryInv.invert(bary);
00153     if (i >= (int) fiberDirRefs.size())
00154         fiberDirRefs.resize(i+1);
00155     Deriv& fiberDirRef = fiberDirRefs[i];
00156     fiberDirRef = baryInv * fiberDir;
00157     fiberDirRef[2] = 0;
00158     fiberDirRef.normalize();
00159 
00160     Real c, s, c2, s2, c3, s3,c4, s4;
00161     c = fiberDirRef[0]; //cos(theta_ref);
00162     s = fiberDirRef[1]; //sin(theta_ref);
00163     c2 = c*c;
00164     s2 = s*s;
00165     c3 = c2*c;
00166     s3 = s2*s;
00167     s4 = s2*s2;
00168     c4 = c2*c2;
00169     
00170     Real K11= c4 * Q11 + 2 *c2*s2 *(Q12+2*Q66) + s4 * Q22;
00171     Real K12 = c2*s2 * (Q11+Q22-4*Q66) + (c4+ s4) * Q12;
00172     Real K22 = s4* Q11 + 2  *c2*s2 * (Q12+2*Q66) + c4 * Q22;
00173     Real K16 = c3 * s * (Q11 - Q12) + c*s3* (Q12 - Q22) - 2*c*s* (c2 -s2) * Q66;
00174     Real K26 = c*s3 * (Q11-Q12) + c3*s* (Q12 - Q22) + 2*c*s* (c2 -s2) * Q66;
00175     Real K66 = c2*s2 * (Q11+Q22-2*Q12 - 2*Q66) + (c4+ s4) * Q66;
00176     
00177     tinfo->materialMatrix[0][0] = K11;
00178     tinfo->materialMatrix[0][1] = K12;
00179     tinfo->materialMatrix[0][2] = K16;
00180     tinfo->materialMatrix[1][0] = K12;
00181     tinfo->materialMatrix[1][1] = K22;
00182     tinfo->materialMatrix[1][2] = K26;
00183     tinfo->materialMatrix[2][0] = K16;
00184     tinfo->materialMatrix[2][1] = K26;
00185     tinfo->materialMatrix[2][2] = K66;
00186 
00187     tinfo->materialMatrix *= (Real)(1.0/12.0);
00188     
00189     cout << "Young1=" << Inherited::f_young.getValue() << endl;
00190     cout << "Young2=" << f_young2.getValue() << endl;
00191     cout << "Poisson1=" << Inherited::f_poisson.getValue() << endl;
00192     cout << "Poisson2=" << f_poisson2.getValue() << endl;
00193  }
00194 
00195 
00196 template <class DataTypes>void TriangularAnisotropicFEMForceField<DataTypes>::draw()
00197 {
00198     glPolygonOffset(1.0, 2.0);
00199     glEnable(GL_POLYGON_OFFSET_FILL);
00200     Inherited::draw();
00201     glDisable(GL_POLYGON_OFFSET_FILL);
00202     if (!getContext()->getShowForceFields())
00203       return;
00204     if (showFiber.getValue() && !fiberDirRefs.empty())
00205     {
00206         const VecCoord& x = *this->mstate->getX();
00207         int nbTriangles=_topology->getNbTriangles();
00208         glColor3f(1,1,1);
00209         glBegin(GL_LINES);
00210         //typename VecElement::const_iterator it;
00211         int i;
00212         for(i=0;i<nbTriangles; ++i) //it = _indexedElements->begin() ; it != _indexedElements->end() ; ++it
00213         {
00214             Index a = _topology->getTriangle(i)[0];//(*it)[0];
00215             Index b = _topology->getTriangle(i)[1];//(*it)[1];
00216             Index c = _topology->getTriangle(i)[2];//(*it)[2];
00217             Coord center = (x[a]+x[b]+x[c])/3;
00218             Coord d = (x[b]-x[a])*fiberDirRefs[i][0] + (x[c]-x[a])*fiberDirRefs[i][1];
00219             d*=0.4;
00220             helper::gl::glVertexT(center-d);
00221             helper::gl::glVertexT(center+d);
00222         }
00223         glEnd();
00224     }
00225 }
00226 
00227 
00228 // Register in the Factory
00229 int TriangularAnisotropicFEMForceFieldClass = core::RegisterObject("Triangular finite element model using anisotropic material")
00230 #ifndef SOFA_FLOAT
00231 .add< TriangularAnisotropicFEMForceField<Vec3dTypes> >()
00232 #endif
00233 #ifndef SOFA_DOUBLE
00234 .add< TriangularAnisotropicFEMForceField<Vec3fTypes> >()
00235 #endif
00236 ;
00237 
00238 #ifndef SOFA_FLOAT
00239 template class TriangularAnisotropicFEMForceField<Vec3dTypes>;
00240 #endif
00241 #ifndef SOFA_DOUBLE
00242 template class TriangularAnisotropicFEMForceField<Vec3fTypes>;
00243 #endif
00244 
00245     
00246 } // namespace forcefield
00247 
00248 } // namespace component
00249 
00250 } // namespace sofa

Generated on Sun Nov 23 03:16:29 2008 for Sofa by  doxygen 1.5.7.1