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
00030
00031
00032
00033
00034
00035
00036 #ifndef _LINEARSYSTEM_HPP_
00037 #define _LINEARSYSTEM_HPP_
00038
00039 #include "ChasteSerialization.hpp"
00040 #include "UblasCustomFunctions.hpp"
00041
00042 #include "PetscTools.hpp"
00043 #include "PetscVecTools.hpp"
00044 #include "PetscMatTools.hpp"
00045 #include "OutputFileHandler.hpp"
00046 #include "PCBlockDiagonal.hpp"
00047 #include "PCLDUFactorisation.hpp"
00048 #include "PCTwoLevelsBlockDiagonal.hpp"
00049 #include "ArchiveLocationInfo.hpp"
00050
00051
00052 #include <petscvec.h>
00053 #include <petscmat.h>
00054 #include <petscksp.h>
00055 #include <petscviewer.h>
00056
00057 #include <string>
00058 #include <cassert>
00059
00065 class LinearSystem
00066 {
00067 friend class TestLinearSystem;
00068 friend class TestPCBlockDiagonal;
00069 friend class TestPCTwoLevelsBlockDiagonal;
00070 friend class TestPCLDUFactorisation;
00071 friend class TestChebyshevIteration;
00072
00073 private:
00074
00075 Mat mLhsMatrix;
00076 Mat mPrecondMatrix;
00077 Vec mRhsVector;
00078 PetscInt mSize;
00084 PetscInt mOwnershipRangeLo;
00085 PetscInt mOwnershipRangeHi;
00087 MatNullSpace mMatNullSpace;
00090 bool mDestroyMatAndVec;
00091
00092 KSP mKspSolver;
00093 bool mKspIsSetup;
00094 double mNonZerosUsed;
00095 bool mMatrixIsConstant;
00096 double mTolerance;
00101 bool mUseAbsoluteTolerance;
00102 std::string mKspType;
00103 std::string mPcType;
00105 Vec mDirichletBoundaryConditionsVector;
00107
00108
00109 PCBlockDiagonal* mpBlockDiagonalPC;
00111 PCLDUFactorisation* mpLDUFactorisationPC;
00113 PCTwoLevelsBlockDiagonal* mpTwoLevelsBlockDiagonalPC;
00114
00116 boost::shared_ptr<std::vector<PetscInt> > mpBathNodes;
00117
00119 bool mPrecondMatrixIsNotLhs;
00120
00122 unsigned mRowPreallocation;
00123
00125 bool mUseFixedNumberIterations;
00126
00132 unsigned mEvaluateNumItsEveryNSolves;
00133
00135 void* mpConvergenceTestContext;
00136
00138 unsigned mNumSolves;
00139
00141 PetscReal mEigMin;
00142
00144 PetscReal mEigMax;
00145
00147 bool mForceSpectrumReevaluation;
00148
00149 #ifdef TRACE_KSP
00150 unsigned mTotalNumIterations;
00151 unsigned mMaxNumIterations;
00152 #endif
00153
00154 friend class boost::serialization::access;
00161 template<class Archive>
00162 void serialize(Archive & archive, const unsigned int version)
00163 {
00164
00165
00166 archive & mNonZerosUsed;
00167 archive & mMatrixIsConstant;
00168 archive & mTolerance;
00169 archive & mUseAbsoluteTolerance;
00170 archive & mKspType;
00171 archive & mPcType;
00172
00173
00174 }
00175
00176 public:
00177
00188 LinearSystem(PetscInt lhsVectorSize, unsigned rowPreallocation=UINT_MAX);
00189
00207 LinearSystem(Vec templateVector, unsigned rowPreallocation, bool newAllocationError=true);
00208
00221 LinearSystem(Vec residualVector, Mat jacobianMatrix);
00222
00230 LinearSystem(PetscInt lhsVectorSize, Mat lhsMatrix, Vec rhsVector);
00231
00235 ~LinearSystem();
00236
00237
00238
00239
00247 void SetMatrixElement(PetscInt row, PetscInt col, double value);
00248
00256 void AddToMatrixElement(PetscInt row, PetscInt col, double value);
00257
00263 void AssembleFinalLinearSystem();
00264
00270 void AssembleIntermediateLinearSystem();
00271
00275 void FinaliseLhsMatrix();
00276
00280 void FinalisePrecondMatrix();
00281
00285 void SwitchWriteModeLhsMatrix();
00286
00290 void FinaliseRhsVector();
00291
00297 void SetMatrixIsSymmetric(bool isSymmetric=true);
00298
00304 bool IsMatrixSymmetric();
00305
00311 void SetMatrixIsConstant(bool matrixIsConstant);
00312
00318 void SetRelativeTolerance(double relativeTolerance);
00319
00325 void SetAbsoluteTolerance(double absoluteTolerance);
00326
00332 void SetKspType(const char* kspType);
00333
00340
00341 void SetPcType(const char* pcType, boost::shared_ptr<std::vector<PetscInt> > pBathNodes=boost::shared_ptr<std::vector<PetscInt> >() );
00342
00346 void DisplayMatrix();
00347
00351 void DisplayRhs();
00352
00361 void SetMatrixRow(PetscInt row, double value);
00362
00369 Vec GetMatrixRowDistributed(unsigned rowIndex);
00370
00379 void ZeroMatrixRowsWithValueOnDiagonal(std::vector<unsigned>& rRows, double diagonalValue);
00380
00381
00389 void ZeroMatrixRowsAndColumnsWithValueOnDiagonal(std::vector<unsigned>& rRowColIndices, double diagonalValue);
00390
00391
00401 void ZeroMatrixColumn(PetscInt col);
00402
00406 void ZeroLhsMatrix();
00407
00411 void ZeroRhsVector();
00412
00416 void ZeroLinearSystem();
00417
00423 Vec Solve(Vec lhsGuess=NULL);
00424
00431 void SetRhsVectorElement(PetscInt row, double value);
00432
00439 void AddToRhsVectorElement(PetscInt row, double value);
00440
00444 unsigned GetSize() const;
00445
00457 void SetNullBasis(Vec nullbasis[], unsigned numberOfBases);
00458
00465 void RemoveNullSpace();
00466
00470 Vec& rGetRhsVector();
00471
00475 Vec GetRhsVector() const;
00476
00480 Mat& rGetLhsMatrix();
00481
00485 Mat GetLhsMatrix() const;
00486
00490 Mat& rGetPrecondMatrix();
00491
00497 Vec& rGetDirichletBoundaryConditionsVector();
00498
00499
00506 void GetOwnershipRange(PetscInt& lo, PetscInt& hi);
00507
00515 double GetMatrixElement(PetscInt row, PetscInt col);
00516
00523 double GetRhsVectorElement(PetscInt row);
00524
00528 unsigned GetNumIterations() const;
00529
00539 template<size_t MATRIX_SIZE>
00540 void AddLhsMultipleValues(unsigned* matrixRowAndColIndices, c_matrix<double, MATRIX_SIZE, MATRIX_SIZE>& rSmallMatrix)
00541 {
00542 PetscMatTools::AddMultipleValues(mLhsMatrix, matrixRowAndColIndices, rSmallMatrix);
00543 }
00544
00554 template<size_t VECTOR_SIZE>
00555 void AddRhsMultipleValues(unsigned* vectorIndices, c_vector<double, VECTOR_SIZE>& smallVector)
00556 {
00557 PetscVecTools::AddMultipleValues(mRhsVector, vectorIndices, smallVector);
00558 }
00559
00564 void SetPrecondMatrixIsDifferentFromLhs(bool precondIsDifferent = true);
00565
00571 void SetUseFixedNumberIterations(bool useFixedNumberIterations = true, unsigned evaluateNumItsEveryNSolves = UINT_MAX);
00572
00577 void ResetKspSolver();
00578 };
00579
00580 #include "SerializationExportWrapper.hpp"
00581
00582 CHASTE_CLASS_EXPORT(LinearSystem)
00583
00584 namespace boost
00585 {
00586 namespace serialization
00587 {
00588 template<class Archive>
00589 inline void save_construct_data(
00590 Archive & ar, const LinearSystem * t, const unsigned int file_version)
00591 {
00592
00593 std::string archive_filename_lhs = ArchiveLocationInfo::GetArchiveDirectory() + "lhs.mat";
00594 std::string archive_filename_rhs = ArchiveLocationInfo::GetArchiveDirectory() + "rhs.vec";
00595 const unsigned size = t->GetSize();
00596 ar << size;
00597
00598 PetscTools::DumpPetscObject(t->GetRhsVector(), archive_filename_rhs);
00599 PetscTools::DumpPetscObject(t->GetLhsMatrix(), archive_filename_lhs);
00600
00601
00602 PetscBool symm_set, is_symmetric;
00603 is_symmetric = PETSC_FALSE;
00604
00605 MatIsSymmetricKnown(t->GetLhsMatrix(), &symm_set, &is_symmetric);
00606 assert(symm_set == is_symmetric);
00607 ar << symm_set;
00608 }
00609
00614 template<class Archive>
00615 inline void load_construct_data(
00616 Archive & ar, LinearSystem * t, const unsigned int file_version)
00617 {
00618 std::string archive_filename_lhs = ArchiveLocationInfo::GetArchiveDirectory() + "lhs.mat";
00619 std::string archive_filename_rhs = ArchiveLocationInfo::GetArchiveDirectory() + "rhs.vec";
00620
00621 PetscInt size;
00622 ar >> size;
00623
00624 Vec new_vec;
00625 PetscTools::ReadPetscObject(new_vec, archive_filename_rhs);
00626
00627 Mat new_mat;
00628 PetscTools::ReadPetscObject(new_mat, archive_filename_lhs);
00629
00630
00631
00632 PetscBool symm_set;
00633
00634 ar >> symm_set;
00635 if (symm_set == PETSC_TRUE)
00636 {
00637 PetscMatTools::SetOption(new_mat, MAT_SYMMETRIC);
00638 PetscMatTools::SetOption(new_mat, MAT_SYMMETRY_ETERNAL);
00639 }
00640
00641 ::new(t)LinearSystem(size, new_mat, new_vec);
00642 }
00643 }
00644 }
00645
00646 #endif //_LINEARSYSTEM_HPP_