MFEM  v4.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
petsc.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 // Author: Stefano Zampini <stefano.zampini@gmail.com>
13 
14 #ifndef MFEM_PETSC
15 #define MFEM_PETSC
16 
17 #include "../config/config.hpp"
18 
19 #ifdef MFEM_USE_PETSC
20 #ifdef MFEM_USE_MPI
21 
22 #include <limits>
23 
24 #include "handle.hpp"
25 #include "hypre.hpp"
26 #include "ode.hpp"
27 
28 #include "petscconf.h"
29 #if !defined(PETSC_USE_REAL_DOUBLE)
30 #error "MFEM does not work with PETSc compiled without double precision"
31 #endif
32 #if defined(PETSC_USE_COMPLEX)
33 #error "MFEM does not work with PETSc compiled with complex numbers support"
34 #endif
35 #if defined(PETSC_USE_64BIT_INDICES) && !defined(HYPRE_BIGINT)
36 #error "Mismatch between HYPRE (32bit) and PETSc (64bit) integer types"
37 #endif
38 #if !defined(PETSC_USE_64BIT_INDICES) && defined(HYPRE_BIGINT)
39 #error "Mismatch between HYPRE (64bit) and PETSc (32bit) integer types"
40 #endif
41 
42 #include "petscversion.h"
43 #if PETSC_VERSION_GE(3,12,0)
44 #include "petscsystypes.h"
45 #else
46 typedef HYPRE_Int PetscInt;
47 typedef double PetscScalar;
48 typedef double PetscReal;
49 typedef int PetscClassId;
50 typedef struct _p_PetscObject *PetscObject;
51 #endif
52 
53 // forward declarations of PETSc objects
54 typedef struct _p_Vec *Vec;
55 typedef struct _p_Mat *Mat;
56 typedef struct _p_KSP *KSP;
57 typedef struct _p_PC *PC;
58 typedef struct _p_SNES *SNES;
59 typedef struct _p_TS *TS;
60 
61 
62 namespace mfem
63 {
64 
65 /// Convenience functions to initialize/finalize PETSc
66 void MFEMInitializePetsc();
67 void MFEMInitializePetsc(int*,char***);
68 void MFEMInitializePetsc(int*,char***,const char[],const char[]);
69 void MFEMFinalizePetsc();
70 
71 class ParFiniteElementSpace;
72 class PetscParMatrix;
73 
74 /// Wrapper for PETSc's vector class
75 class PetscParVector : public Vector
76 {
77 protected:
78  /// The actual PETSc object
79  Vec x;
80 
81  friend class PetscParMatrix;
82  friend class PetscODESolver;
83  friend class PetscLinearSolver;
84  friend class PetscPreconditioner;
85  friend class PetscNonlinearSolver;
86  friend class PetscBDDCSolver;
87 
88  // Set Vector::data and Vector::size from x
89  void _SetDataAndSize_();
90 
91 public:
92  /// Creates vector with given global size and partitioning of the columns.
93  /** If @a col is provided, processor P owns columns [col[P],col[P+1]).
94  Otherwise, PETSc decides the partitioning */
95  PetscParVector(MPI_Comm comm, PetscInt glob_size, PetscInt *col = NULL);
96 
97  /** @brief Creates vector with given global size, partitioning of the
98  columns, and data.
99 
100  The data must be allocated and destroyed outside. If @a _data is NULL, a
101  dummy vector without a valid data array will be created. */
102  PetscParVector(MPI_Comm comm, PetscInt glob_size, PetscScalar *_data,
103  PetscInt *col);
104 
105  /// Creates vector compatible with @a y
106  PetscParVector(const PetscParVector &y);
107 
108  /** @brief Creates a PetscParVector from a Vector
109  @param[in] comm MPI communicator on which the new object lives
110  @param[in] _x The mfem Vector (data is not shared)
111  @param[in] copy Whether to copy the data in _x or not */
112  PetscParVector(MPI_Comm comm, const Vector &_x, bool copy = false);
113 
114  /** @brief Creates vector compatible with the Operator (i.e. in the domain
115  of) @a op or its adjoint. */
116  /** The argument @a allocate determines if the memory is actually allocated
117  to store the data. */
118  explicit PetscParVector(MPI_Comm comm, const Operator &op,
119  bool transpose = false, bool allocate = true);
120 
121  /// Creates vector compatible with (i.e. in the domain of) @a A or @a A^T
122  /** The argument @a allocate determines if the memory is actually allocated
123  to store the data. */
124  explicit PetscParVector(const PetscParMatrix &A, bool transpose = false,
125  bool allocate = true);
126 
127  /// Creates PetscParVector out of PETSc Vec object.
128  /** @param[in] y The PETSc Vec object.
129  @param[in] ref If true, we increase the reference count of @a y. */
130  explicit PetscParVector(Vec y, bool ref=false);
131 
132  /// Create a true dof parallel vector on a given ParFiniteElementSpace
133  explicit PetscParVector(ParFiniteElementSpace *pfes);
134 
135  /// Calls PETSc's destroy function
136  virtual ~PetscParVector();
137 
138  /// Get the associated MPI communicator
139  MPI_Comm GetComm() const;
140 
141  /// Returns the global number of rows
142  PetscInt GlobalSize() const;
143 
144  /// Typecasting to PETSc's Vec type
145  operator Vec() const { return x; }
146 
147  /// Typecasting to PETSc object
148  operator PetscObject() const { return (PetscObject)x; }
149 
150  /// Returns the global vector in each processor
151  Vector* GlobalVector() const;
152 
153  /// Set constant values
155 
156  /** @brief Set values in a vector.
157 
158  @note any process can insert in any location
159  @note This is a collective operation, so all process needs to call it */
161 
162  /** @brief Add values in a vector.
163 
164  @note any process can add to any location
165  @note This is a collective operation, so all process needs to call it */
167 
168  /// Define operators for PETSc vectors.
173 
174  /** @brief Temporarily replace the data of the PETSc Vec object. To return to
175  the original data array, call ResetArray().
176 
177  @note This method calls PETSc's VecPlaceArray() function.
178  @note The inherited Vector::data pointer is not affected by this call. */
179  void PlaceArray(PetscScalar *temp_data);
180 
181  /** @brief Reset the PETSc Vec object to use its default data. Call this
182  method after the use of PlaceArray().
183 
184  @note This method calls PETSc's VecResetArray() function. */
185  void ResetArray();
186 
187  /// Set random values
188  void Randomize(PetscInt seed = 0);
189 
190  /// Prints the vector (to stdout if @a fname is NULL)
191  void Print(const char *fname = NULL, bool binary = false) const;
192 };
193 
194 
195 /// Wrapper for PETSc's matrix class
196 class PetscParMatrix : public Operator
197 {
198 protected:
199  /// The actual PETSc object
201 
202  /// Auxiliary vectors for typecasting
203  mutable PetscParVector *X, *Y;
204 
205  /// Initialize with defaults. Does not initialize inherited members.
206  void Init();
207 
208  /// Delete all owned data. Does not perform re-initialization with defaults.
209  void Destroy();
210 
211  /** @brief Creates a wrapper around a mfem::Operator @a op using PETSc's
212  MATSHELL object and returns the Mat in @a B.
213 
214  This does not take any reference to @a op, that should not be destroyed
215  until @a B is needed. */
216  void MakeWrapper(MPI_Comm comm, const Operator* op, Mat *B);
217 
218  /// Convert an mfem::Operator into a Mat @a B; @a op can be destroyed unless
219  /// tid == PETSC_MATSHELL or tid == PETSC_MATHYPRE
220  /// if op is a BlockOperator, the operator type is relevant to the individual
221  /// blocks
222  void ConvertOperator(MPI_Comm comm, const Operator& op, Mat *B,
223  Operator::Type tid);
224 
225  friend class PetscLinearSolver;
226  friend class PetscPreconditioner;
227 
228 private:
229  /// Constructs a block-diagonal Mat object
230  void BlockDiagonalConstructor(MPI_Comm comm, PetscInt *row_starts,
231  PetscInt *col_starts, SparseMatrix *diag,
232  bool assembled, Mat *A);
233 
234 public:
235  /// Create an empty matrix to be used as a reference to an existing matrix.
236  PetscParMatrix();
237 
238  /// Creates PetscParMatrix out of PETSc's Mat.
239  /** @param[in] a The PETSc Mat object.
240  @param[in] ref If true, we increase the reference count of @a a. */
241  PetscParMatrix(Mat a, bool ref=false);
242 
243  /** @brief Convert a PetscParMatrix @a pa with a new PETSc format @a tid.
244  Note that if @a pa is already a PetscParMatrix of the same type as
245  @a tid, the resulting PetscParMatrix will share the same Mat object */
246  explicit PetscParMatrix(const PetscParMatrix *pa, Operator::Type tid);
247 
248  /** @brief Creates a PetscParMatrix extracting the submatrix of @a A with
249  @a rows row indices and @a cols column indices */
251  const mfem::Array<PetscInt>& cols);
252 
253  /** @brief Convert a HypreParMatrix @a ha to a PetscParMatrix in the given
254  PETSc format @a tid. */
255  /** The supported type ids are: Operator::PETSC_MATAIJ,
256  Operator::PETSC_MATIS, Operator::PETSC_MATSHELL and
257  Operator::PETSC_MATHYPRE
258  @a ha can be destroyed unless tid == PETSC_MATSHELL or
259  tid == PETSC_MATHYPRE */
260  explicit PetscParMatrix(const HypreParMatrix *ha,
262 
263  /** @brief Convert a SparseMatrix @a ha to a PetscParMatrix in the given
264  PETSc format @a tid. */
265  explicit PetscParMatrix(const SparseMatrix *sa,
267 
268  /** @brief Convert an mfem::Operator into a PetscParMatrix in the given PETSc
269  format @a tid. */
270  /** If @a tid is Operator::PETSC_MATSHELL and @a op is not a PetscParMatrix,
271  it converts any mfem::Operator @a op implementing Operator::Mult() and
272  Operator::MultTranspose() into a PetscParMatrix. The Operator @a op
273  should not be deleted while the constructed PetscParMatrix is used.
274 
275  Otherwise, it tries to convert the operator in PETSc's classes.
276  @a op cannot be destroyed if tid == PETSC_MATHYPRE.
277 
278  In particular, if @a op is a BlockOperator, then a MATNEST Mat object is
279  created using @a tid as the type for the blocks.
280  Note that if @a op is already a PetscParMatrix of the same type as
281  @a tid, the resulting PetscParMatrix will share the same Mat object */
282  PetscParMatrix(MPI_Comm comm, const Operator *op,
284 
285  /// Creates block-diagonal square parallel matrix.
286  /** The block-diagonal is given by @a diag which must be in CSR format
287  (finalized). The new PetscParMatrix does not take ownership of any of the
288  input arrays. The type id @a tid can be either PETSC_MATAIJ (parallel
289  distributed CSR) or PETSC_MATIS. */
290  PetscParMatrix(MPI_Comm comm, PetscInt glob_size, PetscInt *row_starts,
291  SparseMatrix *diag, Operator::Type tid);
292 
293  /// Creates block-diagonal rectangular parallel matrix.
294  /** The block-diagonal is given by @a diag which must be in CSR format
295  (finalized). The new PetscParMatrix does not take ownership of any of the
296  input arrays. The type id @a tid can be either PETSC_MATAIJ (parallel
297  distributed CSR) or PETSC_MATIS. */
298  PetscParMatrix(MPI_Comm comm, PetscInt global_num_rows,
299  PetscInt global_num_cols, PetscInt *row_starts,
300  PetscInt *col_starts, SparseMatrix *diag,
301  Operator::Type tid);
302 
303  /// Calls PETSc's destroy function.
304  virtual ~PetscParMatrix() { Destroy(); }
305 
306  /// Replace the inner Mat Object. The reference count of newA is increased
307  void SetMat(Mat newA);
308 
309  /// @name Assignment operators
310  ///@{
315  ///@}
316 
317  /// Matvec: @a y = @a a A @a x + @a b @a y.
318  void Mult(double a, const Vector &x, double b, Vector &y) const;
319 
320  /// Matvec transpose: @a y = @a a A^T @a x + @a b @a y.
321  void MultTranspose(double a, const Vector &x, double b, Vector &y) const;
322 
323  virtual void Mult(const Vector &x, Vector &y) const
324  { Mult(1.0, x, 0.0, y); }
325 
326  virtual void MultTranspose(const Vector &x, Vector &y) const
327  { MultTranspose(1.0, x, 0.0, y); }
328 
329  /// Get the associated MPI communicator
330  MPI_Comm GetComm() const;
331 
332  /// Typecasting to PETSc's Mat type
333  operator Mat() const { return A; }
334 
335  /// Typecasting to PETSc object
336  operator PetscObject() const { return (PetscObject)A; }
337 
338  /// Returns the global index of the first local row
339  PetscInt GetRowStart() const;
340 
341  /// Returns the global index of the first local column
342  PetscInt GetColStart() const;
343 
344  /// Returns the local number of rows
345  PetscInt GetNumRows() const;
346 
347  /// Returns the local number of columns
348  PetscInt GetNumCols() const;
349 
350  /// Returns the global number of rows
351  PetscInt M() const;
352 
353  /// Returns the global number of columns
354  PetscInt N() const;
355 
356  /// Returns the global number of rows
357  PetscInt GetGlobalNumRows() const { return M(); }
358 
359  /// Returns the global number of columns
360  PetscInt GetGlobalNumCols() const { return N(); }
361 
362  /// Returns the number of nonzeros.
363  /** Differently from HYPRE, this call is collective on the communicator,
364  as this number is not stored inside PETSc, but needs to be computed. */
365  PetscInt NNZ() const;
366 
367  /// Returns the inner vector in the domain of A (it creates it if needed)
368  PetscParVector* GetX() const;
369 
370  /// Returns the inner vector in the range of A (it creates it if needed)
371  PetscParVector* GetY() const;
372 
373  /// Returns the transpose of the PetscParMatrix.
374  /** If @a action is false, the new matrix is constructed with the PETSc
375  function MatTranspose().
376  If @a action is true, then the matrix is not actually transposed.
377  Instead, an object that behaves like the transpose is returned. */
378  PetscParMatrix* Transpose(bool action = false);
379 
380  /// Prints the matrix (to stdout if fname is NULL)
381  void Print(const char *fname = NULL, bool binary = false) const;
382 
383  /// Scale all entries by s: A_scaled = s*A.
384  void operator*=(double s);
385 
386  /** @brief Eliminate rows and columns from the matrix, and rows from the
387  vector @a B. Modify @a B with the BC values in @a X. Put @a diag
388  on the diagonal corresponding to eliminated entries */
389  void EliminateRowsCols(const Array<int> &rows_cols, const PetscParVector &X,
390  PetscParVector &B, double diag = 1.);
391  void EliminateRowsCols(const Array<int> &rows_cols, const HypreParVector &X,
392  HypreParVector &B, double diag = 1.);
393 
394  /** @brief Eliminate rows and columns from the matrix and store the
395  eliminated elements in a new matrix Ae (returned).
396 
397  The sum of the modified matrix and the returned matrix, Ae, is equal to
398  the original matrix. */
399  PetscParMatrix* EliminateRowsCols(const Array<int> &rows_cols);
400 
401  /// Scale the local row i by s(i).
402  void ScaleRows(const Vector & s);
403 
404  /// Scale the local col i by s(i).
405  void ScaleCols(const Vector & s);
406 
407  /// Shift diagonal by a constant
408  void Shift(double s);
409 
410  /// Shift diagonal by a vector
411  void Shift(const Vector & s);
412 
413  /** @brief Eliminate only the rows from the matrix */
414  void EliminateRows(const Array<int> &rows);
415 
416  /// Makes this object a reference to another PetscParMatrix
417  void MakeRef(const PetscParMatrix &master);
418 
419  /** @brief Release the PETSc Mat object. If @a dereference is true, decrement
420  the refcount of the Mat object. */
421  Mat ReleaseMat(bool dereference);
422 
423  Type GetType() const;
424 };
425 
426 /// Returns the matrix A * B
427 PetscParMatrix * ParMult(const PetscParMatrix *A, const PetscParMatrix *B);
428 
429 /// Returns the matrix Rt^t * A * P
430 PetscParMatrix * RAP(PetscParMatrix *Rt, PetscParMatrix *A, PetscParMatrix *P);
431 
432 /// Returns the matrix P^t * A * P
433 PetscParMatrix * RAP(PetscParMatrix *A, PetscParMatrix *P);
434 
435 /// Returns the matrix P^t * A * P
436 PetscParMatrix * RAP(HypreParMatrix *A, PetscParMatrix *P);
437 
438 /** @brief Eliminate essential BC specified by @a ess_dof_list from the solution
439  @a X to the r.h.s. @a B.
440 
441  Here, @a A is a matrix with eliminated BC, while @a Ae is such that
442  (@a A + @a Ae) is the original (Neumann) matrix before elimination. */
443 void EliminateBC(PetscParMatrix &A, PetscParMatrix &Ae,
444  const Array<int> &ess_dof_list, const Vector &X, Vector &B);
445 
446 /// Helper class for handling essential boundary conditions.
448 {
449 public:
450  enum Type
451  {
453  CONSTANT, ///< Constant in time b.c.
455  };
456 
458  bctype(_type), setup(false), eval_t(0.0),
459  eval_t_cached(std::numeric_limits<double>::min()) {}
460  PetscBCHandler(Array<int>& ess_tdof_list, Type _type = ZERO);
461 
462  virtual ~PetscBCHandler() {}
463 
464  /// Returns the type of boundary conditions
465  Type GetType() const { return bctype; }
466 
467  /// Sets the type of boundary conditions
468  void SetType(enum Type _type) { bctype = _type; setup = false; }
469 
470  /// Boundary conditions evaluation
471  /** In the result vector, @a g, only values at the essential dofs need to be
472  set. */
473  virtual void Eval(double t, Vector &g)
474  { mfem_error("PetscBCHandler::Eval method not overloaded"); }
475 
476  /// Sets essential dofs (local, per-process numbering)
477  void SetTDofs(Array<int>& list);
478 
479  /// Gets essential dofs (local, per-process numbering)
480  Array<int>& GetTDofs() { return ess_tdof_list; }
481 
482  /// Sets the current time
483  void SetTime(double t) { eval_t = t; }
484 
485  /// SetUp the helper object, where @a n is the size of the solution vector
486  void SetUp(PetscInt n);
487 
488  /// y = x on ess_tdof_list_c and y = g (internally evaluated) on ess_tdof_list
489  void ApplyBC(const Vector &x, Vector &y);
490 
491  /// Replace boundary dofs with the current value
492  void ApplyBC(Vector &x);
493 
494  /// y = x-g on ess_tdof_list, the rest of y is unchanged
495  void FixResidualBC(const Vector& x, Vector& y);
496 
497 private:
498  enum Type bctype;
499  bool setup;
500 
501  double eval_t;
502  double eval_t_cached;
503  Vector eval_g;
504 
505  Array<int> ess_tdof_list; //Essential true dofs
506 };
507 
508 // Helper class for user-defined preconditioners that needs to be setup
510 {
511 private:
512  std::string name;
513 public:
514  PetscPreconditionerFactory(const std::string &_name = "MFEM Factory")
515  : name(_name) { }
516  const char* GetName() { return name.c_str(); }
517  virtual Solver *NewPreconditioner(const OperatorHandle& oh) = 0;
519 };
520 
521 // Forward declarations of helper classes
522 class PetscSolverMonitor;
523 
524 /// Abstract class for PETSc's solvers.
526 {
527 protected:
528  /// Boolean to handle SetFromOptions calls.
529  mutable bool clcustom;
530 
531  /// The actual PETSc object (KSP, PC, SNES or TS).
533 
534  /// The class id of the actual PETSc object
536 
537  /// Right-hand side and solution vector
538  mutable PetscParVector *B, *X;
539 
540  /// Handler for boundary conditions
542 
543  /// Private context for solver
544  void *private_ctx;
545 
546  /// Boolean to handle SetOperator calls.
547  mutable bool operatorset;
548 
549 public:
550  /// Construct an empty PetscSolver. Initialize protected objects to NULL.
551  PetscSolver();
552 
553  /// Destroy the PetscParVectors allocated (if any).
554  virtual ~PetscSolver();
555 
556  /** @name Update of PETSc options.
557  The following Set methods can be used to update the internal PETSc
558  options.
559  @note They will be overwritten by the options in the input PETSc file. */
560  ///@{
561  void SetTol(double tol);
562  void SetRelTol(double tol);
563  void SetAbsTol(double tol);
564  void SetMaxIter(int max_iter);
565  void SetPrintLevel(int plev);
566  ///@}
567 
568  /// Customize object with options set
569  /** If @a customize is false, it disables any options customization. */
570  void Customize(bool customize = true) const;
571  int GetConverged();
572  int GetNumIterations();
573  double GetFinalNorm();
574 
575  /// Sets user-defined monitoring routine.
576  void SetMonitor(PetscSolverMonitor *ctx);
577 
578  /// Sets the object to handle essential boundary conditions
579  void SetBCHandler(PetscBCHandler *bch);
580 
581  /// Sets the object for the creation of the preconditioner
583 
584  /// Conversion function to PetscObject.
585  operator PetscObject() const { return obj; }
586 
587  /// Get the associated MPI communicator
588  MPI_Comm GetComm() const;
589 
590 protected:
591  /// These two methods handle creation and destructions of
592  /// private data for the Solver objects
593  void CreatePrivateContext();
594  void FreePrivateContext();
595 };
596 
597 
598 /// Abstract class for PETSc's linear solvers.
599 class PetscLinearSolver : public PetscSolver, public Solver
600 {
601 private:
602  /// Internal flag to handle HypreParMatrix conversion or not.
603  bool wrap;
604 
605 public:
606  PetscLinearSolver(MPI_Comm comm, const std::string &prefix = std::string(),
607  bool wrap = true);
609  const std::string &prefix = std::string());
610  /// Constructs a solver using a HypreParMatrix.
611  /** If @a wrap is true, then the MatMult ops of HypreParMatrix are wrapped.
612  No preconditioner can be automatically constructed from PETSc. If
613  @a wrap is false, the HypreParMatrix is converted into a the AIJ
614  PETSc format, which is suitable for most preconditioning methods. */
615  PetscLinearSolver(const HypreParMatrix &A, bool wrap = true,
616  const std::string &prefix = std::string());
617  virtual ~PetscLinearSolver();
618 
619  virtual void SetOperator(const Operator &op);
620 
621  /// Allows to prescribe a different operator (@a pop) to construct
622  /// the preconditioner
623  void SetOperator(const Operator &op, const Operator &pop);
624 
625  /// Sets the solver to perform preconditioning
626  void SetPreconditioner(Solver &precond);
627 
628  /// Application of the solver.
629  virtual void Mult(const Vector &b, Vector &x) const;
630 
631  /// Conversion function to PETSc's KSP type.
632  operator KSP() const { return (KSP)obj; }
633 };
634 
635 
637 {
638 public:
639  PetscPCGSolver(MPI_Comm comm, const std::string &prefix = std::string());
640  PetscPCGSolver(PetscParMatrix &A, const std::string &prefix = std::string());
641  PetscPCGSolver(HypreParMatrix &A,bool wrap=true,
642  const std::string &prefix = std::string());
643 };
644 
645 
646 /// Abstract class for PETSc's preconditioners.
647 class PetscPreconditioner : public PetscSolver, public Solver
648 {
649 public:
650  PetscPreconditioner(MPI_Comm comm,
651  const std::string &prefix = std::string());
653  const std::string &prefix = std::string());
654  PetscPreconditioner(MPI_Comm comm, Operator &op,
655  const std::string &prefix = std::string());
656  virtual ~PetscPreconditioner();
657 
658  virtual void SetOperator(const Operator &op);
659 
660  /// Application of the preconditioner.
661  virtual void Mult(const Vector &b, Vector &x) const;
662 
663  /// Conversion function to PETSc's PC type.
664  operator PC() const { return (PC)obj; }
665 };
666 
667 
668 /// Auxiliary class for BDDC customization.
670 {
671 protected:
677  bool netflux;
678  friend class PetscBDDCSolver;
679 
680 public:
682  nat_dof(NULL), nat_dof_local(false), netflux(false)
683  {}
685 
686  /// Specify dofs on the essential boundary.
687  /** If @a loc is false, it is a list of true dofs in local ordering.
688  If @a loc is true, it is a marker for Vdofs in local ordering. */
689  void SetEssBdrDofs(const Array<int> *essdofs, bool loc = false)
690  {
691  ess_dof = essdofs;
692  ess_dof_local = loc;
693  }
694  /// Specify dofs on the natural boundary.
695  /** If @a loc is false, it is a list of true dofs in local ordering.
696  If @a loc is true, it is a marker for Vdofs in local ordering. */
697  void SetNatBdrDofs(const Array<int> *natdofs, bool loc = false)
698  {
699  nat_dof = natdofs;
700  nat_dof_local = loc;
701  }
702  /// Setup BDDC with no-net-flux local solvers. Needs a ParFiniteElementSpace attached
703  void SetComputeNetFlux(bool net = true)
704  {
705  netflux = net;
706  }
707 };
708 
709 
711 {
712 private:
713  void BDDCSolverConstructor(const PetscBDDCSolverParams &opts);
714 
715 public:
716  PetscBDDCSolver(MPI_Comm comm, Operator &op,
718  const std::string &prefix = std::string());
721  const std::string &prefix = std::string());
722 };
723 
724 
726 {
727 public:
728  PetscFieldSplitSolver(MPI_Comm comm, Operator &op,
729  const std::string &prefix = std::string());
730 };
731 
732 
733 /// Abstract class for PETSc's nonlinear solvers.
735 {
736 public:
737  PetscNonlinearSolver(MPI_Comm comm,
738  const std::string &prefix = std::string());
739  PetscNonlinearSolver(MPI_Comm comm, Operator &op,
740  const std::string &prefix = std::string());
741  virtual ~PetscNonlinearSolver();
742 
743  /// Specification of the nonlinear operator.
744  virtual void SetOperator(const Operator &op);
745 
746  /// Specifies the desired format of the Jacobian in case a PetscParMatrix
747  /// is not returned by the GetGradient method.
748  void SetJacobianType(Operator::Type type);
749 
750  /// Application of the solver.
751  virtual void Mult(const Vector &b, Vector &x) const;
752 
753  /// Specification of an objective function to be used for line search.
754  void SetObjective(void (*obj)(Operator* op, const Vector &x, double *f));
755 
756  /// User-defined routine to be applied after a successful line search step.
757  /// The user can change the current direction Y and/or the updated solution W
758  /// (with W = X - lambda * Y) but not the previous solution X.
759  /// If Y or W have been changed, the corresponding booleans need to updated.
760  void SetPostCheck(void (*post)(Operator *op, const Vector &X, Vector &Y,
761  Vector &W, bool &changed_y, bool &changed_w));
762 
763  /// General purpose update function to be called at the beginning of each step
764  /// it is the current nonlinear iteration number
765  /// F is the current function value, X the current solution
766  /// D the previous step taken, and P the previous solution
767  void SetUpdate(void (*update)(Operator *op, int it,
768  const mfem::Vector& F, const mfem::Vector& X,
769  const mfem::Vector& D, const mfem::Vector& P));
770 
771  /// Conversion function to PETSc's SNES type.
772  operator SNES() const { return (SNES)obj; }
773 };
774 
775 
776 /// Abstract class for PETSc's ODE solvers.
777 class PetscODESolver : public PetscSolver, public ODESolver
778 {
779 public:
780  /// The type of the ODE. Use ODE_SOLVER_LINEAR if the jacobians
781  /// are linear and independent of time.
782  enum Type
783  {
786  };
787 
788  PetscODESolver(MPI_Comm comm, const std::string &prefix = std::string());
789  virtual ~PetscODESolver();
790 
791  /// Initialize the ODE solver.
792  virtual void Init(TimeDependentOperator &f_,
793  enum PetscODESolver::Type type);
795 
798 
799  /// Specifies the desired format of the Jacobian in case a PetscParMatrix
800  /// is not returned by the GetGradient methods
801  void SetJacobianType(Operator::Type type);
802 
803  virtual void Step(Vector &x, double &t, double &dt);
804  virtual void Run(Vector &x, double &t, double &dt, double t_final);
805 
806  /// Conversion function to PETSc's TS type.
807  operator TS() const { return (TS)obj; }
808 };
809 
810 
811 /// Abstract class for monitoring PETSc's solvers.
813 {
814 public:
815  bool mon_sol;
816  bool mon_res;
817  PetscSolverMonitor(bool monitor_sol = false, bool monitor_res = true)
818  : mon_sol(monitor_sol), mon_res(monitor_res) {}
819  virtual ~PetscSolverMonitor() {}
820 
821  /// Monitor the solution vector x
822  virtual void MonitorSolution(PetscInt it, PetscReal norm, const Vector &x)
823  {
824  MFEM_ABORT("MonitorSolution() is not implemented!")
825  }
826 
827  /// Monitor the residual vector r
828  virtual void MonitorResidual(PetscInt it, PetscReal norm, const Vector &r)
829  {
830  MFEM_ABORT("MonitorResidual() is not implemented!")
831  }
832 
833  /// Generic monitor to take access to the solver
834  virtual void MonitorSolver(PetscSolver* solver) {}
835 };
836 
837 
838 } // namespace mfem
839 
840 #endif // MFEM_USE_MPI
841 #endif // MFEM_USE_PETSC
842 
843 #endif
PetscPreconditionerFactory(const std::string &_name="MFEM Factory")
Definition: petsc.hpp:514
void SetPreconditioner(Solver &precond)
Sets the solver to perform preconditioning.
Definition: petsc.cpp:2463
void SetPrintLevel(int plev)
Definition: petsc.cpp:1822
PetscParVector * B
Right-hand side and solution vector.
Definition: petsc.hpp:538
void CreatePrivateContext()
Definition: petsc.cpp:2113
void Print(const char *fname=NULL, bool binary=false) const
Prints the matrix (to stdout if fname is NULL)
Definition: petsc.cpp:1408
virtual void SetOperator(const Operator &op)
Specification of the nonlinear operator.
Definition: petsc.cpp:3262
Abstract class for PETSc&#39;s preconditioners.
Definition: petsc.hpp:647
PetscParMatrix & operator+=(const PetscParMatrix &B)
Definition: petsc.cpp:652
double PetscScalar
Definition: petsc.hpp:47
struct _p_TS * TS
Definition: petsc.hpp:59
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Definition: petsc.cpp:2299
HypreParMatrix * RAP(const HypreParMatrix *A, const HypreParMatrix *P)
Returns the matrix P^t * A * P.
Definition: hypre.cpp:1563
bool clcustom
Boolean to handle SetFromOptions calls.
Definition: petsc.hpp:529
void SetObjective(void(*obj)(Operator *op, const Vector &x, double *f))
Specification of an objective function to be used for line search.
Definition: petsc.cpp:3321
HYPRE_Int PetscInt
Definition: petsc.hpp:46
void ConvertOperator(MPI_Comm comm, const Operator &op, Mat *B, Operator::Type tid)
Definition: petsc.cpp:854
double GetFinalNorm()
Definition: petsc.cpp:2088
Wrapper for PETSc&#39;s matrix class.
Definition: petsc.hpp:196
PetscParVector & operator+=(const PetscParVector &y)
Definition: petsc.cpp:407
const Array< int > * nat_dof
Definition: petsc.hpp:675
void ApplyBC(const Vector &x, Vector &y)
y = x on ess_tdof_list_c and y = g (internally evaluated) on ess_tdof_list
Definition: petsc.cpp:2194
Abstract class for PETSc&#39;s linear solvers.
Definition: petsc.hpp:599
Vec x
The actual PETSc object.
Definition: petsc.hpp:79
Abstract class for PETSc&#39;s solvers.
Definition: petsc.hpp:525
PetscODESolver::Type GetType() const
Definition: petsc.cpp:3488
virtual void Run(Vector &x, double &t, double &dt, double t_final)
Perform time integration from time t [in] to time tf [in].
Definition: petsc.cpp:3537
void SetPostCheck(void(*post)(Operator *op, const Vector &X, Vector &Y, Vector &W, bool &changed_y, bool &changed_w))
Definition: petsc.cpp:3332
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition: petsc.hpp:323
ParFiniteElementSpace * fespace
Definition: petsc.hpp:672
Type GetType() const
Returns the type of boundary conditions.
Definition: petsc.hpp:465
Base abstract class for time dependent operators.
Definition: operator.hpp:162
PetscInt GetNumCols() const
Returns the local number of columns.
Definition: petsc.cpp:498
void SetType(PetscODESolver::Type)
Definition: petsc.cpp:3494
virtual void MonitorSolver(PetscSolver *solver)
Generic monitor to take access to the solver.
Definition: petsc.hpp:834
Pointer to an Operator of a specified type.
Definition: handle.hpp:33
void Mult(double a, const Vector &x, double b, Vector &y) const
Matvec: y = a A x + b y.
Definition: petsc.cpp:1375
PetscBDDCSolver(MPI_Comm comm, Operator &op, const PetscBDDCSolverParams &opts=PetscBDDCSolverParams(), const std::string &prefix=std::string())
Definition: petsc.cpp:3177
PetscParVector & AddValues(const Array< PetscInt > &, const Array< PetscScalar > &)
Add values in a vector.
Definition: petsc.cpp:388
void SetMat(Mat newA)
Replace the inner Mat Object. The reference count of newA is increased.
Definition: petsc.cpp:1258
virtual ~PetscSolver()
Destroy the PetscParVectors allocated (if any).
Definition: petsc.cpp:1733
PetscNonlinearSolver(MPI_Comm comm, const std::string &prefix=std::string())
Definition: petsc.cpp:3222
PetscInt GetGlobalNumRows() const
Returns the global number of rows.
Definition: petsc.hpp:357
Type GetType() const
Definition: petsc.cpp:1675
virtual void Step(Vector &x, double &t, double &dt)
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in]...
Definition: petsc.cpp:3512
Abstract class for solving systems of ODEs: dx/dt = f(x,t)
Definition: ode.hpp:22
void Init()
Initialize with defaults. Does not initialize inherited members.
Definition: petsc.cpp:526
PetscPreconditioner(MPI_Comm comm, const std::string &prefix=std::string())
Definition: petsc.cpp:2576
PetscClassId cid
The class id of the actual PETSc object.
Definition: petsc.hpp:535
Abstract parallel finite element space.
Definition: pfespace.hpp:28
Constant in time b.c.
Definition: petsc.hpp:453
void SetRelTol(double tol)
Definition: petsc.cpp:1745
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition: petsc.hpp:326
void Randomize(PetscInt seed=0)
Set random values.
Definition: petsc.cpp:435
PetscPCGSolver(MPI_Comm comm, const std::string &prefix=std::string())
Definition: petsc.cpp:2546
void Destroy()
Delete all owned data. Does not perform re-initialization with defaults.
Definition: petsc.cpp:1233
void SetMonitor(PetscSolverMonitor *ctx)
Sets user-defined monitoring routine.
Definition: petsc.cpp:1899
void SetMaxIter(int max_iter)
Definition: petsc.cpp:1795
Abstract class for PETSc&#39;s ODE solvers.
Definition: petsc.hpp:777
PetscParVector & operator*=(PetscScalar d)
Definition: petsc.cpp:419
struct _p_SNES * SNES
Definition: petsc.hpp:58
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B)
Returns the matrix A * B.
Definition: hypre.cpp:1543
void EliminateRowsCols(const Array< int > &rows_cols, const PetscParVector &X, PetscParVector &B, double diag=1.)
Eliminate rows and columns from the matrix, and rows from the vector B. Modify B with the BC values i...
Definition: petsc.cpp:1619
double PetscReal
Definition: petsc.hpp:48
Wrapper for PETSc&#39;s vector class.
Definition: petsc.hpp:75
void Customize(bool customize=true) const
Customize object with options set.
Definition: petsc.cpp:1989
PetscInt M() const
Returns the global number of rows.
Definition: petsc.cpp:505
int PetscClassId
Definition: petsc.hpp:49
virtual void Mult(const Vector &b, Vector &x) const
Application of the solver.
Definition: petsc.cpp:3359
PetscParVector * Y
Definition: petsc.hpp:203
virtual ~PetscLinearSolver()
Definition: petsc.cpp:2536
PetscInt GetNumRows() const
Returns the local number of rows.
Definition: petsc.cpp:491
void Print(const char *fname=NULL, bool binary=false) const
Prints the vector (to stdout if fname is NULL)
Definition: petsc.cpp:450
struct _p_PC * PC
Definition: petsc.hpp:57
void EliminateBC(HypreParMatrix &A, HypreParMatrix &Ae, const Array< int > &ess_dof_list, const Vector &X, Vector &B)
Definition: hypre.cpp:1617
void ResetArray()
Reset the PETSc Vec object to use its default data. Call this method after the use of PlaceArray()...
Definition: petsc.cpp:430
PetscParVector & SetValues(const Array< PetscInt > &, const Array< PetscScalar > &)
Set values in a vector.
Definition: petsc.cpp:375
virtual void Init(TimeDependentOperator &f_, enum PetscODESolver::Type type)
Initialize the ODE solver.
Definition: petsc.cpp:3415
PetscParMatrix * Transpose(bool action=false)
Returns the transpose of the PetscParMatrix.
Definition: petsc.cpp:1356
PetscObject obj
The actual PETSc object (KSP, PC, SNES or TS).
Definition: petsc.hpp:532
Abstract class for monitoring PETSc&#39;s solvers.
Definition: petsc.hpp:812
Data type sparse matrix.
Definition: sparsemat.hpp:40
void SetJacobianType(Operator::Type type)
Definition: petsc.cpp:3315
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
Definition: error.cpp:146
Auxiliary class for BDDC customization.
Definition: petsc.hpp:669
virtual ~PetscPreconditioner()
Definition: petsc.cpp:2687
MPI_Comm GetComm() const
Get the associated MPI communicator.
Definition: petsc.cpp:820
void FixResidualBC(const Vector &x, Vector &y)
y = x-g on ess_tdof_list, the rest of y is unchanged
Definition: petsc.cpp:2243
PetscParMatrix & operator=(const PetscParMatrix &B)
Definition: petsc.cpp:636
PetscInt GetColStart() const
Returns the global index of the first local column.
Definition: petsc.cpp:484
virtual ~PetscParVector()
Calls PETSc&#39;s destroy function.
Definition: petsc.cpp:246
PetscFieldSplitSolver(MPI_Comm comm, Operator &op, const std::string &prefix=std::string())
Definition: petsc.cpp:3186
PetscBCHandler * bchandler
Handler for boundary conditions.
Definition: petsc.hpp:541
PetscParMatrix & operator-=(const PetscParMatrix &B)
Definition: petsc.cpp:667
virtual Solver * NewPreconditioner(const OperatorHandle &oh)=0
void ScaleRows(const Vector &s)
Scale the local row i by s(i).
Definition: petsc.cpp:1433
MPI_Comm GetComm() const
Get the associated MPI communicator.
Definition: petsc.cpp:1894
void Shift(double s)
Shift diagonal by a constant.
Definition: petsc.cpp:1455
void SetTime(double t)
Sets the current time.
Definition: petsc.hpp:483
ID for class PetscParMatrix, MATSHELL format.
Definition: operator.hpp:142
PetscParMatrix()
Create an empty matrix to be used as a reference to an existing matrix.
Definition: petsc.cpp:533
void SetType(enum Type _type)
Sets the type of boundary conditions.
Definition: petsc.hpp:468
Abstract class for PETSc&#39;s nonlinear solvers.
Definition: petsc.hpp:734
int GetNumIterations()
Definition: petsc.cpp:2055
void SetBCHandler(PetscBCHandler *bch)
Sets the object to handle essential boundary conditions.
Definition: petsc.cpp:1929
Wrapper for hypre&#39;s parallel vector class.
Definition: hypre.hpp:73
virtual void Eval(double t, Vector &g)
Boundary conditions evaluation.
Definition: petsc.hpp:473
Type
Enumeration defining IDs for some classes derived from Operator.
Definition: operator.hpp:135
PetscBCHandler(Type _type=ZERO)
Definition: petsc.hpp:457
PetscInt NNZ() const
Returns the number of nonzeros.
Definition: petsc.cpp:519
PetscLinearSolver(MPI_Comm comm, const std::string &prefix=std::string(), bool wrap=true)
Definition: petsc.cpp:2264
virtual void Mult(const Vector &b, Vector &x) const
Application of the preconditioner.
Definition: petsc.cpp:2657
Mat A
The actual PETSc object.
Definition: petsc.hpp:200
virtual void Init(TimeDependentOperator &f_)
Associate a TimeDependentOperator with the ODE solver.
Definition: petsc.hpp:794
struct _p_Mat * Mat
Definition: petsc.hpp:55
PetscInt N() const
Returns the global number of columns.
Definition: petsc.cpp:512
PetscParVector * GetY() const
Returns the inner vector in the range of A (it creates it if needed)
Definition: petsc.cpp:1346
void SetJacobianType(Operator::Type type)
Definition: petsc.cpp:3482
void MakeWrapper(MPI_Comm comm, const Operator *op, Mat *B)
Creates a wrapper around a mfem::Operator op using PETSc&#39;s MATSHELL object and returns the Mat in B...
Definition: petsc.cpp:833
void SetUpdate(void(*update)(Operator *op, int it, const mfem::Vector &F, const mfem::Vector &X, const mfem::Vector &D, const mfem::Vector &P))
Definition: petsc.cpp:3346
bool operatorset
Boolean to handle SetOperator calls.
Definition: petsc.hpp:547
PetscParVector * X
Auxiliary vectors for typecasting.
Definition: petsc.hpp:203
void MultTranspose(double a, const Vector &x, double b, Vector &y) const
Matvec transpose: y = a A^T x + b y.
Definition: petsc.cpp:1391
PetscParVector & operator-=(const PetscParVector &y)
Definition: petsc.cpp:413
virtual ~PetscSolverMonitor()
Definition: petsc.hpp:819
void MFEMFinalizePetsc()
Definition: petsc.cpp:185
virtual ~PetscNonlinearSolver()
Definition: petsc.cpp:3254
void SetComputeNetFlux(bool net=true)
Setup BDDC with no-net-flux local solvers. Needs a ParFiniteElementSpace attached.
Definition: petsc.hpp:703
virtual ~PetscODESolver()
Definition: petsc.cpp:3407
virtual ~PetscBCHandler()
Definition: petsc.hpp:462
int GetConverged()
Definition: petsc.cpp:2022
PetscSolver()
Construct an empty PetscSolver. Initialize protected objects to NULL.
Definition: petsc.cpp:1723
void SetPreconditionerFactory(PetscPreconditionerFactory *factory)
Sets the object for the creation of the preconditioner.
Definition: petsc.cpp:1948
void MFEMInitializePetsc()
Convenience functions to initialize/finalize PETSc.
Definition: petsc.cpp:168
Mat ReleaseMat(bool dereference)
Release the PETSc Mat object. If dereference is true, decrement the refcount of the Mat object...
Definition: petsc.cpp:1662
PetscParVector(MPI_Comm comm, PetscInt glob_size, PetscInt *col=NULL)
Creates vector with given global size and partitioning of the columns.
Definition: petsc.cpp:228
virtual void MonitorSolution(PetscInt it, PetscReal norm, const Vector &x)
Monitor the solution vector x.
Definition: petsc.hpp:822
ID for class PetscParMatrix, MATAIJ format.
Definition: operator.hpp:140
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Definition: petsc.cpp:2611
void SetSpace(ParFiniteElementSpace *fe)
Definition: petsc.hpp:684
MPI_Comm GetComm() const
Get the associated MPI communicator.
Definition: petsc.cpp:339
PetscInt GlobalSize() const
Returns the global number of rows.
Definition: petsc.cpp:204
PetscParVector * X
Definition: petsc.hpp:538
const Array< int > * ess_dof
Definition: petsc.hpp:673
void _SetDataAndSize_()
Definition: petsc.cpp:193
PetscInt GetRowStart() const
Returns the global index of the first local row.
Definition: petsc.cpp:477
struct _p_PetscObject * PetscObject
Definition: petsc.hpp:50
void SetAbsTol(double tol)
Definition: petsc.cpp:1770
Helper class for handling essential boundary conditions.
Definition: petsc.hpp:447
struct _p_KSP * KSP
Definition: petsc.hpp:56
PetscParVector * GetX() const
Returns the inner vector in the domain of A (it creates it if needed)
Definition: petsc.cpp:1336
Array< int > & GetTDofs()
Gets essential dofs (local, per-process numbering)
Definition: petsc.hpp:480
void SetTol(double tol)
Definition: petsc.cpp:1740
PetscParVector & operator=(PetscScalar d)
Set constant values.
Definition: petsc.cpp:369
PetscSolverMonitor(bool monitor_sol=false, bool monitor_res=true)
Definition: petsc.hpp:817
virtual void MonitorResidual(PetscInt it, PetscReal norm, const Vector &r)
Monitor the residual vector r.
Definition: petsc.hpp:828
Vector data type.
Definition: vector.hpp:48
struct _p_Vec * Vec
Definition: petsc.hpp:54
void PlaceArray(PetscScalar *temp_data)
Temporarily replace the data of the PETSc Vec object. To return to the original data array...
Definition: petsc.cpp:425
void FreePrivateContext()
Definition: petsc.cpp:2144
Vector * GlobalVector() const
Returns the global vector in each processor.
Definition: petsc.cpp:344
PetscODESolver(MPI_Comm comm, const std::string &prefix=std::string())
Definition: petsc.cpp:3382
void EliminateRows(const Array< int > &rows)
Eliminate only the rows from the matrix.
Definition: petsc.cpp:1648
Base class for solvers.
Definition: operator.hpp:279
PetscInt GetGlobalNumCols() const
Returns the global number of columns.
Definition: petsc.hpp:360
void SetNatBdrDofs(const Array< int > *natdofs, bool loc=false)
Specify dofs on the natural boundary.
Definition: petsc.hpp:697
Abstract operator.
Definition: operator.hpp:21
Wrapper for hypre&#39;s ParCSR matrix class.
Definition: hypre.hpp:187
virtual void Mult(const Vector &b, Vector &x) const
Application of the solver.
Definition: petsc.cpp:2503
void operator*=(double s)
Scale all entries by s: A_scaled = s*A.
Definition: petsc.cpp:1370
void SetEssBdrDofs(const Array< int > *essdofs, bool loc=false)
Specify dofs on the essential boundary.
Definition: petsc.hpp:689
void SetTDofs(Array< int > &list)
Sets essential dofs (local, per-process numbering)
Definition: petsc.cpp:2171
void * private_ctx
Private context for solver.
Definition: petsc.hpp:544
void SetUp(PetscInt n)
SetUp the helper object, where n is the size of the solution vector.
Definition: petsc.cpp:2178
void MakeRef(const PetscParMatrix &master)
Makes this object a reference to another PetscParMatrix.
Definition: petsc.cpp:1326
void ScaleCols(const Vector &s)
Scale the local col i by s(i).
Definition: petsc.cpp:1444
virtual ~PetscParMatrix()
Calls PETSc&#39;s destroy function.
Definition: petsc.hpp:304