$extrastylesheet
libMesh::PetscLinearSolver< T > Class Template Reference

#include <petsc_linear_solver.h>

Inheritance diagram for libMesh::PetscLinearSolver< T >:

List of all members.

Public Member Functions

 PetscLinearSolver (const libMesh::Parallel::Communicator &comm_in LIBMESH_CAN_DEFAULT_TO_COMMWORLD)
 ~PetscLinearSolver ()
void clear ()
void init (const char *name=NULL)
void init (PetscMatrix< T > *matrix, const char *name=NULL)
virtual void init_names (const System &)
virtual void restrict_solve_to (const std::vector< unsigned int > *const dofs, const SubsetSolveMode subset_solve_mode=SUBSET_ZERO)
std::pair< unsigned int, Realsolve (SparseMatrix< T > &matrix_in, NumericVector< T > &solution_in, NumericVector< T > &rhs_in, const double tol, const unsigned int m_its)
std::pair< unsigned int, Realadjoint_solve (SparseMatrix< T > &matrix_in, NumericVector< T > &solution_in, NumericVector< T > &rhs_in, const double tol, const unsigned int m_its)
std::pair< unsigned int, Realsolve (SparseMatrix< T > &matrix, SparseMatrix< T > &preconditioner, NumericVector< T > &solution, NumericVector< T > &rhs, const double tol, const unsigned int m_its)
std::pair< unsigned int, Realsolve (const ShellMatrix< T > &shell_matrix, NumericVector< T > &solution_in, NumericVector< T > &rhs_in, const double tol, const unsigned int m_its)
virtual std::pair< unsigned
int, Real
solve (const ShellMatrix< T > &shell_matrix, const SparseMatrix< T > &precond_matrix, NumericVector< T > &solution_in, NumericVector< T > &rhs_in, const double tol, const unsigned int m_its)
PC pc ()
KSP ksp ()
void get_residual_history (std::vector< double > &hist)
Real get_initial_residual ()
virtual LinearConvergenceReason get_converged_reason () const
bool initialized () const
SolverType solver_type () const
void set_solver_type (const SolverType st)
PreconditionerType preconditioner_type () const
void set_preconditioner_type (const PreconditionerType pct)
void attach_preconditioner (Preconditioner< T > *preconditioner)
virtual void reuse_preconditioner (bool)
bool get_same_preconditioner ()
std::pair< unsigned int, Realsolve (SparseMatrix< T > &matrix, SparseMatrix< T > *precond_matrix, NumericVector< T > &, NumericVector< T > &, const double, const unsigned int)
std::pair< unsigned int, Realsolve (const ShellMatrix< T > &matrix, const SparseMatrix< T > *precond_matrix, NumericVector< T > &, NumericVector< T > &, const double, const unsigned int)
virtual void print_converged_reason () const
const Parallel::Communicatorcomm () const
processor_id_type n_processors () const
processor_id_type processor_id () const

Static Public Member Functions

static UniquePtr< LinearSolver
< T > > 
build (const libMesh::Parallel::Communicator &comm_in, const SolverPackage solver_package=libMesh::default_solver_package())
static std::string get_info ()
static void print_info (std::ostream &out=libMesh::out)
static unsigned int n_objects ()
static void enable_print_counter_info ()
static void disable_print_counter_info ()

Protected Types

typedef std::map< std::string,
std::pair< unsigned int,
unsigned int > > 
Counts

Protected Member Functions

void increment_constructor_count (const std::string &name)
void increment_destructor_count (const std::string &name)

Protected Attributes

SolverType _solver_type
PreconditionerType _preconditioner_type
bool _is_initialized
Preconditioner< T > * _preconditioner
bool same_preconditioner
const Parallel::Communicator_communicator

Static Protected Attributes

static Counts _counts
static Threads::atomic
< unsigned int > 
_n_objects
static Threads::spin_mutex _mutex
static bool _enable_print_counter = true

Private Member Functions

void set_petsc_solver_type ()
PetscInt _restrict_solve_to_is_local_size (void) const
void _create_complement_is (const NumericVector< T > &vec_in)

Static Private Member Functions

static PetscErrorCode _petsc_shell_matrix_mult (Mat mat, Vec arg, Vec dest)
static PetscErrorCode _petsc_shell_matrix_mult_add (Mat mat, Vec arg, Vec add, Vec dest)
static PetscErrorCode _petsc_shell_matrix_get_diagonal (Mat mat, Vec dest)

Private Attributes

SLES _sles
PC _pc
KSP _ksp
IS _restrict_solve_to_is
IS _restrict_solve_to_is_complement
SubsetSolveMode _subset_solve_mode

Detailed Description

template<typename T>
class libMesh::PetscLinearSolver< T >

This class provides an interface to PETSc iterative solvers that is compatible with the libMesh LinearSolver<>

Author:
Benjamin Kirk, 2002-2007

Definition at line 98 of file petsc_linear_solver.h.


Member Typedef Documentation

typedef std::map<std::string, std::pair<unsigned int, unsigned int> > libMesh::ReferenceCounter::Counts [protected, inherited]

Data structure to log the information. The log is identified by the class name.

Definition at line 113 of file reference_counter.h.


Constructor & Destructor Documentation

template<typename T >
libMesh::PetscLinearSolver< T >::PetscLinearSolver ( const libMesh::Parallel::Communicator &comm_in  LIBMESH_CAN_DEFAULT_TO_COMMWORLD) [inline]
template<typename T >
libMesh::PetscLinearSolver< T >::~PetscLinearSolver ( ) [inline]

Destructor.

Definition at line 352 of file petsc_linear_solver.h.

{
  this->clear ();
}

Member Function Documentation

template<typename T >
void libMesh::PetscLinearSolver< T >::_create_complement_is ( const NumericVector< T > &  vec_in) [private]

Creates _restrict_solve_to_is_complement to contain all indices that are local in vec_in, except those that are contained in _restrict_solve_to_is.

Definition at line 377 of file petsc_linear_solver.h.

References libMesh::ierr, and libMesh::libmesh_assert().

{
  libmesh_assert(_restrict_solve_to_is);
#if PETSC_VERSION_LESS_THAN(3,0,0)
  // No ISComplement in PETSc 2.3.3
  libmesh_not_implemented();
#else
  if(_restrict_solve_to_is_complement==NULL)
    {
      int ierr = ISComplement(_restrict_solve_to_is,
                              vec_in.first_local_index(),
                              vec_in.last_local_index(),
                              &_restrict_solve_to_is_complement);
      LIBMESH_CHKERRABORT(ierr);
    }
#endif
}
template<typename T >
PetscErrorCode libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_get_diagonal ( Mat  mat,
Vec  dest 
) [static, private]

Internal function if shell matrix mode is used.

Definition at line 1993 of file petsc_linear_solver.C.

References libMesh::ParallelObject::comm(), libMesh::Parallel::Communicator::get(), libMesh::ShellMatrix< T >::get_diagonal(), and libMesh::ierr.

{
  /* Get the matrix context.  */
  PetscErrorCode ierr=0;
  void* ctx;
  ierr = MatShellGetContext(mat,&ctx);

  /* Get user shell matrix object.  */
  const ShellMatrix<T>& shell_matrix = *static_cast<const ShellMatrix<T>*>(ctx);
  CHKERRABORT(shell_matrix.comm().get(), ierr);

  /* Make \p NumericVector instances around the vector.  */
  PetscVector<T> dest_global(dest, shell_matrix.comm());

  /* Call the user function.  */
  shell_matrix.get_diagonal(dest_global);

  return ierr;
}
template<typename T >
PetscErrorCode libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult ( Mat  mat,
Vec  arg,
Vec  dest 
) [static, private]

Internal function if shell matrix mode is used.

Definition at line 1939 of file petsc_linear_solver.C.

References libMesh::ParallelObject::comm(), libMesh::Parallel::Communicator::get(), libMesh::ierr, and libMesh::ShellMatrix< T >::vector_mult().

{
  /* Get the matrix context.  */
  PetscErrorCode ierr=0;
  void* ctx;
  ierr = MatShellGetContext(mat,&ctx);

  /* Get user shell matrix object.  */
  const ShellMatrix<T>& shell_matrix = *static_cast<const ShellMatrix<T>*>(ctx);
  CHKERRABORT(shell_matrix.comm().get(), ierr);

  /* Make \p NumericVector instances around the vectors.  */
  PetscVector<T> arg_global(arg, shell_matrix.comm());
  PetscVector<T> dest_global(dest, shell_matrix.comm());

  /* Call the user function.  */
  shell_matrix.vector_mult(dest_global,arg_global);

  return ierr;
}
template<typename T >
PetscErrorCode libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult_add ( Mat  mat,
Vec  arg,
Vec  add,
Vec  dest 
) [static, private]

Internal function if shell matrix mode is used.

Definition at line 1963 of file petsc_linear_solver.C.

References libMesh::ParallelObject::comm(), libMesh::Parallel::Communicator::get(), libMesh::ierr, and libMesh::ShellMatrix< T >::vector_mult_add().

{
  /* Get the matrix context.  */
  PetscErrorCode ierr=0;
  void* ctx;
  ierr = MatShellGetContext(mat,&ctx);

  /* Get user shell matrix object.  */
  const ShellMatrix<T>& shell_matrix = *static_cast<const ShellMatrix<T>*>(ctx);
  CHKERRABORT(shell_matrix.comm().get(), ierr);

  /* Make \p NumericVector instances around the vectors.  */
  PetscVector<T> arg_global(arg, shell_matrix.comm());
  PetscVector<T> dest_global(dest, shell_matrix.comm());
  PetscVector<T> add_global(add, shell_matrix.comm());

  if(add!=arg)
    {
      arg_global = add_global;
    }

  /* Call the user function.  */
  shell_matrix.vector_mult_add(dest_global,arg_global);

  return ierr;
}
template<typename T >
PetscInt libMesh::PetscLinearSolver< T >::_restrict_solve_to_is_local_size ( void  ) const [inline, private]

Internal method that returns the local size of _restrict_solve_to_is.

Definition at line 362 of file petsc_linear_solver.h.

References libMesh::ierr, and libMesh::libmesh_assert().

{
  libmesh_assert(_restrict_solve_to_is);

  PetscInt s;
  int ierr = ISGetLocalSize(_restrict_solve_to_is,&s);
  LIBMESH_CHKERRABORT(ierr);

  return s;
}
template<typename T >
std::pair< unsigned int, Real > libMesh::PetscLinearSolver< T >::adjoint_solve ( SparseMatrix< T > &  matrix_in,
NumericVector< T > &  solution_in,
NumericVector< T > &  rhs_in,
const double  tol,
const unsigned int  m_its 
) [virtual]

Call the Petsc solver. It calls the method below, using the same matrix for the system and preconditioner matrices.

Reimplemented from libMesh::LinearSolver< T >.

Definition at line 805 of file petsc_linear_solver.C.

References libMesh::PetscMatrix< T >::close(), libMesh::ierr, libMesh::TriangleWrapper::init(), libMesh::PetscMatrix< T >::init(), libMesh::NumericVector< T >::local_size(), libMesh::PetscMatrix< T >::mat(), PetscBool, libMesh::START_LOG(), libMesh::SUBSET_COPY_RHS, libMesh::SUBSET_DONT_TOUCH, and libMesh::SUBSET_ZERO.

