libMesh
Loading...
Searching...
No Matches
quadrature.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
19// Local includes
20#include "libmesh/elem.h"
21#include "libmesh/quadrature.h"
22#include "libmesh/int_range.h"
23
24namespace libMesh
25{
26
27QBase::QBase(unsigned int d,
28 Order o) :
29 allow_rules_with_negative_weights(true),
30 allow_nodal_pyramid_quadrature(false),
31 _dim(d),
32 _order(o),
33 _type(INVALID_ELEM),
34 _elem(nullptr),
35 _p_level(0)
36{}
37
38std::unique_ptr<QBase> QBase::clone() const
39{
40 return QBase::build(this->type(), this->get_dim(), this->get_order());
41}
42
43void QBase::print_info(std::ostream & os) const
44{
45 libmesh_assert(!_points.empty());
46 libmesh_assert(!_weights.empty());
47
48 Real summed_weights=0;
49 os << "N_Q_Points=" << this->n_points() << std::endl << std::endl;
50 for (auto qpoint: index_range(_points))
51 {
52 os << " Point " << qpoint << ":\n"
53 << " "
54 << _points[qpoint]
55 << "\n Weight:\n "
56 << " w=" << _weights[qpoint] << "\n" << std::endl;
57
58 summed_weights += _weights[qpoint];
59 }
60 os << "Summed Weights: " << summed_weights << std::endl;
61}
62
63
64
65void QBase::init(const Elem & elem,
66 unsigned int p)
67{
68 libmesh_assert_equal_to(elem.dim(), _dim);
69
70 // Default to the element p_level() value
71 if (p == invalid_uint)
72 p = elem.p_level();
73
74 ElemType t = elem.type();
75
76 // check to see if we have already
77 // done the work for this quadrature rule
78 //
79 // If we have something like a Polygon subclass then we're going to
80 // need to recompute to be safe; even if we're using the same
81 // element, it might have been distorted enough that its subtriangle
82 // triangulation has been changed.
83 if (t == _type && p == _p_level && !elem.runtime_topology())
84 return;
85 else
86 {
87 _elem = &elem;
88 _type = t;
89 _p_level = p;
90 }
91
92 switch(_elem->dim())
93 {
94 case 0:
95 this->init_0D();
96
97 return;
98
99 case 1:
100 this->init_1D();
101
102 return;
103
104 case 2:
105 this->init_2D();
106
107 return;
108
109 case 3:
110 this->init_3D();
111
112 return;
113
114 default:
115 libmesh_error_msg("Invalid dimension _dim = " << _dim);
116 }
117}
118
119
120
122 unsigned int p,
123 bool simple_type_only)
124{
125 // Some element types require data from a specific element, so can
126 // only be used with newer APIs.
127 if (t == C0POLYGON || t == C0POLYHEDRON)
128 libmesh_error_msg("Code (see stack trace) used an outdated quadrature function overload.\n"
129 "Quadrature rules on a C0Polygon are not defined by its ElemType alone.");
130
131 // This API is dangerous to use on general meshes, which may include
132 // element types where the desired quadrature depends on the
133 // physical element, but we still want to be able to initialize
134 // based on only a type for certain simple cases
135 if (t != EDGE2 && !simple_type_only)
136 libmesh_deprecated();
137
138 // check to see if we have already
139 // done the work for this quadrature rule
140 if (t == _type && p == _p_level)
141 return;
142 else
143 {
144 _elem = nullptr;
145 _type = t;
146 _p_level = p;
147 }
148
149 switch(_dim)
150 {
151 case 0:
152 this->init_0D();
153
154 return;
155
156 case 1:
157 this->init_1D();
158
159 return;
160
161 case 2:
162 this->init_2D();
163
164 return;
165
166 case 3:
167 this->init_3D();
168
169 return;
170
171 default:
172 libmesh_error_msg("Invalid dimension _dim = " << _dim);
173 }
174}
175
176
177
178void QBase::init(const QBase & other_rule)
179{
180 if (other_rule._elem)
181 this->init(*other_rule._elem, other_rule._p_level);
182 else
183 this->init(other_rule._type, other_rule._p_level, true);
184}
185
186
187
188void QBase::init (const Elem & elem,
189 const std::vector<Real> & /* vertex_distance_func */,
190 unsigned int p_level)
191{
192 // dispatch generic implementation
193 this->init(elem.type(), p_level);
194}
195
196
197
199{
200 _points.resize(1);
201 _weights.resize(1);
202 _points[0] = Point(0.);
203 _weights[0] = 1.0;
204}
205
206
207
209{
210 libmesh_not_implemented();
211}
212
213
214
216{
217 libmesh_not_implemented();
218}
219
220
221
222void QBase::scale(std::pair<Real, Real> old_range,
223 std::pair<Real, Real> new_range)
224{
225 // Make sure we are in 1D
226 libmesh_assert_equal_to (_dim, 1);
227
228 Real
229 h_new = new_range.second - new_range.first,
230 h_old = old_range.second - old_range.first;
231
232 // Make sure that we have sane ranges
233 libmesh_assert_greater (h_new, 0.);
234 libmesh_assert_greater (h_old, 0.);
235
236 // Make sure there are some points
237 libmesh_assert_greater (_points.size(), 0);
238
239 // Compute the scale factor
240 Real scfact = h_new/h_old;
241
242 // We're mapping from old_range -> new_range
243 for (auto i : index_range(_points))
244 {
245 _points[i](0) = new_range.first +
246 (_points[i](0) - old_range.first) * scfact;
247
248 // Scale the weights
249 _weights[i] *= scfact;
250 }
251}
252
253
254
255
257{
258
259 const unsigned int np = q1D.n_points();
260
261 _points.resize(np * np);
262
263 _weights.resize(np * np);
264
265 unsigned int q=0;
266
267 for (unsigned int j=0; j<np; j++)
268 for (unsigned int i=0; i<np; i++)
269 {
270 _points[q](0) = q1D.qp(i)(0);
271 _points[q](1) = q1D.qp(j)(0);
272
273 _weights[q] = q1D.w(i)*q1D.w(j);
274
275 q++;
276 }
277}
278
279
280
281
282
284{
285 const unsigned int np = q1D.n_points();
286
287 _points.resize(np * np * np);
288
289 _weights.resize(np * np * np);
290
291 unsigned int q=0;
292
293 for (unsigned int k=0; k<np; k++)
294 for (unsigned int j=0; j<np; j++)
295 for (unsigned int i=0; i<np; i++)
296 {
297 _points[q](0) = q1D.qp(i)(0);
298 _points[q](1) = q1D.qp(j)(0);
299 _points[q](2) = q1D.qp(k)(0);
300
301 _weights[q] = q1D.w(i) * q1D.w(j) * q1D.w(k);
302
303 q++;
304 }
305}
306
307
308
309
310void QBase::tensor_product_prism(const QBase & q1D, const QBase & q2D)
311{
312 const unsigned int n_points1D = q1D.n_points();
313 const unsigned int n_points2D = q2D.n_points();
314
315 _points.resize (n_points1D * n_points2D);
316 _weights.resize (n_points1D * n_points2D);
317
318 unsigned int q=0;
319
320 for (unsigned int j=0; j<n_points1D; j++)
321 for (unsigned int i=0; i<n_points2D; i++)
322 {
323 _points[q](0) = q2D.qp(i)(0);
324 _points[q](1) = q2D.qp(i)(1);
325 _points[q](2) = q1D.qp(j)(0);
326
327 _weights[q] = q2D.w(i) * q1D.w(j);
328
329 q++;
330 }
331
332}
333
334
335
336
337std::ostream & operator << (std::ostream & os, const QBase & q)
338{
339 q.print_info(os);
340 return os;
341}
342
343} // namespace libMesh
This is the base class from which all geometric element types are derived.
Definition elem.h:96
virtual unsigned short dim() const =0
virtual bool runtime_topology() const
Definition elem.h:254
virtual ElemType type() const =0
unsigned int p_level() const
Definition elem.h:3125
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
The QBase class provides the basic functionality from which various quadrature rules can be derived.
Definition quadrature.h:62
std::vector< Point > _points
The locations of the quadrature points in reference element space.
Definition quadrature.h:409
ElemType _type
The type of element for which the current values have been computed.
Definition quadrature.h:391
unsigned int _p_level
The p-level of the element for which the current values have been computed.
Definition quadrature.h:403
Order get_order() const
Definition quadrature.h:249
unsigned int _dim
The spatial dimension of the quadrature rule.
Definition quadrature.h:379
unsigned int n_points() const
Definition quadrature.h:131
void print_info(std::ostream &os=libMesh::out) const
Prints information relevant to the quadrature rule, by default to libMesh::out.
Definition quadrature.C:43
virtual void init_2D()
Initializes the 2D quadrature rule by filling the points and weights vectors with the appropriate val...
Definition quadrature.C:208
virtual QuadratureType type() const =0
void tensor_product_quad(const QBase &q1D)
Constructs a 2D rule from the tensor product of q1D with itself.
Definition quadrature.C:256
Point qp(const unsigned int i) const
Definition quadrature.h:179
virtual void init_0D()
Initializes the 0D quadrature rule by filling the points and weights vectors with the appropriate val...
Definition quadrature.C:198
unsigned int get_dim() const
Definition quadrature.h:150
virtual void init_1D()=0
Initializes the 1D quadrature rule by filling the points and weights vectors with the appropriate val...
Real w(const unsigned int i) const
Definition quadrature.h:188
const Elem * _elem
The element for which the current values were computed, or nullptr if values were computed without a ...
Definition quadrature.h:397
std::vector< Real > _weights
The quadrature weights.
Definition quadrature.h:415
virtual void init(const Elem &e, unsigned int p_level=invalid_uint)
Initializes the data structures for a quadrature rule for the element e.
Definition quadrature.C:65
void tensor_product_prism(const QBase &q1D, const QBase &q2D)
Computes the tensor product of a 1D quadrature rule and a 2D quadrature rule.
Definition quadrature.C:310
virtual void init_3D()
Initializes the 3D quadrature rule by filling the points and weights vectors with the appropriate val...
Definition quadrature.C:215
static std::unique_ptr< QBase > build(std::string_view name, const unsigned int dim, const Order order=INVALID_ORDER)
Builds a specific quadrature rule based on the name string.
virtual std::unique_ptr< QBase > clone() const
Definition quadrature.C:38
void tensor_product_hex(const QBase &q1D)
Computes the tensor product quadrature rule [q1D x q1D x q1D] from the 1D rule q1D.
Definition quadrature.C:283
QBase(unsigned int dim, Order order=INVALID_ORDER)
Constructor.
Definition quadrature.C:27
void scale(std::pair< Real, Real > old_range, std::pair< Real, Real > new_range)
Maps the points of a 1D quadrature rule defined by "old_range" to another 1D interval defined by "new...
Definition quadrature.C:222
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition int_range.h:153
ElemType
Defines an enum for geometric element types.
libmesh_assert(ctx)
std::ostream & operator<<(std::ostream &os, const OrderWrapper &order)
Overload stream operators.
Definition fe_type.h:182
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition libmesh.h:303
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real