1 #include <libmesh/quadrature.h> 
    2 #include <libmesh/string_to_enum.h> 
    3 #include <libmesh/utility.h> 
    4 #include <libmesh/enum_quadrature_type.h> 
   17 #define TEST_ONE_ORDER(qtype, order, maxorder)                          \ 
   18   CPPUNIT_TEST( testBuild<qtype MACROCOMMA order> );                    \ 
   19   CPPUNIT_TEST( test1DWeights<qtype MACROCOMMA order MACROCOMMA maxorder> ); \ 
   20   CPPUNIT_TEST( test2DWeights<qtype MACROCOMMA order MACROCOMMA maxorder> ); \ 
   21   CPPUNIT_TEST( test3DWeights<qtype MACROCOMMA order MACROCOMMA maxorder> ); 
   23 #define TEST_ONE_ORDER(qtype, order, maxorder)                          \ 
   24   CPPUNIT_TEST( testBuild<qtype MACROCOMMA order> );                    \ 
   25   CPPUNIT_TEST( test1DWeights<qtype MACROCOMMA order MACROCOMMA maxorder> ); \ 
   26   CPPUNIT_TEST( test2DWeights<qtype MACROCOMMA order MACROCOMMA maxorder> ); 
   28 #define TEST_ONE_ORDER(qtype, order, maxorder)                          \ 
   29   CPPUNIT_TEST( testBuild<qtype MACROCOMMA order> );                    \ 
   30   CPPUNIT_TEST( test1DWeights<qtype MACROCOMMA order MACROCOMMA maxorder> ); 
   34 #define mymin(a, b) (a < b ? a : b) 
   36 #define TEST_ALL_ORDERS(qtype, maxorder)                \ 
   37   TEST_ONE_ORDER(qtype, FIRST, mymin(1,maxorder));      \ 
   38   TEST_ONE_ORDER(qtype, SECOND, mymin(2,maxorder));     \ 
   39   TEST_ONE_ORDER(qtype, THIRD, mymin(3,maxorder));      \ 
   40   TEST_ONE_ORDER(qtype, FOURTH, mymin(4,maxorder));     \ 
   41   TEST_ONE_ORDER(qtype, FIFTH, mymin(5,maxorder));      \ 
   42   TEST_ONE_ORDER(qtype, SIXTH, mymin(6,maxorder));      \ 
   43   TEST_ONE_ORDER(qtype, SEVENTH, mymin(7,maxorder));    \ 
   44   TEST_ONE_ORDER(qtype, EIGHTH, mymin(8,maxorder));     \ 
   45   TEST_ONE_ORDER(qtype, NINTH, mymin(9,maxorder)); 
   47 #define LIBMESH_ASSERT_REALS_EQUAL(first, second, tolerance)            \ 
   48   if (std::abs(first-second) >= tolerance)                              \ 
   50       std::cerr << "first = " << first << std::endl;                    \ 
   51       std::cerr << "second = " << second << std::endl;                  \ 
   52       std::cerr << "error = " << std::abs(first-second) << std::endl;   \ 
   53       std::cerr << "tolerance = " << tolerance << std::endl;            \ 
   55   CPPUNIT_ASSERT (std::abs(first-second) < tolerance) 
   61   TEST_ALL_ORDERS(
QGAUSS, 9999);
 
   66   TEST_ALL_ORDERS(
QGRID, 1);
 
   98   CPPUNIT_TEST( testMonomialQuadrature );
 
  102   CPPUNIT_TEST( testTriQuadrature );
 
  107   CPPUNIT_TEST( testTetQuadrature );
 
  111   CPPUNIT_TEST( testJacobi );
 
  113   CPPUNIT_TEST_SUITE_END();
 
  130     int dims[2]           = {2, 3};
 
  132     for (
int i=0; i<(LIBMESH_DIM-1); ++i)
 
  136         for (
int order=0; order<7; ++order)
 
  140                                                         static_cast<Order>(order));
 
  141             qrule->init(elem_type[i]);
 
  144             int max_z_power = dims[i]==2 ? 0 : order;
 
  147             for (xyz_power[0]=0; xyz_power[0]<=order; ++xyz_power[0])
 
  148               for (xyz_power[1]=0; xyz_power[1]<=order; ++xyz_power[1])
 
  149                 for (xyz_power[2]=0; xyz_power[2]<=max_z_power; ++xyz_power[2])
 
  152                     if (xyz_power[0] + xyz_power[1] + xyz_power[2] > order)
 
  158                     for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  160                         Real term = qrule->w(qp);
 
  161                         for (
unsigned int d=0; d != LIBMESH_DIM; ++d)
 
  162                           term *= 
