LinearSystem.hpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, 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 
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 //    bool IsMatrixEqualTo(Mat testMatrix);
00238 //    bool IsRhsVectorEqualTo(Vec testVector);
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     // DEBUGGING CODE:
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 // Declare identifier for the serializer
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     //Is the matrix structurally symmetric?
00602     PetscBool symm_set, is_symmetric;
00603     is_symmetric = PETSC_FALSE;
00604     //Note that the following call only changes is_symmetric when symm_set is true
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      //This has to occur after the call to MatLoad as the matrix does not exist until MatLoad is called.
00631      //The property will be copied & set correctly in the LinearSystem constructor.
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 } // namespace ...
00645 
00646 #endif //_LINEARSYSTEM_HPP_

Generated by  doxygen 1.6.2