// ====================================================================== int CompareBlockSizes(string PrecType, const Teuchos::RefCountPtr<Epetra_RowMatrix>& A, int NumParts) { Epetra_MultiVector RHS(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector LHS(A->RowMatrixRowMap(), NumVectors); LHS.PutScalar(0.0); RHS.Random(); Epetra_LinearProblem Problem(&*A, &LHS, &RHS); Teuchos::ParameterList List; List.set("relaxation: damping factor", 1.0); List.set("relaxation: type", PrecType); List.set("relaxation: sweeps",1); List.set("partitioner: type", "linear"); List.set("partitioner: local parts", NumParts); RHS.PutScalar(1.0); LHS.PutScalar(0.0); Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_Amesos> > Prec(&*A); Prec.SetParameters(List); Prec.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(&Prec); AztecOOSolver.Iterate(2550,1e-5); return(AztecOOSolver.NumIters()); }
// ====================================================================== 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 AllSingle(const Teuchos::RefCountPtr<Epetra_RowMatrix>& A, Teuchos::RCP<Epetra_MultiVector> coord) { Epetra_MultiVector LHS(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector RHS(A->RowMatrixRowMap(), NumVectors); LHS.PutScalar(0.0); RHS.Random(); Epetra_LinearProblem Problem(&*A, &LHS, &RHS); Teuchos::ParameterList List; List.set("relaxation: damping factor", 1.0); List.set("relaxation: type", "symmetric Gauss-Seidel"); List.set("relaxation: sweeps",1); List.set("partitioner: overlap",0); List.set("partitioner: type", "line"); List.set("partitioner: line detection threshold",1.0); List.set("partitioner: x-coordinates",&(*coord)[0][0]); List.set("partitioner: y-coordinates",&(*coord)[1][0]); List.set("partitioner: z-coordinates",(double*) 0); RHS.PutScalar(1.0); LHS.PutScalar(0.0); Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_Amesos> > Prec(&*A); Prec.SetParameters(List); Prec.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(&Prec); AztecOOSolver.Iterate(2550,1e-5); printf(" AllSingle iters %d \n",AztecOOSolver.NumIters()); return(AztecOOSolver.NumIters()); }
// ====================================================================== int CompareLineSmootherEntries(const Teuchos::RefCountPtr<Epetra_RowMatrix>& A) { Epetra_MultiVector LHS(A->RowMatrixRowMap(), NumVectors); Epetra_MultiVector RHS(A->RowMatrixRowMap(), NumVectors); LHS.PutScalar(0.0); RHS.Random(); Epetra_LinearProblem Problem(&*A, &LHS, &RHS); Teuchos::ParameterList List; List.set("relaxation: damping factor", 1.0); List.set("relaxation: type", "symmetric Gauss-Seidel"); List.set("relaxation: sweeps",1); List.set("partitioner: overlap",0); List.set("partitioner: type", "line"); List.set("partitioner: line mode","matrix entries"); List.set("partitioner: line detection threshold",10.0); RHS.PutScalar(1.0); LHS.PutScalar(0.0); Ifpack_BlockRelaxation<Ifpack_SparseContainer<Ifpack_Amesos> > Prec(&*A); Prec.SetParameters(List); Prec.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(&Prec); AztecOOSolver.Iterate(2550,1e-5); return(AztecOOSolver.NumIters()); }
// ====================================================================== 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[]) { #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); }