libMesh
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | List of all members
QuadratureTest Class Reference
Inheritance diagram for QuadratureTest:
[legend]

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (QuadratureTest)
 
 TEST_TWENTIETH_ORDER (QGAUSS, 9999)
 
 TEST_ONE_ORDER (QSIMPSON, FIRST, 1)
 
 TEST_ONE_ORDER (QSIMPSON, SECOND, 2)
 
 TEST_ONE_ORDER (QSIMPSON, THIRD, 3)
 
 TEST_ONE_ORDER (QTRAP, FIRST, 1)
 
 TEST_NINTH_ORDER (QGRID, 1)
 
 TEST_ONE_ORDER (QNODAL, FIRST, 1)
 
 TEST_NINTH_ORDER (QGAUSS_LOBATTO, 9)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, ELEVENTH, 11)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, THIRTEENTH, 13)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, FIFTEENTH, 15)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, SEVENTEENTH, 17)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, NINETEENTH, 19)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, TWENTYFIRST, 21)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, TWENTYTHIRD, 23)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, TWENTYFIFTH, 25)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, TWENTYSEVENTH, 27)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, TWENTYNINTH, 29)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, THIRTYFIRST, 31)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, THIRTYTHIRD, 33)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, THIRTYFIFTH, 35)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, THIRTYSEVENTH, 37)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, THIRTYNINTH, 39)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, FORTYFIRST, 41)
 
 TEST_ONE_ORDER (QGAUSS_LOBATTO, FORTYTHIRD, 43)
 
 CPPUNIT_TEST (test1DWeights< QGAUSS MACROCOMMA TWENTYFIRST MACROCOMMA 21 >)
 
 CPPUNIT_TEST (test1DWeights< QGAUSS MACROCOMMA TWENTYFIFTH MACROCOMMA 25 >)
 
 CPPUNIT_TEST (test1DWeights< QGAUSS MACROCOMMA TWENTYSEVENTH MACROCOMMA 27 >)
 
 CPPUNIT_TEST (test1DWeights< QGAUSS MACROCOMMA TWENTYNINTH MACROCOMMA 29 >)
 
 CPPUNIT_TEST (test1DWeights< QGAUSS MACROCOMMA THIRTYFIRST MACROCOMMA 31 >)
 
 CPPUNIT_TEST (test1DWeights< QGAUSS MACROCOMMA THIRTYTHIRD MACROCOMMA 33 >)
 
 CPPUNIT_TEST (test1DWeights< QGAUSS MACROCOMMA THIRTYFIFTH MACROCOMMA 35 >)
 
 CPPUNIT_TEST (test1DWeights< QGAUSS MACROCOMMA THIRTYSEVENTH MACROCOMMA 37 >)
 
 CPPUNIT_TEST (test1DWeights< QGAUSS MACROCOMMA THIRTYNINTH MACROCOMMA 39 >)
 
 CPPUNIT_TEST (test1DWeights< QGAUSS MACROCOMMA FORTYFIRST MACROCOMMA 41 >)
 
 CPPUNIT_TEST (test1DWeights< QGAUSS MACROCOMMA FORTYTHIRD MACROCOMMA 43 >)
 
 CPPUNIT_TEST (testMonomialQuadrature)
 
 CPPUNIT_TEST (testNodalQuadrature)
 
 CPPUNIT_TEST (testTriQuadrature)
 
 CPPUNIT_TEST (testTetQuadrature)
 
 CPPUNIT_TEST (testJacobi)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void tearDown ()
 
void testNodalQuadrature ()
 
void testMonomialQuadrature ()
 
void testTetQuadrature ()
 
void testTriQuadrature ()
 
void testJacobi ()
 
template<QuadratureType qtype, Order order>
void testBuild ()
 
template<QuadratureType qtype, Order order, unsigned int exactorder>
void test1DWeights ()
 
template<QuadratureType qtype, Order order, unsigned int exactorder>
void test2DWeights ()
 
template<QuadratureType qtype, Order order, unsigned int exactorder>
void test3DWeights ()
 

Private Member Functions

void testPolynomial (QBase &qrule, int xp, int yp, int zp, Real true_value)
 
void testPolynomials (QuadratureType qtype, int order, ElemType elem_type, const std::function< Real(int, int, int)> &true_value, int exactorder)
 

Private Attributes

Real quadrature_tolerance
 
const std::function< Real(int, int, int)> edge_integrals
 
const std::function< Real(int, int, int)> quad_integrals
 
const std::function< Real(int, int, int)> tri_integrals
 
const std::function< Real(int, int, int)> hex_integrals
 
const std::function< Real(int, int, int)> tet_integrals
 
const std::function< Real(int, int, int)> prism_integrals
 
const std::function< Real(int, int, int)> pyramid_integrals
 

Detailed Description

Definition at line 72 of file quadrature_test.C.

