Chaste Release::3.1
LinearSystem.hpp
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_