Ifpack_Hypre.cpp

00001 /*@HEADER
00002 // ***********************************************************************
00003 // 
00004 //       Ifpack: Object-Oriented Algebraic Preconditioner Package
00005 //                 Copyright (2009) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 //@HEADER
00028 */
00029 #include "Ifpack_Hypre.h"
00030 #if defined(HAVE_HYPRE) && defined(HAVE_MPI)
00031 
00032 #include "Ifpack_Utils.h"
00033 #include "Epetra_MpiComm.h"
00034 #include "Epetra_IntVector.h"
00035 #include "Epetra_Import.h"
00036 #include "Teuchos_ParameterList.hpp"
00037 #include "Teuchos_RCP.hpp"
00038 
00039 using Teuchos::RCP;
00040 using Teuchos::rcp;
00041 
00042 Ifpack_Hypre::Ifpack_Hypre(Epetra_RowMatrix* A):
00043   A_(rcp(A,false)),
00044   UseTranspose_(false),
00045   IsInitialized_(false),
00046   IsComputed_(false),
00047   Label_(),
00048   NumInitialize_(0),
00049   NumCompute_(0),
00050   NumApplyInverse_(0),
00051   InitializeTime_(0.0),
00052   ComputeTime_(0.0),
00053   ApplyInverseTime_(0.0),
00054   ComputeFlops_(0.0),
00055   ApplyInverseFlops_(0.0),
00056   Time_(A_->Comm()),
00057   SolveOrPrec_(Solver),
00058   NumFunsToCall_(0),
00059   SolverType_(PCG),
00060   PrecondType_(Euclid),
00061   UsePreconditioner_(false),
00062   NiceRowMap_(true)
00063 {
00064   IsSolverSetup_ = new bool[1];
00065   IsPrecondSetup_ = new bool[1];
00066   IsSolverSetup_[0] = false;
00067   IsPrecondSetup_[0] = false;
00068   MPI_Comm comm = GetMpiComm();
00069   int ilower = A_->RowMatrixRowMap().MinMyGID();
00070   int iupper = A_->RowMatrixRowMap().MaxMyGID();
00071   // Need to check if the RowMap is the way Hypre expects (if not more difficult)
00072   std::vector<int> ilowers; ilowers.resize(Comm().NumProc());
00073   std::vector<int> iuppers; iuppers.resize(Comm().NumProc());
00074   int myLower[1]; myLower[0] = ilower;
00075   int myUpper[1]; myUpper[0] = iupper;
00076   Comm().GatherAll(myLower, &ilowers[0], 1);
00077   Comm().GatherAll(myUpper, &iuppers[0], 1);
00078   for(int i = 0; i < Comm().NumProc()-1; i++){
00079     NiceRowMap_ = (NiceRowMap_ && iuppers[i]+1 == ilowers[i+1]);
00080   }
00081   if(!NiceRowMap_){
00082     ilower = (A_->NumGlobalRows() / Comm().NumProc())*Comm().MyPID();
00083     iupper = (A_->NumGlobalRows() / Comm().NumProc())*(Comm().MyPID()+1)-1;
00084     if(Comm().MyPID() == Comm().NumProc()-1){
00085       iupper = A_-> NumGlobalRows()-1;
00086     }
00087   }
00088 
00089   // Next create vectors that will be used when ApplyInverse() is called
00090   IFPACK_CHK_ERRV(HYPRE_IJVectorCreate(comm, ilower, iupper, &XHypre_));
00091   IFPACK_CHK_ERRV(HYPRE_IJVectorSetObjectType(XHypre_, HYPRE_PARCSR));
00092   IFPACK_CHK_ERRV(HYPRE_IJVectorInitialize(XHypre_));
00093   IFPACK_CHK_ERRV(HYPRE_IJVectorAssemble(XHypre_));
00094   IFPACK_CHK_ERRV(HYPRE_IJVectorGetObject(XHypre_, (void**) &ParX_));
00095 
00096   IFPACK_CHK_ERRV(HYPRE_IJVectorCreate(comm, ilower, iupper, &YHypre_));
00097   IFPACK_CHK_ERRV(HYPRE_IJVectorSetObjectType(YHypre_, HYPRE_PARCSR));
00098   IFPACK_CHK_ERRV(HYPRE_IJVectorInitialize(YHypre_));
00099   IFPACK_CHK_ERRV(HYPRE_IJVectorAssemble(YHypre_));
00100   IFPACK_CHK_ERRV(HYPRE_IJVectorGetObject(YHypre_, (void**) &ParY_));
00101 
00102   XVec_ = (hypre_ParVector *) hypre_IJVectorObject(((hypre_IJVector *) XHypre_));
00103   XLocal_ = hypre_ParVectorLocalVector(XVec_);
00104 
00105   YVec_ = (hypre_ParVector *) hypre_IJVectorObject(((hypre_IJVector *) YHypre_));
00106   YLocal_ = hypre_ParVectorLocalVector(YVec_);
00107   std::vector<int> rows; rows.resize(iupper - ilower +1);
00108   for(int i = ilower; i <= iupper; i++){
00109     rows[i-ilower] = i;
00110   }
00111   MySimpleMap_ = rcp(new Epetra_Map(-1, iupper-ilower+1, &rows[0], 0, Comm()));
00112 } //Constructor
00113 
00114 //==============================================================================
00115 void Ifpack_Hypre::Destroy(){
00116   if(IsInitialized()){
00117     IFPACK_CHK_ERRV(HYPRE_IJMatrixDestroy(HypreA_));
00118   } 
00119   IFPACK_CHK_ERRV(HYPRE_IJVectorDestroy(XHypre_));
00120   IFPACK_CHK_ERRV(HYPRE_IJVectorDestroy(YHypre_));
00121   if(IsSolverSetup_[0]){
00122     IFPACK_CHK_ERRV(SolverDestroyPtr_(Solver_));
00123   }
00124   if(IsPrecondSetup_[0]){
00125     IFPACK_CHK_ERRV(PrecondDestroyPtr_(Preconditioner_));
00126   }
00127   delete[] IsSolverSetup_;
00128   delete[] IsPrecondSetup_;
00129 } //Destroy()
00130 
00131 //==============================================================================
00132 int Ifpack_Hypre::Initialize(){
00133   Time_.ResetStartTime();
00134   MPI_Comm comm = GetMpiComm();
00135   int ilower = MySimpleMap_->MinMyGID();
00136   int iupper = MySimpleMap_->MaxMyGID();
00137   IFPACK_CHK_ERR(HYPRE_IJMatrixCreate(comm, ilower, iupper, ilower, iupper, &HypreA_));
00138   IFPACK_CHK_ERR(HYPRE_IJMatrixSetObjectType(HypreA_, HYPRE_PARCSR));
00139   IFPACK_CHK_ERR(HYPRE_IJMatrixInitialize(HypreA_));
00140   for(int i = 0; i < A_->NumMyRows(); i++){
00141     int numElements;
00142     IFPACK_CHK_ERR(A_->NumMyRowEntries(i,numElements));
00143     std::vector<int> indices; indices.resize(numElements);
00144     std::vector<double> values; values.resize(numElements);
00145     int numEntries;
00146     IFPACK_CHK_ERR(A_->ExtractMyRowCopy(i, numElements, numEntries, &values[0], &indices[0]));
00147     for(int j = 0; j < numEntries; j++){
00148       indices[j] = A_->RowMatrixColMap().GID(indices[j]);
00149     }
00150     int GlobalRow[1];
00151     GlobalRow[0] = A_->RowMatrixRowMap().GID(i);
00152     IFPACK_CHK_ERR(HYPRE_IJMatrixSetValues(HypreA_, 1, &numEntries, GlobalRow, &indices[0], &values[0]));
00153   }
00154   IFPACK_CHK_ERR(HYPRE_IJMatrixAssemble(HypreA_));
00155   IFPACK_CHK_ERR(HYPRE_IJMatrixGetObject(HypreA_, (void**)&ParMatrix_));
00156   IsInitialized_=true;
00157   NumInitialize_ = NumInitialize_ + 1;
00158   InitializeTime_ = InitializeTime_ + Time_.ElapsedTime();
00159   return 0;
00160 } //Initialize()
00161 
00162 //==============================================================================
00163 int Ifpack_Hypre::SetParameters(Teuchos::ParameterList& list){
00164   List_ = list;
00165   Hypre_Solver solType = list.get("Solver", PCG);
00166   SolverType_ = solType;
00167   Hypre_Solver precType = list.get("Preconditioner", Euclid);
00168   PrecondType_ = precType;
00169   Hypre_Chooser chooser = list.get("SolveOrPrecondition", Solver);
00170   SolveOrPrec_ = chooser;
00171   bool SetPrecond = list.get("SetPreconditioner", false);
00172   IFPACK_CHK_ERR(SetParameter(SetPrecond));
00173   int NumFunctions = list.get("NumFunctions", 0);
00174   FunsToCall_.clear();
00175   NumFunsToCall_ = 0;
00176   if(NumFunctions > 0){
00177     RCP<FunctionParameter>* params = list.get<RCP<FunctionParameter>*>("Functions");
00178     for(int i = 0; i < NumFunctions; i++){
00179       IFPACK_CHK_ERR(AddFunToList(params[i]));
00180     }
00181   }
00182   return 0;
00183 } //SetParameters()
00184 
00185 //==============================================================================
00186 int Ifpack_Hypre::AddFunToList(RCP<FunctionParameter> NewFun){
00187   NumFunsToCall_ = NumFunsToCall_+1;
00188   FunsToCall_.resize(NumFunsToCall_);
00189   FunsToCall_[NumFunsToCall_-1] = NewFun;
00190   return 0;
00191 } //AddFunToList()
00192 
00193 //==============================================================================
00194 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int), int parameter){
00195   RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter));
00196   IFPACK_CHK_ERR(AddFunToList(temp));
00197   return 0;
00198 } //SetParameter() - int function pointer
00199 
00200 //==============================================================================
00201 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double), double parameter){
00202   RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter));
00203   IFPACK_CHK_ERR(AddFunToList(temp));
00204   return 0;
00205 } //SetParameter() - double function pointer
00206 
00207 //==============================================================================
00208 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double, int), double parameter1, int parameter2){
00209   RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter1, parameter2));
00210   IFPACK_CHK_ERR(AddFunToList(temp));
00211   return 0;
00212 } //SetParameter() - double,int function pointer
00213 
00214 //==============================================================================
00215 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int, int), int parameter1, int parameter2){
00216   RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter1, parameter2));
00217   IFPACK_CHK_ERR(AddFunToList(temp));
00218   return 0;
00219 } //SetParameter() int,int function pointer
00220 
00221 //==============================================================================
00222 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double*), double* parameter){
00223   RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter));
00224   IFPACK_CHK_ERR(AddFunToList(temp));
00225   return 0;
00226 } //SetParameter() - double* function pointer
00227 
00228 //==============================================================================
00229 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int*), int* parameter){
00230   RCP<FunctionParameter> temp = rcp(new FunctionParameter(chooser, pt2Func, parameter));
00231   IFPACK_CHK_ERR(AddFunToList(temp));
00232   return 0;
00233 } //SetParameter() - int* function pointer
00234 
00235 //==============================================================================
00236 int Ifpack_Hypre::SetParameter(Hypre_Chooser chooser, Hypre_Solver solver){
00237   if(chooser == Solver){
00238     SolverType_ = solver;
00239   } else {
00240     PrecondType_ = solver;
00241   }
00242   return 0;
00243 } //SetParameter() - set type of solver
00244 
00245 //==============================================================================
00246 int Ifpack_Hypre::Compute(){
00247   if(IsInitialized() == false){
00248     IFPACK_CHK_ERR(Initialize());
00249   }
00250   Time_.ResetStartTime();
00251   IFPACK_CHK_ERR(SetSolverType(SolverType_));
00252   IFPACK_CHK_ERR(SetPrecondType(PrecondType_));
00253   CallFunctions();
00254   if(UsePreconditioner_){
00255     if(SolverPrecondPtr_ != NULL){
00256       IFPACK_CHK_ERR(SolverPrecondPtr_(Solver_, PrecondSolvePtr_, PrecondSetupPtr_, Preconditioner_));
00257     }
00258   }
00259   if(SolveOrPrec_ == Solver){
00260     IFPACK_CHK_ERR(SolverSetupPtr_(Solver_, ParMatrix_, ParX_, ParY_));
00261     IsSolverSetup_[0] = true;
00262   } else {
00263     IFPACK_CHK_ERR(PrecondSetupPtr_(Preconditioner_, ParMatrix_, ParX_, ParY_));
00264     IsPrecondSetup_[0] = true;
00265   }
00266   IsComputed_ = true;
00267   NumCompute_ = NumCompute_ + 1;
00268   ComputeTime_ = ComputeTime_ + Time_.ElapsedTime();
00269   return 0;
00270 } //Compute()
00271 
00272 //==============================================================================
00273 int Ifpack_Hypre::CallFunctions() const{
00274   for(int i = 0; i < NumFunsToCall_; i++){
00275     IFPACK_CHK_ERR(FunsToCall_[i]->CallFunction(Solver_, Preconditioner_));
00276   }
00277   return 0;
00278 } //CallFunctions()
00279 
00280 //==============================================================================
00281 int Ifpack_Hypre::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const{
00282   if(IsComputed() == false){
00283     IFPACK_CHK_ERR(-1);
00284   }
00285   Time_.ResetStartTime();
00286   bool SameVectors = false;
00287   int NumVectors = X.NumVectors();
00288   if (NumVectors != Y.NumVectors()) IFPACK_CHK_ERR(-1);  // X and Y must have same number of vectors
00289   if(X.Pointers() == Y.Pointers()){
00290     SameVectors = true;
00291   }
00292   for(int VecNum = 0; VecNum < NumVectors; VecNum++) {
00293     //Get values for current vector in multivector.
00294     double * XValues;
00295     IFPACK_CHK_ERR((*X(VecNum)).ExtractView(&XValues));
00296     double * YValues;
00297     if(!SameVectors){
00298       IFPACK_CHK_ERR((*Y(VecNum)).ExtractView(&YValues));
00299     } else {
00300       YValues = new double[X.MyLength()];
00301     }
00302     // Temporarily make a pointer to data in Hypre for end
00303     double *XTemp = XLocal_->data;
00304     // Replace data in Hypre vectors with epetra values
00305     XLocal_->data = XValues;
00306     double *YTemp = YLocal_->data;
00307     YLocal_->data = YValues;
00308 
00309     IFPACK_CHK_ERR(HYPRE_ParVectorSetConstantValues(ParY_, 0.0));
00310     if(SolveOrPrec_ == Solver){
00311       // Use the solver methods
00312       IFPACK_CHK_ERR(SolverSolvePtr_(Solver_, ParMatrix_, ParX_, ParY_));
00313     } else {
00314       // Apply the preconditioner
00315       IFPACK_CHK_ERR(PrecondSolvePtr_(Preconditioner_, ParMatrix_, ParX_, ParY_));
00316     }
00317     if(SameVectors){
00318       int NumEntries = Y.MyLength();
00319       std::vector<double> new_values; new_values.resize(NumEntries);
00320       std::vector<int> new_indices; new_indices.resize(NumEntries);
00321       for(int i = 0; i < NumEntries; i++){
00322         new_values[i] = YValues[i];
00323         new_indices[i] = i;
00324       }
00325       IFPACK_CHK_ERR((*Y(VecNum)).ReplaceMyValues(NumEntries, &new_values[0], &new_indices[0]));
00326       delete[] YValues;
00327     }
00328     XLocal_->data = XTemp;
00329     YLocal_->data = YTemp;
00330   }
00331   NumApplyInverse_ = NumApplyInverse_ + 1;
00332   ApplyInverseTime_ = ApplyInverseTime_ + Time_.ElapsedTime();
00333   return 0;
00334 } //ApplyInverse()
00335 
00336 //==============================================================================
00337 int Ifpack_Hypre::Multiply(bool TransA, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const{
00338   if(IsInitialized() == false){
00339     IFPACK_CHK_ERR(-1);
00340   }
00341   bool SameVectors = false;
00342   int NumVectors = X.NumVectors();
00343   if (NumVectors != Y.NumVectors()) IFPACK_CHK_ERR(-1);  // X and Y must have same number of vectors
00344   if(X.Pointers() == Y.Pointers()){
00345     SameVectors = true;
00346   }
00347   for(int VecNum = 0; VecNum < NumVectors; VecNum++) {
00348     //Get values for current vector in multivector.
00349     double * XValues;
00350     double * YValues;
00351     IFPACK_CHK_ERR((*X(VecNum)).ExtractView(&XValues));
00352     double *XTemp = XLocal_->data;
00353     double *YTemp = YLocal_->data;
00354     if(!SameVectors){
00355       IFPACK_CHK_ERR((*Y(VecNum)).ExtractView(&YValues));
00356     } else {
00357       YValues = new double[X.MyLength()];
00358     }
00359     YLocal_->data = YValues;
00360     IFPACK_CHK_ERR(HYPRE_ParVectorSetConstantValues(ParY_,0.0));
00361     // Temporarily make a pointer to data in Hypre for end
00362     // Replace data in Hypre vectors with epetra values
00363     XLocal_->data = XValues;
00364     // Do actual computation.
00365     if(TransA) {
00366       // Use transpose of A in multiply
00367       IFPACK_CHK_ERR(HYPRE_ParCSRMatrixMatvecT(1.0, ParMatrix_, ParX_, 1.0, ParY_));
00368     } else {
00369       IFPACK_CHK_ERR(HYPRE_ParCSRMatrixMatvec(1.0, ParMatrix_, ParX_, 1.0, ParY_));
00370     }
00371     if(SameVectors){
00372       int NumEntries = Y.MyLength();
00373       std::vector<double> new_values; new_values.resize(NumEntries);
00374       std::vector<int> new_indices; new_indices.resize(NumEntries);
00375       for(int i = 0; i < NumEntries; i++){
00376         new_values[i] = YValues[i];
00377         new_indices[i] = i;
00378       }
00379       IFPACK_CHK_ERR((*Y(VecNum)).ReplaceMyValues(NumEntries, &new_values[0], &new_indices[0]));
00380       delete[] YValues;
00381     }
00382     XLocal_->data = XTemp;
00383     YLocal_->data = YTemp;
00384   }
00385   return 0;
00386 } //Multiply()
00387 
00388 //==============================================================================
00389 ostream& Ifpack_Hypre::Print(ostream& os) const{
00390   if (!Comm().MyPID()) {
00391     os << endl;
00392     os << "================================================================================" << endl;
00393     os << "Ifpack_Hypre: " << Label () << endl << endl;
00394     os << "Using " << Comm().NumProc() << " processors." << endl;
00395     os << "Global number of rows            = " << A_->NumGlobalRows() << endl;
00396     os << "Global number of nonzeros        = " << A_->NumGlobalNonzeros() << endl;
00397     os << "Condition number estimate = " << Condest() << endl;
00398     os << endl;
00399     os << "Phase           # calls   Total Time (s)       Total MFlops     MFlops/s" << endl;
00400     os << "-----           -------   --------------       ------------     --------" << endl;
00401     os << "Initialize()    "   << std::setw(5) << NumInitialize_
00402        << "  " << std::setw(15) << InitializeTime_
00403        << "              0.0              0.0" << endl;
00404     os << "Compute()       "   << std::setw(5) << NumCompute_
00405        << "  " << std::setw(15) << ComputeTime_
00406        << "  " << std::setw(15) << 1.0e-6 * ComputeFlops_;
00407     if (ComputeTime_ != 0.0)
00408       os << "  " << std::setw(15) << 1.0e-6 * ComputeFlops_ / ComputeTime_ << endl;
00409     else
00410       os << "  " << std::setw(15) << 0.0 << endl;
00411     os << "ApplyInverse()  "   << std::setw(5) << NumApplyInverse_
00412        << "  " << std::setw(15) << ApplyInverseTime_
00413        << "  " << std::setw(15) << 1.0e-6 * ApplyInverseFlops_;
00414     if (ApplyInverseTime_ != 0.0)
00415       os << "  " << std::setw(15) << 1.0e-6 * ApplyInverseFlops_ / ApplyInverseTime_ << endl;
00416     else
00417       os << "  " << std::setw(15) << 0.0 << endl;
00418     os << "================================================================================" << endl;
00419     os << endl;
00420   }
00421   return os;
00422 } //Print()
00423 
00424 //==============================================================================
00425 double Ifpack_Hypre::Condest(const Ifpack_CondestType CT, 
00426                              const int MaxIters,
00427                              const double Tol,
00428                              Epetra_RowMatrix* Matrix_in){
00429   if (!IsComputed()) // cannot compute right now
00430     return(-1.0);
00431   Condest_ = Ifpack_Condest(*this, CT, MaxIters, Tol, Matrix_in);
00432   return(Condest_);
00433 } //Condest()
00434 
00435 //==============================================================================
00436 int Ifpack_Hypre::SetSolverType(Hypre_Solver Solver){
00437   switch(Solver) {
00438     case BoomerAMG:
00439       if(IsSolverSetup_[0]){
00440         SolverDestroyPtr_(Solver_);
00441         IsSolverSetup_[0] = false;
00442       }
00443       SolverCreatePtr_ = &Ifpack_Hypre::Hypre_BoomerAMGCreate;
00444       SolverDestroyPtr_ = &HYPRE_BoomerAMGDestroy;
00445       SolverSetupPtr_ = &HYPRE_BoomerAMGSetup;
00446       SolverPrecondPtr_ = NULL;
00447       SolverSolvePtr_ = &HYPRE_BoomerAMGSolve;
00448       break;
00449     case AMS:
00450       if(IsSolverSetup_[0]){
00451         SolverDestroyPtr_(Solver_);
00452         IsSolverSetup_[0] = false;
00453       }
00454       SolverCreatePtr_ = &Ifpack_Hypre::Hypre_AMSCreate;
00455       SolverDestroyPtr_ = &HYPRE_AMSDestroy;
00456       SolverSetupPtr_ = &HYPRE_AMSSetup;
00457       SolverSolvePtr_ = &HYPRE_AMSSolve;
00458       SolverPrecondPtr_ = NULL;
00459       break;
00460     case Hybrid:
00461       if(IsSolverSetup_[0]){
00462         SolverDestroyPtr_(Solver_);
00463         IsSolverSetup_[0] = false;
00464       }
00465       SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRHybridCreate;
00466       SolverDestroyPtr_ = &HYPRE_ParCSRHybridDestroy;
00467       SolverSetupPtr_ = &HYPRE_ParCSRHybridSetup;
00468       SolverSolvePtr_ = &HYPRE_ParCSRHybridSolve;
00469       SolverPrecondPtr_ = &HYPRE_ParCSRHybridSetPrecond;
00470       break;
00471     case PCG:
00472       if(IsSolverSetup_[0]){
00473         SolverDestroyPtr_(Solver_);
00474         IsSolverSetup_[0] = false;
00475       }
00476       SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRPCGCreate;
00477       SolverDestroyPtr_ = &HYPRE_ParCSRPCGDestroy;
00478       SolverSetupPtr_ = &HYPRE_ParCSRPCGSetup;
00479       SolverSolvePtr_ = &HYPRE_ParCSRPCGSolve;
00480       SolverPrecondPtr_ = &HYPRE_ParCSRPCGSetPrecond;
00481       break;
00482     case GMRES:
00483       if(IsSolverSetup_[0]){
00484         SolverDestroyPtr_(Solver_);
00485         IsSolverSetup_[0] = false;
00486       }
00487       SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRGMRESCreate;
00488       SolverDestroyPtr_ = &HYPRE_ParCSRGMRESDestroy;
00489       SolverSetupPtr_ = &HYPRE_ParCSRGMRESSetup;
00490       SolverPrecondPtr_ = &HYPRE_ParCSRGMRESSetPrecond;
00491       break;
00492     case FlexGMRES:
00493       if(IsSolverSetup_[0]){
00494         SolverDestroyPtr_(Solver_);
00495         IsSolverSetup_[0] = false;
00496       }
00497       SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRFlexGMRESCreate;
00498       SolverDestroyPtr_ = &HYPRE_ParCSRFlexGMRESDestroy;
00499       SolverSetupPtr_ = &HYPRE_ParCSRFlexGMRESSetup;
00500       SolverSolvePtr_ = &HYPRE_ParCSRFlexGMRESSolve;
00501       SolverPrecondPtr_ = &HYPRE_ParCSRFlexGMRESSetPrecond;
00502       break;
00503     case LGMRES:
00504       if(IsSolverSetup_[0]){
00505         SolverDestroyPtr_(Solver_);
00506         IsSolverSetup_[0] = false;
00507       }
00508       SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRLGMRESCreate;
00509       SolverDestroyPtr_ = &HYPRE_ParCSRLGMRESDestroy;
00510       SolverSetupPtr_ = &HYPRE_ParCSRLGMRESSetup;
00511       SolverSolvePtr_ = &HYPRE_ParCSRLGMRESSolve;
00512       SolverPrecondPtr_ = &HYPRE_ParCSRLGMRESSetPrecond;
00513       break;
00514     case BiCGSTAB:
00515       if(IsSolverSetup_[0]){
00516         SolverDestroyPtr_(Solver_);
00517         IsSolverSetup_[0] = false;
00518       }
00519       SolverCreatePtr_ = &Ifpack_Hypre::Hypre_ParCSRBiCGSTABCreate;
00520       SolverDestroyPtr_ = &HYPRE_ParCSRBiCGSTABDestroy;
00521       SolverSetupPtr_ = &HYPRE_ParCSRBiCGSTABSetup;
00522       SolverSolvePtr_ = &HYPRE_ParCSRBiCGSTABSolve;
00523       SolverPrecondPtr_ = &HYPRE_ParCSRBiCGSTABSetPrecond;
00524       break;
00525     default:
00526       return -1;
00527     }
00528   CreateSolver();
00529   return 0;
00530 } //SetSolverType()
00531 
00532 //==============================================================================
00533 int Ifpack_Hypre::SetPrecondType(Hypre_Solver Precond){
00534   switch(Precond) {
00535     case BoomerAMG:
00536       if(IsPrecondSetup_[0]){
00537         PrecondDestroyPtr_(Preconditioner_);
00538         IsPrecondSetup_[0] = false;
00539       }
00540       PrecondCreatePtr_ = &Ifpack_Hypre::Hypre_BoomerAMGCreate;
00541       PrecondDestroyPtr_ = &HYPRE_BoomerAMGDestroy;
00542       PrecondSetupPtr_ = &HYPRE_BoomerAMGSetup;
00543       PrecondSolvePtr_ = &HYPRE_BoomerAMGSolve;
00544       break;
00545     case ParaSails:
00546       if(IsPrecondSetup_[0]){
00547         PrecondDestroyPtr_(Preconditioner_);
00548         IsPrecondSetup_[0] = false;
00549       }
00550       PrecondCreatePtr_ = &Ifpack_Hypre::Hypre_ParaSailsCreate;
00551       PrecondDestroyPtr_ = &HYPRE_ParaSailsDestroy;
00552       PrecondSetupPtr_ = &HYPRE_ParaSailsSetup;
00553       PrecondSolvePtr_ = &HYPRE_ParaSailsSolve;
00554       break;
00555     case Euclid:
00556       if(IsPrecondSetup_[0]){
00557         PrecondDestroyPtr_(Preconditioner_);
00558         IsPrecondSetup_[0] = false;
00559       }
00560       PrecondCreatePtr_ = &Ifpack_Hypre::Hypre_EuclidCreate;
00561       PrecondDestroyPtr_ = &HYPRE_EuclidDestroy;
00562       PrecondSetupPtr_ = &HYPRE_EuclidSetup;
00563       PrecondSolvePtr_ = &HYPRE_EuclidSolve;
00564       break;
00565     case AMS:
00566       if(IsPrecondSetup_[0]){
00567         PrecondDestroyPtr_(Preconditioner_);
00568         IsPrecondSetup_[0] = false;
00569       }
00570       PrecondCreatePtr_ = &Ifpack_Hypre::Hypre_AMSCreate;
00571       PrecondDestroyPtr_ = &HYPRE_AMSDestroy;
00572       PrecondSetupPtr_ = &HYPRE_AMSSetup;
00573       PrecondSolvePtr_ = &HYPRE_AMSSolve;
00574       break;
00575     default:
00576       return -1;
00577     }
00578   CreatePrecond();
00579   return 0;
00580 
00581 } //SetPrecondType()
00582 
00583 //==============================================================================
00584 int Ifpack_Hypre::CreateSolver(){
00585   MPI_Comm comm;
00586   HYPRE_ParCSRMatrixGetComm(ParMatrix_, &comm);
00587   return (this->*SolverCreatePtr_)(comm, &Solver_);
00588 } //CreateSolver()
00589 
00590 //==============================================================================
00591 int Ifpack_Hypre::CreatePrecond(){
00592   MPI_Comm comm;
00593   HYPRE_ParCSRMatrixGetComm(ParMatrix_, &comm);
00594   return (this->*PrecondCreatePtr_)(comm, &Preconditioner_);
00595 } //CreatePrecond()
00596 
00597 #endif // HAVE_HYPRE && HAVE_MPI

Generated on Wed May 12 21:30:18 2010 for IFPACK by  doxygen 1.4.7