Member Function Documentation

◆ CPPUNIT_TEST() [1/16]

QuadratureTest::CPPUNIT_TEST ( test1DWeights< QGAUSS MACROCOMMA FORTYFIRST MACROCOMMA 41 >  )

◆ CPPUNIT_TEST() [2/16]

QuadratureTest::CPPUNIT_TEST ( test1DWeights< QGAUSS MACROCOMMA FORTYTHIRD MACROCOMMA 43 >  )

◆ CPPUNIT_TEST() [3/16]

QuadratureTest::CPPUNIT_TEST ( test1DWeights< QGAUSS MACROCOMMA THIRTYFIFTH MACROCOMMA 35 >  )

◆ CPPUNIT_TEST() [4/16]

QuadratureTest::CPPUNIT_TEST ( test1DWeights< QGAUSS MACROCOMMA THIRTYFIRST MACROCOMMA 31 >  )

◆ CPPUNIT_TEST() [5/16]

QuadratureTest::CPPUNIT_TEST ( test1DWeights< QGAUSS MACROCOMMA THIRTYNINTH MACROCOMMA 39 >  )

◆ CPPUNIT_TEST() [6/16]

QuadratureTest::CPPUNIT_TEST ( test1DWeights< QGAUSS MACROCOMMA THIRTYSEVENTH MACROCOMMA 37 >  )

◆ CPPUNIT_TEST() [7/16]

QuadratureTest::CPPUNIT_TEST ( test1DWeights< QGAUSS MACROCOMMA THIRTYTHIRD MACROCOMMA 33 >  )

◆ CPPUNIT_TEST() [8/16]

QuadratureTest::CPPUNIT_TEST ( test1DWeights< QGAUSS MACROCOMMA TWENTYFIFTH MACROCOMMA 25 >  )

◆ CPPUNIT_TEST() [9/16]

QuadratureTest::CPPUNIT_TEST ( test1DWeights< QGAUSS MACROCOMMA TWENTYFIRST MACROCOMMA 21 >  )

◆ CPPUNIT_TEST() [10/16]

QuadratureTest::CPPUNIT_TEST ( test1DWeights< QGAUSS MACROCOMMA TWENTYNINTH MACROCOMMA 29 >  )

◆ CPPUNIT_TEST() [11/16]

QuadratureTest::CPPUNIT_TEST ( test1DWeights< QGAUSS MACROCOMMA TWENTYSEVENTH MACROCOMMA 27 >  )

◆ CPPUNIT_TEST() [12/16]

QuadratureTest::CPPUNIT_TEST ( testJacobi  )

◆ CPPUNIT_TEST() [13/16]

QuadratureTest::CPPUNIT_TEST ( testMonomialQuadrature  )

◆ CPPUNIT_TEST() [14/16]

QuadratureTest::CPPUNIT_TEST ( testNodalQuadrature  )

◆ CPPUNIT_TEST() [15/16]

QuadratureTest::CPPUNIT_TEST ( testTetQuadrature  )

◆ CPPUNIT_TEST() [16/16]

QuadratureTest::CPPUNIT_TEST ( testTriQuadrature  )

◆ CPPUNIT_TEST_SUITE_END()

QuadratureTest::CPPUNIT_TEST_SUITE_END ( )

◆ LIBMESH_CPPUNIT_TEST_SUITE()

QuadratureTest::LIBMESH_CPPUNIT_TEST_SUITE ( QuadratureTest  )

◆ setUp()

void QuadratureTest::setUp ( )
inline

Definition at line 321 of file quadrature_test.C.

322 { quadrature_tolerance = TOLERANCE * std::sqrt(TOLERANCE); }
static constexpr Real TOLERANCE

References quadrature_tolerance, and libMesh::TOLERANCE.

◆ tearDown()

void QuadratureTest::tearDown ( )
inline

Definition at line 324 of file quadrature_test.C.

325 {}

◆ test1DWeights()

template<QuadratureType qtype, Order order, unsigned int exactorder>
void QuadratureTest::test1DWeights ( )
inline

Definition at line 546 of file quadrature_test.C.

547 {
548 LOG_UNIT_TEST;
549
550 testPolynomials(qtype, order, EDGE3, edge_integrals, exactorder);
551 }
void testPolynomials(QuadratureType qtype, int order, ElemType elem_type, const std::function< Real(int, int, int)> &true_value, int exactorder)
const std::function< Real(int, int, int)> edge_integrals

References libMesh::EDGE3, edge_integrals, and testPolynomials().

◆ test2DWeights()

template<QuadratureType qtype, Order order, unsigned int exactorder>
void QuadratureTest::test2DWeights ( )
inline

Definition at line 558 of file quadrature_test.C.

