UncoupledConstraintCorrection.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_CONSTRAINT_UNCOUPLEDCONSTRAINTCORRECTION_INL
00026 #define SOFA_COMPONENT_CONSTRAINT_UNCOUPLEDCONSTRAINTCORRECTION_INL
00027 
00028 #include "UncoupledConstraintCorrection.h"
00029 #include <sofa/defaulttype/RigidTypes.h>
00030 #include <sofa/simulation/tree/GNode.h>
00031 #include <sofa/component/mass/UniformMass.h>
00032 #include <sofa/simulation/common/MechanicalVisitor.h>
00033 
00034 namespace sofa
00035 {
00036 
00037 namespace component
00038 {
00039 
00040 namespace constraint
00041 {
00042 
00043 template<class DataTypes>
00044 UncoupledConstraintCorrection<DataTypes>::UncoupledConstraintCorrection(behavior::MechanicalState<DataTypes> *mm)
00045 : mstate(mm)
00046 {
00047 }
00048 
00049 template<class DataTypes>
00050 UncoupledConstraintCorrection<DataTypes>::~UncoupledConstraintCorrection()
00051 {
00052 }
00053 
00054 template<class DataTypes>
00055 void UncoupledConstraintCorrection<DataTypes>::init()
00056 {
00057     mstate = dynamic_cast< behavior::MechanicalState<DataTypes>* >(getContext()->getMechanicalState());
00058 }
00059 
00060 #ifndef SOFA_FLOAT
00061 template<>
00062     void UncoupledConstraintCorrection<defaulttype::Rigid3Types>::getCompliance(defaulttype::BaseMatrix*W)
00063 {
00064   const VecConst& constraints = *mstate->getC();
00065   Deriv weighedNormal;
00066   Deriv InvM_wN;
00067 
00068   const sofa::defaulttype::Rigid3Mass* massValue;
00069 
00070   simulation::tree::GNode *node = dynamic_cast<simulation::tree::GNode *>(getContext());
00071 
00072   if (node != NULL)
00073   {
00074     core::componentmodel::behavior::BaseMass*_m = node->mass;
00075     component::mass::UniformMass<defaulttype::Rigid3Types, defaulttype::Rigid3Mass> *m = dynamic_cast<component::mass::UniformMass<defaulttype::Rigid3Types, defaulttype::Rigid3Mass>*> (_m);
00076     massValue = &( m->getMass());
00077   }
00078   else
00079   {
00080     massValue = new sofa::defaulttype::Rigid3Mass();
00081     printf("\n WARNING : node is not found => massValue could be false in getCompliance function");
00082   }
00083 
00084   unsigned int numConstraints = constraints.size();
00085 
00086   double dt = this->getContext()->getDt();
00087 
00088   for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
00089   {
00090     int sizeCurRowConst = constraints[curRowConst].size();
00091     int indexCurRowConst = mstate->getConstraintId()[curRowConst];
00092 
00093     for(int i = 0; i < sizeCurRowConst; i++)
00094     {
00095       weighedNormal.getVCenter() = constraints[curRowConst][i].data.getVCenter(); // weighed normal
00096       weighedNormal.getVOrientation() = constraints[curRowConst][i].data.getVOrientation();
00097 
00098       InvM_wN = weighedNormal / (*massValue);
00099       InvM_wN *= dt*dt;
00100         
00101       int indexCurColConst;
00102 
00103       for(unsigned int curColConst = curRowConst; curColConst < numConstraints; curColConst++)
00104       {
00105     int sizeCurColConst = constraints[curColConst].size();
00106     indexCurColConst = mstate->getConstraintId()[curColConst];
00107 
00108     for(int j = 0; j < sizeCurColConst; j++)
00109     {
00110                     //W[indexCurRowConst][indexCurColConst] +=  constraints[curColConst][j].data * InvM_wN;
00111       double w =  constraints[curColConst][j].data * InvM_wN;
00112       W->add(indexCurRowConst, indexCurColConst, w);
00113       if (indexCurRowConst != indexCurColConst)
00114         W->add(indexCurColConst, indexCurRowConst, w);
00115     }
00116       }
00117 /*
00118       for(unsigned int curColConst = curRowConst+1; curColConst < numConstraints; curColConst++)
00119       {
00120       indexCurColConst = mstate->getConstraintId()[curColConst];
00121       W[indexCurColConst][indexCurRowConst] = W[indexCurRowConst][indexCurColConst];
00122     }
00123 */
00124     }
00125   }
00126 }
00127 
00128 template<>
00129     void UncoupledConstraintCorrection<defaulttype::Rigid3Types>::applyContactForce(const defaulttype::BaseVector *f)
00130 {
00131   VecDeriv& force = *mstate->getExternalForces();
00132   const VecConst& constraints = *mstate->getC();
00133   Deriv weighedNormal;
00134 
00135   const sofa::defaulttype::Rigid3Mass* massValue;
00136 
00137   simulation::tree::GNode *node = dynamic_cast<simulation::tree::GNode *>(getContext());
00138 
00139   if (node != NULL)
00140   {
00141     core::componentmodel::behavior::BaseMass*_m = node->mass;
00142     component::mass::UniformMass<defaulttype::Rigid3Types, defaulttype::Rigid3Mass> *m = dynamic_cast<component::mass::UniformMass<defaulttype::Rigid3Types, defaulttype::Rigid3Mass>*> (_m);
00143     massValue = &( m->getMass());
00144   }
00145   else
00146   {
00147     massValue = new sofa::defaulttype::Rigid3Mass();
00148     printf("\n WARNING : node is not found => massValue could be false in getCompliance function");
00149   }
00150 
00151 
00152   double dt = this->getContext()->getDt();
00153 
00154   force.resize(0);
00155   force.resize(1);
00156   force[0] = Deriv();
00157 
00158   int numConstraints = constraints.size();
00159 
00160   for(int c1 = 0; c1 < numConstraints; c1++)
00161   {
00162     int indexC1 = mstate->getConstraintId()[c1];
00163     double fC1 = f->element(indexC1);
00164 
00165     if (fC1 != 0.0)
00166     {
00167       int sizeC1 = constraints[c1].size();
00168       for(int i = 0; i < sizeC1; i++)
00169       { 
00170     weighedNormal = constraints[c1][i].data; // weighted normal
00171     force[0].getVCenter() += weighedNormal.getVCenter() * fC1;
00172     force[0].getVOrientation() += weighedNormal.getVOrientation() * fC1;
00173       }
00174     }
00175   }
00176 
00177 
00178   VecDeriv& dx = *mstate->getDx();
00179   VecCoord& x = *mstate->getX();
00180   VecDeriv& v = *mstate->getV();
00181   VecDeriv& v_free = *mstate->getVfree();
00182   VecCoord& x_free = *mstate->getXfree();
00183 
00184 
00185 //  mstate->setX(x_free);
00186 //  mstate->setV(v_free);
00187   x[0]=x_free[0];
00188   v[0]=v_free[0];
00189 
00190     // Euler integration... will be done in the "integrator" as soon as it exists !
00191   dx.resize(v.size());
00192   dx[0] = force[0] / (*massValue);
00193   dx[0] *= dt;
00194   v[0] += dx[0];
00195   dx[0] *= dt;
00196   x[0] += dx[0];
00197 //  simulation::tree::MechanicalPropagateAndAddDxVisitor(dx).execute(this->getContext());
00198 
00199 }
00200 
00201 template<>
00202     void UncoupledConstraintCorrection<defaulttype::Vec1dTypes>::getCompliance(defaulttype::BaseMatrix *W)
00203 {
00204   const VecConst& constraints = *mstate->getC();
00205   unsigned int numConstraints = constraints.size();
00206 
00207   for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
00208   {
00209     int sizeCurRowConst = constraints[curRowConst].size();
00210     int indexCurRowConst = mstate->getConstraintId()[curRowConst];
00211 
00212     for(int i = 0; i < sizeCurRowConst; i++)
00213     {
00214       int indexCurColConst;
00215 
00216       for(unsigned int curColConst = curRowConst; curColConst < numConstraints; curColConst++)
00217       {
00218     int sizeCurColConst = constraints[curColConst].size();
00219     indexCurColConst = mstate->getConstraintId()[curColConst];
00220 
00221     for(int j = 0; j < sizeCurColConst; j++)
00222     {
00223       if (constraints[curRowConst][i].index == constraints[curColConst][j].index)
00224       {
00225                         //W[indexCurRowConst][indexCurColConst] += (1.0/10000.0) * constraints[curRowConst][i].data.x() * constraints[curColConst][j].data.x();
00226         double w = (1.0/10000.0) * constraints[curRowConst][i].data.x() * constraints[curColConst][j].data.x();
00227         W->add(indexCurRowConst, indexCurColConst, w);
00228         if (indexCurRowConst != indexCurColConst)
00229           W->add(indexCurColConst, indexCurRowConst, w);
00230       }
00231     }
00232       }
00233 /*
00234       for(unsigned int curColConst = curRowConst+1; curColConst < numConstraints; curColConst++)
00235       {
00236       indexCurColConst = mstate->getConstraintId()[curColConst];
00237       W[indexCurColConst][indexCurRowConst] = W[indexCurRowConst][indexCurColConst];
00238     }
00239 */
00240     }
00241   }
00242 
00243 // debug : verifie qu'il n'y a pas de 0 sur la diagonale de W
00244     //printf("\n index : ");
00245     //for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
00246     //{
00247     //  int indexCurRowConst = mstate->getConstraintId()[curRowConst];
00248     //  printf(" %d ",indexCurRowConst);
00249     //  if(abs(W[indexCurRowConst][indexCurRowConst]) < 0.000000001)
00250     //      printf("\n WARNING : there is a 0 on the diagonal of matrix W");
00251 
00252     //  if(abs(W[curRowConst][curRowConst]) <0.000000001)
00253     //      printf("\n stop");
00254     //}
00255 
00256 
00257 }
00258 
00259 template<>
00260     void UncoupledConstraintCorrection<defaulttype::Vec1dTypes>::applyContactForce(const defaulttype::BaseVector *f){
00261 
00262   VecDeriv& force = *mstate->getExternalForces();
00263   const VecConst& constraints = *mstate->getC();
00264   unsigned int numConstraints = constraints.size();
00265 
00266   force.resize((*mstate->getX()).size());
00267 
00268   for(unsigned int c1 = 0; c1 < numConstraints; c1++)
00269   {
00270     int indexC1 = mstate->getConstraintId()[c1];
00271     double fC1 = f->element(indexC1);
00272     if (fC1 != 0.0)
00273     {
00274       int sizeC1 = constraints[c1].size();
00275       for(int i = 0; i < sizeC1; i++)
00276       { 
00277     force[constraints[c1][i].index] += constraints[c1][i].data * fC1;
00278       }
00279     }
00280   }
00281 
00282   VecDeriv& dx = *mstate->getDx();
00283   VecCoord& x = *mstate->getX();
00284   VecDeriv& v = *mstate->getV();
00285   VecDeriv& v_free = *mstate->getVfree();
00286   VecCoord& x_free = *mstate->getXfree();
00287   double dt = this->getContext()->getDt();
00288 
00289 
00290     // Euler integration... will be done in the "integrator" as soon as it exists !
00291   dx.resize(v.size());
00292 
00293   for (unsigned int i=0; i<dx.size(); i++)
00294   {
00295     x[i] = x_free[i];
00296     v[i] = v_free[i];
00297     dx[i] = force[i]/10000.0;
00298     x[i] += dx[i];
00299     v[i] += dx[i]/dt;
00300   }
00301     }
00302 
00303 #endif
00304 #ifndef SOFA_DOUBLE
00305 template<>
00306     void UncoupledConstraintCorrection<defaulttype::Rigid3fTypes>::getCompliance(defaulttype::BaseMatrix*W)
00307 {
00308   const VecConst& constraints = *mstate->getC();
00309   Deriv weighedNormal;
00310   Deriv InvM_wN;
00311 
00312   const sofa::defaulttype::Rigid3fMass* massValue;
00313 
00314   simulation::tree::GNode *node = dynamic_cast<simulation::tree::GNode *>(getContext());
00315 
00316   if (node != NULL)
00317   {
00318     core::componentmodel::behavior::BaseMass*_m = node->mass;
00319     component::mass::UniformMass<defaulttype::Rigid3fTypes, defaulttype::Rigid3fMass> *m = dynamic_cast<component::mass::UniformMass<defaulttype::Rigid3fTypes, defaulttype::Rigid3fMass>*> (_m);
00320     massValue = &( m->getMass());
00321   }
00322   else
00323   {
00324     massValue = new sofa::defaulttype::Rigid3fMass();
00325     printf("\n WARNING : node is not found => massValue could be false in getCompliance function");
00326   }
00327 
00328   unsigned int numConstraints = constraints.size();
00329 
00330   double dt = this->getContext()->getDt();
00331 
00332   for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
00333   {
00334     int sizeCurRowConst = constraints[curRowConst].size();
00335     int indexCurRowConst = mstate->getConstraintId()[curRowConst];
00336 
00337     for(int i = 0; i < sizeCurRowConst; i++)
00338     {
00339       weighedNormal.getVCenter() = constraints[curRowConst][i].data.getVCenter(); // weighed normal
00340       weighedNormal.getVOrientation() = constraints[curRowConst][i].data.getVOrientation();
00341 
00342       InvM_wN = weighedNormal / (*massValue);
00343       InvM_wN *= dt*dt;
00344         
00345       int indexCurColConst;
00346 
00347       for(unsigned int curColConst = curRowConst; curColConst < numConstraints; curColConst++)
00348       {
00349     int sizeCurColConst = constraints[curColConst].size();
00350     indexCurColConst = mstate->getConstraintId()[curColConst];
00351 
00352     for(int j = 0; j < sizeCurColConst; j++)
00353     {
00354                     //W[indexCurRowConst][indexCurColConst] +=  constraints[curColConst][j].data * InvM_wN;
00355       double w =  constraints[curColConst][j].data * InvM_wN;
00356       W->add(indexCurRowConst, indexCurColConst, w);
00357       if (indexCurRowConst != indexCurColConst)
00358         W->add(indexCurColConst, indexCurRowConst, w);
00359     }
00360       }
00361 /*
00362       for(unsigned int curColConst = curRowConst+1; curColConst < numConstraints; curColConst++)
00363       {
00364       indexCurColConst = mstate->getConstraintId()[curColConst];
00365       W[indexCurColConst][indexCurRowConst] = W[indexCurRowConst][indexCurColConst];
00366     }
00367 */
00368     }
00369   }
00370 }
00371 
00372 template<>
00373     void UncoupledConstraintCorrection<defaulttype::Rigid3fTypes>::applyContactForce(const defaulttype::BaseVector *f)
00374 {
00375   VecDeriv& force = *mstate->getExternalForces();
00376   const VecConst& constraints = *mstate->getC();
00377   Deriv weighedNormal;
00378 
00379   const sofa::defaulttype::Rigid3fMass* massValue;
00380 
00381   simulation::tree::GNode *node = dynamic_cast<simulation::tree::GNode *>(getContext());
00382 
00383   if (node != NULL)
00384   {
00385     core::componentmodel::behavior::BaseMass*_m = node->mass;
00386     component::mass::UniformMass<defaulttype::Rigid3fTypes, defaulttype::Rigid3fMass> *m = dynamic_cast<component::mass::UniformMass<defaulttype::Rigid3fTypes, defaulttype::Rigid3fMass>*> (_m);
00387     massValue = &( m->getMass());
00388   }
00389   else
00390   {
00391     massValue = new sofa::defaulttype::Rigid3fMass();
00392     printf("\n WARNING : node is not found => massValue could be false in getCompliance function");
00393   }
00394 
00395 
00396   double dt = this->getContext()->getDt();
00397 
00398   force.resize(0);
00399   force.resize(1);
00400   force[0] = Deriv();
00401 
00402   int numConstraints = constraints.size();
00403 
00404   for(int c1 = 0; c1 < numConstraints; c1++)
00405   {
00406     int indexC1 = mstate->getConstraintId()[c1];
00407     double fC1 = f->element(indexC1);
00408 
00409     if (fC1 != 0.0)
00410     {
00411       int sizeC1 = constraints[c1].size();
00412       for(int i = 0; i < sizeC1; i++)
00413       { 
00414     weighedNormal = constraints[c1][i].data; // weighted normal
00415     force[0].getVCenter() += weighedNormal.getVCenter() * fC1;
00416     force[0].getVOrientation() += weighedNormal.getVOrientation() * fC1;
00417       }
00418     }
00419   }
00420 
00421 
00422   VecDeriv& dx = *mstate->getDx();
00423   VecCoord& x = *mstate->getX();
00424   VecDeriv& v = *mstate->getV();
00425   VecDeriv& v_free = *mstate->getVfree();
00426   VecCoord& x_free = *mstate->getXfree();
00427 
00428 
00429 //  mstate->setX(x_free);
00430 //  mstate->setV(v_free);
00431   x[0]=x_free[0];
00432   v[0]=v_free[0];
00433 
00434     // Euler integration... will be done in the "integrator" as soon as it exists !
00435   dx.resize(v.size());
00436   dx[0] = force[0] / (*massValue);
00437   dx[0] *= dt;
00438   v[0] += dx[0];
00439   dx[0] *= dt;
00440   x[0] += dx[0];
00441 //  simulation::tree::MechanicalPropagateAndAddDxVisitor(dx).execute(this->getContext());
00442 
00443 }
00444 
00445 template<>
00446     void UncoupledConstraintCorrection<defaulttype::Vec1fTypes>::getCompliance(defaulttype::BaseMatrix *W)
00447 {
00448   const VecConst& constraints = *mstate->getC();
00449   unsigned int numConstraints = constraints.size();
00450 
00451   for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
00452   {
00453     int sizeCurRowConst = constraints[curRowConst].size();
00454     int indexCurRowConst = mstate->getConstraintId()[curRowConst];
00455 
00456     for(int i = 0; i < sizeCurRowConst; i++)
00457     {
00458       int indexCurColConst;
00459 
00460       for(unsigned int curColConst = curRowConst; curColConst < numConstraints; curColConst++)
00461       {
00462     int sizeCurColConst = constraints[curColConst].size();
00463     indexCurColConst = mstate->getConstraintId()[curColConst];
00464 
00465     for(int j = 0; j < sizeCurColConst; j++)
00466     {
00467       if (constraints[curRowConst][i].index == constraints[curColConst][j].index)
00468       {
00469                         //W[indexCurRowConst][indexCurColConst] += (1.0/10000.0) * constraints[curRowConst][i].data.x() * constraints[curColConst][j].data.x();
00470         double w = (1.0/10000.0) * constraints[curRowConst][i].data.x() * constraints[curColConst][j].data.x();
00471         W->add(indexCurRowConst, indexCurColConst, w);
00472         if (indexCurRowConst != indexCurColConst)
00473           W->add(indexCurColConst, indexCurRowConst, w);
00474       }
00475     }
00476       }
00477 /*
00478       for(unsigned int curColConst = curRowConst+1; curColConst < numConstraints; curColConst++)
00479       {
00480       indexCurColConst = mstate->getConstraintId()[curColConst];
00481       W[indexCurColConst][indexCurRowConst] = W[indexCurRowConst][indexCurColConst];
00482     }
00483 */
00484     }
00485   }
00486 
00487 // debug : verifie qu'il n'y a pas de 0 sur la diagonale de W
00488     //printf("\n index : ");
00489     //for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
00490     //{
00491     //  int indexCurRowConst = mstate->getConstraintId()[curRowConst];
00492     //  printf(" %d ",indexCurRowConst);
00493     //  if(abs(W[indexCurRowConst][indexCurRowConst]) < 0.000000001)
00494     //      printf("\n WARNING : there is a 0 on the diagonal of matrix W");
00495 
00496     //  if(abs(W[curRowConst][curRowConst]) <0.000000001)
00497     //      printf("\n stop");
00498     //}
00499 
00500 
00501 }
00502 
00503 
00504 template<>
00505     void UncoupledConstraintCorrection<defaulttype::Vec1fTypes>::applyContactForce(const defaulttype::BaseVector *f){
00506 
00507   VecDeriv& force = *mstate->getExternalForces();
00508   const VecConst& constraints = *mstate->getC();
00509   unsigned int numConstraints = constraints.size();
00510 
00511   force.resize((*mstate->getX()).size());
00512 
00513   for(unsigned int c1 = 0; c1 < numConstraints; c1++)
00514   {
00515     int indexC1 = mstate->getConstraintId()[c1];
00516     double fC1 = f->element(indexC1);
00517     if (fC1 != 0.0)
00518     {
00519       int sizeC1 = constraints[c1].size();
00520       for(int i = 0; i < sizeC1; i++)
00521       { 
00522     force[constraints[c1][i].index] += constraints[c1][i].data * fC1;
00523       }
00524     }
00525   }
00526 
00527   VecDeriv& dx = *mstate->getDx();
00528   VecCoord& x = *mstate->getX();
00529   VecDeriv& v = *mstate->getV();
00530   VecDeriv& v_free = *mstate->getVfree();
00531   VecCoord& x_free = *mstate->getXfree();
00532   double dt = this->getContext()->getDt();
00533 
00534 
00535     // Euler integration... will be done in the "integrator" as soon as it exists !
00536   dx.resize(v.size());
00537 
00538   for (unsigned int i=0; i<dx.size(); i++)
00539   {
00540     x[i] = x_free[i];
00541     v[i] = v_free[i];
00542     dx[i] = force[i]/10000.0;
00543     x[i] += dx[i];
00544     v[i] += dx[i]/dt;
00545   }
00546     }
00547 
00548 #endif
00549 
00550 
00551 template<class DataTypes>
00552 void UncoupledConstraintCorrection<DataTypes>::resetContactForce()
00553 {
00554     VecDeriv& force = *mstate->getExternalForces();
00555     for( unsigned i=0; i<force.size(); ++i )
00556         force[i] = Deriv();
00557 }
00558 
00559 } // namespace constraint
00560 
00561 } // namespace component
00562 
00563 } // namespace sofa
00564 
00565 #endif

Generated on Sun Nov 23 02:46:24 2008 for Sofa by  doxygen 1.5.7.1