LinearSolverConstraintCorrection.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_CORE_COMPONENTMODEL_COLLISION_LINEARSOLVERCONTACTCORRECTION_INL
00026 #define SOFA_CORE_COMPONENTMODEL_COLLISION_LINEARSOLVERCONTACTCORRECTION_INL
00027 
00028 #include "LinearSolverConstraintCorrection.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 //compliance computation include
00035 #include <sofa/component/odesolver/CGImplicitSolver.h>
00036 //#include <glib.h>
00037 #include <sstream>
00038 #include <list>
00039 
00040 namespace sofa
00041 {
00042 
00043 namespace component
00044 {
00045 
00046 namespace constraint
00047 {
00048 #define MAX_NUM_CONSTRAINT_PER_NODE 100
00049 #define EPS_UNITARY_FORCE 0.01
00050 
00051 using namespace sofa::component::odesolver;
00052 
00053 template<class DataTypes>
00054 LinearSolverConstraintCorrection<DataTypes>::LinearSolverConstraintCorrection(behavior::MechanicalState<DataTypes> *mm)
00055 : mstate(mm), odesolver(NULL), linearsolver(NULL)
00056 {
00057 }
00058 
00059 template<class DataTypes>
00060 LinearSolverConstraintCorrection<DataTypes>::~LinearSolverConstraintCorrection()
00061 {
00062 }
00063 
00064 
00065 
00067  //   Precomputation of the Constraint Correction for all type of data
00069 
00070 template<class DataTypes>
00071 void LinearSolverConstraintCorrection<DataTypes>::init()
00072 {
00073     mstate = dynamic_cast< behavior::MechanicalState<DataTypes>* >(getContext()->getMechanicalState());
00074     objectmodel::BaseContext* c = this->getContext();
00075 //     odesolver = c->get< behavior::OdeSolver >();
00076 //     linearsolver = c->get< behavior::LinearSolver >();
00077     odesolver=getOdeSolver(c);
00078     linearsolver=getLinearSolver(c);
00079     if (odesolver == NULL)
00080     {
00081         std::cerr << "LinearSolverConstraintCorrection: ERROR no OdeSolver found."<<std::endl;
00082         return;
00083     }
00084     if (linearsolver == NULL)
00085     {
00086         std::cerr << "LinearSolverConstraintCorrection: ERROR no LinearSolver found."<<std::endl;
00087         return;
00088     }
00089     
00090     int n = mstate->getSize()*Deriv::size();
00091     
00092     std::stringstream ss;
00093     
00094     ss << this->getContext()->getName() << ".comp";
00095     
00096     std::ifstream compFileIn(ss.str().c_str(), std::ifstream::binary);
00097     
00098     std::cout << "try to open : " << ss.str() << endl;
00099 
00100     if(compFileIn.good())
00101     {
00102         std::cout << "file open : " << ss.str() << " compliance being loaded" << endl;
00103         refMinv.resize(n,n);
00104         //complianceLoaded = true;
00105         compFileIn.read((char*)refMinv.ptr(), n*n*sizeof(double));
00106         compFileIn.close();
00107     }
00108 }
00109 
00110 template<class DataTypes>
00111 void LinearSolverConstraintCorrection<DataTypes>::getCompliance(defaulttype::BaseMatrix* W)
00112 {
00113     if (!mstate || !odesolver || !linearsolver) return;
00114     
00115     // use the OdeSolver to get the position integration factor
00116     //const double factor = 1.0;
00117     //const double factor = odesolver->getPositionIntegrationFactor(); // dt
00118     const double factor = odesolver->getPositionIntegrationFactor(); //*odesolver->getPositionIntegrationFactor(); // dt*dt
00119 
00120     const unsigned int numDOFs = mstate->getSize();
00121     const unsigned int N = Deriv::size();
00122     const unsigned int numDOFReals = numDOFs*N;
00123     if (refMinv.rowSize() > 0)
00124     {
00125         J.resize(numDOFReals,numDOFReals);
00126         for (unsigned int i=0;i<numDOFReals;++i)
00127             J.set(i,i,1);
00128         linearsolver::FullMatrix<Real> Minv;
00129         Minv.resize(numDOFReals,numDOFReals);
00130         // use the Linear solver to compute J*inv(M)*Jt, where M is the mechanical linear system matrix
00131         linearsolver->addJMInvJt(&Minv, &J, factor);
00132         double err=0,fact=0;
00133         for (unsigned int i=0;i<numDOFReals;++i)
00134             for (unsigned int j=0;j<numDOFReals;++j)
00135             {
00136                 //std::cout << "Minv("<<i<<","<<j<<") = "<<Minv.element(i,j)<<"\t refMinv("<<i<<","<<j<<") = "<<refMinv.element(i,j)<<std::endl;
00137                 if (fabs(refMinv.element(i,j)) > 1.0e-30)
00138                 {
00139                     err += fabs(Minv.element(i,j)-refMinv.element(i,j))/refMinv.element(i,j);
00140                     fact += fabs(Minv.element(i,j)/refMinv.element(i,j));
00141                 }
00142                 else
00143                 {
00144                     err += fabs(Minv.element(i,j)-refMinv.element(i,j));
00145                     fact += 1.0f;
00146                 }
00147             }
00148         std::cout << "LinearSolverConstraintCorrection: mean relative error: "<<err/(numDOFReals*numDOFReals)<<std::endl;
00149         std::cout << "LinearSolverConstraintCorrection: mean relative factor: "<<fact/(numDOFReals*numDOFReals)<<std::endl;
00150         refMinv.resize(0,0);
00151     }
00152     // Compute J
00153     VecConst& constraints = *mstate->getC();
00154     const unsigned int numConstraints = constraints.size();
00155     const unsigned int totalNumConstraints = W->rowSize();
00156     
00157     J.resize(totalNumConstraints, numDOFReals);
00158     for(unsigned int c1 = 0; c1 < numConstraints; c1++)
00159     {
00160         int cid = mstate->getConstraintId()[c1];
00161         for(unsigned int i = 0; i < constraints[c1].size(); i++)
00162         {
00163             int dof = constraints[c1][i].index;
00164             Deriv n = constraints[c1][i].data;
00165             for (unsigned int r=0;r<N;++r)
00166                 J.add(cid, dof*N+r, n[r]);
00167     }
00168     }
00169     
00170     // use the Linear solver to compute J*inv(M)*Jt, where M is the mechanical linear system matrix
00171     linearsolver->addJMInvJt(W, &J, factor);
00172 }
00173 
00174 template<class DataTypes>
00175 void LinearSolverConstraintCorrection<DataTypes>::applyContactForce(const defaulttype::BaseVector *f)
00176 {
00177     behavior::BaseMechanicalState::VecId forceID(behavior::BaseMechanicalState::VecId::V_DERIV, behavior::BaseMechanicalState::VecId::V_FIRST_DYNAMIC_INDEX);
00178     behavior::BaseMechanicalState::VecId dxID(behavior::BaseMechanicalState::VecId::dx()); //behavior::BaseMechanicalState::VecId::V_DERIV, behavior::BaseMechanicalState::VecId::V_FIRST_DYNAMIC_INDEX+1);
00179     mstate->vAlloc(forceID);
00180     mstate->vOp(forceID);
00181 //    mstate->vAlloc(dxID);
00182     mstate->setDx(forceID);
00183     VecDeriv& force = *mstate->getDx();
00184     mstate->setDx(dxID);
00185     VecDeriv& dx = *mstate->getDx();
00186     mstate->setDx(behavior::BaseMechanicalState::VecId::dx());
00187     //VecConst& constraints = *mstate->getC();
00188     //unsigned int numConstraints = constraints.size();
00189     VecCoord& x = *mstate->getX();
00190     VecDeriv& v = *mstate->getV();
00191     VecDeriv v_free = *mstate->getVfree();
00192     VecCoord x_free = *mstate->getXfree();
00193     //double dt = this->getContext()->getDt();
00194 
00195     const unsigned int numDOFs = mstate->getSize();
00196 
00197     dx.clear();
00198     dx.resize(numDOFs);
00199     for (unsigned int i=0; i< numDOFs; i++)
00200         dx[i] = Deriv();
00201     
00202     force.clear();
00203     force.resize(numDOFs);
00204     for (unsigned int i=0; i< numDOFs; i++)
00205         force[i] = Deriv();
00206 #if 0
00207     const unsigned int N = Deriv::size();
00208     const unsigned int numDOFReals = numDOFs*N;
00209     F.resize(numDOFReals);
00210     const linearsolver::FullVector<Real>* fcast = dynamic_cast< const linearsolver::FullVector<Real>* >(f);
00211     if (fcast)
00212         J.mulTranspose(F, *fcast); // fast
00213     else
00214         J.mulTranspose(F, fcast); // slow but generic
00215     for (unsigned int i=0; i< numDOFs; i++)
00216         for (unsigned int r=0;r<N;++r)
00217             force[i][r] = F[i*N+r];
00218 #else
00219     const VecConst& constraints = *mstate->getC();
00220     unsigned int numConstraints = constraints.size();
00221     
00222     for(unsigned int c1 = 0; c1 < numConstraints; c1++)
00223     {
00224         int indexC1 = mstate->getConstraintId()[c1];
00225         double fC1 = f->element(indexC1);
00226         //std::cout << "fC("<<indexC1<<")="<<fC1<<std::endl;
00227         if (fC1 != 0.0)
00228         {
00229             int sizeC1 = constraints[c1].size();
00230             for(int i = 0; i < sizeC1; i++)
00231             {
00232                 //std::cout << "f("<<constraints[c1][i].index<<") += "<< (constraints[c1][i].data * fC1) << std::endl;
00233                 force[constraints[c1][i].index] += constraints[c1][i].data * fC1;
00234             }
00235         }
00236     }
00237 #endif
00238     //for (unsigned int i=0; i< numDOFs; i++)
00239     //    std::cout << "f("<<i<<")="<<force[i]<<std::endl;
00240     linearsolver->setSystemRHVector(forceID);
00241     linearsolver->setSystemLHVector(dxID);
00242     linearsolver->solveSystem(); //TODO: tell the solver not to recompute the matrix
00243     
00244     // use the OdeSolver to get the position integration factor
00245     const double positionFactor = odesolver->getPositionIntegrationFactor();
00246     
00247     // use the OdeSolver to get the position integration factor
00248     const double velocityFactor = odesolver->getVelocityIntegrationFactor();
00249     
00250     for (unsigned int i=0; i< numDOFs; i++)
00251     {
00252         //std::cout << "dx("<<i<<")="<<dx[i]<<std::endl;
00253         Deriv dxi = dx[i]*positionFactor;
00254         Deriv dvi = dx[i]*velocityFactor;
00255         x[i] = x_free[i] + dxi;
00256         v[i] = v_free[i] + dvi;
00257         dx[i] = dxi;
00258     }
00259     mstate->vFree(forceID);
00260 }
00261 
00262 template<class DataTypes>
00263 void LinearSolverConstraintCorrection<DataTypes>::resetContactForce()
00264 {
00265     VecDeriv& force = *mstate->getF();
00266     for( unsigned i=0; i<force.size(); ++i )
00267         force[i] = Deriv();
00268 }
00269 
00270 } // namespace collision
00271 
00272 } // namespace component
00273 
00274 } // namespace sofa
00275 
00276 #endif

Generated on Sun Nov 23 02:42:54 2008 for Sofa by  doxygen 1.5.7.1