BeamFEMForceField.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_BEAMFEMFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_BEAMFEMFORCEFIELD_INL
00027 
00028 #include <sofa/core/componentmodel/behavior/ForceField.inl>
00029 #include <sofa/component/forcefield/BeamFEMForceField.h>
00030 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00031 #include <sofa/component/topology/GridTopology.h>
00032 #include <sofa/helper/PolarDecompose.h>
00033 #include <sofa/helper/gl/template.h>
00034 #include <sofa/helper/gl/Axis.h>
00035 #include <sofa/helper/rmath.h>
00036 #include <assert.h>
00037 #include <iostream>
00038 #include <set>
00039 #include <sofa/helper/system/gl.h>
00040 #include <sofa/core/componentmodel/behavior/MechanicalState.h>
00041 #include <sofa/defaulttype/VecTypes.h>
00042 #include <sofa/defaulttype/RigidTypes.h>
00043 #include <sofa/simulation/tree/GNode.h>
00044 using std::cerr;
00045 using std::endl;
00046 using std::set;
00047 
00048 
00049 namespace sofa
00050 {
00051 
00052 namespace component
00053 {
00054 
00055 namespace forcefield
00056 {
00057 
00058 using namespace sofa::core;
00059 using namespace sofa::core::componentmodel;
00060 using namespace sofa::defaulttype;
00061 
00062 template <class DataTypes>
00063 void BeamFEMForceField<DataTypes>::init()
00064 {
00065     this->core::componentmodel::behavior::ForceField<DataTypes>::init();
00066     sofa::core::objectmodel::BaseContext* context = this->getContext();
00067 
00068     _topology = context->getMeshTopology();
00069 
00070     stiffnessContainer = context->core::objectmodel::BaseContext::get<StiffnessContainer>();
00071     lengthContainer = context->core::objectmodel::BaseContext::get<LengthContainer>();
00072     poissonContainer = context->core::objectmodel::BaseContext::get<PoissonContainer>();
00073     radiusContainer = context->core::objectmodel::BaseContext::get<RadiusContainer>();
00074         
00075         if (_topology==NULL) 
00076         {
00077             std::cerr << "ERROR(BeamFEMForceField): object must have a BaseMeshTopology (i.e. EdgeSetTopology or MeshTopology).\n";
00078         return;
00079         }
00080     else
00081     {
00082         if(_topology->getNbEdges()==0)
00083         {
00084             std::cerr << "ERROR(BeamFEMForceField): topology is empty.\n";
00085             return;
00086         }
00087         _indexedElements = &_topology->getEdges();
00088     }
00089 
00090     beamsData.setCreateFunction(BeamFEMEdgeCreationFunction);
00091     beamsData.setCreateParameter( (void *) this );
00092     beamsData.setDestroyParameter( (void *) this );
00093     
00094     if (_initialPoints.getValue().size() == 0)
00095     {
00096         VecCoord& p = *this->mstate->getX();
00097         _initialPoints.setValue(p);
00098     }
00099 
00100     reinit();
00101 }
00102 
00103 template <class DataTypes>
00104 void BeamFEMForceField<DataTypes>::reinit()
00105 {
00106     unsigned int n = _indexedElements->size();
00107     //_beamQuat.resize( n );
00108     //_stiffnessMatrices.resize( n );
00109     _forces.resize( this->mstate->getSize() ); //_initialPoints.getValue().size() );
00110 
00111     if (!stiffnessContainer)
00112     {
00114         std::cerr << "Warning(BeamFEMForceField): No object from StiffnessContainer has been loaded.\n";
00115     }
00116     if (!lengthContainer)
00117     {
00119         std::cerr << "Warning(BeamFEMForceField): No object from LengthContainer has been loaded.\n";
00120     }
00121     if (!poissonContainer)
00122     {
00124         std::cerr << "Warning(BeamFEMForceField): No object from PoissonContainer has been loaded.\n";
00125     }
00126     if (!radiusContainer)
00127     {
00129         std::cerr << "Warning(BeamFEMForceField): No object from RadiusContainer has been loaded.\n";
00130     }
00131     
00132     initBeams( n );
00133     for (unsigned int i=0;i<n;++i)
00134         reinitBeam(i);
00135     std::cout << "BeamFEMForceField: init OK, "<<n<<" elements."<<std::endl;
00136 }
00137     
00138 template <class DataTypes>
00139 void BeamFEMForceField<DataTypes>::reinitBeam(unsigned int i)
00140 {
00141     double stiffness, length, radius, poisson;
00142     Index a = (*_indexedElements)[i][0];
00143     Index b = (*_indexedElements)[i][1];
00144     const VecCoord& x0 = *this->mstate->getX0();
00145     std::cout << "Beam "<<i<<" : ("<<a<<' '<<b<<") : beamsData size = "<<beamsData.size()<<" mstate size = "<<this->mstate->getSize()<<" x0 size = "<<x0.size()<<std::endl;
00146         //if (needInit)
00147         if (stiffnessContainer) 
00148             stiffness = stiffnessContainer->getStiffness(i) ;
00149         else stiffness =  _youngModulus.getValue() ;
00150         if (lengthContainer) 
00151             length = lengthContainer->getLength(i) ;
00152         else  length = (x0[a].getCenter()-x0[b].getCenter()).norm() ;
00153         if (radiusContainer) 
00154             radius = radiusContainer->getRadius(i) ;
00155         else  radius = _radius.getValue() ;
00156         if (poissonContainer) 
00157             poisson = poissonContainer->getPoisson(i) ;
00158         else poisson = _poissonRatio.getValue() ;
00159             
00160         std::cout << i << " " << stiffness << " " << length << " " << poisson << " " << radius << std::endl;
00161         setBeam(i, stiffness, length, poisson, radius );
00162         
00163         computeStiffness(i,a,b);
00164         initLarge(i,a,b);
00165 }
00166 
00167 template<class DataTypes>
00168 void BeamFEMForceField<DataTypes>::BeamFEMEdgeCreationFunction(int edgeIndex, void* param, BeamInfo &ei,
00169                                         const topology::Edge& e,  const sofa::helper::vector< unsigned int > &a,
00170                                         const sofa::helper::vector< double >&)
00171 {
00172     std::cout << "Create beam "<<edgeIndex<<" ("<<e<<") from "<<a<<std::endl;
00173     BeamFEMForceField<DataTypes>* p = static_cast<BeamFEMForceField<DataTypes>*>(param);
00174     // p->beamsData.resize(edgeIndex+1);
00175     static_cast<BeamFEMForceField<DataTypes>*>(param)->reinitBeam(edgeIndex);
00176     ei = p->beamsData[edgeIndex];
00177    // p->beamsData.resize(edgeIndex);
00178 }
00179 
00180 template <class DataTypes>
00181 void BeamFEMForceField<DataTypes>::handleTopologyChange()
00182 {
00183     //_beamQuat.resize( _indexedElements->size() );    
00184     
00185     std::list<const sofa::core::componentmodel::topology::TopologyChange *>::const_iterator itBegin=_topology->firstChange();
00186     std::list<const sofa::core::componentmodel::topology::TopologyChange *>::const_iterator itEnd=_topology->lastChange();
00187     
00188     beamsData.handleTopologyEvents(itBegin,itEnd);
00189 }
00190 
00191 template<class DataTypes>
00192 void BeamFEMForceField<DataTypes>::addForce (VecDeriv& f, const VecCoord& p, const VecDeriv& /*v*/)
00193 {
00194     f.resize(p.size());
00195     //_beamQuat.resize( _indexedElements->size() );
00196     
00197     // First compute each node rotation
00198     unsigned int i;
00199     
00200     _nodeRotations.resize(p.size());
00201     //Mat3x3d R; R.identity();
00202     for(i=0; i<p.size(); ++i)
00203     {
00204         //R = R * MatrixFromEulerXYZ(p[i][3], p[i][4], p[i][5]);
00205         //_nodeRotations[i] = R;
00206         p[i].getOrientation().toMatrix(_nodeRotations[i]);
00207     }
00208     
00209     typename VecElement::const_iterator it;
00210     
00211     for(it=_indexedElements->begin(),i=0;it!=_indexedElements->end();++it,++i)
00212     {
00213         Index a = (*it)[0];
00214         Index b = (*it)[1];
00215         
00216         initLarge(i,a,b);
00217         accumulateForceLarge( f, p, i, a, b );
00218     }
00219 
00220 }
00221 
00222 template<class DataTypes>
00223 void BeamFEMForceField<DataTypes>::addDForce (VecDeriv& df, const VecDeriv& dx)
00224 {
00225     df.resize(dx.size());
00226     //if(_assembling) applyStiffnessAssembled(v,x);
00227     //else
00228     {
00229         unsigned int i=0;
00230         typename VecElement::const_iterator it;
00231         
00232         for(it = _indexedElements->begin() ; it != _indexedElements->end() ; ++it, ++i)
00233         {
00234             Index a = (*it)[0];
00235             Index b = (*it)[1];
00236         
00237             applyStiffnessLarge( df, dx, i, a, b );
00238         }
00239     }
00240 }
00241 
00242 template<class DataTypes>
00243 typename BeamFEMForceField<DataTypes>::Real BeamFEMForceField<DataTypes>::peudo_determinant_for_coef ( const Mat<2, 3, Real>&  M )
00244 {
00245     return  M[0][1]*M[1][2] - M[1][1]*M[0][2] -  M[0][0]*M[1][2] + M[1][0]*M[0][2] + M[0][0]*M[1][1] - M[1][0]*M[0][1];
00246 }
00247 
00248 template<class DataTypes>
00249 void BeamFEMForceField<DataTypes>::computeStiffness(int i, Index , Index )
00250 {
00251     Real   phiy, phiz;
00252     Real _L = (Real)beamsData[i]._L;
00253     Real _A = (Real)beamsData[i]._A;
00254     Real _nu = (Real)beamsData[i]._nu;
00255     Real _E = (Real)beamsData[i]._E;
00256     Real _Iy = (Real)beamsData[i]._Iy;
00257     Real _Iz = (Real)beamsData[i]._Iz;
00258     Real _Asy = (Real)beamsData[i]._Asy;
00259     Real _Asz = (Real)beamsData[i]._Asz;
00260     Real _G = (Real)beamsData[i]._G;
00261     Real _J = (Real)beamsData[i]._J;
00262     Real L2 = (Real) (_L * _L);
00263     Real L3 = (Real) (L2 * _L);
00264     Real EIy = (Real)(_E * _Iy);
00265     Real EIz = (Real)(_E * _Iz);
00266     
00267     // Find shear-deformation parameters
00268     if (_Asy == 0)
00269         phiy = 0.0;
00270     else
00271         phiy = (Real)(24.0*(1.0+_nu)*_Iz/(_Asy*L2));
00272     
00273     if (_Asz == 0)
00274         phiz = 0.0;
00275     else
00276         phiz = (Real)(24.0*(1.0+_nu)*_Iy/(_Asz*L2));
00277     
00278     StiffnessMatrix& k_loc = beamsData[i]._k_loc;
00279     
00280     // Define stiffness matrix 'k' in local coordinates
00281     k_loc.clear();
00282     k_loc[6][6]   = k_loc[0][0]   = _E*_A/_L;
00283     k_loc[7][7]   = k_loc[1][1]   = (Real)(12.0*EIz/(L3*(1.0+phiy)));
00284     k_loc[8][8]   = k_loc[2][2]   = (Real)(12.0*EIy/(L3*(1.0+phiz)));
00285     k_loc[9][9]   = k_loc[3][3]   = _G*_J/_L;
00286     k_loc[10][10] = k_loc[4][4]   = (Real)((4.0+phiz)*EIy/(_L*(1.0+phiz)));
00287     k_loc[11][11] = k_loc[5][5]   = (Real)((4.0+phiy)*EIz/(_L*(1.0+phiy)));
00288     
00289     k_loc[4][2]   = (Real)(-6.0*EIy/(L2*(1.0+phiz)));
00290     k_loc[5][1]   = (Real)( 6.0*EIz/(L2*(1.0+phiy)));
00291     k_loc[6][0]   = -k_loc[0][0];
00292     k_loc[7][1]   = -k_loc[1][1];
00293     k_loc[7][5]   = -k_loc[5][1];
00294     k_loc[8][2]   = -k_loc[2][2];
00295     k_loc[8][4]   = -k_loc[4][2];
00296     k_loc[9][3]   = -k_loc[3][3];
00297     k_loc[10][2]  = k_loc[4][2];
00298     k_loc[10][4]  = (Real)((2.0-phiz)*EIy/(_L*(1.0+phiz)));
00299     k_loc[10][8]  = -k_loc[4][2];
00300     k_loc[11][1]  = k_loc[5][1];
00301     k_loc[11][5]  = (Real)((2.0-phiy)*EIz/(_L*(1.0+phiy)));
00302     k_loc[11][7]  = -k_loc[5][1];
00303     
00304     for (int i=0; i<=10; i++) 
00305         for (int j=i+1; j<12; j++)
00306         k_loc[i][j] = k_loc[j][i];
00307 }
00308 
00309 inline Quat qDiff(Quat a, const Quat& b)
00310 {
00311     if (a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]<0)
00312     {
00313         a[0] = -a[0];
00314         a[1] = -a[1];
00315         a[2] = -a[2];
00316         a[3] = -a[3];
00317     }
00318     Quat q = b.inverse() * a;
00319     //std::cout << "qDiff("<<a<<","<<b<<")="<<q<<", bq="<<(b*q)<<std::endl;
00320     return q;
00321 }
00322 
00324 template<class DataTypes>
00325 void BeamFEMForceField<DataTypes>::initLarge(int i, Index a, Index b)
00326 {
00327     const VecCoord& x = *this->mstate->getX();
00328 
00329     Quat quatA, quatB, dQ;
00330     Vec3d dW;
00331 
00332     quatA = x[a].getOrientation();
00333     quatB = x[b].getOrientation();
00334 
00335         
00336 
00337     dQ = qDiff(quatB, quatA);
00338 
00339     dW = dQ.toEulerVector();
00340 
00341     double Theta = dW.norm();
00342 
00343     if(Theta>0.0000001){
00344         dW.normalize();
00345             
00346         beamQuat(i) = quatA*dQ.axisToQuat(dW, Theta/2);
00347                 beamQuat(i).normalize();
00348     }
00349     else
00350         beamQuat(i)= quatA;
00351 
00352 }
00353 
00354 template<class DataTypes>
00355 void BeamFEMForceField<DataTypes>::accumulateForceLarge( VecDeriv& f, const VecCoord & x, int i, Index a, Index b )
00356 {
00357     const VecCoord& x0 = *this->mstate->getX0();
00358 
00359     beamQuat(i)= x[a].getOrientation();
00360     
00361     Vec<3,Real> u, P1P2, P1P2_0;
00362     // local displacement
00363     Displacement depl;
00364 
00365     // translations //
00366     P1P2_0 = x0[b].getCenter() - x0[a].getCenter();
00367     P1P2_0 = x0[a].getOrientation().inverseRotate(P1P2_0);
00368     P1P2 = x[b].getCenter() - x[a].getCenter();
00369     P1P2 = x[a].getOrientation().inverseRotate(P1P2);
00370     u = P1P2 - P1P2_0;
00371     
00372     depl[0] = 0.0;  depl[1] = 0.0;  depl[2] = 0.0;
00373     depl[6] = u[0]; depl[7] = u[1]; depl[8] = u[2];
00374 
00375     // rotations //
00376     Quat dQ0, dQ;
00377 
00378     // dQ = QA.i * QB ou dQ = QB * QA.i() ??
00379     dQ0 = qDiff(x0[b].getOrientation(), x0[a].getOrientation()); // x0[a].getOrientation().inverse() * x0[b].getOrientation();
00380     dQ =  qDiff(x[b].getOrientation(), x[a].getOrientation()); // x[a].getOrientation().inverse() * x[b].getOrientation();
00381     //u = dQ.toEulerVector() - dQ0.toEulerVector();
00382     u = qDiff(dQ,dQ0).toEulerVector(); //dQ.toEulerVector() - dQ0.toEulerVector();
00383 
00384     depl[3] = 0.0;  depl[4] = 0.0;  depl[5] = 0.0;
00385     depl[9] = u[0]; depl[10]= u[1]; depl[11]= u[2];
00386 
00387     // this computation can be optimised: (we know that half of "depl" is null)
00388     Displacement force = beamsData[i]._k_loc * depl;
00389     
00390     
00391     // Apply lambda transpose (we use the rotation value of point a for the beam)
00392     
00393     Vec3d fa1 = x[a].getOrientation().rotate(Vec3d(force[0],force[1],force[2]));
00394     Vec3d fa2 = x[a].getOrientation().rotate(Vec3d(force[3],force[4],force[5]));
00395     
00396     Vec3d fb1 = x[a].getOrientation().rotate(Vec3d(force[6],force[7],force[8]));
00397     Vec3d fb2 = x[a].getOrientation().rotate(Vec3d(force[9],force[10],force[11]));
00398     
00399     
00400     f[a] += Deriv(-fa1,-fa2);
00401     f[b] += Deriv(-fb1,-fb2);
00402 
00403 }
00404 
00405 template<class DataTypes>
00406 void BeamFEMForceField<DataTypes>::applyStiffnessLarge( VecDeriv& df, const VecDeriv& dx, int i, Index a, Index b )
00407 {
00408     //const VecCoord& x = *this->mstate->getX();
00409 
00410     Displacement local_depl;
00411     sofa::defaulttype::Vec<3,Real> u;
00412     const Quat& q = beamQuat(i); //x[a].getOrientation();
00413 
00414     u = q.inverseRotate(dx[a].getVCenter());
00415     local_depl[0] = u[0];
00416     local_depl[1] = u[1];
00417     local_depl[2] = u[2];
00418 
00419     u = q.inverseRotate(dx[a].getVOrientation());
00420     local_depl[3] = u[0];
00421     local_depl[4] = u[1];
00422     local_depl[5] = u[2];
00423     
00424 
00425     u = q.inverseRotate(dx[b].getVCenter());
00426     local_depl[6] = u[0];
00427     local_depl[7] = u[1];
00428     local_depl[8] = u[2];
00429 
00430     u = q.inverseRotate(dx[b].getVOrientation());
00431     local_depl[9] = u[0];
00432     local_depl[10] = u[1];
00433     local_depl[11] = u[2];
00434 
00435     Displacement local_force = beamsData[i]._k_loc * local_depl;
00436 
00437     Vec3d fa1 = q.rotate(Vec3d(local_force[0],local_force[1] ,local_force[2] ));
00438     Vec3d fa2 = q.rotate(Vec3d(local_force[3],local_force[4] ,local_force[5] ));
00439     Vec3d fb1 = q.rotate(Vec3d(local_force[6],local_force[7] ,local_force[8] ));
00440     Vec3d fb2 = q.rotate(Vec3d(local_force[9],local_force[10],local_force[11]));
00441     
00442     df[a] += Deriv(-fa1,-fa2);
00443         df[b] += Deriv(-fb1,-fb2);
00444 }
00445 
00446 template<class DataTypes>
00447 void BeamFEMForceField<DataTypes>::addKToMatrix(sofa::defaulttype::BaseMatrix *mat, SReal k, unsigned int &offset)
00448 {
00449     //const VecCoord& x = *this->mstate->getX();
00450 
00451     unsigned int i=0;
00452     typename VecElement::const_iterator it;
00453     
00454     for(it = _indexedElements->begin() ; it != _indexedElements->end() ; ++it, ++i)
00455     {
00456         Index a = (*it)[0];
00457         Index b = (*it)[1];
00458 
00459         Displacement local_depl;
00460         Vec3d u;
00461         const Quat& q = beamQuat(i); //x[a].getOrientation();
00462         Transformation R,Rt;
00463         q.toMatrix(R);
00464         Rt.transpose(R);
00465         const StiffnessMatrix& K0 = beamsData[i]._k_loc;
00466         StiffnessMatrix K;
00467         for (int x1=0;x1<12;x1+=3)
00468             for (int y1=0;y1<12;y1+=3)
00469             {
00470                 Mat<3,3,Real> m;
00471                 K0.getsub(x1,y1, m);
00472                 m = R*m*Rt;
00473                 K.setsub(x1,y1, m);
00474             }
00475         int index[12];
00476         for (int x1=0;x1<6;x1++)
00477             index[x1] = offset+a*6+x1;
00478         for (int x1=0;x1<6;x1++)
00479             index[6+x1] = offset+b*6+x1;
00480         for (int x1=0;x1<12;++x1)
00481             for (int y1=0;y1<12;++y1)
00482                 mat->add(index[x1], index[y1], - K(x1,y1)*k);
00483     }
00484 }
00485 
00486 template<class DataTypes>
00487 void BeamFEMForceField<DataTypes>::draw()
00488 {
00489     if (!getContext()->getShowForceFields()) return;
00490     if (!this->mstate) return;
00491     
00492     const VecCoord& x = *this->mstate->getX();
00493 
00494     //std::cout <<  _indexedElements->size() << " edges, " << x.size() << " points."<<std::endl;
00495     
00496     glDisable(GL_LIGHTING);
00497     glBegin(GL_LINES);
00498     typename VecElement::const_iterator it;
00499     int i;
00500     for(it = _indexedElements->begin(), i = 0 ; it != _indexedElements->end() ; ++it, ++i)
00501     {
00502         Index a = (*it)[0];
00503         Index b = (*it)[1];
00504         //std::cout << "edge " << i << " : "<<a<<" "<<b<<" = "<<x[a].getCenter()<<"  -  "<<x[b].getCenter()<<" = "<<beamsData[i]._L<<std::endl;
00505         defaulttype::Vec3d p; p = (x[a].getCenter()+x[b].getCenter())*0.5;
00506         Vec3d beamVec;
00507         beamVec[0]=beamsData[i]._L*0.5; beamVec[1] = 0.0; beamVec[2] = 0.0;
00508         
00509         const Quat& q = beamQuat(i);
00510         // axis X
00511         glColor3f(1,0,0);
00512         helper::gl::glVertexT(p - q.rotate(beamVec) );
00513         helper::gl::glVertexT(p + q.rotate(beamVec) );
00514         // axis Y
00515         beamVec[0]=0.0; beamVec[1] = beamsData[i]._L*0.5;
00516         glColor3f(0,1,0);
00517         helper::gl::glVertexT(p); // - R.col(1)*len);
00518         helper::gl::glVertexT(p + q.rotate(beamVec) );
00519         // axis Z
00520         beamVec[1]=0.0; beamVec[2] = beamsData[i]._L*0.5;
00521         glColor3f(0,0,1);
00522         helper::gl::glVertexT(p); // - R.col(2)*len);
00523         helper::gl::glVertexT(p + q.rotate(beamVec) );
00524     }
00525     glEnd();
00526 }
00527 
00528 template<class DataTypes>
00529 void BeamFEMForceField<DataTypes>::initBeams(unsigned int size)
00530 {
00531     beamsData.resize(size);
00532 }
00533 
00534 template<class DataTypes>
00535 void BeamFEMForceField<DataTypes>::setBeam(unsigned int i, double E, double L, double nu, double r)
00536 {
00537     beamsData[i].init(E,L,nu,r);
00538 }
00539 
00540 template<class DataTypes>
00541 void BeamFEMForceField<DataTypes>::BeamInfo::init(double E, double L, double nu, double r)
00542 {
00543     _E = E;
00544     _E0 = E;
00545     _nu = nu;
00546     _L = L;
00547     _r = r;
00548 
00549     _G=_E/(2.0*(1.0+_nu));
00550     _Iz = M_PI*r*r*r*r/4;
00551     _Iy = _Iz ;
00552     _J = _Iz+_Iy;
00553     _A = M_PI*r*r;
00554     
00555     _Asy = 0.0;
00556     _Asz = 0.0;
00557 
00558     //_k_loc.ReSize(12, 12);
00559     //_k_flex.ReSize(12,12);
00560     //_lambda.ReSize(12, 12);
00561     //_u_init.ReSize(12,1);
00562     //_u_actual.ReSize(12,1);
00563     //_f_k.ReSize(12,1);
00564 
00565     //_k_loc=0;
00566     //_u_init=0;
00567 
00568     //_Ke.ReSize(12,12);
00569 
00570     //localStiffness();
00571 }
00572 /*
00573 void BeamInfo::localStiffness()
00574 {
00575     int      i,j;
00576     double   phiy, phiz;
00577     double   L2 = _L * _L;
00578     double   L3 = L2 * _L;
00579     double   EIy = _E * _Iy;
00580     double   EIz = _E * _Iz;
00581 
00582     // Find shear-deformation parameters
00583     if (_Asy == 0)
00584         phiy = 0.0;
00585     else
00586         phiy = 24.0*(1.0+_nu)*_Iz/(_Asy*L2);
00587 
00588     if (_Asz == 0)
00589         phiz = 0.0;
00590     else
00591         phiz = 24.0*(1.0+_nu)*_Iy/(_Asz*L2);
00592 
00593 
00594     // Define stiffness matrix 'k' in local coordinates
00595     Try {
00596         _k_loc = 0;
00597         _k_loc(1,1)   = _E*_A/_L;
00598         _k_loc(2,2)   = 12.0*EIz/(L3*(1.0+phiy));
00599         _k_loc(3,3)   = 12.0*EIy/(L3*(1.0+phiz));
00600         _k_loc(4,4)   = _G*_J/_L;
00601         _k_loc(5,5)   = (4.0+phiz)*EIy/(_L*(1.0+phiz));
00602         _k_loc(6,6)   = (4.0+phiy)*EIz/(_L*(1.0+phiy));
00603         _k_loc(7,7)   = _k_loc(1,1);
00604         _k_loc(8,8)   = _k_loc(2,2);
00605         _k_loc(9,9)   = _k_loc(3,3);
00606         _k_loc(10,10) = _k_loc(4,4);
00607         _k_loc(11,11) = _k_loc(5,5);
00608         _k_loc(12,12) = _k_loc(6,6);
00609 
00610         _k_loc(5,3)   = -6.0*EIy/(L2*(1.0+phiz));
00611         _k_loc(6,2)   =  6.0*EIz/(L2*(1.0+phiy));
00612         _k_loc(7,1)   = -_k_loc(1,1);
00613         _k_loc(8,2)   = -_k_loc(2,2);
00614         _k_loc(8,6)   = -_k_loc(6,2);
00615         _k_loc(9,3)   = -_k_loc(3,3);
00616         _k_loc(9,5)   = -_k_loc(5,3);
00617         _k_loc(10,4)  = -_k_loc(4,4);
00618         _k_loc(11,3)  = _k_loc(5,3);
00619         _k_loc(11,5)  = (2.0-phiz)*EIy/(_L*(1.0+phiz));
00620         _k_loc(11,9)  = -_k_loc(5,3);
00621         _k_loc(12,2)  = _k_loc(6,2);
00622         _k_loc(12,6)  = (2.0-phiy)*EIz/(_L*(1.0+phiy));
00623         _k_loc(12,8)  = -_k_loc(6,2);
00624 
00625         for (i=1; i<=11; i++)
00626             for (j=i+1; j<=12; j++)
00627                 _k_loc(i,j) = _k_loc(j,i);
00628 
00629         _k_flex = _k_loc;
00630 
00631 //      for (i=1; i<=12; i++)
00632 //          _k_flex(i,i) = FLEXIBILITY * _k_flex(i,i);
00633 
00634     }
00635     CatchAll { cout << "ERROR while computing '_k_loc'" << NewMAT::Exception::what() << endl;
00636     }
00637 }
00638 */
00639 /*
00640 template<class DataTypes>
00641 void BeamFEMForceField<DataTypes>::computeUinit(unsigned int i, Vec3d &P1, Vec3d &P2, Vec3d &LoX1, Vec3d &LoY1, Vec3d &LoZ1, Vec3d &LoX2, Vec3d &LoY2, Vec3d &LoZ2)
00642 {
00643     beamsData[i].computeUinit(P1, P2, LoX1, LoY1, LoZ1, LoX2, LoY2, LoZ2);
00644 }
00645 
00646 void BeamInfo::computeUinit(Vec3d &P1, Vec3d &P2, Vec3d &LoX1, Vec3d &LoY1, Vec3d &LoZ1, Vec3d &LoX2, Vec3d &LoY2, Vec3d &LoZ2)
00647 {
00648     Vec3d        p2; //position of point2 in local frame (LoX1,LoY1,LoZ1);
00649     Vec3d      P1P2, p1p2, p1p2_init, u_init;
00650     Vec3d      LoX1_loc, LoY1_loc, LoZ1_loc, LoX2_loc, LoY2_loc, LoZ2_loc;
00651     sofa::defaulttype::Mat3x3d    R1;
00652     NewMAT::ColumnVector Finit(9);
00653     NewMAT::ColumnVector Uinit(9);
00654     NewMAT::Matrix K(9,9);
00655 
00656     Finit=0; Uinit=0; K=0;
00657 
00658     LoX1_loc = Vec3d(1.0,0.0,0.0);
00659     LoY1_loc = Vec3d(0.0,1.0,0.0);
00660     LoZ1_loc = Vec3d(0.0,0.0,1.0);
00661 
00662     Try{
00663         K.SubMatrix(1,6,1,6) = _k_loc.SubMatrix(7,12,7,12);
00664     }
00665     CatchAll {
00666         cout << "ERROR while computing 'K' in ComputeUinit" << NewMAT::Exception::what() << endl;
00667     }
00668 
00669     P1P2 = P2 - P1;
00670     p1p2_init = Vec3d(_L,0.0,0.0); //the beam is aligned along LoX1 if there is no initial deformation
00671 
00672     R1[0] = LoX1;
00673     R1[1] = LoY1;
00674     R1[2] = LoZ1;
00675 
00676     p1p2 = R1*P1P2;
00677     
00678     u_init = p1p2 - p1p2_init;
00679 
00680     // add lagrange multipliers:
00681     K(7,1) = 1.0; K(1,7) = 1.0;
00682     K(8,2) = 1.0; K(2,8) = 1.0;
00683     K(9,3) = 1.0; K(3,9) = 1.0;
00684 
00685     //_u_init must respect displacements
00686     Finit(7) = u_init[0];
00687     Finit(8) = u_init[1];
00688     Finit(9) = u_init[2];
00689 
00690     Try
00691     {
00692         Uinit = K.i() *  Finit;
00693     }
00694     CatchAll
00695     {   
00696         cout << "ERROR while computing 'Uinit = K.i() * Finit' in ComputeUinit" << NewMAT::Exception::what() << endl;
00697     }
00698     _u_init=0.0;
00699     _u_init.SubMatrix(7,12,1,1) = Uinit.SubMatrix(1,6,1,1);
00700     Vec3d vtemp = Vec3d(Uinit(4), Uinit(5), Uinit(6));
00701     
00702     if (vtemp == Vec3d(0.0,0.0,0.0))
00703         vtemp = Vec3d(0.0,0.0,1.0);
00704     
00705     Quaternion q(vtemp, vtemp.norm());
00706     vtemp.normalize();
00707 
00708     LoX2_loc = q.rotate(LoX1_loc);
00709     LoY2_loc = q.rotate(LoY1_loc);
00710     LoZ2_loc = q.rotate(LoZ1_loc);
00711 
00712     LoX2 = LoX1 * LoX2_loc[0] + LoY1 * LoX2_loc[1] + LoZ1 * LoX2_loc[2] ;
00713     LoY2 = LoX1 * LoY2_loc[0] + LoY1 * LoY2_loc[1] + LoZ1 * LoY2_loc[2] ;
00714     LoZ2 = LoX1 * LoZ2_loc[0] + LoY1 * LoZ2_loc[1] + LoZ1 * LoZ2_loc[2] ;
00715 
00716     _u_actual = _u_init;
00717 }
00718 */
00719 } // namespace forcefield
00720 
00721 } // namespace component
00722 
00723 } // namespace sofa
00724 
00725 #endif

Generated on Sun Nov 23 02:51:37 2008 for Sofa by  doxygen 1.5.7.1