Chaste Release::3.1
|
00001 /* 00002 00003 Copyright (c) 2005-2012, University of Oxford. 00004 All rights reserved. 00005 00006 University of Oxford means the Chancellor, Masters and Scholars of the 00007 University of Oxford, having an administrative office at Wellington 00008 Square, Oxford OX1 2JD, UK. 00009 00010 This file is part of Chaste. 00011 00012 Redistribution and use in source and binary forms, with or without 00013 modification, are permitted provided that the following conditions are met: 00014 * Redistributions of source code must retain the above copyright notice, 00015 this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright notice, 00017 this list of conditions and the following disclaimer in the documentation 00018 and/or other materials provided with the distribution. 00019 * Neither the name of the University of Oxford nor the names of its 00020 contributors may be used to endorse or promote products derived from this 00021 software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 */ 00035 00036 #ifndef _LINEARSYSTEM_HPP_ 00037 #define _LINEARSYSTEM_HPP_ 00038 00039 #include "ChasteSerialization.hpp" 00040 #include "UblasCustomFunctions.hpp" // needs to be 'first' 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 #include <boost/serialization/shared_ptr.hpp> 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 //MatNullSpace mMatNullSpace; // Gets re-created by calling code on load 00165 00166 archive & mNonZerosUsed; 00167 archive & mMatrixIsConstant; 00168 archive & mTolerance; 00169 archive & mUseAbsoluteTolerance; 00170 archive & mKspType; 00171 archive & mPcType; 00172 00173 //Vec mDirichletBoundaryConditionsVector; // Gets re-created by calling code on load 00174 } 00175 00176 public: 00177 00188 LinearSystem(PetscInt lhsVectorSize, unsigned rowPreallocation=UINT_MAX); 00189 00203 LinearSystem(Vec templateVector, unsigned rowPreallocation); 00204 00217 LinearSystem(Vec residualVector, Mat jacobianMatrix); 00218 00226 LinearSystem(PetscInt lhsVectorSize, Mat lhsMatrix, Vec rhsVector); 00227 00231 ~LinearSystem(); 00232 00233 // bool IsMatrixEqualTo(Mat testMatrix); 00234 // bool IsRhsVectorEqualTo(Vec testVector); 00235 00243 void SetMatrixElement(PetscInt row, PetscInt col, double value); 00244 00252 void AddToMatrixElement(PetscInt row, PetscInt col, double value); 00253 00259 void AssembleFinalLinearSystem(); 00260 00266 void AssembleIntermediateLinearSystem(); 00267 00271 void FinaliseLhsMatrix(); 00272 00276 void FinalisePrecondMatrix(); 00277 00281 void SwitchWriteModeLhsMatrix(); 00282 00286 void FinaliseRhsVector(); 00287 00293 void SetMatrixIsSymmetric(bool isSymmetric=true); 00294 00300 bool IsMatrixSymmetric(); 00301 00307 void SetMatrixIsConstant(bool matrixIsConstant); 00308 00314 void SetRelativeTolerance(double relativeTolerance); 00315 00321 void SetAbsoluteTolerance(double absoluteTolerance); 00322 00328 void SetKspType(const char* kspType); 00329 00336 00337 void SetPcType(const char* pcType, boost::shared_ptr<std::vector<PetscInt> > pBathNodes=boost::shared_ptr<std::vector<PetscInt> >() ); 00338 00342 void DisplayMatrix(); 00343 00347 void DisplayRhs(); 00348 00357 void SetMatrixRow(PetscInt row, double value); 00358 00365 Vec GetMatrixRowDistributed(unsigned rowIndex); 00366 00375 void ZeroMatrixRowsWithValueOnDiagonal(std::vector<unsigned>& rRows, double diagonalValue); 00376 00377 00385 void ZeroMatrixRowsAndColumnsWithValueOnDiagonal(std::vector<unsigned>& rRowColIndices, double diagonalValue); 00386 00387 00397 void ZeroMatrixColumn(PetscInt col); 00398 00402 void ZeroLhsMatrix(); 00403 00407 void ZeroRhsVector(); 00408 00412 void ZeroLinearSystem(); 00413 00419 Vec Solve(Vec lhsGuess=NULL); 00420 00427 void SetRhsVectorElement(PetscInt row, double value); 00428 00435 void AddToRhsVectorElement(PetscInt row, double value); 00436 00440 unsigned GetSize() const; 00441 00453 void SetNullBasis(Vec nullbasis[], unsigned numberOfBases); 00454 00461 void RemoveNullSpace(); 00462 00466 Vec& rGetRhsVector(); 00467 00471 Vec GetRhsVector() const; 00472 00476 Mat& rGetLhsMatrix(); 00477 00481 Mat GetLhsMatrix() const; 00482 00486 Mat& rGetPrecondMatrix(); 00487 00493 Vec& rGetDirichletBoundaryConditionsVector(); 00494 00495 // DEBUGGING CODE: 00502 void GetOwnershipRange(PetscInt& lo, PetscInt& hi); 00503 00511 double GetMatrixElement(PetscInt row, PetscInt col); 00512 00519 double GetRhsVectorElement(PetscInt row); 00520 00524 unsigned GetNumIterations() const; 00525 00535 template<size_t MATRIX_SIZE> 00536 void AddLhsMultipleValues(unsigned* matrixRowAndColIndices, c_matrix<double, MATRIX_SIZE, MATRIX_SIZE>& rSmallMatrix) 00537 { 00538 PetscMatTools::AddMultipleValues(mLhsMatrix, matrixRowAndColIndices, rSmallMatrix); 00539 } 00540 00550 template<size_t VECTOR_SIZE> 00551 void AddRhsMultipleValues(unsigned* vectorIndices, c_vector<double, VECTOR_SIZE>& smallVector) 00552 { 00553 PetscVecTools::AddMultipleValues(mRhsVector, vectorIndices, smallVector); 00554 } 00555 00560 void SetPrecondMatrixIsDifferentFromLhs(bool precondIsDifferent = true); 00561 00567 void SetUseFixedNumberIterations(bool useFixedNumberIterations = true, unsigned evaluateNumItsEveryNSolves = UINT_MAX); 00568 00573 void ResetKspSolver(); 00574 }; 00575 00576 #include "SerializationExportWrapper.hpp" 00577 // Declare identifier for the serializer 00578 CHASTE_CLASS_EXPORT(LinearSystem) 00579 00580 namespace boost 00581 { 00582 namespace serialization 00583 { 00584 template<class Archive> 00585 inline void save_construct_data( 00586 Archive & ar, const LinearSystem * t, const unsigned int file_version) 00587 { 00588 00589 std::string archive_filename_lhs = ArchiveLocationInfo::GetArchiveDirectory() + "lhs.mat"; 00590 std::string archive_filename_rhs = ArchiveLocationInfo::GetArchiveDirectory() + "rhs.vec"; 00591 const unsigned size = t->GetSize(); 00592 ar << size; 00593 00594 PetscTools::DumpPetscObject(t->GetRhsVector(), archive_filename_rhs); 00595 PetscTools::DumpPetscObject(t->GetLhsMatrix(), archive_filename_lhs); 00596 00597 //Is the matrix structurally symmetric? 00598 PetscTruth symm_set, is_symmetric; 00599 is_symmetric = PETSC_FALSE; 00600 //Note that the following call only changes is_symmetric when symm_set is true 00601 MatIsSymmetricKnown(t->GetLhsMatrix(), &symm_set, &is_symmetric); 00602 assert(symm_set == is_symmetric); 00603 ar << symm_set; 00604 } 00605 00610 template<class Archive> 00611 inline void load_construct_data( 00612 Archive & ar, LinearSystem * t, const unsigned int file_version) 00613 { 00614 std::string archive_filename_lhs = ArchiveLocationInfo::GetArchiveDirectory() + "lhs.mat"; 00615 std::string archive_filename_rhs = ArchiveLocationInfo::GetArchiveDirectory() + "rhs.vec"; 00616 00617 PetscInt size; 00618 ar >> size; 00619 00620 Vec new_vec; 00621 PetscTools::ReadPetscObject(new_vec, archive_filename_rhs); 00622 00623 Mat new_mat; 00624 PetscTools::ReadPetscObject(new_mat, archive_filename_lhs); 00625 00626 //This has to occur after the call to MatLoad as the matrix does not exist until MatLoad is called. 00627 //The property will be copied & set correctly in the LinearSystem constructor. 00628 PetscTruth symm_set; 00629 00630 ar >> symm_set; 00631 if (symm_set == PETSC_TRUE) 00632 { 00633 PetscMatTools::SetOption(new_mat, MAT_SYMMETRIC); 00634 PetscMatTools::SetOption(new_mat, MAT_SYMMETRY_ETERNAL); 00635 } 00636 00637 ::new(t)LinearSystem(size, new_mat, new_vec); 00638 } 00639 } 00640 } // namespace ... 00641 00642 #endif //_LINEARSYSTEM_HPP_