{
  START_LOG("solve()", "PetscLinearSolver");

  // Make sure the data passed in are really of Petsc types
  PetscMatrix<T>* matrix   = cast_ptr<PetscMatrix<T>*>(&matrix_in);
  // Note that the matrix and precond matrix are the same
  PetscMatrix<T>* precond  = cast_ptr<PetscMatrix<T>*>(&matrix_in);
  PetscVector<T>* solution = cast_ptr<PetscVector<T>*>(&solution_in);
  PetscVector<T>* rhs      = cast_ptr<PetscVector<T>*>(&rhs_in);

  this->init (matrix);

  PetscErrorCode ierr=0;
  PetscInt its=0, max_its = static_cast<PetscInt>(m_its);
  PetscReal final_resid=0.;

  // Close the matrices and vectors in case this wasn't already done.
  matrix->close ();
  precond->close ();
  solution->close ();
  rhs->close ();

  //   // If matrix != precond, then this means we have specified a
  //   // special preconditioner, so reset preconditioner type to PCMAT.
  //   if (matrix != precond)
  //     {
  //       this->_preconditioner_type = USER_PRECOND;
  //       this->set_petsc_preconditioner_type ();
  //     }

  // 2.1.x & earlier style
#if PETSC_VERSION_LESS_THAN(2,2,0)

  if(_restrict_solve_to_is!=NULL)
    {
      libmesh_not_implemented();
    }

  // Based on http://wolfgang.math.tamu.edu/svn/public/deal.II/branches/MATH676/2008/deal.II/lac/source/petsc_solver.cc, http://tccc.iesl.forth.gr/AMS_EPEAEK/Elements/doc/in_html/petsc/SLES/index.html

  SLES sles;
  ierr = SLESCreate (this->comm().get(), &sles);
  LIBMESH_CHKERRABORT(ierr);

  ierr = SLESSetOperators (sles, matrix->mat(), precond->mat(), this->same_preconditioner ? SAME_PRECONDITIONER : DIFFERENT_NONZERO_PATTERN);
  LIBMESH_CHKERRABORT(ierr);

  KSP ksp;
  ierr = SLESGetKSP (sles, &ksp);
  LIBMESH_CHKERRABORT(ierr);

  ierr = SLESSetUp (sles, rhs->vec(), solution->vec());
  LIBMESH_CHKERRABORT(ierr);

  // See http://tccc.iesl.forth.gr/AMS_EPEAEK/Elements/doc/in_html/petsc/KSP/KSPSolveTrans.html#KSPSolveTrans
  ierr = SLESSolveTrans (ksp, &its);
  LIBMESH_CHKERRABORT(ierr);

  // 2.2.0
#elif PETSC_VERSION_LESS_THAN(2,2,1)

  if(_restrict_solve_to_is!=NULL)
    {
      libmesh_not_implemented();
    }

  // Set operators. The input matrix works as the preconditioning matrix
  // This was commented earlier but it looks like KSPSetOperators is supported
  // after PETSc 2.2.0
  ierr = KSPSetOperators(_ksp, matrix->mat(), precond->mat(),
                         this->same_preconditioner ? SAME_PRECONDITIONER : DIFFERENT_NONZERO_PATTERN);
  LIBMESH_CHKERRABORT(ierr);


  // Set the tolerances for the iterative solver.  Use the user-supplied
  // tolerance for the relative residual & leave the others at default values.
  // Convergence is detected at iteration k if
  // ||r_k||_2 < max(rtol*||b||_2 , abstol)
  // where r_k is the residual vector and b is the right-hand side.  Note that
  // it is the *maximum* of the two values, the larger of which will almost
  // always be rtol*||b||_2.
  ierr = KSPSetTolerances (_ksp,
                           tol,           // rtol   = relative decrease in residual  (1.e-5)
                           PETSC_DEFAULT, // abstol = absolute convergence tolerance (1.e-50)
                           PETSC_DEFAULT, // dtol   = divergence tolerance           (1.e+5)
                           max_its);
  LIBMESH_CHKERRABORT(ierr);


  // Set the solution vector to use
  ierr = KSPSetSolution (_ksp, solution->vec());
  LIBMESH_CHKERRABORT(ierr);

  // Set the RHS vector to use
  ierr = KSPSetRhs (_ksp, rhs->vec());
  LIBMESH_CHKERRABORT(ierr);

  // Solve the linear system
  ierr = KSPSolveTranspose (_ksp);
  LIBMESH_CHKERRABORT(ierr);

  // Get the number of iterations required for convergence
  ierr = KSPGetIterationNumber (_ksp, &its);
  LIBMESH_CHKERRABORT(ierr);

  // Get the norm of the final residual to return to the user.
  ierr = KSPGetResidualNorm (_ksp, &final_resid);
  LIBMESH_CHKERRABORT(ierr);

  // 2.2.1 & newer style
#else

  Mat submat = NULL;
  Mat subprecond = NULL;
  Vec subrhs = NULL;
  Vec subsolution = NULL;
  VecScatter scatter = NULL;
  PetscMatrix<Number>* subprecond_matrix = NULL;

  // Set operators.  Also restrict rhs and solution vector to
  // subdomain if neccessary.
  if(_restrict_solve_to_is!=NULL)
    {
      PetscInt is_local_size = this->_restrict_solve_to_is_local_size();

      ierr = VecCreate(this->comm().get(),&subrhs);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetSizes(subrhs,is_local_size,PETSC_DECIDE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetFromOptions(subrhs);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecCreate(this->comm().get(),&subsolution);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetSizes(subsolution,is_local_size,PETSC_DECIDE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetFromOptions(subsolution);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterCreate(rhs->vec(),_restrict_solve_to_is, subrhs,NULL, &scatter);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterBegin(scatter,rhs->vec(),subrhs,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,rhs->vec(),subrhs,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterBegin(scatter,solution->vec(),subsolution,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,solution->vec(),subsolution,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);

#if PETSC_VERSION_LESS_THAN(3,1,0)
      ierr = MatGetSubMatrix(matrix->mat(),
                             _restrict_solve_to_is,_restrict_solve_to_is,
                             PETSC_DECIDE,MAT_INITIAL_MATRIX,&submat);
      LIBMESH_CHKERRABORT(ierr);
      ierr = MatGetSubMatrix(precond->mat(),
                             _restrict_solve_to_is,_restrict_solve_to_is,
                             PETSC_DECIDE,MAT_INITIAL_MATRIX,&subprecond);
      LIBMESH_CHKERRABORT(ierr);
#else
      ierr = MatGetSubMatrix(matrix->mat(),
                             _restrict_solve_to_is,_restrict_solve_to_is,
                             MAT_INITIAL_MATRIX,&submat);
      LIBMESH_CHKERRABORT(ierr);
      ierr = MatGetSubMatrix(precond->mat(),
                             _restrict_solve_to_is,_restrict_solve_to_is,
                             MAT_INITIAL_MATRIX,&subprecond);
      LIBMESH_CHKERRABORT(ierr);
#endif

      /* Since removing columns of the matrix changes the equation
         system, we will now change the right hand side to compensate
         for this.  Note that this is not necessary if \p SUBSET_ZERO
         has been selected.  */
      if(_subset_solve_mode!=SUBSET_ZERO)
        {
          _create_complement_is(rhs_in);
          PetscInt is_complement_local_size =
            cast_int<PetscInt>(rhs_in.local_size()-is_local_size);

          Vec subvec1 = NULL;
          Mat submat1 = NULL;
          VecScatter scatter1 = NULL;

          ierr = VecCreate(this->comm().get(),&subvec1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetSizes(subvec1,is_complement_local_size,PETSC_DECIDE);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetFromOptions(subvec1);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScatterCreate(rhs->vec(),_restrict_solve_to_is_complement, subvec1,NULL, &scatter1);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScatterBegin(scatter1,_subset_solve_mode==SUBSET_COPY_RHS ? rhs->vec() : solution->vec(),subvec1,INSERT_VALUES,SCATTER_FORWARD);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecScatterEnd(scatter1,_subset_solve_mode==SUBSET_COPY_RHS ? rhs->vec() : solution->vec(),subvec1,INSERT_VALUES,SCATTER_FORWARD);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScale(subvec1,-1.0);
          LIBMESH_CHKERRABORT(ierr);

#if PETSC_VERSION_LESS_THAN(3,1,0)
          ierr = MatGetSubMatrix(matrix->mat(),
                                 _restrict_solve_to_is,_restrict_solve_to_is_complement,
                                 PETSC_DECIDE,MAT_INITIAL_MATRIX,&submat1);
          LIBMESH_CHKERRABORT(ierr);
#else
          ierr = MatGetSubMatrix(matrix->mat(),
                                 _restrict_solve_to_is,_restrict_solve_to_is_complement,
                                 MAT_INITIAL_MATRIX,&submat1);
          LIBMESH_CHKERRABORT(ierr);
#endif

          ierr = MatMultAdd(submat1,subvec1,subrhs,subrhs);
          LIBMESH_CHKERRABORT(ierr);

          ierr = LibMeshVecScatterDestroy(&scatter1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = LibMeshVecDestroy(&subvec1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = LibMeshMatDestroy(&submat1);
          LIBMESH_CHKERRABORT(ierr);
        }
#if PETSC_RELEASE_LESS_THAN(3,5,0)
      ierr = KSPSetOperators(_ksp, submat, subprecond,
                             this->same_preconditioner ? SAME_PRECONDITIONER : DIFFERENT_NONZERO_PATTERN);
#else
      ierr = KSPSetOperators(_ksp, submat, subprecond);

      PetscBool ksp_reuse_preconditioner = this->same_preconditioner ? PETSC_TRUE : PETSC_FALSE;
      ierr = KSPSetReusePreconditioner(_ksp, ksp_reuse_preconditioner);
#endif
      LIBMESH_CHKERRABORT(ierr);

      if(this->_preconditioner)
        {
          subprecond_matrix = new PetscMatrix<Number>(subprecond,
                                                      this->comm());
          this->_preconditioner->set_matrix(*subprecond_matrix);
          this->_preconditioner->init();
        }
    }
  else
    {
#if PETSC_RELEASE_LESS_THAN(3,5,0)
      ierr = KSPSetOperators(_ksp, matrix->mat(), precond->mat(),
                             this->same_preconditioner ? SAME_PRECONDITIONER : DIFFERENT_NONZERO_PATTERN);
#else
      ierr = KSPSetOperators(_ksp, matrix->mat(), precond->mat());

      PetscBool ksp_reuse_preconditioner = this->same_preconditioner ? PETSC_TRUE : PETSC_FALSE;
      ierr = KSPSetReusePreconditioner(_ksp, ksp_reuse_preconditioner);
#endif
      LIBMESH_CHKERRABORT(ierr);

      if(this->_preconditioner)
        {
          this->_preconditioner->set_matrix(matrix_in);
          this->_preconditioner->init();
        }
    }

  // Set the tolerances for the iterative solver.  Use the user-supplied
  // tolerance for the relative residual & leave the others at default values.
  ierr = KSPSetTolerances (_ksp, tol, PETSC_DEFAULT,
                           PETSC_DEFAULT, max_its);
  LIBMESH_CHKERRABORT(ierr);

  // Solve the linear system
  if(_restrict_solve_to_is!=NULL)
    {
      ierr = KSPSolveTranspose (_ksp, subrhs, subsolution);
      LIBMESH_CHKERRABORT(ierr);
    }
  else
    {
      ierr = KSPSolveTranspose (_ksp, rhs->vec(), solution->vec());
      LIBMESH_CHKERRABORT(ierr);
    }

  // Get the number of iterations required for convergence
  ierr = KSPGetIterationNumber (_ksp, &its);
  LIBMESH_CHKERRABORT(ierr);

  // Get the norm of the final residual to return to the user.
  ierr = KSPGetResidualNorm (_ksp, &final_resid);
  LIBMESH_CHKERRABORT(ierr);

  if(_restrict_solve_to_is!=NULL)
    {
      switch(_subset_solve_mode)
        {
        case SUBSET_ZERO:
          ierr = VecZeroEntries(solution->vec());
          LIBMESH_CHKERRABORT(ierr);
          break;

        case SUBSET_COPY_RHS:
          ierr = VecCopy(rhs->vec(),solution->vec());
          LIBMESH_CHKERRABORT(ierr);
          break;

        case SUBSET_DONT_TOUCH:
          /* Nothing to do here.  */
          break;

        default:
          libmesh_error_msg("Invalid subset solve mode = " << _subset_solve_mode);
        }
      ierr = VecScatterBegin(scatter,subsolution,solution->vec(),INSERT_VALUES,SCATTER_REVERSE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,subsolution,solution->vec(),INSERT_VALUES,SCATTER_REVERSE);
      LIBMESH_CHKERRABORT(ierr);

      ierr = LibMeshVecScatterDestroy(&scatter);
      LIBMESH_CHKERRABORT(ierr);

      if(this->_preconditioner)
        {
          /* Before we delete subprecond_matrix, we should give the
             _preconditioner a different matrix.  */
          this->_preconditioner->set_matrix(matrix_in);
          this->_preconditioner->init();
          delete subprecond_matrix;
          subprecond_matrix = NULL;
        }

      ierr = LibMeshVecDestroy(&subsolution);
      LIBMESH_CHKERRABORT(ierr);
      ierr = LibMeshVecDestroy(&subrhs);
      LIBMESH_CHKERRABORT(ierr);
      ierr = LibMeshMatDestroy(&submat);
      LIBMESH_CHKERRABORT(ierr);
      ierr = LibMeshMatDestroy(&subprecond);
      LIBMESH_CHKERRABORT(ierr);
    }

#endif

  STOP_LOG("solve()", "PetscLinearSolver");
  // return the # of its. and the final residual norm.
  return std::make_pair(its, final_resid);
}
template<typename T>
void libMesh::LinearSolver< T >::attach_preconditioner ( Preconditioner< T > *  preconditioner) [inherited]

Attaches a Preconditioner object to be used

Definition at line 101 of file linear_solver.C.

References libMesh::libMeshPrivateData::_is_initialized, and libMesh::SHELL_PRECOND.

{
  if (this->_is_initialized)
    libmesh_error_msg("Preconditioner must be attached before the solver is initialized!");

  _preconditioner_type = SHELL_PRECOND;
  _preconditioner = preconditioner;
}
template<typename T >
UniquePtr< LinearSolver< T > > libMesh::LinearSolver< T >::build ( const libMesh::Parallel::Communicator comm_in,
const SolverPackage  solver_package = libMesh::default_solver_package() 
) [static, inherited]

Builds a LinearSolver using the linear solver package specified by solver_package

Definition at line 41 of file linear_solver.C.

References libMesh::EIGEN_SOLVERS, libMesh::LASPACK_SOLVERS, libMesh::PETSC_SOLVERS, and libMesh::TRILINOS_SOLVERS.

{
  // Build the appropriate solver
  switch (solver_package)
    {


#ifdef LIBMESH_HAVE_LASPACK
    case LASPACK_SOLVERS:
      return UniquePtr<LinearSolver<T> >(new LaspackLinearSolver<T>(comm));
#endif


#ifdef LIBMESH_HAVE_PETSC
    case PETSC_SOLVERS:
      return UniquePtr<LinearSolver<T> >(new PetscLinearSolver<T>(comm));
#endif


#ifdef LIBMESH_HAVE_TRILINOS
    case TRILINOS_SOLVERS:
      return UniquePtr<LinearSolver<T> >(new AztecLinearSolver<T>(comm));
#endif


#ifdef LIBMESH_HAVE_EIGEN
    case EIGEN_SOLVERS:
      return UniquePtr<LinearSolver<T> >(new EigenSparseLinearSolver<T>(comm));
#endif

    default:
      libmesh_error_msg("ERROR:  Unrecognized solver package: " << solver_package);
    }

  return UniquePtr<LinearSolver<T> >();
}
template<typename T >
void libMesh::PetscLinearSolver< T >::clear ( ) [virtual]

Release all memory and clear data structures.

Reimplemented from libMesh::LinearSolver< T >.

Definition at line 107 of file petsc_linear_solver.C.

References libMesh::libMeshPrivateData::_is_initialized, libMesh::BLOCK_JACOBI_PRECOND, libMesh::GMRES, libMesh::ierr, libMesh::ILU_PRECOND, libMesh::initialized(), and libMesh::n_processors().

{
  if (this->initialized())
    {
      /* If we were restricted to some subset, this restriction must
         be removed and the subset index set destroyed.  */
      if(_restrict_solve_to_is!=NULL)
        {
          PetscErrorCode ierr = LibMeshISDestroy(&_restrict_solve_to_is);
          LIBMESH_CHKERRABORT(ierr);
          _restrict_solve_to_is = NULL;
        }

      if(_restrict_solve_to_is_complement!=NULL)
        {
          PetscErrorCode ierr = LibMeshISDestroy(&_restrict_solve_to_is_complement);
          LIBMESH_CHKERRABORT(ierr);
          _restrict_solve_to_is_complement = NULL;
        }

      this->_is_initialized = false;

      PetscErrorCode ierr=0;

#if PETSC_VERSION_LESS_THAN(2,2,0)

      // 2.1.x & earlier style
      ierr = SLESDestroy(_sles);
      LIBMESH_CHKERRABORT(ierr);

#else

      // 2.2.0 & newer style
      ierr = LibMeshKSPDestroy(&_ksp);
      LIBMESH_CHKERRABORT(ierr);

#endif


      // Mimic PETSc default solver and preconditioner
      this->_solver_type           = GMRES;

      if(!this->_preconditioner)
        {
          if (this->n_processors() == 1)
            this->_preconditioner_type = ILU_PRECOND;
          else
            this->_preconditioner_type = BLOCK_JACOBI_PRECOND;
        }
    }
}
const Parallel::Communicator& libMesh::ParallelObject::comm ( ) const [inline, inherited]
Returns:
a reference to the Parallel::Communicator object used by this mesh.

Definition at line 86 of file parallel_object.h.

References libMesh::ParallelObject::_communicator.

Referenced by libMesh::__libmesh_petsc_diff_solver_monitor(), libMesh::__libmesh_petsc_diff_solver_residual(), libMesh::__libmesh_petsc_snes_residual(), libMesh::MeshRefinement::_coarsen_elements(), libMesh::ExactSolution::_compute_error(), libMesh::MetisPartitioner::_do_partition(), libMesh::ParmetisPartitioner::_do_repartition(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult_add(), libMesh::EquationSystems::_read_impl(), libMesh::MeshRefinement::_refine_elements(), libMesh::ImplicitSystem::add_matrix(), libMesh::System::add_vector(), libMesh::UnstructuredMesh::all_second_order(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::FEMSystem::assemble_qoi(), libMesh::MeshCommunication::assign_global_indices(), libMesh::ParmetisPartitioner::assign_partitioning(), libMesh::DofMap::attach_matrix(), libMesh::MeshTools::bounding_box(), libMesh::MeshBase::cache_elem_dims(), libMesh::System::calculate_norm(), libMesh::MeshRefinement::coarsen_elements(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::DofMap::distribute_dofs(), DMlibMeshFunction(), DMlibMeshSetSystem_libMesh(), libMesh::MeshRefinement::eliminate_unrefined_patches(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::MeshRefinement::flag_elements_by_elem_fraction(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::MeshRefinement::flag_elements_by_nelem_target(), libMesh::CondensedEigenSystem::get_eigenpair(), libMesh::ImplicitSystem::get_linear_solver(), libMesh::LocationMap< T >::init(), libMesh::TimeSolver::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::EigenSystem::init_data(), libMesh::EigenSystem::init_matrices(), libMesh::ParmetisPartitioner::initialize(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::ParallelMesh::libmesh_assert_valid_parallel_flags(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::MeshRefinement::limit_level_mismatch_at_edge(), libMesh::MeshRefinement::limit_level_mismatch_at_node(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::MeshCommunication::make_elems_parallel_consistent(), libMesh::MeshRefinement::make_flags_parallel_consistent(), libMesh::MeshCommunication::make_node_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::MeshRefinement::make_refinement_compatible(), libMesh::FEMSystem::mesh_position_set(), libMesh::MeshSerializer::MeshSerializer(), libMesh::ParallelMesh::n_active_elem(), libMesh::MeshTools::n_active_levels(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::CondensedEigenSystem::n_global_non_condensed_dofs(), libMesh::MeshTools::n_levels(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::MeshTools::n_p_levels(), libMesh::ParallelMesh::parallel_max_elem_id(), libMesh::ParallelMesh::parallel_max_node_id(), libMesh::ParallelMesh::parallel_n_elem(), libMesh::ParallelMesh::parallel_n_nodes(), libMesh::Partitioner::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::petsc_auto_fieldsplit(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshBase::prepare_for_use(), libMesh::System::project_vector(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::MeshBase::recalculate_n_partitions(), libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::MeshRefinement::refine_elements(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::MeshBase::subdomain_ids(), libMesh::BoundaryInfo::sync(), libMesh::Parallel::sync_element_data_by_parent_id(), libMesh::Parallel::sync_node_data_by_element_id(), libMesh::MeshRefinement::test_level_one(), libMesh::MeshRefinement::test_unflagged(), libMesh::MeshTools::total_weight(), libMesh::NameBasedIO::write(), libMesh::CheckpointIO::write(), libMesh::XdrIO::write(), libMesh::LegacyXdrIO::write_mesh(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), and libMesh::DivaIO::write_stream().

  { return _communicator; }

Methods to enable/disable the reference counter output from print_info()

Definition at line 100 of file reference_counter.C.

References libMesh::ReferenceCounter::_enable_print_counter.

{
  _enable_print_counter = true;
  return;
}
template<typename T >
LinearConvergenceReason libMesh::PetscLinearSolver< T >::get_converged_reason ( ) const [virtual]

Returns the solver's convergence flag

Implements libMesh::LinearSolver< T >.

Definition at line 1899 of file petsc_linear_solver.C.

References libMesh::CONVERGED_ATOL, libMesh::CONVERGED_ATOL_NORMAL, libMesh::CONVERGED_CG_CONSTRAINED, libMesh::CONVERGED_CG_NEG_CURVE, libMesh::CONVERGED_HAPPY_BREAKDOWN, libMesh::CONVERGED_ITERATING, libMesh::CONVERGED_ITS, libMesh::CONVERGED_RTOL, libMesh::CONVERGED_RTOL_NORMAL, libMesh::CONVERGED_STEP_LENGTH, libMesh::DIVERGED_BREAKDOWN, libMesh::DIVERGED_BREAKDOWN_BICG, libMesh::DIVERGED_DTOL, libMesh::DIVERGED_INDEFINITE_MAT, libMesh::DIVERGED_INDEFINITE_PC, libMesh::DIVERGED_ITS, libMesh::DIVERGED_NAN, libMesh::DIVERGED_NONSYMMETRIC, libMesh::DIVERGED_NULL, libMesh::err, and libMesh::UNKNOWN_FLAG.

{
  KSPConvergedReason reason;
  KSPGetConvergedReason(_ksp, &reason);

  switch(reason)
    {
#if !PETSC_VERSION_LESS_THAN(3,2,0)
    case KSP_CONVERGED_RTOL_NORMAL     : return CONVERGED_RTOL_NORMAL;
    case KSP_CONVERGED_ATOL_NORMAL     : return CONVERGED_ATOL_NORMAL;
#endif
    case KSP_CONVERGED_RTOL            : return CONVERGED_RTOL;
    case KSP_CONVERGED_ATOL            : return CONVERGED_ATOL;
    case KSP_CONVERGED_ITS             : return CONVERGED_ITS;
    case KSP_CONVERGED_CG_NEG_CURVE    : return CONVERGED_CG_NEG_CURVE;
    case KSP_CONVERGED_CG_CONSTRAINED  : return CONVERGED_CG_CONSTRAINED;
    case KSP_CONVERGED_STEP_LENGTH     : return CONVERGED_STEP_LENGTH;
    case KSP_CONVERGED_HAPPY_BREAKDOWN : return CONVERGED_HAPPY_BREAKDOWN;
    case KSP_DIVERGED_NULL             : return DIVERGED_NULL;
    case KSP_DIVERGED_ITS              : return DIVERGED_ITS;
    case KSP_DIVERGED_DTOL             : return DIVERGED_DTOL;
    case KSP_DIVERGED_BREAKDOWN        : return DIVERGED_BREAKDOWN;
    case KSP_DIVERGED_BREAKDOWN_BICG   : return DIVERGED_BREAKDOWN_BICG;
    case KSP_DIVERGED_NONSYMMETRIC     : return DIVERGED_NONSYMMETRIC;
    case KSP_DIVERGED_INDEFINITE_PC    : return DIVERGED_INDEFINITE_PC;
#if PETSC_VERSION_LESS_THAN(3,4,0)
    case KSP_DIVERGED_NAN              : return DIVERGED_NAN;
#else
    case KSP_DIVERGED_NANORINF         : return DIVERGED_NAN;
#endif
    case KSP_DIVERGED_INDEFINITE_MAT   : return DIVERGED_INDEFINITE_MAT;
    case KSP_CONVERGED_ITERATING       : return CONVERGED_ITERATING;
    default :
      libMesh::err << "Unknown convergence flag!" << std::endl;
      return UNKNOWN_FLAG;
    }
}
std::string libMesh::ReferenceCounter::get_info ( ) [static, inherited]

Gets a string containing the reference information.

Definition at line 47 of file reference_counter.C.

References libMesh::ReferenceCounter::_counts, and libMesh::Quality::name().

Referenced by libMesh::ReferenceCounter::print_info().

{
#if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)

  std::ostringstream oss;

  oss << '\n'
      << " ---------------------------------------------------------------------------- \n"
      << "| Reference count information                                                |\n"
      << " ---------------------------------------------------------------------------- \n";

  for (Counts::iterator it = _counts.begin();
       it != _counts.end(); ++it)
    {
      const std::string name(it->first);
      const unsigned int creations    = it->second.first;
      const unsigned int destructions = it->second.second;

      oss << "| " << name << " reference count information:\n"
          << "|  Creations:    " << creations    << '\n'
          << "|  Destructions: " << destructions << '\n';
    }

  oss << " ---------------------------------------------------------------------------- \n";

  return oss.str();

#else

  return "";

#endif
}
template<typename T >
Real libMesh::PetscLinearSolver< T >::get_initial_residual ( )

Returns just the initial residual for the solve just completed with this interface. Use this method instead of the one above if you just want the starting residual and not the entire history.

Definition at line 1785 of file petsc_linear_solver.C.

References libMesh::err, and libMesh::ierr.

{
  PetscErrorCode ierr = 0;
  PetscInt its  = 0;

  // Fill the residual history vector with the residual norms
  // Note that GetResidualHistory() does not copy any values, it
  // simply sets the pointer p.  Note that for some Krylov subspace
  // methods, the number of residuals returned in the history
  // vector may be different from what you are expecting.  For
  // example, TFQMR returns two residual values per iteration step.
  PetscReal* p;
  ierr = KSPGetResidualHistory(_ksp, &p, &its);
  LIBMESH_CHKERRABORT(ierr);

  // Check no residual history
  if (its == 0)
    {
      libMesh::err << "No iterations have been performed, returning 0." << std::endl;
      return 0.;
    }

  // Otherwise, return the value pointed to by p.
  return *p;
}
template<typename T >
void libMesh::PetscLinearSolver< T >::get_residual_history ( std::vector< double > &  hist)

Fills the input vector with the sequence of residual norms from the latest iterative solve.

Definition at line 1752 of file petsc_linear_solver.C.

References libMesh::ierr.

{
  PetscErrorCode ierr = 0;
  PetscInt its  = 0;

  // Fill the residual history vector with the residual norms
  // Note that GetResidualHistory() does not copy any values, it
  // simply sets the pointer p.  Note that for some Krylov subspace
  // methods, the number of residuals returned in the history
  // vector may be different from what you are expecting.  For
  // example, TFQMR returns two residual values per iteration step.
  PetscReal* p;
  ierr = KSPGetResidualHistory(_ksp, &p, &its);
  LIBMESH_CHKERRABORT(ierr);

  // Check for early return
  if (its == 0) return;

  // Create space to store the result
  hist.resize(its);

  // Copy history into the vector provided by the user.
  for (PetscInt i=0; i<its; ++i)
    {
      hist[i] = *p;
      p++;
    }
}
template<typename T >
bool libMesh::LinearSolver< T >::get_same_preconditioner ( ) [inline, inherited]

Definition at line 305 of file linear_solver.h.

{
  return same_preconditioner;
}
void libMesh::ReferenceCounter::increment_constructor_count ( const std::string &  name) [inline, protected, inherited]

Increments the construction counter. Should be called in the constructor of any derived class that will be reference counted.

Definition at line 163 of file reference_counter.h.

References libMesh::ReferenceCounter::_counts, libMesh::Quality::name(), and libMesh::Threads::spin_mtx.

Referenced by libMesh::ReferenceCountedObject< RBParametrized >::ReferenceCountedObject().

{
  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
  std::pair<unsigned int, unsigned int>& p = _counts[name];

  p.first++;
}
void libMesh::ReferenceCounter::increment_destructor_count ( const std::string &  name) [inline, protected, inherited]

Increments the destruction counter. Should be called in the destructor of any derived class that will be reference counted.

Definition at line 176 of file reference_counter.h.

References libMesh::ReferenceCounter::_counts, libMesh::Quality::name(), and libMesh::Threads::spin_mtx.

Referenced by libMesh::ReferenceCountedObject< RBParametrized >::~ReferenceCountedObject().

{
  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
  std::pair<unsigned int, unsigned int>& p = _counts[name];

  p.second++;
}
template<typename T >
void libMesh::PetscLinearSolver< T >::init ( const char *  name = NULL) [virtual]

Initialize data structures if not done so already. Assigns a name, which is turned into an underscore-separated prefix for the underlying KSP object.

Implements libMesh::LinearSolver< T >.

Definition at line 162 of file petsc_linear_solver.C.

References libMesh::__libmesh_petsc_preconditioner_apply(), libMesh::__libmesh_petsc_preconditioner_setup(), libMesh::libMeshPrivateData::_is_initialized, libMesh::ierr, libMesh::initialized(), and libMesh::PetscPreconditioner< T >::set_petsc_preconditioner_type().

Referenced by libMesh::PetscLinearSolver< T >::ksp(), and libMesh::PetscLinearSolver< T >::pc().

{
  // Initialize the data structures if not done so already.
  if (!this->initialized())
    {
      this->_is_initialized = true;

      PetscErrorCode ierr=0;

      // 2.1.x & earlier style
#if PETSC_VERSION_LESS_THAN(2,2,0)

      // Create the linear solver context
      ierr = SLESCreate (this->comm().get(), &_sles);
      LIBMESH_CHKERRABORT(ierr);

      // Create the Krylov subspace & preconditioner contexts
      ierr = SLESGetKSP       (_sles, &_ksp);
      LIBMESH_CHKERRABORT(ierr);
      ierr = SLESGetPC        (_sles, &_pc);
      LIBMESH_CHKERRABORT(ierr);

      // Set user-specified  solver and preconditioner types
      this->set_petsc_solver_type();

      // Set the options from user-input
      // Set runtime options, e.g.,
      //      -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
      //  These options will override those specified above as long as
      //  SLESSetFromOptions() is called _after_ any other customization
      //  routines.

      ierr = SLESSetFromOptions (_sles);
      LIBMESH_CHKERRABORT(ierr);

      // 2.2.0 & newer style
#else

      // Create the linear solver context
      ierr = KSPCreate (this->comm().get(), &_ksp);
      LIBMESH_CHKERRABORT(ierr);

      if (name)
        {
          ierr = KSPSetOptionsPrefix(_ksp, name);
          LIBMESH_CHKERRABORT(ierr);
        }

      // Create the preconditioner context
      ierr = KSPGetPC        (_ksp, &_pc);
      LIBMESH_CHKERRABORT(ierr);

      // Set user-specified  solver and preconditioner types
      this->set_petsc_solver_type();

      // Set the options from user-input
      // Set runtime options, e.g.,
      //      -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
      //  These options will override those specified above as long as
      //  KSPSetFromOptions() is called _after_ any other customization
      //  routines.

      ierr = KSPSetFromOptions (_ksp);
      LIBMESH_CHKERRABORT(ierr);

      // Not sure if this is necessary, or if it is already handled by KSPSetFromOptions?
      // NOT NECESSARY!!!!
      //ierr = PCSetFromOptions (_pc);
      //LIBMESH_CHKERRABORT(ierr);


#endif

      // Have the Krylov subspace method use our good initial guess
      // rather than 0, unless the user requested a KSPType of
      // preonly, which complains if asked to use initial guesses.
#if PETSC_VERSION_LESS_THAN(3,0,0) || !PETSC_RELEASE_LESS_THAN(3,4,0)
      // Pre-3.0 and petsc-dev (as of October 2012) use non-const versions
      KSPType ksp_type;
#else
      const KSPType ksp_type;
#endif

      ierr = KSPGetType (_ksp, &ksp_type);
      LIBMESH_CHKERRABORT(ierr);

      if (strcmp(ksp_type, "preonly"))
        {
          ierr = KSPSetInitialGuessNonzero (_ksp, PETSC_TRUE);
          LIBMESH_CHKERRABORT(ierr);
        }

      // Notify PETSc of location to store residual history.
      // This needs to be called before any solves, since
      // it sets the residual history length to zero.  The default
      // behavior is for PETSc to allocate (internally) an array
      // of size 1000 to hold the residual norm history.
      ierr = KSPSetResidualHistory(_ksp,
                                   PETSC_NULL,   // pointer to the array which holds the history
                                   PETSC_DECIDE, // size of the array holding the history
                                   PETSC_TRUE);  // Whether or not to reset the history for each solve.
      LIBMESH_CHKERRABORT(ierr);

      PetscPreconditioner<T>::set_petsc_preconditioner_type(this->_preconditioner_type,_pc);

      //If there is a preconditioner object we need to set the internal setup and apply routines
      if(this->_preconditioner)
        {
          this->_preconditioner->init();
          PCShellSetContext(_pc,(void*)this->_preconditioner);
          PCShellSetSetUp(_pc,__libmesh_petsc_preconditioner_setup);
          PCShellSetApply(_pc,__libmesh_petsc_preconditioner_apply);
        }
    }
}
template<typename T >
void libMesh::PetscLinearSolver< T >::init ( PetscMatrix< T > *  matrix,
const char *  name = NULL 
)

Initialize data structures if not done so already plus much more

Definition at line 280 of file petsc_linear_solver.C.

References libMesh::__libmesh_petsc_preconditioner_apply(), libMesh::__libmesh_petsc_preconditioner_setup(), libMesh::libMeshPrivateData::_is_initialized, libMesh::ierr, libMesh::initialized(), libMesh::PetscMatrix< T >::mat(), and libMesh::PetscPreconditioner< T >::set_petsc_preconditioner_type().

{
  // Initialize the data structures if not done so already.
  if (!this->initialized())
    {
      this->_is_initialized = true;

      PetscErrorCode ierr=0;

      // 2.1.x & earlier style
#if PETSC_VERSION_LESS_THAN(2,2,0)

      // Create the linear solver context
      ierr = SLESCreate (this->comm().get(), &_sles);
      LIBMESH_CHKERRABORT(ierr);

      // Create the Krylov subspace & preconditioner contexts
      ierr = SLESGetKSP       (_sles, &_ksp);
      LIBMESH_CHKERRABORT(ierr);
      ierr = SLESGetPC        (_sles, &_pc);
      LIBMESH_CHKERRABORT(ierr);

      // Set user-specified  solver and preconditioner types
      this->set_petsc_solver_type();

      // Set the options from user-input
      // Set runtime options, e.g.,
      //      -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
      //  These options will override those specified above as long as
      //  SLESSetFromOptions() is called _after_ any other customization
      //  routines.

      ierr = SLESSetFromOptions (_sles);
      LIBMESH_CHKERRABORT(ierr);

      // 2.2.0 & newer style
#else

      // Create the linear solver context
      ierr = KSPCreate (this->comm().get(), &_ksp);
      LIBMESH_CHKERRABORT(ierr);

      if (name)
        {
          ierr = KSPSetOptionsPrefix(_ksp, name);
          LIBMESH_CHKERRABORT(ierr);
        }

      //ierr = PCCreate (this->comm().get(), &_pc);
      //     LIBMESH_CHKERRABORT(ierr);

      // Create the preconditioner context
      ierr = KSPGetPC        (_ksp, &_pc);
      LIBMESH_CHKERRABORT(ierr);

      // Set operators. The input matrix works as the preconditioning matrix
#if PETSC_RELEASE_LESS_THAN(3,5,0)
      ierr = KSPSetOperators(_ksp, matrix->mat(), matrix->mat(),DIFFERENT_NONZERO_PATTERN);
#else
      ierr = KSPSetOperators(_ksp, matrix->mat(), matrix->mat());
#endif
      LIBMESH_CHKERRABORT(ierr);

      // Set user-specified  solver and preconditioner types
      this->set_petsc_solver_type();

      // Set the options from user-input
      // Set runtime options, e.g.,
      //      -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
      //  These options will override those specified above as long as
      //  KSPSetFromOptions() is called _after_ any other customization
      //  routines.

      ierr = KSPSetFromOptions (_ksp);
      LIBMESH_CHKERRABORT(ierr);

      // Not sure if this is necessary, or if it is already handled by KSPSetFromOptions?
      // NOT NECESSARY!!!!
      //ierr = PCSetFromOptions (_pc);
      //LIBMESH_CHKERRABORT(ierr);


#endif

      // Have the Krylov subspace method use our good initial guess
      // rather than 0, unless the user requested a KSPType of
      // preonly, which complains if asked to use initial guesses.
#if PETSC_VERSION_LESS_THAN(3,0,0) || !PETSC_RELEASE_LESS_THAN(3,4,0)
      KSPType ksp_type;
#else
      const KSPType ksp_type;
#endif

      ierr = KSPGetType (_ksp, &ksp_type);
      LIBMESH_CHKERRABORT(ierr);

      if (strcmp(ksp_type, "preonly"))
        {
          ierr = KSPSetInitialGuessNonzero (_ksp, PETSC_TRUE);
          LIBMESH_CHKERRABORT(ierr);
        }

      // Notify PETSc of location to store residual history.
      // This needs to be called before any solves, since
      // it sets the residual history length to zero.  The default
      // behavior is for PETSc to allocate (internally) an array
      // of size 1000 to hold the residual norm history.
      ierr = KSPSetResidualHistory(_ksp,
                                   PETSC_NULL,   // pointer to the array which holds the history
                                   PETSC_DECIDE, // size of the array holding the history
                                   PETSC_TRUE);  // Whether or not to reset the history for each solve.
      LIBMESH_CHKERRABORT(ierr);

      PetscPreconditioner<T>::set_petsc_preconditioner_type(this->_preconditioner_type,_pc);
      if(this->_preconditioner)
        {
          this->_preconditioner->set_matrix(*matrix);
          this->_preconditioner->init();
          PCShellSetContext(_pc,(void*)this->_preconditioner);
          PCShellSetSetUp(_pc,__libmesh_petsc_preconditioner_setup);
          PCShellSetApply(_pc,__libmesh_petsc_preconditioner_apply);
        }
    }
}
template<typename T >
void libMesh::PetscLinearSolver< T >::init_names ( const System sys) [virtual]

Apply names to the system to be solved. This sets an option prefix from the system name and sets field names from the system's variable names.

Since field names are applied to DoF numberings, this method must be called again after any System reinit.

Reimplemented from libMesh::LinearSolver< T >.

Definition at line 410 of file petsc_linear_solver.C.

References libMesh::pc, and libMesh::petsc_auto_fieldsplit().

{
  petsc_auto_fieldsplit(this->pc(), sys);
}
template<typename T>
bool libMesh::LinearSolver< T >::initialized ( ) const [inline, inherited]
Returns:
true if the data structures are initialized, false otherwise.

Definition at line 85 of file linear_solver.h.

{ return _is_initialized; }
template<typename T >
KSP libMesh::PetscLinearSolver< T >::ksp ( ) [inline]

Returns the raw PETSc ksp context pointer. This is useful if you are for example setting a custom convergence test with KSPSetConvergenceTest().

Definition at line 234 of file petsc_linear_solver.h.

References libMesh::PetscLinearSolver< T >::_ksp, and libMesh::PetscLinearSolver< T >::init().

{ this->init(); return _ksp; }
static unsigned int libMesh::ReferenceCounter::n_objects ( ) [inline, static, inherited]

Prints the number of outstanding (created, but not yet destroyed) objects.

Definition at line 79 of file reference_counter.h.

References libMesh::ReferenceCounter::_n_objects.

Referenced by libMesh::LibMeshInit::~LibMeshInit().

  { return _n_objects; }
Returns:
the number of processors in the group.

Definition at line 92 of file parallel_object.h.

References libMesh::ParallelObject::_communicator, and libMesh::Parallel::Communicator::size().

Referenced by libMesh::ParmetisPartitioner::_do_repartition(), libMesh::ParallelMesh::add_elem(), libMesh::ParallelMesh::add_node(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::FEMSystem::assembly(), libMesh::ParmetisPartitioner::assign_partitioning(), libMesh::ParallelMesh::assign_unique_ids(), libMesh::AztecLinearSolver< T >::AztecLinearSolver(), libMesh::ParallelMesh::clear(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::UnstructuredMesh::create_pid_mesh(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_local_dofs_node_major(), libMesh::DofMap::distribute_local_dofs_var_major(), libMesh::EnsightIO::EnsightIO(), libMesh::MeshBase::get_info(), libMesh::EquationSystems::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::ParmetisPartitioner::initialize(), libMesh::Nemesis_IO_Helper::initialize(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::DofMap::local_variable_indices(), libMesh::MeshBase::n_active_elem_on_proc(), libMesh::MeshBase::n_elem_on_proc(), libMesh::MeshBase::n_nodes_on_proc(), libMesh::Partitioner::partition(), libMesh::MeshBase::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::PetscLinearSolver< T >::PetscLinearSolver(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshTools::processor_bounding_box(), libMesh::System::project_vector(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::XdrIO::read(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::System::read_serialized_vector(), libMesh::Partitioner::repartition(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::BoundaryInfo::sync(), libMesh::ParallelMesh::update_parallel_id_counts(), libMesh::CheckpointIO::write(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::System::write_parallel_data(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().

  { return cast_int<processor_id_type>(_communicator.size()); }
template<typename T >
PC libMesh::PetscLinearSolver< T >::pc ( ) [inline]

Returns the raw PETSc preconditioner context pointer. This allows you to specify the PCShellSetApply() and PCShellSetSetUp() functions if you desire. Just don't do anything crazy like calling PCDestroy()!

Definition at line 227 of file petsc_linear_solver.h.

References libMesh::PetscLinearSolver< T >::_pc, and libMesh::PetscLinearSolver< T >::init().

{ this->init(); return _pc; }
template<typename T >
PreconditionerType libMesh::LinearSolver< T >::preconditioner_type ( ) const [inherited]

Returns the type of preconditioner to use.

Definition at line 81 of file linear_solver.C.

{
  if(_preconditioner)
    return _preconditioner->type();

  return _preconditioner_type;
}
template<typename T >
void libMesh::LinearSolver< T >::print_converged_reason ( ) const [virtual, inherited]

Prints a useful message about why the latest linear solve con(di)verged.

Reimplemented in libMesh::LaspackLinearSolver< T >, and libMesh::EigenSparseLinearSolver< T >.

Definition at line 159 of file linear_solver.C.

References libMesh::Utility::enum_to_string(), and libMesh::out.

{
  LinearConvergenceReason reason = this->get_converged_reason();
  libMesh::out << "Linear solver convergence/divergence reason: " << Utility::enum_to_string(reason) << std::endl;
}
void libMesh::ReferenceCounter::print_info ( std::ostream &  out = libMesh::out) [static, inherited]

Prints the reference information, by default to libMesh::out.

Definition at line 88 of file reference_counter.C.

References libMesh::ReferenceCounter::_enable_print_counter, and libMesh::ReferenceCounter::get_info().

Referenced by libMesh::LibMeshInit::~LibMeshInit().

Returns:
the rank of this processor in the group.

Definition at line 98 of file parallel_object.h.

References libMesh::ParallelObject::_communicator, and libMesh::Parallel::Communicator::rank().

Referenced by libMesh::MetisPartitioner::_do_partition(), libMesh::EquationSystems::_read_impl(), libMesh::SerialMesh::active_local_elements_begin(), libMesh::ParallelMesh::active_local_elements_begin(), libMesh::SerialMesh::active_local_elements_end(), libMesh::ParallelMesh::active_local_elements_end(), libMesh::SerialMesh::active_local_subdomain_elements_begin(), libMesh::ParallelMesh::active_local_subdomain_elements_begin(), libMesh::SerialMesh::active_local_subdomain_elements_end(), libMesh::ParallelMesh::active_local_subdomain_elements_end(), libMesh::SerialMesh::active_not_local_elements_begin(), libMesh::ParallelMesh::active_not_local_elements_begin(), libMesh::SerialMesh::active_not_local_elements_end(), libMesh::ParallelMesh::active_not_local_elements_end(), libMesh::ParallelMesh::add_elem(), libMesh::DofMap::add_neighbors_to_send_list(), libMesh::ParallelMesh::add_node(), libMesh::UnstructuredMesh::all_second_order(), libMesh::FEMSystem::assembly(), libMesh::ParmetisPartitioner::assign_partitioning(), libMesh::ParallelMesh::assign_unique_ids(), libMesh::EquationSystems::build_discontinuous_solution_vector(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::ParmetisPartitioner::build_graph(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::DofMap::build_sparsity(), libMesh::ParallelMesh::clear(), libMesh::ExodusII_IO_Helper::close(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::compute_communication_map_parameters(), libMesh::Nemesis_IO_Helper::compute_internal_and_border_elems_and_internal_nodes(), libMesh::Nemesis_IO_Helper::compute_node_communication_maps(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::ExodusII_IO_Helper::create(), libMesh::ParallelMesh::delete_elem(), libMesh::ParallelMesh::delete_node(), libMesh::DofMap::distribute_dofs(), libMesh::DofMap::distribute_local_dofs_node_major(), libMesh::DofMap::distribute_local_dofs_var_major(), libMesh::DofMap::end_dof(), libMesh::DofMap::end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::SerialMesh::facelocal_elements_begin(), libMesh::ParallelMesh::facelocal_elements_begin(), libMesh::SerialMesh::facelocal_elements_end(), libMesh::ParallelMesh::facelocal_elements_end(), libMesh::MeshFunction::find_element(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::DofMap::first_dof(), libMesh::DofMap::first_old_dof(), libMesh::Nemesis_IO_Helper::get_cmap_params(), libMesh::Nemesis_IO_Helper::get_eb_info_global(), libMesh::Nemesis_IO_Helper::get_elem_cmap(), libMesh::Nemesis_IO_Helper::get_elem_map(), libMesh::MeshBase::get_info(), libMesh::Nemesis_IO_Helper::get_init_global(), libMesh::Nemesis_IO_Helper::get_init_info(), libMesh::Nemesis_IO_Helper::get_loadbal_param(), libMesh::Nemesis_IO_Helper::get_node_cmap(), libMesh::Nemesis_IO_Helper::get_node_map(), libMesh::Nemesis_IO_Helper::get_ns_param_global(), libMesh::Nemesis_IO_Helper::get_ss_param_global(), libMesh::SystemSubsetBySubdomain::init(), libMesh::ParmetisPartitioner::initialize(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize_element_variables(), libMesh::ExodusII_IO_Helper::initialize_global_variables(), libMesh::ExodusII_IO_Helper::initialize_nodal_variables(), libMesh::ParallelMesh::insert_elem(), libMesh::SparsityPattern::Build::join(), libMesh::DofMap::last_dof(), libMesh::MeshTools::libmesh_assert_valid_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::SerialMesh::local_elements_begin(), libMesh::ParallelMesh::local_elements_begin(), libMesh::SerialMesh::local_elements_end(), libMesh::ParallelMesh::local_elements_end(), libMesh::SerialMesh::local_level_elements_begin(), libMesh::ParallelMesh::local_level_elements_begin(), libMesh::SerialMesh::local_level_elements_end(), libMesh::ParallelMesh::local_level_elements_end(), libMesh::SerialMesh::local_nodes_begin(), libMesh::ParallelMesh::local_nodes_begin(), libMesh::SerialMesh::local_nodes_end(), libMesh::ParallelMesh::local_nodes_end(), libMesh::SerialMesh::local_not_level_elements_begin(), libMesh::ParallelMesh::local_not_level_elements_begin(), libMesh::SerialMesh::local_not_level_elements_end(), libMesh::ParallelMesh::local_not_level_elements_end(), libMesh::DofMap::local_variable_indices(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::MeshBase::n_active_local_elem(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::DofMap::n_local_dofs(), libMesh::System::n_local_dofs(), libMesh::MeshBase::n_local_elem(), libMesh::MeshBase::n_local_nodes(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::SerialMesh::not_local_elements_begin(), libMesh::ParallelMesh::not_local_elements_begin(), libMesh::SerialMesh::not_local_elements_end(), libMesh::ParallelMesh::not_local_elements_end(), libMesh::WeightedPatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::SparsityPattern::Build::operator()(), libMesh::PatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::ParallelMesh::ParallelMesh(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::System::project_vector(), libMesh::Nemesis_IO_Helper::put_cmap_params(), libMesh::Nemesis_IO_Helper::put_elem_cmap(), libMesh::Nemesis_IO_Helper::put_elem_map(), libMesh::Nemesis_IO_Helper::put_loadbal_param(), libMesh::Nemesis_IO_Helper::put_node_cmap(), libMesh::Nemesis_IO_Helper::put_node_map(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::XdrIO::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::System::read_serialized_data(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::System::read_serialized_vectors(), libMesh::MeshData::read_xdr(), libMesh::SerialMesh::semilocal_elements_begin(), libMesh::ParallelMesh::semilocal_elements_begin(), libMesh::SerialMesh::semilocal_elements_end(), libMesh::ParallelMesh::semilocal_elements_end(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::BoundaryInfo::sync(), libMesh::MeshTools::total_weight(), libMesh::ParallelMesh::update_parallel_id_counts(), libMesh::MeshTools::weight(), libMesh::NameBasedIO::write(), libMesh::ExodusII_IO::write(), libMesh::CheckpointIO::write(), libMesh::XdrIO::write(), libMesh::EquationSystems::write(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO::write_element_data(), libMesh::ExodusII_IO_Helper::write_element_values(), libMesh::ExodusII_IO_Helper::write_elements(), libMesh::ExodusII_IO::write_global_data(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::System::write_header(), libMesh::ExodusII_IO::write_information_records(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::UCDIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::Nemesis_IO_Helper::write_nodesets(), libMesh::System::write_parallel_data(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bc_names(), libMesh::XdrIO::write_serialized_bcs(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::System::write_serialized_data(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::XdrIO::write_serialized_subdomain_names(), libMesh::System::write_serialized_vector(), libMesh::System::write_serialized_vectors(), libMesh::ExodusII_IO_Helper::write_sidesets(), libMesh::Nemesis_IO_Helper::write_sidesets(), libMesh::ExodusII_IO::write_timestep(), and libMesh::ExodusII_IO_Helper::write_timestep().

  { return cast_int<processor_id_type>(_communicator.rank()); }
template<typename T >
void libMesh::PetscLinearSolver< T >::restrict_solve_to ( const std::vector< unsigned int > *const  dofs,
const SubsetSolveMode  subset_solve_mode = SUBSET_ZERO 
) [virtual]

After calling this method, all successive solves will be restricted to the given set of dofs, which must contain local dofs on each processor only and not contain any duplicates. This mode can be disabled by calling this method with dofs being a NULL pointer.

Reimplemented from libMesh::LinearSolver< T >.

Definition at line 419 of file petsc_linear_solver.C.

References libMesh::ierr, and PETSC_OWN_POINTER.

{
  PetscErrorCode ierr=0;

  /* The preconditioner (in particular if a default preconditioner)
     will have to be reset.  We call this->clear() to do that.  This
     call will also remove and free any previous subset that may have
     been set before.  */
  this->clear();

  _subset_solve_mode = subset_solve_mode;

  if(dofs!=NULL)
    {
      PetscInt* petsc_dofs = NULL;
      ierr = PetscMalloc(dofs->size()*sizeof(PetscInt), &petsc_dofs);
      LIBMESH_CHKERRABORT(ierr);

      for(size_t i=0; i<dofs->size(); i++)
        {
          petsc_dofs[i] = (*dofs)[i];
        }

      ierr = ISCreateLibMesh(this->comm().get(),dofs->size(),petsc_dofs,PETSC_OWN_POINTER,&_restrict_solve_to_is);
      LIBMESH_CHKERRABORT(ierr);
    }
}
template<typename T >
void libMesh::LinearSolver< T >::reuse_preconditioner ( bool  reuse_flag) [virtual, inherited]

Definition at line 112 of file linear_solver.C.

Referenced by libMesh::ImplicitSystem::disable_cache().

{
  same_preconditioner = reuse_flag;
}
template<typename T >
void libMesh::PetscLinearSolver< T >::set_petsc_solver_type ( ) [private]

Tells PETSC to use the user-specified solver stored in _solver_type

Definition at line 1815 of file petsc_linear_solver.C.

References libMesh::BICG, libMesh::BICGSTAB, libMesh::CG, libMesh::CGS, libMesh::CHEBYSHEV, libMesh::CR, libMesh::Utility::enum_to_string(), libMesh::err, libMesh::GMRES, libMesh::ierr, libMesh::LSQR, libMesh::MINRES, libMesh::RICHARDSON, libMesh::TCQMR, and libMesh::TFQMR.

{
  PetscErrorCode ierr = 0;

  switch (this->_solver_type)
    {

    case CG:
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPCG));
      LIBMESH_CHKERRABORT(ierr);
      return;

    case CR:
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPCR));
      LIBMESH_CHKERRABORT(ierr);
      return;

    case CGS:
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPCGS));
      LIBMESH_CHKERRABORT(ierr);
      return;

    case BICG:
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPBICG));
      LIBMESH_CHKERRABORT(ierr);
      return;

    case TCQMR:
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPTCQMR));
      LIBMESH_CHKERRABORT(ierr);
      return;

    case TFQMR:
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPTFQMR));
      LIBMESH_CHKERRABORT(ierr);
      return;

    case LSQR:
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPLSQR));
      LIBMESH_CHKERRABORT(ierr);
      return;

    case BICGSTAB:
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPBCGS));
      LIBMESH_CHKERRABORT(ierr);
      return;

    case MINRES:
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPMINRES));
      LIBMESH_CHKERRABORT(ierr);
      return;

    case GMRES:
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPGMRES));
      LIBMESH_CHKERRABORT(ierr);
      return;

    case RICHARDSON:
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPRICHARDSON));
      LIBMESH_CHKERRABORT(ierr);
      return;

    case CHEBYSHEV:
#if defined(LIBMESH_HAVE_PETSC) && PETSC_VERSION_LESS_THAN(3,3,0)
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPCHEBYCHEV));
      LIBMESH_CHKERRABORT(ierr);
      return;
#else
      ierr = KSPSetType (_ksp, const_cast<KSPType>(KSPCHEBYSHEV));
      LIBMESH_CHKERRABORT(ierr);
      return;
#endif


    default:
      libMesh::err << "ERROR:  Unsupported PETSC Solver: "
                   << Utility::enum_to_string(this->_solver_type) << std::endl
                   << "Continuing with PETSC defaults" << std::endl;
    }
}
template<typename T >
void libMesh::LinearSolver< T >::set_preconditioner_type ( const PreconditionerType  pct) [inherited]

Sets the type of preconditioner to use.

Definition at line 91 of file linear_solver.C.

{
  if(_preconditioner)
    _preconditioner->set_type(pct);
  else
    _preconditioner_type = pct;
}
template<typename T>
void libMesh::LinearSolver< T >::set_solver_type ( const SolverType  st) [inline, inherited]

Sets the type of solver to use.

Definition at line 116 of file linear_solver.h.

  { _solver_type = st; }
template<typename T >
std::pair<unsigned int, Real> libMesh::PetscLinearSolver< T >::solve ( SparseMatrix< T > &  matrix_in,
NumericVector< T > &  solution_in,
NumericVector< T > &  rhs_in,
const double  tol,
const unsigned int  m_its 
) [inline, virtual]

Call the Petsc solver. It calls the method below, using the same matrix for the system and preconditioner matrices.

Implements libMesh::LinearSolver< T >.

Definition at line 154 of file petsc_linear_solver.h.

  {
    return this->solve(matrix_in, matrix_in, solution_in, rhs_in, tol, m_its);
  }
template<typename T>
std::pair< unsigned int, Real > libMesh::LinearSolver< T >::solve ( SparseMatrix< T > &  matrix,
SparseMatrix< T > *  precond_matrix,
NumericVector< T > &  sol,
NumericVector< T > &  rhs,
const double  tol,
const unsigned int  n_iter 
) [inline, inherited]

This function calls the solver "_solver_type" preconditioned with the "_preconditioner_type" preconditioner. The preconditioning matrix is used if it is provided, or the system matrix is used if precond_matrix is null

Definition at line 313 of file linear_solver.h.

{
  if (pc_mat)
    return this->solve(mat, *pc_mat, sol, rhs, tol, n_iter);
  else
    return this->solve(mat, sol, rhs, tol, n_iter);
}
template<typename T >
std::pair< unsigned int, Real > libMesh::PetscLinearSolver< T >::solve ( SparseMatrix< T > &  matrix,
SparseMatrix< T > &  preconditioner,
NumericVector< T > &  solution,
NumericVector< T > &  rhs,
const double  tol,
const unsigned int  m_its 
) [virtual]

This method allows you to call a linear solver while specifying the matrix to use as the (left) preconditioning matrix. Note that the linear solver will not compute a preconditioner in this case, and will instead premultiply by the matrix you provide.

In PETSc, this is accomplished by calling

PCSetType(_pc, PCMAT);

before invoking KSPSolve(). Note: this functionality is not implemented in the LinearSolver class since there is not a built-in analog to this method for LasPack -- You could probably implement it by hand if you wanted.

Implements libMesh::LinearSolver< T >.

Definition at line 452 of file petsc_linear_solver.C.

References libMesh::PetscMatrix< T >::close(), libMesh::ierr, libMesh::TriangleWrapper::init(), libMesh::PetscMatrix< T >::init(), libMesh::NumericVector< T >::local_size(), libMesh::PetscMatrix< T >::mat(), PetscBool, libMesh::START_LOG(), libMesh::SUBSET_COPY_RHS, libMesh::SUBSET_DONT_TOUCH, and libMesh::SUBSET_ZERO.

{
  START_LOG("solve()", "PetscLinearSolver");

  // Make sure the data passed in are really of Petsc types
  PetscMatrix<T>* matrix   = cast_ptr<PetscMatrix<T>*>(&matrix_in);
  PetscMatrix<T>* precond  = cast_ptr<PetscMatrix<T>*>(&precond_in);
  PetscVector<T>* solution = cast_ptr<PetscVector<T>*>(&solution_in);
  PetscVector<T>* rhs      = cast_ptr<PetscVector<T>*>(&rhs_in);

  this->init (matrix);

  PetscErrorCode ierr=0;
  PetscInt its=0, max_its = static_cast<PetscInt>(m_its);
  PetscReal final_resid=0.;

  // Close the matrices and vectors in case this wasn't already done.
  matrix->close ();
  precond->close ();
  solution->close ();
  rhs->close ();

  //   // If matrix != precond, then this means we have specified a
  //   // special preconditioner, so reset preconditioner type to PCMAT.
  //   if (matrix != precond)
  //     {
  //       this->_preconditioner_type = USER_PRECOND;
  //       this->set_petsc_preconditioner_type ();
  //     }

  // 2.1.x & earlier style
#if PETSC_VERSION_LESS_THAN(2,2,0)

  if(_restrict_solve_to_is!=NULL)
    {
      libmesh_not_implemented();
    }

  // Set operators. The input matrix works as the preconditioning matrix
  ierr = SLESSetOperators(_sles, matrix->mat(), precond->mat(),
                          DIFFERENT_NONZERO_PATTERN);
  LIBMESH_CHKERRABORT(ierr);

  // Set the tolerances for the iterative solver.  Use the user-supplied
  // tolerance for the relative residual & leave the others at default values.
  ierr = KSPSetTolerances (_ksp, tol, PETSC_DEFAULT,
                           PETSC_DEFAULT, max_its);
  LIBMESH_CHKERRABORT(ierr);


  // Solve the linear system
  ierr = SLESSolve (_sles, rhs->vec(), solution->vec(), &its);
  LIBMESH_CHKERRABORT(ierr);


  // Get the norm of the final residual to return to the user.
  ierr = KSPGetResidualNorm (_ksp, &final_resid);
  LIBMESH_CHKERRABORT(ierr);

  // 2.2.0
#elif PETSC_VERSION_LESS_THAN(2,2,1)

  if(_restrict_solve_to_is!=NULL)
    {
      libmesh_not_implemented();
    }

  // Set operators. The input matrix works as the preconditioning matrix
  //ierr = KSPSetOperators(_ksp, matrix->mat(), precond->mat(),
  // SAME_NONZERO_PATTERN);
  //       LIBMESH_CHKERRABORT(ierr);


  // Set the tolerances for the iterative solver.  Use the user-supplied
  // tolerance for the relative residual & leave the others at default values.
  // Convergence is detected at iteration k if
  // ||r_k||_2 < max(rtol*||b||_2 , abstol)
  // where r_k is the residual vector and b is the right-hand side.  Note that
  // it is the *maximum* of the two values, the larger of which will almost
  // always be rtol*||b||_2.
  ierr = KSPSetTolerances (_ksp,
                           tol,           // rtol   = relative decrease in residual  (1.e-5)
                           PETSC_DEFAULT, // abstol = absolute convergence tolerance (1.e-50)
                           PETSC_DEFAULT, // dtol   = divergence tolerance           (1.e+5)
                           max_its);
  LIBMESH_CHKERRABORT(ierr);


  // Set the solution vector to use
  ierr = KSPSetSolution (_ksp, solution->vec());
  LIBMESH_CHKERRABORT(ierr);

  // Set the RHS vector to use
  ierr = KSPSetRhs (_ksp, rhs->vec());
  LIBMESH_CHKERRABORT(ierr);

  // Solve the linear system
  ierr = KSPSolve (_ksp);
  LIBMESH_CHKERRABORT(ierr);

  // Get the number of iterations required for convergence
  ierr = KSPGetIterationNumber (_ksp, &its);
  LIBMESH_CHKERRABORT(ierr);

  // Get the norm of the final residual to return to the user.
  ierr = KSPGetResidualNorm (_ksp, &final_resid);
  LIBMESH_CHKERRABORT(ierr);

  // 2.2.1 & newer style
#else

  Mat submat = NULL;
  Mat subprecond = NULL;
  Vec subrhs = NULL;
  Vec subsolution = NULL;
  VecScatter scatter = NULL;
  PetscMatrix<Number>* subprecond_matrix = NULL;

  // Set operators.  Also restrict rhs and solution vector to
  // subdomain if neccessary.
  if(_restrict_solve_to_is!=NULL)
    {
      PetscInt is_local_size = this->_restrict_solve_to_is_local_size();

      ierr = VecCreate(this->comm().get(),&subrhs);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetSizes(subrhs,is_local_size,PETSC_DECIDE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetFromOptions(subrhs);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecCreate(this->comm().get(),&subsolution);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetSizes(subsolution,is_local_size,PETSC_DECIDE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetFromOptions(subsolution);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterCreate(rhs->vec(),_restrict_solve_to_is, subrhs,NULL, &scatter);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterBegin(scatter,rhs->vec(),subrhs,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,rhs->vec(),subrhs,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterBegin(scatter,solution->vec(),subsolution,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,solution->vec(),subsolution,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);

#if PETSC_VERSION_LESS_THAN(3,1,0)
      ierr = MatGetSubMatrix(matrix->mat(),
                             _restrict_solve_to_is,_restrict_solve_to_is,
                             PETSC_DECIDE,MAT_INITIAL_MATRIX,&submat);
      LIBMESH_CHKERRABORT(ierr);
      ierr = MatGetSubMatrix(precond->mat(),
                             _restrict_solve_to_is,_restrict_solve_to_is,
                             PETSC_DECIDE,MAT_INITIAL_MATRIX,&subprecond);
      LIBMESH_CHKERRABORT(ierr);
#else
      ierr = MatGetSubMatrix(matrix->mat(),
                             _restrict_solve_to_is,_restrict_solve_to_is,
                             MAT_INITIAL_MATRIX,&submat);
      LIBMESH_CHKERRABORT(ierr);
      ierr = MatGetSubMatrix(precond->mat(),
                             _restrict_solve_to_is,_restrict_solve_to_is,
                             MAT_INITIAL_MATRIX,&subprecond);
      LIBMESH_CHKERRABORT(ierr);
#endif

      /* Since removing columns of the matrix changes the equation
         system, we will now change the right hand side to compensate
         for this.  Note that this is not necessary if \p SUBSET_ZERO
         has been selected.  */
      if(_subset_solve_mode!=SUBSET_ZERO)
        {
          _create_complement_is(rhs_in);
          PetscInt is_complement_local_size =
            cast_int<PetscInt>(rhs_in.local_size()-is_local_size);

          Vec subvec1 = NULL;
          Mat submat1 = NULL;
          VecScatter scatter1 = NULL;

          ierr = VecCreate(this->comm().get(),&subvec1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetSizes(subvec1,is_complement_local_size,PETSC_DECIDE);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetFromOptions(subvec1);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScatterCreate(rhs->vec(),_restrict_solve_to_is_complement, subvec1,NULL, &scatter1);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScatterBegin(scatter1,_subset_solve_mode==SUBSET_COPY_RHS ? rhs->vec() : solution->vec(),subvec1,INSERT_VALUES,SCATTER_FORWARD);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecScatterEnd(scatter1,_subset_solve_mode==SUBSET_COPY_RHS ? rhs->vec() : solution->vec(),subvec1,INSERT_VALUES,SCATTER_FORWARD);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScale(subvec1,-1.0);
          LIBMESH_CHKERRABORT(ierr);

#if PETSC_VERSION_LESS_THAN(3,1,0)
          ierr = MatGetSubMatrix(matrix->mat(),
                                 _restrict_solve_to_is,_restrict_solve_to_is_complement,
                                 PETSC_DECIDE,MAT_INITIAL_MATRIX,&submat1);
          LIBMESH_CHKERRABORT(ierr);
#else
          ierr = MatGetSubMatrix(matrix->mat(),
                                 _restrict_solve_to_is,_restrict_solve_to_is_complement,
                                 MAT_INITIAL_MATRIX,&submat1);
          LIBMESH_CHKERRABORT(ierr);
#endif

          ierr = MatMultAdd(submat1,subvec1,subrhs,subrhs);
          LIBMESH_CHKERRABORT(ierr);

          ierr = LibMeshVecScatterDestroy(&scatter1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = LibMeshVecDestroy(&subvec1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = LibMeshMatDestroy(&submat1);
          LIBMESH_CHKERRABORT(ierr);
        }
#if PETSC_RELEASE_LESS_THAN(3,5,0)
      ierr = KSPSetOperators(_ksp, submat, subprecond,
                             this->same_preconditioner ? SAME_PRECONDITIONER : DIFFERENT_NONZERO_PATTERN);
#else
      ierr = KSPSetOperators(_ksp, submat, subprecond);

      PetscBool ksp_reuse_preconditioner = this->same_preconditioner ? PETSC_TRUE : PETSC_FALSE;
      ierr = KSPSetReusePreconditioner(_ksp, ksp_reuse_preconditioner);
#endif
      LIBMESH_CHKERRABORT(ierr);

      if(this->_preconditioner)
        {
          subprecond_matrix = new PetscMatrix<Number>(subprecond,
                                                      this->comm());
          this->_preconditioner->set_matrix(*subprecond_matrix);
          this->_preconditioner->init();
        }
    }
  else
    {
#if PETSC_RELEASE_LESS_THAN(3,5,0)
      ierr = KSPSetOperators(_ksp, matrix->mat(), precond->mat(),
                             this->same_preconditioner ? SAME_PRECONDITIONER : DIFFERENT_NONZERO_PATTERN);
#else
      ierr = KSPSetOperators(_ksp, matrix->mat(), precond->mat());

      PetscBool ksp_reuse_preconditioner = this->same_preconditioner ? PETSC_TRUE : PETSC_FALSE;
      ierr = KSPSetReusePreconditioner(_ksp, ksp_reuse_preconditioner);
#endif
      LIBMESH_CHKERRABORT(ierr);

      if(this->_preconditioner)
        {
          this->_preconditioner->set_matrix(matrix_in);
          this->_preconditioner->init();
        }
    }

  // Set the tolerances for the iterative solver.  Use the user-supplied
  // tolerance for the relative residual & leave the others at default values.
  ierr = KSPSetTolerances (_ksp, tol, PETSC_DEFAULT,
                           PETSC_DEFAULT, max_its);
  LIBMESH_CHKERRABORT(ierr);

  // Solve the linear system
  if(_restrict_solve_to_is!=NULL)
    {
      ierr = KSPSolve (_ksp, subrhs, subsolution);
      LIBMESH_CHKERRABORT(ierr);
    }
  else
    {
      ierr = KSPSolve (_ksp, rhs->vec(), solution->vec());
      LIBMESH_CHKERRABORT(ierr);
    }

  // Get the number of iterations required for convergence
  ierr = KSPGetIterationNumber (_ksp, &its);
  LIBMESH_CHKERRABORT(ierr);

  // Get the norm of the final residual to return to the user.
  ierr = KSPGetResidualNorm (_ksp, &final_resid);
  LIBMESH_CHKERRABORT(ierr);

  if(_restrict_solve_to_is!=NULL)
    {
      switch(_subset_solve_mode)
        {
        case SUBSET_ZERO:
          ierr = VecZeroEntries(solution->vec());
          LIBMESH_CHKERRABORT(ierr);
          break;

        case SUBSET_COPY_RHS:
          ierr = VecCopy(rhs->vec(),solution->vec());
          LIBMESH_CHKERRABORT(ierr);
          break;

        case SUBSET_DONT_TOUCH:
          /* Nothing to do here.  */
          break;

        default:
          libmesh_error_msg("Invalid subset solve mode = " << _subset_solve_mode);
        }
      ierr = VecScatterBegin(scatter,subsolution,solution->vec(),INSERT_VALUES,SCATTER_REVERSE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,subsolution,solution->vec(),INSERT_VALUES,SCATTER_REVERSE);
      LIBMESH_CHKERRABORT(ierr);

      ierr = LibMeshVecScatterDestroy(&scatter);
      LIBMESH_CHKERRABORT(ierr);

      if(this->_preconditioner)
        {
          /* Before we delete subprecond_matrix, we should give the
             _preconditioner a different matrix.  */
          this->_preconditioner->set_matrix(matrix_in);
          this->_preconditioner->init();
          delete subprecond_matrix;
          subprecond_matrix = NULL;
        }

      ierr = LibMeshVecDestroy(&subsolution);
      LIBMESH_CHKERRABORT(ierr);
      ierr = LibMeshVecDestroy(&subrhs);
      LIBMESH_CHKERRABORT(ierr);
      ierr = LibMeshMatDestroy(&submat);
      LIBMESH_CHKERRABORT(ierr);
      ierr = LibMeshMatDestroy(&subprecond);
      LIBMESH_CHKERRABORT(ierr);
    }

#endif

  STOP_LOG("solve()", "PetscLinearSolver");
  // return the # of its. and the final residual norm.
  return std::make_pair(its, final_resid);
}
template<typename T >
std::pair< unsigned int, Real > libMesh::PetscLinearSolver< T >::solve ( const ShellMatrix< T > &  shell_matrix,
NumericVector< T > &  solution_in,
NumericVector< T > &  rhs_in,
const double  tol,
const unsigned int  m_its 
) [virtual]

This function solves a system whose matrix is a shell matrix.

Implements libMesh::LinearSolver< T >.

Definition at line 1160 of file petsc_linear_solver.C.

References libMesh::PetscVector< T >::close(), libMesh::ierr, libMesh::TriangleWrapper::init(), libMesh::libmesh_assert(), libMesh::NumericVector< T >::local_size(), libMesh::NumericVector< T >::size(), libMesh::START_LOG(), libMesh::SUBSET_COPY_RHS, libMesh::SUBSET_DONT_TOUCH, libMesh::SUBSET_ZERO, and libMesh::PetscVector< T >::vec().

{

#if PETSC_VERSION_LESS_THAN(2,3,1)
  // FIXME[JWP]: There will be a bunch of unused variable warnings
  // for older PETScs here.
  libmesh_error_msg("This method has been developed with PETSc 2.3.1.  " \
                    << "No one has made it backwards compatible with older " \
                    << "versions of PETSc so far; however, it might work " \
                    << "without any change with some older version.");

#else

#if PETSC_VERSION_LESS_THAN(3,1,0)
  if (_restrict_solve_to_is!=NULL)
    libmesh_error_msg("The current implementation of subset solves with " \
                      << "shell matrices requires PETSc version 3.1 or above.  " \
                      << "Older PETSc version do not support automatic " \
                      << "submatrix generation of shell matrices.");
#endif

  START_LOG("solve()", "PetscLinearSolver");

  // Make sure the data passed in are really of Petsc types
  PetscVector<T>* solution = cast_ptr<PetscVector<T>*>(&solution_in);
  PetscVector<T>* rhs      = cast_ptr<PetscVector<T>*>(&rhs_in);

  this->init ();

  PetscErrorCode ierr=0;
  PetscInt its=0, max_its = static_cast<PetscInt>(m_its);
  PetscReal final_resid=0.;

  Mat submat = NULL;
  Vec subrhs = NULL;
  Vec subsolution = NULL;
  VecScatter scatter = NULL;

  // Close the matrices and vectors in case this wasn't already done.
  solution->close ();
  rhs->close ();

  // Prepare the matrix.
  Mat mat;
  ierr = MatCreateShell(this->comm().get(),
                        rhs_in.local_size(),
                        solution_in.local_size(),
                        rhs_in.size(),
                        solution_in.size(),
                        const_cast<void*>(static_cast<const void*>(&shell_matrix)),
                        &mat);
  /* Note that the const_cast above is only necessary because PETSc
     does not accept a const void*.  Inside the member function
     _petsc_shell_matrix() below, the pointer is casted back to a
     const ShellMatrix<T>*.  */

  LIBMESH_CHKERRABORT(ierr);
  ierr = MatShellSetOperation(mat,MATOP_MULT,reinterpret_cast<void(*)(void)>(_petsc_shell_matrix_mult));
  LIBMESH_CHKERRABORT(ierr);
  ierr = MatShellSetOperation(mat,MATOP_MULT_ADD,reinterpret_cast<void(*)(void)>(_petsc_shell_matrix_mult_add));
  LIBMESH_CHKERRABORT(ierr);
  ierr = MatShellSetOperation(mat,MATOP_GET_DIAGONAL,reinterpret_cast<void(*)(void)>(_petsc_shell_matrix_get_diagonal));
  LIBMESH_CHKERRABORT(ierr);

  // Restrict rhs and solution vectors and set operators.  The input
  // matrix works as the preconditioning matrix.
  if(_restrict_solve_to_is!=NULL)
    {
      PetscInt is_local_size = this->_restrict_solve_to_is_local_size();

      ierr = VecCreate(this->comm().get(),&subrhs);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetSizes(subrhs,is_local_size,PETSC_DECIDE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetFromOptions(subrhs);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecCreate(this->comm().get(),&subsolution);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetSizes(subsolution,is_local_size,PETSC_DECIDE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetFromOptions(subsolution);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterCreate(rhs->vec(),_restrict_solve_to_is, subrhs,NULL, &scatter);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterBegin(scatter,rhs->vec(),subrhs,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,rhs->vec(),subrhs,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterBegin(scatter,solution->vec(),subsolution,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,solution->vec(),subsolution,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);

#if PETSC_VERSION_LESS_THAN(3,1,0)
      /* This point can't be reached, see above.  */
      libmesh_assert(false);
#else
      ierr = MatGetSubMatrix(mat,
                             _restrict_solve_to_is,_restrict_solve_to_is,
                             MAT_INITIAL_MATRIX,&submat);
      LIBMESH_CHKERRABORT(ierr);
#endif

      /* Since removing columns of the matrix changes the equation
         system, we will now change the right hand side to compensate
         for this.  Note that this is not necessary if \p SUBSET_ZERO
         has been selected.  */
      if(_subset_solve_mode!=SUBSET_ZERO)
        {
          _create_complement_is(rhs_in);
          PetscInt is_complement_local_size =
            cast_int<PetscInt>(rhs_in.local_size()-is_local_size);

          Vec subvec1 = NULL;
          Mat submat1 = NULL;
          VecScatter scatter1 = NULL;

          ierr = VecCreate(this->comm().get(),&subvec1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetSizes(subvec1,is_complement_local_size,PETSC_DECIDE);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetFromOptions(subvec1);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScatterCreate(rhs->vec(),_restrict_solve_to_is_complement, subvec1,NULL, &scatter1);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScatterBegin(scatter1,_subset_solve_mode==SUBSET_COPY_RHS ? rhs->vec() : solution->vec(),subvec1,INSERT_VALUES,SCATTER_FORWARD);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecScatterEnd(scatter1,_subset_solve_mode==SUBSET_COPY_RHS ? rhs->vec() : solution->vec(),subvec1,INSERT_VALUES,SCATTER_FORWARD);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScale(subvec1,-1.0);
          LIBMESH_CHKERRABORT(ierr);

#if PETSC_VERSION_LESS_THAN(3,1,0)
          /* This point can't be reached, see above.  */
          libmesh_assert(false);
#else
          ierr = MatGetSubMatrix(mat,
                                 _restrict_solve_to_is,_restrict_solve_to_is_complement,
                                 MAT_INITIAL_MATRIX,&submat1);
          LIBMESH_CHKERRABORT(ierr);
#endif

          // The following lines would be correct, but don't work
          // correctly in PETSc up to 3.1.0-p5.  See discussion in
          // petsc-users of Nov 9, 2010.
          //
          // ierr = MatMultAdd(submat1,subvec1,subrhs,subrhs);
          // LIBMESH_CHKERRABORT(ierr);
          //
          // We workaround by using a temporary vector.  Note that the
          // fix in PETsc 3.1.0-p6 uses a temporary vector internally,
          // so this is no effective performance loss.
          Vec subvec2 = NULL;
          ierr = VecCreate(this->comm().get(),&subvec2);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetSizes(subvec2,is_local_size,PETSC_DECIDE);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetFromOptions(subvec2);
          LIBMESH_CHKERRABORT(ierr);
          ierr = MatMult(submat1,subvec1,subvec2);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecAXPY(subrhs,1.0,subvec2);

          ierr = LibMeshVecScatterDestroy(&scatter1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = LibMeshVecDestroy(&subvec1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = LibMeshMatDestroy(&submat1);
          LIBMESH_CHKERRABORT(ierr);
        }
#if PETSC_RELEASE_LESS_THAN(3,5,0)
      ierr = KSPSetOperators(_ksp, submat, submat,
                             DIFFERENT_NONZERO_PATTERN);
#else
      ierr = KSPSetOperators(_ksp, submat, submat);
#endif
      LIBMESH_CHKERRABORT(ierr);
    }
  else
    {
#if PETSC_RELEASE_LESS_THAN(3,5,0)
      ierr = KSPSetOperators(_ksp, mat, mat,
                             DIFFERENT_NONZERO_PATTERN);
#else
      ierr = KSPSetOperators(_ksp, mat, mat);
#endif
      LIBMESH_CHKERRABORT(ierr);
    }

  // Set the tolerances for the iterative solver.  Use the user-supplied
  // tolerance for the relative residual & leave the others at default values.
  ierr = KSPSetTolerances (_ksp, tol, PETSC_DEFAULT,
                           PETSC_DEFAULT, max_its);
  LIBMESH_CHKERRABORT(ierr);

  // Solve the linear system
  if(_restrict_solve_to_is!=NULL)
    {
      ierr = KSPSolve (_ksp, subrhs, subsolution);
      LIBMESH_CHKERRABORT(ierr);
    }
  else
    {
      ierr = KSPSolve (_ksp, rhs->vec(), solution->vec());
      LIBMESH_CHKERRABORT(ierr);
    }

  // Get the number of iterations required for convergence
  ierr = KSPGetIterationNumber (_ksp, &its);
  LIBMESH_CHKERRABORT(ierr);

  // Get the norm of the final residual to return to the user.
  ierr = KSPGetResidualNorm (_ksp, &final_resid);
  LIBMESH_CHKERRABORT(ierr);

  if(_restrict_solve_to_is!=NULL)
    {
      switch(_subset_solve_mode)
        {
        case SUBSET_ZERO:
          ierr = VecZeroEntries(solution->vec());
          LIBMESH_CHKERRABORT(ierr);
          break;

        case SUBSET_COPY_RHS:
          ierr = VecCopy(rhs->vec(),solution->vec());
          LIBMESH_CHKERRABORT(ierr);
          break;

        case SUBSET_DONT_TOUCH:
          /* Nothing to do here.  */
          break;

        default:
          libmesh_error_msg("Invalid subset solve mode = " << _subset_solve_mode);
        }
      ierr = VecScatterBegin(scatter,subsolution,solution->vec(),INSERT_VALUES,SCATTER_REVERSE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,subsolution,solution->vec(),INSERT_VALUES,SCATTER_REVERSE);
      LIBMESH_CHKERRABORT(ierr);

      ierr = LibMeshVecScatterDestroy(&scatter);
      LIBMESH_CHKERRABORT(ierr);

      ierr = LibMeshVecDestroy(&subsolution);
      LIBMESH_CHKERRABORT(ierr);
      ierr = LibMeshVecDestroy(&subrhs);
      LIBMESH_CHKERRABORT(ierr);
      ierr = LibMeshMatDestroy(&submat);
      LIBMESH_CHKERRABORT(ierr);
    }

  // Destroy the matrix.
  ierr = LibMeshMatDestroy(&mat);
  LIBMESH_CHKERRABORT(ierr);

  STOP_LOG("solve()", "PetscLinearSolver");
  // return the # of its. and the final residual norm.
  return std::make_pair(its, final_resid);

#endif

}
template<typename T >
std::pair< unsigned int, Real > libMesh::PetscLinearSolver< T >::solve ( const ShellMatrix< T > &  shell_matrix,
const SparseMatrix< T > &  precond_matrix,
NumericVector< T > &  solution_in,
NumericVector< T > &  rhs_in,
const double  tol,
const unsigned int  m_its 
) [virtual]

This function solves a system whose matrix is a shell matrix, but a sparse matrix is used as preconditioning matrix, this allowing other preconditioners than JACOBI.

Implements libMesh::LinearSolver< T >.

Definition at line 1439 of file petsc_linear_solver.C.

References libMesh::PetscMatrix< T >::close(), libMesh::ierr, libMesh::TriangleWrapper::init(), libMesh::PetscMatrix< T >::init(), libMesh::libmesh_assert(), libMesh::NumericVector< T >::local_size(), libMesh::NumericVector< T >::size(), libMesh::START_LOG(), libMesh::SUBSET_COPY_RHS, libMesh::SUBSET_DONT_TOUCH, and libMesh::SUBSET_ZERO.

{

#if PETSC_VERSION_LESS_THAN(2,3,1)
  // FIXME[JWP]: There will be a bunch of unused variable warnings
  // for older PETScs here.
  libmesh_error_msg("This method has been developed with PETSc 2.3.1.  " \
                    << "No one has made it backwards compatible with older " \
                    << "versions of PETSc so far; however, it might work " \
                    << "without any change with some older version.");

#else

#if PETSC_VERSION_LESS_THAN(3,1,0)
  if (_restrict_solve_to_is!=NULL)
    libmesh_error_msg("The current implementation of subset solves with " \
                      << "shell matrices requires PETSc version 3.1 or above.  " \
                      << "Older PETSc version do not support automatic " \
                      << "submatrix generation of shell matrices.");
#endif

  START_LOG("solve()", "PetscLinearSolver");

  // Make sure the data passed in are really of Petsc types
  const PetscMatrix<T>* precond  = cast_ptr<const PetscMatrix<T>*>(&precond_matrix);
  PetscVector<T>* solution = cast_ptr<PetscVector<T>*>(&solution_in);
  PetscVector<T>* rhs      = cast_ptr<PetscVector<T>*>(&rhs_in);

  this->init ();

  PetscErrorCode ierr=0;
  PetscInt its=0, max_its = static_cast<PetscInt>(m_its);
  PetscReal final_resid=0.;

  Mat submat = NULL;
  Mat subprecond = NULL;
  Vec subrhs = NULL;
  Vec subsolution = NULL;
  VecScatter scatter = NULL;
  PetscMatrix<Number>* subprecond_matrix = NULL;

  // Close the matrices and vectors in case this wasn't already done.
  solution->close ();
  rhs->close ();

  // Prepare the matrix.
  Mat mat;
  ierr = MatCreateShell(this->comm().get(),
                        rhs_in.local_size(),
                        solution_in.local_size(),
                        rhs_in.size(),
                        solution_in.size(),
                        const_cast<void*>(static_cast<const void*>(&shell_matrix)),
                        &mat);
  /* Note that the const_cast above is only necessary because PETSc
     does not accept a const void*.  Inside the member function
     _petsc_shell_matrix() below, the pointer is casted back to a
     const ShellMatrix<T>*.  */

  LIBMESH_CHKERRABORT(ierr);
  ierr = MatShellSetOperation(mat,MATOP_MULT,reinterpret_cast<void(*)(void)>(_petsc_shell_matrix_mult));
  LIBMESH_CHKERRABORT(ierr);
  ierr = MatShellSetOperation(mat,MATOP_MULT_ADD,reinterpret_cast<void(*)(void)>(_petsc_shell_matrix_mult_add));
  LIBMESH_CHKERRABORT(ierr);
  ierr = MatShellSetOperation(mat,MATOP_GET_DIAGONAL,reinterpret_cast<void(*)(void)>(_petsc_shell_matrix_get_diagonal));
  LIBMESH_CHKERRABORT(ierr);

  // Restrict rhs and solution vectors and set operators.  The input
  // matrix works as the preconditioning matrix.
  if(_restrict_solve_to_is!=NULL)
    {
      PetscInt is_local_size = this->_restrict_solve_to_is_local_size();

      ierr = VecCreate(this->comm().get(),&subrhs);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetSizes(subrhs,is_local_size,PETSC_DECIDE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetFromOptions(subrhs);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecCreate(this->comm().get(),&subsolution);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetSizes(subsolution,is_local_size,PETSC_DECIDE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecSetFromOptions(subsolution);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterCreate(rhs->vec(),_restrict_solve_to_is, subrhs,NULL, &scatter);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterBegin(scatter,rhs->vec(),subrhs,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,rhs->vec(),subrhs,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);

      ierr = VecScatterBegin(scatter,solution->vec(),subsolution,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,solution->vec(),subsolution,INSERT_VALUES,SCATTER_FORWARD);
      LIBMESH_CHKERRABORT(ierr);

#if PETSC_VERSION_LESS_THAN(3,1,0)
      /* This point can't be reached, see above.  */
      libmesh_assert(false);
#else
      ierr = MatGetSubMatrix(mat,
                             _restrict_solve_to_is,_restrict_solve_to_is,
                             MAT_INITIAL_MATRIX,&submat);
      LIBMESH_CHKERRABORT(ierr);
      ierr = MatGetSubMatrix(const_cast<PetscMatrix<T>*>(precond)->mat(),
                             _restrict_solve_to_is,_restrict_solve_to_is,
                             MAT_INITIAL_MATRIX,&subprecond);
      LIBMESH_CHKERRABORT(ierr);
#endif

      /* Since removing columns of the matrix changes the equation
         system, we will now change the right hand side to compensate
         for this.  Note that this is not necessary if \p SUBSET_ZERO
         has been selected.  */
      if(_subset_solve_mode!=SUBSET_ZERO)
        {
          _create_complement_is(rhs_in);
          PetscInt is_complement_local_size = rhs_in.local_size()-is_local_size;

          Vec subvec1 = NULL;
          Mat submat1 = NULL;
          VecScatter scatter1 = NULL;

          ierr = VecCreate(this->comm().get(),&subvec1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetSizes(subvec1,is_complement_local_size,PETSC_DECIDE);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetFromOptions(subvec1);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScatterCreate(rhs->vec(),_restrict_solve_to_is_complement, subvec1,NULL, &scatter1);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScatterBegin(scatter1,_subset_solve_mode==SUBSET_COPY_RHS ? rhs->vec() : solution->vec(),subvec1,INSERT_VALUES,SCATTER_FORWARD);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecScatterEnd(scatter1,_subset_solve_mode==SUBSET_COPY_RHS ? rhs->vec() : solution->vec(),subvec1,INSERT_VALUES,SCATTER_FORWARD);
          LIBMESH_CHKERRABORT(ierr);

          ierr = VecScale(subvec1,-1.0);
          LIBMESH_CHKERRABORT(ierr);

#if PETSC_VERSION_LESS_THAN(3,1,0)
          /* This point can't be reached, see above.  */
          libmesh_assert(false);
#else
          ierr = MatGetSubMatrix(mat,
                                 _restrict_solve_to_is,_restrict_solve_to_is_complement,
                                 MAT_INITIAL_MATRIX,&submat1);
          LIBMESH_CHKERRABORT(ierr);
#endif

          // The following lines would be correct, but don't work
          // correctly in PETSc up to 3.1.0-p5.  See discussion in
          // petsc-users of Nov 9, 2010.
          //
          // ierr = MatMultAdd(submat1,subvec1,subrhs,subrhs);
          // LIBMESH_CHKERRABORT(ierr);
          //
          // We workaround by using a temporary vector.  Note that the
          // fix in PETsc 3.1.0-p6 uses a temporary vector internally,
          // so this is no effective performance loss.
          Vec subvec2 = NULL;
          ierr = VecCreate(this->comm().get(),&subvec2);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetSizes(subvec2,is_local_size,PETSC_DECIDE);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecSetFromOptions(subvec2);
          LIBMESH_CHKERRABORT(ierr);
          ierr = MatMult(submat1,subvec1,subvec2);
          LIBMESH_CHKERRABORT(ierr);
          ierr = VecAXPY(subrhs,1.0,subvec2);
          LIBMESH_CHKERRABORT(ierr);

          ierr = LibMeshVecScatterDestroy(&scatter1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = LibMeshVecDestroy(&subvec1);
          LIBMESH_CHKERRABORT(ierr);
          ierr = LibMeshMatDestroy(&submat1);
          LIBMESH_CHKERRABORT(ierr);
        }

#if PETSC_RELEASE_LESS_THAN(3,5,0)
      ierr = KSPSetOperators(_ksp, submat, subprecond,
                             DIFFERENT_NONZERO_PATTERN);
#else
      ierr = KSPSetOperators(_ksp, submat, subprecond);
#endif
      LIBMESH_CHKERRABORT(ierr);

      if(this->_preconditioner)
        {
          subprecond_matrix = new PetscMatrix<Number>(subprecond,
                                                      this->comm());
          this->_preconditioner->set_matrix(*subprecond_matrix);
          this->_preconditioner->init();
        }
    }
  else
    {
#if PETSC_RELEASE_LESS_THAN(3,5,0)
      ierr = KSPSetOperators(_ksp, mat, const_cast<PetscMatrix<T>*>(precond)->mat(),
                             DIFFERENT_NONZERO_PATTERN);
#else
      ierr = KSPSetOperators(_ksp, mat, const_cast<PetscMatrix<T>*>(precond)->mat());
#endif
      LIBMESH_CHKERRABORT(ierr);

      if(this->_preconditioner)
        {
          this->_preconditioner->set_matrix(const_cast<SparseMatrix<Number>&>(precond_matrix));
          this->_preconditioner->init();
        }
    }

  // Set the tolerances for the iterative solver.  Use the user-supplied
  // tolerance for the relative residual & leave the others at default values.
  ierr = KSPSetTolerances (_ksp, tol, PETSC_DEFAULT,
                           PETSC_DEFAULT, max_its);
  LIBMESH_CHKERRABORT(ierr);

  // Solve the linear system
  if(_restrict_solve_to_is!=NULL)
    {
      ierr = KSPSolve (_ksp, subrhs, subsolution);
      LIBMESH_CHKERRABORT(ierr);
    }
  else
    {
      ierr = KSPSolve (_ksp, rhs->vec(), solution->vec());
      LIBMESH_CHKERRABORT(ierr);
    }

  // Get the number of iterations required for convergence
  ierr = KSPGetIterationNumber (_ksp, &its);
  LIBMESH_CHKERRABORT(ierr);

  // Get the norm of the final residual to return to the user.
  ierr = KSPGetResidualNorm (_ksp, &final_resid);
  LIBMESH_CHKERRABORT(ierr);

  if(_restrict_solve_to_is!=NULL)
    {
      switch(_subset_solve_mode)
        {
        case SUBSET_ZERO:
          ierr = VecZeroEntries(solution->vec());
          LIBMESH_CHKERRABORT(ierr);
          break;

        case SUBSET_COPY_RHS:
          ierr = VecCopy(rhs->vec(),solution->vec());
          LIBMESH_CHKERRABORT(ierr);
          break;

        case SUBSET_DONT_TOUCH:
          /* Nothing to do here.  */
          break;

        default:
          libmesh_error_msg("Invalid subset solve mode = " << _subset_solve_mode);
        }
      ierr = VecScatterBegin(scatter,subsolution,solution->vec(),INSERT_VALUES,SCATTER_REVERSE);
      LIBMESH_CHKERRABORT(ierr);
      ierr = VecScatterEnd(scatter,subsolution,solution->vec(),INSERT_VALUES,SCATTER_REVERSE);
      LIBMESH_CHKERRABORT(ierr);

      ierr = LibMeshVecScatterDestroy(&scatter);
      LIBMESH_CHKERRABORT(ierr);

      if(this->_preconditioner)
        {
          /* Before we delete subprecond_matrix, we should give the
             _preconditioner a different matrix.  */
          this->_preconditioner->set_matrix(const_cast<SparseMatrix<Number>&>(precond_matrix));
          this->_preconditioner->init();
          delete subprecond_matrix;
          subprecond_matrix = NULL;
        }

      ierr = LibMeshVecDestroy(&subsolution);
      LIBMESH_CHKERRABORT(ierr);
      ierr = LibMeshVecDestroy(&subrhs);
      LIBMESH_CHKERRABORT(ierr);
      ierr = LibMeshMatDestroy(&submat);
      LIBMESH_CHKERRABORT(ierr);
      ierr = LibMeshMatDestroy(&subprecond);
      LIBMESH_CHKERRABORT(ierr);
    }

  // Destroy the matrix.
  ierr = LibMeshMatDestroy(&mat);
  LIBMESH_CHKERRABORT(ierr);

  STOP_LOG("solve()", "PetscLinearSolver");
  // return the # of its. and the final residual norm.
  return std::make_pair(its, final_resid);

#endif

}
template<typename T>
std::pair< unsigned int, Real > libMesh::LinearSolver< T >::solve ( const ShellMatrix< T > &  matrix,
const SparseMatrix< T > *  precond_matrix,
NumericVector< T > &  sol,
NumericVector< T > &  rhs,
const double  tol,
const unsigned int  n_iter 
) [inline, inherited]

This function solves a system whose matrix is a shell matrix, but an optional sparse matrix may be used as preconditioning matrix.

Definition at line 330 of file linear_solver.h.

{
  if (pc_mat)
    return this->solve(mat, *pc_mat, sol, rhs, tol, n_iter);
  else
    return this->solve(mat, sol, rhs, tol, n_iter);
}
template<typename T>
SolverType libMesh::LinearSolver< T >::solver_type ( ) const [inline, inherited]

Returns the type of solver to use.

Definition at line 111 of file linear_solver.h.

{ return _solver_type; }

Member Data Documentation

bool libMesh::ReferenceCounter::_enable_print_counter = true [static, protected, inherited]

Flag to control whether reference count information is printed when print_info is called.

Definition at line 137 of file reference_counter.h.

Referenced by libMesh::ReferenceCounter::disable_print_counter_info(), libMesh::ReferenceCounter::enable_print_counter_info(), and libMesh::ReferenceCounter::print_info().

template<typename T>
bool libMesh::LinearSolver< T >::_is_initialized [protected, inherited]

Flag indicating if the data structures have been initialized.

Definition at line 261 of file linear_solver.h.

Referenced by libMesh::LinearSolver< Number >::initialized().

template<typename T >
KSP libMesh::PetscLinearSolver< T >::_ksp [private]

Krylov subspace context

Definition at line 296 of file petsc_linear_solver.h.

Referenced by libMesh::PetscLinearSolver< T >::ksp().

Mutual exclusion object to enable thread-safe reference counting.

Definition at line 131 of file reference_counter.h.

Threads::atomic< unsigned int > libMesh::ReferenceCounter::_n_objects [static, protected, inherited]

The number of objects. Print the reference count information when the number returns to 0.

Definition at line 126 of file reference_counter.h.

Referenced by libMesh::ReferenceCounter::n_objects(), libMesh::ReferenceCounter::ReferenceCounter(), and libMesh::ReferenceCounter::~ReferenceCounter().

template<typename T >
PC libMesh::PetscLinearSolver< T >::_pc [private]

Preconditioner context

Definition at line 291 of file petsc_linear_solver.h.

Referenced by libMesh::PetscLinearSolver< T >::pc().

template<typename T>
Preconditioner<T>* libMesh::LinearSolver< T >::_preconditioner [protected, inherited]

Holds the Preconditioner object to be used for the linear solves.

Definition at line 266 of file linear_solver.h.

template<typename T>
PreconditionerType libMesh::LinearSolver< T >::_preconditioner_type [protected, inherited]

Enum statitng with type of preconditioner to use.

Definition at line 256 of file linear_solver.h.

Referenced by libMesh::AztecLinearSolver< T >::AztecLinearSolver(), and libMesh::PetscLinearSolver< T >::PetscLinearSolver().

template<typename T >
IS libMesh::PetscLinearSolver< T >::_restrict_solve_to_is [private]

PETSc index set containing the dofs on which to solve (NULL means solve on all dofs).

Definition at line 302 of file petsc_linear_solver.h.

template<typename T >
IS libMesh::PetscLinearSolver< T >::_restrict_solve_to_is_complement [private]

PETSc index set, complement to _restrict_solve_to_is. This will be created on demand by the method _create_complement_is().

Definition at line 309 of file petsc_linear_solver.h.

template<typename T >
SLES libMesh::PetscLinearSolver< T >::_sles [private]

Linear solver context

Definition at line 284 of file petsc_linear_solver.h.

template<typename T>
SolverType libMesh::LinearSolver< T >::_solver_type [protected, inherited]
template<typename T >
SubsetSolveMode libMesh::PetscLinearSolver< T >::_subset_solve_mode [private]

If restrict-solve-to-subset mode is active, this member decides what happens with the dofs outside the subset.

Definition at line 328 of file petsc_linear_solver.h.

template<typename T>
bool libMesh::LinearSolver< T >::same_preconditioner [protected, inherited]

Boolean flag to indicate whether we want to use an identical preconditioner to the previous solve. This can save substantial work in the cases where the system matrix is the same for successive solves.

Definition at line 274 of file linear_solver.h.


The documentation for this class was generated from the following files: