//============================================================================== Ifpack_ReorderFilter::Ifpack_ReorderFilter(const Teuchos::RefCountPtr<Epetra_RowMatrix>& Matrix_in, const Teuchos::RefCountPtr<Ifpack_Reordering>& Reordering_in) : A_(Matrix_in), Reordering_(Reordering_in), NumMyRows_(Matrix_in->NumMyRows()), MaxNumEntries_(Matrix_in->MaxNumEntries()) { }
// ====================================================================== bool BasicTest(string PrecType, const Teuchos::RefCountPtr<Epetra_RowMatrix>& A,bool backward, bool reorder=false) { Epetra_MultiVector LHS(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector RHS(A->RowMatrixRowMap(), NumVectors); LHS.PutScalar(0.0); RHS.Random(); double starting_residual = Galeri::ComputeNorm(&*A, &LHS, &RHS); Epetra_LinearProblem Problem(&*A, &LHS, &RHS); // Set up the list Teuchos::ParameterList List; List.set("relaxation: damping factor", 1.0); List.set("relaxation: sweeps",2550); List.set("relaxation: type", PrecType); if(backward) List.set("relaxation: backward mode",backward); // Reordering if needed int NumRows=A->NumMyRows(); std::vector<int> RowList(NumRows); if(reorder) { for(int i=0; i<NumRows; i++) RowList[i]=i; List.set("relaxation: number of local smoothing indices",NumRows); List.set("relaxation: local smoothing indices",RowList.size()>0? &RowList[0] : (int*)0); } Ifpack_PointRelaxation Point(&*A); Point.SetParameters(List); Point.Compute(); // use the preconditioner as solver, with 1550 iterations Point.ApplyInverse(RHS,LHS); // compute the real residual double residual = Galeri::ComputeNorm(&*A, &LHS, &RHS); if (A->Comm().MyPID() == 0 && verbose) cout << "||A * x - b||_2 (scaled) = " << residual / starting_residual << endl; // Jacobi is very slow to converge here if (residual / starting_residual < 1e-2) { if (verbose) cout << "BasicTest Test passed" << endl; return(true); } else { if (verbose) cout << "BasicTest Test failed!" << endl; return(false); } }
//========================================================================== int Ifpack_CrsIct::InitValues(const Epetra_CrsMatrix & A) { int ierr = 0; int i, j; int NumIn, NumL, NumU; bool DiagFound; int NumNonzeroDiags = 0; Teuchos::RefCountPtr<Epetra_CrsMatrix> OverlapA = Teuchos::rcp( (Epetra_CrsMatrix *) &A_ , false ); if (LevelOverlap_>0) { EPETRA_CHK_ERR(-1); // Not implemented yet //OverlapA = new Epetra_CrsMatrix(Copy, *Graph_.OverlapGraph()); //EPETRA_CHK_ERR(OverlapA->Import(A, *Graph_.OverlapImporter(), Insert)); //EPETRA_CHK_ERR(OverlapA->FillComplete()); } // Get Maximun Row length int MaxNumEntries = OverlapA->MaxNumEntries(); vector<int> InI(MaxNumEntries); // Allocate temp space vector<int> UI(MaxNumEntries); vector<double> InV(MaxNumEntries); vector<double> UV(MaxNumEntries); double *DV; ierr = D_->ExtractView(&DV); // Get view of diagonal // First we copy the user's matrix into diagonal vector and U, regardless of fill level int NumRows = OverlapA->NumMyRows(); for (i=0; i< NumRows; i++) { OverlapA->ExtractMyRowCopy(i, MaxNumEntries, NumIn, &InV[0], &InI[0]); // Get Values and Indices // Split into L and U (we don't assume that indices are ordered). NumL = 0; NumU = 0; DiagFound = false; for (j=0; j< NumIn; j++) { int k = InI[j]; if (k==i) { DiagFound = true; DV[i] += Rthresh_ * InV[j] + EPETRA_SGN(InV[j]) * Athresh_; // Store perturbed diagonal in Epetra_Vector D_ } else if (k < 0) return(-1); // Out of range else if (i<k && k<NumRows) { UI[NumU] = k; UV[NumU] = InV[j]; NumU++; } } // Check in things for this row of L and U if (DiagFound) NumNonzeroDiags++; if (NumU) U_->InsertMyValues(i, NumU, &UV[0], &UI[0]); } U_->FillComplete(A_.OperatorDomainMap(), A_.OperatorRangeMap()); SetValuesInitialized(true); SetFactored(false); int ierr1 = 0; if (NumNonzeroDiags<U_->NumMyRows()) ierr1 = 1; A_.Comm().MaxAll(&ierr1, &ierr, 1); EPETRA_CHK_ERR(ierr); return(0); }
// ====================================================================== bool KrylovTest(string PrecType, const Teuchos::RefCountPtr<Epetra_RowMatrix>& A, bool backward, bool reorder=false) { Epetra_MultiVector LHS(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector RHS(A->RowMatrixRowMap(), NumVectors); LHS.PutScalar(0.0); RHS.Random(); Epetra_LinearProblem Problem(&*A, &LHS, &RHS); // Set up the list Teuchos::ParameterList List; List.set("relaxation: damping factor", 1.0); List.set("relaxation: type", PrecType); if(backward) List.set("relaxation: backward mode",backward); // Reordering if needed int NumRows=A->NumMyRows(); std::vector<int> RowList(NumRows); if(reorder) { for(int i=0; i<NumRows; i++) RowList[i]=i; List.set("relaxation: number of local smoothing indices",NumRows); List.set("relaxation: local smoothing indices",RowList.size()>0? &RowList[0] : (int*)0); } int Iters1, Iters10; if (verbose) { cout << "Krylov test: Using " << PrecType << " with AztecOO" << endl; } // ============================================== // // get the number of iterations with 1 sweep only // // ============================================== // { List.set("relaxation: sweeps",1); Ifpack_PointRelaxation Point(&*A); Point.SetParameters(List); Point.Compute(); // set AztecOO solver object AztecOO AztecOOSolver(Problem); AztecOOSolver.SetAztecOption(AZ_solver,Solver); AztecOOSolver.SetAztecOption(AZ_output,AZ_none); AztecOOSolver.SetPrecOperator(&Point); AztecOOSolver.Iterate(2550,1e-5); double TrueResidual = AztecOOSolver.TrueResidual(); // some output if (verbose && Problem.GetMatrix()->Comm().MyPID() == 0) { cout << "Norm of the true residual = " << TrueResidual << endl; } Iters1 = AztecOOSolver.NumIters(); } // ======================================================== // // now re-run with 10 sweeps, solver should converge faster // ======================================================== // { List.set("relaxation: sweeps",10); Ifpack_PointRelaxation Point(&*A); Point.SetParameters(List); Point.Compute(); LHS.PutScalar(0.0); // set AztecOO solver object AztecOO AztecOOSolver(Problem); AztecOOSolver.SetAztecOption(AZ_solver,Solver); AztecOOSolver.SetAztecOption(AZ_output,AZ_none); AztecOOSolver.SetPrecOperator(&Point); AztecOOSolver.Iterate(2550,1e-5); double TrueResidual = AztecOOSolver.TrueResidual(); // some output if (verbose && Problem.GetMatrix()->Comm().MyPID() == 0) { cout << "Norm of the true residual = " << TrueResidual << endl; } Iters10 = AztecOOSolver.NumIters(); } if (verbose) { cout << "Iters_1 = " << Iters1 << ", Iters_10 = " << Iters10 << endl; cout << "(second number should be smaller than first one)" << endl; } if (Iters10 > Iters1) { if (verbose) cout << "KrylovTest TEST FAILED!" << endl; return(false); } else { if (verbose) cout << "KrylovTest TEST PASSED" << endl; return(true); } }
// ====================================================================== bool ComparePointAndBlock(string PrecType, const Teuchos::RefCountPtr<Epetra_RowMatrix>& A, int sweeps) { Epetra_MultiVector RHS(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector LHS(A->RowMatrixRowMap(), NumVectors); LHS.PutScalar(0.0); RHS.Random(); Epetra_LinearProblem Problem(&*A, &LHS, &RHS); // Set up the list Teuchos::ParameterList List; List.set("relaxation: damping factor", 1.0); List.set("relaxation: type", PrecType); List.set("relaxation: sweeps",sweeps); List.set("partitioner: type", "linear"); List.set("partitioner: local parts", A->NumMyRows()); int ItersPoint, ItersBlock; // ================================================== // // get the number of iterations with point relaxation // // ================================================== // { RHS.PutScalar(1.0); LHS.PutScalar(0.0); Ifpack_PointRelaxation Point(&*A); Point.SetParameters(List); Point.Compute(); // set AztecOO solver object AztecOO AztecOOSolver(Problem); AztecOOSolver.SetAztecOption(AZ_solver,Solver); if (verbose) AztecOOSolver.SetAztecOption(AZ_output,32); else AztecOOSolver.SetAztecOption(AZ_output,AZ_none); AztecOOSolver.SetPrecOperator(&Point); AztecOOSolver.Iterate(2550,1e-2); double TrueResidual = AztecOOSolver.TrueResidual(); ItersPoint = AztecOOSolver.NumIters(); // some output if (verbose && Problem.GetMatrix()->Comm().MyPID() == 0) { cout << "Iterations = " << ItersPoint << endl; cout << "Norm of the true residual = " << TrueResidual << endl; } } // ================================================== // // get the number of iterations with block relaxation // // ================================================== // { RHS.PutScalar(1.0); LHS.PutScalar(0.0); Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_Amesos> > Block(&*A); Block.SetParameters(List); Block.Compute(); // set AztecOO solver object AztecOO AztecOOSolver(Problem); AztecOOSolver.SetAztecOption(AZ_solver,Solver); if (verbose) AztecOOSolver.SetAztecOption(AZ_output,32); else AztecOOSolver.SetAztecOption(AZ_output,AZ_none); AztecOOSolver.SetPrecOperator(&Block); AztecOOSolver.Iterate(2550,1e-2); double TrueResidual = AztecOOSolver.TrueResidual(); ItersBlock = AztecOOSolver.NumIters(); // some output if (verbose && Problem.GetMatrix()->Comm().MyPID() == 0) { cout << "Iterations " << ItersBlock << endl; cout << "Norm of the true residual = " << TrueResidual << endl; } } int diff = ItersPoint - ItersBlock; if (diff < 0) diff = -diff; if (diff > 10) { if (verbose) cout << "ComparePointandBlock TEST FAILED!" << endl; return(false); } else { if (verbose) cout << "ComparePointandBlock TEST PASSED" << endl; return(true); } }
// ====================================================================== bool TestContainer(std::string Type, const Teuchos::RefCountPtr<Epetra_RowMatrix>& A) { using std::cout; using std::endl; int NumVectors = 3; int NumMyRows = A->NumMyRows(); Epetra_MultiVector LHS_exact(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector LHS(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector RHS(A->RowMatrixRowMap(), NumVectors); LHS_exact.Random(); LHS.PutScalar(0.0); A->Multiply(false, LHS_exact, RHS); Epetra_LinearProblem Problem(&*A, &LHS, &RHS); if (verbose) { cout << "Container type = " << Type << endl; cout << "NumMyRows = " << NumMyRows << ", NumVectors = " << NumVectors << endl; } LHS.PutScalar(0.0); Teuchos::RefCountPtr<Ifpack_Container> Container; if (Type == "dense") Container = Teuchos::rcp( new Ifpack_DenseContainer(A->NumMyRows(), NumVectors) ); else Container = Teuchos::rcp( new Ifpack_SparseContainer<Ifpack_Amesos>(A->NumMyRows(), NumVectors) ); assert (Container != Teuchos::null); IFPACK_CHK_ERR(Container->Initialize()); // set as ID all the local rows of A for (int i = 0 ; i < A->NumMyRows() ; ++i) Container->ID(i) = i; // extract submatrix (in this case, the entire matrix) // and complete setup IFPACK_CHK_ERR(Container->Compute(*A)); // set the RHS and LHS for (int i = 0 ; i < A->NumMyRows() ; ++i) for (int j = 0 ; j < NumVectors ; ++j) { Container->RHS(i,j) = RHS[j][i]; Container->LHS(i,j) = LHS[j][i]; } // set parameters (empty for dense containers) Teuchos::ParameterList List; List.set("amesos: solver type", Type); IFPACK_CHK_ERR(Container->SetParameters(List)); // solve the linear system IFPACK_CHK_ERR(Container->ApplyInverse()); // get the computed solution, store it in LHS for (int i = 0 ; i < A->NumMyRows() ; ++i) for (int j = 0 ; j < NumVectors ; ++j) { LHS[j][i] = Container->LHS(i,j); } double residual = Galeri::ComputeNorm(&LHS, &LHS_exact); if (A->Comm().MyPID() == 0 && verbose) { cout << "||x_exact - x||_2 = " << residual << endl; cout << *Container; } bool passed = false; if (residual < 1e-5) passed = true; return(passed); }
int main(int argc, char *argv[]) { using std::cout; using std::endl; int ierr = 0, i, j; int nx, ny; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); //int size, rank; // Number of MPI processes, My process ID //MPI_Comm_size(MPI_COMM_WORLD, &size); //MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else //int size = 1; // Serial case (not using MPI) //int rank = 0; Epetra_SerialComm Comm; #endif bool verbose = false; int nextarg = 1; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') { verbose = true; nextarg++; } // char tmp; // if (rank==0) cout << "Press any key to continue..."<< endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if (verbose && MyPID==0) cout << Ifpack_Version() << endl << endl; if (verbose) cout << Comm <<endl; //int sqrtNumProc = (int) ceil(sqrt((double) NumProc)); bool verbose1 = verbose; verbose = verbose && (MyPID==0); if (verbose1 && argc != 4) { nx = 10; ny = 12*NumProc; cout << "Setting nx = " << nx << ", ny = " << ny << endl; } else if (!verbose1 && argc != 3) { nx = 10; ny = 12*NumProc; } else { nx = atoi(argv[nextarg++]); if (nx<3) {cout << "nx = " << nx << ": Must be greater than 2 for meaningful graph." << endl; exit(1);} ny = atoi(argv[nextarg++]); if (ny<3) {cout << "ny = " << ny << ": Must be greater than 2 for meaningful graph." << endl; exit(1);} } int NumGlobalPoints = nx*ny; int IndexBase = 0; if (verbose) cout << "\n\n*****Building 5 point matrix, Level 1 and 2 filled matrices for" << endl << " nx = " << nx << ", ny = " << ny << endl<< endl; // Create a 5 point stencil graph, level 1 fill of it and level 2 fill of it Epetra_Map Map(NumGlobalPoints, IndexBase, Comm); int NumMyPoints = Map.NumMyPoints(); Epetra_CrsGraph A(Copy, Map, 5); Epetra_CrsGraph L0(Copy, Map, Map, 2); Epetra_CrsGraph U0(Copy, Map, Map, 2); Epetra_CrsGraph L1(Copy, Map, Map, 3); Epetra_CrsGraph U1(Copy, Map, Map, 3); Epetra_CrsGraph L2(Copy, Map, Map, 4); Epetra_CrsGraph U2(Copy, Map, Map, 4); // Add rows one-at-a-time std::vector<int> Indices(4); // Work space for (j=0; j<ny; j++) { for (i=0; i<nx; i++) { int Row = i+j*nx; if (Map.MyGID(Row)) { // Only work on rows I own //**** Work on lower triangle of all three matrices **** // Define entries (i-1,j), (i,j-1) int k = 0; if (i>0) Indices[k++] = i-1 + j *nx; if (j>0) Indices[k++] = i +(j-1)*nx; // Define lower triangular terms of original matrix and L(0) assert(A.InsertGlobalIndices(Row, k, &Indices[0])>=0); assert(L0.InsertGlobalIndices(Row, k, &Indices[0])>=0); // Define entry (i+1,j-1) if ((i<nx-1) && (j>0 )) Indices[k++] = i+1 +(j-1)*nx; // Define lower triangle of level(1) fill matrix assert(L1.InsertGlobalIndices(Row, k, &Indices[0])>=0); // Define entry (i+2, j-1) if ((i<nx-2) && (j>0 )) Indices[k++] = i+2 +(j-1)*nx; // Define lower triangle of level(2) fill matrix assert(L2.InsertGlobalIndices(Row, k, &Indices[0])>=0); // Define main diagonal of original matrix assert(A.InsertGlobalIndices(Row, 1, &Row)>=0); k = 0; // Reset index counter //**** Work on upper triangle of all three matrices **** // Define entries (i+1,j), ( i,j+1) if (i<nx-1) Indices[k++] = i+1 + j *nx; if (j<ny-1) Indices[k++] = i +(j+1)*nx; // Define upper triangular terms of original matrix and L(0) assert(A.InsertGlobalIndices(Row, k, &Indices[0])>=0); assert(U0.InsertGlobalIndices(Row, k, &Indices[0])>=0); // Define entry (i-1,j+1) if ((i>0 ) && (j<ny-1)) Indices[k++] = i-1 +(j+1)*nx; // Define upper triangle of level(1) fill matrix assert(U1.InsertGlobalIndices(Row, k, &Indices[0])>=0); // Define entry (i-2, j+1) if ((i>1 ) && (j<ny-1)) Indices[k++] = i-2 +(j+1)*nx; // Define upper triangle of level(2) fill matrix assert(U2.InsertGlobalIndices(Row, k, &Indices[0])>=0); } } } // Finish up if (verbose) cout << "\n\nCompleting A" << endl<< endl; assert(A.FillComplete()==0); if (verbose) cout << "\n\nCompleting L0" << endl<< endl; assert(L0.FillComplete()==0); if (verbose) cout << "\n\nCompleting U0" << endl<< endl; assert(U0.FillComplete()==0); if (verbose) cout << "\n\nCompleting L1" << endl<< endl; assert(L1.FillComplete()==0); if (verbose) cout << "\n\nCompleting U1" << endl<< endl; assert(U1.FillComplete()==0); if (verbose) cout << "\n\nCompleting L2" << endl<< endl; assert(L2.FillComplete()==0); if (verbose) cout << "\n\nCompleting U2" << endl<< endl; assert(U2.FillComplete()==0); if (verbose) cout << "\n\n*****Testing ILU(0) constructor on A" << endl<< endl; Ifpack_IlukGraph ILU0(A, 0, 0); assert(ILU0.ConstructFilledGraph()==0); assert(check(L0, U0, ILU0, NumGlobalPoints, NumMyPoints, 0, verbose)==0); if (verbose) cout << "\n\n*****Testing ILU(1) constructor on A" << endl<< endl; Ifpack_IlukGraph ILU1(A, 1, 0); assert(ILU1.ConstructFilledGraph()==0); assert(check(L1, U1, ILU1, NumGlobalPoints, NumMyPoints, 1, verbose)==0); if (verbose) cout << "\n\n*****Testing ILU(2) constructor on A" << endl<< endl; Ifpack_IlukGraph ILU2(A, 2, 0); assert(ILU2.ConstructFilledGraph()==0); assert(check(L2, U2, ILU2, NumGlobalPoints, NumMyPoints, 2, verbose)==0); if (verbose) cout << "\n\n*****Testing copy constructor" << endl<< endl; Ifpack_IlukGraph ILUC(ILU2); assert(check(L2, U2, ILUC, NumGlobalPoints, NumMyPoints, 2, verbose)==0); if (verbose) cout << "\n\n*****Testing copy constructor" << endl<< endl; Teuchos::RefCountPtr<Ifpack_IlukGraph> OverlapGraph; for (int overlap = 1; overlap < 4; overlap++) { if (verbose) cout << "\n\n*********************************************" << endl; if (verbose) cout << "\n\nConstruct Level 1 fill with Overlap = " << overlap << ".\n\n" << endl; OverlapGraph = Teuchos::rcp( new Ifpack_IlukGraph(A, 1, overlap) ); assert(OverlapGraph->ConstructFilledGraph()==0); if (verbose) { cout << "Number of Global Rows = " << OverlapGraph->NumGlobalRows() << endl; cout << "Number of Global Nonzeros = " << OverlapGraph->NumGlobalNonzeros() << endl; cout << "Number of Local Rows = " << OverlapGraph->NumMyRows() << endl; cout << "Number of Local Nonzeros = " << OverlapGraph->NumMyNonzeros() << endl; } } if (verbose1) { // Test ostream << operator (if verbose1) // Construct a Map that puts 6 equations on each PE int NumElements1 = 6; int NumPoints1 = NumElements1; // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of terms for the ith global equation on this processor std::vector<int> NumNz1(NumPoints1); // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for (i=0; i<NumPoints1; i++) if (i==0 || i == NumPoints1-1) NumNz1[i] = 2; else NumNz1[i] = 3; // Create a Epetra_Matrix Epetra_Map Map1(NumPoints1, NumPoints1, 1, Comm); Epetra_CrsGraph A1(Copy, Map1, &NumNz1[0]); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 std::vector<int> Indices1(2); int NumEntries1; for (i=0; i<NumPoints1; i++) { if (i==0) { Indices1[0] = 2; NumEntries1 = 1; } else if (i == NumPoints1-1) { Indices1[0] = NumPoints1-1; NumEntries1 = 1; } else { Indices1[0] = i; Indices1[1] = i+2; NumEntries1 = 2; } assert(A1.InsertGlobalIndices(i+1, NumEntries1, &Indices1[0])==0); int ip1 = i+1; assert(A1.InsertGlobalIndices(ip1, 1, &ip1)==0); // Put in the diagonal entry } // Finish up assert(A1.FillComplete()==0); if (verbose) cout << "\n\nPrint out tridiagonal matrix with IndexBase = 1.\n\n" << endl; cout << A1 << endl; if (verbose) cout << "\n\nConstruct Level 1 fill with IndexBase = 1.\n\n" << endl; Ifpack_IlukGraph ILU11(A1, 1, 0); assert(ILU11.ConstructFilledGraph()==0); if (verbose) cout << "\n\nPrint out Level 1 ILU graph of tridiagonal matrix with IndexBase = 1.\n\n" << endl; if (verbose1) cout << ILU11 << endl; } #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif if (Comm.NumProc() == 1) { #ifdef HAVE_MPI MPI_Finalize(); #endif cout << "Test `TestOverlappingRowMatrix.exe' passed!" << endl; exit(EXIT_SUCCESS); } Teuchos::ParameterList GaleriList; int nx = 100; GaleriList.set("n", nx * nx); GaleriList.set("nx", nx); GaleriList.set("ny", nx); Teuchos::RefCountPtr<Epetra_Map> Map = Teuchos::rcp( Galeri::CreateMap64("Linear", Comm, GaleriList) ); Teuchos::RefCountPtr<Epetra_CrsMatrix> A = Teuchos::rcp( Galeri::CreateCrsMatrix("Laplace2D", &*Map, GaleriList) ); int OverlapLevel = 5; Epetra_Time Time(Comm); // ======================================== // // Build the overlapping matrix using class // // Ifpack_OverlappingRowMatrix. // // ======================================== // Time.ResetStartTime(); Ifpack_OverlappingRowMatrix B(A,OverlapLevel); if (Comm.MyPID() == 0) cout << "Time to create B = " << Time.ElapsedTime() << endl; long long NumGlobalRowsB = B.NumGlobalRows64(); long long NumGlobalNonzerosB = B.NumGlobalNonzeros64(); Epetra_Vector X(A->RowMatrixRowMap()); Epetra_Vector Y(A->RowMatrixRowMap()); for (int i = 0 ; i < A->NumMyRows() ; ++i) X[i] = 1.0* A->RowMatrixRowMap().GID64(i); Y.PutScalar(0.0); Epetra_Vector ExtX_B(B.RowMatrixRowMap()); Epetra_Vector ExtY_B(B.RowMatrixRowMap()); ExtY_B.PutScalar(0.0); IFPACK_CHK_ERR(B.ImportMultiVector(X,ExtX_B)); IFPACK_CHK_ERR(B.Multiply(false,ExtX_B,ExtY_B)); IFPACK_CHK_ERR(B.ExportMultiVector(ExtY_B,Y,Add)); double Norm_B; Y.Norm2(&Norm_B); if (Comm.MyPID() == 0) cout << "Norm of Y using B = " << Norm_B << endl; // ================================================== // //Build the overlapping matrix as an Epetra_CrsMatrix // // ================================================== // Time.ResetStartTime(); Epetra_CrsMatrix& C = *(Ifpack_CreateOverlappingCrsMatrix(&*A,OverlapLevel)); if (Comm.MyPID() == 0) cout << "Time to create C = " << Time.ElapsedTime() << endl; // simple checks on global quantities long long NumGlobalRowsC = C.NumGlobalRows64(); long long NumGlobalNonzerosC = C.NumGlobalNonzeros64(); assert (NumGlobalRowsB == NumGlobalRowsC); assert (NumGlobalNonzerosB == NumGlobalNonzerosC); Epetra_Vector ExtX_C(C.RowMatrixRowMap()); Epetra_Vector ExtY_C(C.RowMatrixRowMap()); ExtY_C.PutScalar(0.0); Y.PutScalar(0.0); IFPACK_CHK_ERR(C.Multiply(false,X,Y)); double Norm_C; Y.Norm2(&Norm_C); if (Comm.MyPID() == 0) cout << "Norm of Y using C = " << Norm_C << endl; if (IFPACK_ABS(Norm_B - Norm_C) > 1e-5) IFPACK_CHK_ERR(-1); // ======================= // // now localize the matrix // // ======================= // Ifpack_LocalFilter D(Teuchos::rcp(&B, false)); #ifdef HAVE_MPI MPI_Finalize() ; #endif if (Comm.MyPID() == 0) cout << "Test `TestOverlappingRowMatrix.exe' passed!" << endl; return(EXIT_SUCCESS); }