559 {
560 LOG_UNIT_TEST;
561
562 testPolynomials(qtype, order, QUAD8, quad_integrals, exactorder);
563
564 // We may eventually support Gauss-Lobatto type quadrature on triangles...
565 if (qtype == QGAUSS_LOBATTO)
566 return;
567
568 // QGrid needs to be changed to use symmetric offsets on triangles
569 // so it can at *least* get linears right...
570 if (qtype == QGRID)
571 testPolynomials(qtype, order, TRI6, tri_integrals, 0);
572 // QSimpson doesn't even get all quadratics on a triangle
573 else if (qtype == QSIMPSON)
574 testPolynomials(qtype, order, TRI6, tri_integrals, std::min(1u,exactorder));
575 else
576 {
577 // Our 18th order and higher triangle rules were only computed
578 // in double precision, so we use a lower tolerance here.
579 if ((sizeof(Real) > sizeof(double)) && (order > 17))
581
582 testPolynomials(qtype, order, TRI6, tri_integrals, exactorder);
583 }
584 }
const std::function< Real(int, int, int)> quad_integrals
const std::function< Real(int, int, int)> tri_integrals
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

References libMesh::QGAUSS_LOBATTO, libMesh::QGRID, libMesh::QSIMPSON, libMesh::QUAD8, quad_integrals, quadrature_tolerance, libMesh::Real, testPolynomials(), libMesh::TOLERANCE, libMesh::TRI6, and tri_integrals.

◆ test3DWeights()

template<QuadratureType qtype, Order order, unsigned int exactorder>
void QuadratureTest::test3DWeights ( )
inline

Definition at line 591 of file quadrature_test.C.

592 {
593 LOG_UNIT_TEST;
594
595 testPolynomials(qtype, order, HEX20, hex_integrals, exactorder);
596
597 // We may eventually support Gauss-Lobatto type quadrature on tets and prisms...
598 if (qtype == QGAUSS_LOBATTO)
599 return;
600
601 // QGrid needs to be changed to use symmetric offsets on
602 // non-tensor product elements so it can at *least* get linears
603 // right...
604 if (qtype == QGRID)
605 {
606 testPolynomials(qtype, order, TET10, tet_integrals, 0);
608 }
609 // QSimpson doesn't get all quadratics on a simplex or its extrusion
610 else if (qtype == QSIMPSON)
611 {
612 testPolynomials(qtype, order, TET10, tet_integrals, std::min(1u,exactorder));
613 testPolynomials(qtype, order, PRISM15, prism_integrals, std::min(1u,exactorder));
614
615 // And on pyramids we gave up and redid QTrap
616 testPolynomials(qtype, order, PYRAMID14, pyramid_integrals, std::min(1u,exactorder));
617 }
618 else
619 {
620 testPolynomials(qtype, order, TET10, tet_integrals, exactorder);
621 testPolynomials(qtype, order, PYRAMID14, pyramid_integrals, exactorder);
622
623 // Our 18th order and higher triangle rules (used to construct
624 // prism rules) were only computed in double precision, so we
625 // use a lower tolerance here.
626 if ((sizeof(Real) > sizeof(double)) && (order > 17))
628
629 testPolynomials(qtype, order, PRISM15, prism_integrals, exactorder);
630 }
631 }
const std::function< Real(int, int, int)> prism_integrals
const std::function< Real(int, int, int)> tet_integrals
const std::function< Real(int, int, int)> hex_integrals
const std::function< Real(int, int, int)> pyramid_integrals

References libMesh::HEX20, hex_integrals, libMesh::PRISM15, prism_integrals, libMesh::PYRAMID14, pyramid_integrals, libMesh::QGAUSS_LOBATTO, libMesh::QGRID, libMesh::QSIMPSON, quadrature_tolerance, libMesh::Real, testPolynomials(), libMesh::TET10, tet_integrals, and libMesh::TOLERANCE.

◆ TEST_NINTH_ORDER() [1/2]

QuadratureTest::TEST_NINTH_ORDER ( QGAUSS_LOBATTO  ,
 
)

◆ TEST_NINTH_ORDER() [2/2]

QuadratureTest::TEST_NINTH_ORDER ( QGRID  ,
 
)

◆ TEST_ONE_ORDER() [1/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
ELEVENTH  ,
11   
)

◆ TEST_ONE_ORDER() [2/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
FIFTEENTH  ,
15   
)

◆ TEST_ONE_ORDER() [3/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
FORTYFIRST  ,
41   
)

◆ TEST_ONE_ORDER() [4/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
FORTYTHIRD  ,
43   
)

◆ TEST_ONE_ORDER() [5/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
NINETEENTH  ,
19   
)

◆ TEST_ONE_ORDER() [6/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
SEVENTEENTH  ,
17   
)

◆ TEST_ONE_ORDER() [7/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
THIRTEENTH  ,
13   
)

