IFPACK  Development
Ifpack_Hypre.h
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 *GloballyContiguousRowMap_;}
437 
439  const Epetra_Map& OperatorRangeMap() const{ return *GloballyContiguousRowMap_;}
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 CopyEpetraToHypre();
552 
554  int AddFunToList(Teuchos::RCP<FunctionParameter> NewFun);
555 
557  int Hypre_BoomerAMGCreate(MPI_Comm /*comm*/, HYPRE_Solver *solver)
558  { return HYPRE_BoomerAMGCreate(solver);}
559 
561  int Hypre_ParaSailsCreate(MPI_Comm comm, HYPRE_Solver *solver)
562  { return HYPRE_ParaSailsCreate(comm, solver);}
563 
565  int Hypre_EuclidCreate(MPI_Comm comm, HYPRE_Solver *solver)
566  { return HYPRE_EuclidCreate(comm, solver);}
567 
569  int Hypre_AMSCreate(MPI_Comm /*comm*/, HYPRE_Solver *solver)
570  { return HYPRE_AMSCreate(solver);}
571 
573  int Hypre_ParCSRHybridCreate(MPI_Comm /*comm*/, HYPRE_Solver *solver)
574  { return HYPRE_ParCSRHybridCreate(solver);}
575 
577  int Hypre_ParCSRPCGCreate(MPI_Comm comm, HYPRE_Solver *solver)
578  { return HYPRE_ParCSRPCGCreate(comm, solver);}
579 
581  int Hypre_ParCSRGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
582  { return HYPRE_ParCSRGMRESCreate(comm, solver);}
583 
585  int Hypre_ParCSRFlexGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
586  { return HYPRE_ParCSRFlexGMRESCreate(comm, solver);}
587 
589  int Hypre_ParCSRLGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver)
590  { return HYPRE_ParCSRLGMRESCreate(comm, solver);}
591 
593  int Hypre_ParCSRBiCGSTABCreate(MPI_Comm comm, HYPRE_Solver *solver)
594  { return HYPRE_ParCSRBiCGSTABCreate(comm, solver);}
595 
596  // @}
597  // @{ Internal data
598 
600  Teuchos::RefCountPtr<Epetra_RowMatrix> A_;
602  Teuchos::ParameterList List_;
604  bool UseTranspose_;
606  double Condest_;
608  bool IsInitialized_;
610  bool IsComputed_;
612  char Label_[160];
614  int NumInitialize_;
616  int NumCompute_;
618  mutable int NumApplyInverse_;
620  double InitializeTime_;
622  double ComputeTime_;
624  mutable double ApplyInverseTime_;
626  double ComputeFlops_;
628  mutable double ApplyInverseFlops_;
630  mutable Epetra_Time Time_;
631 
633  mutable HYPRE_IJMatrix HypreA_;
635  mutable HYPRE_ParCSRMatrix ParMatrix_;
637  mutable HYPRE_IJVector XHypre_;
639  mutable HYPRE_IJVector YHypre_;
640  mutable HYPRE_ParVector ParX_;
641  mutable HYPRE_ParVector ParY_;
642  mutable hypre_ParVector *XVec_;
643  mutable hypre_ParVector *YVec_;
644  mutable hypre_Vector *XLocal_;
645  mutable hypre_Vector *YLocal_;
647  mutable HYPRE_Solver Solver_;
649  mutable HYPRE_Solver Preconditioner_;
650  // The following are pointers to functions to use the solver and preconditioner.
651  int (Ifpack_Hypre::*SolverCreatePtr_)(MPI_Comm, HYPRE_Solver*);
652  int (*SolverDestroyPtr_)(HYPRE_Solver);
653  int (*SolverSetupPtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
654  int (*SolverSolvePtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
655  int (*SolverPrecondPtr_)(HYPRE_Solver, HYPRE_PtrToParSolverFcn, HYPRE_PtrToParSolverFcn, HYPRE_Solver);
656  int (Ifpack_Hypre::*PrecondCreatePtr_)(MPI_Comm, HYPRE_Solver*);
657  int (*PrecondDestroyPtr_)(HYPRE_Solver);
658  int (*PrecondSetupPtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
659  int (*PrecondSolvePtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
660 
661  bool *IsSolverSetup_;
662  bool *IsPrecondSetup_;
664  Hypre_Chooser SolveOrPrec_;
666  Teuchos::RCP<const Epetra_Map> GloballyContiguousRowMap_;
667  Teuchos::RCP<const Epetra_Map> GloballyContiguousColMap_;
669  int NumFunsToCall_;
671  Hypre_Solver SolverType_;
673  Hypre_Solver PrecondType_;
675  bool UsePreconditioner_;
677  std::vector<Teuchos::RCP<FunctionParameter> > FunsToCall_;
678 };
679 
680 #endif // HAVE_HYPRE
681 #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.
virtual double InitializeTime() const =0
Returns the time spent in Initialize().
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.
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.
virtual int NumApplyInverse() const =0
Returns the number of calls to ApplyInverse().