Documentation


massspringsolver.inl

Go to the documentation of this file.
00001 /***************************************************************************
00002                           massspringsolver.inl  -  description
00003                              -------------------
00004     begin                : Thu Nov 27 2003
00005     copyright            : (C) 2003 by François Faure, GRAVIR
00006     email                : Francois.Faure@imag.fr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "massspringsolver.h"
00019 #include <animal/physicalSolver.inl>
00020 #include <animal/odeImplicitSolver.inl>
00021 #include<iostream>
00022 using std::cerr; using std::endl;
00023 
00024 namespace animal {
00025 
00026 template<class P, class V, class Im, class R, class I>
00027 typename MassSpringSolver<P,V,Im,R,I>::Real MassSpringSolver<P,V,Im,R,I>::_thresholdDistance=1.e-12;
00028 
00029 template<class P, class V, class Im, class R, class I>
00030 bool MassSpringSolver<P,V,Im,R,I>::_debug=false;
00031 
00032 
00033 template<class P, class V, class Im, class R, class I>
00034 MassSpringSolver<P,V,Im,R,I>::MassSpringSolver()
00035     : _links(0)
00036     , _stiffnesses(0)
00037     , _restLengths(0)
00038     , _own_restLengths(false)
00039     , _isotropy(0.03)
00040 {
00041 //  cerr<<"MassSpringSolver<P,V,Im,R,I>::MassSpringSolver()"<<endl;
00042 }
00043 
00044 template<class P,class V,class Im,class R,class I>
00045 void MassSpringSolver<P,V,Im,R,I>::solveODE(
00046     Positions& pos,
00047     Vector& vel,
00048     Real dt
00049 )
00050 {
00051   //cerr<<"MassSpringSolver<P,V,Im,R,I>::solveODE "<< endl;
00052     _OdeImplicitSolver::solveODE(pos,vel,dt);
00053     this->applyExponentialDamping(vel,dt);
00054 }
00055 
00056 
00057 template<class P, class V, class Im, class R, class I>
00058 MassSpringSolver<P,V,Im,R,I>::~MassSpringSolver()
00059 {
00060     if( _own_restLengths ) delete _restLengths;
00061 }
00062 
00063 
00064 
00065 
00066 
00068 template<class P, class V, class Im, class R, class I>
00069 void MassSpringSolver<P,V,Im,R,I>::setMethod( int m ){
00070     this->_OdeImplicitSolver::setMethod(m);
00071 }
00073 template<class P, class V, class Im, class R, class I>
00074 int MassSpringSolver<P,V,Im,R,I>::getMethod() const {
00075     return this->_OdeImplicitSolver::method();
00076 }
00078 template<class P, class V, class Im, class R, class I>
00079 void MassSpringSolver<P,V,Im,R,I>::setIsotropy( Real isot ){
00080     this->_isotropy = isot;
00081 }
00083 template<class P, class V, class Im, class R, class I>
00084 typename MassSpringSolver<P,V,Im,R,I>::Real MassSpringSolver<P,V,Im,R,I>::getIsotropy() const {
00085     return this->_isotropy;
00086 }
00088 template<class P, class V, class Im, class R, class I>
00089 const typename MassSpringSolver<P,V,Im,R,I>::Real& MassSpringSolver<P,V,Im,R,I>::get_common_damping_ratio(){
00090     return this->_dampingRatio;
00091 }
00093 template<class P, class V, class Im, class R, class I>
00094 void MassSpringSolver<P,V,Im,R,I>::set_common_damping_ratio( const Real& _newVal){
00095     this->_dampingRatio = _newVal;
00096 }
00097 
00099 template<class P, class V, class Im, class R, class I>
00100 void MassSpringSolver<P,V,Im,R,I>::set_spring_indices( VecIndex* newVal){ _links=newVal; }
00101 
00103 template<class P, class V, class Im, class R, class I>
00104 void MassSpringSolver<P,V,Im,R,I>::set_stiffnesses( VecReal* newVal){ _stiffnesses = newVal; }
00105 
00107 //template<class P, class V, class Im, class R, class I>
00108 //void MassSpringSolver<P,V,Im,R,I>::set_rest_lengths( R* r )
00109 //{
00110 //  assert( size(*_links)%2==size(*r) );
00111 //  this->_restLengths = r;
00112 //  _own_restLengths = false;
00113 //}
00114 
00115 //  /** Set the rest lengths of the springs according to the current particle positions. */
00116 //template<class P, class V, class Im, class R, class I>
00117 //void MassSpringSolver<P,V,Im,R,I>::create_rest_lengths( const Positions& p )
00118 //{
00119 //  assert(false);
00120 //  assert( size(*_links)%2==0 );
00121 //  if(!_restLengths) _restLengths = new VecReal;
00122 //  _own_restLengths = true;
00123 //  for( unsigned int i=0; i<_links->size(); i+=2 )
00124 //  {
00125 //    Position x =  p[(*_links)[i]];
00126 //    cerr<<"p0 = " << x <<", p1 = "<< p[(*_links)[i+1]]
00127 //    << endl;
00128 //    v_meq( x, p[(*_links)[i+1]] );   // x==p[a]-p[b]
00129 //    _restLengths->push_back( v_norm( x ) );
00130 //  }
00131 //  cerr<<"MassSpringSolver<P,V,Im,R,I>::create_rest_lengths: "
00132 //  << *_restLengths
00133 //  << endl;
00134 //}
00135 
00136 
00138 template<class P, class V, class Im, class R, class I>
00139 void MassSpringSolver<P,V,Im,R,I>::accumulateSpringForce(Vec& fa, Vec& fb,
00140     const Vec& pa, const Vec& pb,
00141     const Vec& va, const Vec& vb,
00142     const Real& stiffness, const Real& dampingRatio, const Real& restLength)
00143 {
00144    Real distance;
00145    Vec direction;
00146    if( computeDistanceAndDirection(distance, direction, pa, pb ) )
00147    {
00148    Real elongation = distance-restLength;
00149          Vec relativeVelocity = vb;
00150          v_meq(relativeVelocity,va);
00151          Real elongationVelocity = v_dot(direction,relativeVelocity);
00152          Vec f = direction;
00153          v_teq( f, stiffness*(elongation + dampingRatio*elongationVelocity) );
00154          v_peq( fa, f );
00155          v_meq( fb, f );
00156 //   cerr <<"MassSpringSolver<P,V,Im,R,I>::accumulateSpringForce" << endl
00157         if (_debug){
00158         cerr << ", point " << pa <<", force += "<< fa << endl   
00159             << ", point " << pb <<", force -= "<< fb << endl
00160             << ", distance = " << distance <<", elongation = "<< elongation <<endl
00161             << ", direction = " << direction << endl
00162         << endl;
00163         }
00164    }
00165 }
00166 
00168 template<class P, class Vec, class Im, class Real, class I>
00169 void MassSpringSolver<P,Vec,Im,Real,I>::accumulateSpringForceAndGradientMatrix
00170     ( Vec& fa, Vec& fb, Vec& grad,
00171     const Vec& pa, const Vec& pb,
00172     const Vec& va, const Vec& vb,
00173     const Real& stiffness, const Real& dampingRatio, const Real& restLength)
00174 {
00175    Real distance;
00176    Vec direction;
00177    if( computeDistanceAndDirection(distance, direction, pa, pb) )
00178    {
00179      grad = direction;
00180          Real elongation = distance-restLength;
00181          Vec relativeVelocity = vb;
00182          v_meq(relativeVelocity,va);
00183          Real elongationVelocity = v_dot(direction,relativeVelocity);
00184          Vec f = direction;
00185          v_teq( f, stiffness*(elongation + dampingRatio*elongationVelocity) );
00186          //cerr<<"MassSpringSolver<P,V,Im,R,I>::accumulateSpringForceAndGradientMatrix, f= "<< f << endl;
00187          v_peq( fa, f );
00188          v_meq( fb, f );
00189    }
00190 }
00191 
00194 template<class P, class V, class Im, class R, class I>
00195 bool MassSpringSolver<P,V,Im,R,I>::computeDistanceAndDirection(Real& d, Vec& u,
00196 const Vec& pa, const Vec& pb){
00197     u = pb-pa;
00198     d = v_norm(u);
00199     //cerr << "massSpringSolver::_thresholdDistance " << _thresholdDistance << endl;
00200     if( d<get_thresholdDistance() ) return false;
00201     v_teq( u, 1/d);
00202     return true;
00203 }
00204 
00206 template<class P, class V, class Im, class R, class I>
00207 void MassSpringSolver<P,V,Im,R,I>::computeForces( Vector& f, const Positions& p, const Vector& v)
00208 {
00209     _PhysicalSolver::computeForces(f,p,v);
00210     // f==0
00211   assert( size(*_links)%2 ==0);
00212     for( unsigned int i=0; i<_links->size(); i+=2 )
00213     {
00214     Index& a = (*_links)[i  ];
00215     Index& b = (*_links)[i+1];
00216         if (_debug){
00217             cerr << "index du point a= " << a << endl
00218             << "index du point b= " << b << endl;
00219         }
00220         accumulateSpringForce( f[a], f[b], p[a], p[b], v[a], v[b], (*_stiffnesses)[i/2], _dampingRatio, (*_restLengths)[i/2] );
00221     }
00222    //cerr << "MassSpringSolver<P,V,Im,R,I>::computeForces: " << f << endl;
00223 }
00224 
00226 template<class P, class V, class Im, class R, class I>
00227 void MassSpringSolver<P,V,Im,R,I>::computeAccelerations( Vector& a, const Positions& p, const Vector& v)
00228 {
00229     _PhysicalSolver::computeAccelerations(a,p,v);
00230     //cerr<<"MassSpringSolver<P,V,Im,R,I>::computeAccelerations: "<< a << endl;
00231 }
00232 
00234 template<class P, class V, class Im, class R, class I>
00235 void MassSpringSolver<P,V,Im,R,I>::computeAccelerationsAndStiffness( Vector& f, const Positions& p, const Vector& v)
00236 {
00237       //typedef container_traits<Vector>::value_type VectorEntry;
00238     _PhysicalSolver::computeForces(f,p,v);
00239     // f==0
00240   assert( size(*_links)%2 ==0);
00241   assert( size(*_stiffnesses)==size(*_links)/2 );
00242   assert( size(*_restLengths)==size(*_links)/2 );
00243   assert( size(p)==size(f) );
00244   assert( size(v)==size(f) );
00245   //cerr<<"computeAccelerationsAndGradient, size(p)== "<<size(p)<<endl;
00246   //cerr<<"computeAccelerationsAndGradient, restLengths== "<<*_restLengths<<endl;
00247   _directions.resize( size(*_links)/2 );
00248     for( unsigned int i=0; i<_links->size(); i+=2 )
00249     {
00250     Index& a = (*_links)[i  ];
00251     Index& b = (*_links)[i+1];
00252         accumulateSpringForceAndGradientMatrix(
00253             f[a],
00254             f[b],
00255             _directions[i/2],
00256             p[a],
00257             p[b],
00258             v[a],
00259             v[b],
00260             (*_stiffnesses)[i/2],
00261             _dampingRatio,
00262             (*_restLengths)[i/2] );
00263     }
00264   //cerr<<"computeAccelerationsAndGradient, f== "<<f<<endl;
00265 
00266   this->applyForces(f,f);
00267   // f==f/m
00268 
00269   this->applyGravity(f);
00270   // f== g + f/m
00271 
00272     //cerr<<"MassSpringSolver<P,V,Im,R,I>::computeAccelerationsAndGradient, a= "<< f << endl;
00273 
00274 }
00275 
00276 //  /** Compute the force applied to the particles and update the gradient matrix.
00277 //  \param f force vector
00278 //  \param p current positions
00279 //  \param v current velocities
00280 //  */
00281 //template<class Positions, class Vector, class Im, class R, class I>
00282 //  void MassSpringSolver<Positions,Vector,Im,R,I>
00283 //  ::computeForce( Vector& f, const Positions& p, const Vector& v )
00284 //  {
00285 //      //typedef container_traits<Vector>::value_type VectorEntry;
00286 //  _PhysicalSolver::computeForces(f,p,v);
00287 //  // f==0
00288 //  assert( size(*_links)%2 ==0);
00289 //  assert( size(*_stiffnesses)==size(*_links)/2 );
00290 //  assert( size(*_restLengths)==size(*_links)/2 );
00291 //  assert( size(p)==size(f) );
00292 //  assert( size(v)==size(f) );
00293 //  cerr<<"::computeForce, size(p)== "<<size(p)<<endl;
00294 //  cerr<<"::computeForce, restLengths== "<<*_restLengths<<endl;
00295 //  _directions.resize( size(*_links)/2 );
00296 //  for( unsigned int i=0; i<_links->size(); i+=2 )
00297 //  {
00298 //    Index& a = (*_links)[i  ];
00299 //    Index& b = (*_links)[i+1];
00300 //      accumulateSpringForceAndGradientMatrix(
00301 //          f[a],
00302 //          f[b],
00303 //          _directions[i/2],
00304 //          p[a],
00305 //          p[b],
00306 //          v[a],
00307 //          v[b],
00308 //          (*_stiffnesses)[i/2],
00309 //          _dampingRatio,
00310 //          (*_restLengths)[i/2] );
00311 //  }
00312 //  cerr<<"::computeForce, f== "<<f<<endl;
00313 //
00314 //  }
00315 
00320 template<class Positions, class Vector, class Im, class R, class I>
00321     void MassSpringSolver<Positions,Vector,Im,R,I>
00322 	::applyForces( Vector& a, const Vector& f)
00323     {
00324     this->_PhysicalSolver::applyForces(a,f);
00325     }
00326 
00327     /* old stuff
00328 template<class Positions, class Vector, class Im, class Real, class I>
00329     void MassSpringSolver<Positions,Vector,Im,Real,I>
00330     ::v_eq_h_dfdx_x( Vector& v, Real h, const Vector& x )
00331     {
00332      assert( size(v)==size(x) );
00333 
00334      v_assign( v, Value<Vec>::zero() );
00335      // v==0
00336      assert( size(_directions)==size(*_links)/2);
00337      assert( size(*_stiffnesses)==size(*_links)/2);
00338      //cerr<<"::v_eq_h_dfdx_x, directions= "<< _directions << endl;
00339 
00340          for( unsigned int i=0, iend=size(_directions); i!=iend; ++i )
00341          {
00342               Real u; Vec p;
00343               Real hh = -h * (*_stiffnesses)[i];
00344 
00345         // first endpoint
00346               u = v_dot(_directions[i],x[ (*_links)[i/2] ]);
00347               v_eq_ab( p, hh*u, _directions[i] );
00348               v_peq( v[ (*_links)[i/2  ] ], p );
00349               v_meq( v[ (*_links)[i/2+1] ], p );
00350 
00351         // second endpoint
00352         u = v_dot(_directions[i],x[i/2+1]);
00353               v_eq_ab( p, hh*u, _directions[i] );
00354               v_peq( v[ (*_links)[i/2+1] ], p );
00355               v_meq( v[ (*_links)[i/2  ] ], p );
00356          }
00357     }
00358 
00359 template<class Positions, class Vector, class Im, class Real, class I>
00360     void MassSpringSolver<Positions,Vector,Im,Real,I>
00361     ::v_peq_h_dfdx_x( Vector& v, Real h, const Vector& x )
00362     {
00363      assert( size(v)==size(x) );
00364      assert( size((*_stiffnesses))==size(_directions) );
00365      assert( size(_directions)==size(*_links)/2 );
00366 
00367          for( unsigned int i=0, iend=size(_directions); i!=iend; ++i )
00368          {
00369               Real u; Vec p;
00370             Real hh = -h * (*_stiffnesses)[i];
00371 
00372         // first endpoint
00373               u = v_dot(_directions[i],x[ (*_links)[i/2] ]);
00374               v_eq_ab( p, hh*u, _directions[i] );
00375               v_peq( v[ (*_links)[i/2  ] ], p );
00376               v_meq( v[ (*_links)[i/2+1] ], p );
00377 
00378         // second endpoint
00379         u = v_dot(_directions[i],x[ (*_links)[i/2+1] ]);
00380               v_eq_ab( p, hh*u, _directions[i] );
00381               v_peq( v[ (*_links)[i/2+1] ], p );
00382               v_meq( v[ (*_links)[i/2  ] ], p );
00383          }
00384 
00385     }
00386 old stuff */
00387 
00388 
00394 template<class Positions, class Vector, class Im, class Real, class I>
00395     void MassSpringSolver<Positions,Vector,Im,Real,I>
00396 	::v_eq_h_dfdx_x( Vector& v, Real h, const Vector& x )
00397     {
00398         v_assign( v, Value<Vec>::zero() );
00399         v_peq_h_dfdx_x(v,h,x);
00400     }
00401 
00408 template<class Positions, class Vector, class Im, class Real, class I>
00409     void MassSpringSolver<Positions,Vector,Im,Real,I>
00410 	::v_peq_h_dfdx_x( Vector& v, Real h, const Vector& x )
00411     {
00412      assert( size(v)==size(x) );
00413      assert( size((*_stiffnesses))==size(_directions) );
00414      assert( size(_directions)==size(*_links)/2 );
00415      //cerr<<"MassSpringSolver:v_peq_h_dfdx_x, links= "<< *_links << endl;
00416 
00417          for( unsigned int i=0, iend=size(_directions); i!=iend; ++i )
00418          {
00419             Real u; Vec p, piso;
00420             Real hk = -h * (*_stiffnesses)[i];
00421             Real hiso = _isotropy * hk;
00422             Real hh = hk -  hiso;
00423             std::size_t i1=(*_links)[i*2], i2=(*_links)[(i*2)+1];
00424             //cerr<<"MassSpringSolver:v_peq_h_dfdx_x, i1= "<< i1<<", i2= "<< i2 << endl;
00425 
00426             // === first endpoint
00427             // anisotropic part
00428             u = v_dot(_directions[i],x[i1]);
00429             v_eq_ab( p, hh*u, _directions[i] );
00430             v_peq( v[i1], p );
00431             v_meq( v[i2], p );
00432             // isotropic part
00433             v_eq_ab( piso, hiso, x[i1] );
00434             v_peq( v[i1], piso );
00435             v_meq( v[i2], piso );
00436 
00437             // === second endpoint
00438             // anisotropic part
00439             u = v_dot(_directions[i],x[i2]);
00440             v_eq_ab( p, hh*u, _directions[i] );
00441             v_peq( v[i2], p );
00442             v_meq( v[i1], p );
00443             // isotropic part
00444             v_eq_ab( piso, hiso, x[i2] );
00445             v_peq( v[i2], piso );
00446             v_meq( v[i1], piso );
00447          }
00448 
00449     }
00450 
00451 }//animal

Generated on Thu Dec 23 13:52:26 2004 by doxygen 1.3.6