HexahedralFEMForceField.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_HEXAHEDRALFEMFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_HEXAHEDRALFEMFORCEFIELD_INL
00027 
00028 #include <sofa/core/componentmodel/behavior/ForceField.inl>
00029 #include <sofa/component/forcefield/HexahedralFEMForceField.h>
00030 #include <sofa/helper/PolarDecompose.h>
00031 #include <sofa/helper/gl/template.h>
00032 #include <assert.h>
00033 #include <iostream>
00034 #include <set>
00035 
00036 #include <sofa/component/topology/HexahedronData.inl>
00037 
00038 using std::cerr;
00039 using std::endl;
00040 using std::set;
00041 
00042 
00043 
00044 // indices ordering  (same as in HexahedronSetTopology):
00045 //
00046 //     Y  7---------6
00047 //     ^ /         /|
00048 //     |/    Z    / |
00049 //     3----^----2  |
00050 //     |   /     |  |
00051 //     |  4------|--5
00052 //     | /       | /
00053 //     |/        |/
00054 //     0---------1-->X
00055 
00056 
00057 
00058 namespace sofa
00059 {
00060 
00061 namespace component
00062 {
00063 
00064 namespace forcefield
00065 {
00066 
00067 using namespace sofa::defaulttype;
00068 using namespace sofa::component::topology;
00069 using namespace core::componentmodel::topology;
00070 
00071 template< class DataTypes>
00072 void HexahedralFEMForceField<DataTypes>::FHexahedronCreationFunction (int hexahedronIndex, void* param, 
00073                                                                                       HexahedronInformation &,
00074                                                                                       const Hexahedron& , 
00075                                                                                       const helper::vector< unsigned int > &,
00076                                                                                       const helper::vector< double >&)
00077 {
00078     HexahedralFEMForceField<DataTypes> *ff= (HexahedralFEMForceField<DataTypes> *)param;
00079     if (ff) {
00080 
00081         switch(ff->method)
00082         {
00083         case LARGE :
00084             ff->computeMaterialStiffness(hexahedronIndex);
00085             ff->initLarge(hexahedronIndex);
00086 
00087             break;
00088         case POLAR :
00089             ff->computeMaterialStiffness(hexahedronIndex);
00090             ff->initPolar(hexahedronIndex);
00091             break;
00092         }
00093     }
00094 }
00095 
00096 template<class DataTypes>
00097 void HexahedralFEMForceField<DataTypes>::parse(core::objectmodel::BaseObjectDescription* arg)
00098 {
00099     this->core::componentmodel::behavior::ForceField<DataTypes>::parse(arg);
00100     //this->setComputeGlobalMatrix(std::string(arg->getAttribute("computeGlobalMatrix","false"))=="true"); // necessary ?
00101     
00102 }
00103 
00104 template <class DataTypes> void HexahedralFEMForceField<DataTypes>::handleTopologyChange()
00105 {
00106     std::list<const TopologyChange *>::const_iterator itBegin=_topology->firstChange();
00107     std::list<const TopologyChange *>::const_iterator itEnd=_topology->lastChange();
00108 
00109 
00110     hexahedronInfo.handleTopologyEvents(itBegin,itEnd);
00111 
00112 }
00113 
00114 template <class DataTypes>
00115 void HexahedralFEMForceField<DataTypes>::init()
00116 {
00117     if(_alreadyInit)return;
00118     else _alreadyInit=true;
00119     
00120     this->core::componentmodel::behavior::ForceField<DataTypes>::init();
00121 
00122     _topology = getContext()->getMeshTopology();    
00123 
00124     if (_topology->getNbHexas()==0)
00125     {
00126         std::cerr << "ERROR(HexahedralFEMForceField): object must have a Hexahedral Set Topology.\n";
00127         return;
00128     }
00129 
00130     
00131     /*
00132     if( this->getContext()->getMeshTopology()==NULL )
00133     {
00134         std::cerr << "ERROR(HexahedralFEMForceField): object must have a Topology.\n";
00135         return;
00136     }
00137         
00138     if ( _topology==NULL)
00139     {
00140         std::cerr << "ERROR(HexahedralFEMForceField): object must have a MeshTopology.\n";
00141         return;
00142     }
00143     else if( _topology->getNbCubes()<=0 )
00144     {
00145         std::cerr << "ERROR(HexahedralFEMForceField): object must have a hexahedric MeshTopology.\n";
00146         std::cerr << _topology->getName()<<std::endl;
00147         std::cerr << _topology->getTypeName()<<std::endl;
00148         cerr<<_topology->getNbPoints()<<endl;
00149         return;
00150     }
00151 
00152     */
00153 
00154 //  if (!_topology->getCubes().empty())
00155 //  else
00156 //  {
00157         //_indexedElements = & (_topology->getCubes());
00158 //  }
00159     //_sparseGrid = dynamic_cast<topology::SparseGridTopology*>(_topology);
00160     
00161 
00162     /*
00163     if (_initialPoints.getValue().size() == 0)
00164     {
00165       VecCoord& p = *this->mstate->getX();
00166       _initialPoints.setValue(p);
00167     }
00168     */
00169     
00170     //hexahedronInfo[i].materialMatrix.resize(_indexedElements->size() );
00171     //_rotations.resize( _indexedElements->size() );
00172     //_rotatedInitialElements.resize(_topology->getNbHexas()); //_indexedElements->size()
00173     // _elementStiffnesses.resize(_topology->getNbHexas()); //_indexedElements->size()
00174     //  _stiffnesses.resize( _initialPoints.getValue().size()*3 ); // assembly ?
00175     
00176     reinit(); // compute per-element stiffness matrices and other precomputed values
00177     
00178     
00179 //  unsigned int i=0;
00180 //  typename VecElement::const_iterator it;
00181 //  for(it = _indexedElements->begin() ; it != _indexedElements->end() ; ++it, ++i)
00182 //  {
00183 //      Element c = *it;
00184 //      for(int w=0;w<8;++w)
00185 //      {
00186 //          cerr<<"sparse w : "<<c[w]<<"    "<<_initialPoints.getValue()[c[w]]<<endl;
00187 //      }
00188 //      cerr<<"------\n";
00189 //  }
00190     
00191 
00192     
00193     
00194     
00195     
00196 }
00197 
00198 
00199 template <class DataTypes>
00200         void HexahedralFEMForceField<DataTypes>::reinit()
00201 {
00202   if (f_method.getValue() == "large")
00203     this->setMethod(LARGE);
00204   else if (f_method.getValue()  == "polar")
00205     this->setMethod(POLAR); 
00206 
00207     hexahedronInfo.resize(_topology->getNbHexas());
00208 
00209     for (int i=0;i<_topology->getNbHexas();++i) {
00210         FHexahedronCreationFunction(i, (void*) this, hexahedronInfo[i],
00211             _topology->getHexa(i),  (const std::vector< unsigned int > )0,
00212             (const std::vector< double >)0);
00213     }
00214 
00215     hexahedronInfo.setCreateFunction(FHexahedronCreationFunction);
00216     hexahedronInfo.setCreateParameter( (void *) this );
00217     hexahedronInfo.setDestroyParameter( (void *) this );
00218 
00219 }
00220 
00221 
00222 
00226 
00227 
00228 
00229 
00230 template<class DataTypes>
00231 void HexahedralFEMForceField<DataTypes>::addForce (VecDeriv& f, const VecCoord& p, const VecDeriv& /*v*/)
00232 {
00233     f.resize(p.size()); 
00234 
00235     switch(method)
00236     {
00237     case LARGE :
00238         {
00239             for(int i = 0 ; i<_topology->getNbHexas();++i)
00240             {
00241                 accumulateForceLarge( f, p, i);
00242             }
00243             break;
00244         }
00245     case POLAR :
00246         {
00247             for(int i = 0 ; i<_topology->getNbHexas();++i)
00248             {
00249                 accumulateForcePolar( f, p, i);
00250             }
00251             break;
00252         }
00253     }
00254 
00255 }
00256 
00257 template<class DataTypes>
00258 void HexahedralFEMForceField<DataTypes>::addDForce (VecDeriv& v, const VecDeriv& x)
00259 {
00260     if( v.size()!=x.size() ) v.resize(x.size());        
00261 
00262         //typename VecElement::const_iterator it;
00263         
00264                 //for(it = _indexedElements->begin() ; it != _indexedElements->end() ; ++it, ++i)
00265                 for(int i = 0 ; i<_topology->getNbHexas();++i)
00266                 {
00267                     
00268                     Transformation R_0_2;
00269                     R_0_2.transpose(hexahedronInfo[i].rotation);
00270 
00271                     Displacement X;
00272                     
00273                     for(int w=0;w<8;++w)
00274                     {
00275                         Coord x_2;
00276                         x_2 = R_0_2 * x[_topology->getHexa(i)[w]]; 
00277                         X[w*3] = x_2[0];
00278                         X[w*3+1] = x_2[1];
00279                         X[w*3+2] = x_2[2];
00280                     }
00281         
00282                     Displacement F;
00283                     computeForce( F, X, hexahedronInfo[i].stiffness );//computeForce( F, X, hexahedronInfo[i].stiffness );
00284                     
00285                                         
00286                     for(int w=0;w<8;++w)
00287                         v[_topology->getHexa(i)[w]] -= hexahedronInfo[i].rotation * Deriv( F[w*3],  F[w*3+1],  F[w*3+2]  );
00288                 }
00289                 
00290 }
00291 
00292 template <class DataTypes> 
00293     double HexahedralFEMForceField<DataTypes>::getPotentialEnergy(const VecCoord&)
00294 {
00295     std::cerr<<"HexahedralFEMForceField::getPotentialEnergy-not-implemented !!!"<<std::endl;
00296     return 0;
00297 }
00298 
00299 
00300 
00301 
00302 
00306 
00307 
00308 
00309 
00310 
00311 
00312 template<class DataTypes>
00313 void HexahedralFEMForceField<DataTypes>::computeElementStiffness( ElementStiffness &K, const MaterialStiffness &M, const Vec<8,Coord> &nodes, const int /* elementIndice */)
00314 {
00315     Mat33 J_1; // only accurate for orthogonal regular hexa
00316     J_1.fill( 0.0 );
00317     Coord l = nodes[6] - nodes[0];
00318     J_1[0][0]=2.0f / l[0];
00319     J_1[1][1]=2.0f / l[1];
00320     J_1[2][2]=2.0f / l[2];
00321     
00322 
00323     Real vol = ((nodes[1]-nodes[0]).norm()*(nodes[3]-nodes[0]).norm()*(nodes[4]-nodes[0]).norm());
00324     vol /= 8.0; // ???
00325     
00326     K.clear();
00327     
00328     
00329     for(int i=0;i<8;++i)
00330     {
00331         Mat33 k = vol*integrateStiffness(  _coef[i][0], _coef[i][1],_coef[i][2],  _coef[i][0], _coef[i][1],_coef[i][2], M[0][0], M[0][1],M[2][2], J_1  );
00332         
00333         
00334         for(int m=0;m<3;++m)
00335             for(int l=0;l<3;++l)
00336         {
00337                 K[i*3+m][i*3+l] += k[m][l];
00338         }       
00339         
00340                     
00341     
00342         for(int j=i+1;j<8;++j)
00343         {
00344             Mat33 k = vol*integrateStiffness(  _coef[i][0], _coef[i][1],_coef[i][2],  _coef[j][0], _coef[j][1],_coef[j][2], M[0][0], M[0][1],M[2][2], J_1  );
00345             
00346     
00347             for(int m=0;m<3;++m)
00348                 for(int l=0;l<3;++l)
00349             {
00350                 K[i*3+m][j*3+l] += k[m][l];
00351 //                  K[j*3+l][i*3+m] += k[m][l];
00352             }
00353         }
00354     }
00355 
00356     for(int i=0;i<24;++i)
00357         for(int j=i+1;j<24;++j)
00358     {
00359         K[j][i] = K[i][j];
00360     }
00361 
00362 
00363 }
00364 
00365 
00366 
00367 
00368 template<class DataTypes>
00369 typename HexahedralFEMForceField<DataTypes>::Mat33 HexahedralFEMForceField<DataTypes>::integrateStiffness( int signx0, int signy0, int signz0, int signx1, int signy1, int signz1, const Real u, const Real v, const Real w, const Mat33& J_1  )
00370 {
00371 //  Real xmax=1,ymax=1,zmax=1,xmin=-1,ymin=-1,zmin=-1;
00372 //  Real t1 = (Real)(signx0*signy0);
00373 //  Real t2 = signz0*w;
00374 //  Real t3 = t2*signx1;
00375 //  Real t4 = t1*t3;
00376 //  Real t5 = xmax-xmin;
00377 //  Real t6 = t5*signy1/2.0f;
00378 //  Real t7 = ymax-ymin;
00379 //  Real t8 = t6*t7/2.0f;
00380 //  Real t9 = zmax-zmin;
00381 //  Real t10 = signz1*t9/2.0f;
00382 //  Real t12 = t8*t10*J_1[0][0];
00383 //  Real t15 = signz0*u;
00384 //  Real t17 = t1*t15*signx1;
00385 //  Real t20 = (Real)(signy0*signz0);
00386 //  Real t23 = 1.0f+signx1*(xmax+xmin)/2.0f;
00387 //  Real t24 = w*t23;
00388 //  Real t26 = signy1*t7/2.0f;
00389 //  Real t27 = t26*t10;
00390 //  Real t28 = t20*t24*t27;
00391 //  Real t29 = (Real)(signx0*signz0);
00392 //  Real t30 = u*signx1;
00393 //  Real t34 = 1.0f+signy1*(ymax+ymin)/2.0f;
00394 //  Real t35 = t5*t34/2.0f;
00395 //  Real t36 = t35*t10;
00396 //  Real t37 = t29*t30*t36;
00397 //  Real t44 = 1.0f+signz1*(zmax+zmin)/2.0f;
00398 //  Real t46 = t6*t7*t44/2.0f;
00399 //  Real t47 = t1*t30*t46;
00400 //  Real t53 = t35*t44;
00401 //  Real t55 = t2*t23;
00402 //  Real t57 = t34*signz1*t9/2.0f;
00403 //  Real t58 = t55*t57;
00404 //  Real t59 = signy0*w;
00405 //  Real t60 = t59*t23;
00406 //  Real t61 = t26*t44;
00407 //  Real t62 = t60*t61;
00408 //  Real t66 = w*signx1;
00409 //  Real t67 = t1*t66;
00410 //  Real t68 = t67*t46;
00411 //  Real t69 = t29*t66;
00412 //  Real t70 = t69*t36;
00413 //  Real t75 = v*t23;
00414 //  Real t78 = t20*t66;
00415 //  Real t84 = signx0*v*t23;
00416 //  Real t104 = v*signx1;
00417 //  Real t105 = t20*t104;
00418 //  Real t112 = signy0*v;
00419 //  Real t115 = signx0*w;
00420 //  Real t116 = t115*t23;
00421 //  Real t123 = t8*t10*J_1[1][1];
00422 //  Real t130 = t20*u*t23*t27;
00423 //  Real t141 = t115*signx1*t53;
00424 //  Real t168 = signz0*v;
00425 //  Real t190 = t8*t10*J_1[2][2];
00426 //  Mat33 K;
00427 //  K[0][0] = t4*t12/36.0f+t17*t12/72.0f+(t28+t37)*J_1[0][0]/24.0f+(t47+t28)*J_1[0][0]/
00428 //          24.0f+(signx0*u*signx1*t53+t58+t62)*J_1[0][0]/8.0f+(t68+t70)*J_1[0][0]/24.0f;
00429 //  K[0][1] = (t29*t75*t27+t78*t36)*J_1[1][1]/24.0f+(t84*t61+t59*signx1*t53)*J_1[1][1]
00430 // /8.0f;
00431 //  K[0][2] = (t1*t75*t27+t78*t46)*J_1[2][2]/24.0f+(t84*t57+t3*t53)*J_1[2][2]/8.0f;
00432 //  K[1][0] = (t105*t36+t29*t24*t27)*J_1[0][0]/24.0f+(t112*signx1*t53+t116*t61)
00433 //          *J_1[0][0]/8.0f;
00434 //  K[1][1] = t17*t123/72.0f+t4*t123/36.0f+(t70+t130)*J_1[1][1]/24.0f+(t68+t28)*
00435 //          J_1[1][1]/24.0f+(signy0*u*t23*t61+t58+t141)*J_1[1][1]/8.0f+(t47+t70)*J_1[1][1]/24.0f;
00436 //  K[1][2] = (t1*t104*t36+t69*t46)*J_1[2][2]/24.0f+(t112*t23*t57+t55*t61)*J_1[2][2]/
00437 //          8.0f;
00438 //  K[2][0] = (t105*t46+t1*t24*t27)*J_1[0][0]/24.0f+(t168*signx1*t53+t116*t57)*
00439 //          J_1[0][0]/8.0f;
00440 //  K[2][1] = (t29*t104*t46+t67*t36)*J_1[1][1]/24.0f+(t168*t23*t61+t60*t57)*J_1[1][1]/
00441 //          8.0f;
00442 //  K[2][2] = t4*t190/36.0f+(t28+t70)*J_1[2][2]/24.0f+t17*t190/72.0f+(t68+t130)*
00443 //          J_1[2][2]/24.0f+(t15*t23*t57+t62+t141)*J_1[2][2]/8.0f+(t68+t37)*J_1[2][2]/24.0f;
00444 // 
00445 //  return J_1 * K;
00446     
00447     Mat33 K;
00448     
00449     Real t1 = J_1[0][0]*J_1[0][0];
00450     Real t2 = t1*signx0;
00451     Real t3 = (Real)(signy0*signz0);
00452     Real t4 = t2*t3;
00453     Real t5 = w*signx1;
00454     Real t6 = (Real)(signy1*signz1);
00455     Real t7 = t5*t6;
00456     Real t10 = t1*signy0;
00457     Real t12 = w*signy1;
00458     Real t13 = t12*signz1;
00459     Real t16 = t2*signz0;
00460     Real t17 = u*signx1;
00461     Real t18 = t17*signz1;
00462     Real t21 = t17*t6;
00463     Real t24 = t2*signy0;
00464     Real t25 = t17*signy1;
00465     Real t28 = t5*signy1;
00466     Real t32 = w*signz1;
00467     Real t37 = t5*signz1;
00468     Real t43 = J_1[0][0]*signx0;
00469     Real t45 = v*J_1[1][1];
00470     Real t49 = J_1[0][0]*signy0;
00471     Real t50 = t49*signz0;
00472     Real t51 = w*J_1[1][1];
00473     Real t52 = (Real)(signx1*signz1);
00474     Real t53 = t51*t52;
00475     Real t56 = t45*signy1;
00476     Real t64 = v*J_1[2][2];
00477     Real t68 = w*J_1[2][2];
00478         Real t69 = (Real)(signx1*signy1);
00479     Real t70 = t68*t69;
00480     Real t73 = t64*signz1;
00481     Real t81 = J_1[1][1]*signy0;
00482     Real t83 = v*J_1[0][0];
00483     Real t87 = J_1[1][1]*signx0;
00484     Real t88 = t87*signz0;
00485     Real t89 = w*J_1[0][0];
00486     Real t90 = t89*t6;
00487     Real t93 = t83*signx1;
00488     Real t100 = J_1[1][1]*J_1[1][1];
00489     Real t101 = t100*signx0;
00490     Real t102 = t101*t3;
00491     Real t110 = t100*signy0;
00492     Real t111 = t110*signz0;
00493     Real t112 = u*signy1;
00494     Real t113 = t112*signz1;
00495     Real t116 = t101*signy0;
00496     Real t144 = J_1[2][2]*signy0;
00497     Real t149 = J_1[2][2]*signx0;
00498     Real t150 = t149*signy0;
00499     Real t153 = J_1[2][2]*signz0;
00500     Real t172 = J_1[2][2]*J_1[2][2];
00501     Real t173 = t172*signx0;
00502     Real t174 = t173*t3;
00503     Real t177 = t173*signz0;
00504     Real t180 = t172*signy0;
00505     Real t181 = t180*signz0;
00506     K[0][0] = (float)(t4*t7/36.0+t10*signz0*t13/12.0+t16*t18/24.0+t4*t21/72.0+
00507             t24*t25/24.0+t24*t28/24.0+t1*signz0*t32/8.0+t10*t12/8.0+t16*t37/24.0+t2*t17/8.0);
00508         K[0][1] = (float)(t43*signz0*t45*t6/24.0+t50*t53/24.0+t43*t56/8.0+t49*t51*
00509             signx1/8.0);
00510         K[0][2] = (float)(t43*signy0*t64*t6/24.0+t50*t70/24.0+t43*t73/8.0+J_1[0][0]*signz0
00511             *t68*signx1/8.0);
00512         K[1][0] = (float)(t81*signz0*t83*t52/24.0+t88*t90/24.0+t81*t93/8.0+t87*t89*
00513             signy1/8.0);
00514         K[1][1] = (float)(t102*t7/36.0+t102*t21/72.0+t101*signz0*t37/12.0+t111*t113
00515             /24.0+t116*t28/24.0+t100*signz0*t32/8.0+t111*t13/24.0+t116*t25/24.0+t110*t112/
00516             8.0+t101*t5/8.0);
00517         K[1][2] = (float)(t87*signy0*t64*t52/24.0+t88*t70/24.0+t81*t73/8.0+J_1[1][1]*
00518             signz0*t68*signy1/8.0);
00519         K[2][0] = (float)(t144*signz0*t83*t69/24.0+t150*t90/24.0+t153*t93/8.0+t149*
00520             t89*signz1/8.0);
00521         K[2][1] = (float)(t149*signz0*t45*t69/24.0+t150*t53/24.0+t153*t56/8.0+t144*
00522             t51*signz1/8.0);
00523         K[2][2] = (float)(t174*t7/36.0+t177*t37/24.0+t181*t13/24.0+t174*t21/72.0+
00524             t173*signy0*t28/12.0+t180*t12/8.0+t181*t113/24.0+t177*t18/24.0+t172*signz0*u*
00525             signz1/8.0+t173*t5/8.0);
00526 
00527     return K /*/(J_1[0][0]*J_1[1][1]*J_1[2][2])*/;
00528     
00529 }
00530 
00531 
00532 
00533 template<class DataTypes>
00534 void HexahedralFEMForceField<DataTypes>::computeMaterialStiffness(int i)
00535 {
00536     //const Real youngModulus = (localStiffnessFactor.empty() ? 1.0f : localStiffnessFactor[i*localStiffnessFactor.size()/_topology->getNbHexas()])*_youngModulus;
00537 
00538     hexahedronInfo[i].materialMatrix[0][0] = hexahedronInfo[i].materialMatrix[1][1] = hexahedronInfo[i].materialMatrix[2][2] = 1;
00539     hexahedronInfo[i].materialMatrix[0][1] = hexahedronInfo[i].materialMatrix[0][2] = hexahedronInfo[i].materialMatrix[1][0]
00540             = hexahedronInfo[i].materialMatrix[1][2] = hexahedronInfo[i].materialMatrix[2][0] =
00541             hexahedronInfo[i].materialMatrix[2][1] = f_poissonRatio.getValue()/(1-f_poissonRatio.getValue());
00542     hexahedronInfo[i].materialMatrix[0][3] = hexahedronInfo[i].materialMatrix[0][4] =   hexahedronInfo[i].materialMatrix[0][5] = 0;
00543     hexahedronInfo[i].materialMatrix[1][3] = hexahedronInfo[i].materialMatrix[1][4] =   hexahedronInfo[i].materialMatrix[1][5] = 0;
00544     hexahedronInfo[i].materialMatrix[2][3] = hexahedronInfo[i].materialMatrix[2][4] =   hexahedronInfo[i].materialMatrix[2][5] = 0;
00545     hexahedronInfo[i].materialMatrix[3][0] = hexahedronInfo[i].materialMatrix[3][1] = hexahedronInfo[i].materialMatrix[3][2] = hexahedronInfo[i].materialMatrix[3][4] = hexahedronInfo[i].materialMatrix[3][5] = 0;
00546     hexahedronInfo[i].materialMatrix[4][0] = hexahedronInfo[i].materialMatrix[4][1] = hexahedronInfo[i].materialMatrix[4][2] = hexahedronInfo[i].materialMatrix[4][3] = hexahedronInfo[i].materialMatrix[4][5] = 0;
00547     hexahedronInfo[i].materialMatrix[5][0] = hexahedronInfo[i].materialMatrix[5][1] = hexahedronInfo[i].materialMatrix[5][2] = hexahedronInfo[i].materialMatrix[5][3] = hexahedronInfo[i].materialMatrix[5][4] = 0;
00548     hexahedronInfo[i].materialMatrix[3][3] = hexahedronInfo[i].materialMatrix[4][4] = hexahedronInfo[i].materialMatrix[5][5] = (1-2*f_poissonRatio.getValue())/(2*(1-f_poissonRatio.getValue()));
00549     hexahedronInfo[i].materialMatrix *= (f_youngModulus.getValue()*(1-f_poissonRatio.getValue()))/((1+f_poissonRatio.getValue())*(1-2*f_poissonRatio.getValue()));
00550 }
00551 
00552 template<class DataTypes>
00553         void HexahedralFEMForceField<DataTypes>::computeForce( Displacement &F, const Displacement &Depl, const ElementStiffness &K )
00554 {
00555     F = K*Depl;
00556 }
00557 
00558 
00559 
00560 
00561 
00562 
00563 
00564 
00565 
00570 
00571 
00572 template<class DataTypes>
00573 void HexahedralFEMForceField<DataTypes>::initLarge(int i)
00574 {
00575         // Rotation matrix (initial Hexahedre/world)
00576         // first vector on first edge
00577         // second vector in the plane of the two first edges
00578         // third vector orthogonal to first and second
00579 
00580     const VecCoord *X0=this->mstate->getX0();
00581 
00582     Vec<8,Coord> nodes;
00583     for(int w=0;w<8;++w)
00584         nodes[w] = (*X0)[_topology->getHexa(i)[w]];
00585     
00586     
00587         Coord horizontal;
00588         horizontal = (nodes[1]-nodes[0] + nodes[2]-nodes[3] + nodes[5]-nodes[4] + nodes[6]-nodes[7])*.25;
00589         Coord vertical;
00590         vertical = (nodes[3]-nodes[0] + nodes[2]-nodes[1] + nodes[7]-nodes[4] + nodes[6]-nodes[5])*.25;
00591         Transformation R_0_1;
00592         computeRotationLarge( R_0_1, horizontal,vertical);
00593         
00594     for(int w=0;w<8;++w)
00595         hexahedronInfo[i].rotatedInitialElements[w] = R_0_1*(*X0)[_topology->getHexa(i)[w]];
00596         
00597         
00598         computeElementStiffness( hexahedronInfo[i].stiffness, hexahedronInfo[i].materialMatrix, nodes, i );//computeElementStiffness( hexahedronInfo[i].stiffness, hexahedronInfo[i].materialMatrix, nodes, i );
00599         
00600         
00601 //      if(i==0) cerr<<hexahedronInfo[i].stiffness<<endl;
00602 }
00603 
00604 template<class DataTypes>
00605 void HexahedralFEMForceField<DataTypes>::computeRotationLarge( Transformation &r, Coord &edgex, Coord &edgey)
00606 {
00607     // first vector on first edge
00608     // second vector in the plane of the two first edges
00609     // third vector orthogonal to first and second  
00610     edgex.normalize();
00611     edgey.normalize();
00612 
00613     Coord edgez = cross( edgex, edgey );
00614     edgez.normalize();
00615 
00616     edgey = cross( edgez, edgex );
00617     edgey.normalize();
00618 
00619     r[0][0] = edgex[0];
00620     r[0][1] = edgex[1];
00621     r[0][2] = edgex[2];
00622     r[1][0] = edgey[0];
00623     r[1][1] = edgey[1];
00624     r[1][2] = edgey[2];
00625     r[2][0] = edgez[0];
00626     r[2][1] = edgez[1];
00627     r[2][2] = edgez[2];
00628     
00629     
00630 //  r[0][0] = 1;
00631 //  r[0][1] = 0;
00632 //  r[0][2] = 0;
00633 //  r[1][0] = 0;
00634 //  r[1][1] = 1;
00635 //  r[1][2] = 0;
00636 //  r[2][0] = 0;
00637 //  r[2][1] = 0;
00638 //  r[2][2] = 1;
00639 }
00640 
00641 template<class DataTypes>
00642 void HexahedralFEMForceField<DataTypes>::accumulateForceLarge( Vector& f, const Vector & p, int i)
00643 {   
00644     Vec<8,Coord> nodes;
00645     for(int w=0;w<8;++w)
00646         nodes[w] = p[_topology->getHexa(i)[w]];
00647     
00648     Coord horizontal;
00649     horizontal = (nodes[1]-nodes[0] + nodes[2]-nodes[3] + nodes[5]-nodes[4] + nodes[6]-nodes[7])*.25;
00650     Coord vertical;
00651     vertical = (nodes[3]-nodes[0] + nodes[2]-nodes[1] + nodes[7]-nodes[4] + nodes[6]-nodes[5])*.25;
00652     
00653     Transformation R_0_2; // Rotation matrix (deformed and displaced Hexahedron/world)
00654     computeRotationLarge( R_0_2, horizontal,vertical);
00655         
00656     hexahedronInfo[i].rotation.transpose(R_0_2);
00657     
00658     // positions of the deformed and displaced Hexahedre in its frame
00659     Vec<8,Coord> deformed;
00660     for(int w=0;w<8;++w)
00661         deformed[w] = R_0_2 * nodes[w];
00662     
00663     
00664     // displacement
00665     Displacement D;
00666     for(int k=0 ; k<8 ; ++k )
00667     {
00668         int indice = k*3;
00669         for(int j=0 ; j<3 ; ++j )   
00670             D[indice+j] = hexahedronInfo[i].rotatedInitialElements[k][j] - deformed[k][j];
00671     }
00672     
00673     
00674 //  if(f_updateStiffnessMatrix.getValue())
00675 //      computeElementStiffness( hexahedronInfo[i].stiffness, hexahedronInfo[i].materialMatrix, deformed );
00676 
00677     
00678     Displacement F; //forces
00679     computeForce( F, D, hexahedronInfo[i].stiffness ); // computeForce( F, D, hexahedronInfo[i].stiffness ); // compute force on element
00680 
00681     for(int w=0;w<8;++w)
00682     f[_topology->getHexa(i)[w]] += hexahedronInfo[i].rotation * Deriv( F[w*3],  F[w*3+1],   F[w*3+2]  );
00683 }
00684 
00685 
00686 
00687 
00688 
00689 
00690 
00695 
00696 
00697 
00698 template<class DataTypes>
00699 void HexahedralFEMForceField<DataTypes>::initPolar(int i)
00700 {
00701     const VecCoord *X0=this->mstate->getX0();
00702 
00703     Vec<8,Coord> nodes;
00704     for(int j=0;j<8;++j)
00705         nodes[j] = (*X0)[_topology->getHexa(i)[j]];
00706     
00707     Transformation R_0_1; // Rotation matrix (deformed and displaced Hexahedron/world)
00708     computeRotationPolar( R_0_1, nodes );
00709     
00710 
00711     for(int j=0;j<8;++j)
00712     {
00713         hexahedronInfo[i].rotatedInitialElements[j] = R_0_1 * nodes[j];
00714     }
00715         
00716     computeElementStiffness( hexahedronInfo[i].stiffness, hexahedronInfo[i].materialMatrix, nodes, i );
00717     
00718 }
00719 
00720 
00721 
00722 template<class DataTypes>
00723 void HexahedralFEMForceField<DataTypes>::computeRotationPolar( Transformation &r, Vec<8,Coord> &nodes)
00724 {
00725     Transformation A;
00726     Coord Edge =(nodes[1]-nodes[0] + nodes[2]-nodes[3] + nodes[5]-nodes[4] + nodes[6]-nodes[7])*.25;
00727     A[0][0] = Edge[0];
00728     A[0][1] = Edge[1];
00729     A[0][2] = Edge[2];
00730     Edge = (nodes[3]-nodes[0] + nodes[2]-nodes[1] + nodes[7]-nodes[4] + nodes[6]-nodes[5])*.25;
00731     A[1][0] = Edge[0];
00732     A[1][1] = Edge[1];
00733     A[1][2] = Edge[2];
00734     Edge = (nodes[4]-nodes[0] + nodes[5]-nodes[1] + nodes[7]-nodes[3] + nodes[6]-nodes[2])*.25;
00735     A[2][0] = Edge[0];
00736     A[2][1] = Edge[1];
00737     A[2][2] = Edge[2];
00738         
00739     Mat33 HT;
00740     for(int k=0;k<3;++k) 
00741         for(int j=0;j<3;++j) 
00742             HT[k][j]=A[k][j];
00743     //HT[3][0] = HT[3][1] = HT[3][2] = HT[0][3] = HT[1][3] = HT[2][3] = 0;
00744     //HT[3][3] = 1;
00745     Mat33 S;
00746     
00747     polar_decomp(HT, r, S);
00748 }
00749 
00750 
00751 template<class DataTypes>
00752 void HexahedralFEMForceField<DataTypes>::accumulateForcePolar( Vector& f, const Vector & p, int i)
00753 {
00754     Vec<8,Coord> nodes;
00755     for(int j=0;j<8;++j)
00756         nodes[j] = p[_topology->getHexa(i)[j]];
00757     
00758         
00759     Transformation R_0_2; // Rotation matrix (deformed and displaced Hexahedron/world)
00760     computeRotationPolar( R_0_2, nodes );
00761         
00762     hexahedronInfo[i].rotation.transpose( R_0_2 );
00763     
00764     
00765     // positions of the deformed and displaced Hexahedre in its frame
00766     Vec<8,Coord> deformed;
00767     for(int j=0;j<8;++j)
00768         deformed[j] = R_0_2 * nodes[j];
00769     
00770     
00771     
00772     // displacement
00773     Displacement D;
00774     for(int k=0 ; k<8 ; ++k )
00775     {
00776         int indice = k*3;
00777         for(int j=0 ; j<3 ; ++j )   
00778             D[indice+j] = hexahedronInfo[i].rotatedInitialElements[k][j] - deformed[k][j];
00779     }
00780             
00781     //forces        
00782     Displacement F;
00783     
00784 //  if(f_updateStiffnessMatrix.getValue())
00785 //      computeElementStiffness( hexahedronInfo[i].stiffness, hexahedronInfo[i].materialMatrix, deformed );
00786 
00787     // compute force on element
00788     computeForce( F, D, hexahedronInfo[i].stiffness );
00789         
00790 
00791     for(int j=0;j<8;++j)
00792         f[_topology->getHexa(i)[j]] += hexahedronInfo[i].rotation * Deriv( F[j*3],  F[j*3+1],   F[j*3+2]  );
00793 }
00794 
00795 
00796 
00797 
00798 
00799 
00803 
00804 
00805 
00806 
00807 
00808 template<class DataTypes>
00809 void HexahedralFEMForceField<DataTypes>::draw()
00810 {
00811 //  cerr<<"HexahedralFEMForceField<DataTypes>::draw()\n";
00812     if (!getContext()->getShowForceFields()) return;
00813     if (!this->mstate) return;
00814     
00815 
00816     const VecCoord& x = *this->mstate->getX();
00817 
00818     if (getContext()->getShowWireFrame())
00819         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00820 
00821     glDisable(GL_LIGHTING);
00822 
00823     //typename VecElement::const_iterator it;
00824     //int i;
00825     //for(it = _indexedElements->begin(), i = 0 ; it != _indexedElements->end() ; ++it, ++i)
00826     
00827     for(int i = 0 ; i<_topology->getNbHexas();++i)
00828     {
00829 
00830         const Hexahedron &t=_topology->getHexa(i);
00831 
00832         Index a = t[0];
00833         Index b = t[1];
00834         Index d = t[2];
00835         Index c = t[3];
00836         Index e = t[4];
00837         Index f = t[5];
00838         Index h = t[6];
00839         Index g = t[7];
00840 
00841 //      Coord center = (x[a]+x[b]+x[c]+x[d]+x[e]+x[g]+x[f]+x[h])*0.0625;
00842 //      Real percentage = 0.666667;
00843 //      Coord pa = (x[a]+center)*percentage;
00844 //      Coord pb = (x[b]+center)*percentage;
00845 //      Coord pc = (x[c]+center)*percentage;
00846 //      Coord pd = (x[d]+center)*percentage;
00847 //      Coord pe = (x[e]+center)*percentage;
00848 //      Coord pf = (x[f]+center)*percentage;
00849 //      Coord pg = (x[g]+center)*percentage;
00850 //      Coord ph = (x[h]+center)*percentage;
00851         
00852         Coord center = (x[a]+x[b]+x[c]+x[d]+x[e]+x[g]+x[f]+x[h])*0.125;
00853         Real percentage = (Real) 0.15;
00854         Coord p0 = x[a]-(x[a]-center)*percentage;
00855         Coord p1 = x[b]-(x[b]-center)*percentage;
00856         Coord p2 = x[c]-(x[c]-center)*percentage;
00857         Coord p3 = x[d]-(x[d]-center)*percentage;
00858         Coord p4 = x[e]-(x[e]-center)*percentage;
00859         Coord p5 = x[f]-(x[f]-center)*percentage;
00860         Coord p6 = x[g]-(x[g]-center)*percentage;
00861         Coord p7 = x[h]-(x[h]-center)*percentage;
00862         
00863         
00864 //      if( _sparseGrid && _sparseGrid->getType(i)==topology::SparseGridTopology::BOUNDARY )
00865 //          continue;
00866         
00867     glColor4f(0.7f, 0.7f, 0.1f, (1.0f));
00868         glBegin(GL_QUADS);
00869         helper::gl::glVertexT(p5);
00870         helper::gl::glVertexT(p1);
00871         helper::gl::glVertexT(p3);
00872         helper::gl::glVertexT(p7);
00873         //glEnd();
00874         glColor4f(0.7f, 0, 0, (1.0f));
00875         //glBegin(GL_POLYGON);
00876         helper::gl::glVertexT(p1);
00877         helper::gl::glVertexT(p0);
00878         helper::gl::glVertexT(p2);
00879         helper::gl::glVertexT(p3);
00880         //glEnd(); 
00881         glColor4f(0, 0.7f, 0, (1.0f)); // ok
00882         //glBegin(GL_POLYGON);
00883         helper::gl::glVertexT(p0);
00884         helper::gl::glVertexT(p4);
00885         helper::gl::glVertexT(p6);
00886         helper::gl::glVertexT(p2);
00887         //glEnd(); 
00888         glColor4f(0, 0, 0.7f, (1.0f));
00889         //glBegin(GL_POLYGON);
00890         helper::gl::glVertexT(p4);
00891         helper::gl::glVertexT(p5);
00892         helper::gl::glVertexT(p7);
00893         helper::gl::glVertexT(p6);
00894         //glEnd();
00895         glColor4f(0.1f, 0.7f, 0.7f, (1.0f)); // ok
00896         //glBegin(GL_POLYGON);
00897         helper::gl::glVertexT(p7);
00898         helper::gl::glVertexT(p3);
00899         helper::gl::glVertexT(p2);
00900         helper::gl::glVertexT(p6);
00901         //glEnd();
00902         glColor4f(0.7f, 0.1f, 0.7f, (1.0f));
00903         //glBegin(GL_POLYGON);
00904         helper::gl::glVertexT(p1);
00905         helper::gl::glVertexT(p5);
00906         helper::gl::glVertexT(p4);
00907         helper::gl::glVertexT(p0);
00908         glEnd();
00909     }
00910     
00911     if (getContext()->getShowWireFrame())
00912         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00913         
00914 }
00915 
00916 } // namespace forcefield
00917 
00918 } // namespace component
00919 
00920 } // namespace sofa
00921 
00922 #endif

Generated on Sun Nov 23 02:57:20 2008 for Sofa by  doxygen 1.5.7.1