27 const double tol = 1.0E-12;
30 std::vector<util::Point> &nodes) {
33 io::CSVReader<3> in(filename);
35 while (in.read_row(x, y, z))
36 nodes.emplace_back(x, y, z);
39 size_t readElements(
const std::string &filename,
const size_t &elem_type,
40 std::vector<size_t> &elements) {
43 io::CSVReader<3> in(filename);
44 std::vector<size_t> ids(3, 0);
45 while (in.read_row(ids[0], ids[1], ids[2])) {
47 elements.emplace_back(
id);
51 return elements.size() / num_vertex;
53 io::CSVReader<4> in(filename);
54 std::vector<size_t> ids(4, 0);
55 while (in.read_row(ids[0], ids[1], ids[2], ids[3])) {
57 elements.emplace_back(
id);
61 return elements.size() / num_vertex;
63 io::CSVReader<4> in(filename);
64 std::vector<size_t> ids(4, 0);
65 while (in.read_row(ids[0], ids[1], ids[2], ids[3])) {
67 elements.emplace_back(
id);
71 return elements.size() / num_vertex;
73 std::cerr <<
"Error: readElements() only supports vtk_type_triangle, vtk_type_quad, and vtk_type_tetra elem_type in testing.\n";
80 const std::vector<fe::QuadData> &qds,
85 I_approx += qd.d_w * std::pow(qd.d_p.d_x, i) * std::pow(qd.d_p.d_y, j);
87 if (std::abs(I_exact - I_approx) >
tol) {
88 std::cout <<
"Error in order = " << n <<
". Exact integration = " << I_exact
89 <<
" and approximate integration = " << I_approx
90 <<
" of polynomial of order (i = " << i <<
" + j = " << j
91 <<
") = " << i + j <<
" over reference element "
92 <<
"is not matching using quadrature points.\n";
101 const size_t &j,
const size_t &k,
102 const std::vector<fe::QuadData> &qds,
105 double I_approx = 0.;
107 I_approx += qd.d_w * std::pow(qd.d_p.d_x, i) * std::pow(qd.d_p.d_y, j) *
108 std::pow(qd.d_p.d_z, k);
110 if (std::abs(I_exact - I_approx) >
tol) {
111 std::cout <<
"Error in order = " << n <<
". Exact integration = " << I_exact
112 <<
" and approximate integration = " << I_approx
113 <<
" of polynomial of order (i = " << i <<
" + j = " << j
114 <<
" + k = " << k <<
") = " << i + j + k
115 <<
" over reference element "
116 <<
"is not matching using quadrature points.\n";
118 std::cout <<
"Print " << i <<
" " << j <<
" " << k
119 <<
" debug id = " <<
debug_id <<
"\n";
121 std::cout << qd.printStr() <<
"\n";
141 for (
size_t i = 1; i <= r; i++)
142 a *=
double(n - i + 1) / double(i);
151 for (
size_t k = 0; k <= beta + 1; k++) {
166 if (alpha % 2 == 0 and beta % 2 == 0)
167 return 4. / double((alpha + 1) * (beta + 1));
176 for (
size_t i = 0; i <= theta + 1; i++) {
179 (double(theta + 1) * double(i + beta + 1));
181 factor_i = factor_i * (-1.);
183 for (
size_t j = 0; j <= theta + beta + 2 + 1; j++) {
188 factor_j = factor_j * (-1.);
190 I += factor_i * factor_j;
216 size_t error_test_1 = 0;
222 std::vector<fe::QuadData> qds = quad.getQuadPoints(nodes);
227 if (std::abs(sum - 0.5) >
tol) {
228 std::cout <<
"Error in order = " << n
229 <<
". Sum of quad weights is not "
230 "equal to area of reference "
238 for (
size_t i = 0; i <= n; i++)
239 for (
size_t j = 0; j <= n; j++) {
249 qds = quad.getQuadPoints(nodes);
261 qds = quad.getQuadPoints(nodes);
280 qds = quad.getQuadPoints(nodes);
289 size_t error_test_2 = 0;
291 static std::vector<util::Point> nodes;
292 static std::vector<size_t> elements;
293 static size_t num_vertex = 3;
295 static size_t num_elems = 0;
296 if (num_elems == 0) {
297 readNodes(filepath +
"/triMesh_nodes.csv", nodes);
298 num_elems =
readElements(filepath +
"/triMesh_elements.csv", elem_type,
303 for (
size_t i = 0; i <= n; i++)
304 for (
size_t j = 0; j <= n; j++) {
309 double I_exact = 1. / (double(i + 1) * double(j + 1));
310 double I_approx = 0.;
312 for (
size_t e = 0; e < num_elems; e++) {
313 std::vector<util::Point> enodes = {
314 nodes[elements[num_vertex * e + 0]],
315 nodes[elements[num_vertex * e + 1]],
316 nodes[elements[num_vertex * e + 2]]};
317 std::vector<fe::QuadData> qds = quad.getQuadPoints(enodes);
320 qd.d_w * std::pow(qd.d_p.d_x, i) * std::pow(qd.d_p.d_y, j);
323 if (std::abs(I_exact - I_approx) >
tol) {
324 std::cout <<
"Error in order = " << n
325 <<
". Exact integration = " << I_exact
326 <<
" and approximate integration = " << I_approx
327 <<
" of polynomial of order (i = " << i <<
" + j = " << j
328 <<
") = " << i + j <<
" over square domain [0,1]x[0,1] "
329 <<
"is not matching using quadrature points.\n";
337 std::cout <<
"**********************************\n";
338 std::cout <<
"Triangle Quadrature Test\n";
339 std::cout <<
"**********************************\n";
341 std::cout <<
"Quad order = " << n <<
". ";
342 if (error_test_1 == 0)
343 std::cout <<
"TEST 1 : PASS. ";
345 std::cout <<
"TEST 1 : FAIL. ";
346 if (error_test_2 == 0)
347 std::cout <<
"TEST 2 : PASS. ";
349 std::cout <<
"TEST 2 : FAIL. ";
369 size_t error_test_1 = 0;
373 std::vector<util::Point> nodes = {
376 std::vector<fe::QuadData> qds = quad.getQuadPoints(nodes);
381 if (std::abs(sum - 4.0) >
tol) {
382 std::cout <<
"Error in order = " << n
383 <<
". Sum of quad weights is not "
384 "equal to area of reference "
392 for (
size_t i = 0; i <= 2 * n - 1; i++)
393 for (
size_t j = 0; j <= 2 * n - 1; j++) {
400 qds = quad.getQuadPoints(nodes);
412 qds = quad.getQuadPoints(nodes);
431 qds = quad.getQuadPoints(nodes);
440 qds = quad.getQuadPoints(nodes);
449 size_t error_test_2 = 0;
451 static std::vector<util::Point> nodes;
452 static std::vector<size_t> elements;
453 static size_t num_vertex = 4;
455 static size_t num_elems = 0;
456 if (num_elems == 0) {
457 readNodes(filepath +
"/quadMesh_nodes.csv", nodes);
458 num_elems =
readElements(filepath +
"/quadMesh_elements.csv", elem_type,
463 for (
size_t i = 0; i <= 2 * n - 1; i++)
464 for (
size_t j = 0; j <= 2 * n - 1; j++) {
466 double I_exact = 1. / (double(i + 1) * double(j + 1));
467 double I_approx = 0.;
469 for (
size_t e = 0; e < num_elems; e++) {
470 std::vector<util::Point> enodes = {
471 nodes[elements[num_vertex * e + 0]],
472 nodes[elements[num_vertex * e + 1]],
473 nodes[elements[num_vertex * e + 2]],
474 nodes[elements[num_vertex * e + 3]]};
475 std::vector<fe::QuadData> qds = quad.getQuadPoints(enodes);
478 qd.d_w * std::pow(qd.d_p.d_x, i) * std::pow(qd.d_p.d_y, j);
481 if (std::abs(I_exact - I_approx) >
tol) {
482 std::cout <<
"Error in order = " << n
483 <<
". Exact integration = " << I_exact
484 <<
" and approximate integration = " << I_approx
485 <<
" of polynomial of order (i = " << i <<
" + j = " << j
486 <<
") = " << i + j <<
" over square domain [0,1]x[0,1] "
487 <<
"is not matching using quadrature points.\n";
495 std::cout <<
"**********************************\n";
496 std::cout <<
"Quadrangle Quadrature Test\n";
497 std::cout <<
"**********************************\n";
499 std::cout <<
"Quad order = " << n <<
". ";
500 std::cout << (error_test_1 == 0 ?
"TEST 1 : PASS. " :
"TEST 1 : FAIL. ");
501 std::cout << (error_test_2 == 0 ?
"TEST 2 : PASS. \n" :
"TEST 2 : FAIL. \n");
512 std::vector<util::Point> nodes = {
util::Point(2., 2., 0.),
515 size_t num_vertex = 3;
519 std::vector<std::vector<size_t>> elements;
520 for (
size_t i = 0; i < N; i++)
521 elements.emplace_back(std::vector<size_t>{0, 1, 2});
523 auto t11 = steady_clock::now();
527 for (
size_t e = 0; e < N; e++) {
533 std::vector<util::Point> enodes = {
534 nodes[elements[e][0]], nodes[elements[e][1]], nodes[elements[e][2]]};
535 std::vector<fe::QuadData> qds = quad.getQuadPoints(enodes);
537 sum += qd.d_w * (qd.d_shapes[0] + qd.d_shapes[1] + qd.d_shapes[2]);
539 auto t12 = steady_clock::now();
542 size_t num_quad_pts = 0;
543 std::vector<fe::QuadData> quad_data;
544 for (
size_t e = 0; e < N; e++) {
545 std::vector<fe::QuadData> qds = quad.getQuadPoints(nodes);
547 num_quad_pts = qds.size();
549 quad_data.emplace_back(qd);
552 auto t21 = steady_clock::now();
554 for (
size_t e = 0; e < N; e++) {
555 for (
size_t q = 0; q < num_quad_pts; q++) {
560 auto t22 = steady_clock::now();
562 if (n == 1 and N == 1000) {
563 std::cout <<
"**********************************\n";
564 std::cout <<
"Quadrature Time Efficiency Test\n";
565 std::cout <<
"**********************************\n";
567 std::cout <<
"Quad order = " << n <<
". Num Elements = " << N <<
".\n ";
570 double perc = (dt_1 - dt_2) * 100. / dt_2;
571 double qpt_mem = 13 *
sizeof(double);
572 double mem2 = double(quad_data.capacity() * qpt_mem) / double(1000000);
573 std::cout <<
" dt1 = " << dt_1 <<
", dt2 = " << dt_2 <<
", perc = " << perc
574 <<
". Mem saved = " << mem2 <<
" MB.\n";
593 size_t error_test_1 = 0;
600 std::vector<fe::QuadData> qds = quad.getQuadPoints(nodes);
606 if (std::abs(sum - 1. / 6.) >
tol) {
607 std::cout <<
"Error in order = " << n
608 <<
". Sum of quad weights is not "
609 "equal to volume of reference "
617 for (
size_t i = 0; i <= n; i++)
618 for (
size_t j = 0; j <= n; j++)
619 for (
size_t k = 0; k <= n; k++) {
633 qds = quad.getQuadPoints(nodes);
647 qds = quad.getQuadPoints(nodes);
667 qds = quad.getQuadPoints(nodes);
677 qds = quad.getQuadPoints(nodes);
687 size_t error_test_2 = 0;
689 static std::vector<util::Point> nodes;
690 static std::vector<size_t> elements;
691 static size_t num_vertex = 4;
693 static size_t num_elems = 0;
694 if (num_elems == 0) {
695 readNodes(filepath +
"tetMesh_nodes.csv", nodes);
696 num_elems =
readElements(filepath +
"tetMesh_elements.csv", elem_type,
701 for (
size_t i = 0; i <= n; i++)
702 for (
size_t j = 0; j <= n; j++)
703 for (
size_t k = 0; k <= n; k++) {
708 double I_exact = 1. / (double(i + 1) * double(j + 1) * double(k + 1));
709 double I_approx = 0.;
711 for (
size_t e = 0; e < num_elems; e++) {
712 std::vector<util::Point> enodes = {
713 nodes[elements[num_vertex * e + 0]],
714 nodes[elements[num_vertex * e + 1]],
715 nodes[elements[num_vertex * e + 2]],
716 nodes[elements[num_vertex * e + 3]]};
717 std::vector<fe::QuadData> qds = quad.getQuadPoints(enodes);
718 for (
auto qd : qds) {
719 I_approx += qd.d_w * std::pow(qd.d_p.d_x, i) *
720 std::pow(qd.d_p.d_y, j) * std::pow(qd.d_p.d_z, k);
724 std::cout <<
"Print " << i <<
" " << j <<
" " << k <<
"\n";
726 std::vector<size_t> enode_ids = {
727 elements[num_vertex * e + 0],
728 elements[num_vertex * e + 1],
729 elements[num_vertex * e + 2],
730 elements[num_vertex * e + 3]};
732 std::cout << qd.printStr() <<
"\n";
738 if (std::abs(I_exact - I_approx) >
tol) {
739 std::cout <<
"Error in order = " << n
740 <<
". Exact integration = " << I_exact
741 <<
" and approximate integration = " << I_approx
742 <<
" of polynomial of order (i = " << i <<
" + j = " << j
743 <<
" + k = " << k <<
") = " << i + j + k
744 <<
" over cubic domain [0,1]x[0,1]x[0,1] "
745 <<
"is not matching using quadrature points.\n";
753 std::cout <<
"**********************************\n";
754 std::cout <<
"Tetrahedron Quadrature Test\n";
755 std::cout <<
"**********************************\n";
757 std::cout <<
"Quad order = " << n <<
". ";
758 if (error_test_1 == 0)
759 std::cout <<
"TEST 1 : PASS. ";
761 std::cout <<
"TEST 1 : FAIL. ";
A class for mapping and quadrature related operations for bi-linear quadrangle element.
A class for mapping and quadrature related operations for linear tetrahedron element.
A class for mapping and quadrature related operations for linear triangle element.
static int vtk_map_element_to_num_nodes[16]
Map from element type to number of nodes (for vtk)
static const int vtk_type_triangle
Integer flag for triangle element.
static const int vtk_type_quad
Integer flag for quad element.
static const int vtk_type_tetra
Integer flag for tetrahedron element.
size_t readElements(const std::string &filename, const size_t &elem_type, std::vector< size_t > &elements)
void readNodes(const std::string &filename, std::vector< util::Point > &nodes)
bool checkRefIntegration(const size_t &n, const size_t &i, const size_t &j, const std::vector< fe::QuadData > &qds, double &I_exact)
void testTriElemTime(size_t n, size_t N)
Computes the time needed when quad data for elements are stored and when they are computed as and whe...
double getExactIntegrationRefTri(size_t alpha, size_t beta)
Computes integration of polynomial exactly over reference triangle.
double getNChooseR(size_t n, size_t r)
Computes "n choose r".
double getExactIntegrationRefQuad(size_t alpha, size_t beta)
Computes integration of polynomial exactly over reference quadrangle.
void testLineElem(size_t n, std::string filepath)
Perform test on quadrature points on line elements (NOT IMPLEMENTED)
void testTetElem(size_t n, std::string filepath)
Perform test on quadrature points on tetrahedral elements.
void testQuadElem(size_t n, std::string filepath)
Perform test on quadrature points on quadrangle elements.
double getExactIntegrationRefTet(size_t alpha, size_t beta, size_t theta)
Computes integration of polynomial exactly over reference tetrahedral.
void testTriElem(size_t n, std::string filepath)
Perform test on quadrature points on triangle elements.
std::string printStr(const T &msg, int nt=print_default_tab)
Returns formatted string for output.
float timeDiff(std::chrono::steady_clock::time_point begin, std::chrono::steady_clock::time_point end, std::string unit="microseconds")
Returns difference between two times.
A struct to store the quadrature data. List of data are.
std::vector< double > d_shapes
Value of shape functions at quad point p.
double d_w
Quadrature weight.
A structure to represent 3d vectors.