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_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& ) {}
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
00170 this->getMatrixDimension(&nbRow, &nbCol);
00171 resizeSystem(nbRow);
00172 systemMatrix->clear();
00173 unsigned int offset = 0;
00174
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
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
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
00208
00209
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
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
00307
00308
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 }
00354
00355 }
00356
00357 #endif