◆ TEST_ONE_ORDER() [8/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
THIRTYFIFTH  ,
35   
)

◆ TEST_ONE_ORDER() [9/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
THIRTYFIRST  ,
31   
)

◆ TEST_ONE_ORDER() [10/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
THIRTYNINTH  ,
39   
)

◆ TEST_ONE_ORDER() [11/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
THIRTYSEVENTH  ,
37   
)

◆ TEST_ONE_ORDER() [12/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
THIRTYTHIRD  ,
33   
)

◆ TEST_ONE_ORDER() [13/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
TWENTYFIFTH  ,
25   
)

◆ TEST_ONE_ORDER() [14/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
TWENTYFIRST  ,
21   
)

◆ TEST_ONE_ORDER() [15/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
TWENTYNINTH  ,
29   
)

◆ TEST_ONE_ORDER() [16/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
TWENTYSEVENTH  ,
27   
)

◆ TEST_ONE_ORDER() [17/22]

QuadratureTest::TEST_ONE_ORDER ( QGAUSS_LOBATTO  ,
TWENTYTHIRD  ,
23   
)

◆ TEST_ONE_ORDER() [18/22]

QuadratureTest::TEST_ONE_ORDER ( QNODAL  ,
FIRST  ,
 
)

◆ TEST_ONE_ORDER() [19/22]

QuadratureTest::TEST_ONE_ORDER ( QSIMPSON  ,
FIRST  ,
 
)

◆ TEST_ONE_ORDER() [20/22]

QuadratureTest::TEST_ONE_ORDER ( QSIMPSON  ,
SECOND  ,
 
)

◆ TEST_ONE_ORDER() [21/22]

QuadratureTest::TEST_ONE_ORDER ( QSIMPSON  ,
THIRD  ,
 
)

◆ TEST_ONE_ORDER() [22/22]

QuadratureTest::TEST_ONE_ORDER ( QTRAP  ,
FIRST  ,
 
)

◆ TEST_TWENTIETH_ORDER()

QuadratureTest::TEST_TWENTIETH_ORDER ( QGAUSS  ,
9999   
)

◆ testBuild()

template<QuadratureType qtype, Order order>
void QuadratureTest::testBuild ( )
inline

Definition at line 512 of file quadrature_test.C.

513 {
514 LOG_UNIT_TEST;
515
516 std::unique_ptr<QBase> qrule1D = QBase::build (qtype, 1, order);
517 std::unique_ptr<QBase> qrule2D = QBase::build (qtype, 2, order);
518 std::unique_ptr<QBase> qrule3D = QBase::build (qtype, 3, order);
519
520 CPPUNIT_ASSERT_EQUAL ( qtype, qrule1D->type() );
521 CPPUNIT_ASSERT_EQUAL ( qtype, qrule2D->type() );
522 CPPUNIT_ASSERT_EQUAL ( qtype, qrule3D->type() );
523
524 // Simpson's Rule is inherently third-order
525 if (qtype != QSIMPSON)
526 {
527 CPPUNIT_ASSERT_EQUAL ( order, qrule1D->get_base_order() );
528 CPPUNIT_ASSERT_EQUAL ( order, qrule2D->get_base_order() );
529 CPPUNIT_ASSERT_EQUAL ( order, qrule3D->get_base_order() );
530 }
531
532 CPPUNIT_ASSERT_EQUAL ( static_cast<unsigned int>(1) , qrule1D->get_dim() );
533 CPPUNIT_ASSERT_EQUAL ( static_cast<unsigned int>(2) , qrule2D->get_dim() );
534 CPPUNIT_ASSERT_EQUAL ( static_cast<unsigned int>(3) , qrule3D->get_dim() );
535
536 // Test the enum-to-string conversion for this qtype is
537 // implemented, but not what the actual value is.
539 }
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.
std::string enum_to_string(const T e)

References libMesh::QBase::build(), libMesh::Utility::enum_to_string(), and libMesh::QSIMPSON.

◆ testJacobi()

void QuadratureTest::testJacobi ( )
inline

Definition at line 434 of file quadrature_test.C.

