libMesh::PetscPreconditioner< T > Class Template Reference

#include <petsc_preconditioner.h>

Inheritance diagram for libMesh::PetscPreconditioner< T >:

List of all members.

Public Member Functions

 PetscPreconditioner ()
virtual ~PetscPreconditioner ()
virtual void apply (const NumericVector< T > &x, NumericVector< T > &y)
virtual void clear ()
virtual void init ()
PC pc ()
bool initialized () const
virtual void setup ()
void set_matrix (SparseMatrix< Number > &mat)
PreconditionerType type () const
void set_type (const PreconditionerType pct)

Static Public Member Functions

static void set_petsc_preconditioner_type (const PreconditionerType &preconditioner_type, PC &pc)
static Preconditioner< T > * build (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

PC _pc
Mat _mat
SparseMatrix< T > * _matrix
PreconditionerType _preconditioner_type
bool _is_initialized

Static Protected Attributes

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

Static Private Member Functions

static void set_petsc_subpreconditioner_type (PCType type, PC &pc)
static void set_petsc_subpreconditioner_type (const PCType type, PC &pc)

Detailed Description

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

This class provides an interface to the suite of preconditioners available from Petsc.

Author:
Derek Gaston, 2009

Definition at line 60 of file petsc_preconditioner.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::PetscPreconditioner< T >::PetscPreconditioner (  )  [inline]

Constructor. Initializes PetscPreconditioner data structures

Definition at line 137 of file petsc_preconditioner.h.

00137                                              :
00138   Preconditioner<T>(),
00139   _pc(PETSC_NULL)
00140 {
00141 }

template<typename T >
libMesh::PetscPreconditioner< T >::~PetscPreconditioner (  )  [inline, virtual]

Destructor.

Definition at line 147 of file petsc_preconditioner.h.

References libMesh::PetscPreconditioner< T >::clear().

00148 {
00149   this->clear ();
00150 }


Member Function Documentation

template<typename T >
void libMesh::PetscPreconditioner< T >::apply ( const NumericVector< T > &  x,
NumericVector< T > &  y 
) [inline, virtual]

Computes the preconditioned vector "y" based on input "x". Usually by solving Py=x to get the action of P^-1 x.

Implements libMesh::Preconditioner< T >.

Definition at line 44 of file petsc_preconditioner.C.

References libMesh::PetscPreconditioner< T >::_pc, libMesh::COMM_WORLD, and libMesh::PetscVector< T >::vec().

00045 {
00046   PetscVector<T> & x_pvec = libmesh_cast_ref<PetscVector<T>&>(const_cast<NumericVector<T>&>(x));
00047   PetscVector<T> & y_pvec = libmesh_cast_ref<PetscVector<T>&>(const_cast<NumericVector<T>&>(y));
00048 
00049   Vec x_vec = x_pvec.vec();
00050   Vec y_vec = y_pvec.vec();
00051 
00052   int ierr = PCApply(_pc,x_vec,y_vec);
00053   CHKERRABORT(libMesh::COMM_WORLD,ierr);
00054 }

template<typename T >
Preconditioner< T > * libMesh::Preconditioner< T >::build ( const SolverPackage  solver_package = libMesh::default_solver_package()  )  [inline, static, inherited]

Builds a Preconditioner using the linear solver package specified by solver_package

Definition at line 35 of file preconditioner.C.

References libMesh::err, libMeshEnums::PETSC_SOLVERS, and libMesh::TRILINOS_SOLVERS.

00036 {
00037   // Build the appropriate solver
00038   switch (solver_package)
00039     {
00040 
00041 /*
00042 #ifdef LIBMESH_HAVE_LASPACK
00043     case LASPACK_SOLVERS:
00044       {
00045         AutoPtr<Preconditioner<T> > ap(new LaspackPreconditioner<T>);
00046         return ap;
00047       }
00048 #endif
00049 */
00050 
00051 #ifdef LIBMESH_HAVE_PETSC
00052     case PETSC_SOLVERS:
00053       {
00054         return new PetscPreconditioner<T>();
00055       }
00056 #endif
00057 
00058 #ifdef LIBMESH_HAVE_TRILINOS
00059     case TRILINOS_SOLVERS:
00060       return new TrilinosPreconditioner<T>();
00061 #endif
00062 
00063     default:
00064       libMesh::err << "ERROR:  Unrecognized solver package: "
00065                     << solver_package
00066                     << std::endl;
00067       libmesh_error();
00068     }
00069 
00070   return NULL;
00071 }

template<typename T >
virtual void libMesh::PetscPreconditioner< T >::clear (  )  [inline, virtual]

Release all memory and clear data structures.

Reimplemented from libMesh::Preconditioner< T >.

Definition at line 83 of file petsc_preconditioner.h.

Referenced by libMesh::PetscPreconditioner< T >::~PetscPreconditioner().

00083 {}

void libMesh::ReferenceCounter::disable_print_counter_info (  )  [static, inherited]

Definition at line 106 of file reference_counter.C.

References libMesh::ReferenceCounter::_enable_print_counter.

00107 {
00108   _enable_print_counter = false;
00109   return;
00110 }

void libMesh::ReferenceCounter::enable_print_counter_info (  )  [static, inherited]

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.

00101 {
00102   _enable_print_counter = true;
00103   return;
00104 }

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().

00048 {
00049 #if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
00050 
00051   std::ostringstream oss;
00052 
00053   oss << '\n'
00054       << " ---------------------------------------------------------------------------- \n"
00055       << "| Reference count information                                                |\n"
00056       << " ---------------------------------------------------------------------------- \n";
00057 
00058   for (Counts::iterator it = _counts.begin();
00059        it != _counts.end(); ++it)
00060     {
00061       const std::string name(it->first);
00062       const unsigned int creations    = it->second.first;
00063       const unsigned int destructions = it->second.second;
00064 
00065       oss << "| " << name << " reference count information:\n"
00066           << "|  Creations:    " << creations    << '\n'
00067           << "|  Destructions: " << destructions << '\n';
00068     }
00069 
00070   oss << " ---------------------------------------------------------------------------- \n";
00071 
00072   return oss.str();
00073 
00074 #else
00075 
00076   return "";
00077 
00078 #endif
00079 }

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, and libMesh::Threads::spin_mtx.

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

00164 {
00165   Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
00166   std::pair<unsigned int, unsigned int>& p = _counts[name];
00167 
00168   p.first++;
00169 }

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, and libMesh::Threads::spin_mtx.

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

00177 {
00178   Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
00179   std::pair<unsigned int, unsigned int>& p = _counts[name];
00180 
00181   p.second++;
00182 }

template<typename T >
void libMesh::PetscPreconditioner< T >::init (  )  [inline, virtual]

Initialize data structures if not done so already.

Reimplemented from libMesh::Preconditioner< T >.

Definition at line 60 of file petsc_preconditioner.C.

References libMesh::Preconditioner< T >::_is_initialized, libMesh::PetscPreconditioner< T >::_mat, libMesh::Preconditioner< T >::_matrix, libMesh::PetscPreconditioner< T >::_pc, libMesh::Preconditioner< T >::_preconditioner_type, libMesh::COMM_WORLD, libMesh::err, libMesh::PetscMatrix< T >::mat(), and libMesh::PetscPreconditioner< T >::set_petsc_preconditioner_type().

00061 {
00062   if(!this->_matrix)
00063   {
00064     libMesh::err << "ERROR: No matrix set for PetscPreconditioner, but init() called" << std::endl;
00065     libmesh_error();
00066   }
00067 
00068   // Clear the preconditioner in case it has been created in the past
00069   if (!this->_is_initialized)
00070   {
00071     // Should probably use PCReset(), but it's not working at the moment so we'll destroy instead
00072     if (_pc)
00073     {
00074       int ierr = LibMeshPCDestroy(&_pc);
00075       CHKERRABORT(libMesh::COMM_WORLD,ierr);
00076     }
00077 
00078     int ierr = PCCreate(libMesh::COMM_WORLD,&_pc);
00079     CHKERRABORT(libMesh::COMM_WORLD,ierr);
00080 
00081     PetscMatrix<T> * pmatrix = libmesh_cast_ptr<PetscMatrix<T>*, SparseMatrix<T> >(this->_matrix);
00082 
00083     _mat = pmatrix->mat();
00084   }
00085 
00086   int ierr = PCSetOperators(_pc,_mat,_mat,SAME_NONZERO_PATTERN);
00087   CHKERRABORT(libMesh::COMM_WORLD,ierr);
00088 
00089   // Set the PCType.  Note: this used to be done *before* the call to
00090   // PCSetOperators(), and only when !_is_initialized, but
00091   // 1.) Some preconditioners (those employing sub-preconditioners,
00092   // for example) have to call PCSetUp(), and can only do this after
00093   // the operators have been set.
00094   // 2.) It should be safe to call set_petsc_preconditioner_type()
00095   // multiple times.
00096   set_petsc_preconditioner_type(this->_preconditioner_type, _pc);
00097 
00098   this->_is_initialized = true;
00099 }

template<typename T>
bool libMesh::Preconditioner< T >::initialized (  )  const [inline, inherited]
Returns:
true if the data structures are initialized, false otherwise.

Definition at line 86 of file preconditioner.h.

00086 { return _is_initialized; }

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.

00080   { return _n_objects; }

template<typename T >
PC libMesh::PetscPreconditioner< T >::pc (  )  [inline]

Returns the actual Petsc PC struct. Useful for more advanced purposes

Definition at line 94 of file petsc_preconditioner.h.

References libMesh::PetscPreconditioner< T >::_pc.

00094 { return _pc; }

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().

00089 {
00090   if( _enable_print_counter ) out_stream << ReferenceCounter::get_info();
00091 }

template<typename T >
void libMesh::Preconditioner< T >::set_matrix ( SparseMatrix< Number > &  mat  )  [inline, inherited]

Sets the matrix P to be preconditioned.

Definition at line 172 of file preconditioner.h.

References libMesh::Preconditioner< T >::_is_initialized, and libMesh::Preconditioner< T >::_matrix.

00173 {
00174   //If the matrix is changing then we (probably) need to reinitialize.
00175   _is_initialized = false;
00176   _matrix = &mat;
00177 }

template<typename T >
void libMesh::PetscPreconditioner< T >::set_petsc_preconditioner_type ( const PreconditionerType &  preconditioner_type,
PC &  pc 
) [inline, static]

Tells PETSC to use the user-specified preconditioner

Definition at line 105 of file petsc_preconditioner.C.

References libMeshEnums::AMG_PRECOND, libMeshEnums::ASM_PRECOND, libMeshEnums::BLOCK_JACOBI_PRECOND, libMeshEnums::CHOLESKY_PRECOND, libMesh::COMM_WORLD, libMeshEnums::EISENSTAT_PRECOND, libMesh::err, libMeshEnums::ICC_PRECOND, libMeshEnums::IDENTITY_PRECOND, libMeshEnums::ILU_PRECOND, libMeshEnums::JACOBI_PRECOND, libMeshEnums::LU_PRECOND, libMesh::n_processors(), libMesh::PetscPreconditioner< T >::set_petsc_subpreconditioner_type(), libMeshEnums::SHELL_PRECOND, libMeshEnums::SOR_PRECOND, and libMeshEnums::USER_PRECOND.

Referenced by libMesh::PetscPreconditioner< T >::init().

00106 {
00107   int ierr = 0;
00108 
00109   switch (preconditioner_type)
00110   {
00111   case IDENTITY_PRECOND:
00112     ierr = PCSetType (pc, (char*) PCNONE);      CHKERRABORT(libMesh::COMM_WORLD,ierr); break;
00113 
00114   case CHOLESKY_PRECOND:
00115     ierr = PCSetType (pc, (char*) PCCHOLESKY);  CHKERRABORT(libMesh::COMM_WORLD,ierr); break;
00116 
00117   case ICC_PRECOND:
00118     ierr = PCSetType (pc, (char*) PCICC);       CHKERRABORT(libMesh::COMM_WORLD,ierr); break;
00119 
00120   case ILU_PRECOND:
00121     {
00122       // In serial, just set the ILU preconditioner type
00123       if (libMesh::n_processors() == 1)
00124         {
00125           ierr = PCSetType (pc, (char*) PCILU);
00126           CHKERRABORT(libMesh::COMM_WORLD,ierr);
00127         }
00128       else
00129         {
00130           // But PETSc has no truly parallel ILU, instead you have to set
00131           // an actual parallel preconditioner (e.g. block Jacobi) and then
00132           // assign ILU sub-preconditioners.
00133           ierr = PCSetType (pc, (char*) PCBJACOBI);
00134           CHKERRABORT(libMesh::COMM_WORLD,ierr);
00135 
00136           // Set ILU as the sub preconditioner type
00137           set_petsc_subpreconditioner_type(PCILU, pc);
00138         }
00139       break;
00140     }
00141 
00142   case LU_PRECOND:
00143     {
00144       // In serial, just set the LU preconditioner type
00145       if (libMesh::n_processors() == 1)
00146         {
00147           ierr = PCSetType (pc, (char*) PCLU);
00148           CHKERRABORT(libMesh::COMM_WORLD,ierr);
00149         }
00150       else
00151         {
00152           // But PETSc has no truly parallel LU, instead you have to set
00153           // an actual parallel preconditioner (e.g. block Jacobi) and then
00154           // assign LU sub-preconditioners.
00155           ierr = PCSetType (pc, (char*) PCBJACOBI);
00156           CHKERRABORT(libMesh::COMM_WORLD,ierr);
00157 
00158           // Set ILU as the sub preconditioner type
00159           set_petsc_subpreconditioner_type(PCLU, pc);
00160         }
00161       break;
00162     }
00163 
00164   case ASM_PRECOND:
00165     {
00166       // In parallel, I think ASM uses ILU by default as the sub-preconditioner...
00167       // I tried setting a different sub-preconditioner here, but apparently the matrix
00168       // is not in the correct state (at this point) to call PCSetUp().
00169       ierr = PCSetType (pc, (char*) PCASM);
00170       CHKERRABORT(libMesh::COMM_WORLD,ierr);
00171       break;
00172     }
00173 
00174   case JACOBI_PRECOND:
00175     ierr = PCSetType (pc, (char*) PCJACOBI);    CHKERRABORT(libMesh::COMM_WORLD,ierr); break;
00176 
00177   case BLOCK_JACOBI_PRECOND:
00178     ierr = PCSetType (pc, (char*) PCBJACOBI);   CHKERRABORT(libMesh::COMM_WORLD,ierr); break;
00179 
00180   case SOR_PRECOND:
00181     ierr = PCSetType (pc, (char*) PCSOR);       CHKERRABORT(libMesh::COMM_WORLD,ierr); break;
00182 
00183   case EISENSTAT_PRECOND:
00184     ierr = PCSetType (pc, (char*) PCEISENSTAT); CHKERRABORT(libMesh::COMM_WORLD,ierr); break;
00185 
00186   case AMG_PRECOND:
00187     ierr = PCSetType (pc, (char*) PCHYPRE);     CHKERRABORT(libMesh::COMM_WORLD,ierr); break;
00188 
00189 #if !(PETSC_VERSION_LESS_THAN(2,1,2))
00190     // Only available for PETSC >= 2.1.2
00191   case USER_PRECOND:
00192     ierr = PCSetType (pc, (char*) PCMAT);       CHKERRABORT(libMesh::COMM_WORLD,ierr); break;
00193 #endif
00194 
00195   case SHELL_PRECOND:
00196     ierr = PCSetType (pc, (char*) PCSHELL);     CHKERRABORT(libMesh::COMM_WORLD,ierr); break;
00197 
00198   default:
00199     libMesh::err << "ERROR:  Unsupported PETSC Preconditioner: "
00200                   << preconditioner_type       << std::endl
00201                   << "Continuing with PETSC defaults" << std::endl;
00202   }
00203 
00204   // Set additional options if we are doing AMG and
00205   // HYPRE is available
00206 #ifdef LIBMESH_HAVE_PETSC_HYPRE
00207   if (preconditioner_type == AMG_PRECOND)
00208     {
00209       ierr = PCHYPRESetType(pc, "boomeramg");
00210       CHKERRABORT(libMesh::COMM_WORLD,ierr);
00211     }
00212 #endif
00213 
00214   // Let the commandline override stuff
00215   // FIXME: Unless we are doing AMG???
00216   if (preconditioner_type != AMG_PRECOND)
00217     {
00218       ierr = PCSetFromOptions(pc);
00219       CHKERRABORT(libMesh::COMM_WORLD,ierr);
00220     }
00221 }

template<typename T >
static void libMesh::PetscPreconditioner< T >::set_petsc_subpreconditioner_type ( const PCType  type,
PC &  pc 
) [static, private]
template<typename T >
void libMesh::PetscPreconditioner< T >::set_petsc_subpreconditioner_type ( PCType  type,
PC &  pc 
) [inline, static, private]

Some PETSc preconditioners (ILU, LU) don't work in parallel. This function is called from set_petsc_preconditioner_type() to set additional options for those so-called sub-preconditioners. This method ends up being static so that it can be called from set_petsc_preconditioner_type(). Not sure why set_petsc_preconditioner_type() needs to be static though...

Definition at line 227 of file petsc_preconditioner.C.

References libMesh::COMM_WORLD.

Referenced by libMesh::PetscPreconditioner< T >::set_petsc_preconditioner_type().

00231 {
00232   // For catching PETSc error return codes
00233   int ierr = 0;
00234 
00235   // All docs say must call KSPSetUp or PCSetUp before calling PCBJacobiGetSubKSP.
00236   // You must call PCSetUp after the preconditioner operators have been set, otherwise you get the:
00237   //
00238   // "Object is in wrong state!"
00239   // "Matrix must be set first."
00240   //
00241   // error messages...
00242   ierr = PCSetUp(pc);
00243   CHKERRABORT(libMesh::COMM_WORLD,ierr);
00244 
00245   // To store array of local KSP contexts on this processor
00246   KSP* subksps;
00247 
00248   // the number of blocks on this processor
00249   int n_local;
00250 
00251   // The global number of the first block on this processor.
00252   // This is not used, so we just pass PETSC_NULL instead.
00253   // int first_local;
00254 
00255   // Fill array of local KSP contexts
00256   ierr = PCBJacobiGetSubKSP(pc, &n_local, PETSC_NULL, &subksps);
00257   CHKERRABORT(libMesh::COMM_WORLD,ierr);
00258 
00259   // Loop over sub-ksp objects, set ILU preconditioner
00260   for (int i=0; i<n_local; ++i)
00261     {
00262       // Get pointer to sub KSP object's PC
00263       PC subpc;
00264       ierr = KSPGetPC(subksps[i], &subpc);
00265       CHKERRABORT(libMesh::COMM_WORLD,ierr);
00266 
00267       // Set requested type on the sub PC
00268       ierr = PCSetType(subpc, type);
00269       CHKERRABORT(libMesh::COMM_WORLD,ierr);
00270     }
00271 
00272 }

template<typename T >
void libMesh::Preconditioner< T >::set_type ( const PreconditionerType  pct  )  [inline, inherited]

Sets the type of preconditioner to use.

Definition at line 181 of file preconditioner.h.

References libMesh::Preconditioner< T >::_is_initialized, and libMesh::Preconditioner< T >::_preconditioner_type.

00182 {
00183   //If the preconditioner type changes we (probably) need to reinitialize.
00184   _is_initialized = false;
00185   _preconditioner_type = pct;
00186 }

template<typename T>
virtual void libMesh::Preconditioner< T >::setup (  )  [inline, virtual, inherited]

This is called every time the "operator might have changed".

This is essentially where you need to fill in your preconditioning matrix.

Definition at line 111 of file preconditioner.h.

00111 {}

template<typename T>
PreconditionerType libMesh::Preconditioner< T >::type (  )  const [inline, inherited]

Returns the type of preconditioner to use.

Definition at line 121 of file preconditioner.h.

00122   { return _preconditioner_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 >
Mat libMesh::PetscPreconditioner< T >::_mat [protected]

Petsc Matrix that's been pulled out of the _matrix object. This happens during init...

Definition at line 112 of file petsc_preconditioner.h.

Referenced by libMesh::PetscPreconditioner< T >::init().

template<typename T>
SparseMatrix<T>* libMesh::Preconditioner< T >::_matrix [protected, inherited]

The matrix P... ie the matrix to be preconditioned. This is often the actual system matrix of a linear sytem.

Definition at line 135 of file preconditioner.h.

Referenced by libMesh::TrilinosPreconditioner< T >::init(), libMesh::PetscPreconditioner< T >::init(), and libMesh::Preconditioner< T >::set_matrix().

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().


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

Site Created By: libMesh Developers
Last modified: February 05 2013 19:55:33 UTC

Hosted By:
SourceForge.net Logo