// ============================================================================ bool ML_Epetra::MatrixFreePreconditioner:: CheckSPD(const Epetra_Operator& A, const bool UseApply, const int NumChecks, const int NumVectors) const { bool res = true; std::vector<double> norm(NumVectors); if (!IsComputed()) return(false); if (MyPID() == 0) std::cout << "Checking SPD property of the operator... " << std::endl; Epetra_MultiVector X(A.OperatorDomainMap(), NumVectors); Epetra_MultiVector AX(A.OperatorRangeMap(), NumVectors); try { for (int i = 0; i < NumChecks; ++i) { int ierr; if (X.Random()) res = false; if (UseApply) ierr = A.Apply(X, AX); else ierr = A.ApplyInverse(X, AX); if (ierr < 0) throw(-1); AX.Dot(X, &norm[0]); for (int v = 0; v < NumVectors; ++v) { std::cout << norm[v] << std::endl; if (norm[v] <= 0.0) throw(-2); } } } catch(...) { res = false; } if (MyPID() == 0) { if (res) std::cout << "Passed: all x * A * x are positive." << std::endl; else std::cout << "Failed: some x * A * x are negative or zero!" << std::endl; } return(res); }
Teuchos::RCP<Epetra_CrsMatrix> Epetra_Operator_to_Epetra_Matrix::constructInverseMatrix(const Epetra_Operator &op, const Epetra_Map &map) { int numEntriesPerRow = 0; Teuchos::RCP<Epetra_FECrsMatrix> matrix = Teuchos::rcp(new Epetra_FECrsMatrix(::Copy, map, numEntriesPerRow)); int numRows = map.NumGlobalElements(); Epetra_Vector X(map); Epetra_Vector Y(map); double tol = 1e-15; // values below this will be considered 0 for (int rowIndex=0; rowIndex<numRows; rowIndex++) { int lid = map.LID(rowIndex); if (lid != -1) { X[lid] = 1.0; } op.ApplyInverse(X, Y); if (lid != -1) { X[lid] = 0.0; } std::vector<double> values; std::vector<int> indices; for (int i=0; i<map.NumMyElements(); i++) { if (abs(Y[i]) > tol) { values.push_back(Y[i]); indices.push_back(map.GID(i)); } } matrix->InsertGlobalValues(rowIndex, values.size(), &values[0], &indices[0]); } matrix->GlobalAssemble(); return matrix; }