435 {
436 LOG_UNIT_TEST;
437
438 constexpr int max_order = 43; // We seriously implemented that?!
439
440 // LibMesh supports two different types of Jacobi quadrature
442
443 // The weights of the Jacobi quadrature rules in libmesh have been
444 // scaled based on their intended use:
445 // (alpha=1, beta=0) rule weights sum to 1/2.
446 // (alpha=2, beta=0) rule weights sum to 1/3.
447 Real initial_sum_weights[2] = {.5, 1./3.};
448
449 // The points of the Jacobi rules in LibMesh are also defined on
450 // [0,1]... this has to be taken into account when computing the
451 // exact integral values in Maple! Also note: if you scale the
452 // points to a different interval, you need to also compute what
453 // the sum of the weights should be for that interval, it will not
454 // simply be the element length for weighted quadrature rules like
455 // Jacobi. For general alpha and beta=0, the sum of the weights
456 // on the interval [-1,1] is 2^(alpha+1) / (alpha+1).
457 std::vector<std::vector<Real>> true_integrals(2);
458
459 // alpha=1 integral values
460 // int((1-x)*x^p, x=0..1) = 1 / (p^2 + 3p + 2)
461 true_integrals[0].resize(max_order);
462 for (std::size_t p=0; p<true_integrals[0].size(); ++p)
463 true_integrals[0][p] = 1. / (p*p + 3.*p + 2.);
464
465 // alpha=2 integral values
466 // int((1-x)^2*x^p, x=0..1) = 2 / (p^3 + 6*p^2 + 11*p + 6)
467 true_integrals[1].resize(max_order);
468 for (std::size_t p=0; p<true_integrals[1].size(); ++p)
469 true_integrals[1][p] = 2. / (p*p*p + 6.*p*p + 11.*p + 6.);
470
471 // Test both types of Jacobi quadrature rules
472 for (int qt=0; qt<2; ++qt)
473 {
474 for (int order=0; order<max_order; ++order)
475 {
476 std::unique_ptr<QBase> qrule = QBase::build(qtype[qt],
477 /*dim=*/1,
478 static_cast<Order>(order));
479
480 // Initialize on a 1D element, EDGE2/3/4 should not matter...
481 qrule->init (EDGE2, 0, true);
482
483 // Test the sum of the weights for this order
484 Real sumw = 0.;
485 for (unsigned int qp=0; qp<qrule->n_points(); qp++)
486 sumw += qrule->w(qp);
487
488 // Make sure that the weights add up to the value we expect
489 LIBMESH_ASSERT_REALS_EQUAL(initial_sum_weights[qt], sumw, quadrature_tolerance);
490
491 // Test integrating different polynomial powers
492 for (int testpower=0; testpower<=order; ++testpower)
493 {
494 // Note that the weighting function, (1-x)^alpha *
495 // (1+x)^beta, is built into these quadrature rules;
496 // the polynomials we actually integrate are just the
497 // usual monomials.
498 Real sumq = 0.;
499 for (unsigned int qp=0; qp<qrule->n_points(); qp++)
500 sumq += qrule->w(qp) * std::pow(qrule->qp(qp)(0), testpower);
501
502 // Make sure that the computed integral agrees with the "true" value
503 LIBMESH_ASSERT_REALS_EQUAL(true_integrals[qt][testpower], sumq, quadrature_tolerance);
504 } // end for(testpower)
505 } // end for(order)
506 } // end for(qt)
507 } // testJacobi
QuadratureType
Defines an enum for currently available quadrature rules.

References libMesh::QBase::build(), libMesh::EDGE2, libMesh::QJACOBI_1_0, libMesh::QJACOBI_2_0, quadrature_tolerance, and libMesh::Real.

◆ testMonomialQuadrature()

void QuadratureTest::testMonomialQuadrature ( )
inline

Definition at line 385 of file quadrature_test.C.

386 {
387 LOG_UNIT_TEST;
388
389 const std::vector<std::vector<ElemType>> all_types =
390 {{EDGE2}, {QUAD4, TRI3}, {HEX8, TET4, PRISM6, PYRAMID5}};
391 const std::vector<std::vector<std::function<Real(int,int,int)>>>
392 true_values =
396
397 for (auto i : index_range(all_types))
398 for (auto j : index_range(all_types[i]))
399 for (int order=0; order<17; ++order)
400 testPolynomials(QMONOMIAL, order, all_types[i][j], true_values[i][j], order);
401 }
void ErrorVector unsigned int
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

References libMesh::EDGE2, edge_integrals, libMesh::HEX8, hex_integrals, libMesh::index_range(), libMesh::PRISM6, prism_integrals, libMesh::PYRAMID5, pyramid_integrals, libMesh::QMONOMIAL, libMesh::QUAD4, quad_integrals, libMesh::Real, testPolynomials(), libMesh::TET4, tet_integrals, libMesh::TRI3, and tri_integrals.

◆ testNodalQuadrature()

void QuadratureTest::testNodalQuadrature ( )
inline

Definition at line 327 of file quadrature_test.C.

