OdeSolverImpl.cpp

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 #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 : /*mat(NULL),*/ 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     //VecId v(t, vectors[t].alloc());
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     //if (vectors[v.type].free(v.index))
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     //MechanicalComputeDfVisitor(df).execute( getContext() );
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 // BaseMatrix & BaseVector Computations
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         //std::cout << "MechanicalAddMBK_ToMatrixVisitor "<< mFact << " " << bFact << " " << kFact << " " << offset << std::endl;
00258         MechanicalAddMBK_ToMatrixVisitor(A, mFact, bFact, kFact, offset).execute( getContext() );
00259     }
00260 }
00261 /*
00262 void SolverImpl::addMBKdx_ToVector(defaulttype::BaseVector *V, VecId dx, double mFact, double bFact, double kFact, unsigned int offset)
00263 {
00264     if (V != NULL)
00265         MechanicalAddMBKdx_ToVectorVisitor(V, dx, mFact, bFact, kFact, offset).execute( getContext() );
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     //out << *m;
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 } // namespace simulation
00367 
00368 } // namespace sofa

Generated on Sun Nov 23 04:05:47 2008 for Sofa by  doxygen 1.5.7.1