EpetraExt Development
Loading...
Searching...
No Matches
EpetraExt_PETScAIJMatrix.cpp
Go to the documentation of this file.
1//@HEADER
2// ***********************************************************************
3//
4// EpetraExt: Epetra Extended - Linear Algebra Services Package
5// Copyright (2011) Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8// the U.S. Government retains certain rights in this software.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38//
39// ***********************************************************************
40//@HEADER
41
42/*#############################################################################
43# CVS File Information
44# Current revision: $Revision$
45# Last modified: $Date$
46# Modified by: $Author$
47#############################################################################*/
48
50#ifdef HAVE_PETSC
51
52#include "Epetra_Import.h"
53#include "Epetra_Export.h"
54#include "Epetra_Vector.h"
55#include "Epetra_MultiVector.h"
57
58//==============================================================================
60 : Amat_(Amat),
61 Epetra_Object("Epetra::PETScAIJMatrix"),
62 Values_(0),
63 Indices_(0),
64 MaxNumEntries_(-1),
65 ImportVector_(0),
66 NormInf_(-1.0),
67 NormOne_(-1.0),
68 Comm_(0),
69 DomainMap_(0),
70 ColMap_(0),
71 Importer_(0),
72 NumGlobalNonzeros_(0),
73 NumMyNonzeros_(0),
74 NumMyRows_(0),
75 NumGlobalRows_(0),
76 NumMyCols_(0),
77 PetscRowStart_(0),
78 PetscRowEnd_(0),
79 MatType_(" ")
80{
81#ifdef HAVE_MPI
82 MPI_Comm comm;
83 PetscObjectGetComm( (PetscObject)Amat, &comm);
84 Comm_ = new Epetra_MpiComm(comm);
85#else
86 Comm_ = new Epetra_SerialComm();
87#endif
88 int ierr;
89 char errMsg[80];
90 //MatGetType(Amat, const_cast<const char**>(&MatType_));
91 MatGetType(Amat, &MatType_);
92 if ( strcmp(MatType_,MATSEQAIJ) != 0 && strcmp(MatType_,MATMPIAIJ) != 0 ) {
93 sprintf(errMsg,"PETSc matrix must be either seqaij or mpiaij (but it is %s)",MatType_);
94 throw Comm_->ReportError(errMsg,-1);
95 }
96 petscMatrixType mt;
97 Mat_MPIAIJ* aij=0;
98 if (strcmp(MatType_,MATMPIAIJ) == 0) {
99 mt = PETSC_MPI_AIJ;
100 aij = (Mat_MPIAIJ*)Amat->data;
101 }
102 else if (strcmp(MatType_,MATSEQAIJ) == 0) {
103 mt = PETSC_SEQ_AIJ;
104 }
105 int numLocalRows, numLocalCols;
106 ierr = MatGetLocalSize(Amat,&numLocalRows,&numLocalCols);
107 if (ierr) {
108 sprintf(errMsg,"EpetraExt_PETScAIJMatrix.cpp, line %d, MatGetLocalSize() returned error code %d",__LINE__,ierr);
109 throw Comm_->ReportError(errMsg,-1);
110 }
111 NumMyRows_ = numLocalRows;
112 NumMyCols_ = numLocalCols; //numLocalCols is the total # of unique columns in the local matrix (the diagonal block)
113 //TODO what happens if some columns are empty?
114 if (mt == PETSC_MPI_AIJ)
115 NumMyCols_ += aij->B->cmap->n;
116 MatInfo info;
117 ierr = MatGetInfo(Amat,MAT_LOCAL,&info);
118 if (ierr) {
119 sprintf(errMsg,"EpetraExt_PETScAIJMatrix.cpp, line %d, MatGetInfo() returned error code %d",__LINE__,ierr);
120 throw Comm_->ReportError(errMsg,-1);
121 }
122 NumMyNonzeros_ = (int) info.nz_used; //PETSc stores nnz as double
123 Comm_->SumAll(&(info.nz_used), &NumGlobalNonzeros_, 1);
124
125 //The PETSc documentation warns that this may not be robust.
126 //In particular, this will break if the ordering is not contiguous!
127 int rowStart, rowEnd;
128 ierr = MatGetOwnershipRange(Amat,&rowStart,&rowEnd);
129 if (ierr) {
130 sprintf(errMsg,"EpetraExt_PETScAIJMatrix.cpp, line %d, MatGetOwnershipRange() returned error code %d",__LINE__,ierr);
131 throw Comm_->ReportError(errMsg,-1);
132 }
133
134 PetscRowStart_ = rowStart;
135 PetscRowEnd_ = rowEnd;
136
137 int* MyGlobalElements = new int[rowEnd-rowStart];
138 for (int i=0; i<rowEnd-rowStart; i++)
139 MyGlobalElements[i] = rowStart+i;
140
141 ierr = MatGetInfo(Amat,MAT_GLOBAL_SUM,&info);
142 if (ierr) {
143 sprintf(errMsg,"EpetraExt_PETScAIJMatrix.cpp, line %d, MatGetInfo() returned error code %d",__LINE__,ierr);
144 throw Comm_->ReportError(errMsg,-1);
145 }
146 int tmp;
147 ierr = MatGetSize(Amat,&NumGlobalRows_,&tmp);
148
149 DomainMap_ = new Epetra_Map(NumGlobalRows_, NumMyRows_, MyGlobalElements, 0, *Comm_);
150
151 // get the GIDs of the non-local columns
152 //FIXME what if the matrix is sequential?
153
154 int * ColGIDs = new int[NumMyCols_];
155 for (int i=0; i<numLocalCols; i++) ColGIDs[i] = MyGlobalElements[i];
156 for (int i=numLocalCols; i<NumMyCols_; i++) ColGIDs[i] = aij->garray[i-numLocalCols];
157
158 ColMap_ = new Epetra_Map(-1, NumMyCols_, ColGIDs, 0, *Comm_);
159
160 Importer_ = new Epetra_Import(*ColMap_, *DomainMap_);
161
162 delete [] MyGlobalElements;
163 delete [] ColGIDs;
164} //Epetra_PETScAIJMatrix(Mat Amat)
165
166//==============================================================================
167
169 if (ImportVector_!=0) delete ImportVector_;
170 delete Importer_;
171 delete ColMap_;
172 delete DomainMap_;
173 delete Comm_;
174
175 if (Values_!=0) {delete [] Values_; Values_=0;}
176 if (Indices_!=0) {delete [] Indices_; Indices_=0;}
177} //Epetra_PETScAIJMatrix dtor
178
179//==========================================================================
180
181//extern "C" {
182 PetscErrorCode MatCreateColmap_MPIAIJ_Private(Mat);
183//}
184
185int Epetra_PETScAIJMatrix::ExtractMyRowCopy(int Row, int Length, int & NumEntries, double * Values,
186 int * Indices) const
187{
188 int nz;
189 PetscInt *gcols, *lcols, ierr;
190 PetscScalar *vals;
191 bool alloc=false;
192
193 // PETSc assumes the row number is global, whereas Trilinos assumes it's local.
194 int globalRow = PetscRowStart_ + Row;
195 assert(globalRow < PetscRowEnd_);
196 ierr=MatGetRow(Amat_, globalRow, &nz, (const PetscInt**) &gcols, (const PetscScalar **) &vals);CHKERRQ(ierr);
197
198 // I ripped this bit of code from PETSc's MatSetValues_MPIAIJ() in mpiaij.c. The PETSc getrow returns everything in
199 // global numbering, so we must convert to local numbering.
200 if (strcmp(MatType_,MATMPIAIJ) == 0) {
201 Mat_MPIAIJ *aij = (Mat_MPIAIJ*)Amat_->data;
202 lcols = (PetscInt *) malloc(nz * sizeof(int));
203 alloc=true;
204 if (!aij->colmap) {
205 ierr = MatCreateColmap_MPIAIJ_Private(Amat_);CHKERRQ(ierr);
206 }
207 /*
208 A PETSc parallel aij matrix uses two matrices to represent the local rows.
209 The first matrix, A, is square and contains all local columns.
210 The second matrix, B, is rectangular and contains all non-local columns.
211
212 Matrix A:
213 Local column ID's are mapped to global column id's by adding cmap.rstart.
214 Given the global ID of a local column, the local ID is found by
215 subtracting cmap.rstart.
216
217 Matrix B:
218 Non-local column ID's are mapped to global column id's by the local-to-
219 global map garray. Given the global ID of a local column, the local ID is
220 found by the global-to-local map colmap. colmap is either an array or
221 hash table, the latter being the case when PETSC_USE_CTABLE is defined.
222 */
223 int offset = Amat_->cmap->n-1; //offset for non-local column indices
224
225 for (int i=0; i<nz; i++) {
226 if (gcols[i] >= Amat_->cmap->rstart && gcols[i] < Amat_->cmap->rend) {
227 lcols[i] = gcols[i] - Amat_->cmap->rstart;
228 } else {
229# ifdef PETSC_USE_CTABLE
230 ierr = PetscTableFind(aij->colmap,gcols[i]+1,lcols+i);CHKERRQ(ierr);
231 lcols[i] = lcols[i] + offset;
232# else
233 lcols[i] = aij->colmap[gcols[i]] + offset;
234# endif
235 }
236
237 } //for i=0; i<nz; i++)
238 }
239 else lcols = gcols;
240
241 NumEntries = nz;
242 if (NumEntries > Length) return(-1);
243 for (int i=0; i<NumEntries; i++) {
244 Indices[i] = lcols[i];
245 Values[i] = vals[i];
246 }
247 if (alloc) free(lcols);
248 MatRestoreRow(Amat_,globalRow,&nz,(const PetscInt**) &gcols, (const PetscScalar **) &vals);
249 return(0);
250} //ExtractMyRowCopy()
251
252//==========================================================================
253
254int Epetra_PETScAIJMatrix::NumMyRowEntries(int Row, int & NumEntries) const
255{
256 // NOTE: MatRestoreRow was previously zeroing out NumEntries.
257 // Do not pass NumEntries to it.
258 int globalRow = PetscRowStart_ + Row;
259 MatGetRow(Amat_, globalRow, &NumEntries, PETSC_NULL, PETSC_NULL);
260 MatRestoreRow(Amat_,globalRow,PETSC_NULL, PETSC_NULL, PETSC_NULL);
261 return(0);
262}
263
264//==============================================================================
265
267{
268 //TODO optimization: only get this diagonal once
269 Vec petscDiag;
270 double *vals=0;
271 int length;
272
273 int ierr=VecCreate(Comm_->Comm(),&petscDiag);CHKERRQ(ierr);
274 VecSetSizes(petscDiag,NumMyRows_,NumGlobalRows_);
275# ifdef HAVE_MPI
276 ierr = VecSetType(petscDiag,VECMPI);CHKERRQ(ierr);
277# else //TODO untested!!
278 VecSetType(petscDiag,VECSEQ);
279# endif
280
281 MatGetDiagonal(Amat_, petscDiag);
282 VecGetArray(petscDiag,&vals);
283 VecGetLocalSize(petscDiag,&length);
284 for (int i=0; i<length; i++) Diagonal[i] = vals[i];
285 VecRestoreArray(petscDiag,&vals);
286 VecDestroy(&petscDiag);
287 return(0);
288}
289
290//=============================================================================
291
292int Epetra_PETScAIJMatrix::Multiply(bool TransA,
293 const Epetra_MultiVector& X,
294 Epetra_MultiVector& Y) const
295{
296 (void)TransA;
297 int NumVectors = X.NumVectors();
298 if (NumVectors!=Y.NumVectors()) EPETRA_CHK_ERR(-1); // X and Y must have same number of vectors
299
300 double ** xptrs;
301 double ** yptrs;
302 X.ExtractView(&xptrs);
303 Y.ExtractView(&yptrs);
304 if (RowMatrixImporter()!=0) {
305 if (ImportVector_!=0) {
306 if (ImportVector_->NumVectors()!=NumVectors) { delete ImportVector_; ImportVector_= 0;}
307 }
308 if (ImportVector_==0) ImportVector_ = new Epetra_MultiVector(RowMatrixColMap(),NumVectors);
309 ImportVector_->Import(X, *RowMatrixImporter(), Insert);
310 ImportVector_->ExtractView(&xptrs);
311 }
312
313 double *vals=0;
314 int length;
315 Vec petscX, petscY;
316 int ierr;
317 for (int i=0; i<NumVectors; i++) {
318# ifdef HAVE_MPI
319 ierr=VecCreateMPIWithArray(Comm_->Comm(),1,X.MyLength(),X.GlobalLength(),xptrs[i],&petscX); CHKERRQ(ierr);
320 ierr=VecCreateMPIWithArray(Comm_->Comm(),1, Y.MyLength(),Y.GlobalLength(),yptrs[i],&petscY); CHKERRQ(ierr);
321# else //FIXME untested
322 ierr=VecCreateSeqWithArray(Comm_->Comm(),1, X.MyLength(),X.GlobalLength(),xptrs[i],&petscX); CHKERRQ(ierr);
323 ierr=VecCreateSeqWithArray(Comm_->Comm(),1, Y.MyLength(),Y.GlobalLength(),yptrs[i],&petscY); CHKERRQ(ierr);
324# endif
325
326 ierr = MatMult(Amat_,petscX,petscY);CHKERRQ(ierr);
327
328 ierr = VecGetArray(petscY,&vals);CHKERRQ(ierr);
329 ierr = VecGetLocalSize(petscY,&length);CHKERRQ(ierr);
330 for (int j=0; j<length; j++) yptrs[i][j] = vals[j];
331 ierr = VecRestoreArray(petscY,&vals);CHKERRQ(ierr);
332 }
333
334 VecDestroy(&petscX); VecDestroy(&petscY);
335
336 double flops = NumGlobalNonzeros();
337 flops *= 2.0;
338 flops *= (double) NumVectors;
339 UpdateFlops(flops);
340 return(0);
341} //Multiply()
342
343//=============================================================================
344
345int Epetra_PETScAIJMatrix::Solve(bool Upper, bool Trans, bool UnitDiagonal,
346 const Epetra_MultiVector& X,
347 Epetra_MultiVector& Y) const
348{
349 (void)Upper;
350 (void)Trans;
351 (void)UnitDiagonal;
352 (void)X;
353 (void)Y;
354 return(-1); // Not implemented
355}
356
357//=============================================================================
358// Utility routine to get the specified row and put it into Values_ and Indices_ arrays
360 int NumEntries;
361
362 if (MaxNumEntries_==-1) {
363 for (int i=0; i < NumMyRows_; i++) {
364 NumMyRowEntries(i, NumEntries);
365 if (NumEntries>MaxNumEntries_) MaxNumEntries_ = NumEntries;
366 }
367 }
368 return(MaxNumEntries_);
369}
370
371//=============================================================================
372// Utility routine to get the specified row and put it into Values_ and Indices_ arrays
373int Epetra_PETScAIJMatrix::GetRow(int Row) const {
374 int NumEntries;
376
377 if (MaxNumEntries>0) {
378 if (Values_==0) Values_ = new double[MaxNumEntries];
379 if (Indices_==0) Indices_ = new int[MaxNumEntries];
380 }
381 Epetra_PETScAIJMatrix::ExtractMyRowCopy(Row, MaxNumEntries, NumEntries, Values_, Indices_);
382
383 return(NumEntries);
384}
385
386//=============================================================================
388//
389// Put inverse of the sum of absolute values of the ith row of A in x[i].
390//
391
392 if (!OperatorRangeMap().SameAs(x.Map())) EPETRA_CHK_ERR(-2); // x must have the same distribution as the range of A
393
394 int ierr = 0;
395 int i, j;
396 for (i=0; i < NumMyRows_; i++) {
397 int NumEntries = GetRow(i); // Copies ith row of matrix into Values_ and Indices_
398 double scale = 0.0;
399 for (j=0; j < NumEntries; j++) scale += fabs(Values_[j]);
400 if (scale<Epetra_MinDouble) {
401 if (scale==0.0) ierr = 1; // Set error to 1 to signal that zero rowsum found (supercedes ierr = 2)
402 else if (ierr!=1) ierr = 2;
403 x[i] = Epetra_MaxDouble;
404 }
405 else
406 x[i] = 1.0/scale;
407 }
409 EPETRA_CHK_ERR(ierr);
410 return(0);
411}
412
413//=============================================================================
415//
416// Put inverse of the sum of absolute values of the jth column of A in x[j].
417//
418
419 if (!Filled()) EPETRA_CHK_ERR(-1); // Matrix must be filled.
420 if (!OperatorDomainMap().SameAs(x.Map())) EPETRA_CHK_ERR(-2); // x must have the same distribution as the domain of A
421
422
423 Epetra_Vector * xp = 0;
424 Epetra_Vector * x_tmp = 0;
425
426
427 // If we have a non-trivial importer, we must export elements that are permuted or belong to other processors
428 if (RowMatrixImporter()!=0) {
429 x_tmp = new Epetra_Vector(RowMatrixColMap()); // Create import vector if needed
430 xp = x_tmp;
431 }
432 int ierr = 0;
433 int i, j;
434
435 for (i=0; i < NumMyCols_; i++) (*xp)[i] = 0.0;
436
437 for (i=0; i < NumMyRows_; i++) {
438 int NumEntries = GetRow(i);// Copies ith row of matrix into Values_ and Indices_
439 for (j=0; j < NumEntries; j++) (*xp)[Indices_[j]] += fabs(Values_[j]);
440 }
441
442 if (RowMatrixImporter()!=0){
443 x.Export(*x_tmp, *RowMatrixImporter(), Add); // Fill x with Values from import vector
444 delete x_tmp;
445 xp = &x;
446 }
447 // Invert values, don't allow them to get too large
448 for (i=0; i < NumMyRows_; i++) {
449 double scale = (*xp)[i];
450 if (scale<Epetra_MinDouble) {
451 if (scale==0.0) ierr = 1; // Set error to 1 to signal that zero rowsum found (supercedes ierr = 2)
452 else if (ierr!=1) ierr = 2;
453 (*xp)[i] = Epetra_MaxDouble;
454 }
455 else
456 (*xp)[i] = 1.0/scale;
457 }
459 EPETRA_CHK_ERR(ierr);
460 return(0);
461}
462
463//=============================================================================
465//
466// This function scales the ith row of A by x[i].
467//
468 double *xptr;
469 X.ExtractView(&xptr);
470 Vec petscX;
471# ifdef HAVE_MPI
472 int ierr=VecCreateMPIWithArray(Comm_->Comm(),1, X.MyLength(),X.GlobalLength(),xptr,&petscX); CHKERRQ(ierr);
473# else //FIXME untested
474 int ierr=VecCreateSeqWithArray(Comm_->Comm(),1, X.MyLength(),X.GlobalLength(),xptr,&petscX); CHKERRQ(ierr);
475# endif
476
477 MatDiagonalScale(Amat_, petscX, PETSC_NULL);
478
479 ierr=VecDestroy(&petscX); CHKERRQ(ierr);
480 return(0);
481} //LeftScale()
482
483//=============================================================================
485//
486// This function scales the jth row of A by x[j].
487//
488 double *xptr;
489 X.ExtractView(&xptr);
490 Vec petscX;
491# ifdef HAVE_MPI
492 int ierr=VecCreateMPIWithArray(Comm_->Comm(),1,X.MyLength(),X.GlobalLength(),xptr,&petscX); CHKERRQ(ierr);
493# else //FIXME untested
494 int ierr=VecCreateSeqWithArray(Comm_->Comm(),1,X.MyLength(),X.GlobalLength(),xptr,&petscX); CHKERRQ(ierr);
495# endif
496
497 MatDiagonalScale(Amat_, PETSC_NULL, petscX);
498
499 ierr=VecDestroy(&petscX); CHKERRQ(ierr);
500 return(0);
501} //RightScale()
502
503//=============================================================================
504
505double Epetra_PETScAIJMatrix::NormInf() const {
506 if (NormInf_>-1.0) return(NormInf_);
507
508 MatNorm(Amat_, NORM_INFINITY,&NormInf_);
510
511 return(NormInf_);
512}
513
514//=============================================================================
515
516double Epetra_PETScAIJMatrix::NormOne() const {
517 if (NormOne_>-1.0) return(NormOne_);
518 if (!Filled()) EPETRA_CHK_ERR(-1); // Matrix must be filled.
519
520 MatNorm(Amat_, NORM_1,&NormOne_);
522
523 return(NormOne_);
524}
525
526//=============================================================================
527
528void Epetra_PETScAIJMatrix::Print(std::ostream& os) const {
529 return;
530}
531
532#endif /*HAVE_PETSC*/
void UpdateFlops(int Flops_in) const
const Epetra_BlockMap & Map() const
int Import(const Epetra_SrcDistObject &A, const Epetra_Import &Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor=0)
int Export(const Epetra_SrcDistObject &A, const Epetra_Import &Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor=0)
int GlobalLength() const
int NumVectors() const
int MyLength() const
int ExtractView(double **A, int *MyLDA) const
int RightScale(const Epetra_Vector &x)
Scales the Epetra_PETScAIJMatrix on the right with a Epetra_Vector x.
double NormInf() const
Returns the infinity norm of the global matrix.
virtual ~Epetra_PETScAIJMatrix()
Epetra_PETScAIJMatrix Destructor.
bool Filled() const
If FillComplete() has been called, this query returns true, otherwise it returns false.
virtual const Epetra_Import * RowMatrixImporter() const
Returns the Epetra_Import object that contains the import operations for distributed operations.
int InvColSums(Epetra_Vector &x) const
Computes the sum of absolute values of the columns of the Epetra_PETScAIJMatrix, results returned in ...
const Epetra_Map & OperatorDomainMap() const
Returns the Epetra_Map object associated with the domain of this operator.
int ExtractDiagonalCopy(Epetra_Vector &Diagonal) const
Returns a copy of the main diagonal in a user-provided vector.
int InvRowSums(Epetra_Vector &x) const
Computes the sum of absolute values of the rows of the Epetra_PETScAIJMatrix, results returned in x.
int NumGlobalNonzeros() const
Returns the number of nonzero entries in the global matrix.
virtual void Print(std::ostream &os) const
Print method.
int Solve(bool Upper, bool Trans, bool UnitDiagonal, const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Returns the result of a Epetra_PETScAIJMatrix multiplied by a Epetra_MultiVector X in Y.
int NumMyRowEntries(int MyRow, int &NumEntries) const
Return the current number of values stored for the specified local row.
const Epetra_Map & RowMatrixColMap() const
Returns the Column Map object needed for implementing Epetra_RowMatrix.
Epetra_PETScAIJMatrix(Mat Amat)
Epetra_PETScAIJMatrix constructor.
int MaxNumEntries() const
Returns the maximum of NumMyRowEntries() over all rows.
int LeftScale(const Epetra_Vector &x)
Scales the Epetra_PETScAIJMatrix on the left with a Epetra_Vector x.
int Multiply(bool TransA, const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Returns the result of a Epetra_PETScAIJMatrix multiplied by a Epetra_MultiVector X in Y.
const Epetra_Map & OperatorRangeMap() const
Returns the Epetra_Map object associated with the range of this operator (same as domain).
int ExtractMyRowCopy(int MyRow, int Length, int &NumEntries, double *Values, int *Indices) const
Returns a copy of the specified local row in user-provided arrays.
double NormOne() const
Returns the one norm of the global matrix.
int ExtractView(double **V) const