LinearSystem.hpp
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
00026
00027
00028
00029 #ifndef _LINEARSYSTEM_HPP_
00030 #define _LINEARSYSTEM_HPP_
00031
00032 #include "ChasteSerialization.hpp"
00033 #include "UblasCustomFunctions.hpp"
00034
00035 #include "PetscTools.hpp"
00036 #include "PetscVecTools.hpp"
00037 #include "PetscMatTools.hpp"
00038 #include "OutputFileHandler.hpp"
00039 #include "PCBlockDiagonal.hpp"
00040 #include "PCLDUFactorisation.hpp"
00041 #include "PCTwoLevelsBlockDiagonal.hpp"
00042 #include "ArchiveLocationInfo.hpp"
00043 #include <boost/serialization/shared_ptr.hpp>
00044
00045 #include <petscvec.h>
00046 #include <petscmat.h>
00047 #include <petscksp.h>
00048 #include <petscviewer.h>
00049
00050 #include <string>
00051 #include <cassert>
00052
00058 class LinearSystem
00059 {
00060 friend class TestLinearSystem;
00061 friend class TestPCBlockDiagonal;
00062 friend class TestPCTwoLevelsBlockDiagonal;
00063 friend class TestPCLDUFactorisation;
00064 friend class TestChebyshevIteration;
00065
00066 private:
00067
00068 Mat mLhsMatrix;
00069 Mat mPrecondMatrix;
00070 Vec mRhsVector;
00071 PetscInt mSize;
00077 PetscInt mOwnershipRangeLo;
00078 PetscInt mOwnershipRangeHi;
00080 MatNullSpace mMatNullSpace;
00083 bool mDestroyMatAndVec;
00084
00085 KSP mKspSolver;
00086 bool mKspIsSetup;
00087 double mNonZerosUsed;
00088 bool mMatrixIsConstant;
00089 double mTolerance;
00094 bool mUseAbsoluteTolerance;
00095 std::string mKspType;
00096 std::string mPcType;
00098 Vec mDirichletBoundaryConditionsVector;
00100
00101
00102 PCBlockDiagonal* mpBlockDiagonalPC;
00104 PCLDUFactorisation* mpLDUFactorisationPC;
00106 PCTwoLevelsBlockDiagonal* mpTwoLevelsBlockDiagonalPC;
00107
00109 boost::shared_ptr<std::vector<PetscInt> > mpBathNodes;
00110
00112 bool mPrecondMatrixIsNotLhs;
00113
00115 unsigned mRowPreallocation;
00116
00118 bool mUseFixedNumberIterations;
00119
00125 unsigned mEvaluateNumItsEveryNSolves;
00126
00128 void* mpConvergenceTestContext;
00129
00131 unsigned mNumSolves;
00132
00134 PetscReal mEigMin;
00135
00137 PetscReal mEigMax;
00138
00140 bool mForceSpectrumReevaluation;
00141
00142 #ifdef TRACE_KSP
00143 unsigned mTotalNumIterations;
00144 unsigned mMaxNumIterations;
00145 #endif
00146
00147 friend class boost::serialization::access;
00154 template<class Archive>
00155 void serialize(Archive & archive, const unsigned int version)
00156 {
00157
00158
00159 archive & mNonZerosUsed;
00160 archive & mMatrixIsConstant;
00161 archive & mTolerance;
00162 archive & mUseAbsoluteTolerance;
00163 archive & mKspType;
00164 archive & mPcType;
00165
00166
00167 }
00168
00169 public:
00170
00181 LinearSystem(PetscInt lhsVectorSize, unsigned rowPreallocation=UINT_MAX);
00182
00196 LinearSystem(Vec templateVector, unsigned rowPreallocation);
00197
00210 LinearSystem(Vec residualVector, Mat jacobianMatrix);
00211
00219 LinearSystem(PetscInt lhsVectorSize, Mat lhsMatrix, Vec rhsVector);
00220
00224 ~LinearSystem();
00225
00226
00227
00228
00236 void SetMatrixElement(PetscInt row, PetscInt col, double value);
00237
00245 void AddToMatrixElement(PetscInt row, PetscInt col, double value);
00246
00252 void AssembleFinalLinearSystem();
00253
00259 void AssembleIntermediateLinearSystem();
00260
00264 void FinaliseLhsMatrix();
00265
00269 void FinalisePrecondMatrix();
00270
00274 void SwitchWriteModeLhsMatrix();
00275
00279 void FinaliseRhsVector();
00280
00286 void SetMatrixIsSymmetric(bool isSymmetric=true);
00287
00293 bool IsMatrixSymmetric();
00294
00300 void SetMatrixIsConstant(bool matrixIsConstant);
00301
00307 void SetRelativeTolerance(double relativeTolerance);
00308
00314 void SetAbsoluteTolerance(double absoluteTolerance);
00315
00321 void SetKspType(const char* kspType);
00322
00329
00330 void SetPcType(const char* pcType, boost::shared_ptr<std::vector<PetscInt> > pBathNodes=boost::shared_ptr<std::vector<PetscInt> >() );
00331
00335 void DisplayMatrix();
00336
00340 void DisplayRhs();
00341
00350 void SetMatrixRow(PetscInt row, double value);
00351
00358 Vec GetMatrixRowDistributed(unsigned rowIndex);
00359
00368 void ZeroMatrixRowsWithValueOnDiagonal(std::vector<unsigned>& rRows, double diagonalValue);
00369
00370
00378 void ZeroMatrixRowsAndColumnsWithValueOnDiagonal(std::vector<unsigned>& rRowColIndices, double diagonalValue);
00379
00380
00390 void ZeroMatrixColumn(PetscInt col);
00391
00395 void ZeroLhsMatrix();
00396
00400 void ZeroRhsVector();
00401
00405 void ZeroLinearSystem();
00406
00412 Vec Solve(Vec lhsGuess=NULL);
00413
00420 void SetRhsVectorElement(PetscInt row, double value);
00421
00428 void AddToRhsVectorElement(PetscInt row, double value);
00429
00433 unsigned GetSize() const;
00434
00446 void SetNullBasis(Vec nullbasis[], unsigned numberOfBases);
00447
00454 void RemoveNullSpace();
00455
00459 Vec& rGetRhsVector();
00460
00464 Vec GetRhsVector() const;
00465
00469 Mat& rGetLhsMatrix();
00470
00474 Mat GetLhsMatrix() const;
00475
00479 Mat& rGetPrecondMatrix();
00480
00486 Vec& rGetDirichletBoundaryConditionsVector();
00487
00488
00495 void GetOwnershipRange(PetscInt& lo, PetscInt& hi);
00496
00504 double GetMatrixElement(PetscInt row, PetscInt col);
00505
00512 double GetRhsVectorElement(PetscInt row);
00513
00517 unsigned GetNumIterations() const;
00518
00528 template<size_t MATRIX_SIZE>
00529 void AddLhsMultipleValues(unsigned* matrixRowAndColIndices, c_matrix<double, MATRIX_SIZE, MATRIX_SIZE>& rSmallMatrix)
00530 {
00531 PetscMatTools::AddMultipleValues(mLhsMatrix, matrixRowAndColIndices, rSmallMatrix);
00532 }
00533
00543 template<size_t VECTOR_SIZE>
00544 void AddRhsMultipleValues(unsigned* vectorIndices, c_vector<double, VECTOR_SIZE>& smallVector)
00545 {
00546 PetscVecTools::AddMultipleValues(mRhsVector, vectorIndices, smallVector);
00547 }
00548
00553 void SetPrecondMatrixIsDifferentFromLhs(bool precondIsDifferent = true);
00554
00560 void SetUseFixedNumberIterations(bool useFixedNumberIterations = true, unsigned evaluateNumItsEveryNSolves = UINT_MAX);
00561
00566 void ResetKspSolver();
00567 };
00568
00569 #include "SerializationExportWrapper.hpp"
00570
00571 CHASTE_CLASS_EXPORT(LinearSystem)
00572
00573 namespace boost
00574 {
00575 namespace serialization
00576 {
00577 template<class Archive>
00578 inline void save_construct_data(
00579 Archive & ar, const LinearSystem * t, const unsigned int file_version)
00580 {
00581
00582 std::string archive_filename_lhs = ArchiveLocationInfo::GetArchiveDirectory() + "lhs.mat";
00583 std::string archive_filename_rhs = ArchiveLocationInfo::GetArchiveDirectory() + "rhs.vec";
00584 const unsigned size = t->GetSize();
00585 ar << size;
00586
00587 PetscTools::DumpPetscObject(t->GetRhsVector(), archive_filename_rhs);
00588 PetscTools::DumpPetscObject(t->GetLhsMatrix(), archive_filename_lhs);
00589
00590
00591 PetscTruth symm_set, is_symmetric;
00592 is_symmetric = PETSC_FALSE;
00593
00594 MatIsSymmetricKnown(t->GetLhsMatrix(), &symm_set, &is_symmetric);
00595 assert(symm_set == is_symmetric);
00596 ar << symm_set;
00597 }
00598
00603 template<class Archive>
00604 inline void load_construct_data(
00605 Archive & ar, LinearSystem * t, const unsigned int file_version)
00606 {
00607 std::string archive_filename_lhs = ArchiveLocationInfo::GetArchiveDirectory() + "lhs.mat";
00608 std::string archive_filename_rhs = ArchiveLocationInfo::GetArchiveDirectory() + "rhs.vec";
00609
00610 PetscInt size;
00611 ar >> size;
00612
00613 Vec new_vec;
00614 PetscTools::ReadPetscObject(new_vec, archive_filename_rhs);
00615
00616 Mat new_mat;
00617 PetscTools::ReadPetscObject(new_mat, archive_filename_lhs);
00618
00619
00620
00621 PetscTruth symm_set;
00622 ar >> symm_set;
00623 if (symm_set == PETSC_TRUE)
00624 {
00625 PetscMatTools::SetOption(new_mat, MAT_SYMMETRIC);
00626 PetscMatTools::SetOption(new_mat, MAT_SYMMETRY_ETERNAL);
00627 }
00628
00629 ::new(t)LinearSystem(size, new_mat, new_vec);
00630 }
00631 }
00632 }
00633
00634 #endif //_LINEARSYSTEM_HPP_