Skip to content

Commit 7bbcc34

Browse files
authored
Merge pull request #3430 from jwpeterson/allow_nodal_pyramid_quadrature
Add flag that controls whether nodal pyramid quadrature is allowed
2 parents 3f05f40 + 99bb23d commit 7bbcc34

File tree

7 files changed

+37
-0
lines changed

7 files changed

+37
-0
lines changed

include/quadrature/quadrature.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,19 @@ class QBase : public ReferenceCountedObject<QBase>
245245
*/
246246
bool allow_rules_with_negative_weights;
247247

248+
/**
249+
* The flag's value defaults to false so that one does not accidentally
250+
* use a nodal quadrature rule on Pyramid elements, since evaluating the
251+
* inverse element Jacobian (e.g. dphi) is not well-defined at the
252+
* Pyramid apex because the element Jacobian is zero there.
253+
*
254+
* We do not want to completely prevent someone from using a nodal
255+
* quadrature rule on Pyramids, however, since there are legitimate
256+
* use cases (lumped mass matrix) so the flag can be set to true to
257+
* override this behavior.
258+
*/
259+
bool allow_nodal_pyramid_quadrature;
260+
248261
protected:
249262

250263

src/geom/elem.C

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,6 +2424,9 @@ bool Elem::has_invertible_map(Real /*tol*/) const
24242424
FEMap fe_map;
24252425
auto & jac = fe_map.get_jacobian();
24262426

2427+
// We have a separate check for is_singular_node() below, so in this
2428+
// case its "OK" to do nodal quadrature on pyramids.
2429+
qnodal.allow_nodal_pyramid_quadrature = true;
24272430
qnodal.init(this->type());
24282431
auto & qp = qnodal.get_points();
24292432
libmesh_assert_equal_to(qp.size(), this->n_nodes());

src/quadrature/quadrature.C

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace libMesh
2727
QBase::QBase(unsigned int d,
2828
Order o) :
2929
allow_rules_with_negative_weights(true),
30+
allow_nodal_pyramid_quadrature(false),
3031
_dim(d),
3132
_order(o),
3233
_type(INVALID_ELEM),

src/quadrature/quadrature_nodal_3D.C

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ void QNodal::init_3D(const ElemType, unsigned int)
3737
case HEX8:
3838
case PYRAMID5:
3939
{
40+
// Construct QTrap rule that matches our own nodal pyramid quadrature permissions
4041
QTrap rule(/*dim=*/3, /*ignored*/_order);
42+
rule.allow_nodal_pyramid_quadrature = this->allow_nodal_pyramid_quadrature;
4143
rule.init(_type, /*ignored*/_p_level);
4244
_points.swap (rule.get_points());
4345
_weights.swap(rule.get_weights());
@@ -107,7 +109,9 @@ void QNodal::init_3D(const ElemType, unsigned int)
107109
case PYRAMID13:
108110
case PYRAMID14:
109111
{
112+
// Construct QSimpson rule that matches our own nodal pyramid quadrature permissions
110113
QSimpson rule(/*dim=*/3, /*ignored*/_order);
114+
rule.allow_nodal_pyramid_quadrature = this->allow_nodal_pyramid_quadrature;
111115
rule.init(_type, /*ignored*/_p_level);
112116
_points.swap (rule.get_points());
113117
_weights.swap(rule.get_weights());

src/quadrature/quadrature_simpson_3D.C

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ void QSimpson::init_3D(const ElemType, unsigned int)
140140
case PYRAMID13:
141141
case PYRAMID14:
142142
{
143+
libmesh_error_msg_if(!allow_nodal_pyramid_quadrature,
144+
"Nodal quadrature on Pyramid elements is not allowed by default since\n"
145+
"the Jacobian of the inverse element map is not well-defined at the Pyramid apex.\n"
146+
"Set the QBase::allow_nodal_pyramid_quadrature flag to true to ignore skip this check.");
147+
143148
_points.resize(14);
144149
_weights.resize(14);
145150

src/quadrature/quadrature_trap_3D.C

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ void QTrap::init_3D(const ElemType, unsigned int)
9292
case PYRAMID13:
9393
case PYRAMID14:
9494
{
95+
libmesh_error_msg_if(!allow_nodal_pyramid_quadrature,
96+
"Nodal quadrature on Pyramid elements is not allowed by default since\n"
97+
"the Jacobian of the inverse element map is not well-defined at the Pyramid apex.\n"
98+
"Set the QBase::allow_nodal_pyramid_quadrature flag to true to ignore skip this check.");
99+
95100
_points.resize(5);
96101
_weights.resize(5);
97102

tests/quadrature/quadrature_test.C

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ private:
177177
std::unique_ptr<QBase> qrule =
178178
QBase::build(qtype, dim, static_cast<Order>(order));
179179

180+
// We are testing integration on the reference elements here, so
181+
// the element map is not relevant, and we can safely use nodal
182+
// Pyramid quadrature.
183+
if (elem_type == PYRAMID5 || elem_type == PYRAMID13 || elem_type == PYRAMID14 || elem_type == PYRAMID18)
184+
qrule->allow_nodal_pyramid_quadrature = true;
185+
180186
qrule->init (elem_type);
181187

182188
const int max_y_order = dim>1 ? 0 : exactorder;

0 commit comments

Comments
 (0)