MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
lor.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, 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_LOR
13#define MFEM_LOR
14
15#include "../bilinearform.hpp"
16
17namespace mfem
18{
19
20/// @brief Abstract base class for LORDiscretization and ParLORDiscretization
21/// classes, which construct low-order refined versions of bilinear forms.
23{
24private:
25 using GetIntegratorsFn = Array<BilinearFormIntegrator*> *(BilinearForm::*)();
26 using GetMarkersFn = Array<Array<int>*> *(BilinearForm::*)();
27 using AddIntegratorFn = void (BilinearForm::*)(BilinearFormIntegrator*);
28 using AddIntegratorMarkersFn =
30
32 const IntegrationRule *ir_el, *ir_face;
33 std::map<BilinearFormIntegrator*, const IntegrationRule*> ir_map;
34
35 /// Adds all the integrators from the BilinearForm @a a_from to @a a_to. If
36 /// the mesh consists of tensor product elements, temporarily changes the
37 /// integration rules of the integrators to use collocated quadrature for
38 /// better conditioning of the LOR system.
39 void AddIntegrators(BilinearForm &a_from,
40 BilinearForm &a_to,
41 GetIntegratorsFn get_integrators,
42 AddIntegratorFn add_integrator,
43 const IntegrationRule *ir);
44
45 /// Adds all the integrators from the BilinearForm @a a_from to @a a_to,
46 /// using the same marker lists (e.g. for integrators only applied to
47 /// certain boundary attributes). @sa LORBase::AddIntegrators
48 void AddIntegratorsAndMarkers(BilinearForm &a_from,
49 BilinearForm &a_to,
50 GetIntegratorsFn get_integrators,
51 GetMarkersFn get_markers,
52 AddIntegratorMarkersFn add_integrator_marker,
53 AddIntegratorFn add_integrator,
54 const IntegrationRule *ir);
55
56 /// Resets the integration rules of the integrators of @a a to their original
57 /// values (after temporarily changing them for LOR assembly).
58 void ResetIntegrationRules(GetIntegratorsFn get_integrators);
59
60protected:
61 enum FESpaceType { H1, ND, RT, L2, INVALID };
62
65 Mesh *mesh = nullptr;
68 BilinearForm *a = nullptr;
72
73 /// Constructs the local DOF (ldof) permutation. In parallel this is used as
74 /// an intermediate step in computing the DOF permutation (see
75 /// ConstructDofPermutation and GetDofPermutation).
77
78 /// Construct the permutation that maps LOR DOFs to high-order DOFs. See
79 /// GetDofPermutation.
80 void ConstructDofPermutation() const;
81
82 /// Returns true if the LOR space and HO space have the same DOF numbering
83 /// (H1 or L2 spaces), false otherwise (ND or RT spaces).
84 bool HasSameDofNumbering() const;
85
86 /// Sets up the prolongation and restriction operators required in the case
87 /// of different DOF numberings (ND or RT spaces) or nonconforming spaces.
89
90 /// Returns the type of finite element space: H1, ND, RT or L2.
92
93 /// Returns the order of the LOR space. 1 for H1 or ND, 0 for L2 or RT.
94 int GetLOROrder() const;
95
96 /// Construct the LOR space (overridden for serial and parallel versions).
97 virtual void FormLORSpace() = 0;
98
99 /// Construct the LORBase object for the given FE space and refinement type.
100 LORBase(FiniteElementSpace &fes_ho_, int ref_type_);
101
102public:
103 /// Returns the assembled LOR system (const version).
104 const OperatorHandle &GetAssembledSystem() const;
105
106 /// Returns the assembled LOR system (non-const version).
108
109 /// Assembles the LOR system corresponding to @a a_ho.
110 void AssembleSystem(BilinearForm &a_ho, const Array<int> &ess_dofs);
111
112 /// Assembles the LOR system corresponding to @a a_ho using the legacy method.
113 void LegacyAssembleSystem(BilinearForm &a_ho, const Array<int> &ess_dofs);
114
115 /// @brief Returns the permutation that maps LOR DOFs to high-order DOFs.
116 ///
117 /// This permutation is constructed the first time it is requested, and then
118 /// is cached. For H1 and L2 finite element spaces (or for nonconforming
119 /// spaces) this is the identity. In these cases, RequiresDofPermutation will
120 /// return false. However, if the DOF permutation is requested, an identity
121 /// permutation will be built and returned.
122 ///
123 /// For vector finite element spaces (ND and RT), the DOF permutation is
124 /// nontrivial. Returns an array @a perm such that, given an index @a i of a
125 /// LOR dof, @a perm[i] is the index of the corresponding HO dof.
126 const Array<int> &GetDofPermutation() const;
127
128 /// Returns the low-order refined finite element space.
130
131 virtual ~LORBase();
132};
133
134/// Create and assemble a low-order refined version of a BilinearForm.
136{
137protected:
138 void FormLORSpace() override;
139public:
140 /// @brief Construct the low-order refined version of @a a_ho using the given
141 /// list of essential DOFs.
142 ///
143 /// The mesh is refined using the refinement type specified by @a ref_type
144 /// (see Mesh::MakeRefined).
147
148 /// @brief Construct a low-order refined version of the FiniteElementSpace @a
149 /// fes_ho.
150 ///
151 /// The mesh is refined using the refinement type specified by @a ref_type
152 /// (see Mesh::MakeRefined).
155
156 /// Return the assembled LOR operator as a SparseMatrix.
158};
159
160#ifdef MFEM_USE_MPI
161
162/// Create and assemble a low-order refined version of a ParBilinearForm.
164{
165protected:
166 void FormLORSpace() override;
167public:
168 /// @brief Construct the low-order refined version of @a a_ho using the given
169 /// list of essential DOFs.
170 ///
171 /// The mesh is refined using the refinement type specified by @a ref_type
172 /// (see ParMesh::MakeRefined).
175
176 /// @brief Construct a low-order refined version of the ParFiniteElementSpace
177 /// @a fes_ho.
178 ///
179 /// The mesh is refined using the refinement type specified by @a ref_type
180 /// (see ParMesh::MakeRefined).
183
184 /// Return the assembled LOR operator as a HypreParMatrix.
186
187 /// Return the LOR ParFiniteElementSpace.
189};
190
191#endif
192
193/// @brief Represents a solver of type @a SolverType created using the low-order
194/// refined version of the given BilinearForm or ParBilinearForm.
195///
196/// @note To achieve good solver performance, the high-order finite element
197/// space should use BasisType::GaussLobatto for H1 discretizations, and basis
198/// pair (BasisType::GaussLobatto, BasisType::IntegratedGLL) for Nedelec and
199/// Raviart-Thomas elements.
200template <typename SolverType>
201class LORSolver : public Solver
202{
203protected:
205 bool own_lor = true;
206 SolverType solver;
207public:
208 /// @brief Create a solver of type @a SolverType, formed using the assembled
209 /// SparseMatrix of the LOR version of @a a_ho. @see LORDiscretization
211 int ref_type=BasisType::GaussLobatto)
212 {
213 lor = new LORDiscretization(a_ho, ess_tdof_list, ref_type);
215 }
216
217#ifdef MFEM_USE_MPI
218 /// @brief Create a solver of type @a SolverType, formed using the assembled
219 /// HypreParMatrix of the LOR version of @a a_ho. @see ParLORDiscretization
221 int ref_type=BasisType::GaussLobatto)
222 {
223 lor = new ParLORDiscretization(a_ho, ess_tdof_list, ref_type);
225 }
226#endif
227
228 /// @brief Create a solver of type @a SolverType using Operator @a op and
229 /// arguments @a args.
230 template <typename... Args>
231 LORSolver(const Operator &op, LORBase &lor_, Args&&... args) : solver(args...)
232 {
233 lor = &lor_;
234 own_lor = false;
235 SetOperator(op);
236 }
237
238 /// @brief Create a solver of type @a SolverType using the assembled LOR
239 /// operator represented by @a lor_.
240 ///
241 /// The given @a args will be used as arguments to the solver constructor.
242 template <typename... Args>
243 LORSolver(LORBase &lor_, Args&&... args)
244 : LORSolver(*lor_.GetAssembledSystem(), lor_, args...) { }
245
246 void SetOperator(const Operator &op)
247 {
248 solver.SetOperator(op);
249 width = solver.Width();
250 height = solver.Height();
251 }
252
253 void Mult(const Vector &x, Vector &y) const { solver.Mult(x, y); }
254
255 /// Access the underlying solver.
256 SolverType &GetSolver() { return solver; }
257
258 /// Access the underlying solver.
259 const SolverType &GetSolver() const { return solver; }
260
261 /// Access the LOR discretization object.
262 const LORBase &GetLOR() const { return *lor; }
263
264 ~LORSolver() { if (own_lor) { delete lor; } }
265};
266
267#ifdef MFEM_USE_MPI
268
269// Template specialization for batched LOR AMS (implementation in lor_ams.cpp)
270template <>
271class LORSolver<HypreAMS> : public Solver
272{
273protected:
274 OperatorHandle A; ///< The assembled system matrix.
275 Vector *xyz = nullptr; ///< Data for vertex coordinate vectors.
276 HypreAMS *solver = nullptr; ///< The underlying AMS solver.
277public:
278 /// @brief Creates the AMS solvers for the given form and essential DOFs.
279 ///
280 /// Assembles the LOR matrices for the form @a a_ho and the associated
281 /// discrete gradient matrix and vertex coordinate vectors.
283 int ref_type=BasisType::GaussLobatto);
284
285 /// Calls HypreAMS::SetOperator.
286 void SetOperator(const Operator &op);
287
288 /// Apply the action of the AMS preconditioner.
289 void Mult(const Vector &x, Vector &y) const;
290
291 /// Access the underlying solver.
293
294 /// Access the underlying solver (const version).
295 const HypreAMS &GetSolver() const;
296
297 ~LORSolver();
298};
299
300// Template specialization for batched LOR ADS (implementation in lor_ads.cpp)
301template <>
302class LORSolver<HypreADS> : public Solver
303{
304protected:
305 OperatorHandle A; ///< The assembled system matrix.
306 Vector *xyz = nullptr; ///< Data for vertex coordinate vectors.
307 HypreADS *solver = nullptr; ///< The underlying ADS solver.
308public:
309 /// @brief Creates the ADS solvers for the given form and essential DOFs.
310 ///
311 /// Assembles the LOR matrices for the form @a a_ho and the associated
312 /// discrete gradient matrix and vertex coordinate vectors.
314 int ref_type=BasisType::GaussLobatto);
315
316 /// Calls HypreADS::SetOperator.
317 void SetOperator(const Operator &op);
318
319 /// Apply the action of the ADS preconditioner.
320 void Mult(const Vector &x, Vector &y) const;
321
322 /// Access the underlying solver.
324
325 /// Access the underlying solver (const version).
326 const HypreADS &GetSolver() const;
327
328 ~LORSolver();
329};
330
331#endif
332
333} // namespace mfem
334
335#endif
@ GaussLobatto
Closed type.
Definition fe_base.hpp:36
Efficient batched assembly of LOR discretizations on device.
Abstract base class BilinearFormIntegrator.
A "square matrix" operator for the associated FE space and BLFIntegrators The sum of all the BLFInteg...
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Definition fe_coll.hpp:27
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:210
The Auxiliary-space Divergence Solver in hypre.
Definition hypre.hpp:2066
The Auxiliary-space Maxwell Solver in hypre.
Definition hypre.hpp:1989
Wrapper for hypre's ParCSR matrix class.
Definition hypre.hpp:419
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:96
Container class for integration rules.
Definition intrules.hpp:430
Abstract base class for LORDiscretization and ParLORDiscretization classes, which construct low-order...
Definition lor.hpp:23
LORBase(FiniteElementSpace &fes_ho_, int ref_type_)
Construct the LORBase object for the given FE space and refinement type.
Definition lor.cpp:338
int GetLOROrder() const
Returns the order of the LOR space. 1 for H1 or ND, 0 for L2 or RT.
Definition lor.cpp:84
void ConstructLocalDofPermutation(Array< int > &perm_) const
Definition lor.cpp:90
bool HasSameDofNumbering() const
Definition lor.cpp:259
void ConstructDofPermutation() const
Definition lor.cpp:210
FiniteElementSpace * fes
Definition lor.hpp:67
void AssembleSystem(BilinearForm &a_ho, const Array< int > &ess_dofs)
Assembles the LOR system corresponding to a_ho.
Definition lor.cpp:367
FESpaceType GetFESpaceType() const
Returns the type of finite element space: H1, ND, RT or L2.
Definition lor.cpp:73
FiniteElementCollection * fec
Definition lor.hpp:66
void SetupProlongationAndRestriction()
Definition lor.cpp:277
class BatchedLORAssembly * batched_lor
Definition lor.hpp:69
FiniteElementSpace & fes_ho
Definition lor.hpp:64
OperatorHandle A
Definition lor.hpp:70
BilinearForm * a
Definition lor.hpp:68
virtual void FormLORSpace()=0
Construct the LOR space (overridden for serial and parallel versions).
Array< int > perm
Definition lor.hpp:71
int ref_type
Definition lor.hpp:63
const Array< int > & GetDofPermutation() const
Returns the permutation that maps LOR DOFs to high-order DOFs.
Definition lor.cpp:253
FiniteElementSpace & GetFESpace() const
Returns the low-order refined finite element space.
Definition lor.cpp:358
virtual ~LORBase()
Definition lor.cpp:431
const OperatorHandle & GetAssembledSystem() const
Returns the assembled LOR system (const version).
Definition lor.cpp:271
Mesh * mesh
Definition lor.hpp:65
void LegacyAssembleSystem(BilinearForm &a_ho, const Array< int > &ess_dofs)
Assembles the LOR system corresponding to a_ho using the legacy method.
Definition lor.cpp:387
Create and assemble a low-order refined version of a BilinearForm.
Definition lor.hpp:136
LORDiscretization(BilinearForm &a_ho, const Array< int > &ess_tdof_list, int ref_type=BasisType::GaussLobatto)
Construct the low-order refined version of a_ho using the given list of essential DOFs.
Definition lor.cpp:440
void FormLORSpace() override
Construct the LOR space (overridden for serial and parallel versions).
Definition lor.cpp:457
SparseMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a SparseMatrix.
Definition lor.cpp:477
OperatorHandle A
The assembled system matrix.
Definition lor.hpp:305
OperatorHandle A
The assembled system matrix.
Definition lor.hpp:274
Represents a solver of type SolverType created using the low-order refined version of the given Bilin...
Definition lor.hpp:202
LORSolver(LORBase &lor_, Args &&... args)
Create a solver of type SolverType using the assembled LOR operator represented by lor_.
Definition lor.hpp:243
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition lor.hpp:253
void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Definition lor.hpp:246
LORSolver(const Operator &op, LORBase &lor_, Args &&... args)
Create a solver of type SolverType using Operator op and arguments args.
Definition lor.hpp:231
const SolverType & GetSolver() const
Access the underlying solver.
Definition lor.hpp:259
SolverType & GetSolver()
Access the underlying solver.
Definition lor.hpp:256
LORBase * lor
Definition lor.hpp:204
const LORBase & GetLOR() const
Access the LOR discretization object.
Definition lor.hpp:262
LORSolver(ParBilinearForm &a_ho, const Array< int > &ess_tdof_list, int ref_type=BasisType::GaussLobatto)
Create a solver of type SolverType, formed using the assembled HypreParMatrix of the LOR version of a...
Definition lor.hpp:220
SolverType solver
Definition lor.hpp:206
LORSolver(BilinearForm &a_ho, const Array< int > &ess_tdof_list, int ref_type=BasisType::GaussLobatto)
Create a solver of type SolverType, formed using the assembled SparseMatrix of the LOR version of a_h...
Definition lor.hpp:210
Mesh data type.
Definition mesh.hpp:67
Pointer to an Operator of a specified type.
Definition handle.hpp:34
Abstract operator.
Definition operator.hpp:27
int width
Dimension of the input / number of columns in the matrix.
Definition operator.hpp:30
int height
Dimension of the output / number of rows in the matrix.
Definition operator.hpp:29
Class for parallel bilinear form.
Abstract parallel finite element space.
Definition pfespace.hpp:31
Create and assemble a low-order refined version of a ParBilinearForm.
Definition lor.hpp:164
ParFiniteElementSpace & GetParFESpace() const
Return the LOR ParFiniteElementSpace.
Definition lor.cpp:529
ParLORDiscretization(ParBilinearForm &a_ho, const Array< int > &ess_tdof_list, int ref_type=BasisType::GaussLobatto)
Construct the low-order refined version of a_ho using the given list of essential DOFs.
Definition lor.cpp:485
HypreParMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a HypreParMatrix.
Definition lor.cpp:523
void FormLORSpace() override
Construct the LOR space (overridden for serial and parallel versions).
Definition lor.cpp:502
Base class for solvers.
Definition operator.hpp:855
Data type sparse matrix.
Definition sparsemat.hpp:51
Vector data type.
Definition vector.hpp:82
const int * ess_tdof_list