328 {
329 LOG_UNIT_TEST;
330
331 const std::vector<std::vector<ElemType>> all_types =
332 {{EDGE2, EDGE3, EDGE4},
333 {TRI3, TRI6, TRI7},
334 {QUAD4, QUAD8, QUAD9},
335 {TET4, TET10, TET14},
336 {HEX8, HEX20, HEX27},
339
340 const std::function<Real(int,int,int)> true_values[] =
348
349 for (auto i : index_range(all_types))
350 for (ElemType elem_type : all_types[i])
351 {
352 const unsigned int order = Elem::build(elem_type)->default_order();
353
354 unsigned int exactorder = order;
355 // There are some sad exceptions to the "positive nodal
356 // quadrature can integrate polynomials up to the element
357 // order" rule.
358 //
359 // Some "quadratic" elements can only exactly integrate
360 // linears when mass lumping.
361 if (elem_type == TRI6 || elem_type == QUAD8 ||
362 elem_type == TET10 || elem_type == HEX20 ||
363 elem_type == PRISM15 || elem_type == PRISM18 ||
364 elem_type == PYRAMID13 || elem_type == PYRAMID14 ||
365 // And some partially-cubic elements can only do quadratics
366 elem_type == TET14 || elem_type == PRISM20)
367 exactorder--;
368
369 // And one partially-cubic element can only do linears.
370 // Seriously.
371 if (elem_type == PYRAMID18)
372 exactorder=1;
373
374 // Our PRISM20 rule was only computed in double precision.
375 if ((sizeof(Real) > sizeof(double)) && elem_type == PRISM20)
377 else // restore the default
379
380 testPolynomials(QNODAL, order, elem_type, true_values[i], exactorder);
381 }
382 }
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition elem.C:442
ElemType
Defines an enum for geometric element types.

References libMesh::Elem::build(), libMesh::EDGE2, libMesh::EDGE3, libMesh::EDGE4, edge_integrals, libMesh::HEX20, libMesh::HEX27, libMesh::HEX8, hex_integrals, libMesh::index_range(), libMesh::PRISM15, libMesh::PRISM18, libMesh::PRISM20, libMesh::PRISM21, libMesh::PRISM6, prism_integrals, libMesh::PYRAMID13, libMesh::PYRAMID14, libMesh::PYRAMID18, libMesh::PYRAMID5, pyramid_integrals, libMesh::QNODAL, libMesh::QUAD4, libMesh::QUAD8, libMesh::QUAD9, quad_integrals, quadrature_tolerance, libMesh::Real, testPolynomials(), libMesh::TET10, libMesh::TET14, libMesh::TET4, tet_integrals, libMesh::TOLERANCE, libMesh::TRI3, libMesh::TRI6, libMesh::TRI7, and tri_integrals.

◆ testPolynomial()

void QuadratureTest::testPolynomial ( QBase qrule,
int  xp,
int  yp,
int  zp,
Real  true_value 
)
inlineprivate

Definition at line 150 of file quadrature_test.C.

153 {
154 Real sum = 0.;
155 for (unsigned int qp=0; qp<qrule.n_points(); qp++)
156 {
157 const Point p = qrule.qp(qp);
158 Real val = qrule.w(qp) * std::pow(p(0),xp);
159 if (qrule.get_dim() > 1)
160 val *= std::pow(p(1),yp);
161 if (qrule.get_dim() > 2)
162 val *= std::pow(p(2),zp);
163 sum += val;
164 }
165
166 // Make sure that the weighted evaluations add up to the true
167 // integral value we expect
168 LIBMESH_ASSERT_REALS_EQUAL(true_value, sum, quadrature_tolerance);
169 }
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
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
Real w(const unsigned int i) const
Definition quadrature.h:188

References libMesh::QBase::get_dim(), libMesh::QBase::n_points(), libMesh::QBase::qp(), quadrature_tolerance, libMesh::Real, and libMesh::QBase::w().

Referenced by testPolynomials().

◆ testPolynomials()

void QuadratureTest::testPolynomials ( QuadratureType  qtype,
int  order,
ElemType  elem_type,
const std::function< Real(int, int, int)> &  true_value,
int  exactorder 
)
inlineprivate

Definition at line 171 of file quadrature_test.C.

175 {
176 auto elem = Elem::build(elem_type);
177 unsigned int dim = elem->dim();
178 std::unique_ptr<QBase> qrule =
179 QBase::build(qtype, dim, static_cast<Order>(order));
180
181 // We are testing integration on the reference elements here, so
182 // the element map is not relevant, and we can safely use nodal
183 // Pyramid quadrature.
184 if (elem_type == PYRAMID5 || elem_type == PYRAMID13 ||
185 elem_type == PYRAMID14 || elem_type == PYRAMID18)
186 qrule->allow_nodal_pyramid_quadrature = true;
187
188 qrule->init (*elem);
189
190 const int max_y_order = dim>1 ? 0 : exactorder;
191 const int max_z_order = dim>2 ? 0 : exactorder;
192
193 for (int xp=0; xp <= exactorder; ++xp)
194 for (int yp=0; yp <= max_y_order; ++yp)
195 for (int zp=0; zp <= max_z_order; ++zp)
196 {
197 // Only try to integrate polynomials we can integrate exactly
198 if (xp + yp + zp > exactorder)
199 continue;
200
201 const Real exact = true_value(xp, yp, zp);
202 testPolynomial(*qrule, xp, yp, zp, exact);
203 }
204 }
unsigned int dim
void testPolynomial(QBase &qrule, int xp, int yp, int zp, Real true_value)

References libMesh::Elem::build(), libMesh::QBase::build(), dim, libMesh::PYRAMID13, libMesh::PYRAMID14, libMesh::PYRAMID18, libMesh::PYRAMID5, libMesh::Real, and testPolynomial().

Referenced by test1DWeights(), test2DWeights(), test3DWeights(), testMonomialQuadrature(), testNodalQuadrature(), testTetQuadrature(), and testTriQuadrature().

◆ testTetQuadrature()

void QuadratureTest::testTetQuadrature ( )
inline

Definition at line 403 of file quadrature_test.C.

404 {
405 LOG_UNIT_TEST;
406
407 // There are 3 different families of quadrature rules for tetrahedra
409
410 int end_order = 7;
411
412 for (int qt=0; qt<3; ++qt)
413 for (int order=0; order<end_order; ++order)
414 {
415 // Our higher order tet rules were only computed to double
416 // precision
417 if ((sizeof(Real) > sizeof(double)) && order > 2)
419 testPolynomials(qtype[qt], order, TET4, tet_integrals, order);
420 }
421 }

References libMesh::QCONICAL, libMesh::QGAUSS, libMesh::QGRUNDMANN_MOLLER, quadrature_tolerance, libMesh::Real, testPolynomials(), libMesh::TET4, tet_integrals, and libMesh::TOLERANCE.

◆ testTriQuadrature()

void QuadratureTest::testTriQuadrature ( )
inline

Definition at line 423 of file quadrature_test.C.

424 {
425 LOG_UNIT_TEST;
426
428
429 for (int qt=0; qt<4; ++qt)
430 for (int order=0; order<10; ++order)
431 testPolynomials(qtype[qt], order, TRI3, tri_integrals, order);
432 }

References libMesh::QCLOUGH, libMesh::QCONICAL, libMesh::QGAUSS, libMesh::QGRUNDMANN_MOLLER, testPolynomials(), libMesh::TRI3, and tri_integrals.

Member Data Documentation

◆ edge_integrals

const std::function<Real(int,int,int)> QuadratureTest::edge_integrals
private
Initial value:
=
[](int mode, int, int) {
return (mode % 2) ? 0 : (Real(2.0) / (mode+1));
}

Definition at line 206 of file quadrature_test.C.

207 {
208 return (mode % 2) ? 0 : (Real(2.0) / (mode+1));
209 };

Referenced by test1DWeights(), testMonomialQuadrature(), and testNodalQuadrature().

◆ hex_integrals

const std::function<Real(int,int,int)> QuadratureTest::hex_integrals
private
Initial value:
=
[](int modex, int modey, int modez) {
const Real exactx = (modex % 2) ?
0 : (Real(2.0) / (modex+1));
const Real exacty = (modey % 2) ?
0 : (Real(2.0) / (modey+1));
const Real exactz = (modez % 2) ?
0 : (Real(2.0) / (modez+1));
return exactx*exacty*exactz;
}

Definition at line 251 of file quadrature_test.C.

252 {
253 const Real exactx = (modex % 2) ?
254 0 : (Real(2.0) / (modex+1));
255
256 const Real exacty = (modey % 2) ?
257 0 : (Real(2.0) / (modey+1));
258
259 const Real exactz = (modez % 2) ?
260 0 : (Real(2.0) / (modez+1));
261
262 return exactx*exacty*exactz;
263 };

Referenced by test3DWeights(), testMonomialQuadrature(), and testNodalQuadrature().

◆ prism_integrals

const std::function<Real(int,int,int)> QuadratureTest::prism_integrals
private
Initial value:
=
[this](int modex, int modey, int modez) {
const Real exactz = (modez % 2) ?
0 : (Real(2.0) / (modez+1));
return exactz * tri_integrals(modex, modey, 0);
}

Definition at line 300 of file quadrature_test.C.

301 {
302 const Real exactz = (modez % 2) ?
303 0 : (Real(2.0) / (modez+1));
304
305 return exactz * tri_integrals(modex, modey, 0);
306 };

Referenced by test3DWeights(), testMonomialQuadrature(), and testNodalQuadrature().

◆ pyramid_integrals

const std::function<Real(int,int,int)> QuadratureTest::pyramid_integrals
private
Initial value:
=
[](int modex, int modey, int modez) {
const int binom = Utility::binomial(modex+modey+modez+3, modez);
if (modex%2 || modey%2)
return Real(0);
return Real(4)/((modex+1)*(modey+1)*binom*(modex+modey+modez+3));
}

Definition at line 308 of file quadrature_test.C.

309 {
310
311 const int binom = Utility::binomial(modex+modey+modez+3, modez);
312
313 if (modex%2 || modey%2)
314 return Real(0);
315
316 return Real(4)/((modex+1)*(modey+1)*binom*(modex+modey+modez+3));
317 };
T binomial(T n, T k)
Definition utility.h:322

Referenced by test3DWeights(), testMonomialQuadrature(), and testNodalQuadrature().

◆ quad_integrals

const std::function<Real(int,int,int)> QuadratureTest::quad_integrals
private
Initial value:
=
[](int modex, int modey, int) {
const Real exactx = (modex % 2) ?
0 : (Real(2.0) / (modex+1));
const Real exacty = (modey % 2) ?
0 : (Real(2.0) / (modey+1));
return exactx*exacty;
}

Definition at line 211 of file quadrature_test.C.

212 {
213 const Real exactx = (modex % 2) ?
214 0 : (Real(2.0) / (modex+1));
215
216 const Real exacty = (modey % 2) ?
217 0 : (Real(2.0) / (modey+1));
218
219 return exactx*exacty;
220 };

Referenced by test2DWeights(), testMonomialQuadrature(), and testNodalQuadrature().

◆ quadrature_tolerance

Real QuadratureTest::quadrature_tolerance
private

◆ tet_integrals

const std::function<Real(int,int,int)> QuadratureTest::tet_integrals
private

Definition at line 265 of file quadrature_test.C.

266 {
267 // Compute the true integral, a! b! c! / (a + b + c + 3)!
268 Real analytical = 1.0;
269
270 // Sort the a, b, c values
271 int sorted_powers[3] = {x_power, y_power, z_power};
272 std::sort(sorted_powers, sorted_powers+3);
273
274 // Cancel the largest power with the denominator, fill in the
275 // entries for the remaining numerator terms and the denominator.
276 std::vector<int>
277 numerator_1(sorted_powers[0] > 1 ? sorted_powers[0]-1 : 0),
278 numerator_2(sorted_powers[1] > 1 ? sorted_powers[1]-1 : 0),
279 denominator(3 + sorted_powers[0] + sorted_powers[1]);
280
281 // Fill up the vectors with sequences starting at the right values.
282 std::iota(numerator_1.begin(), numerator_1.end(), 2);
283 std::iota(numerator_2.begin(), numerator_2.end(), 2);
284 std::iota(denominator.begin(), denominator.end(), sorted_powers[2]+1);
285
286 // The denominator is guaranteed to have the most terms...
287 for (std::size_t i=0; i<denominator.size(); ++i)
288 {
289 if (i < numerator_1.size())
290 analytical *= numerator_1[i];
291
292 if (i < numerator_2.size())
293 analytical *= numerator_2[i];
294
295 analytical /= denominator[i];
296 }
297 return analytical;
298 };

Referenced by test3DWeights(), testMonomialQuadrature(), testNodalQuadrature(), and testTetQuadrature().

◆ tri_integrals

const std::function<Real(int,int,int)> QuadratureTest::tri_integrals
private
Initial value:
=
[](int x_power, int y_power, int) {
Real analytical = 1.0;
unsigned
larger_power = std::max(x_power, y_power),
smaller_power = std::min(x_power, y_power);
std::vector<unsigned>
numerator(smaller_power > 1 ? smaller_power-1 : 0),
denominator(2+smaller_power);
std::iota(numerator.begin(), numerator.end(), 2);
std::iota(denominator.begin(), denominator.end(), larger_power+1);
for (std::size_t i=0; i<denominator.size(); ++i)
{
if (i < numerator.size())
analytical *= numerator[i];
analytical /= denominator[i];
}
return analytical;
}

Definition at line 222 of file quadrature_test.C.

223 {
224 // Compute the true integral, a! b! / (a + b + 2)!
225 Real analytical = 1.0;
226
227 unsigned
228 larger_power = std::max(x_power, y_power),
229 smaller_power = std::min(x_power, y_power);
230
231 // Cancel the larger of the two numerator terms with the
232 // denominator, and fill in the remaining entries.
233 std::vector<unsigned>
234 numerator(smaller_power > 1 ? smaller_power-1 : 0),
235 denominator(2+smaller_power);
236
237 // Fill up the vectors with sequences starting at the right values.
238 std::iota(numerator.begin(), numerator.end(), 2);
239 std::iota(denominator.begin(), denominator.end(), larger_power+1);
240
241 // The denominator is guaranteed to have more terms...
242 for (std::size_t i=0; i<denominator.size(); ++i)
243 {
244 if (i < numerator.size())
245 analytical *= numerator[i];
246 analytical /= denominator[i];
247 }
248 return analytical;
249 };

Referenced by test2DWeights(), testMonomialQuadrature(), testNodalQuadrature(), and testTriQuadrature().


The documentation for this class was generated from the following file: