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 );