Ifpack Package Browser (Single Doxygen Collection)  Development
Ifpack_Hypre.h
Go to the documentation of this file.
1 /*@HEADER
2 // ***********************************************************************
3 //
4 // Ifpack: Object-Oriented Algebraic Preconditioner Package
5 // Copyright (2002) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 //@HEADER
41 */
42 
43 #ifndef IFPACK_HYPRE_H
44 #define IFPACK_HYPRE_H
45 
46 #include "Ifpack_ConfigDefs.h"
47 #ifdef HAVE_HYPRE
48 
49 #include "HYPRE_IJ_mv.h"
50 #include "HYPRE_parcsr_ls.h"
51 #include "krylov.h"
52 #include "_hypre_parcsr_mv.h"
53 #include "_hypre_IJ_mv.h"
54 #include "HYPRE_parcsr_mv.h"
55 #include "HYPRE.h"
56 #include "Ifpack_Preconditioner.h"
57 #include "Ifpack_Condest.h"
58 #include "Ifpack_ScalingType.h"
59 #include "Epetra_CompObject.h"
60 #include "Epetra_MultiVector.h"
61 #include "Epetra_Vector.h"
62 #include "Epetra_CrsGraph.h"
63 #include "Epetra_CrsMatrix.h"
64 #include "Epetra_BlockMap.h"
65 #include "Epetra_Map.h"
66 #include "Epetra_Object.h"
67 #include "Epetra_Comm.h"
68 #include "Epetra_CrsMatrix.h"
69 #include "Epetra_Time.h"
70 #include "Teuchos_RefCountPtr.hpp"
71 #include "Epetra_MpiComm.h"
72 
73 #ifndef HYPRE_ENUMS
74 #define HYPRE_ENUMS
75 enum Hypre_Solver{
77  BoomerAMG,
78  ParaSails,
79  Euclid,
80  AMS,
81  Hybrid,
82  PCG,
83  GMRES,
84  FlexGMRES,
85  LGMRES,
86  BiCGSTAB
87 };
88 
90 enum Hypre_Chooser{
91  Solver,
92  Preconditioner
93 };
94 #endif //HYPRE_ENUMS
95 
97 class FunctionParameter{
98  public:
100  FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, int), int param1) :
101  chooser_(chooser),
102  option_(0),
103  int_func_(funct_name),
104  int_param1_(param1) {}
105 
107  FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, double), double param1):
108  chooser_(chooser),
109  option_(1),
110  double_func_(funct_name),
111  double_param1_(param1) {}
112 
114  FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, double, int), double param1, int param2):
115  chooser_(chooser),
116  option_(2),
117  double_int_func_(funct_name),
118  int_param1_(param2),
119  double_param1_(param1) {}
120 
122  FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, int, int), int param1, int param2):
123  chooser_(chooser),
124  option_(3),
125  int_int_func_(funct_name),
126  int_param1_(param1),
127  int_param2_(param2) {}
128 
130  FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, int*), int *param1):
131  chooser_(chooser),
132  option_(4),
133  int_star_func_(funct_name),
134  int_star_param_(param1) {}
135 
137  FunctionParameter(Hypre_Chooser chooser, int (*funct_name)(HYPRE_Solver, double*), double* param1):
138  chooser_(chooser),
139  option_(5),
140  double_star_func_(funct_name),
141  double_star_param_(param1) {}
142 
144  int CallFunction(HYPRE_Solver solver, HYPRE_Solver precond){
145  if(chooser_ == Solver){
146  if(option_ == 0){
147  return int_func_(solver, int_param1_);
148  } else if(option_ == 1){
149  return double_func_(solver, double_param1_);
150  } else if(option_ == 2){
151  return double_int_func_(solver, double_param1_, int_param1_);
152  } else if (option_ == 3){
153  return int_int_func_(solver, int_param1_, int_param2_);
154  } else if (option_ == 4){
155  return int_star_func_(solver, int_star_param_);
156  } else {
157  return double_star_func_(solver, double_star_param_);
158  }
159  } else {
160  if(option_ == 0){
161  return int_func_(precond, int_param1_);
162  } else if(option_ == 1){
163  return double_func_(precond, double_param1_);
164  } else if(option_ == 2){
165  return double_int_func_(precond, double_param1_, int_param1_);
166  } else if(option_ == 3) {
167  return int_int_func_(precond, int_param1_, int_param2_);
168  } else if(option_ == 4) {
169  return int_star_func_(precond, int_star_param_);
170  } else {
171  return double_star_func_(precond, double_star_param_);
172  }
173  }
174  }
175 
176  private:
177  Hypre_Chooser chooser_;
178  int option_;
179  int (*int_func_)(HYPRE_Solver, int);
180  int (*double_func_)(HYPRE_Solver, double);
181  int (*double_int_func_)(HYPRE_Solver, double, int);
182  int (*int_int_func_)(HYPRE_Solver, int, int);
183  int (*int_star_func_)(HYPRE_Solver, int*);
184  int (*double_star_func_)(HYPRE_Solver, double*);
185  int int_param1_;
186  int int_param2_;
187  double double_param1_;
188  int *int_star_param_;
189  double *double_star_param_;
190 };
191 
192 namespace Teuchos {
193  class ParameterList;
194 }
195 
197 
202 class Ifpack_Hypre: public Ifpack_Preconditioner {
203 
204 public:
205  // @{ Constructors and destructors.
207  Ifpack_Hypre(Epetra_RowMatrix* A);
208 
210  ~Ifpack_Hypre(){ Destroy();}
211 
212  // @}
213  // @{ Construction methods
214 
216  int Initialize();
217 
219  bool IsInitialized() const{ return(IsInitialized_);}
220 
222 
224  int Compute();
225 
227  bool IsComputed() const{ return(IsComputed_);}
228 
229 
231  /* This method is only available if the Teuchos package is enabled.
232  This method recognizes six parameter names: Solver,
233  Preconditioner, SolveOrPrecondition, SetPreconditioner, NumFunctions and Functions. These names are
234  case sensitive. Solver requires an enumerated parameter of type Hypre_Solver. Preconditioner is similar
235  except requires the type be a preconditioner. The options are listed below:
236  Solvers Preconditioners
237  BoomerAMG BoomerAMG
238  AMS ParaSails
239  Hybrid AMS
240  PCG (Default) Euclid (Default)
241  GMRES
242  FlexGMRES
243  LGMRES
244  BiCGSTAB
245  SolveOrPrecondition takes enumerated type Hypre_Chooser, Solver will solve the system, Preconditioner will apply the preconditioner.
246  SetPreconditioner takes a boolean, true means the solver will use the preconditioner.
247  NumFunctions takes an int that describes how many parameters will be passed into Functions. (This needs to be correct.)
248  Functions takes an array of Ref Counted Pointers to an object called FunctionParameter. This class is implemented in Ifpack_Hypre.h.
249  The object takes whether it is Solver or Preconditioner that we are setting a parameter for.
250  The function in Hypre that sets the parameter, and the parameters for that function. An example is below:
251 
252  RCP<FunctionParameter> functs[2];
253  functs[0] = rcp(new FunctionParameter(Solver, &HYPRE_PCGSetMaxIter, 1000)); // max iterations
254  functs[1] = rcp(new FunctionParameter(Solver, &HYPRE_PCGSetTol, 1e-7)); // conv. tolerance
255  list.set("NumFunctions", 2);
256  list.set<RCP<FunctionParameter>*>("Functions", functs);
257  NOTE: SetParameters() must be called to use ApplyInverse(), the solvers will not be created otherwise. An empty list is acceptable to use defaults.
258  */
259  int SetParameters(Teuchos::ParameterList& parameterlist);
260 
262 
270  int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int), int parameter);
271 
273 
281  int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double), double parameter);
282 
284 
293  int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double, int), double parameter1, int parameter2);
294 
296 
305  int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int, int), int parameter1, int parameter2);
306 
308 
316  int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, double*), double* parameter);
317 
319 
327  int SetParameter(Hypre_Chooser chooser, int (*pt2Func)(HYPRE_Solver, int*), int* parameter);
328 
330 
339  int SetParameter(Hypre_Chooser chooser, Hypre_Solver Solver);
340 
342 
350  int SetParameter(bool UsePreconditioner){ UsePreconditioner_ = UsePreconditioner; return 0;}
351 
353 
359  int SetParameter(Hypre_Chooser chooser) { SolveOrPrec_ = chooser; return 0;}
360 
362  int CallFunctions() const;
363 
365 
374  int SetUseTranspose(bool UseTranspose_in) {UseTranspose_ = UseTranspose_in; return(0);};
375 
376  // @}
377 
378  // @{ Mathematical functions.
379  // Applies the matrix to X, returns the result in Y.
380  int Apply(const Epetra_MultiVector& X,
381  Epetra_MultiVector& Y) const{ return(Multiply(false,X,Y));}
382 
384 
395  int Multiply(bool Trans, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const;
396 
398 
411  int ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const;
412 
414  double Condest(const Ifpack_CondestType CT = Ifpack_Cheap,
415  const int MaxIters = 1550,
416  const double Tol = 1e-9,
417  Epetra_RowMatrix* Matrix_in = 0);
418 
420  double Condest() const{ return(Condest_);}
421 
422  // @}
423  // @{ Query methods
424 
426  const char* Label() const {return(Label_);}
427 
429  int SetLabel(const char* Label_in)
430  {
431  strcpy(Label_,Label_in);
432  return(0);
433  }
434 
436  const Epetra_Map& OperatorDomainMap() const{ return *MySimpleMap_;}
437 
439  const Epetra_Map& OperatorRangeMap() const{ return *MySimpleMap_;}
440 
442  double NormInf() const {return(0.0);};
443 
445  bool HasNormInf() const {return(false);};
446 
448  bool UseTranspose() const {return(UseTranspose_);};
449 
451  const Epetra_Comm & Comm() const{return(A_->Comm());};
452 
454  const Epetra_RowMatrix& Matrix() const{ return(*A_);}
455 
457  const HYPRE_IJMatrix& HypreMatrix()
458  {
459  if(IsInitialized() == false)
460  Initialize();
461  return(HypreA_);
462  }
463 
465  virtual std::ostream& Print(std::ostream& os) const;
466 
468  virtual int NumInitialize() const{ return(NumInitialize_);}
469 
471  virtual int NumCompute() const{ return(NumCompute_);}
472 
474  virtual int NumApplyInverse() const{ return(NumApplyInverse_);}
475 
477  virtual double InitializeTime() const{ return(InitializeTime_);}
478 
480  virtual double ComputeTime() const{ return(ComputeTime_);}
481 
483  virtual double ApplyInverseTime() const{ return(ApplyInverseTime_);}
484 
486  virtual double InitializeFlops() const{ return(0.0);}
487 
489  virtual double ComputeFlops() const{ return(ComputeFlops_);}
490 
492  virtual double ApplyInverseFlops() const{ return(ApplyInverseFlops_);}
493 
494 private:
495 
496  // @}
497  // @{ Private methods
498 
500  Ifpack_Hypre(const Ifpack_Hypre& RHS) : Time_(RHS.Comm()){}
501 
503  Ifpack_Hypre& operator=(const Ifpack_Hypre& RHS){ return(*this);}
504 
506  void Destroy();
507 
509  MPI_Comm GetMpiComm() const
510  { return (dynamic_cast<const Epetra_MpiComm*>(&A_->Comm()))->GetMpiComm();}
511 
513 
523  int Solve(bool Trans, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const;
524 
525 
527  int NumGlobalRows() const {return(A_->NumGlobalRows());};
528 
530  int NumGlobalCols() const {return(A_->NumGlobalCols());};
531 
533  int NumMyRows() const {return(A_->NumMyRows());};
534 
536  int NumMyCols() const {return(A_->NumMyCols());};
537 
539  int SetSolverType(Hypre_Solver solver);
540 
542  int SetPrecondType(Hypre_Solver precond);
543 
545  int CreateSolver();
546 
548  int CreatePrecond();
549 
551  int AddFunToList(Teuchos::RCP<FunctionParameter> NewFun);
552 
554  int Hypre_BoomerAMGCreate(MPI_Comm comm, HYPRE_Solver *solver)
555  { return HYPRE_BoomerAMGCreate(solver);}
556 
558  int Hypre_ParaSailsCreate(MPI_Comm comm, HYPRE_Solver *solver)
559  { return HYPRE_ParaSailsCreate(comm, solver);}
560 
562  int Hypre_EuclidCreate(MPI_Comm comm, HYPRE_Solver *solver)
563  { return HYPRE_EuclidCreate(comm, solver);}
564 
566  int Hypre_AMSCreate(MPI_Comm comm, HYPRE_Solver *solver)
567  { return HYPRE_AMSCreate(solver);}
568 
570  int Hypre_ParCSRHybridCreate(MPI_Comm comm, HYPRE_Solver *solver)
571  { return HYPRE_ParCSRHybridCreate(solver);}
572 
574  int Hypre_ParCSRPCGCreate(MPI_Comm comm, HYPRE_Solver *solver)
575  { return HYPRE_ParCSRPCGCreate(comm, solver);}
576 
578  int Hypre_ParCSRGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
579  { return HYPRE_ParCSRGMRESCreate(comm, solver);}
580 
582  int Hypre_ParCSRFlexGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
583  { return HYPRE_ParCSRFlexGMRESCreate(comm, solver);}
584 
586  int Hypre_ParCSRLGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
587  { return HYPRE_ParCSRLGMRESCreate(comm, solver);}
588 
590  int Hypre_ParCSRBiCGSTABCreate(MPI_Comm comm, HYPRE_Solver *solver)
591  { return HYPRE_ParCSRBiCGSTABCreate(comm, solver);}
592 
593  // @}
594  // @{ Internal data
595 
597  Teuchos::RefCountPtr<Epetra_RowMatrix> A_;
601  bool UseTranspose_;
603  double Condest_;
605  bool IsInitialized_;
607  bool IsComputed_;
609  char Label_[160];
611  int NumInitialize_;
613  int NumCompute_;
615  mutable int NumApplyInverse_;
617  double InitializeTime_;
619  double ComputeTime_;
621  mutable double ApplyInverseTime_;
623  double ComputeFlops_;
625  mutable double ApplyInverseFlops_;
627  mutable Epetra_Time Time_;
628 
630  mutable HYPRE_IJMatrix HypreA_;
632  mutable HYPRE_ParCSRMatrix ParMatrix_;
634  mutable HYPRE_IJVector XHypre_;
636  mutable HYPRE_IJVector YHypre_;
637  mutable HYPRE_ParVector ParX_;
638  mutable HYPRE_ParVector ParY_;
639  mutable hypre_ParVector *XVec_;
640  mutable hypre_ParVector *YVec_;
641  mutable hypre_Vector *XLocal_;
642  mutable hypre_Vector *YLocal_;
644  mutable HYPRE_Solver Solver_;
646  mutable HYPRE_Solver Preconditioner_;
647  // The following are pointers to functions to use the solver and preconditioner.
648  int (Ifpack_Hypre::*SolverCreatePtr_)(MPI_Comm, HYPRE_Solver*);
649  int (*SolverDestroyPtr_)(HYPRE_Solver);
650  int (*SolverSetupPtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
651  int (*SolverSolvePtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
652  int (*SolverPrecondPtr_)(HYPRE_Solver, HYPRE_PtrToParSolverFcn, HYPRE_PtrToParSolverFcn, HYPRE_Solver);
653  int (Ifpack_Hypre::*PrecondCreatePtr_)(MPI_Comm, HYPRE_Solver*);
654  int (*PrecondDestroyPtr_)(HYPRE_Solver);
655  int (*PrecondSetupPtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
656  int (*PrecondSolvePtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
657 
658  bool *IsSolverSetup_;
659  bool *IsPrecondSetup_;
661  Hypre_Chooser SolveOrPrec_;
663  Teuchos::RefCountPtr<Epetra_Map> MySimpleMap_;
665  int NumFunsToCall_;
667  Hypre_Solver SolverType_;
669  Hypre_Solver PrecondType_;
671  bool UsePreconditioner_;
673  std::vector<Teuchos::RCP<FunctionParameter> > FunsToCall_;
675  bool NiceRowMap_;
676 };
677 
678 #endif // HAVE_HYPRE
679 #endif /* IFPACK_HYPRE_H */
virtual int NumInitialize() const =0
Returns the number of calls to Initialize().
virtual int SetUseTranspose(bool UseTranspose)=0
virtual double ComputeTime() const =0
Returns the time spent in Compute().
virtual double ComputeFlops() const =0
Returns the number of flops in the computation phase.
virtual double ApplyInverseTime() const =0
Returns the time spent in ApplyInverse().
virtual double ApplyInverseFlops() const =0
Returns the number of flops in the application of the preconditioner.
virtual const Epetra_RowMatrix & Matrix() const =0
Returns a pointer to the matrix to be preconditioned.
virtual bool IsInitialized() const =0
Returns true if the preconditioner has been successfully initialized, false otherwise.
virtual std::ostream & Print(std::ostream &os) const =0
Prints basic information on iostream. This function is used by operator<<.
virtual const Epetra_Map & OperatorDomainMap() const=0
virtual const char * Label() const=0
virtual int Initialize()=0
Computes all it is necessary to initialize the preconditioner.
static bool Solver
Definition: performance.cpp:70
virtual double InitializeTime() const =0
Returns the time spent in Initialize().
Ifpack_CondestType
Ifpack_CondestType: enum to define the type of condition number estimate.
virtual int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const=0
virtual const Epetra_Map & OperatorRangeMap() const=0
virtual const Epetra_Comm & Comm() const=0
virtual int SetParameters(Teuchos::ParameterList &List)=0
Sets all parameters for the preconditioner.
virtual double Condest() const =0
Returns the computed condition number estimate, or -1.0 if not computed.
virtual bool UseTranspose() const=0
Ifpack_ScalingType enumerable type.
Ifpack_Preconditioner: basic class for preconditioning in Ifpack.
virtual int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const =0
Applies the preconditioner to vector X, returns the result in Y.
virtual double InitializeFlops() const =0
Returns the number of flops in the initialization phase.
void BiCGSTAB(Epetra_CrsMatrix &A, Epetra_Vector &x, Epetra_Vector &b, Ifpack_CrsRiluk *M, int Maxiter, double Tolerance, double *residual, bool verbose)
cheap estimate
virtual bool HasNormInf() const=0
virtual int NumCompute() const =0
Returns the number of calls to Compute().
virtual double NormInf() const=0
virtual bool IsComputed() const =0
Returns true if the preconditioner has been successfully computed, false otherwise.
virtual int Compute()=0
Computes all it is necessary to apply the preconditioner.
int Solve(int, TYPE *, TYPE *, TYPE *)
virtual int NumApplyInverse() const =0
Returns the number of calls to ApplyInverse().
#define RHS(a)
Definition: MatGenFD.c:60