libMesh
Loading...
Searching...
No Matches
quadrature_conical.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// libMesh includes
20#include "libmesh/quadrature_conical.h"
21#include "libmesh/quadrature_gauss.h"
22#include "libmesh/quadrature_jacobi.h"
23#include "libmesh/enum_quadrature_type.h"
24
25namespace libMesh
26{
27
28// See also the files:
29// quadrature_conical_2D.C
30// quadrature_conical_3D.C
31// for additional implementation.
32
34{
35 return QCONICAL;
36}
37
38std::unique_ptr<QBase> QConical::clone() const
39{
40 return std::make_unique<QConical>(*this);
41}
42
44{
45 QGauss gauss1D(1, get_order());
46 gauss1D.init(*this);
47
48 // Swap points and weights with the about-to-be destroyed rule.
49 _points.swap(gauss1D.get_points());
50 _weights.swap(gauss1D.get_weights());
51}
52
53
54
55// Builds and scales a Gauss rule and a Jacobi rule.
56// Then combines them to compute points and weights
57// of a 2D conical product rule.
59{
60 // Be sure the underlying rule object was built with the same dimension as the
61 // rule we are about to construct.
62 libmesh_assert_equal_to (this->get_dim(), 2);
63
64 QGauss gauss1D(1, get_order());
65 QJacobi jac1D(1, get_order(), 1, 0);
66
67 // The Gauss rule needs to be scaled to [0,1]
68 std::pair<Real, Real> old_range(-1, 1);
69 std::pair<Real, Real> new_range( 0, 1);
70 gauss1D.scale(old_range,
71 new_range);
72
73 // Now construct the points and weights for the conical product rule.
74
75 // Both rules should have the same number of points.
76 libmesh_assert_equal_to (gauss1D.n_points(), jac1D.n_points());
77
78 // Save the number of points as a convenient variable
79 const unsigned int np = gauss1D.n_points();
80
81 // Both rules should be between x=0 and x=1
82 libmesh_assert_greater_equal (gauss1D.qp(0)(0), 0.0);
83 libmesh_assert_less_equal (gauss1D.qp(np-1)(0), 1.0);
84 libmesh_assert_greater_equal (jac1D.qp(0)(0), 0.0);
85 libmesh_assert_less_equal (jac1D.qp(np-1)(0), 1.0);
86
87 // Resize the points and weights vectors
88 _points.resize(np * np);
89 _weights.resize(np * np);
90
91 // Compute the conical product
92 unsigned int gp = 0;
93 for (unsigned int i=0; i<np; i++)
94 for (unsigned int j=0; j<np; j++)
95 {
96 _points[gp](0) = jac1D.qp(j)(0); //s[j];
97 _points[gp](1) = gauss1D.qp(i)(0) * (1.-jac1D.qp(j)(0)); //r[i]*(1.-s[j]);
98 _weights[gp] = gauss1D.w(i) * jac1D.w(j); //A[i]*B[j];
99 gp++;
100 }
101}
102
103
104
105
106// Builds and scales a Gauss rule and a Jacobi rule.
107// Then combines them to compute points and weights
108// of a 3D conical product rule for the Tet.
110{
111 // Be sure the underlying rule object was built with the same dimension as the
112 // rule we are about to construct.
113 libmesh_assert_equal_to (this->get_dim(), 3);
114
115 QGauss gauss1D(1, get_order());
116 QJacobi jacA1D(1, get_order(), /*alpha=*/1, /*beta=*/0);
117 QJacobi jacB1D(1, get_order(), /*alpha=*/2, /*beta=*/0);
118
119 // The Gauss rule needs to be scaled to [0,1]
120 std::pair<Real, Real> old_range(-1, 1);
121 std::pair<Real, Real> new_range( 0, 1);
122 gauss1D.scale(old_range,
123 new_range);
124
125 // Now construct the points and weights for the conical product rule.
126
127 // All rules should have the same number of points
128 libmesh_assert_equal_to (gauss1D.n_points(), jacA1D.n_points());
129 libmesh_assert_equal_to (jacA1D.n_points(), jacB1D.n_points());
130
131 // Save the number of points as a convenient variable
132 const unsigned int np = gauss1D.n_points();
133
134 // All rules should be between x=0 and x=1
135 libmesh_assert_greater_equal (gauss1D.qp(0)(0), 0.0);
136 libmesh_assert_less_equal (gauss1D.qp(np-1)(0), 1.0);
137 libmesh_assert_greater_equal (jacA1D.qp(0)(0), 0.0);
138 libmesh_assert_less_equal (jacA1D.qp(np-1)(0), 1.0);
139 libmesh_assert_greater_equal (jacB1D.qp(0)(0), 0.0);
140 libmesh_assert_less_equal (jacB1D.qp(np-1)(0), 1.0);
141
142 // Resize the points and weights vectors
143 _points.resize(np * np * np);
144 _weights.resize(np * np * np);
145
146 // Compute the conical product
147 unsigned int gp = 0;
148 for (unsigned int i=0; i<np; i++)
149 for (unsigned int j=0; j<np; j++)
150 for (unsigned int k=0; k<np; k++)
151 {
152 _points[gp](0) = jacB1D.qp(k)(0); //t[k];
153 _points[gp](1) = jacA1D.qp(j)(0) * (1.-jacB1D.qp(k)(0)); //s[j]*(1.-t[k]);
154 _points[gp](2) = gauss1D.qp(i)(0) * (1.-jacA1D.qp(j)(0)) * (1.-jacB1D.qp(k)(0)); //r[i]*(1.-s[j])*(1.-t[k]);
155 _weights[gp] = gauss1D.w(i) * jacA1D.w(j) * jacB1D.w(k); //A[i]*B[j]*C[k];
156 gp++;
157 }
158}
159
160
161
162
163
164// Builds and scales a Gauss rule and a Jacobi rule.
165// Then combines them to compute points and weights
166// of a 3D conical product rule for the Pyramid. The integral
167// over the reference Pyramid can be written (in LaTeX notation) as:
168//
169// If := \int_0^1 dz \int_{-(1-z)}^{(1-z)} dy \int_{-(1-z)}^{(1-z)} f(x,y,z) dx (1)
170//
171// (Imagine a stack of infinitely thin squares which decrease in size as
172// you approach the apex.) Under the transformation of variables:
173//
174// z=w
175// y=(1-z)v
176// x=(1-z)u,
177//
178// The Jacobian determinant of this transformation is |J|=(1-w)^2, and
179// the integral itself is transformed to:
180//
181// If = \int_0^1 (1-w)^2 dw \int_{-1}^{1} dv \int_{-1}^{1} f((1-w)u, (1-w)v, w) du (2)
182//
183// The integral can now be approximated by the product of three 1D quadrature rules:
184// A Jacobi rule with alpha==2, beta==0 in w, and Gauss rules in v and u. In this way
185// we can obtain 3D rules to any order for which the 1D rules exist.
187{
188 // Be sure the underlying rule object was built with the same dimension as the
189 // rule we are about to construct.
190 libmesh_assert_equal_to (this->get_dim(), 3);
191
192 QGauss gauss1D(1, get_order());
193 QJacobi jac1D(1, get_order(), 2, 0);
194
195 // These rules should have the same number of points
196 libmesh_assert_equal_to (gauss1D.n_points(), jac1D.n_points());
197
198 // Save the number of points as a convenient variable
199 const unsigned int np = gauss1D.n_points();
200
201 // Resize the points and weights vectors
202 _points.resize(np * np * np);
203 _weights.resize(np * np * np);
204
205 // Compute the conical product
206 unsigned int q = 0;
207 for (unsigned int i=0; i<np; ++i)
208 for (unsigned int j=0; j<np; ++j)
209 for (unsigned int k=0; k<np; ++k, ++q)
210 {
211 const Real xi=gauss1D.qp(i)(0);
212 const Real yj=gauss1D.qp(j)(0);
213 const Real zk=jac1D.qp(k)(0);
214
215 _points[q](0) = (1.-zk) * xi;
216 _points[q](1) = (1.-zk) * yj;
217 _points[q](2) = zk;
218 _weights[q] = gauss1D.w(i) * gauss1D.w(j) * jac1D.w(k);
219 }
220}
221
222} // namespace libMesh
std::vector< Point > _points
The locations of the quadrature points in reference element space.
Definition quadrature.h:409
Order get_order() const
Definition quadrature.h:249
const std::vector< Point > & get_points() const
Definition quadrature.h:156
unsigned int n_points() const
Definition quadrature.h:131
Point qp(const unsigned int i) const
Definition quadrature.h:179
unsigned int get_dim() const
Definition quadrature.h:150
const std::vector< Real > & get_weights() const
Definition quadrature.h:168
Real w(const unsigned int i) const
Definition quadrature.h:188
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 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
virtual void init_1D() override
In 1D, use a Gauss rule.
void conical_product_tri()
Implementation of conical product rule for a Tri in 2D of order get_order().
void conical_product_tet()
Implementation of conical product rule for a Tet in 3D of order get_order().
virtual QuadratureType type() const override
void conical_product_pyramid()
Implementation of conical product rule for a Pyramid in 3D of order get_order().
virtual std::unique_ptr< QBase > clone() const override
This class implements specific orders of Gauss quadrature.
This class implements two (for now) Jacobi-Gauss quadrature rules.
The libMesh namespace provides an interface to certain functionality in the library.
QuadratureType
Defines an enum for currently available quadrature rules.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real