MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
bounds.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_BOUNDS
13#define MFEM_BOUNDS
14
15#include "../config/config.hpp"
16#include "fespace.hpp"
17
18namespace mfem
19{
20
21/** @name Piecewise linear bounds of bases
22 \brief Piecewise linear bounds of bases can be used to compute bounds on
23 the grid function in each element. The bounds for the bases are constructed
24 based on the following parameters:
25
26 (i) @b nb: number of bases/nodes in 1D (i.e. polynomial order+1),
27
28 (ii) @b b_type: bases type, 0 - Lagrange interpolants on Gauss-Legendre
29 nodes, 1 - Lagrange interpolants on Gauss-Lobatto-Legendre nodes, and
30 2 - Positive/Bernstein bases on uniformly distributed nodes,
31
32 (iii) @b ncp: number of control points used to construct the piecewise
33 linear bounds
34
35 (iv) @b cp_type: control point distribution. 0 - GL + end-points,
36 1 - Chebyshev.
37
38 Note: @b nb and @b b_type are inferred directly from the grid-function.
39
40 If the user does not specify @b ncp and @b cp_type, the minimum value of
41 @b ncp is used that would bound the bases for the @b cp_type. We default
42 to @b cp_type = 0 as it requires fewer number of points to bound the bases.
43 Typically, @b ncp = 2 @b nb is sufficient to get fairly compact bounds, and
44 increasing @b ncp results in tighter bounds.
45
46 Finally, only tensor-product elements are currently supported.
47
48 For more technical details see:
49 Mittal et al., "General Field Evaluation in High-Order Meshes on GPUs" &
50 Dzanic et al., "A method for bounding high-order finite element
51 functions: Applications to mesh validity and bounds-preserving limiters".
52*/
54{
55private:
56 int nb; // #mesh nodes in 1D
57 int ncp; // #control points in 1D
58 int b_type; // bases type: 0 - GL, 1 - GLL, 2 - Bernstein
59 int cp_type; // control points type: 0 - GL+Ends, 1 - Chebyshev
60 bool proj = true; // Use linear projection to compute bounds.
61 real_t tol = 0.0; // offset bounds to avoid round-off errors
62 Vector nodes, weights, control_points;
63 DenseMatrix lbound, ubound; // ncp x nb matrices with bounds of all bases
64 // Some auxiliary storage for computing the bounds with Bernstein
65 DenseMatrix basisMatNodes; // Bernstein bases at equispaced nodes
66 DenseMatrix basisMatInt; // Bernstein bases at GLL nodes
67 Vector nodes_int, weights_int; // Integration nodes and weights
68 DenseMatrix basisMatLU; // Used to compute LU factors for Bernstein
69 mutable Array<int> lu_ip;
70
71 // stores min_ncp for nb = 2..12 for Lagrange interpolants on GL nodes
72 // with GL+end points and Chebyshev points as control points
73 static constexpr int min_ncp_gl_x[2][11]= {{3,5,6,8,9,10,11,11,12,13,14},
74 {3,5,8,9,11,12,14,15,17,18,20}
75 };
76
77 // stores min_ncp for nb = 2..12 for Lagrange interpolants on GLL nodes
78 // with GL+end points and Chebyshev points as control points
79 static constexpr int min_ncp_gll_x[2][11]= {{3,5,7,8,9,10,12,13,14,15,16},
80 {3,5,8,10,12,13,15,17,19,21,22}
81 };
82
83 // stores min_ncp for nb = 2..12 for Bernstein bases with GL+end points
84 // and Chebyshev points as control points
85 static constexpr int min_ncp_pos_x[2][11]= {{3,5,7,8,8,9,10,10,11,12,13},
86 {3,5,8,9,11,12,13,13,14,15,16}
87 };
88
89 /// Helper function to extract lower or upper bounding matrix
90 DenseMatrix GetBoundingMatrix(int dim, bool is_lower) const;
91
92public:
93 // Constructor
94 PLBound(const int nb_i, const int ncp_i, const int b_type_i,
95 const int cp_type_i, const real_t tol_i)
96 {
97 Setup(nb_i, ncp_i, b_type_i, cp_type_i, tol_i);
98 }
99
100 // Constructor
101 PLBound(const FiniteElementSpace *fes,
102 const int ncp_i = -1, const int cp_type_i = 0);
103
104 /// Get minimum number of control points needed to bound the given bases
105 int GetMinimumPointsForGivenBases(int nb_i, int b_type_i,
106 int cp_type_i) const;
107
108 /// Print information about the bounds
109 void Print(std::ostream &outp = mfem::out) const;
110
111 /** @brief Enable (default) or disable linear projection before bounding.
112 *
113 * @details This projection increases the computational cost but results in
114 * tighter bounds.
115 */
116 void SetProjectionFlagForBounding(bool proj_) { proj = proj_; }
117
118 /** @brief Compute piecewise linear bounds for the lexicographically-ordered
119 * nodal coefficients in @a coeff in 1D/2D/3D.
120 *
121 * @param[in] rdim The spatial dimension of the element (1, 2, or 3).
122 * @param[in] coeff The vector of lexicographically-ordered coefficients.
123 * Should be of size nb^rdim, where nb is the number of
124 * bases/nodes in 1D. These coefficients must correspond
125 * to the bases type and number of bases, used in the
126 * constructor of PLBound.
127 *
128 * @param[out] intmin The vector of minimum bound for all control points.
129 * @param[out] intmax The vector of maximum bound for all control points.
130 * Both intmin and intmax are of size ncp^rdim, where
131 * ncp is the number of control points in 1D, and are
132 * ordered lexicographically.
133 */
134 void GetNDBounds(const int rdim, const Vector &coeff,
135 Vector &intmin, Vector &intmax) const;
136
137 /// Get number of control points used to compute the bounds.
138 int GetNControlPoints() const { return ncp; }
139
140 /// Get 1D control point locations (lexicographic order) in [0,1].
141 const Vector &GetControlPoints() const { return control_points; }
142
143 /** @brief Get lower and upper bounding matrix (ncp^dim x nb^dim)
144 *
145 * @details The matrices can be used to compute the bounds at control points
146 * by a simple matrix-vector product with the
147 * lexicographically-ordered nodal coefficients.
148 * The resulting output is also lexicographically-ordered.
149 *
150 * @note These matrices do not account for the linear projection step that
151 * is optionally done in GetNDBounds before bounding the function.
152 */
153 ///@{
154 DenseMatrix GetLowerBoundMatrix(int dim = 1) const;
155 DenseMatrix GetUpperBoundMatrix(int dim = 1) const;
156 ///@}
157
158private:
159 /** @brief Compute piecewise linear bounds for the lexicographically-ordered
160 * nodal coefficients in @a coeff in 1D.
161 * See GetNDBounds for details of the input and output parameters.
162 */
163 void Get1DBounds(const Vector &coeff, Vector &intmin, Vector &intmax) const;
164
165 /** @brief Compute piecewise linear bounds for the lexicographically-ordered
166 * nodal coefficients in @a coeff in 2D.
167 * See GetNDBounds for details of the input and output parameters.
168 */
169 void Get2DBounds(const Vector &coeff, Vector &intmin, Vector &intmax) const;
170
171 /** @brief Compute piecewise linear bounds for the lexicographically-ordered
172 * nodal coefficients in @a coeff in 3D.
173 * See GetNDBounds for details of the input and output parameters.
174 */
175 void Get3DBounds(const Vector &coeff, Vector &intmin, Vector &intmax) const;
176
177 /** @brief Setup matrix used to compute values at given 1D locations in [0,1]
178 * for Bernstein bases.
179 */
180 void SetupBernsteinBasisMat(DenseMatrix &basisMat, Vector &nodesBern) const;
181
182 void Setup(const int nb_i, const int ncp_i, const int b_type_i,
183 const int cp_type_i, const real_t tol_i);
184};
185
186} // namespace mfem
187
188#endif // MFEM_BOUNDS
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:210
const Vector & GetControlPoints() const
Get 1D control point locations (lexicographic order) in [0,1].
Definition bounds.hpp:141
void GetNDBounds(const int rdim, const Vector &coeff, Vector &intmin, Vector &intmax) const
Compute piecewise linear bounds for the lexicographically-ordered nodal coefficients in coeff in 1D/2...
Definition bounds.cpp:636
void Print(std::ostream &outp=mfem::out) const
Print information about the bounds.
Definition bounds.cpp:740
PLBound(const int nb_i, const int ncp_i, const int b_type_i, const int cp_type_i, const real_t tol_i)
Definition bounds.hpp:94
int GetNControlPoints() const
Get number of control points used to compute the bounds.
Definition bounds.hpp:138
DenseMatrix GetLowerBoundMatrix(int dim=1) const
Get lower and upper bounding matrix (ncp^dim x nb^dim)
Definition bounds.cpp:698
void SetProjectionFlagForBounding(bool proj_)
Enable (default) or disable linear projection before bounding.
Definition bounds.hpp:116
int GetMinimumPointsForGivenBases(int nb_i, int b_type_i, int cp_type_i) const
Get minimum number of control points needed to bound the given bases.
Definition bounds.cpp:712
DenseMatrix GetUpperBoundMatrix(int dim=1) const
Definition bounds.cpp:703
Vector data type.
Definition vector.hpp:82
int dim
Definition ex24.cpp:53
real_t proj(GridFunction &psi, GridFunction &alpha_grad, real_t target_volume, real_t tol=1e-12, int max_its=100)
Bregman projection of ρ = sigmoid(ψ) onto the subspace ∫_Ω ρ dx = θ vol(Ω) as follows:
Definition ex37.hpp:395
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
float real_t
Definition config.hpp:46