MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
hybridization.hpp
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#ifndef MFEM_HYBRIDIZATION
13#define MFEM_HYBRIDIZATION
14
15#include "../config/config.hpp"
16#include "fespace.hpp"
17#include "bilininteg.hpp"
18#include <memory>
19
20namespace mfem
21{
22
23/** @brief Auxiliary class Hybridization, used to implement BilinearForm
24 hybridization.
25
26 Hybridization can be viewed as a technique for solving linear systems
27 obtained through finite element assembly. The assembled matrix $ A $ can
28 be written as:
29 $$ A = P^T \hat{A} P, $$
30 where $ P $ is the matrix mapping the conforming finite element space to
31 the purely local finite element space without any inter-element constraints
32 imposed, and $ \hat{A} $ is the block-diagonal matrix of all element
33 matrices.
34
35 We assume that:
36 - $ \hat{A} $ is invertible,
37 - $ P $ has a left inverse $ R $, such that $ R P = I $,
38 - a constraint matrix $ C $ can be constructed, such that
39 $ \operatorname{Ker}(C) = \operatorname{Im}(P) $.
40
41 Under these conditions, the linear system $ A x = b $ can be solved
42 using the following procedure:
43 - solve for $ \lambda $ in the linear system:
44 $$ (C \hat{A}^{-1} C^T) \lambda = C \hat{A}^{-1} R^T b $$
45 - compute $ x = R \hat{A}^{-1} (R^T b - C^T \lambda) $
46
47 Hybridization is advantageous when the matrix
48 $ H = (C \hat{A}^{-1} C^T) $ of the hybridized system is either smaller
49 than the original system, or is simpler to invert with a known method.
50
51 In some cases, e.g. high-order elements, the matrix $ C $ can be written
52 as
53 $$ C = \begin{pmatrix} 0 & C_b \end{pmatrix}, $$
54 and then the hybridized matrix $ H $ can be assembled using the identity
55 $$ H = C_b S_b^{-1} C_b^T, $$
56 where $ S_b $ is the Schur complement of $ \hat{A} $ with respect to
57 the same decomposition as the columns of $ C $:
58 $$ S_b = \hat{A}_b - \hat{A}_{bf} \hat{A}_{f}^{-1} \hat{A}_{fb}. $$
59
60 Hybridization can also be viewed as a discretization method for imposing
61 (weak) continuity constraints between neighboring elements. */
63{
65protected:
66 FiniteElementSpace &fes; ///< The finite element space.
67 FiniteElementSpace &c_fes; ///< The constraint finite element space.
68 /// Extension for device execution.
69 std::unique_ptr<class HybridizationExtension> ext;
70 /// The constraint integrator.
71 std::unique_ptr<BilinearFormIntegrator> c_bfi;
72 /// The constraint boundary face integrators
73 std::vector<BilinearFormIntegrator*> boundary_constraint_integs;
74 /// Boundary markers for constraint face integrators
75 std::vector<Array<int>*> boundary_constraint_integs_marker;
76 /// Indicates if the boundary_constraint_integs integrators are owned externally
78
79 /// The constraint matrix.
80 std::unique_ptr<SparseMatrix> Ct;
81 /// The Schur complement system for the Lagrange multiplier.
82 std::unique_ptr<SparseMatrix> H;
83
88
89#ifdef MFEM_USE_MPI
90 std::unique_ptr<HypreParMatrix> pC, P_pc; // for parallel non-conforming meshes
92#endif
93
94 /// Construct the constraint matrix.
95 void ConstructC();
96
97 /// Returns the local indices of the i-dofs and b-dofs of element @a el.
98 void GetIBDofs(int el, Array<int> &i_dofs, Array<int> &b_dofs) const;
99
100 /// Returns global indices of the b-dofs of element @a el.
101 void GetBDofs(int el, int &num_idofs, Array<int> &b_dofs) const;
102
103 /// Construct the Schur complement system.
104 void ComputeH();
105
106 // Compute depending on mode:
107 // - mode 0: bf = Af^{-1} Rf^t b, where
108 // the non-"boundary" part of bf is set to 0;
109 // - mode 1: bf = Af^{-1} ( Rf^t b - Cf^t lambda ), where
110 // the "essential" part of bf is set to 0.
111 // Input: size(b) = fes->GetConformingVSize()
112 // size(lambda) = c_fes->GetConformingVSize()
113 void MultAfInv(const Vector &b, const Vector &lambda, Vector &bf,
114 int mode) const;
115
116public:
117 /// Constructor.
119
120 /// Destructor.
122
123 /// Turns on device execution.
125
126 /// @brief Set the integrator that will be used to construct the constraint
127 /// matrix C.
128 ///
129 /// The Hybridization object assumes ownership of the integrator, i.e. it
130 /// will delete the integrator when destroyed.
132 { c_bfi.reset(c_integ); }
133
134 /** Add the boundary face integrator that will be used to construct the
135 constraint matrix C. The Hybridization object assumes ownership of the
136 integrator, i.e. it will delete the integrator when destroyed. */
138 {
139 boundary_constraint_integs.push_back(c_integ);
140 boundary_constraint_integs_marker.push_back(nullptr);
141 }
143 Array<int> &bdr_marker)
144 {
145 boundary_constraint_integs.push_back(c_integ);
146 boundary_constraint_integs_marker.push_back(&bdr_marker);
147 }
148
149 /// Access all integrators added with AddBdrConstraintIntegrator().
152
153 /// Access all boundary markers added with AddBdrConstraintIntegrator().
154 /** If no marker was specified when the integrator was added, the
155 corresponding pointer (to Array<int>) will be NULL. */
158
159 /// Indicate that boundary constraint integrators are not owned
161
162 /// Prepare the Hybridization object for assembly.
163 void Init(const Array<int> &ess_tdof_list);
164
165 /// Assemble the element matrix A into the hybridized system matrix.
166 void AssembleMatrix(int el, const DenseMatrix &A);
167
168 /// Assemble all of the element matrices given in the form of a DenseTensor.
169 void AssembleElementMatrices(const class DenseTensor &el_mats);
170
171 /// Assemble the boundary element matrix A into the hybridized system matrix.
172 void AssembleBdrMatrix(int bdr_el, const DenseMatrix &A);
173
174 /// Finalize the construction of the hybridized matrix.
175 void Finalize();
176
177 /// Return the serial hybridized matrix.
178 SparseMatrix &GetMatrix() { return *H; }
179
180#ifdef MFEM_USE_MPI
181 /// Return the parallel hybridized matrix.
183
184 /// @brief Return the parallel hybridized matrix in the format specified by
185 /// SetOperatorType().
186 void GetParallelMatrix(OperatorHandle &H_h) const { H_h = pH; }
187
188 /// Set the operator type id for the parallel hybridized matrix/operator.
190#endif
191
192 /// @brief Perform the reduction of the given right-hand side @a b to a
193 /// right-hand side vector @a b_r for the hybridized system.
194 void ReduceRHS(const Vector &b, Vector &b_r) const;
195
196 /// @brief Reconstruct the solution of the original system @a sol from
197 /// solution of the hybridized system @a sol_r and the original right-hand
198 /// side @a b.
199 ///
200 /// It is assumed that the vector sol has the correct essential boundary
201 /// conditions.
202 void ComputeSolution(const Vector &b, const Vector &sol_r,
203 Vector &sol) const;
204
205 /// @brief Destroy the current hybridization matrix while preserving the
206 /// computed constraint matrix and the set of essential true dofs.
207 ///
208 /// After Reset(), a new hybridized matrix can be assembled via
209 /// AssembleMatrix() and Finalize(). The Mesh and FiniteElementSpace objects
210 /// are assumed to be unmodified. If that is not the case, a new
211 /// Hybridization object must be created.
212 void Reset();
213};
214
215}
216
217#endif
Abstract base class BilinearFormIntegrator.
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
Rank 3 tensor (array of matrices)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:244
Extension class supporting Hybridization on device (GPU).
Auxiliary class Hybridization, used to implement BilinearForm hybridization.
void Reset()
Destroy the current hybridization matrix while preserving the computed constraint matrix and the set ...
Array< int > hat_offsets
void AssembleElementMatrices(const class DenseTensor &el_mats)
Assemble all of the element matrices given in the form of a DenseTensor.
~Hybridization()
Destructor.
void Init(const Array< int > &ess_tdof_list)
Prepare the Hybridization object for assembly.
std::unique_ptr< HypreParMatrix > pC
SparseMatrix & GetMatrix()
Return the serial hybridized matrix.
void UseExternalBdrConstraintIntegrators()
Indicate that boundary constraint integrators are not owned.
void EnableDeviceExecution()
Turns on device execution.
FiniteElementSpace & c_fes
std::vector< BilinearFormIntegrator * > boundary_constraint_integs
The constraint boundary face integrators.
void AssembleBdrMatrix(int bdr_el, const DenseMatrix &A)
Assemble the boundary element matrix A into the hybridized system matrix.
Array< int > * GetBdrConstraintIntegratorMarker(int i)
Access all boundary markers added with AddBdrConstraintIntegrator().
bool extern_bdr_constr_integs
Indicates if the boundary_constraint_integs integrators are owned externally.
void SetOperatorType(Operator::Type tid)
Set the operator type id for the parallel hybridized matrix/operator.
std::unique_ptr< SparseMatrix > Ct
The constraint matrix.
void AssembleMatrix(int el, const DenseMatrix &A)
Assemble the element matrix A into the hybridized system matrix.
void MultAfInv(const Vector &b, const Vector &lambda, Vector &bf, int mode) const
std::unique_ptr< HypreParMatrix > P_pc
std::unique_ptr< SparseMatrix > H
The Schur complement system for the Lagrange multiplier.
void GetIBDofs(int el, Array< int > &i_dofs, Array< int > &b_dofs) const
Returns the local indices of the i-dofs and b-dofs of element el.
BilinearFormIntegrator & GetBdrConstraintIntegrator(int i)
Access all integrators added with AddBdrConstraintIntegrator().
void AddBdrConstraintIntegrator(BilinearFormIntegrator *c_integ)
void ComputeH()
Construct the Schur complement system.
std::unique_ptr< class HybridizationExtension > ext
Extension for device execution.
Array< int > hat_dofs_marker
void ComputeSolution(const Vector &b, const Vector &sol_r, Vector &sol) const
Reconstruct the solution of the original system sol from solution of the hybridized system sol_r and ...
Array< int > Af_f_offsets
FiniteElementSpace & fes
The finite element space.
Array< int > Af_offsets
void Finalize()
Finalize the construction of the hybridized matrix.
void AddBdrConstraintIntegrator(BilinearFormIntegrator *c_integ, Array< int > &bdr_marker)
Hybridization(FiniteElementSpace *fespace, FiniteElementSpace *c_fespace)
Constructor.
HypreParMatrix & GetParallelMatrix()
Return the parallel hybridized matrix.
std::vector< Array< int > * > boundary_constraint_integs_marker
Boundary markers for constraint face integrators.
void GetParallelMatrix(OperatorHandle &H_h) const
Return the parallel hybridized matrix in the format specified by SetOperatorType().
void GetBDofs(int el, int &num_idofs, Array< int > &b_dofs) const
Returns global indices of the b-dofs of element el.
void ConstructC()
Construct the constraint matrix.
Array< real_t > Af_data
std::unique_ptr< BilinearFormIntegrator > c_bfi
The constraint integrator.
void ReduceRHS(const Vector &b, Vector &b_r) const
Perform the reduction of the given right-hand side b to a right-hand side vector b_r for the hybridiz...
void SetConstraintIntegrator(BilinearFormIntegrator *c_integ)
Set the integrator that will be used to construct the constraint matrix C.
Wrapper for hypre's ParCSR matrix class.
Definition hypre.hpp:408
Pointer to an Operator of a specified type.
Definition handle.hpp:34
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.
Definition handle.hpp:132
OpType * Is() const
Return the Operator pointer dynamically cast to a specified OpType.
Definition handle.hpp:108
Type
Enumeration defining IDs for some classes derived from Operator.
Definition operator.hpp:284
Data type sparse matrix.
Definition sparsemat.hpp:51
Vector data type.
Definition vector.hpp:82
real_t b
Definition lissajous.cpp:42