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