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 #include <sofa/simulation/common/OdeSolverImpl.h>
00026 #include <sofa/simulation/common/MechanicalVisitor.h>
00027 #include <sofa/simulation/common/MechanicalMatrixVisitor.h>
00028 #include <sofa/simulation/common/MechanicalVPrintVisitor.h>
00029 #include <sofa/simulation/common/VelocityThresholdVisitor.h>
00030 #include <sofa/core/componentmodel/behavior/LinearSolver.h>
00031
00032
00033 #include <stdlib.h>
00034 #include <math.h>
00035
00036 namespace sofa
00037 {
00038
00039 namespace simulation
00040 {
00041
00042
00043 SolverImpl::SolverImpl()
00044 : result(0)
00045 {}
00046
00047 SolverImpl::~SolverImpl()
00048 {}
00049
00050 double SolverImpl::finish()
00051 {
00052 return result;
00053 }
00054
00055 SolverImpl::VecId SolverImpl::v_alloc(VecId::Type t)
00056 {
00057
00058 VecId v(t, VecId::V_FIRST_DYNAMIC_INDEX);
00059 MechanicalVAvailVisitor(v).execute( getContext() );
00060 MechanicalVAllocVisitor(v).execute( getContext() );
00061 return v;
00062 }
00063
00064 void SolverImpl::v_free(VecId v)
00065 {
00066
00067 MechanicalVFreeVisitor(v).execute( getContext() );
00068 }
00069
00070 void SolverImpl::v_clear(VecId v)
00071 {
00072 MechanicalVOpVisitor(v).execute( getContext() );
00073 }
00074
00075 void SolverImpl::v_eq(VecId v, VecId a)
00076 {
00077 MechanicalVOpVisitor(v,a).execute( getContext() );
00078 }
00079
00080 void SolverImpl::v_peq(VecId v, VecId a, double f)
00081 {
00082 MechanicalVOpVisitor(v,v,a,f).execute( getContext() );
00083 }
00084 void SolverImpl::v_teq(VecId v, double f)
00085 {
00086 MechanicalVOpVisitor(v,VecId::null(),v,f).execute( getContext() );
00087 }
00088 void SolverImpl::v_op(VecId v, VecId a, VecId b, double f)
00089 {
00090 MechanicalVOpVisitor(v,a,b,f).execute( getContext() );
00091 }
00092
00093 void SolverImpl::v_dot(VecId a, VecId b)
00094 {
00095 result = 0;
00096 MechanicalVDotVisitor(a,b,&result).execute( getContext() );
00097 }
00098
00099 void SolverImpl::v_threshold(VecId a, double t)
00100 {
00101 VelocityThresholdVisitor(a,t).execute( getContext() );
00102 }
00103
00104 void SolverImpl::propagateDx(VecId dx)
00105 {
00106 MechanicalPropagateDxVisitor(dx).execute( getContext() );
00107 }
00108
00109 void SolverImpl::propagateDxAndResetDf(VecId dx, VecId df)
00110 {
00111 MechanicalPropagateDxAndResetForceVisitor(dx,df).execute( getContext() );
00112 finish();
00113 }
00114
00115 void SolverImpl::projectResponse(VecId dx, double **W)
00116 {
00117 MechanicalApplyConstraintsVisitor(dx, W).execute( getContext() );
00118 }
00119
00120 void SolverImpl::addMdx(VecId res, VecId dx, double factor)
00121 {
00122 MechanicalAddMDxVisitor(res,dx,factor).execute( getContext() );
00123 }
00124
00125 void SolverImpl::integrateVelocity(VecId res, VecId x, VecId v, double dt)
00126 {
00127 MechanicalVOpVisitor(res,x,v,dt).execute( getContext() );
00128 }
00129
00130 void SolverImpl::accFromF(VecId a, VecId f)
00131 {
00132 MechanicalAccFromFVisitor(a,f).execute( getContext() );
00133 }
00134
00135 void OdeSolverImpl::propagatePositionAndVelocity(double t, VecId x, VecId v)
00136 {
00137 MechanicalPropagatePositionAndVelocityVisitor(t,x,v).execute( getContext() );
00138 }
00139
00140 void SolverImpl::computeForce(VecId result, bool clear, bool accumulate)
00141 {
00142 if (clear)
00143 {
00144 MechanicalResetForceVisitor(result).execute( getContext() );
00145 finish();
00146 }
00147 MechanicalComputeForceVisitor(result, accumulate).execute( getContext() );
00148 }
00149
00150 void SolverImpl::computeDf(VecId df, bool clear, bool accumulate)
00151 {
00152 if (clear)
00153 {
00154 MechanicalResetForceVisitor(df).execute( getContext() );
00155 finish();
00156 }
00157 MechanicalComputeDfVisitor(df, false, accumulate).execute( getContext() );
00158 }
00159
00160 void SolverImpl::computeDfV(VecId df, bool clear, bool accumulate)
00161 {
00162 if (clear)
00163 {
00164 MechanicalResetForceVisitor(df).execute( getContext() );
00165 finish();
00166 }
00167 MechanicalComputeDfVisitor(df, true, accumulate).execute( getContext() );
00168 }
00169
00170 void SolverImpl::addMBKdx(VecId df, double m, double b, double k, bool clear, bool accumulate)
00171 {
00172 if (clear)
00173 {
00174 MechanicalResetForceVisitor(df, true).execute( getContext() );
00175 finish();
00176 }
00177 MechanicalAddMBKdxVisitor(df,m,b,k, false, accumulate).execute( getContext() );
00178 }
00179
00180 void SolverImpl::addMBKv(VecId df, double m, double b, double k, bool clear, bool accumulate)
00181 {
00182 if (clear)
00183 {
00184 MechanicalResetForceVisitor(df, true).execute( getContext() );
00185 finish();
00186 }
00187 MechanicalAddMBKdxVisitor(df,m,b,k, true, accumulate).execute( getContext() );
00188 }
00189
00190 void OdeSolverImpl::computeAcc(double t, VecId a, VecId x, VecId v)
00191 {
00192 MultiVector f(this, VecId::force());
00193 propagatePositionAndVelocity(t, x, v);
00194 computeForce(f);
00195 if( this->f_printLog.getValue()==true ){
00196 cerr<<"OdeSolver::computeAcc, f = "<<f<<endl;
00197 }
00198
00199 accFromF(a, f);
00200 projectResponse(a);
00201 }
00202
00203 void SolverImpl::addSeparateGravity(double dt)
00204 {
00205 MechanicalAddSeparateGravityVisitor(dt).execute( getContext() );
00206 }
00207
00208 void SolverImpl::computeContactForce(VecId result)
00209 {
00210 MechanicalResetForceVisitor(result).execute( getContext() );
00211 finish();
00212 MechanicalComputeContactForceVisitor(result).execute( getContext() );
00213 }
00214
00215 void SolverImpl::computeContactDf(VecId df)
00216 {
00217 MechanicalResetForceVisitor(df).execute( getContext() );
00218 finish();
00219
00220 }
00221
00222 void OdeSolverImpl::computeContactAcc(double t, VecId a, VecId x, VecId v)
00223 {
00224 MultiVector f(this, VecId::force());
00225 propagatePositionAndVelocity(t, x, v);
00226 computeContactForce(f);
00227 if( this->f_printLog.getValue()==true ){
00228 cerr<<"OdeSolver::computeContactAcc, f = "<<f<<endl;
00229 }
00230
00231 accFromF(a, f);
00232 projectResponse(a);
00233 }
00234
00235 void SolverImpl::print( VecId v, std::ostream& out )
00236 {
00237 MechanicalVPrintVisitor(v,out).execute( getContext() );
00238 }
00239
00240 void SolverImpl::printWithElapsedTime( VecId v, unsigned time, std::ostream& out )
00241 {
00242 const double fact = 1000000.0 / (100*helper::system::thread::CTime::getTicksPerSec());
00243 MechanicalVPrintWithElapsedTimeVisitor(v,(int)((fact*time+0.5)*0.001), out).execute( getContext() );
00244 }
00245
00246
00247
00248 void SolverImpl::getMatrixDimension(unsigned int * const nbRow, unsigned int * const nbCol)
00249 {
00250 MechanicalGetMatrixDimensionVisitor(nbRow, nbCol).execute( getContext() );
00251 }
00252
00253 void SolverImpl::addMBK_ToMatrix(defaulttype::BaseMatrix *A, double mFact, double bFact, double kFact, unsigned int offset)
00254 {
00255 if (A != NULL)
00256 {
00257
00258 MechanicalAddMBK_ToMatrixVisitor(A, mFact, bFact, kFact, offset).execute( getContext() );
00259 }
00260 }
00261
00262
00263
00264
00265
00266
00267
00268 void SolverImpl::multiVector2BaseVector(VecId src, defaulttype::BaseVector *dest, unsigned int offset)
00269 {
00270 if (dest != NULL)
00271 {
00272 MechanicalMultiVector2BaseVectorVisitor(src, dest, offset).execute( getContext() );;
00273 }
00274 }
00275
00276 void SolverImpl::multiVectorPeqBaseVector(VecId dest, defaulttype::BaseVector *src, unsigned int offset)
00277 {
00278 if (src != NULL)
00279 {
00280 MechanicalMultiVectorPeqBaseVectorVisitor(dest, src, offset).execute( getContext() );;
00281 }
00282 }
00283
00284 using sofa::core::componentmodel::behavior::LinearSolver;
00285 using sofa::core::objectmodel::BaseContext;
00286
00287 void OdeSolverImpl::m_resetSystem()
00288 {
00289 LinearSolver* s = getContext()->get<LinearSolver>(BaseContext::SearchDown);
00290 if (!s)
00291 {
00292 std::cerr << "ERROR: "<<this->getClassName()<<" requires a LinearSolver."<<std::endl;
00293 return;
00294 }
00295 s->resetSystem();
00296 }
00297
00298 void OdeSolverImpl::m_setSystemMBKMatrix(double mFact, double bFact, double kFact)
00299 {
00300 LinearSolver* s = getContext()->get<LinearSolver>(BaseContext::SearchDown);
00301 if (!s)
00302 {
00303 std::cerr << "ERROR: "<<this->getClassName()<<" requires a LinearSolver."<<std::endl;
00304 return;
00305 }
00306 s->setSystemMBKMatrix(mFact, bFact, kFact);
00307 }
00308
00309 void OdeSolverImpl::m_setSystemRHVector(VecId v)
00310 {
00311 LinearSolver* s = getContext()->get<LinearSolver>(BaseContext::SearchDown);
00312 if (!s)
00313 {
00314 std::cerr << "ERROR: "<<this->getClassName()<<" requires a LinearSolver."<<std::endl;
00315 return;
00316 }
00317 s->setSystemRHVector(v);
00318 }
00319
00320 void OdeSolverImpl::m_setSystemLHVector(VecId v)
00321 {
00322 LinearSolver* s = getContext()->get<LinearSolver>(BaseContext::SearchDown);
00323 if (!s)
00324 {
00325 std::cerr << "ERROR: "<<this->getClassName()<<" requires a LinearSolver."<<std::endl;
00326 return;
00327 }
00328 s->setSystemLHVector(v);
00329 }
00330
00331 void OdeSolverImpl::m_solveSystem()
00332 {
00333 LinearSolver* s = getContext()->get<LinearSolver>(BaseContext::SearchDown);
00334 if (!s)
00335 {
00336 std::cerr << "ERROR: "<<this->getClassName()<<" requires a LinearSolver."<<std::endl;
00337 return;
00338 }
00339 s->solveSystem();
00340 }
00341
00342 void OdeSolverImpl::m_print( std::ostream& out )
00343 {
00344 LinearSolver* s = getContext()->get<LinearSolver>(BaseContext::SearchDown);
00345 if (!s)
00346 {
00347 std::cerr << "ERROR: "<<this->getClassName()<<" requires a LinearSolver."<<std::endl;
00348 return;
00349 }
00350 defaulttype::BaseMatrix* m = s->getSystemBaseMatrix();
00351 if (!m) return;
00352
00353 int ny = m->rowSize();
00354 int nx = m->colSize();
00355 out << "[";
00356 for (int y=0;y<ny;++y)
00357 {
00358 out << "[";
00359 for (int x=0;x<nx;x++)
00360 out << ' ' << m->element(x,y);
00361 out << "]";
00362 }
00363 out << "]";
00364 }
00365
00366 }
00367
00368 }