LinearSystem.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
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 
00030 #ifndef _LINEARSYSTEM_HPP_
00031 #define _LINEARSYSTEM_HPP_
00032 
00033 #include "UblasCustomFunctions.hpp"
00034 #include <petscvec.h>
00035 #include <petscmat.h>
00036 #include <petscksp.h>
00037 
00038 #include <string>
00039 
00045 class LinearSystem
00046 {
00047     friend class TestLinearSystem;
00048 
00049 private:
00050     Mat mLhsMatrix;
00051     Vec mRhsVector;
00052     PetscInt mSize;
00057     PetscInt mOwnershipRangeLo; 
00058     PetscInt mOwnershipRangeHi; 
00060     MatNullSpace mMatNullSpace;
00061 
00063     bool mDestroyMatAndVec;
00064 
00065     KSP mKspSolver;
00066     bool mKspIsSetup; //Used by Solve method to track whether KSP has been used
00067     double mNonZerosUsed; //Yes, it really is stored as a double.
00068     bool mMatrixIsConstant;
00069     double mTolerance;
00070     bool mUseAbsoluteTolerance;
00071     char mKspType[30];
00072     char mPcType[30];
00073 
00074     Vec mDirichletBoundaryConditionsVector; 
00076 public:
00077     LinearSystem(PetscInt lhsVectorSize, MatType matType=(MatType) MATMPIAIJ);
00078     LinearSystem(Vec templateVector);
00079     LinearSystem(Vec residualVector, Mat jacobianMatrix);
00080     ~LinearSystem();
00081 
00082 //    bool IsMatrixEqualTo(Mat testMatrix);
00083 //    bool IsRhsVectorEqualTo(Vec testVector);
00084     void SetMatrixElement(PetscInt row, PetscInt col, double value);
00085     void AddToMatrixElement(PetscInt row, PetscInt col, double value);
00086 
00087     void AssembleFinalLinearSystem();         // Call before solve
00088     void AssembleIntermediateLinearSystem();  // Should be called before AddToMatrixElement
00089     void AssembleFinalLhsMatrix();
00090     void AssembleIntermediateLhsMatrix();
00091     void AssembleRhsVector();
00092 
00093     void SetMatrixIsSymmetric();
00094     void SetMatrixIsConstant(bool matrixIsConstant);
00095     void SetRelativeTolerance(double relativeTolerance);
00096     void SetAbsoluteTolerance(double absoluteTolerance);
00097     void SetKspType(const char*);
00098     void SetPcType(const char*);
00099     void DisplayMatrix();
00100     void DisplayRhs();
00101     void SetMatrixRow(PetscInt row, double value);
00102     void ZeroMatrixRow(PetscInt row);
00103     void ZeroMatrixColumn(PetscInt col);
00104     void ZeroLhsMatrix();
00105     void ZeroRhsVector();
00106     void ZeroLinearSystem();
00107     Vec Solve(Vec lhsGuess=NULL);
00108     void SetRhsVectorElement(PetscInt row, double value);
00109     void AddToRhsVectorElement(PetscInt row, double value);
00110     unsigned GetSize();
00111     void SetNullBasis(Vec nullbasis[], unsigned numberOfBases);
00112     Vec& rGetRhsVector();
00113     Mat& rGetLhsMatrix();
00114     Vec& rGetDirichletBoundaryConditionsVector();
00115 
00116 
00117     // DEBUGGING CODE:
00118     void GetOwnershipRange(PetscInt &lo, PetscInt &hi);
00119     double GetMatrixElement(PetscInt row, PetscInt col);
00120     double GetRhsVectorElement(PetscInt row);
00121 
00122 
00123     /***
00124      * Add multiple values to the matrix of linear system
00125      * @param matrixRowAndColIndices mapping from index of the ublas matrix (see param below)
00126      *  to index of the Petsc matrix of this linear system
00127      * @param smallMatrix Ublas matrix containing the values to be added
00128      *
00129      * N.B. Values which are not local (ie the row is not owned) will be skipped.
00130      */
00131     template<size_t MATRIX_SIZE>
00132     void AddLhsMultipleValues(unsigned* matrixRowAndColIndices, c_matrix<double, MATRIX_SIZE, MATRIX_SIZE>& smallMatrix)
00133     {
00134         PetscInt matrix_row_indices[MATRIX_SIZE];
00135         PetscInt num_rows_owned=0;
00136         PetscInt global_row;
00137 
00138         for (unsigned row = 0; row<MATRIX_SIZE; row++)
00139         {
00140             global_row = matrixRowAndColIndices[row];
00141             if (global_row >=mOwnershipRangeLo && global_row <mOwnershipRangeHi)
00142             {
00143                 matrix_row_indices[num_rows_owned++] = global_row;
00144             }
00145         }
00146         
00147         if ( num_rows_owned == MATRIX_SIZE)
00148         {
00149             MatSetValues(mLhsMatrix,
00150                          num_rows_owned,
00151                          matrix_row_indices,
00152                          MATRIX_SIZE,
00153                          (PetscInt*) matrixRowAndColIndices,
00154                          smallMatrix.data(),
00155                          ADD_VALUES);
00156         }
00157         else
00158         {
00159             // We need continuous data, if some of the rows do not belong to the processor their values
00160             // are not passed to MatSetValues 
00161             double values[MATRIX_SIZE*MATRIX_SIZE];
00162             unsigned num_values_owned = 0;
00163             for (unsigned row = 0; row<MATRIX_SIZE; row++)
00164             {
00165                 global_row = matrixRowAndColIndices[row];
00166                 if (global_row >=mOwnershipRangeLo && global_row <mOwnershipRangeHi)
00167                 {
00168                     for (unsigned col=0; col<MATRIX_SIZE; col++)
00169                     {
00170                         values[num_values_owned++] = smallMatrix(row,col);
00171                     }
00172                 }
00173             }
00174             
00175             MatSetValues(mLhsMatrix,
00176                          num_rows_owned,
00177                          matrix_row_indices,
00178                          MATRIX_SIZE,
00179                          (PetscInt*) matrixRowAndColIndices,
00180                          values,
00181                          ADD_VALUES);           
00182         }
00183     };
00184 
00185 
00186     /***
00187      * Add multiple values to the RHS vector
00188      * @param vectorIndices mapping from index of the ublas vector (see param below)
00189      *  to index of the vector of this linear system
00190      * @param smallVector Ublas vector containing the values to be added
00191      *
00192      * N.B. Values which are not local (ie the row is not owned) will be skipped.
00193      */
00194     template<size_t VECTOR_SIZE>
00195     void AddRhsMultipleValues(unsigned* VectorIndices, c_vector<double, VECTOR_SIZE>& smallVector)
00196     {
00197         PetscInt indices_owned[VECTOR_SIZE];
00198         PetscInt num_indices_owned=0;
00199         PetscInt global_row;
00200 
00201         for (unsigned row = 0; row<VECTOR_SIZE; row++)
00202         {
00203             global_row = VectorIndices[row];
00204             if (global_row >=mOwnershipRangeLo && global_row <mOwnershipRangeHi)
00205             {
00206                 indices_owned[num_indices_owned++] = global_row;
00207             }
00208         }
00209         
00210         if (num_indices_owned == VECTOR_SIZE)
00211         {
00212             VecSetValues(mRhsVector,
00213                          num_indices_owned,
00214                          indices_owned,
00215                          smallVector.data(),
00216                          ADD_VALUES);
00217         }
00218         else
00219         {
00220             // We need continuous data, if some of the rows do not belong to the processor their values
00221             // are not passed to MatSetValues 
00222             double values[VECTOR_SIZE];
00223             unsigned num_values_owned = 0;
00224             
00225             for (unsigned row = 0; row<VECTOR_SIZE; row++)
00226             {
00227                 global_row = VectorIndices[row];
00228                 if (global_row >=mOwnershipRangeLo && global_row <mOwnershipRangeHi)
00229                 {
00230                     values[num_values_owned++] = smallVector(row);
00231                 }
00232             }
00233             
00234             VecSetValues(mRhsVector,
00235                          num_indices_owned,
00236                          indices_owned,
00237                          values,
00238                          ADD_VALUES);                                   
00239         }
00240     }
00241 };
00242 
00243 #endif //_LINEARSYSTEM_HPP_

Generated on Wed Mar 18 12:51:52 2009 for Chaste by  doxygen 1.5.5