int writeRowMatrix(FILE * handle, const Epetra_RowMatrix & A) { long long numRows_LL = A.NumGlobalRows64(); if(numRows_LL > std::numeric_limits<int>::max()) throw "EpetraExt::writeRowMatrix: numRows_LL > std::numeric_limits<int>::max()"; int numRows = static_cast<int>(numRows_LL); Epetra_Map rowMap = A.RowMatrixRowMap(); Epetra_Map colMap = A.RowMatrixColMap(); const Epetra_Comm & comm = rowMap.Comm(); long long ioffset = 1 - rowMap.IndexBase64(); // Matlab indices start at 1 long long joffset = 1 - colMap.IndexBase64(); // Matlab indices start at 1 if (comm.MyPID()!=0) { if (A.NumMyRows()!=0) {EPETRA_CHK_ERR(-1);} if (A.NumMyCols()!=0) {EPETRA_CHK_ERR(-1);} } else { if (numRows!=A.NumMyRows()) {EPETRA_CHK_ERR(-1);} Epetra_SerialDenseVector values(A.MaxNumEntries()); Epetra_IntSerialDenseVector indices(A.MaxNumEntries()); for (int i=0; i<numRows; i++) { long long I = rowMap.GID64(i) + ioffset; int numEntries; if (A.ExtractMyRowCopy(i, values.Length(), numEntries, values.Values(), indices.Values())!=0) {EPETRA_CHK_ERR(-1);} for (int j=0; j<numEntries; j++) { long long J = colMap.GID64(indices[j]) + joffset; double val = values[j]; fprintf(handle, "%lld %lld %22.16e\n", I, J, val); } } } return(0); }
// ============================================================================ void EpetraExt::XMLWriter:: Write(const std::string& Label, const Epetra_RowMatrix& Matrix) { TEUCHOS_TEST_FOR_EXCEPTION(IsOpen_ == false, std::logic_error, "No file has been opened"); long long Rows = Matrix.NumGlobalRows64(); long long Cols = Matrix.NumGlobalRows64(); long long Nonzeros = Matrix.NumGlobalNonzeros64(); if (Comm_.MyPID() == 0) { std::ofstream of(FileName_.c_str(), std::ios::app); of << "<PointMatrix Label=\"" << Label << '"' << " Rows=\"" << Rows << '"' << " Columns=\"" << Cols<< '"' << " Nonzeros=\"" << Nonzeros << '"' << " Type=\"double\" StartingIndex=\"0\">" << std::endl; } int Length = Matrix.MaxNumEntries(); std::vector<int> Indices(Length); std::vector<double> Values(Length); for (int iproc = 0; iproc < Comm_.NumProc(); iproc++) { if (iproc == Comm_.MyPID()) { std::ofstream of(FileName_.c_str(), std::ios::app); of.precision(15); for (int i = 0; i < Matrix.NumMyRows(); ++i) { int NumMyEntries; Matrix.ExtractMyRowCopy(i, Length, NumMyEntries, &Values[0], &Indices[0]); long long GRID = Matrix.RowMatrixRowMap().GID64(i); for (int j = 0; j < NumMyEntries; ++j) of << GRID << " " << Matrix.RowMatrixColMap().GID64(Indices[j]) << " " << std::setiosflags(std::ios::scientific) << Values[j] << std::endl; } of.close(); } Comm_.Barrier(); } if (Comm_.MyPID() == 0) { std::ofstream of(FileName_.c_str(), std::ios::app); of << "</PointMatrix>" << std::endl; of.close(); } }
int RowMatrixToMatrixMarketFile( const char *filename, const Epetra_RowMatrix & A, const char * matrixName, const char *matrixDescription, bool writeHeader) { long long M = A.NumGlobalRows64(); long long N = A.NumGlobalCols64(); long long nz = A.NumGlobalNonzeros64(); FILE * handle = 0; if (A.RowMatrixRowMap().Comm().MyPID()==0) { // Only PE 0 does this section handle = fopen(filename,"w"); if (!handle) {EPETRA_CHK_ERR(-1);} MM_typecode matcode; mm_initialize_typecode(&matcode); mm_set_matrix(&matcode); mm_set_coordinate(&matcode); mm_set_real(&matcode); if (writeHeader==true) { // Only write header if requested (true by default) if (mm_write_banner(handle, matcode)!=0) {EPETRA_CHK_ERR(-1);} if (matrixName!=0) fprintf(handle, "%% \n%% %s\n", matrixName); if (matrixDescription!=0) fprintf(handle, "%% %s\n%% \n", matrixDescription); if (mm_write_mtx_crd_size(handle, M, N, nz)!=0) {EPETRA_CHK_ERR(-1);} } } if (RowMatrixToHandle(handle, A)!=0) {EPETRA_CHK_ERR(-1);}// Everybody calls this routine if (A.RowMatrixRowMap().Comm().MyPID()==0) // Only PE 0 opened a file if (fclose(handle)!=0) {EPETRA_CHK_ERR(-1);} return(0); }
int check(Epetra_RowMatrix& A, Epetra_RowMatrix & B, bool verbose) { int ierr = 0; EPETRA_TEST_ERR(!A.Comm().NumProc()==B.Comm().NumProc(),ierr); EPETRA_TEST_ERR(!A.Comm().MyPID()==B.Comm().MyPID(),ierr); EPETRA_TEST_ERR(!A.Filled()==B.Filled(),ierr); EPETRA_TEST_ERR(!A.HasNormInf()==B.HasNormInf(),ierr); EPETRA_TEST_ERR(!A.LowerTriangular()==B.LowerTriangular(),ierr); EPETRA_TEST_ERR(!A.Map().SameAs(B.Map()),ierr); EPETRA_TEST_ERR(!A.MaxNumEntries()==B.MaxNumEntries(),ierr); EPETRA_TEST_ERR(!A.NumGlobalCols64()==B.NumGlobalCols64(),ierr); EPETRA_TEST_ERR(!A.NumGlobalDiagonals64()==B.NumGlobalDiagonals64(),ierr); EPETRA_TEST_ERR(!A.NumGlobalNonzeros64()==B.NumGlobalNonzeros64(),ierr); EPETRA_TEST_ERR(!A.NumGlobalRows64()==B.NumGlobalRows64(),ierr); EPETRA_TEST_ERR(!A.NumMyCols()==B.NumMyCols(),ierr); EPETRA_TEST_ERR(!A.NumMyDiagonals()==B.NumMyDiagonals(),ierr); EPETRA_TEST_ERR(!A.NumMyNonzeros()==B.NumMyNonzeros(),ierr); for (int i=0; i<A.NumMyRows(); i++) { int nA, nB; A.NumMyRowEntries(i,nA); B.NumMyRowEntries(i,nB); EPETRA_TEST_ERR(!nA==nB,ierr); } EPETRA_TEST_ERR(!A.NumMyRows()==B.NumMyRows(),ierr); EPETRA_TEST_ERR(!A.OperatorDomainMap().SameAs(B.OperatorDomainMap()),ierr); EPETRA_TEST_ERR(!A.OperatorRangeMap().SameAs(B.OperatorRangeMap()),ierr); EPETRA_TEST_ERR(!A.RowMatrixColMap().SameAs(B.RowMatrixColMap()),ierr); EPETRA_TEST_ERR(!A.RowMatrixRowMap().SameAs(B.RowMatrixRowMap()),ierr); EPETRA_TEST_ERR(!A.UpperTriangular()==B.UpperTriangular(),ierr); EPETRA_TEST_ERR(!A.UseTranspose()==B.UseTranspose(),ierr); int NumVectors = 5; { // No transpose case Epetra_MultiVector X(A.OperatorDomainMap(), NumVectors); Epetra_MultiVector YA1(A.OperatorRangeMap(), NumVectors); Epetra_MultiVector YA2(YA1); Epetra_MultiVector YB1(YA1); Epetra_MultiVector YB2(YA1); X.Random(); bool transA = false; A.SetUseTranspose(transA); B.SetUseTranspose(transA); A.Apply(X,YA1); A.Multiply(transA, X, YA2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YA2,"A Multiply and A Apply", verbose),ierr); B.Apply(X,YB1); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB1,"A Multiply and B Multiply", verbose),ierr); B.Multiply(transA, X, YB2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB2,"A Multiply and B Apply", verbose), ierr); } {// transpose case Epetra_MultiVector X(A.OperatorRangeMap(), NumVectors); Epetra_MultiVector YA1(A.OperatorDomainMap(), NumVectors); Epetra_MultiVector YA2(YA1); Epetra_MultiVector YB1(YA1); Epetra_MultiVector YB2(YA1); X.Random(); bool transA = true; A.SetUseTranspose(transA); B.SetUseTranspose(transA); A.Apply(X,YA1); A.Multiply(transA, X, YA2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YA2, "A Multiply and A Apply (transpose)", verbose),ierr); B.Apply(X,YB1); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB1, "A Multiply and B Multiply (transpose)", verbose),ierr); B.Multiply(transA, X,YB2); EPETRA_TEST_ERR(checkMultiVectors(YA1,YB2, "A Multiply and B Apply (transpose)", verbose),ierr); } Epetra_Vector diagA(A.RowMatrixRowMap()); EPETRA_TEST_ERR(A.ExtractDiagonalCopy(diagA),ierr); Epetra_Vector diagB(B.RowMatrixRowMap()); EPETRA_TEST_ERR(B.ExtractDiagonalCopy(diagB),ierr); EPETRA_TEST_ERR(checkMultiVectors(diagA,diagB, "ExtractDiagonalCopy", verbose),ierr); Epetra_Vector rowA(A.RowMatrixRowMap()); EPETRA_TEST_ERR(A.InvRowSums(rowA),ierr); Epetra_Vector rowB(B.RowMatrixRowMap()); EPETRA_TEST_ERR(B.InvRowSums(rowB),ierr) EPETRA_TEST_ERR(checkMultiVectors(rowA,rowB, "InvRowSums", verbose),ierr); Epetra_Vector colA(A.RowMatrixColMap()); EPETRA_TEST_ERR(A.InvColSums(colA),ierr); Epetra_Vector colB(B.RowMatrixColMap()); EPETRA_TEST_ERR(B.InvColSums(colB),ierr); EPETRA_TEST_ERR(checkMultiVectors(colA,colB, "InvColSums", verbose),ierr); EPETRA_TEST_ERR(checkValues(A.NormInf(), B.NormInf(), "NormInf before scaling", verbose), ierr); EPETRA_TEST_ERR(checkValues(A.NormOne(), B.NormOne(), "NormOne before scaling", verbose),ierr); EPETRA_TEST_ERR(A.RightScale(colA),ierr); EPETRA_TEST_ERR(B.RightScale(colB),ierr); EPETRA_TEST_ERR(A.LeftScale(rowA),ierr); EPETRA_TEST_ERR(B.LeftScale(rowB),ierr); EPETRA_TEST_ERR(checkValues(A.NormInf(), B.NormInf(), "NormInf after scaling", verbose), ierr); EPETRA_TEST_ERR(checkValues(A.NormOne(), B.NormOne(), "NormOne after scaling", verbose),ierr); vector<double> valuesA(A.MaxNumEntries()); vector<int> indicesA(A.MaxNumEntries()); vector<double> valuesB(B.MaxNumEntries()); vector<int> indicesB(B.MaxNumEntries()); return(0); for (int i=0; i<A.NumMyRows(); i++) { int nA, nB; EPETRA_TEST_ERR(A.ExtractMyRowCopy(i, A.MaxNumEntries(), nA, &valuesA[0], &indicesA[0]),ierr); EPETRA_TEST_ERR(B.ExtractMyRowCopy(i, B.MaxNumEntries(), nB, &valuesB[0], &indicesB[0]),ierr); EPETRA_TEST_ERR(!nA==nB,ierr); for (int j=0; j<nA; j++) { double curVal = valuesA[j]; int curIndex = indicesA[j]; bool notfound = true; int jj = 0; while (notfound && jj< nB) { if (!checkValues(curVal, valuesB[jj])) notfound = false; jj++; } EPETRA_TEST_ERR(notfound, ierr); vector<int>::iterator p = find(indicesB.begin(),indicesB.end(),curIndex); // find curIndex in indicesB EPETRA_TEST_ERR(p==indicesB.end(), ierr); } } if (verbose) cout << "RowMatrix Methods check OK" << endl; return (ierr); }
// ====================================================================== int Ifpack_PrintSparsity(const Epetra_RowMatrix& A, const char* InputFileName, const int NumPDEEqns) { int ltit; long long m,nc,nr,maxdim; double lrmrgn,botmrgn,xtit,ytit,ytitof,fnstit,siz = 0.0; double xl,xr, yb,yt, scfct,u2dot,frlw,delt,paperx; bool square = false; /*change square to .true. if you prefer a square frame around a rectangular matrix */ double conv = 2.54; char munt = 'E'; /* put 'E' for centimeters, 'U' for inches */ int ptitle = 0; /* position of the title, 0 under the drawing, else above */ FILE* fp = NULL; int NumMyRows; //int NumMyCols; long long NumGlobalRows; long long NumGlobalCols; int MyPID; int NumProc; char FileName[1024]; char title[1024]; const Epetra_Comm& Comm = A.Comm(); /* --------------------- execution begins ---------------------- */ if (strlen(A.Label()) != 0) strcpy(title, A.Label()); else sprintf(title, "%s", "matrix"); if (InputFileName == 0) sprintf(FileName, "%s.ps", title); else strcpy(FileName, InputFileName); MyPID = Comm.MyPID(); NumProc = Comm.NumProc(); NumMyRows = A.NumMyRows(); //NumMyCols = A.NumMyCols(); NumGlobalRows = A.NumGlobalRows64(); NumGlobalCols = A.NumGlobalCols64(); if (NumGlobalRows != NumGlobalCols) IFPACK_CHK_ERR(-1); // never tested /* to be changed for rect matrices */ maxdim = (NumGlobalRows>NumGlobalCols)?NumGlobalRows:NumGlobalCols; maxdim /= NumPDEEqns; m = 1 + maxdim; nr = NumGlobalRows / NumPDEEqns + 1; nc = NumGlobalCols / NumPDEEqns + 1; if (munt == 'E') { u2dot = 72.0/conv; paperx = 21.0; siz = 10.0; } else { u2dot = 72.0; paperx = 8.5*conv; siz = siz*conv; } /* left and right margins (drawing is centered) */ lrmrgn = (paperx-siz)/2.0; /* bottom margin : 2 cm */ botmrgn = 2.0; /* c scaling factor */ scfct = siz*u2dot/m; /* matrix frame line witdh */ frlw = 0.25; /* font size for title (cm) */ fnstit = 0.5; /* mfh 23 Jan 2013: title is always nonnull, since it's an array of fixed nonzero length. The 'if' test thus results in a compiler warning. */ /*if (title) ltit = strlen(title);*/ /*else ltit = 0;*/ ltit = strlen(title); /* position of title : centered horizontally */ /* at 1.0 cm vertically over the drawing */ ytitof = 1.0; xtit = paperx/2.0; ytit = botmrgn+siz*nr/m + ytitof; /* almost exact bounding box */ xl = lrmrgn*u2dot - scfct*frlw/2; xr = (lrmrgn+siz)*u2dot + scfct*frlw/2; yb = botmrgn*u2dot - scfct*frlw/2; yt = (botmrgn+siz*nr/m)*u2dot + scfct*frlw/2; if (ltit == 0) { yt = yt + (ytitof+fnstit*0.70)*u2dot; } /* add some room to bounding box */ delt = 10.0; xl = xl-delt; xr = xr+delt; yb = yb-delt; yt = yt+delt; /* correction for title under the drawing */ if ((ptitle == 0) && (ltit == 0)) { ytit = botmrgn + fnstit*0.3; botmrgn = botmrgn + ytitof + fnstit*0.7; } /* begin of output */ if (MyPID == 0) { fp = fopen(FileName,"w"); fprintf(fp,"%s","%%!PS-Adobe-2.0\n"); fprintf(fp,"%s","%%Creator: IFPACK\n"); fprintf(fp,"%%%%BoundingBox: %f %f %f %f\n", xl,yb,xr,yt); fprintf(fp,"%s","%%EndComments\n"); fprintf(fp,"%s","/cm {72 mul 2.54 div} def\n"); fprintf(fp,"%s","/mc {72 div 2.54 mul} def\n"); fprintf(fp,"%s","/pnum { 72 div 2.54 mul 20 string "); fprintf(fp,"%s","cvs print ( ) print} def\n"); fprintf(fp,"%s","/Cshow {dup stringwidth pop -2 div 0 rmoveto show} def\n"); /* we leave margins etc. in cm so it is easy to modify them if needed by editing the output file */ fprintf(fp,"%s","gsave\n"); if (ltit != 0) { fprintf(fp,"/Helvetica findfont %e cm scalefont setfont\n", fnstit); fprintf(fp,"%f cm %f cm moveto\n", xtit,ytit); fprintf(fp,"(%s) Cshow\n", title); fprintf(fp,"%f cm %f cm translate\n", lrmrgn,botmrgn); } fprintf(fp,"%f cm %d div dup scale \n", siz, (int) m); /* draw a frame around the matrix */ fprintf(fp,"%f setlinewidth\n", frlw); fprintf(fp,"%s","newpath\n"); fprintf(fp,"%s","0 0 moveto "); if (square) { printf("------------------- %d\n", (int) m); fprintf(fp,"%d %d lineto\n", (int) m, 0); fprintf(fp,"%d %d lineto\n", (int) m, (int) m); fprintf(fp,"%d %d lineto\n", 0, (int) m); } else { fprintf(fp,"%d %d lineto\n", (int) nc, 0); fprintf(fp,"%d %d lineto\n", (int) nc, (int) nr); fprintf(fp,"%d %d lineto\n", 0, (int) nr); } fprintf(fp,"%s","closepath stroke\n"); /* plotting loop */ fprintf(fp,"%s","1 1 translate\n"); fprintf(fp,"%s","0.8 setlinewidth\n"); fprintf(fp,"%s","/p {moveto 0 -.40 rmoveto \n"); fprintf(fp,"%s"," 0 .80 rlineto stroke} def\n"); fclose(fp); } int MaxEntries = A.MaxNumEntries(); std::vector<int> Indices(MaxEntries); std::vector<double> Values(MaxEntries); for (int pid = 0 ; pid < NumProc ; ++pid) { if (pid == MyPID) { fp = fopen(FileName,"a"); if( fp == NULL ) { fprintf(stderr,"%s","ERROR\n"); exit(EXIT_FAILURE); } for (int i = 0 ; i < NumMyRows ; ++i) { if (i % NumPDEEqns) continue; int Nnz; A.ExtractMyRowCopy(i,MaxEntries,Nnz,&Values[0],&Indices[0]); long long grow = A.RowMatrixRowMap().GID64(i); for (int j = 0 ; j < Nnz ; ++j) { int col = Indices[j]; if (col % NumPDEEqns == 0) { long long gcol = A.RowMatrixColMap().GID64(Indices[j]); grow /= NumPDEEqns; gcol /= NumPDEEqns; fprintf(fp,"%lld %lld p\n", gcol, NumGlobalRows - grow - 1); } } } fprintf(fp,"%s","%end of data for this process\n"); if( pid == NumProc - 1 ) fprintf(fp,"%s","showpage\n"); fclose(fp); } Comm.Barrier(); } return(0); }
int Ifpack_Analyze(const Epetra_RowMatrix& A, const bool Cheap, const int NumPDEEqns) { int NumMyRows = A.NumMyRows(); long long NumGlobalRows = A.NumGlobalRows64(); long long NumGlobalCols = A.NumGlobalCols64(); long long MyBandwidth = 0, GlobalBandwidth; long long MyLowerNonzeros = 0, MyUpperNonzeros = 0; long long GlobalLowerNonzeros, GlobalUpperNonzeros; long long MyDiagonallyDominant = 0, GlobalDiagonallyDominant; long long MyWeaklyDiagonallyDominant = 0, GlobalWeaklyDiagonallyDominant; double MyMin, MyAvg, MyMax; double GlobalMin, GlobalAvg, GlobalMax; long long GlobalStorage; bool verbose = (A.Comm().MyPID() == 0); GlobalStorage = sizeof(int*) * NumGlobalRows + sizeof(int) * A.NumGlobalNonzeros64() + sizeof(double) * A.NumGlobalNonzeros64(); if (verbose) { print(); Ifpack_PrintLine(); print<const char*>("Label", A.Label()); print<long long>("Global rows", NumGlobalRows); print<long long>("Global columns", NumGlobalCols); print<long long>("Stored nonzeros", A.NumGlobalNonzeros64()); print<long long>("Nonzeros / row", A.NumGlobalNonzeros64() / NumGlobalRows); print<double>("Estimated storage (Mbytes)", 1.0e-6 * GlobalStorage); } long long NumMyActualNonzeros = 0, NumGlobalActualNonzeros; long long NumMyEmptyRows = 0, NumGlobalEmptyRows; long long NumMyDirichletRows = 0, NumGlobalDirichletRows; std::vector<int> colInd(A.MaxNumEntries()); std::vector<double> colVal(A.MaxNumEntries()); Epetra_Vector Diag(A.RowMatrixRowMap()); Epetra_Vector RowSum(A.RowMatrixRowMap()); Diag.PutScalar(0.0); RowSum.PutScalar(0.0); for (int i = 0 ; i < NumMyRows ; ++i) { long long GRID = A.RowMatrixRowMap().GID64(i); int Nnz; IFPACK_CHK_ERR(A.ExtractMyRowCopy(i,A.MaxNumEntries(),Nnz, &colVal[0],&colInd[0])); if (Nnz == 0) NumMyEmptyRows++; if (Nnz == 1) NumMyDirichletRows++; for (int j = 0 ; j < Nnz ; ++j) { double v = colVal[j]; if (v < 0) v = -v; if (colVal[j] != 0.0) NumMyActualNonzeros++; long long GCID = A.RowMatrixColMap().GID64(colInd[j]); if (GCID != GRID) RowSum[i] += v; else Diag[i] = v; if (GCID < GRID) MyLowerNonzeros++; else if (GCID > GRID) MyUpperNonzeros++; long long b = GCID - GRID; if (b < 0) b = -b; if (b > MyBandwidth) MyBandwidth = b; } if (Diag[i] > RowSum[i]) MyDiagonallyDominant++; if (Diag[i] >= RowSum[i]) MyWeaklyDiagonallyDominant++; RowSum[i] += Diag[i]; } // ======================== // // summing up global values // // ======================== // A.Comm().SumAll(&MyDiagonallyDominant,&GlobalDiagonallyDominant,1); A.Comm().SumAll(&MyWeaklyDiagonallyDominant,&GlobalWeaklyDiagonallyDominant,1); A.Comm().SumAll(&NumMyActualNonzeros, &NumGlobalActualNonzeros, 1); A.Comm().SumAll(&NumMyEmptyRows, &NumGlobalEmptyRows, 1); A.Comm().SumAll(&NumMyDirichletRows, &NumGlobalDirichletRows, 1); A.Comm().SumAll(&MyBandwidth, &GlobalBandwidth, 1); A.Comm().SumAll(&MyLowerNonzeros, &GlobalLowerNonzeros, 1); A.Comm().SumAll(&MyUpperNonzeros, &GlobalUpperNonzeros, 1); A.Comm().SumAll(&MyDiagonallyDominant, &GlobalDiagonallyDominant, 1); A.Comm().SumAll(&MyWeaklyDiagonallyDominant, &GlobalWeaklyDiagonallyDominant, 1); double NormOne = A.NormOne(); double NormInf = A.NormInf(); double NormF = Ifpack_FrobeniusNorm(A); if (verbose) { print(); print<long long>("Actual nonzeros", NumGlobalActualNonzeros); print<long long>("Nonzeros in strict lower part", GlobalLowerNonzeros); print<long long>("Nonzeros in strict upper part", GlobalUpperNonzeros); print(); print<long long>("Empty rows", NumGlobalEmptyRows, 100.0 * NumGlobalEmptyRows / NumGlobalRows); print<long long>("Dirichlet rows", NumGlobalDirichletRows, 100.0 * NumGlobalDirichletRows / NumGlobalRows); print<long long>("Diagonally dominant rows", GlobalDiagonallyDominant, 100.0 * GlobalDiagonallyDominant / NumGlobalRows); print<long long>("Weakly diag. dominant rows", GlobalWeaklyDiagonallyDominant, 100.0 * GlobalWeaklyDiagonallyDominant / NumGlobalRows); print(); print<long long>("Maximum bandwidth", GlobalBandwidth); print(); print("", "one-norm", "inf-norm", "Frobenius", false); print("", "========", "========", "=========", false); print(); print<double>("A", NormOne, NormInf, NormF); } if (Cheap == false) { // create A + A^T and A - A^T Epetra_FECrsMatrix AplusAT(Copy, A.RowMatrixRowMap(), 0); Epetra_FECrsMatrix AminusAT(Copy, A.RowMatrixRowMap(), 0); #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES if(A.RowMatrixRowMap().GlobalIndicesInt()) { for (int i = 0 ; i < NumMyRows ; ++i) { int GRID = A.RowMatrixRowMap().GID(i); assert (GRID != -1); int Nnz; IFPACK_CHK_ERR(A.ExtractMyRowCopy(i,A.MaxNumEntries(),Nnz, &colVal[0],&colInd[0])); for (int j = 0 ; j < Nnz ; ++j) { int GCID = A.RowMatrixColMap().GID(colInd[j]); assert (GCID != -1); double plus_val = colVal[j]; double minus_val = -colVal[j]; if (AplusAT.SumIntoGlobalValues(1,&GRID,1,&GCID,&plus_val) != 0) { IFPACK_CHK_ERR(AplusAT.InsertGlobalValues(1,&GRID,1,&GCID,&plus_val)); } if (AplusAT.SumIntoGlobalValues(1,&GCID,1,&GRID,&plus_val) != 0) { IFPACK_CHK_ERR(AplusAT.InsertGlobalValues(1,&GCID,1,&GRID,&plus_val)); } if (AminusAT.SumIntoGlobalValues(1,&GRID,1,&GCID,&plus_val) != 0) { IFPACK_CHK_ERR(AminusAT.InsertGlobalValues(1,&GRID,1,&GCID,&plus_val)); } if (AminusAT.SumIntoGlobalValues(1,&GCID,1,&GRID,&minus_val) != 0) { IFPACK_CHK_ERR(AminusAT.InsertGlobalValues(1,&GCID,1,&GRID,&minus_val)); } } } } else #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES if(A.RowMatrixRowMap().GlobalIndicesLongLong()) { for (int i = 0 ; i < NumMyRows ; ++i) { long long GRID = A.RowMatrixRowMap().GID64(i); assert (GRID != -1); int Nnz; IFPACK_CHK_ERR(A.ExtractMyRowCopy(i,A.MaxNumEntries(),Nnz, &colVal[0],&colInd[0])); for (int j = 0 ; j < Nnz ; ++j) { long long GCID = A.RowMatrixColMap().GID64(colInd[j]); assert (GCID != -1); double plus_val = colVal[j]; double minus_val = -colVal[j]; if (AplusAT.SumIntoGlobalValues(1,&GRID,1,&GCID,&plus_val) != 0) { IFPACK_CHK_ERR(AplusAT.InsertGlobalValues(1,&GRID,1,&GCID,&plus_val)); } if (AplusAT.SumIntoGlobalValues(1,&GCID,1,&GRID,&plus_val) != 0) { IFPACK_CHK_ERR(AplusAT.InsertGlobalValues(1,&GCID,1,&GRID,&plus_val)); } if (AminusAT.SumIntoGlobalValues(1,&GRID,1,&GCID,&plus_val) != 0) { IFPACK_CHK_ERR(AminusAT.InsertGlobalValues(1,&GRID,1,&GCID,&plus_val)); } if (AminusAT.SumIntoGlobalValues(1,&GCID,1,&GRID,&minus_val) != 0) { IFPACK_CHK_ERR(AminusAT.InsertGlobalValues(1,&GCID,1,&GRID,&minus_val)); } } } } else #endif throw "Ifpack_Analyze: GlobalIndices type unknown"; AplusAT.FillComplete(); AminusAT.FillComplete(); AplusAT.Scale(0.5); AminusAT.Scale(0.5); NormOne = AplusAT.NormOne(); NormInf = AplusAT.NormInf(); NormF = Ifpack_FrobeniusNorm(AplusAT); if (verbose) { print<double>("A + A^T", NormOne, NormInf, NormF); } NormOne = AminusAT.NormOne(); NormInf = AminusAT.NormInf(); NormF = Ifpack_FrobeniusNorm(AminusAT); if (verbose) { print<double>("A - A^T", NormOne, NormInf, NormF); } } if (verbose) { print(); print<const char*>("", "min", "avg", "max", false); print<const char*>("", "===", "===", "===", false); } MyMax = -DBL_MAX; MyMin = DBL_MAX; MyAvg = 0.0; for (int i = 0 ; i < NumMyRows ; ++i) { int Nnz; IFPACK_CHK_ERR(A.ExtractMyRowCopy(i,A.MaxNumEntries(),Nnz, &colVal[0],&colInd[0])); for (int j = 0 ; j < Nnz ; ++j) { MyAvg += colVal[j]; if (colVal[j] > MyMax) MyMax = colVal[j]; if (colVal[j] < MyMin) MyMin = colVal[j]; } } A.Comm().MaxAll(&MyMax, &GlobalMax, 1); A.Comm().MinAll(&MyMin, &GlobalMin, 1); A.Comm().SumAll(&MyAvg, &GlobalAvg, 1); GlobalAvg /= A.NumGlobalNonzeros64(); if (verbose) { print(); print<double>(" A(i,j)", GlobalMin, GlobalAvg, GlobalMax); } MyMax = 0.0; MyMin = DBL_MAX; MyAvg = 0.0; for (int i = 0 ; i < NumMyRows ; ++i) { int Nnz; IFPACK_CHK_ERR(A.ExtractMyRowCopy(i,A.MaxNumEntries(),Nnz, &colVal[0],&colInd[0])); for (int j = 0 ; j < Nnz ; ++j) { double v = colVal[j]; if (v < 0) v = -v; MyAvg += v; if (colVal[j] > MyMax) MyMax = v; if (colVal[j] < MyMin) MyMin = v; } } A.Comm().MaxAll(&MyMax, &GlobalMax, 1); A.Comm().MinAll(&MyMin, &GlobalMin, 1); A.Comm().SumAll(&MyAvg, &GlobalAvg, 1); GlobalAvg /= A.NumGlobalNonzeros64(); if (verbose) { print<double>("|A(i,j)|", GlobalMin, GlobalAvg, GlobalMax); } // ================= // // diagonal elements // // ================= // Diag.MinValue(&GlobalMin); Diag.MaxValue(&GlobalMax); Diag.MeanValue(&GlobalAvg); if (verbose) { print(); print<double>(" A(k,k)", GlobalMin, GlobalAvg, GlobalMax); } Diag.Abs(Diag); Diag.MinValue(&GlobalMin); Diag.MaxValue(&GlobalMax); Diag.MeanValue(&GlobalAvg); if (verbose) { print<double>("|A(k,k)|", GlobalMin, GlobalAvg, GlobalMax); } // ============================================== // // cycle over all equations for diagonal elements // // ============================================== // if (NumPDEEqns > 1 ) { if (verbose) print(); for (int ie = 0 ; ie < NumPDEEqns ; ie++) { MyMin = DBL_MAX; MyMax = -DBL_MAX; MyAvg = 0.0; for (int i = ie ; i < Diag.MyLength() ; i += NumPDEEqns) { double d = Diag[i]; MyAvg += d; if (d < MyMin) MyMin = d; if (d > MyMax) MyMax = d; } A.Comm().MinAll(&MyMin, &GlobalMin, 1); A.Comm().MaxAll(&MyMax, &GlobalMax, 1); A.Comm().SumAll(&MyAvg, &GlobalAvg, 1); // does not really work fine if the number of global // elements is not a multiple of NumPDEEqns GlobalAvg /= (Diag.GlobalLength64() / NumPDEEqns); if (verbose) { char str[80]; sprintf(str, " A(k,k), eq %d", ie); print<double>(str, GlobalMin, GlobalAvg, GlobalMax); } } } // ======== // // row sums // // ======== // RowSum.MinValue(&GlobalMin); RowSum.MaxValue(&GlobalMax); RowSum.MeanValue(&GlobalAvg); if (verbose) { print(); print<double>(" sum_j A(k,j)", GlobalMin, GlobalAvg, GlobalMax); } // ===================================== // // cycle over all equations for row sums // // ===================================== // if (NumPDEEqns > 1 ) { if (verbose) print(); for (int ie = 0 ; ie < NumPDEEqns ; ie++) { MyMin = DBL_MAX; MyMax = -DBL_MAX; MyAvg = 0.0; for (int i = ie ; i < Diag.MyLength() ; i += NumPDEEqns) { double d = RowSum[i]; MyAvg += d; if (d < MyMin) MyMin = d; if (d > MyMax) MyMax = d; } A.Comm().MinAll(&MyMin, &GlobalMin, 1); A.Comm().MaxAll(&MyMax, &GlobalMax, 1); A.Comm().SumAll(&MyAvg, &GlobalAvg, 1); // does not really work fine if the number of global // elements is not a multiple of NumPDEEqns GlobalAvg /= (Diag.GlobalLength64() / NumPDEEqns); if (verbose) { char str[80]; sprintf(str, " sum_j A(k,j), eq %d", ie); print<double>(str, GlobalMin, GlobalAvg, GlobalMax); } } } if (verbose) Ifpack_PrintLine(); return(0); }