IFPACK  Development
 All Classes Files Functions Variables Enumerations Friends
Ifpack_Hypre.h
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 
00043 #ifndef IFPACK_HYPRE_H
00044 #define IFPACK_HYPRE_H
00045 
00046 #include "Ifpack_ConfigDefs.h"
00047 #ifdef HAVE_HYPRE
00048 
00049 #include "HYPRE_IJ_mv.h"
00050 #include "HYPRE_parcsr_ls.h"
00051 #include "krylov.h"
00052 #include "_hypre_parcsr_mv.h"
00053 #include "_hypre_IJ_mv.h"
00054 #include "HYPRE_parcsr_mv.h"
00055 #include "HYPRE.h"
00056 #include "Ifpack_Preconditioner.h"
00057 #include "Ifpack_Condest.h"
00058 #include "Ifpack_ScalingType.h"
00059 #include "Epetra_CompObject.h"
00060 #include "Epetra_MultiVector.h"
00061 #include "Epetra_Vector.h"
00062 #include "Epetra_CrsGraph.h"
00063 #include "Epetra_CrsMatrix.h"
00064 #include "Epetra_BlockMap.h"
00065 #include "Epetra_Map.h"
00066 #include "Epetra_Object.h"
00067 #include "Epetra_Comm.h"
00068 #include "Epetra_CrsMatrix.h"
00069 #include "Epetra_Time.h"
00070 #include "Teuchos_RefCountPtr.hpp"
00071 #include "Epetra_MpiComm.h"
00072 
00073 #ifndef HYPRE_ENUMS
00074 #define HYPRE_ENUMS
00075 
00076 enum Hypre_Solver{ 
00077     BoomerAMG,
00078     ParaSails,
00079     Euclid,
00080     AMS,
00081     Hybrid,
00082     PCG,
00083     GMRES,
00084     FlexGMRES,
00085     LGMRES,
00086     BiCGSTAB
00087 };
00088 
00090 enum Hypre_Chooser{
00091     Solver,
00092     Preconditioner
00093 };
00094 #endif //HYPRE_ENUMS
00095 
00097 class FunctionParameter{
00098   public:
00100     FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, int), int param1) :
00101       chooser_(chooser),
00102       option_(0),
00103       int_func_(funct_name),
00104       int_param1_(param1) {}
00105 
00107     FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, double), double param1):
00108       chooser_(chooser),
00109       option_(1),
00110       double_func_(funct_name),
00111       double_param1_(param1) {}
00112 
00114     FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, double, int), double param1, int param2):
00115       chooser_(chooser),
00116       option_(2),
00117       double_int_func_(funct_name),
00118       int_param1_(param2),
00119       double_param1_(param1) {}
00120 
00122     FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, int, int), int param1, int param2):
00123       chooser_(chooser),
00124       option_(3),
00125       int_int_func_(funct_name),
00126       int_param1_(param1),
00127       int_param2_(param2) {}
00128 
00130     FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, int*), int *param1):
00131       chooser_(chooser),
00132       option_(4),
00133       int_star_func_(funct_name),
00134       int_star_param_(param1) {}
00135 
00137     FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, double*), double* param1):
00138       chooser_(chooser),
00139       option_(5),
00140       double_star_func_(funct_name),
00141       double_star_param_(param1) {}
00142 
00144     int CallFunction(HYPRE_Solver solver, HYPRE_Solver precond){
00145       if(chooser_ == Solver){
00146         if(option_ == 0){
00147           return int_func_(solver, int_param1_);
00148         } else if(option_ == 1){
00149           return double_func_(solver, double_param1_);
00150         } else if(option_ == 2){
00151           return double_int_func_(solver, double_param1_, int_param1_);
00152         } else if (option_ == 3){
00153           return int_int_func_(solver, int_param1_, int_param2_);
00154         } else if (option_ == 4){
00155           return int_star_func_(solver, int_star_param_);
00156         } else {
00157           return double_star_func_(solver, double_star_param_);
00158         }
00159       } else {
00160         if(option_ == 0){
00161           return int_func_(precond, int_param1_);
00162         } else if(option_ == 1){
00163           return double_func_(precond, double_param1_);
00164         } else if(option_ == 2){
00165           return double_int_func_(precond, double_param1_, int_param1_);
00166         } else if(option_ == 3) {
00167           return int_int_func_(precond, int_param1_, int_param2_);
00168         } else if(option_ == 4) {
00169           return int_star_func_(precond, int_star_param_);
00170         } else {
00171           return double_star_func_(precond, double_star_param_);
00172         }
00173       }
00174     }
00175 
00176   private:
00177     Hypre_Chooser chooser_;
00178     int option_;
00179     int (*int_func_)(HYPRE_Solver, int);
00180     int (*double_func_)(HYPRE_Solver, double);
00181     int (*double_int_func_)(HYPRE_Solver, double, int);
00182     int (*int_int_func_)(HYPRE_Solver, int, int);
00183     int (*int_star_func_)(HYPRE_Solver, int*);
00184     int (*double_star_func_)(HYPRE_Solver, double*);
00185     int int_param1_;
00186     int int_param2_;
00187     double double_param1_;
00188     int *int_star_param_;
00189     double *double_star_param_;
00190 };
00191 
00192 namespace Teuchos {
00193   class ParameterList;
00194 }
00195 
00197 
00202 class Ifpack_Hypre: public Ifpack_Preconditioner {
00203       
00204 public:
00205   // @{ Constructors and destructors.
00207   Ifpack_Hypre(Epetra_RowMatrix* A);
00208   
00210   ~Ifpack_Hypre(){ Destroy();}
00211 
00212   // @}
00213   // @{ Construction methods
00214   
00216   int Initialize();
00217   
00219   bool IsInitialized() const{ return(IsInitialized_);}
00220 
00222 
00224   int Compute();
00225 
00227   bool IsComputed() const{ return(IsComputed_);}
00228 
00229 
00231   /* This method is only available if the Teuchos package is enabled.
00232      This method recognizes six parameter names: Solver,
00233      Preconditioner, SolveOrPrecondition, SetPreconditioner, NumFunctions and Functions. These names are
00234      case sensitive. Solver requires an enumerated parameter of type Hypre_Solver. Preconditioner is similar
00235      except requires the type be a preconditioner. The options are listed below:
00236                        Solvers                            Preconditioners
00237                        BoomerAMG                          BoomerAMG
00238                        AMS                                ParaSails
00239                        Hybrid                             AMS
00240                        PCG (Default)                      Euclid (Default)
00241                        GMRES                              
00242                        FlexGMRES                          
00243                        LGMRES
00244                        BiCGSTAB
00245      SolveOrPrecondition takes enumerated type Hypre_Chooser, Solver will solve the system, Preconditioner will apply the preconditioner.
00246      SetPreconditioner takes a boolean, true means the solver will use the preconditioner.
00247      NumFunctions takes an int that describes how many parameters will be passed into Functions. (This needs to be correct.)
00248      Functions takes an array of Ref Counted Pointers to an object called FunctionParameter. This class is implemented in Ifpack_Hypre.h.
00249      The object takes whether it is Solver or Preconditioner that we are setting a parameter for.
00250      The function in Hypre that sets the parameter, and the parameters for that function. An example is below:
00251   
00252      RCP<FunctionParameter> functs[2];
00253      functs[0] = rcp(new FunctionParameter(Solver, &HYPRE_PCGSetMaxIter, 1000)); // max iterations 
00254      functs[1] = rcp(new FunctionParameter(Solver, &HYPRE_PCGSetTol, 1e-7)); // conv. tolerance 
00255      list.set("NumFunctions", 2);
00256      list.set<RCP<FunctionParameter>*>("Functions", functs); 
00257      NOTE: SetParameters() must be called to use ApplyInverse(), the solvers will not be created otherwise. An empty list is acceptable to use defaults.
00258   */
00259   int SetParameters(Teuchos::ParameterList& parameterlist);
00260 
00262 
00270     int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int), int parameter);
00271 
00273 
00281     int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double), double parameter);
00282 
00284 
00293     int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double, int), double parameter1, int parameter2);
00294 
00296 
00305     int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int, int), int parameter1, int parameter2);
00306 
00308 
00316     int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double*), double* parameter);
00317 
00319 
00327     int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int*), int* parameter);
00328 
00330 
00339     int SetParameter(Hypre_Chooser chooser, Hypre_Solver Solver);
00340 
00342 
00350     int SetParameter(bool UsePreconditioner){ UsePreconditioner = UsePreconditioner_; return 0;}
00351 
00353 
00359     int SetParameter(Hypre_Chooser chooser) { SolveOrPrec_ = chooser; return 0;}
00360 
00362     int CallFunctions() const;
00363 
00365 
00374   int SetUseTranspose(bool UseTranspose_in) {UseTranspose_ = UseTranspose_in; return(0);};
00375 
00376   // @}
00377 
00378   // @{ Mathematical functions.
00379   // Applies the matrix to X, returns the result in Y.
00380   int Apply(const Epetra_MultiVector& X, 
00381            Epetra_MultiVector& Y) const{ return(Multiply(false,X,Y));}
00382 
00384 
00395   int Multiply(bool Trans, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const;
00396 
00398 
00411   int ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const;
00412 
00414   double Condest(const Ifpack_CondestType CT = Ifpack_Cheap, 
00415                  const int MaxIters = 1550,
00416                  const double Tol = 1e-9,
00417          Epetra_RowMatrix* Matrix_in = 0);
00418 
00420   double Condest() const{ return(Condest_);}
00421 
00422   // @}
00423   // @{ Query methods
00424   
00426   const char* Label() const {return(Label_);}
00427 
00429   int SetLabel(const char* Label_in)
00430   {
00431     strcpy(Label_,Label_in);
00432     return(0);
00433   }
00434 
00436   const Epetra_Map& OperatorDomainMap() const{ return *MySimpleMap_;}
00437 
00439   const Epetra_Map& OperatorRangeMap() const{ return *MySimpleMap_;}
00440   
00442   double NormInf() const {return(0.0);};
00443 
00445   bool HasNormInf() const {return(false);};
00446 
00448   bool UseTranspose() const {return(UseTranspose_);};
00449 
00451   const Epetra_Comm & Comm() const{return(A_->Comm());};
00452 
00454   const Epetra_RowMatrix& Matrix() const{ return(*A_);}
00455 
00457   const HYPRE_IJMatrix& HypreMatrix()
00458   {
00459     if(IsInitialized() == false)
00460       Initialize();
00461     return(HypreA_);
00462   }
00463 
00465   virtual ostream& Print(ostream& os) const;
00466 
00468   virtual int NumInitialize() const{ return(NumInitialize_);}
00469 
00471   virtual int NumCompute() const{ return(NumCompute_);}
00472 
00474   virtual int NumApplyInverse() const{ return(NumApplyInverse_);}
00475 
00477   virtual double InitializeTime() const{ return(InitializeTime_);}
00478 
00480   virtual double ComputeTime() const{ return(ComputeTime_);}
00481 
00483   virtual double ApplyInverseTime() const{ return(ApplyInverseTime_);}
00484 
00486   virtual double InitializeFlops() const{ return(0.0);}
00487 
00489   virtual double ComputeFlops() const{ return(ComputeFlops_);}
00490 
00492   virtual double ApplyInverseFlops() const{ return(ApplyInverseFlops_);}
00493 
00494 private:
00495 
00496   // @}
00497   // @{ Private methods
00498 
00500   Ifpack_Hypre(const Ifpack_Hypre& RHS) : Time_(RHS.Comm()){}
00501 
00503   Ifpack_Hypre& operator=(const Ifpack_Hypre& RHS){ return(*this);}
00504 
00506   void Destroy();
00507 
00509   MPI_Comm GetMpiComm() const
00510     { return (dynamic_cast<const Epetra_MpiComm*>(&A_->Comm()))->GetMpiComm();}
00511 
00513 
00523   int Solve(bool Trans, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const;
00524 
00525 
00527   int NumGlobalRows() const {return(A_->NumGlobalRows());};
00528   
00530   int NumGlobalCols() const {return(A_->NumGlobalCols());};
00531   
00533   int NumMyRows() const {return(A_->NumMyRows());};
00534   
00536   int NumMyCols() const {return(A_->NumMyCols());};
00537   
00539   int SetSolverType(Hypre_Solver solver); 
00540 
00542   int SetPrecondType(Hypre_Solver precond);
00543 
00545   int CreateSolver();
00546 
00548   int CreatePrecond();
00549 
00551   int AddFunToList(Teuchos::RCP<FunctionParameter> NewFun);
00552 
00554   int Hypre_BoomerAMGCreate(MPI_Comm comm, HYPRE_Solver *solver)
00555     { return HYPRE_BoomerAMGCreate(solver);}
00556 
00558   int Hypre_ParaSailsCreate(MPI_Comm comm, HYPRE_Solver *solver)
00559     { return HYPRE_ParaSailsCreate(comm, solver);}
00560 
00562   int Hypre_EuclidCreate(MPI_Comm comm, HYPRE_Solver *solver)
00563     { return HYPRE_EuclidCreate(comm, solver);}
00564 
00566   int Hypre_AMSCreate(MPI_Comm comm, HYPRE_Solver *solver)
00567     { return HYPRE_AMSCreate(solver);}
00568 
00570   int Hypre_ParCSRHybridCreate(MPI_Comm comm, HYPRE_Solver *solver)
00571     { return HYPRE_ParCSRHybridCreate(solver);}
00572 
00574   int Hypre_ParCSRPCGCreate(MPI_Comm comm, HYPRE_Solver *solver)
00575     { return HYPRE_ParCSRPCGCreate(comm, solver);}
00576 
00578   int Hypre_ParCSRGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
00579     { return HYPRE_ParCSRGMRESCreate(comm, solver);}
00580 
00582   int Hypre_ParCSRFlexGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
00583     { return HYPRE_ParCSRFlexGMRESCreate(comm, solver);}
00584 
00586   int Hypre_ParCSRLGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
00587     { return HYPRE_ParCSRLGMRESCreate(comm, solver);}
00588 
00590   int Hypre_ParCSRBiCGSTABCreate(MPI_Comm comm, HYPRE_Solver *solver)
00591     { return HYPRE_ParCSRBiCGSTABCreate(comm, solver);}
00592 
00593   // @}
00594   // @{ Internal data
00595   
00597   Teuchos::RefCountPtr<Epetra_RowMatrix> A_;
00599   Teuchos::ParameterList List_;
00601   bool UseTranspose_;
00603   double Condest_;
00605   bool IsInitialized_;
00607   bool IsComputed_;
00609   char Label_[160];
00611   int NumInitialize_;
00613   int NumCompute_;
00615   mutable int NumApplyInverse_;
00617   double InitializeTime_;
00619   double ComputeTime_;
00621   mutable double ApplyInverseTime_;
00623   double ComputeFlops_;
00625   mutable double ApplyInverseFlops_;
00627   mutable Epetra_Time Time_;
00628 
00630   mutable HYPRE_IJMatrix HypreA_;
00632   mutable HYPRE_ParCSRMatrix ParMatrix_;
00634   mutable HYPRE_IJVector XHypre_;
00636   mutable HYPRE_IJVector YHypre_;
00637   mutable HYPRE_ParVector ParX_;
00638   mutable HYPRE_ParVector ParY_;
00639   mutable hypre_ParVector *XVec_;
00640   mutable hypre_ParVector *YVec_;
00641   mutable hypre_Vector *XLocal_;
00642   mutable hypre_Vector *YLocal_;
00644   mutable HYPRE_Solver Solver_;
00646   mutable HYPRE_Solver Preconditioner_;
00647   //  The following are pointers to functions to use the solver and preconditioner.
00648   int (Ifpack_Hypre::*SolverCreatePtr_)(MPI_Comm, HYPRE_Solver*);
00649   int (*SolverDestroyPtr_)(HYPRE_Solver);
00650   int (*SolverSetupPtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
00651   int (*SolverSolvePtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
00652   int (*SolverPrecondPtr_)(HYPRE_Solver, HYPRE_PtrToParSolverFcn, HYPRE_PtrToParSolverFcn, HYPRE_Solver);
00653   int (Ifpack_Hypre::*PrecondCreatePtr_)(MPI_Comm, HYPRE_Solver*);
00654   int (*PrecondDestroyPtr_)(HYPRE_Solver);
00655   int (*PrecondSetupPtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
00656   int (*PrecondSolvePtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
00657 
00658   bool *IsSolverSetup_;
00659   bool *IsPrecondSetup_;
00661   Hypre_Chooser SolveOrPrec_;
00663   Teuchos::RefCountPtr<Epetra_Map> MySimpleMap_;
00665   int NumFunsToCall_;
00667   Hypre_Solver SolverType_;
00669   Hypre_Solver PrecondType_;
00671   bool UsePreconditioner_;
00673   std::vector<Teuchos::RCP<FunctionParameter> > FunsToCall_;
00675   bool NiceRowMap_;
00676 };
00677 
00678 #endif // HAVE_HYPRE
00679 #endif /* IFPACK_HYPRE_H */
 All Classes Files Functions Variables Enumerations Friends