std::pow(qrule->qp(qp)(d), xyz_power[d]);
 
  172                     Real exact_x = (xyz_power[0] % 2) ? 0 : (
Real(2.0) / (xyz_power[0]+1));
 
  173                     Real exact_y = (xyz_power[1] % 2) ? 0 : (
Real(2.0) / (xyz_power[1]+1));
 
  174                     Real exact_z = (xyz_power[2] % 2) ? 0 : (
Real(2.0) / (xyz_power[2]+1));
 
  180                     Real exact = exact_x*exact_y*exact_z;
 
  183                     LIBMESH_ASSERT_REALS_EQUAL(exact, sumq, quadrature_tolerance);
 
  196     if (quadrature_tolerance < 1e-16)
 
  199     for (
int qt=0; qt<3; ++qt)
 
  200       for (
int order=0; order<end_order; ++order)
 
  204                                                       static_cast<Order>(order));
 
  211           for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  212             sumw += qrule->w(qp);
 
  215           LIBMESH_ASSERT_REALS_EQUAL(1/
Real(6), sumw, quadrature_tolerance);
 
  218           for (
int x_power=0; x_power<=order; ++x_power)
 
  219             for (
int y_power=0; y_power<=order; ++y_power)
 
  220               for (
int z_power=0; z_power<=order; ++z_power)
 
  223                   if (x_power + y_power + z_power > order)
 
  228                   for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  230                       * 
std::pow(qrule->qp(qp)(0), x_power)
 
  231                       * 
std::pow(qrule->qp(qp)(1), y_power)
 
  232                       * 
std::pow(qrule->qp(qp)(2), z_power);
 
  237                   Real analytical = 1.0;
 
  240                     int sorted_powers[3] = {x_power, y_power, z_power};
 
  241                     std::sort(sorted_powers, sorted_powers+3);
 
  246                       numerator_1(sorted_powers[0] > 1 ? sorted_powers[0]-1 : 0),
 
  247                       numerator_2(sorted_powers[1] > 1 ? sorted_powers[1]-1 : 0),
 
  248                       denominator(3 + sorted_powers[0] + sorted_powers[1]);
 
  251                     std::iota(numerator_1.begin(), numerator_1.end(), 2);
 
  252                     std::iota(numerator_2.begin(), numerator_2.end(), 2);
 
  253                     std::iota(denominator.begin(), denominator.end(), sorted_powers[2]+1);
 
  256                     for (std::size_t i=0; i<denominator.size(); ++i)
 
  258                         if (i < numerator_1.size())
 
  259                           analytical *= numerator_1[i];
 
  261                         if (i < numerator_2.size())
 
  262                           analytical *= numerator_2[i];
 
  264                         analytical /= denominator[i];
 
  271                   LIBMESH_ASSERT_REALS_EQUAL(analytical, sumq, quadrature_tolerance);
 
  280     for (
int qt=0; qt<4; ++qt)
 
  281       for (
int order=0; order<10; ++order)
 
  285                                                       static_cast<Order>(order));
 
  292           for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  293             sumw += qrule->w(qp);
 
  296           LIBMESH_ASSERT_REALS_EQUAL(0.5, sumw, quadrature_tolerance);
 
  299           for (
int x_power=0; x_power<=order; ++x_power)
 
  300             for (
int y_power=0; y_power<=order; ++y_power)
 
  303                 if (x_power + y_power > order)
 
  308                 for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  310                     * 
std::pow(qrule->qp(qp)(0), x_power)
 
  311                     * 
std::pow(qrule->qp(qp)(1), y_power);
 
  316                 Real analytical = 1.0;
 
  319                     larger_power = std::max(x_power, y_power),
 
  320                     smaller_power = std::min(x_power, y_power);
 
  324                   std::vector<unsigned>
 
  325                     numerator(smaller_power > 1 ? smaller_power-1 : 0),
 
  326                     denominator(2+smaller_power);
 
  329                   std::iota(numerator.begin(), numerator.end(), 2);
 
  330                   std::iota(denominator.begin(), denominator.end(), larger_power+1);
 
  333                   for (std::size_t i=0; i<denominator.size(); ++i)
 
  335                       if (i < numerator.size())
 
  336                         analytical *= numerator[i];
 
  337                       analytical /= denominator[i];
 
  344                 LIBMESH_ASSERT_REALS_EQUAL(analytical, sumq, quadrature_tolerance);
 
  358     Real initial_sum_weights[2] = {.5, 1./3.};
 
  368     std::vector<std::vector<Real>> true_integrals(2);
 
  372     true_integrals[0].resize(10);
 
  373     for (std::size_t p=0; p<true_integrals[0].size(); ++p)
 
  374       true_integrals[0][p] = 1. / (p*p + 3.*p + 2.);
 
  378     true_integrals[1].resize(10);
 
  379     for (std::size_t p=0; p<true_integrals[1].size(); ++p)
 
  380       true_integrals[1][p] = 2. / (p*p*p + 6.*p*p + 11.*p + 6.);
 
  383     for (
int qt=0; qt<2; ++qt)
 
  385         for (
int order=0; order<10; ++order)
 
  389                                                         static_cast<Order>(order));
 
  396             for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  397               sumw += qrule->w(qp);
 
  400             LIBMESH_ASSERT_REALS_EQUAL(initial_sum_weights[qt], sumw, quadrature_tolerance);
 
  403             for (
int testpower=0; testpower<=order; ++testpower)
 
  410                 for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  411                   sumq += qrule->w(qp) * 
