00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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;
00067 double mNonZerosUsed;
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
00083
00084 void SetMatrixElement(PetscInt row, PetscInt col, double value);
00085 void AddToMatrixElement(PetscInt row, PetscInt col, double value);
00086
00087 void AssembleFinalLinearSystem();
00088 void AssembleIntermediateLinearSystem();
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
00118 void GetOwnershipRange(PetscInt &lo, PetscInt &hi);
00119 double GetMatrixElement(PetscInt row, PetscInt col);
00120 double GetRhsVectorElement(PetscInt row);
00121
00122
00123
00124
00125
00126
00127
00128
00129
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
00160
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
00188
00189
00190
00191
00192
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
00221
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_