MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
handle.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
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(HYPRE_MIXEDINT)) && !defined(PETSC_USE_64BIT_INDICES)) || \
21 (!defined(HYPRE_BIGINT) && !defined(HYPRE_MIXEDINT) && defined(PETSC_USE_64BIT_INDICES))
22#error HYPRE and PETSC do not use the same size integers!
23#endif
24#endif
25
26namespace 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
48#ifdef MFEM_USE_PETSC
49 break;
50#else
51 MFEM_ABORT("cannot use PETSc matrix formats: "
52 "MFEM is not built with PETSc support");
53#endif
54 default:
55 MFEM_ABORT("invalid Operator::Type, type_id = " << (int)type_id);
56 }
57 return tid;
58}
59
60#ifdef MFEM_USE_MPI
62 HYPRE_BigInt *row_starts,
63 SparseMatrix *diag)
64{
65 if (own_oper) { delete oper; }
66
67 switch (type_id)
68 {
69 case Operator::ANY_TYPE: // --> MFEM_SPARSEMAT
71 // As a parallel Operator, the SparseMatrix simply represents the local
72 // Operator, without the need of any communication.
73 pSet(diag, false);
74 return;
76 oper = new HypreParMatrix(comm, glob_size, row_starts, diag);
77 break;
78#ifdef MFEM_USE_PETSC
81 // Assuming that PetscInt is the same size as HYPRE_Int, checked above.
82 oper = new PetscParMatrix(comm, glob_size, (PetscInt*)row_starts, diag,
83 type_id);
84 break;
85#endif
86 default: MFEM_ABORT(not_supported_msg << type_id);
87 }
88 own_oper = true;
89}
90
92MakeRectangularBlockDiag(MPI_Comm comm, HYPRE_BigInt glob_num_rows,
93 HYPRE_BigInt glob_num_cols, HYPRE_BigInt *row_starts,
94 HYPRE_BigInt *col_starts, SparseMatrix *diag)
95{
96 if (own_oper) { delete oper; }
97
98 switch (type_id)
99 {
100 case Operator::ANY_TYPE: // --> MFEM_SPARSEMAT
102 // As a parallel Operator, the SparseMatrix simply represents the local
103 // Operator, without the need of any communication.
104 pSet(diag, false);
105 return;
107 oper = new HypreParMatrix(comm, glob_num_rows, glob_num_cols,
108 row_starts, col_starts, diag);
109 break;
110#ifdef MFEM_USE_PETSC
113 // Assuming that PetscInt is the same size as HYPRE_Int, checked above.
114 oper = new PetscParMatrix(comm, glob_num_rows, glob_num_cols,
115 (PetscInt*)row_starts, (PetscInt*)col_starts, diag, type_id);
116 break;
117#endif
118 default: MFEM_ABORT(not_supported_msg << type_id);
119 }
120 own_oper = true;
121}
122#endif // MFEM_USE_MPI
123
125{
126 if (A.Type() != Operator::ANY_TYPE)
127 {
128 MFEM_VERIFY(A.Type() == P.Type(), "type mismatch in A and P");
129 }
130 Clear();
131 switch (A.Type())
132 {
134 pSet(new RAPOperator(*P.Ptr(), *A.Ptr(), *P.Ptr()));
135 break;
137 {
139 SparseMatrix *RA = mfem::Mult(*R, *A.As<SparseMatrix>());
140 delete R;
141 pSet(mfem::Mult(*RA, *P.As<SparseMatrix>()));
142 delete RA;
143 break;
144 }
145#ifdef MFEM_USE_MPI
148 break;
149#ifdef MFEM_USE_PETSC
153 {
155 break;
156 }
157#endif
158#endif
159 default: MFEM_ABORT(not_supported_msg << A.Type());
160 }
161}
162
165{
166 if (A.Type() != Operator::ANY_TYPE)
167 {
168 MFEM_VERIFY(A.Type() == Rt.Type(), "type mismatch in A and Rt");
169 MFEM_VERIFY(A.Type() == P.Type(), "type mismatch in A and P");
170 }
171 Clear();
172 switch (A.Type())
173 {
175 pSet(new RAPOperator(*Rt.Ptr(), *A.Ptr(), *P.Ptr()));
176 break;
178 {
180 *P.As<SparseMatrix>()));
181 break;
182 }
183#ifdef MFEM_USE_MPI
186 P.As<HypreParMatrix>()));
187 break;
188#ifdef MFEM_USE_PETSC
192 {
194 P.As<PetscParMatrix>()));
195 break;
196 }
197#endif
198#endif
199 default: MFEM_ABORT(not_supported_msg << A.Type());
200 }
201}
202
204{
205 if (own_oper) { delete oper; }
206 if (Type() == A.Type() || Type() == Operator::ANY_TYPE)
207 {
208 oper = A.Ptr();
209 own_oper = false;
210 return;
211 }
212 oper = NULL;
213 switch (Type()) // target type id
214 {
216 {
217 oper = A.Is<SparseMatrix>();
218 break;
219 }
221 {
222#ifdef MFEM_USE_MPI
223 oper = A.Is<HypreParMatrix>();
224#endif
225 break;
226 }
229 {
230 switch (A.Type()) // source type id
231 {
233#ifdef MFEM_USE_PETSC
235#endif
236 break;
237 default: break;
238 }
239#ifdef MFEM_USE_PETSC
240 if (!oper)
241 {
243 if (pA->GetType() == Type()) { oper = pA; }
244 }
245#endif
246 break;
247 }
248 default: break;
249 }
250 MFEM_VERIFY(oper != NULL, "conversion from type id = " << A.Type()
251 << " to type id = " << Type() << " is not supported");
252 own_oper = true;
253}
254
256 const Array<int> &ess_dof_list)
257{
258 Clear();
259 switch (A.Type())
260 {
262 {
263 bool own_A = A.OwnsOperator();
264 A.SetOperatorOwner(false);
265 A.Reset(new ConstrainedOperator(A.Ptr(), ess_dof_list, own_A));
266 // Keep this object empty - this will be OK if this object is only
267 // used as the A_e parameter in a call to A.EliminateBC().
268 break;
269 }
271 {
272 const Matrix::DiagonalPolicy preserve_diag = Matrix::DIAG_KEEP;
273 SparseMatrix *sA = A.As<SparseMatrix>();
274 SparseMatrix *Ae = new SparseMatrix(sA->Height());
275 for (int i = 0; i < ess_dof_list.Size(); i++)
276 {
277 sA->EliminateRowCol(ess_dof_list[i], *Ae, preserve_diag);
278 }
279 Ae->Finalize();
280 pSet(Ae);
281 break;
282 }
284 {
285#ifdef MFEM_USE_MPI
286 pSet(A.As<HypreParMatrix>()->EliminateRowsCols(ess_dof_list));
287#else
288 MFEM_ABORT("type id = Hypre_ParCSR requires MFEM_USE_MPI");
289#endif
290 break;
291 }
295 {
296#ifdef MFEM_USE_PETSC
297 pSet(A.As<PetscParMatrix>()->EliminateRowsCols(ess_dof_list));
298#else
299 MFEM_ABORT("type id = Operator::PETSC_* requires MFEM_USE_PETSC");
300#endif
301 break;
302 }
303 default: MFEM_ABORT(not_supported_msg << A.Type());
304 }
305}
306
308{
309 switch (Type())
310 {
312 {
313#ifdef MFEM_USE_MPI
314 this->As<HypreParMatrix>()->EliminateRows(ess_dof_list);
315#else
316 MFEM_ABORT("type id = Hypre_ParCSR requires MFEM_USE_MPI");
317#endif
318 break;
319 }
320 default:
321 MFEM_ABORT(not_supported_msg << Type());
322 }
323}
324
326{
327 switch (Type())
328 {
330 {
331#ifdef MFEM_USE_MPI
332 auto Ae = this->As<HypreParMatrix>()->EliminateCols(ess_dof_list);
333 delete Ae;
334#else
335 MFEM_ABORT("type id = Hypre_ParCSR requires MFEM_USE_MPI");
336#endif
337 break;
338 }
339 default:
340 MFEM_ABORT(not_supported_msg << Type());
341 }
342}
343
345 const Array<int> &ess_dof_list,
346 const Vector &X, Vector &B) const
347{
348 switch (Type())
349 {
351 {
353 MFEM_VERIFY(A != NULL, "EliminateRowsCols() is not called");
354 A->EliminateRHS(X, B);
355 break;
356 }
358 {
359 A_e.As<SparseMatrix>()->AddMult(X, B, -1.);
360 As<SparseMatrix>()->PartMult(ess_dof_list, X, B);
361 break;
362 }
364 {
365#ifdef MFEM_USE_MPI
367 ess_dof_list, X, B);
368#else
369 MFEM_ABORT("type id = Hypre_ParCSR requires MFEM_USE_MPI");
370#endif
371 break;
372 }
376 {
377#ifdef MFEM_USE_PETSC
379 ess_dof_list, X, B);
380#else
381 MFEM_ABORT("type id = Operator::PETSC_* requires MFEM_USE_PETSC");
382#endif
383 break;
384 }
385 default: MFEM_ABORT(not_supported_msg << Type());
386 }
387}
388
389} // namespace mfem
int Size() const
Return the logical size of the array.
Definition array.hpp:147
Square Operator for imposing essential boundary conditions using only the action, Mult(),...
Definition operator.hpp:992
void EliminateRHS(const Vector &x, Vector &b) const
Eliminate "essential boundary condition" values specified in x from the given right-hand side b.
Definition operator.cpp:559
Wrapper for hypre's ParCSR matrix class.
Definition hypre.hpp:408
void EliminateRowsCols(const Array< int > &rows_cols, const HypreParVector &X, HypreParVector &B)
Definition hypre.cpp:2397
Pointer to an Operator of a specified type.
Definition handle.hpp:34
Operator::Type type_id
Definition handle.hpp:39
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get().
Definition handle.hpp:104
void pSet(OpType *A, bool own_A=true)
Definition handle.hpp:45
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:255
bool OwnsOperator() const
Return true if the OperatorHandle owns the held Operator.
Definition handle.hpp:117
void EliminateRows(const Array< int > &ess_dof_list)
Eliminate the rows corresponding to the essential dofs ess_dof_list.
Definition handle.cpp:307
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
Definition handle.hpp:120
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:163
void ConvertFrom(OperatorHandle &A)
Convert the given OperatorHandle A to the currently set type id.
Definition handle.cpp:203
void EliminateCols(const Array< int > &ess_dof_list)
Eliminate columns corresponding to the essential dofs ess_dof_list.
Definition handle.cpp:325
void MakePtAP(OperatorHandle &A, OperatorHandle &P)
Reset the OperatorHandle to hold the product P^t A P.
Definition handle.cpp:124
void MakeSquareBlockDiag(MPI_Comm comm, HYPRE_BigInt glob_size, HYPRE_BigInt *row_starts, SparseMatrix *diag)
Reset the OperatorHandle to hold a parallel square block-diagonal matrix using the currently set type...
Definition handle.cpp:61
Operator::Type CheckType(Operator::Type tid)
Definition handle.cpp:32
static const char not_supported_msg[]
Definition handle.hpp:36
Operator * Ptr() const
Access the underlying Operator pointer.
Definition handle.hpp:87
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged.
Definition handle.hpp:124
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
Definition handle.hpp:145
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:344
OpType * Is() const
Return the Operator pointer dynamically cast to a specified OpType.
Definition handle.hpp:108
Operator::Type Type() const
Get the currently set operator type id.
Definition handle.hpp:99
Operator * oper
Definition handle.hpp:38
void MakeRectangularBlockDiag(MPI_Comm comm, HYPRE_BigInt glob_num_rows, HYPRE_BigInt glob_num_cols, HYPRE_BigInt *row_starts, HYPRE_BigInt *col_starts, SparseMatrix *diag)
Reset the OperatorHandle to hold a parallel rectangular block-diagonal matrix using the currently set...
Definition handle.cpp:92
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:66
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
Definition operator.hpp:48
@ DIAG_KEEP
Keep the diagonal value.
Definition operator.hpp:51
Type
Enumeration defining IDs for some classes derived from Operator.
Definition operator.hpp:284
@ ANY_TYPE
ID for the base class Operator, i.e. any type.
Definition operator.hpp:285
@ MFEM_SPARSEMAT
ID for class SparseMatrix.
Definition operator.hpp:286
@ PETSC_MATIS
ID for class PetscParMatrix, MATIS format.
Definition operator.hpp:289
@ Hypre_ParCSR
ID for class HypreParMatrix.
Definition operator.hpp:287
@ PETSC_MATGENERIC
ID for class PetscParMatrix, unspecified format.
Definition operator.hpp:293
@ PETSC_MATAIJ
ID for class PetscParMatrix, MATAIJ format.
Definition operator.hpp:288
Wrapper for PETSc's matrix class.
Definition petsc.hpp:319
void EliminateRowsCols(const Array< int > &rows_cols, const PetscParVector &X, PetscParVector &B, real_t 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:2271
Type GetType() const
Definition petsc.cpp:2327
The operator x -> R*A*P*x constructed through the actions of R^T, A and P.
Definition operator.hpp:914
Data type sparse matrix.
Definition sparsemat.hpp:51
void EliminateRowCol(int rc, const real_t sol, Vector &rhs, DiagonalPolicy dpolicy=DIAG_ONE)
Eliminate row rc and column rc and modify the rhs using sol.
Vector data type.
Definition vector.hpp:82
HYPRE_Int HYPRE_BigInt
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition table.cpp:548
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
Definition table.cpp:486
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
void EliminateBC(const HypreParMatrix &A, const HypreParMatrix &Ae, const Array< int > &ess_dof_list, const Vector &X, Vector &B)
Eliminate essential BC specified by ess_dof_list from the solution X to the r.h.s....
Definition hypre.cpp:3437
HYPRE_Int PetscInt
Definition petsc.hpp:50