MFEM v2.0
|
00001 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at 00002 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights 00003 // reserved. See file COPYRIGHT for details. 00004 // 00005 // This file is part of the MFEM library. For more information and source code 00006 // availability see http://mfem.googlecode.com. 00007 // 00008 // MFEM is free software; you can redistribute it and/or modify it under the 00009 // terms of the GNU Lesser General Public License (as published by the Free 00010 // Software Foundation) version 2.1 dated February 1999. 00011 00012 #ifndef MFEM_HYPRE 00013 #define MFEM_HYPRE 00014 00015 // Enable internal hypre timing routines 00016 #define HYPRE_TIMING 00017 00018 // hypre header files 00019 #include "seq_mv.h" 00020 #include "_hypre_parcsr_mv.h" 00021 #include "_hypre_parcsr_ls.h" 00022 00024 class HypreParVector : public Vector 00025 { 00026 private: 00027 int own_ParVector; 00028 00030 hypre_ParVector *x; 00031 00032 friend class HypreParMatrix; 00033 00034 public: 00037 HypreParVector(int glob_size, int *col); 00040 HypreParVector(int glob_size, double *_data, int *col); 00042 HypreParVector(const HypreParVector &y); 00044 HypreParVector(HYPRE_ParVector y); 00045 00047 operator hypre_ParVector*() const; 00049 operator HYPRE_ParVector() const; 00051 hypre_ParVector *StealParVector() { own_ParVector = 0; return x; } 00052 00054 Vector *GlobalVector(); 00055 00057 HypreParVector& operator= (double d); 00059 HypreParVector& operator= (const HypreParVector &y); 00060 00065 void SetData(double *_data); 00066 00068 int Randomize(int seed); 00069 00071 void Print(const char *fname); 00072 00074 ~HypreParVector(); 00075 }; 00076 00078 double InnerProduct(HypreParVector &x, HypreParVector &y); 00079 double InnerProduct(HypreParVector *x, HypreParVector *y); 00080 00081 00083 class HypreParMatrix : public Operator 00084 { 00085 private: 00087 hypre_ParCSRMatrix *A; 00088 00090 hypre_ParCSRCommPkg *CommPkg; 00091 00093 mutable HypreParVector *X, *Y; 00094 00095 public: 00097 HypreParMatrix(hypre_ParCSRMatrix *a) : A(a) 00098 { X = Y = 0; CommPkg = 0; } 00100 HypreParMatrix(int size, int *row, SparseMatrix *diag); 00103 HypreParMatrix(int M, int N, int *row, int *col, SparseMatrix *diag); 00105 HypreParMatrix(int M, int N, int *row, int *col, SparseMatrix *diag, 00106 SparseMatrix *offd, int *cmap); 00107 00109 HypreParMatrix(int *row, int *col, SparseMatrix *a); 00110 00112 HypreParMatrix(int M, int N, int *row, int *col, Table *diag); 00114 HypreParMatrix(MPI_Comm comm, int id, int np, int *row, int *col, 00115 int *i_diag, int *j_diag, int *i_offd, int *j_offd, 00116 int *cmap, int cmap_size); 00117 00122 HypreParMatrix(MPI_Comm comm, int nrows, int glob_nrows, int glob_ncols, 00123 int *I, int *J, double *data, int *rows, int *cols); 00124 00125 // hypre's communication package object 00126 void SetCommPkg(hypre_ParCSRCommPkg *comm_pkg); 00127 void CheckCommPkg(); 00128 void DestroyCommPkg(); 00129 00131 operator hypre_ParCSRMatrix*(); 00133 operator HYPRE_ParCSRMatrix(); 00135 hypre_ParCSRMatrix* StealData(); 00136 00138 inline int NNZ() { return A->num_nonzeros; } 00140 inline int * RowPart() { return A->row_starts; } 00142 inline int * ColPart() { return A->col_starts; } 00144 inline int M() { return A -> global_num_rows; } 00146 inline int N() { return A -> global_num_cols; } 00147 00149 void GetDiag(Vector &diag); 00151 HypreParMatrix * Transpose(); 00152 00154 int GetNumRows() const 00155 { return hypre_CSRMatrixNumRows(hypre_ParCSRMatrixDiag(A)); } 00156 00157 int GetGlobalNumRows() const { return hypre_ParCSRMatrixGlobalNumRows(A); } 00158 00159 int GetGlobalNumCols() const { return hypre_ParCSRMatrixGlobalNumCols(A); } 00160 00161 int *GetRowStarts() const { return hypre_ParCSRMatrixRowStarts(A); } 00162 00163 int *GetColStarts() const { return hypre_ParCSRMatrixColStarts(A); } 00164 00166 int Mult(HypreParVector &x, HypreParVector &y, 00167 double alpha = 1.0, double beta = 0.0); 00169 int Mult(HYPRE_ParVector x, HYPRE_ParVector y, 00170 double alpha = 1.0, double beta = 0.0); 00172 int MultTranspose(HypreParVector &x, HypreParVector &y, 00173 double alpha = 1.0, double beta = 0.0); 00174 00175 virtual void Mult(const Vector &x, Vector &y) const; 00176 virtual void MultTranspose(const Vector &x, Vector &y) const; 00177 00179 void Print(const char *fname, int offi = 0, int offj = 0); 00181 void Read(const char *fname); 00182 00184 virtual ~HypreParMatrix(); 00185 }; 00186 00188 HypreParMatrix * ParMult(HypreParMatrix *A, HypreParMatrix *B); 00189 00191 HypreParMatrix * RAP(HypreParMatrix *A, HypreParMatrix *P); 00192 00196 void EliminateBC(HypreParMatrix &A, HypreParMatrix &Ae, 00197 Array<int> &ess_dof_list, 00198 HypreParVector &x, HypreParVector &b); 00199 00201 class HypreSolver : public Operator 00202 { 00203 protected: 00205 HypreParMatrix *A; 00206 00208 mutable HypreParVector *B, *X; 00209 00211 mutable int setup_called; 00212 00213 public: 00214 HypreSolver(); 00215 00216 HypreSolver(HypreParMatrix *_A); 00217 00219 virtual operator HYPRE_Solver() const = 0; 00220 00222 virtual HYPRE_PtrToParSolverFcn SetupFcn() const = 0; 00224 virtual HYPRE_PtrToParSolverFcn SolveFcn() const = 0; 00225 00227 virtual void Mult(const HypreParVector &b, HypreParVector &x) const; 00228 virtual void Mult(const Vector &b, Vector &x) const; 00229 00230 virtual ~HypreSolver(); 00231 }; 00232 00234 class HyprePCG : public HypreSolver 00235 { 00236 private: 00237 int print_level, use_zero_initial_iterate; 00238 HYPRE_Solver pcg_solver; 00239 00240 public: 00241 HyprePCG(HypreParMatrix &_A); 00242 00243 void SetTol(double tol); 00244 void SetMaxIter(int max_iter); 00245 void SetLogging(int logging); 00246 void SetPrintLevel(int print_lvl); 00247 00249 void SetPreconditioner(HypreSolver &precond); 00250 00254 void SetResidualConvergenceOptions(int res_frequency=-1, double rtol=0.0); 00255 00257 void SetZeroInintialIterate() { use_zero_initial_iterate = 1; } 00258 00259 void GetNumIterations(int &num_iterations) 00260 { HYPRE_ParCSRPCGGetNumIterations(pcg_solver, &num_iterations); } 00261 00263 virtual operator HYPRE_Solver() const { return pcg_solver; } 00264 00266 virtual HYPRE_PtrToParSolverFcn SetupFcn() const 00267 { return (HYPRE_PtrToParSolverFcn) HYPRE_ParCSRPCGSetup; } 00269 virtual HYPRE_PtrToParSolverFcn SolveFcn() const 00270 { return (HYPRE_PtrToParSolverFcn) HYPRE_ParCSRPCGSolve; } 00271 00273 virtual void Mult(const HypreParVector &b, HypreParVector &x) const; 00274 using HypreSolver::Mult; 00275 00276 virtual ~HyprePCG(); 00277 }; 00278 00280 class HypreGMRES : public HypreSolver 00281 { 00282 private: 00283 int print_level, use_zero_initial_iterate; 00284 HYPRE_Solver gmres_solver; 00285 00286 public: 00287 HypreGMRES(HypreParMatrix &_A); 00288 00289 void SetTol(double tol); 00290 void SetMaxIter(int max_iter); 00291 void SetKDim(int dim); 00292 void SetLogging(int logging); 00293 void SetPrintLevel(int print_lvl); 00294 00296 void SetPreconditioner(HypreSolver &precond); 00297 00299 void SetZeroInintialIterate() { use_zero_initial_iterate = 1; } 00300 00302 virtual operator HYPRE_Solver() const { return gmres_solver; } 00303 00305 virtual HYPRE_PtrToParSolverFcn SetupFcn() const 00306 { return (HYPRE_PtrToParSolverFcn) HYPRE_ParCSRGMRESSetup; } 00308 virtual HYPRE_PtrToParSolverFcn SolveFcn() const 00309 { return (HYPRE_PtrToParSolverFcn) HYPRE_ParCSRGMRESSolve; } 00310 00312 virtual void Mult (const HypreParVector &b, HypreParVector &x) const; 00313 using HypreSolver::Mult; 00314 00315 virtual ~HypreGMRES(); 00316 }; 00317 00319 class HypreIdentity : public HypreSolver 00320 { 00321 public: 00322 virtual operator HYPRE_Solver() const { return NULL; } 00323 00324 virtual HYPRE_PtrToParSolverFcn SetupFcn() const 00325 { return (HYPRE_PtrToParSolverFcn) hypre_ParKrylovIdentitySetup; } 00326 virtual HYPRE_PtrToParSolverFcn SolveFcn() const 00327 { return (HYPRE_PtrToParSolverFcn) hypre_ParKrylovIdentity; } 00328 00329 virtual ~HypreIdentity() { } 00330 }; 00331 00333 class HypreDiagScale : public HypreSolver 00334 { 00335 public: 00336 virtual operator HYPRE_Solver() const { return NULL; } 00337 00338 virtual HYPRE_PtrToParSolverFcn SetupFcn() const 00339 { return (HYPRE_PtrToParSolverFcn) HYPRE_ParCSRDiagScaleSetup; } 00340 virtual HYPRE_PtrToParSolverFcn SolveFcn() const 00341 { return (HYPRE_PtrToParSolverFcn) HYPRE_ParCSRDiagScale; } 00342 00343 HypreParMatrix* GetData() { return A; } 00344 virtual ~HypreDiagScale() { } 00345 }; 00346 00348 class HypreParaSails : public HypreSolver 00349 { 00350 private: 00351 HYPRE_Solver sai_precond; 00352 00353 public: 00354 HypreParaSails(HypreParMatrix &A); 00355 00356 void SetSymmetry(int sym); 00357 00359 virtual operator HYPRE_Solver() const { return sai_precond; } 00360 00361 virtual HYPRE_PtrToParSolverFcn SetupFcn() const 00362 { return (HYPRE_PtrToParSolverFcn) HYPRE_ParaSailsSetup; } 00363 virtual HYPRE_PtrToParSolverFcn SolveFcn() const 00364 { return (HYPRE_PtrToParSolverFcn) HYPRE_ParaSailsSolve; } 00365 00366 virtual ~HypreParaSails(); 00367 }; 00368 00370 class HypreBoomerAMG : public HypreSolver 00371 { 00372 private: 00373 HYPRE_Solver amg_precond; 00374 00375 public: 00376 HypreBoomerAMG(HypreParMatrix &A); 00377 00381 void SetSystemsOptions(int dim); 00382 00384 virtual operator HYPRE_Solver() const { return amg_precond; } 00385 00386 virtual HYPRE_PtrToParSolverFcn SetupFcn() const 00387 { return (HYPRE_PtrToParSolverFcn) HYPRE_BoomerAMGSetup; } 00388 virtual HYPRE_PtrToParSolverFcn SolveFcn() const 00389 { return (HYPRE_PtrToParSolverFcn) HYPRE_BoomerAMGSolve; } 00390 00391 virtual ~HypreBoomerAMG(); 00392 }; 00393 00394 class ParFiniteElementSpace; 00395 00397 HypreParMatrix* DiscreteGrad(ParFiniteElementSpace *edge_fespace, 00398 ParFiniteElementSpace *vert_fespace); 00400 HypreParMatrix* DiscreteCurl(ParFiniteElementSpace *face_fespace, 00401 ParFiniteElementSpace *edge_fespace); 00402 00404 class HypreAMS : public HypreSolver 00405 { 00406 private: 00407 HYPRE_Solver ams; 00408 00410 HypreParVector *x, *y, *z; 00412 HypreParMatrix *G; 00414 HypreParMatrix *Pi, *Pix, *Piy, *Piz; 00415 00416 public: 00417 HypreAMS(HypreParMatrix &A, ParFiniteElementSpace *edge_fespace); 00418 00420 virtual operator HYPRE_Solver() const { return ams; } 00421 00422 virtual HYPRE_PtrToParSolverFcn SetupFcn() const 00423 { return (HYPRE_PtrToParSolverFcn) HYPRE_AMSSetup; } 00424 virtual HYPRE_PtrToParSolverFcn SolveFcn() const 00425 { return (HYPRE_PtrToParSolverFcn) HYPRE_AMSSolve; } 00426 00427 virtual ~HypreAMS(); 00428 }; 00429 00431 class HypreADS : public HypreSolver 00432 { 00433 private: 00434 HYPRE_Solver ads; 00435 00437 HypreParVector *x, *y, *z; 00439 HypreParMatrix *G; 00441 HypreParMatrix *C; 00443 HypreParMatrix *ND_Pi, *ND_Pix, *ND_Piy, *ND_Piz; 00445 HypreParMatrix *RT_Pi, *RT_Pix, *RT_Piy, *RT_Piz; 00446 00447 public: 00448 HypreADS(HypreParMatrix &A, ParFiniteElementSpace *face_fespace); 00449 00451 virtual operator HYPRE_Solver() const { return ads; } 00452 00453 virtual HYPRE_PtrToParSolverFcn SetupFcn() const 00454 { return (HYPRE_PtrToParSolverFcn) HYPRE_ADSSetup; } 00455 virtual HYPRE_PtrToParSolverFcn SolveFcn() const 00456 { return (HYPRE_PtrToParSolverFcn) HYPRE_ADSSolve; } 00457 00458 virtual ~HypreADS(); 00459 }; 00460 00461 #endif