LinearSolverConstraintCorrection.inl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00035 #include <sofa/component/odesolver/CGImplicitSolver.h>
00036
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
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
00076
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
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
00116
00117
00118 const double factor = odesolver->getPositionIntegrationFactor();
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
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
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
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
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());
00179 mstate->vAlloc(forceID);
00180 mstate->vOp(forceID);
00181
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
00188
00189 VecCoord& x = *mstate->getX();
00190 VecDeriv& v = *mstate->getV();
00191 VecDeriv v_free = *mstate->getVfree();
00192 VecCoord x_free = *mstate->getXfree();
00193
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);
00213 else
00214 J.mulTranspose(F, fcast);
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
00227 if (fC1 != 0.0)
00228 {
00229 int sizeC1 = constraints[c1].size();
00230 for(int i = 0; i < sizeC1; i++)
00231 {
00232
00233 force[constraints[c1][i].index] += constraints[c1][i].data * fC1;
00234 }
00235 }
00236 }
00237 #endif
00238
00239
00240 linearsolver->setSystemRHVector(forceID);
00241 linearsolver->setSystemLHVector(dxID);
00242 linearsolver->solveSystem();
00243
00244
00245 const double positionFactor = odesolver->getPositionIntegrationFactor();
00246
00247
00248 const double velocityFactor = odesolver->getVelocityIntegrationFactor();
00249
00250 for (unsigned int i=0; i< numDOFs; i++)
00251 {
00252
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 }
00271
00272 }
00273
00274 }
00275
00276 #endif