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 #include "PetscMatTools.hpp"
00030 #include <cassert>
00031
00032
00034
00036
00037 void PetscMatTools::SetElement(Mat matrix, PetscInt row, PetscInt col, double value)
00038 {
00039 PetscInt lo, hi;
00040 GetOwnershipRange(matrix, lo, hi);
00041
00042 if (row >= lo && row < hi)
00043 {
00044 MatSetValue(matrix, row, col, value, INSERT_VALUES);
00045 }
00046 }
00047
00048 void PetscMatTools::AddToElement(Mat matrix, PetscInt row, PetscInt col, double value)
00049 {
00050 PetscInt lo, hi;
00051 GetOwnershipRange(matrix, lo, hi);
00052
00053 if (row >= lo && row < hi)
00054 {
00055 MatSetValue(matrix, row, col, value, ADD_VALUES);
00056 }
00057 }
00058
00059 void PetscMatTools::AssembleFinal(Mat matrix)
00060 {
00061 MatAssemblyBegin(matrix, MAT_FINAL_ASSEMBLY);
00062 MatAssemblyEnd(matrix, MAT_FINAL_ASSEMBLY);
00063 }
00064
00065 void PetscMatTools::AssembleIntermediate(Mat matrix)
00066 {
00067 MatAssemblyBegin(matrix, MAT_FLUSH_ASSEMBLY);
00068 MatAssemblyEnd(matrix, MAT_FLUSH_ASSEMBLY);
00069 }
00070
00071 void PetscMatTools::Display(Mat matrix)
00072 {
00073 MatView(matrix,PETSC_VIEWER_STDOUT_WORLD);
00074 }
00075
00076 void PetscMatTools::SetRow(Mat matrix, PetscInt row, double value)
00077 {
00078 PetscInt lo, hi;
00079 GetOwnershipRange(matrix, lo, hi);
00080
00081 if (row >= lo && row < hi)
00082 {
00083 PetscInt rows, cols;
00084 MatGetSize(matrix, &rows, &cols);
00085 for (PetscInt i=0; i<cols; i++)
00086 {
00087 SetElement(matrix, row, i, value);
00088 }
00089 }
00090 }
00091
00092 void PetscMatTools::ZeroRowsWithValueOnDiagonal(Mat matrix, std::vector<unsigned>& rRows, double diagonalValue)
00093 {
00094 AssembleFinal(matrix);
00095
00096
00097
00098
00099
00100 #if (PETSC_VERSION_MAJOR == 3) //PETSc 3.x.x
00101 #if (PETSC_VERSION_MINOR == 0)
00102 MatSetOption(matrix, MAT_KEEP_ZEROED_ROWS, PETSC_TRUE);
00103 #else
00104 MatSetOption(matrix, MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
00105 #endif
00106 #else
00107 MatSetOption(matrix, MAT_KEEP_ZEROED_ROWS);
00108 #endif
00109
00110 PetscInt* rows = new PetscInt[rRows.size()];
00111 for(unsigned i=0; i<rRows.size(); i++)
00112 {
00113 rows[i] = rRows[i];
00114 }
00115 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00116 IS is;
00117 ISCreateGeneral(PETSC_COMM_WORLD, rRows.size(), rows, &is);
00118 MatZeroRows(matrix, is, &diagonalValue);
00119 ISDestroy(is);
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 #else
00163 MatZeroRows(matrix, rRows.size(), rows, diagonalValue);
00164 #endif
00165 delete [] rows;
00166 }
00167
00168
00169 void PetscMatTools::ZeroRowsAndColumnsWithValueOnDiagonal(Mat matrix, std::vector<unsigned>& rRowColIndices, double diagonalValue)
00170 {
00171 AssembleFinal(matrix);
00172
00173 PetscInt lo, hi;
00174 GetOwnershipRange(matrix, lo, hi);
00175 std::vector<unsigned>* p_nonzero_rows_per_column = new std::vector<unsigned>[rRowColIndices.size()];
00176
00177
00178
00179
00180
00181 for(unsigned index=0; index<rRowColIndices.size(); index++)
00182 {
00183 unsigned column = rRowColIndices[index];
00184
00185
00186
00187 for (PetscInt row = lo; row < hi; row++)
00188 {
00189 if (GetElement(matrix, row, column) != 0.0)
00190 {
00191 p_nonzero_rows_per_column[index].push_back(row);
00192 }
00193 }
00194 }
00195
00196
00197 for(unsigned index=0; index<rRowColIndices.size(); index++)
00198 {
00199
00200 unsigned size = p_nonzero_rows_per_column[index].size();
00201 PetscInt* rows = new PetscInt[size];
00202 PetscInt cols[1];
00203 double* zeros = new double[size];
00204
00205 cols[0] = rRowColIndices[index];
00206
00207 for (unsigned i=0; i<size; i++)
00208 {
00209 rows[i] = p_nonzero_rows_per_column[index][i];
00210 zeros[i] = 0.0;
00211 }
00212
00213 MatSetValues(matrix, size, rows, 1, cols, zeros, INSERT_VALUES);
00214 delete [] rows;
00215 delete [] zeros;
00216 }
00217 delete[] p_nonzero_rows_per_column;
00218
00219
00220 ZeroRowsWithValueOnDiagonal(matrix, rRowColIndices, diagonalValue);
00221 }
00222
00223 void PetscMatTools::ZeroColumn(Mat matrix, PetscInt col)
00224 {
00225 AssembleFinal(matrix);
00226
00227 PetscInt lo, hi;
00228 GetOwnershipRange(matrix, lo, hi);
00229
00230
00231
00232 std::vector<unsigned> nonzero_rows;
00233 for (PetscInt row = lo; row < hi; row++)
00234 {
00235 if (GetElement(matrix, row, col) != 0.0)
00236 {
00237 nonzero_rows.push_back(row);
00238 }
00239 }
00240
00241
00242 unsigned size = nonzero_rows.size();
00243 PetscInt* rows = new PetscInt[size];
00244 PetscInt cols[1];
00245 double* zeros = new double[size];
00246
00247 cols[0] = col;
00248
00249 for (unsigned i=0; i<size; i++)
00250 {
00251 rows[i] = nonzero_rows[i];
00252 zeros[i] = 0.0;
00253 }
00254
00255 MatSetValues(matrix, size, rows, 1, cols, zeros, INSERT_VALUES);
00256 delete [] rows;
00257 delete [] zeros;
00258 }
00259
00260 void PetscMatTools::Zero(Mat matrix)
00261 {
00262 MatZeroEntries(matrix);
00263 }
00264
00265 unsigned PetscMatTools::GetSize(Mat matrix)
00266 {
00267 PetscInt rows, cols;
00268
00269 MatGetSize(matrix, &rows, &cols);
00270 assert(rows == cols);
00271 return (unsigned) rows;
00272 }
00273
00274 void PetscMatTools::GetOwnershipRange(Mat matrix, PetscInt& lo, PetscInt& hi)
00275 {
00276 MatGetOwnershipRange(matrix, &lo, &hi);
00277 }
00278
00279 double PetscMatTools::GetElement(Mat matrix, PetscInt row, PetscInt col)
00280 {
00281 PetscInt lo, hi;
00282 GetOwnershipRange(matrix, lo, hi);
00283
00284 assert(lo <= row && row < hi);
00285 PetscInt row_as_array[1];
00286 row_as_array[0] = row;
00287 PetscInt col_as_array[1];
00288 col_as_array[0] = col;
00289
00290 double ret_array[1];
00291
00292 MatGetValues(matrix, 1, row_as_array, 1, col_as_array, ret_array);
00293
00294 return ret_array[0];
00295 }
00296
00297
00298 void PetscMatTools::SetOption(Mat matrix, MatOption option)
00299 {
00300 #if (PETSC_VERSION_MAJOR == 3) //PETSc 3.x.x
00301 MatSetOption(matrix, option, PETSC_TRUE);
00302 #else
00303 MatSetOption(matrix, option);
00304 #endif
00305 }
00306
00307
00308
00309 Vec PetscMatTools::GetMatrixRowDistributed(Mat matrix, unsigned rowIndex)
00310 {
00311
00312
00313
00314 PetscInt lo, hi;
00315 PetscMatTools::GetOwnershipRange(matrix, lo, hi);
00316 unsigned size = PetscMatTools::GetSize(matrix);
00317
00318 Vec mat_ith_row = PetscTools::CreateVec(size, hi-lo, false);
00319
00320 PetscInt num_entries;
00321 const PetscInt* column_indices;
00322 const PetscScalar* values;
00323
00324 bool am_row_owner = (PetscInt)rowIndex >= lo && (PetscInt)rowIndex < hi;
00325
00326
00327
00328 if (am_row_owner)
00329 {
00330 MatGetRow(matrix, rowIndex, &num_entries, &column_indices, &values);
00331 VecSetValues(mat_ith_row, num_entries, column_indices, values, INSERT_VALUES);
00332 }
00333
00334 VecAssemblyBegin(mat_ith_row);
00335 VecAssemblyEnd(mat_ith_row);
00336
00337 if (am_row_owner)
00338 {
00339 MatRestoreRow(matrix, rowIndex, &num_entries, &column_indices, &values);
00340 }
00341
00342 return mat_ith_row;
00343 }