MatrixLinearSolver.h

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_SIMULATION_MATRIXLINEARSOLVER_H
00026 #define SOFA_SIMULATION_MATRIXLINEARSOLVER_H
00027 
00028 #include <sofa/simulation/common/OdeSolverImpl.h>
00029 #include <sofa/core/componentmodel/behavior/LinearSolver.h>
00030 
00031 namespace sofa
00032 {
00033 
00034 namespace simulation
00035 {
00036 
00037 
00038 template<class Matrix, class Vector>
00039 class MatrixLinearSolverInternalData
00040 {
00041 public:
00042     MatrixLinearSolverInternalData(core::objectmodel::BaseObject*)
00043     {}
00044 };
00045 
00046 template<class Matrix, class Vector>
00047 class MatrixLinearSolver : public sofa::core::componentmodel::behavior::LinearSolver, public SolverImpl
00048 {
00049 public:
00050     typedef sofa::core::componentmodel::behavior::BaseMechanicalState::VecId VecId;
00051     
00052     MatrixLinearSolver();
00053     virtual ~MatrixLinearSolver();
00054     
00056     void resetSystem();
00057     
00059     void resizeSystem(int n);
00060     
00066     void setSystemMBKMatrix(double mFact=0.0, double bFact=0.0, double kFact=0.0);
00067     
00069     void setSystemRHVector(VecId v);
00070     
00073     void setSystemLHVector(VecId v);
00074     
00076     Matrix* getSystemMatrix() { return systemMatrix; }
00077     
00079     Vector* getSystemRHVector() { return systemRHVector; }
00080     
00082     Vector* getSystemLHVector() { return systemLHVector; }
00083     
00085     defaulttype::BaseMatrix* getSystemBaseMatrix() { return systemMatrix; }
00086     
00088     defaulttype::BaseVector* getSystemRHBaseVector() { return systemRHVector; }
00089     
00091     defaulttype::BaseVector* getSystemLHBaseVector() { return systemLHVector; }
00092     
00094     virtual void solveSystem();
00095 
00096     virtual std::string getTemplateName() const
00097     {
00098         return templateName(this);
00099     }
00100     
00101     static std::string templateName(const MatrixLinearSolver<Matrix,Vector>* = NULL)
00102     {
00103         return Matrix::Name();
00104     }
00105     
00106     
00107 protected:
00108     
00109     virtual void invert(Matrix& /*M*/) {}
00110         
00111     virtual void solve(Matrix& M, Vector& solution, Vector& rh) = 0;
00112     
00113     Vector* createVector();
00114     void deleteVector(Vector* v);
00115 
00116     Matrix* createMatrix();
00117     void deleteMatrix(Matrix* v);
00118 
00119     MatrixLinearSolverInternalData<Matrix,Vector>* data;
00120 
00121     bool needInvert;
00122     Matrix* systemMatrix;
00123     Vector* systemRHVector;
00124     Vector* systemLHVector;
00125     VecId solutionVecId;
00126 };
00127 
00128 template<class Matrix, class Vector>
00129 MatrixLinearSolver<Matrix,Vector>::MatrixLinearSolver()
00130 : needInvert(true), systemMatrix(NULL), systemRHVector(NULL), systemLHVector(NULL)
00131 {
00132     data = new MatrixLinearSolverInternalData<Matrix,Vector>(this);
00133 }
00134 
00135 template<class Matrix, class Vector>
00136 MatrixLinearSolver<Matrix,Vector>::~MatrixLinearSolver()
00137 {
00138     if (systemMatrix) deleteMatrix(systemMatrix);
00139     if (systemRHVector) deleteVector(systemRHVector);
00140     if (systemLHVector) deleteVector(systemLHVector);
00141 }
00142 
00143 template<class Matrix, class Vector>
00144 void MatrixLinearSolver<Matrix,Vector>::resetSystem()
00145 {
00146     if (systemMatrix) systemMatrix->clear();
00147     if (systemRHVector) systemRHVector->clear();
00148     if (systemLHVector) systemLHVector->clear();
00149     solutionVecId = VecId();
00150     needInvert = true;
00151 }
00152 
00153 template<class Matrix, class Vector>
00154 void MatrixLinearSolver<Matrix,Vector>::resizeSystem(int n)
00155 {
00156     if (!systemMatrix) systemMatrix = createMatrix();
00157     systemMatrix->resize(n,n);
00158     if (!systemRHVector) systemRHVector = createVector();
00159     systemRHVector->resize(n);
00160     if (!systemLHVector) systemLHVector = createVector();
00161     systemLHVector->resize(n);
00162     needInvert = true;
00163 }
00164 
00165 template<class Matrix, class Vector>
00166 void MatrixLinearSolver<Matrix,Vector>::setSystemMBKMatrix(double mFact, double bFact, double kFact)
00167 {
00168     unsigned int nbRow=0, nbCol=0;
00169     //MechanicalGetMatrixDimensionVisitor(nbRow, nbCol).execute( getContext() );
00170     this->getMatrixDimension(&nbRow, &nbCol);
00171     resizeSystem(nbRow);
00172     systemMatrix->clear();
00173     unsigned int offset = 0;
00174     //MechanicalAddMBK_ToMatrixVisitor(systemMatrix, mFact, bFact, kFact, offset).execute( getContext() );
00175     this->addMBK_ToMatrix(systemMatrix, mFact, bFact, kFact, offset);
00176 }
00177 
00178 template<class Matrix, class Vector>
00179 void MatrixLinearSolver<Matrix,Vector>::setSystemRHVector(VecId v)
00180 {
00181     unsigned int offset = 0;
00182     //MechanicalMultiVector2BaseVectorVisitor(v, systemRHVector, offset).execute( getContext() );
00183     this->multiVector2BaseVector(v, systemRHVector, offset);
00184 }
00185 
00186 template<class Matrix, class Vector>
00187 void MatrixLinearSolver<Matrix,Vector>::setSystemLHVector(VecId v)
00188 {
00189     solutionVecId = v;
00190     unsigned int offset = 0;
00191     //MechanicalMultiVector2BaseVectorVisitor(v, systemLHVector, offset).execute( getContext() );
00192     this->multiVector2BaseVector(v, systemLHVector, offset);
00193 }
00194 
00195 template<class Matrix, class Vector>
00196 void MatrixLinearSolver<Matrix,Vector>::solveSystem()
00197 {
00198     if (needInvert)
00199     {
00200         this->invert(*systemMatrix);
00201         needInvert = false;
00202     }
00203     this->solve(*systemMatrix, *systemLHVector, *systemRHVector);
00204     if (!solutionVecId.isNull())
00205     {
00206         unsigned int offset = 0;
00207         //MechanicalBaseVector2MultiVectorVisitor(systemLHVector, solutionVecId, offset).execute( getContext() );
00208         //MechanicalVOpVisitor(solutionVecId).execute( getContext() ); // clear solutionVecId
00209         //MechanicalMultiVectorPeqBaseVectorVisitor(solutionVecId, systemLHVector, offset).execute( getContext() );
00210         v_clear(solutionVecId);
00211         multiVectorPeqBaseVector(solutionVecId, systemLHVector, offset);
00212     }
00213 }
00214 
00215 template<class Matrix, class Vector>
00216 Vector* MatrixLinearSolver<Matrix,Vector>::createVector()
00217 {
00218     return new Vector;
00219 }
00220 
00221 template<class Matrix, class Vector>
00222 void MatrixLinearSolver<Matrix,Vector>::deleteVector(Vector* v)
00223 {
00224     delete v;
00225 }
00226 
00227 template<class Matrix, class Vector>
00228 Matrix* MatrixLinearSolver<Matrix,Vector>::createMatrix()
00229 {
00230     return new Matrix;
00231 }
00232 
00233 template<class Matrix, class Vector>
00234 void MatrixLinearSolver<Matrix,Vector>::deleteMatrix(Matrix* v)
00235 {
00236     delete v;
00237 }
00238 
00239     
00240 class GraphScatteredMatrix;
00241 class GraphScatteredVector;
00242 template <class T1, class T2>
00243 class MultExpr
00244 {
00245 public:
00246     T1& a;
00247     T2& b;
00248     MultExpr(T1& a, T2& b) : a(a), b(b) {}
00249 };
00250 
00251 class GraphScatteredMatrix
00252 {
00253 protected:
00254     SolverImpl* parent;
00255     double mFact, bFact, kFact;
00256 public:
00257     GraphScatteredMatrix(SolverImpl* p)
00258     : parent(p), mFact(0.0), bFact(0.0), kFact(0.0)
00259     {
00260     }
00261     void setMBKFacts(double m, double b, double k)
00262     {
00263         mFact = m;
00264         bFact = b;
00265         kFact = k;
00266     }
00267     MultExpr<GraphScatteredMatrix,GraphScatteredVector> operator*(GraphScatteredVector& v)
00268     {
00269         return MultExpr<GraphScatteredMatrix,GraphScatteredVector>(*this, v);
00270     }
00271     void apply(GraphScatteredVector& res, GraphScatteredVector& x);
00272     //void papply(GraphScatteredVector& res, GraphScatteredVector& x);
00273     
00274     static const char* Name() { return "GraphScattered"; }
00275 };
00276 
00277 
00278 class GraphScatteredVector : public sofa::core::componentmodel::behavior::MultiVector<SolverImpl>
00279 {
00280 public:
00281     typedef sofa::core::componentmodel::behavior::MultiVector<SolverImpl> Inherit;
00282     GraphScatteredVector(SolverImpl* p, VecId id)
00283     : Inherit(p, id)
00284     {
00285     }
00286     GraphScatteredVector(SolverImpl* p, VecId::Type t = VecId::V_DERIV)
00287     : Inherit(p, t)
00288     {
00289     }
00290     void set(VecId id)
00291     {
00292         this->v = id;
00293     }
00294     void reset()
00295     {
00296         this->v = VecId();
00297     }
00298     
00299     friend class GraphScatteredMatrix;
00300     
00301     void operator=(const MultExpr<GraphScatteredMatrix,GraphScatteredVector>& expr)
00302     {
00303         expr.a.apply(*this,expr.b);
00304     }
00305     
00306     //void operator+=(const MultExpr<GraphScatteredMatrix,GraphScatteredVector>& expr)
00307     //{
00308     //    expr.a.papply(*this,expr.b);
00309     //}
00310     
00311     static const char* Name() { return "GraphScattered"; }
00312 };
00313 
00314 template<>
00315 void MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::resetSystem();
00316 
00317 template<>
00318 void MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::resizeSystem(int);
00319 
00320 template<>
00321 void MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::setSystemMBKMatrix(double mFact, double bFact, double kFact);
00322 
00323 template<>
00324 void MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::setSystemRHVector(VecId v);
00325 
00326 template<>
00327 void MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::setSystemLHVector(VecId v);
00328 
00329 template<>
00330 void MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::solveSystem();
00331 
00332 template<>
00333 GraphScatteredVector* MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::createVector();
00334 
00335 template<>
00336 void MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::deleteVector(GraphScatteredVector* v);
00337     
00338 template<>
00339 GraphScatteredMatrix* MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::createMatrix();
00340 
00341 template<>
00342 void MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::deleteMatrix(GraphScatteredMatrix* v);
00343 
00344 template<>
00345 defaulttype::BaseMatrix* MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::getSystemBaseMatrix();
00346 
00347 template<>
00348 defaulttype::BaseVector* MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::getSystemRHBaseVector();
00349 
00350 template<>
00351 defaulttype::BaseVector* MatrixLinearSolver<GraphScatteredMatrix,GraphScatteredVector>::getSystemLHBaseVector();
00352 
00353 } // namespace simulation
00354 
00355 } // namespace sofa
00356 
00357 #endif

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