Ifpack2 Templated Preconditioning Package  Version 1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Ifpack2_Hypre_decl.hpp
1 /*@HEADER
2 // ***********************************************************************
3 //
4 // Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
5 // Copyright (2009) 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 IFPACK2_HYPRE_DECL_HPP
44 #define IFPACK2_HYPRE_DECL_HPP
45 
46 #include "Ifpack2_ConfigDefs.hpp"
47 #if defined(HAVE_IFPACK2_HYPRE) && defined(HAVE_IFPACK2_MPI)
48 
51 #include "Tpetra_MultiVector.hpp"
52 #include "Tpetra_Vector.hpp"
53 #include "Tpetra_CrsGraph.hpp"
54 #include "Tpetra_CrsMatrix.hpp"
55 #include "Tpetra_Map.hpp"
56 #include "Tpetra_CrsMatrix.hpp"
57 
58 #include "Teuchos_RefCountPtr.hpp"
59 #include "Teuchos_ArrayRCP.hpp"
60 #include "Teuchos_Exceptions.hpp"
61 
62 #include "Ifpack2_Hypre_FunctionParameters.hpp"
63 
64 #include <map>
65 
66 // Hypre forward declarations (to avoid downstream header pollution)
67 struct hypre_IJMatrix_struct;
68 typedef struct hypre_IJMatrix_struct *HYPRE_IJMatrix;
69 struct hypre_IJVector_struct;
70 typedef struct hypre_IJVector_struct *HYPRE_IJVector;
71 struct hypre_ParCSRMatrix_struct;
72 typedef struct hypre_ParCSRMatrix_struct* HYPRE_ParCSRMatrix;
73 struct hypre_ParVector_struct;
74 typedef struct hypre_ParVector_struct * HYPRE_ParVector;
75 struct hypre_Solver_struct;
76 typedef struct hypre_Solver_struct *HYPRE_Solver;
77 struct hypre_ParVector_struct;
78 typedef struct hypre_ParVector_struct hypre_ParVector;
79 //struct hypre_Vector;
80 
81 namespace Ifpack2 {
82 
83 
84 #ifndef HYPRE_ENUMS
85 #define HYPRE_ENUMS
86  enum Hypre_Solver{
88  BoomerAMG,
89  ParaSails,
90  Euclid,
91  AMS,
92  Hybrid,
93  PCG,
94  GMRES,
95  FlexGMRES,
96  LGMRES,
97  BiCGSTAB
98  };
99 
101  enum Hypre_Chooser{
102  Hypre_Is_Solver,
103  Hypre_Is_Preconditioner
104  };
105 #endif //HYPRE_ENUMS
106 
107 
108 class NotImplemented : public Teuchos::ExceptionBase {
109 public:
110  NotImplemented(const std::string& what_arg) : Teuchos::ExceptionBase(what_arg) {}
111 };
112 
114 
119 template<class MatrixType>
120 class Hypre:
121  virtual public Ifpack2::Preconditioner<typename MatrixType::scalar_type,
122  typename MatrixType::local_ordinal_type,
123  typename MatrixType::global_ordinal_type,
124  typename MatrixType::node_type>,
125  virtual public Ifpack2::Details::CanChangeMatrix<Tpetra::RowMatrix<typename MatrixType::scalar_type,
126  typename MatrixType::local_ordinal_type,
127  typename MatrixType::global_ordinal_type,
128  typename MatrixType::node_type> >
129 {
130 public:
131 
133  typedef typename MatrixType::scalar_type scalar_type;
134 
136  typedef typename MatrixType::local_ordinal_type local_ordinal_type;
137 
139  typedef typename MatrixType::global_ordinal_type global_ordinal_type;
140 
142  typedef typename MatrixType::node_type::device_type device_type;
143 
145  typedef typename MatrixType::node_type node_type;
146 
148  typedef typename Teuchos::ScalarTraits<scalar_type>::magnitudeType magnitude_type;
149 
154  typedef Tpetra::RowMatrix<scalar_type, local_ordinal_type,
155  global_ordinal_type, node_type> row_matrix_type;
156 
157  static_assert (std::is_same<MatrixType, row_matrix_type>::value,
158  "Ifpack2::Hypre: MatrixType must be a Tpetra::RowMatrix "
159  "specialization. Don't use Tpetra::CrsMatrix here.");
160 
161 
163  typedef Tpetra::CrsMatrix<scalar_type, local_ordinal_type,
164  global_ordinal_type, node_type> crs_matrix_type;
165 
167  typedef Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> map_type;
168 
174  typedef Tpetra::Vector<scalar_type, local_ordinal_type,
175  global_ordinal_type, node_type> vector_type;
176 
178  typedef Tpetra::MultiVector<scalar_type, local_ordinal_type,
179  global_ordinal_type, node_type> multivector_type;
180 
181 
182  explicit Hypre(const Teuchos::RCP<const row_matrix_type>& A) { throw NotImplemented("Ifpack2::Hypre only works when instantiated on <HYPRE_REAL, LocalOrdinal, HYPRE_Int, Node>"); }
183 
184  // @}
185  // @{ Construction methods
187  void initialize() {}
188 
190  bool isInitialized() const{ return false;}
191 
193 
195  void compute() {}
196 
198  bool isComputed() const{ return false;}
199 
200  void setParameters(const Teuchos::ParameterList& parameterlist) {}
201 
202 
204 
205 
228  virtual void
229  setMatrix (const Teuchos::RCP<const row_matrix_type>& A) {}
231 
260  void
261  apply (const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& X,
262  Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& Y,
264  scalar_type alpha = Teuchos::ScalarTraits<scalar_type>::one(),
265  scalar_type beta = Teuchos::ScalarTraits<scalar_type>::zero()) const {}
266 
268  Teuchos::RCP<const map_type> getDomainMap() const { return Teuchos::null; }
269 
271  Teuchos::RCP<const map_type> getRangeMap() const { return Teuchos::null; }
272 
274  bool hasTransposeApply() const { return false; }
275 
296  void
297  applyMat (const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& X,
298  Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& Y,
299  Teuchos::ETransp mode = Teuchos::NO_TRANS) const {}
300 
301  Teuchos::RCP<const row_matrix_type> getMatrix() const { return Teuchos::null; }
302 
304 
306  int getNumInitialize() const { return 0; }
307 
309  int getNumCompute() const { return 0; }
310 
312  int getNumApply() const { return 0; }
313 
315  double getInitializeTime() const { return 0.0; }
316 
318  double getComputeTime() const { return 0.0; }
319 
321  double getApplyTime() const { return 0.0; }
322 
323 
324 };
325 
326 template<class LocalOrdinal, class Node>
327 class Hypre<Tpetra::RowMatrix<HYPRE_Real, LocalOrdinal, HYPRE_Int, Node> >:
328  virtual public Ifpack2::Preconditioner<HYPRE_Real,
329  LocalOrdinal,
330  HYPRE_Int,
331  Node>,
332  virtual public Ifpack2::Details::CanChangeMatrix<Tpetra::RowMatrix<HYPRE_Real,
333  LocalOrdinal,
334  HYPRE_Int,
335  Node> >
336 {
337 public:
339 
340 
342  typedef Tpetra::RowMatrix<HYPRE_Real, LocalOrdinal, HYPRE_Int, Node> MatrixType;
343 
345  typedef typename MatrixType::scalar_type scalar_type;
346 
348  typedef typename MatrixType::local_ordinal_type local_ordinal_type;
349 
351  typedef typename MatrixType::global_ordinal_type global_ordinal_type;
352 
354  typedef typename MatrixType::node_type::device_type device_type;
355 
357  typedef typename MatrixType::node_type node_type;
358 
360  typedef typename Teuchos::ScalarTraits<scalar_type>::magnitudeType magnitude_type;
361 
366  typedef Tpetra::RowMatrix<scalar_type, local_ordinal_type,
367  global_ordinal_type, node_type> row_matrix_type;
368 
369  static_assert (std::is_same<MatrixType, row_matrix_type>::value,
370  "Ifpack2::Hypre: MatrixType must be a Tpetra::RowMatrix "
371  "specialization. Don't use Tpetra::CrsMatrix here.");
372 
373 
375  typedef Tpetra::CrsMatrix<scalar_type, local_ordinal_type,
376  global_ordinal_type, node_type> crs_matrix_type;
377 
379  typedef Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> map_type;
380 
386  typedef Tpetra::Vector<scalar_type, local_ordinal_type,
387  global_ordinal_type, node_type> vector_type;
388 
390  typedef Tpetra::MultiVector<scalar_type, local_ordinal_type,
391  global_ordinal_type, node_type> multivector_type;
392 
393  // Hypre Specs
394  // This will need to be either int or long long depending on how Hypre was built
395  // typedef global_ordinal_type global_ordinal_type;
396 
397  typedef global_ordinal_type (*HYPRE_PtrToParSolverFcn)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
398 
400  // \name Constructors and destructors
402 
424  explicit Hypre(const Teuchos::RCP<const row_matrix_type>& A);
425 
427  ~Hypre();
428 
429  // @}
430  // @{ Construction methods
432  void initialize();
433 
435  bool isInitialized() const{ return(IsInitialized_);}
436 
438 
440  void compute();
441 
443  bool isComputed() const{ return(IsComputed_);}
444 
446  /* This method is only available if the Teuchos package is enabled.
447  This method recognizes six parameter names: Solver,
448  Preconditioner, SolveOrPrecondition, SetPreconditioner, NumFunctions and Functions. These names are
449  case sensitive. Solver requires an enumerated parameter of type Hypre_Solver. Preconditioner is similar
450  except requires the type be a preconditioner. The options are listed below:
451  Solvers Preconditioners
452  BoomerAMG BoomerAMG
453  AMS ParaSails
454  Hybrid AMS
455  PCG (Default) Euclid (Default)
456  GMRES
457  FlexGMRES
458  LGMRES
459  BiCGSTAB
460  SolveOrPrecondition takes enumerated type Hypre_Chooser, Solver will solve the system, Preconditioner will apply the preconditioner.
461  SetPreconditioner takes a boolean, true means the solver will use the preconditioner.
462  NumFunctions takes an int that describes how many parameters will be passed into Functions. (This needs to be correct.)
463  Functions takes an array of Ref Counted Pointers to an object called FunctionParameter. This class is implemented in Ifpack_Hypre.h.
464  The object takes whether it is Solver or Preconditioner that we are setting a parameter for.
465  The function in Hypre that sets the parameter, and the parameters for that function. An example is below:
466 
467  RCP<FunctionParameter> functs[2];
468  functs[0] = rcp(new FunctionParameter(Solver, &HYPRE_PCGSetMaxIter, 1000)); // max iterations
469  functs[1] = rcp(new FunctionParameter(Solver, &HYPRE_PCGSetTol, 1e-7)); // conv. tolerance
470  list.set("NumFunctions", 2);
471  list.set<RCP<FunctionParameter>*>("Functions", functs);
472  NOTE: SetParameters() must be called to use ApplyInverse(), the solvers will not be created otherwise. An empty list is acceptable to use defaults.
473  */
474  void setParameters(const Teuchos::ParameterList& parameterlist);
475 
477 
485  int SetParameter(Hypre_Chooser chooser, HYPRE_Int (*pt2Func)(HYPRE_Solver, HYPRE_Int), HYPRE_Int parameter);
486 
488 
496  int SetParameter(Hypre_Chooser chooser, HYPRE_Int (*pt2Func)(HYPRE_Solver, HYPRE_Real), HYPRE_Real parameter);
497 
499 
508  int SetParameter(Hypre_Chooser chooser, HYPRE_Int (*pt2Func)(HYPRE_Solver, HYPRE_Real, HYPRE_Int), HYPRE_Real parameter1, HYPRE_Int parameter2);
509 
511 
520  int SetParameter(Hypre_Chooser chooser, HYPRE_Int (*pt2Func)(HYPRE_Solver, HYPRE_Int, HYPRE_Real), HYPRE_Int parameter1, HYPRE_Real parameter2);
521 
523 
532  int SetParameter(Hypre_Chooser chooser, HYPRE_Int (*pt2Func)(HYPRE_Solver, HYPRE_Int, HYPRE_Int), HYPRE_Int parameter1, HYPRE_Int parameter2);
533 
535 
543  int SetParameter(Hypre_Chooser chooser, HYPRE_Int (*pt2Func)(HYPRE_Solver, HYPRE_Real*), HYPRE_Real* parameter);
544 
546 
554  int SetParameter(Hypre_Chooser chooser, HYPRE_Int (*pt2Func)(HYPRE_Solver, HYPRE_Int*), HYPRE_Int* parameter);
555 
557 
566  int SetParameter(Hypre_Chooser chooser, HYPRE_Int (*pt2Func)(HYPRE_Solver, HYPRE_Int**), HYPRE_Int** parameter);
567 
569 
578  int SetParameter(Hypre_Chooser chooser, Hypre_Solver Solver);
579 
581 
589  int SetParameter(bool UsePreconditioner){ UsePreconditioner_ = UsePreconditioner; return 0;}
590 
592 
598  int SetParameter(Hypre_Chooser chooser) { SolveOrPrec_ = chooser; return 0;}
599 
601  int SetCoordinates(Teuchos::RCP<multivector_type> coords);
602 
604  int SetDiscreteGradient(Teuchos::RCP<const crs_matrix_type> G);
605 
607  int CallFunctions() const;
608 
610 
612 
635  virtual void
636  setMatrix (const Teuchos::RCP<const row_matrix_type>& A);
638 
667  void
668  apply (const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& X,
669  Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& Y,
671  scalar_type alpha = Teuchos::ScalarTraits<scalar_type>::one(),
672  scalar_type beta = Teuchos::ScalarTraits<scalar_type>::zero()) const;
673 
675  Teuchos::RCP<const map_type> getDomainMap() const;
676 
678  Teuchos::RCP<const map_type> getRangeMap() const;
679 
681  bool hasTransposeApply() const;
682 
703  void
704  applyMat (const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& X,
705  Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& Y,
706  Teuchos::ETransp mode = Teuchos::NO_TRANS) const;
707 
709 
711 
713  Teuchos::RCP<const Teuchos::Comm<int> > getComm() const;
714 
716  Teuchos::RCP<const row_matrix_type> getMatrix() const;
717 
723  getCrsMatrix() const;
724 
726  int getNumInitialize() const;
727 
729  int getNumCompute() const;
730 
732  int getNumApply() const;
733 
735  double getInitializeTime() const;
736 
738  double getComputeTime() const;
739 
741  double getApplyTime() const;
742 
744 
746 
748  std::string description() const;
749 
752 
754 
755 private:
756  // @{ Private methods
757 
760 
762  typedef Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type> MV;
763 
765  Hypre(const Hypre<MatrixType>&);
766 
768  Hypre<MatrixType>& operator= (const Hypre<MatrixType>&);
769 
771  int SetSolverType(Hypre_Solver solver);
772 
774  int SetPrecondType(Hypre_Solver precond);
775 
777  int CreateSolver();
778 
780  int CreatePrecond();
781 
783  int CopyTpetraToHypre();
784 
786  int AddFunToList(Teuchos::RCP<FunctionParameter> NewFun);
787 
789  HYPRE_Int Hypre_BoomerAMGCreate(MPI_Comm comm, HYPRE_Solver *solver);
790 
792  HYPRE_Int Hypre_ParaSailsCreate(MPI_Comm comm, HYPRE_Solver *solver);
793 
795  HYPRE_Int Hypre_EuclidCreate(MPI_Comm comm, HYPRE_Solver *solver);
796 
798  HYPRE_Int Hypre_AMSCreate(MPI_Comm comm, HYPRE_Solver *solver);
799 
801  HYPRE_Int Hypre_ParCSRHybridCreate(MPI_Comm comm, HYPRE_Solver *solver);
802 
804  HYPRE_Int Hypre_ParCSRPCGCreate(MPI_Comm comm, HYPRE_Solver *solver);
805 
807  HYPRE_Int Hypre_ParCSRGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver);
808 
810  HYPRE_Int Hypre_ParCSRFlexGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver);
811 
813  HYPRE_Int Hypre_ParCSRLGMRESCreate(MPI_Comm comm, HYPRE_Solver *solver);
814 
816  HYPRE_Int Hypre_ParCSRBiCGSTABCreate(MPI_Comm comm, HYPRE_Solver *solver);
817 
820  MakeContiguousColumnMap(Teuchos::RCP<const crs_matrix_type> &Matrix) const;
821 
823  void Destroy();
824 
825  // @}
826  // @{ Internal data
831 
833  bool IsInitialized_;
835  bool IsComputed_;
837  int NumInitialize_;
839  int NumCompute_;
844  mutable int NumApply_;
846  double InitializeTime_;
848  double ComputeTime_;
853  mutable double ApplyTime_;
855  double ComputeFlops_;
860  mutable double ApplyFlops_;
861 
862 
864  mutable HYPRE_IJMatrix HypreA_;
866  mutable HYPRE_ParCSRMatrix ParMatrix_;
867 
871  mutable HYPRE_IJMatrix HypreG_;
873  mutable HYPRE_ParCSRMatrix ParMatrixG_;
874 
876  mutable HYPRE_IJVector XHypre_;
878  mutable HYPRE_IJVector YHypre_;
879  mutable HYPRE_ParVector ParX_;
880  mutable HYPRE_ParVector ParY_;
881  mutable Teuchos::RCP<hypre_ParVector> XVec_;
882  mutable Teuchos::RCP<hypre_ParVector> YVec_;
883 
885  mutable HYPRE_IJVector xHypre_;
886  mutable HYPRE_IJVector yHypre_;
887  mutable HYPRE_IJVector zHypre_;
888  mutable HYPRE_ParVector xPar_;
889  mutable HYPRE_ParVector yPar_;
890  mutable HYPRE_ParVector zPar_;
891 
893  mutable HYPRE_Solver Solver_;
895  mutable HYPRE_Solver Preconditioner_;
896  // The following are pointers to functions to use the solver and preconditioner.
897  HYPRE_Int (Hypre::*SolverCreatePtr_)(MPI_Comm, HYPRE_Solver*);
898  HYPRE_Int (*SolverDestroyPtr_)(HYPRE_Solver);
899  HYPRE_Int (*SolverSetupPtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
900  HYPRE_Int (*SolverSolvePtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
901  HYPRE_Int (*SolverPrecondPtr_)(HYPRE_Solver, HYPRE_PtrToParSolverFcn, HYPRE_PtrToParSolverFcn, HYPRE_Solver);
902  HYPRE_Int (Hypre::*PrecondCreatePtr_)(MPI_Comm, HYPRE_Solver*);
903  HYPRE_Int (*PrecondDestroyPtr_)(HYPRE_Solver);
904  HYPRE_Int (*PrecondSetupPtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
905  HYPRE_Int (*PrecondSolvePtr_)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
906 
907  bool IsSolverCreated_;
908  bool IsPrecondCreated_;
910  Hypre_Chooser SolveOrPrec_;
912  Teuchos::RCP<const map_type> GloballyContiguousRowMap_;
913  Teuchos::RCP<const map_type> GloballyContiguousColMap_;
914  Teuchos::RCP<const map_type> GloballyContiguousNodeRowMap_;
915  Teuchos::RCP<const map_type> GloballyContiguousNodeColMap_;
917  int NumFunsToCall_;
919  Hypre_Solver SolverType_;
921  Hypre_Solver PrecondType_;
923  bool UsePreconditioner_;
925  std::vector<Teuchos::RCP<FunctionParameter> > FunsToCall_;
927  bool Dump_;
929  mutable Teuchos::ArrayRCP<scalar_type> VectorCache_;
930 
931 };
932 
933 
934 }//end Ifpack2 namespace
935 
936 #endif // HAVE_IFPACK2_HYPRE && HAVE_IFPACK2_MPI
937 #endif /* IFPACK2_HYPRE_DECL_HPP */
Mix-in interface for preconditioners that can change their matrix after construction.
Definition: Ifpack2_Details_CanChangeMatrix.hpp:93
Interface for all Ifpack2 preconditioners.
Definition: Ifpack2_Preconditioner.hpp:107
Declaration of interface for preconditioners that can change their matrix after construction.
static const EVerbosityLevel verbLevel_default
Uses AztecOO&#39;s GMRES.
Definition: Ifpack2_CondestType.hpp:53