//----------------------------------------------------------------------------- double dolfin::residual(const GenericLinearOperator& A, const GenericVector& x, const GenericVector& b) { std::shared_ptr<GenericVector> y = x.factory().create_vector(x.mpi_comm()); A.mult(x, *y); *y -= b; return y->norm("l2"); }
//----------------------------------------------------------------------------- bool dolfin::in_nullspace(const GenericLinearOperator& A, const VectorSpaceBasis& basis, std::string type) { // Tolerance (maybe this should be a parameter?) const double tol = 1.0e-7; // Get dimension, and return if basis is empty const std::size_t dim = basis.dim(); if (dim == 0) return true; // Get factory and create vector for LHS dolfin_assert(basis[0]); GenericLinearAlgebraFactory& factory = basis[0]->factory(); std::shared_ptr<GenericVector> y = factory.create_vector(basis[0]->mpi_comm()); const GenericMatrix* _A = NULL; if (type == "right") { // Do nothing } else if (type == "left") { const GenericMatrix* _A = dynamic_cast<const GenericMatrix*>(&A); if (!_A) { dolfin_error("test_nullspace.cpp", "calling is_nullspace(...)", "Left nullspace can be tested for GenericMatrix only (not GenericLinearOperator)"); } } else { dolfin_error("test_nullspace.cpp", "calling is_nullspace(...)", "Left nullspace can be tested for GenericMatrix only (not GenericLinearOperator)"); } // Test nullspace for (std::size_t i = 0; i < dim; ++i) { std::shared_ptr<const GenericVector> x = basis[i]; dolfin_assert(x); if (!_A) A.mult(*x, *y); else _A->transpmult(*x, *y); if (y->norm("l2") > tol) return false; } return true; }
int usermult(Mat A, Vec x, Vec y) { // Wrap PETSc Vec as dolfin::PETScVector boost::shared_ptr<Vec> _x(&x, NoDeleter()); boost::shared_ptr<Vec> _y(&y, NoDeleter()); PETScVector __x(_x); PETScVector __y(_y); // Extract pointer to PETScLinearOperator void* ctx = 0; MatShellGetContext(A, &ctx); PETScLinearOperator* _A = ((PETScLinearOperator*) ctx); // Call user-defined mult function through wrapper dolfin_assert(_A); GenericLinearOperator* wrapper = _A->wrapper(); dolfin_assert(wrapper); wrapper->mult(__x, __y); return 0; }