LinearSystem.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #ifndef _LINEARSYSTEM_HPP_
00030 #define _LINEARSYSTEM_HPP_
00031 
00032 #include "ChasteSerialization.hpp"
00033 #include "UblasCustomFunctions.hpp" // needs to be 'first'
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         //MatNullSpace mMatNullSpace; // Gets re-created by calling code on load
00158 
00159         archive & mNonZerosUsed;
00160         archive & mMatrixIsConstant;
00161         archive & mTolerance;
00162         archive & mUseAbsoluteTolerance;
00163         archive & mKspType;
00164         archive & mPcType;
00165 
00166         //Vec mDirichletBoundaryConditionsVector; // Gets re-created by calling code on load
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 //    bool IsMatrixEqualTo(Mat testMatrix);
00227 //    bool IsRhsVectorEqualTo(Vec testVector);
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     // DEBUGGING CODE:
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 // Declare identifier for the serializer
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     //Is the matrix structurally symmetric?
00591     PetscTruth symm_set, is_symmetric;
00592     is_symmetric = PETSC_FALSE;
00593     //Note that the following call only changes is_symmetric when symm_set is true
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      //This has to occur after the call to MatLoad as the matrix does not exist until MatLoad is called.
00620      //The property will be copied & set correctly in the LinearSystem constructor.
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 } // namespace ...
00633 
00634 #endif //_LINEARSYSTEM_HPP_
Generated on Thu Dec 22 13:00:07 2011 for Chaste by  doxygen 1.6.3