MFEM  v3.4
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
handle.cpp
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 #include "handle.hpp"
13 #include "sparsemat.hpp"
14 #ifdef MFEM_USE_MPI
15 #include "petsc.hpp"
16 #endif
17 
18 // Make sure that hypre and PETSc use the same size indices.
19 #if defined(MFEM_USE_MPI) && defined(MFEM_USE_PETSC)
20 #if (defined(HYPRE_BIGINT) && !defined(PETSC_USE_64BIT_INDICES)) || \
21  (!defined(HYPRE_BIGINT) && defined(PETSC_USE_64BIT_INDICES))
22 #error HYPRE and PETSC do not use the same size integers!
23 #endif
24 #endif
25 
26 namespace mfem
27 {
28 
30  "Operator::Type is not supported: type_id = ";
31 
33 {
34  switch (tid)
35  {
36  case Operator::ANY_TYPE: break;
37  case Operator::MFEM_SPARSEMAT: break;
39 #ifdef MFEM_USE_MPI
40  break;
41 #else
42  MFEM_ABORT("cannot use HYPRE parallel matrix format: "
43  "MFEM is not built with HYPRE support");
44 #endif
47 #ifdef MFEM_USE_PETSC
48  break;
49 #else
50  MFEM_ABORT("cannot use PETSc matrix formats: "
51  "MFEM is not built with PETSc support");
52 #endif
53  default:
54  MFEM_ABORT("invalid Operator::Type, type_id = " << (int)type_id);
55  }
56  return tid;
57 }
58 
59 #ifdef MFEM_USE_MPI
60 void OperatorHandle::MakeSquareBlockDiag(MPI_Comm comm, HYPRE_Int glob_size,
61  HYPRE_Int *row_starts,
62  SparseMatrix *diag)
63 {
64  if (own_oper) { delete oper; }
65 
66  switch (type_id)
67  {
68  case Operator::ANY_TYPE: // --> MFEM_SPARSEMAT
70  // As a parallel Operator, the SparseMatrix simply represents the local
71  // Operator, without the need of any communication.
72  pSet(diag, false);
73  return;
75  oper = new HypreParMatrix(comm, glob_size, row_starts, diag);
76  break;
77 #ifdef MFEM_USE_PETSC
80  // Assuming that PetscInt is the same size as HYPRE_Int, checked above.
81  oper = new PetscParMatrix(comm, glob_size, row_starts, diag, type_id);
82  break;
83 #endif
84  default: MFEM_ABORT(not_supported_msg << type_id);
85  }
86  own_oper = true;
87 }
88 
90 MakeRectangularBlockDiag(MPI_Comm comm, HYPRE_Int glob_num_rows,
91  HYPRE_Int glob_num_cols, HYPRE_Int *row_starts,
92  HYPRE_Int *col_starts, SparseMatrix *diag)
93 {
94  if (own_oper) { delete oper; }
95 
96  switch (type_id)
97  {
98  case Operator::ANY_TYPE: // --> MFEM_SPARSEMAT
100  // As a parallel Operator, the SparseMatrix simply represents the local
101  // Operator, without the need of any communication.
102  pSet(diag, false);
103  return;
105  oper = new HypreParMatrix(comm, glob_num_rows, glob_num_cols,
106  row_starts, col_starts, diag);
107  break;
108 #ifdef MFEM_USE_PETSC
111  // Assuming that PetscInt is the same size as HYPRE_Int, checked above.
112  oper = new PetscParMatrix(comm, glob_num_rows, glob_num_cols,
113  row_starts, col_starts, diag, type_id);
114  break;
115 #endif
116  default: MFEM_ABORT(not_supported_msg << type_id);
117  }
118  own_oper = true;
119 }
120 #endif // MFEM_USE_MPI
121 
123 {
124  if (A.Type() != Operator::ANY_TYPE)
125  {
126  MFEM_VERIFY(A.Type() == P.Type(), "type mismatch in A and P");
127  }
128  Clear();
129  switch (A.Type())
130  {
131  case Operator::ANY_TYPE:
132  pSet(new RAPOperator(*P.Ptr(), *A.Ptr(), *P.Ptr()));
133  break;
135  {
137  SparseMatrix *RA = mfem::Mult(*R, *A.As<SparseMatrix>());
138  delete R;
139  pSet(mfem::Mult(*RA, *P.As<SparseMatrix>()));
140  delete RA;
141  break;
142  }
143 #ifdef MFEM_USE_MPI
146  break;
147 #ifdef MFEM_USE_PETSC
150  {
152  break;
153  }
154 #endif
155 #endif
156  default: MFEM_ABORT(not_supported_msg << A.Type());
157  }
158 }
159 
161  OperatorHandle &P)
162 {
163  if (A.Type() != Operator::ANY_TYPE)
164  {
165  MFEM_VERIFY(A.Type() == Rt.Type(), "type mismatch in A and Rt");
166  MFEM_VERIFY(A.Type() == P.Type(), "type mismatch in A and P");
167  }
168  Clear();
169  switch (A.Type())
170  {
171  case Operator::ANY_TYPE:
172  pSet(new RAPOperator(*Rt.Ptr(), *A.Ptr(), *P.Ptr()));
173  break;
175  {
177  *P.As<SparseMatrix>()));
178  break;
179  }
180 #ifdef MFEM_USE_MPI
183  P.As<HypreParMatrix>()));
184  break;
185 #ifdef MFEM_USE_PETSC
188  {
190  P.As<PetscParMatrix>()));
191  break;
192  }
193 #endif
194 #endif
195  default: MFEM_ABORT(not_supported_msg << A.Type());
196  }
197 }
198 
200 {
201  if (own_oper) { delete oper; }
202  if (Type() == A.Type() || Type() == Operator::ANY_TYPE)
203  {
204  oper = A.Ptr();
205  own_oper = false;
206  return;
207  }
208  oper = NULL;
209  switch (Type()) // target type id
210  {
212  {
213  oper = A.Is<SparseMatrix>();
214  break;
215  }
217  {
218 #ifdef MFEM_USE_MPI
219  oper = A.Is<HypreParMatrix>();
220 #endif
221  break;
222  }
225  {
226  switch (A.Type()) // source type id
227  {
229 #ifdef MFEM_USE_PETSC
230  oper = new PetscParMatrix(A.As<HypreParMatrix>(), Type());
231 #endif
232  break;
233  default: break;
234  }
235 #ifdef MFEM_USE_PETSC
236  if (!oper)
237  {
238  PetscParMatrix *pA = A.Is<PetscParMatrix>();
239  if (pA->GetType() == Type()) { oper = pA; }
240  }
241 #endif
242  break;
243  }
244  default: break;
245  }
246  MFEM_VERIFY(oper != NULL, "conversion from type id = " << A.Type()
247  << " to type id = " << Type() << " is not supported");
248  own_oper = true;
249 }
250 
252  const Array<int> &ess_dof_list)
253 {
254  Clear();
255  switch (A.Type())
256  {
257  case Operator::ANY_TYPE:
258  {
259  bool own_A = A.OwnsOperator();
260  A.SetOperatorOwner(false);
261  A.Reset(new ConstrainedOperator(A.Ptr(), ess_dof_list, own_A));
262  // Keep this object empty - this will be OK if this object is only
263  // used as the A_e parameter in a call to A.EliminateBC().
264  break;
265  }
267  {
268  const Matrix::DiagonalPolicy preserve_diag = Matrix::DIAG_KEEP;
269  SparseMatrix *sA = A.As<SparseMatrix>();
270  SparseMatrix *Ae = new SparseMatrix(sA->Height());
271  for (int i = 0; i < ess_dof_list.Size(); i++)
272  {
273  sA->EliminateRowCol(ess_dof_list[i], *Ae, preserve_diag);
274  }
275  Ae->Finalize();
276  pSet(Ae);
277  break;
278  }
280  {
281 #ifdef MFEM_USE_MPI
282  pSet(A.As<HypreParMatrix>()->EliminateRowsCols(ess_dof_list));
283 #else
284  MFEM_ABORT("type id = Hypre_ParCSR requires MFEM_USE_MPI");
285 #endif
286  break;
287  }
290  {
291 #ifdef MFEM_USE_PETSC
292  pSet(A.As<PetscParMatrix>()->EliminateRowsCols(ess_dof_list));
293 #else
294  MFEM_ABORT("type id = Operator::PETSC_* requires MFEM_USE_PETSC");
295 #endif
296  break;
297  }
298  default: MFEM_ABORT(not_supported_msg << A.Type());
299  }
300 }
301 
303  const Array<int> &ess_dof_list,
304  const Vector &X, Vector &B) const
305 {
306  switch (Type())
307  {
308  case Operator::ANY_TYPE:
309  {
310  ConstrainedOperator *A = Is<ConstrainedOperator>();
311  MFEM_VERIFY(A != NULL, "EliminateRowsCols() is not called");
312  A->EliminateRHS(X, B);
313  break;
314  }
316  {
317  A_e.As<SparseMatrix>()->AddMult(X, B, -1.);
318  As<SparseMatrix>()->PartMult(ess_dof_list, X, B);
319  break;
320  }
322  {
323 #ifdef MFEM_USE_MPI
324  mfem::EliminateBC(*As<HypreParMatrix>(), *A_e.As<HypreParMatrix>(),
325  ess_dof_list, X, B);
326 #else
327  MFEM_ABORT("type id = Hypre_ParCSR requires MFEM_USE_MPI");
328 #endif
329  break;
330  }
333  {
334 #ifdef MFEM_USE_PETSC
335  mfem::EliminateBC(*As<PetscParMatrix>(), *A_e.As<PetscParMatrix>(),
336  ess_dof_list, X, B);
337 #else
338  MFEM_ABORT("type id = Operator::PETSC_* requires MFEM_USE_PETSC");
339 #endif
340  break;
341  }
342  default: MFEM_ABORT(not_supported_msg << Type());
343  }
344 }
345 
346 } // namespace mfem
int Size() const
Logical size of the array.
Definition: array.hpp:133
void EliminateRowsCols(const Array< int > &rows_cols, const HypreParVector &X, HypreParVector &B)
Definition: hypre.cpp:1368
void ConvertFrom(OperatorHandle &A)
Convert the given OperatorHandle A to the currently set type id.
Definition: handle.cpp:199
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
Definition: handle.hpp:90
HypreParMatrix * RAP(const HypreParMatrix *A, const HypreParMatrix *P)
Returns the matrix P^t * A * P.
Definition: hypre.cpp:1558
Wrapper for PETSc&#39;s matrix class.
Definition: petsc.hpp:133
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:478
Pointer to an Operator of a specified type.
Definition: handle.hpp:33
Operator::Type Type() const
Get the currently set operator type id.
Definition: handle.hpp:85
void EliminateBC(const OperatorHandle &A_e, const Array< int > &ess_dof_list, const Vector &X, Vector &B) const
Eliminate essential dofs from the solution X into the r.h.s. B.
Definition: handle.cpp:302
Type GetType() const
Definition: petsc.cpp:1260
Operator * oper
Definition: handle.hpp:38
static const char not_supported_msg[]
Definition: handle.hpp:36
void EliminateBC(HypreParMatrix &A, HypreParMatrix &Ae, const Array< int > &ess_dof_list, const Vector &X, Vector &B)
Definition: hypre.cpp:1612
ID for class SparseMatrix.
Definition: operator.hpp:127
ID for the base class Operator, i.e. any type.
Definition: operator.hpp:126
OpType * Is() const
Return the Operator pointer dynamically cast to a specified OpType.
Definition: handle.hpp:94
Keep the diagonal value.
Definition: matrix.hpp:36
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
Definition: densemat.cpp:3010
Data type sparse matrix.
Definition: sparsemat.hpp:38
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:36
void EliminateRowsCols(OperatorHandle &A, const Array< int > &ess_dof_list)
Reset the OperatorHandle to be the eliminated part of A after elimination of the essential dofs ess_d...
Definition: handle.cpp:251
Operator::Type CheckType(Operator::Type tid)
Definition: handle.cpp:32
void EliminateRowsCols(const Array< int > &rows_cols, const PetscParVector &X, PetscParVector &B)
Eliminate rows and columns from the matrix, and rows from the vector B. Modify B with the BC values i...
Definition: petsc.cpp:1219
void Transpose(const Table &A, Table &At, int _ncols_A)
Transpose a Table.
Definition: table.cpp:418
The operator x -&gt; R*A*P*x constructed through the actions of R^T, A and P.
Definition: operator.hpp:349
Operator * Ptr() const
Access the underlying Operator pointer.
Definition: handle.hpp:82
Type
Enumeration defining IDs for some classes derived from Operator.
Definition: operator.hpp:124
bool OwnsOperator() const
Return true if the OperatorHandle owns the held Operator.
Definition: handle.hpp:103
void EliminateRowCol(int rc, const double sol, Vector &rhs, DiagonalPolicy dpolicy=DIAG_ONE)
Eliminate row rc and column rc and modify the rhs using sol.
Definition: sparsemat.cpp:1204
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged...
Definition: handle.hpp:110
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
Definition: handle.hpp:106
void MakeSquareBlockDiag(MPI_Comm comm, HYPRE_Int glob_size, HYPRE_Int *row_starts, SparseMatrix *diag)
Reset the OperatorHandle to hold a parallel square block-diagonal matrix using the currently set type...
Definition: handle.cpp:60
void pSet(OpType *A, bool own_A=true)
Definition: handle.hpp:45
void EliminateRHS(const Vector &x, Vector &b) const
Eliminate &quot;essential boundary condition&quot; values specified in x from the given right-hand side b...
Definition: operator.cpp:163
Operator::Type type_id
Definition: handle.hpp:39
ID for class PetscParMatrix, MATAIJ format.
Definition: operator.hpp:129
void MakeRectangularBlockDiag(MPI_Comm comm, HYPRE_Int glob_num_rows, HYPRE_Int glob_num_cols, HYPRE_Int *row_starts, HYPRE_Int *col_starts, SparseMatrix *diag)
Reset the OperatorHandle to hold a parallel rectangular block-diagonal matrix using the currently set...
Definition: handle.cpp:90
Vector data type.
Definition: vector.hpp:48
ID for class HypreParMatrix.
Definition: operator.hpp:128
Square Operator for imposing essential boundary conditions using only the action, Mult()...
Definition: operator.hpp:401
Wrapper for hypre&#39;s ParCSR matrix class.
Definition: hypre.hpp:175
ID for class PetscParMatrix, MATIS format.
Definition: operator.hpp:130
void MakePtAP(OperatorHandle &A, OperatorHandle &P)
Reset the OperatorHandle to hold the product P^t A P.
Definition: handle.cpp:122
void MakeRAP(OperatorHandle &Rt, OperatorHandle &A, OperatorHandle &P)
Reset the OperatorHandle to hold the product R A P, where R = Rt^t.
Definition: handle.cpp:160
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
Definition: handle.hpp:131