void Test(const string what, Epetra_RowMatrix& A) { T Prec(&A); bool UseTranspose = true; IFPACK_CHK_ERRV(Prec.Initialize()); IFPACK_CHK_ERRV(Prec.Compute()); IFPACK_CHK_ERRV(Prec.SetUseTranspose(UseTranspose)); Epetra_MultiVector LHS_exact(A.OperatorDomainMap(), 2); Epetra_MultiVector LHS(A.OperatorDomainMap(), 2); Epetra_MultiVector RHS(A.OperatorRangeMap(), 2); LHS_exact.Random(); LHS.PutScalar(0.0); A.Multiply(UseTranspose, LHS_exact, RHS); Prec.ApplyInverse(RHS, LHS); LHS.Update(1.0, LHS_exact, -1.0); double norm[2]; LHS.Norm2(norm); norm[0] += norm[1]; if (norm[0] > 1e-5) { cout << what << ": Test failed: norm = " << norm[0] << endl; exit(EXIT_FAILURE); } cout << what << ": Test passed: norm = " << norm[0] << endl; }
// ====================================================================== bool TestContainer(string Type, const Teuchos::RefCountPtr<Epetra_RowMatrix>& A) { 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); }