|
IFPACK Development
|
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 00030 #ifndef IFPACK_HYPRE_H 00031 #define IFPACK_HYPRE_H 00032 00033 #include "Ifpack_ConfigDefs.h" 00034 #ifdef HAVE_HYPRE 00035 00036 #include "HYPRE_IJ_mv.h" 00037 #include "HYPRE_parcsr_ls.h" 00038 #include "krylov.h" 00039 #include "_hypre_parcsr_mv.h" 00040 #include "_hypre_IJ_mv.h" 00041 #include "HYPRE_parcsr_mv.h" 00042 #include "HYPRE.h" 00043 #include "Ifpack_Preconditioner.h" 00044 #include "Ifpack_Condest.h" 00045 #include "Ifpack_ScalingType.h" 00046 #include "Epetra_CompObject.h" 00047 #include "Epetra_MultiVector.h" 00048 #include "Epetra_Vector.h" 00049 #include "Epetra_CrsGraph.h" 00050 #include "Epetra_CrsMatrix.h" 00051 #include "Epetra_BlockMap.h" 00052 #include "Epetra_Map.h" 00053 #include "Epetra_Object.h" 00054 #include "Epetra_Comm.h" 00055 #include "Epetra_CrsMatrix.h" 00056 #include "Epetra_Time.h" 00057 #include "Teuchos_RefCountPtr.hpp" 00058 #include "Epetra_MpiComm.h" 00059 00060 #ifndef HYPRE_ENUMS 00061 #define HYPRE_ENUMS 00062 00063 enum Hypre_Solver{ 00064 BoomerAMG, 00065 ParaSails, 00066 Euclid, 00067 AMS, 00068 Hybrid, 00069 PCG, 00070 GMRES, 00071 FlexGMRES, 00072 LGMRES, 00073 BiCGSTAB 00074 }; 00075 00077 enum Hypre_Chooser{ 00078 Solver, 00079 Preconditioner 00080 }; 00081 #endif //HYPRE_ENUMS 00082 00084 class FunctionParameter{ 00085 public: 00087 FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, int), int param1) : 00088 chooser_(chooser), 00089 option_(0), 00090 int_func_(funct_name), 00091 int_param1_(param1) {} 00092 00094 FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, double), double param1): 00095 chooser_(chooser), 00096 option_(1), 00097 double_func_(funct_name), 00098 double_param1_(param1) {} 00099 00101 FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, double, int), double param1, int param2): 00102 chooser_(chooser), 00103 option_(2), 00104 double_int_func_(funct_name), 00105 int_param1_(param2), 00106 double_param1_(param1) {} 00107 00109 FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, int, int), int param1, int param2): 00110 chooser_(chooser), 00111 option_(3), 00112 int_int_func_(funct_name), 00113 int_param1_(param1), 00114 int_param2_(param2) {} 00115 00117 FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, int*), int *param1): 00118 chooser_(chooser), 00119 option_(4), 00120 int_star_func_(funct_name), 00121 int_star_param_(param1) {} 00122 00124 FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, double*), double* param1): 00125 chooser_(chooser), 00126 option_(5), 00127 double_star_func_(funct_name), 00128 double_star_param_(param1) {} 00129 00131 int CallFunction(HYPRE_Solver solver, HYPRE_Solver precond){ 00132 if(chooser_ == Solver){ 00133 if(option_ == 0){ 00134 return int_func_(solver, int_param1_); 00135 } else if(option_ == 1){ 00136 return double_func_(solver, double_param1_); 00137 } else if(option_ == 2){ 00138 return double_int_func_(solver, double_param1_, int_param1_); 00139 } else if (option_ == 3){ 00140 return int_int_func_(solver, int_param1_, int_param2_); 00141 } else if (option_ == 4){ 00142 return int_star_func_(solver, int_star_param_); 00143 } else { 00144 return double_star_func_(solver, double_star_param_); 00145 } 00146 } else { 00147 if(option_ == 0){ 00148 return int_func_(precond, int_param1_); 00149 } else if(option_ == 1){ 00150 return double_func_(precond, double_param1_); 00151 } else if(option_ == 2){ 00152 return double_int_func_(precond, double_param1_, int_param1_); 00153 } else if(option_ == 3) { 00154 return int_int_func_(precond, int_param1_, int_param2_); 00155 } else if(option_ == 4) { 00156 return int_star_func_(precond, int_star_param_); 00157 } else { 00158 return double_star_func_(precond, double_star_param_); 00159 } 00160 } 00161 } 00162 00163 private: 00164 Hypre_Chooser chooser_; 00165 int option_; 00166 int (*int_func_)(HYPRE_Solver, int); 00167 int (*double_func_)(HYPRE_Solver, double); 00168 int (*double_int_func_)(HYPRE_Solver, double, int); 00169 int (*int_int_func_)(HYPRE_Solver, int, int); 00170 int (*int_star_func_)(HYPRE_Solver, int*); 00171 int (*double_star_func_)(HYPRE_Solver, double*); 00172 int int_param1_; 00173 int int_param2_; 00174 double double_param1_; 00175 int *int_star_param_; 00176 double *double_star_param_; 00177 }; 00178 00179 namespace Teuchos { 00180 class ParameterList; 00181 } 00182 00184 00189 class Ifpack_Hypre: public Ifpack_Preconditioner { 00190 00191 public: 00192 // @{ Constructors and destructors. 00194 Ifpack_Hypre(Epetra_RowMatrix* A); 00195 00197 ~Ifpack_Hypre(){ Destroy();} 00198 00199 // @} 00200 // @{ Construction methods 00201 00203 int Initialize(); 00204 00206 bool IsInitialized() const{ return(IsInitialized_);} 00207 00209 00211 int Compute(); 00212 00214 bool IsComputed() const{ return(IsComputed_);} 00215 00216 00218 /* This method is only available if the Teuchos package is enabled. 00219 This method recognizes six parameter names: Solver, 00220 Preconditioner, SolveOrPrecondition, SetPreconditioner, NumFunctions and Functions. These names are 00221 case sensitive. Solver requires an enumerated parameter of type Hypre_Solver. Preconditioner is similar 00222 except requires the type be a preconditioner. The options are listed below: 00223 Solvers Preconditioners 00224 BoomerAMG BoomerAMG 00225 AMS ParaSails 00226 Hybrid AMS 00227 PCG (Default) Euclid (Default) 00228 GMRES 00229 FlexGMRES 00230 LGMRES 00231 BiCGSTAB 00232 SolveOrPrecondition takes enumerated type Hypre_Chooser, Solver will solve the system, Preconditioner will apply the preconditioner. 00233 SetPreconditioner takes a boolean, true means the solver will use the preconditioner. 00234 NumFunctions takes an int that describes how many parameters will be passed into Functions. (This needs to be correct.) 00235 Functions takes an array of Ref Counted Pointers to an object called FunctionParameter. This class is implemented in Ifpack_Hypre.h. 00236 The object takes whether it is Solver or Preconditioner that we are setting a parameter for. 00237 The function in Hypre that sets the parameter, and the parameters for that function. An example is below: 00238 00239 RCP<FunctionParameter> functs[2]; 00240 functs[0] = rcp(new FunctionParameter(Solver, &HYPRE_PCGSetMaxIter, 1000)); // max iterations 00241 functs[1] = rcp(new FunctionParameter(Solver, &HYPRE_PCGSetTol, 1e-7)); // conv. tolerance 00242 list.set("NumFunctions", 2); 00243 list.set<RCP<FunctionParameter>*>("Functions", functs); 00244 NOTE: SetParameters() must be called to use ApplyInverse(), the solvers will not be created otherwise. An empty list is acceptable to use defaults. 00245 */ 00246 int SetParameters(Teuchos::ParameterList& parameterlist); 00247 00249 00257 int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int), int parameter); 00258 00260 00268 int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double), double parameter); 00269 00271 00280 int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double, int), double parameter1, int parameter2); 00281 00283 00292 int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int, int), int parameter1, int parameter2); 00293 00295 00303 int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double*), double* parameter); 00304 00306 00314 int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int*), int* parameter); 00315 00317 00326 int SetParameter(Hypre_Chooser chooser, Hypre_Solver Solver); 00327 00329 00337 int SetParameter(bool UsePreconditioner){ UsePreconditioner = UsePreconditioner_; return 0;} 00338 00340 00346 int SetParameter(Hypre_Chooser chooser) { SolveOrPrec_ = chooser; return 0;} 00347 00349 int CallFunctions() const; 00350 00352 00361 int SetUseTranspose(bool UseTranspose_in) {UseTranspose_ = UseTranspose_in; return(0);}; 00362 00363 // @} 00364 00365 // @{ Mathematical functions. 00366 // Applies the matrix to X, returns the result in Y. 00367 int Apply(const Epetra_MultiVector& X, 00368 Epetra_MultiVector& Y) const{ return(Multiply(false,X,Y));} 00369 00371 00382 int Multiply(bool Trans, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const; 00383 00385 00398 int ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const; 00399 00401 double Condest(const Ifpack_CondestType CT = Ifpack_Cheap, 00402 const int MaxIters = 1550, 00403 const double Tol = 1e-9, 00404 Epetra_RowMatrix* Matrix_in = 0); 00405 00407 double Condest() const{ return(Condest_);} 00408 00409 // @} 00410 // @{ Query methods 00411 00413 const char* Label() const {return(Label_);} 00414 00416 int SetLabel(const char* Label_in) 00417 { 00418 strcpy(Label_,Label_in); 00419 return(0); 00420 } 00421 00423 const Epetra_Map& OperatorDomainMap() const{ return *MySimpleMap_;} 00424 00426 const Epetra_Map& OperatorRangeMap() const{ return *MySimpleMap_;} 00427 00429 double NormInf() const {return(0.0);}; 00430 00432 bool HasNormInf() const {return(false);}; 00433 00435 bool UseTranspose() const {return(UseTranspose_);}; 00436 00438 const Epetra_Comm & Comm() const{return(A_->Comm());}; 00439 00441 const Epetra_RowMatrix& Matrix() const{ return(*A_);} 00442 00444 const HYPRE_IJMatrix& HypreMatrix() 00445 { 00446 if(IsInitialized() == false) 00447 Initialize(); 00448 return(HypreA_); 00449 } 00450 00452 virtual ostream& Print(ostream& os) const; 00453 00455 virtual int NumInitialize() const{ return(NumInitialize_);} 00456 00458 virtual int NumCompute() const{ return(NumCompute_);} 00459 00461 virtual int NumApplyInverse() const{ return(NumApplyInverse_);} 00462 00464 virtual double InitializeTime() const{ return(InitializeTime_);} 00465 00467 virtual double ComputeTime() const{ return(ComputeTime_);} 00468 00470 virtual double ApplyInverseTime() const{ return(ApplyInverseTime_);} 00471 00473 virtual double InitializeFlops() const{ return(0.0);} 00474 00476 virtual double ComputeFlops() const{ return(ComputeFlops_);} 00477 00479 virtual double ApplyInverseFlops() const{ return(ApplyInverseFlops_);} 00480 00481 private: 00482 00483 // @} 00484 // @{ Private methods 00485 00487 Ifpack_Hypre(const Ifpack_Hypre& RHS) : Time_(RHS.Comm()){} 00488 00490 Ifpack_Hypre& operator=(const Ifpack_Hypre& RHS){ return(*this);} 00491 00493 void Destroy(); 00494 00496 MPI_Comm GetMpiComm() const 00497 { return (dynamic_cast<const Epetra_MpiComm*>(&A_->Comm()))->GetMpiComm();} 00498 00500 00510 int Solve(bool Trans, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const; 00511 00512 00514 int NumGlobalRows() const {return(A_->NumGlobalRows());}; 00515 00517 int NumGlobalCols() const {return(A_->NumGlobalCols());}; 00518 00520 int NumMyRows() const {return(A_->NumMyRows());}; 00521 00523 int NumMyCols() const {return(A_->NumMyCols());}; 00524 00526 int SetSolverType(Hypre_Solver solver); 00527 00529 int SetPrecondType(Hypre_Solver precond); 00530 00532 int CreateSolver(); 00533 00535 int CreatePrecond(); 00536 00538 int AddFunToList(Teuchos::RCP<FunctionParameter> NewFun); 00539 00541 int Hypre_BoomerAMGCreate(MPI_Comm comm, HYPRE_Solver *solver) 00542 { return HYPRE_BoomerAMGCreate(solver);} 00543 00545 int Hypre_ParaSailsCreate(MPI_Comm comm, HYPRE_Solver *solver) 00546 { return HYPRE_ParaSailsCreate(comm, solver);} 00547 00549 int Hypre_EuclidCreate(MPI_Comm comm, HYPRE_Solver *solver) 00550 { return HYPRE_EuclidCreate(comm, solver);} 00551 00553 int Hypre_AMSCreate(MPI_Comm comm, HYPRE_Solver *solver) 00554 { return HYPRE_AMSCreate(solver);} 00555 00557 int Hypre_ParCSRHybridCreate(MPI_Comm comm, HYPRE_Solver *solver) 00558 { return HYPRE_ParCSRHybridCreate(solver);} 00559 00561 int Hypre_ParCSRPCGCreate(MPI_Comm comm, HYPRE_Solver *solver) 00562 { return HYPRE_ParCSRPCGCreate(comm, solver);} 00563 00565 int Hypre_ParCSRGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver) 00566 { return HYPRE_ParCSRGMRESCreate(comm, solver);} 00567 00569 int Hypre_ParCSRFlexGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver) 00570 { return HYPRE_ParCSRFlexGMRESCreate(comm, solver);} 00571 00573 int Hypre_ParCSRLGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver) 00574 { return HYPRE_ParCSRLGMRESCreate(comm, solver);} 00575 00577 int Hypre_ParCSRBiCGSTABCreate(MPI_Comm comm, HYPRE_Solver *solver) 00578 { return HYPRE_ParCSRBiCGSTABCreate(comm, solver);} 00579 00580 // @} 00581 // @{ Internal data 00582 00584 Teuchos::RefCountPtr<Epetra_RowMatrix> A_; 00586 Teuchos::ParameterList List_; 00588 bool UseTranspose_; 00590 double Condest_; 00592 bool IsInitialized_; 00594 bool IsComputed_; 00596 char Label_[160]; 00598 int NumInitialize_; 00600 int NumCompute_; 00602 mutable int NumApplyInverse_; 00604 double InitializeTime_; 00606 double ComputeTime_; 00608 mutable double ApplyInverseTime_; 00610 double ComputeFlops_; 00612 mutable double ApplyInverseFlops_; 00614 mutable Epetra_Time Time_; 00615 00617 mutable HYPRE_IJMatrix HypreA_; 00619 mutable HYPRE_ParCSRMatrix ParMatrix_; 00621 mutable HYPRE_IJVector XHypre_; 00623 mutable HYPRE_IJVector YHypre_; 00624 mutable HYPRE_ParVector ParX_; 00625 mutable HYPRE_ParVector ParY_; 00626 mutable hypre_ParVector *XVec_; 00627 mutable hypre_ParVector *YVec_; 00628 mutable hypre_Vector *XLocal_; 00629 mutable hypre_Vector *YLocal_; 00631 mutable HYPRE_Solver Solver_; 00633 mutable HYPRE_Solver Preconditioner_; 00634 // The following are pointers to functions to use the solver and preconditioner. 00635 int (Ifpack_Hypre::*SolverCreatePtr_)(MPI_Comm, HYPRE_Solver*); 00636 int (*SolverDestroyPtr_)(HYPRE_Solver); 00637 int (*SolverSetupPtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector); 00638 int (*SolverSolvePtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector); 00639 int (*SolverPrecondPtr_)(HYPRE_Solver, HYPRE_PtrToParSolverFcn, HYPRE_PtrToParSolverFcn, HYPRE_Solver); 00640 int (Ifpack_Hypre::*PrecondCreatePtr_)(MPI_Comm, HYPRE_Solver*); 00641 int (*PrecondDestroyPtr_)(HYPRE_Solver); 00642 int (*PrecondSetupPtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector); 00643 int (*PrecondSolvePtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector); 00644 00645 bool *IsSolverSetup_; 00646 bool *IsPrecondSetup_; 00648 Hypre_Chooser SolveOrPrec_; 00650 Teuchos::RefCountPtr<Epetra_Map> MySimpleMap_; 00652 int NumFunsToCall_; 00654 Hypre_Solver SolverType_; 00656 Hypre_Solver PrecondType_; 00658 bool UsePreconditioner_; 00660 std::vector<Teuchos::RCP<FunctionParameter> > FunsToCall_; 00662 bool NiceRowMap_; 00663 }; 00664 00665 #endif // HAVE_HYPRE 00666 #endif /* IFPACK_HYPRE_H */
1.7.4