std::pow(qrule->qp(qp)(0), testpower);
 
  414                 LIBMESH_ASSERT_REALS_EQUAL(true_integrals[qt][testpower], sumq, quadrature_tolerance);
 
  422   template <QuadratureType qtype, Order order>
 
  425     std::unique_ptr<QBase> qrule1D = 
QBase::build (qtype, 1, order);
 
  426     std::unique_ptr<QBase> qrule2D = 
QBase::build (qtype, 2, order);
 
  427     std::unique_ptr<QBase> qrule3D = 
QBase::build (qtype, 3, order);
 
  429     CPPUNIT_ASSERT_EQUAL ( static_cast<unsigned int>(1) , qrule1D->get_dim() );
 
  430     CPPUNIT_ASSERT_EQUAL ( static_cast<unsigned int>(2) , qrule2D->get_dim() );
 
  431     CPPUNIT_ASSERT_EQUAL ( static_cast<unsigned int>(3) , qrule3D->get_dim() );
 
  442   template <QuadratureType qtype, Order order, 
unsigned int exactorder>
 
  445     std::unique_ptr<QBase> qrule = 
QBase::build(qtype , 1, order);
 
  448     for (
unsigned int mode=0; mode <= exactorder; ++mode)
 
  452         for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  453           sum += qrule->w(qp) * 
std::pow(qrule->qp(qp)(0), static_cast<Real>(mode));
 
  455         const Real exact = (mode % 2) ?
 
  456           0 : (
Real(2.0) / (mode+1));
 
  458         if (
std::abs(exact - sum) >= quadrature_tolerance)
 
  460             std::cout << 
"qtype = " << qtype << std::endl;
 
  461             std::cout << 
"order = " << order << std::endl;
 
  462             std::cout << 
"exactorder = " << exactorder << std::endl;
 
  463             std::cout << 
"mode = " << mode << std::endl;
 
  464             std::cout << 
"exact = " << exact << std::endl;
 
  465             std::cout << 
"sum = " << sum << std::endl << std::endl;
 
  468         LIBMESH_ASSERT_REALS_EQUAL( exact , sum , quadrature_tolerance );
 
  476   template <QuadratureType qtype, Order order, 
unsigned int exactorder>
 
  479     std::unique_ptr<QBase> qrule = 
QBase::build(qtype, 2, order);
 
  482     for (
unsigned int modex=0; modex <= exactorder; ++modex)
 
  483       for (
unsigned int modey=0; modey <= exactorder; ++modey)
 
  487           for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  489               * 
std::pow(qrule->qp(qp)(0), static_cast<Real>(modex))
 
  490               * 
std::pow(qrule->qp(qp)(1), static_cast<Real>(modey));
 
  492           const Real exactx = (modex % 2) ?
 
  493             0 : (
Real(2.0) / (modex+1));
 
  495           const Real exacty = (modey % 2) ?
 
  496             0 : (
Real(2.0) / (modey+1));
 
  498           const Real exact = exactx*exacty;
 
  500           LIBMESH_ASSERT_REALS_EQUAL( exact , sum , quadrature_tolerance );
 
  510         for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  513         LIBMESH_ASSERT_REALS_EQUAL( 0.5 , sum , quadrature_tolerance );
 
  521   template <QuadratureType qtype, Order order, 
unsigned int exactorder>
 
  524     std::unique_ptr<QBase> qrule = 
QBase::build(qtype, 3, order);
 
  527     for (
unsigned int modex=0; modex <= exactorder; ++modex)
 
  528       for (
unsigned int modey=0; modey <= exactorder; ++modey)
 
  529         for (
unsigned int modez=0; modez <= exactorder; ++modez)
 
  533             for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  535                 * 
std::pow(qrule->qp(qp)(0), static_cast<Real>(modex))
 
  536                 * 
std::pow(qrule->qp(qp)(1), static_cast<Real>(modey))
 
  537                 * 
std::pow(qrule->qp(qp)(2), static_cast<Real>(modez));
 
  539             const Real exactx = (modex % 2) ?
 
  540               0 : (
Real(2.0) / (modex+1));
 
  542             const Real exacty = (modey % 2) ?
 
  543               0 : (
Real(2.0) / (modey+1));
 
  545             const Real exactz = (modez % 2) ?
 
  546               0 : (
Real(2.0) / (modez+1));
 
  548             const Real exact = exactx*exacty*exactz;
 
  550             LIBMESH_ASSERT_REALS_EQUAL( exact , sum , quadrature_tolerance );
 
  560         for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  563         LIBMESH_ASSERT_REALS_EQUAL( 1/
Real(6), sum , quadrature_tolerance );
 
  569         for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  572         LIBMESH_ASSERT_REALS_EQUAL( 1., sum , quadrature_tolerance );