29 const double tol = 1.0E-12;
32 const std::vector<util::Point> &u) {
33 std::vector<double> uflat(B.
nDof());
34 const int dim = B.
dim();
35 for (
size_t a = 0; a < u.size(); a++) {
36 uflat[dim *
static_cast<int>(a)] = u[a][0];
38 uflat[dim *
static_cast<int>(a) + 1] = u[a][1];
40 uflat[dim *
static_cast<int>(a) + 2] = u[a][2];
42 std::vector<double> e(B.
nStrain(), 0.);
43 for (
int i = 0; i < B.
nStrain(); i++)
44 for (
int j = 0; j < B.
nDof(); j++)
45 e[i] += B(i, j) * uflat[j];
50 s(0, 1) = (dim == 2) ? e[2] : e[5];
61 std::vector<util::Point> &nodes) {
64 io::CSVReader<3> in(filename);
66 while (in.read_row(x, y, z))
67 nodes.emplace_back(x, y, z);
70 size_t readElements(
const std::string &filename,
const size_t &elem_type,
71 std::vector<size_t> &elements) {
74 io::CSVReader<3> in(filename);
75 std::vector<size_t> ids(3, 0);
76 while (in.read_row(ids[0], ids[1], ids[2])) {
78 elements.emplace_back(
id);
82 return elements.size() / num_vertex;
84 io::CSVReader<4> in(filename);
85 std::vector<size_t> ids(4, 0);
86 while (in.read_row(ids[0], ids[1], ids[2], ids[3])) {
88 elements.emplace_back(
id);
92 return elements.size() / num_vertex;
94 io::CSVReader<4> in(filename);
95 std::vector<size_t> ids(4, 0);
96 while (in.read_row(ids[0], ids[1], ids[2], ids[3])) {
98 elements.emplace_back(
id);
102 return elements.size() / num_vertex;
104 std::cerr <<
"Error: readElements() only supports vtk_type_triangle, vtk_type_quad, and vtk_type_tetra elem_type in testing.\n";
111 const std::vector<fe::QuadData> &qds,
114 double I_approx = 0.;
116 I_approx += qd.d_w * std::pow(qd.d_p.d_x, i) * std::pow(qd.d_p.d_y, j);
118 if (std::abs(I_exact - I_approx) >
tol) {
119 std::cout <<
"Error in order = " << n <<
". Exact integration = " << I_exact
120 <<
" and approximate integration = " << I_approx
121 <<
" of polynomial of order (i = " << i <<
" + j = " << j
122 <<
") = " << i + j <<
" over reference element "
123 <<
"is not matching using quadrature points.\n";
132 const size_t &j,
const size_t &k,
133 const std::vector<fe::QuadData> &qds,
136 double I_approx = 0.;
138 I_approx += qd.d_w * std::pow(qd.d_p.d_x, i) * std::pow(qd.d_p.d_y, j) *
139 std::pow(qd.d_p.d_z, k);
141 if (std::abs(I_exact - I_approx) >
tol) {
142 std::cout <<
"Error in order = " << n <<
". Exact integration = " << I_exact
143 <<
" and approximate integration = " << I_approx
144 <<
" of polynomial of order (i = " << i <<
" + j = " << j
145 <<
" + k = " << k <<
") = " << i + j + k
146 <<
" over reference element "
147 <<
"is not matching using quadrature points.\n";
149 std::cout <<
"Print " << i <<
" " << j <<
" " << k
150 <<
" debug id = " <<
debug_id <<
"\n";
152 std::cout << qd.printStr() <<
"\n";
172 for (
size_t i = 1; i <= r; i++)
173 a *=
double(n - i + 1) / double(i);
182 for (
size_t k = 0; k <= beta + 1; k++) {
197 if (alpha % 2 == 0 and beta % 2 == 0)
198 return 4. / double((alpha + 1) * (beta + 1));
207 for (
size_t i = 0; i <= theta + 1; i++) {
210 (double(theta + 1) * double(i + beta + 1));
212 factor_i = factor_i * (-1.);
214 for (
size_t j = 0; j <= theta + beta + 2 + 1; j++) {
219 factor_j = factor_j * (-1.);
221 I += factor_i * factor_j;
247 size_t error_test_1 = 0;
253 std::vector<fe::QuadData> qds = quad.getQuadPoints(nodes);
258 if (std::abs(sum - 0.5) >
tol) {
259 std::cout <<
"Error in order = " << n
260 <<
". Sum of quad weights is not "
261 "equal to area of reference "
269 for (
size_t i = 0; i <= n; i++)
270 for (
size_t j = 0; j <= n; j++) {
280 qds = quad.getQuadPoints(nodes);
292 qds = quad.getQuadPoints(nodes);
311 qds = quad.getQuadPoints(nodes);
320 size_t error_test_2 = 0;
322 static std::vector<util::Point> nodes;
323 static std::vector<size_t> elements;
324 static size_t num_vertex = 3;
326 static size_t num_elems = 0;
327 if (num_elems == 0) {
328 readNodes(filepath +
"/triMesh_nodes.csv", nodes);
329 num_elems =
readElements(filepath +
"/triMesh_elements.csv", elem_type,
334 for (
size_t i = 0; i <= n; i++)
335 for (
size_t j = 0; j <= n; j++) {
340 double I_exact = 1. / (double(i + 1) * double(j + 1));
341 double I_approx = 0.;
343 for (
size_t e = 0; e < num_elems; e++) {
344 std::vector<util::Point> enodes = {
345 nodes[elements[num_vertex * e + 0]],
346 nodes[elements[num_vertex * e + 1]],
347 nodes[elements[num_vertex * e + 2]]};
348 std::vector<fe::QuadData> qds = quad.getQuadPoints(enodes);
351 qd.d_w * std::pow(qd.d_p.d_x, i) * std::pow(qd.d_p.d_y, j);
354 if (std::abs(I_exact - I_approx) >
tol) {
355 std::cout <<
"Error in order = " << n
356 <<
". Exact integration = " << I_exact
357 <<
" and approximate integration = " << I_approx
358 <<
" of polynomial of order (i = " << i <<
" + j = " << j
359 <<
") = " << i + j <<
" over square domain [0,1]x[0,1] "
360 <<
"is not matching using quadrature points.\n";
368 std::cout <<
"**********************************\n";
369 std::cout <<
"Triangle Quadrature Test\n";
370 std::cout <<
"**********************************\n";
372 std::cout <<
"Quad order = " << n <<
". ";
373 if (error_test_1 == 0)
374 std::cout <<
"TEST 1 : PASS. ";
376 std::cout <<
"TEST 1 : FAIL. ";
377 if (error_test_2 == 0)
378 std::cout <<
"TEST 2 : PASS. ";
380 std::cout <<
"TEST 2 : FAIL. ";
400 size_t error_test_1 = 0;
404 std::vector<util::Point> nodes = {
407 std::vector<fe::QuadData> qds = quad.getQuadPoints(nodes);
412 if (std::abs(sum - 4.0) >
tol) {
413 std::cout <<
"Error in order = " << n
414 <<
". Sum of quad weights is not "
415 "equal to area of reference "
423 for (
size_t i = 0; i <= 2 * n - 1; i++)
424 for (
size_t j = 0; j <= 2 * n - 1; j++) {
431 qds = quad.getQuadPoints(nodes);
443 qds = quad.getQuadPoints(nodes);
462 qds = quad.getQuadPoints(nodes);
471 qds = quad.getQuadPoints(nodes);
480 size_t error_test_2 = 0;
482 static std::vector<util::Point> nodes;
483 static std::vector<size_t> elements;
484 static size_t num_vertex = 4;
486 static size_t num_elems = 0;
487 if (num_elems == 0) {
488 readNodes(filepath +
"/quadMesh_nodes.csv", nodes);
489 num_elems =
readElements(filepath +
"/quadMesh_elements.csv", elem_type,
494 for (
size_t i = 0; i <= 2 * n - 1; i++)
495 for (
size_t j = 0; j <= 2 * n - 1; j++) {
497 double I_exact = 1. / (double(i + 1) * double(j + 1));
498 double I_approx = 0.;
500 for (
size_t e = 0; e < num_elems; e++) {
501 std::vector<util::Point> enodes = {
502 nodes[elements[num_vertex * e + 0]],
503 nodes[elements[num_vertex * e + 1]],
504 nodes[elements[num_vertex * e + 2]],
505 nodes[elements[num_vertex * e + 3]]};
506 std::vector<fe::QuadData> qds = quad.getQuadPoints(enodes);
509 qd.d_w * std::pow(qd.d_p.d_x, i) * std::pow(qd.d_p.d_y, j);
512 if (std::abs(I_exact - I_approx) >
tol) {
513 std::cout <<
"Error in order = " << n
514 <<
". Exact integration = " << I_exact
515 <<
" and approximate integration = " << I_approx
516 <<
" of polynomial of order (i = " << i <<
" + j = " << j
517 <<
") = " << i + j <<
" over square domain [0,1]x[0,1] "
518 <<
"is not matching using quadrature points.\n";
526 std::cout <<
"**********************************\n";
527 std::cout <<
"Quadrangle Quadrature Test\n";
528 std::cout <<
"**********************************\n";
530 std::cout <<
"Quad order = " << n <<
". ";
531 std::cout << (error_test_1 == 0 ?
"TEST 1 : PASS. " :
"TEST 1 : FAIL. ");
532 std::cout << (error_test_2 == 0 ?
"TEST 2 : PASS. \n" :
"TEST 2 : FAIL. \n");
543 std::vector<util::Point> nodes = {
util::Point(2., 2., 0.),
546 size_t num_vertex = 3;
550 std::vector<std::vector<size_t>> elements;
551 for (
size_t i = 0; i < N; i++)
552 elements.emplace_back(std::vector<size_t>{0, 1, 2});
554 auto t11 = steady_clock::now();
558 for (
size_t e = 0; e < N; e++) {
564 std::vector<util::Point> enodes = {
565 nodes[elements[e][0]], nodes[elements[e][1]], nodes[elements[e][2]]};
566 std::vector<fe::QuadData> qds = quad.getQuadPoints(enodes);
568 sum += qd.d_w * (qd.d_shapes[0] + qd.d_shapes[1] + qd.d_shapes[2]);
570 auto t12 = steady_clock::now();
573 size_t num_quad_pts = 0;
574 std::vector<fe::QuadData> quad_data;
575 for (
size_t e = 0; e < N; e++) {
576 std::vector<fe::QuadData> qds = quad.getQuadPoints(nodes);
578 num_quad_pts = qds.size();
580 quad_data.emplace_back(qd);
583 auto t21 = steady_clock::now();
585 for (
size_t e = 0; e < N; e++) {
586 for (
size_t q = 0; q < num_quad_pts; q++) {
591 auto t22 = steady_clock::now();
593 if (n == 1 and N == 1000) {
594 std::cout <<
"**********************************\n";
595 std::cout <<
"Quadrature Time Efficiency Test\n";
596 std::cout <<
"**********************************\n";
598 std::cout <<
"Quad order = " << n <<
". Num Elements = " << N <<
".\n ";
601 double perc = (dt_1 - dt_2) * 100. / dt_2;
602 double qpt_mem = 13 *
sizeof(double);
603 double mem2 = double(quad_data.capacity() * qpt_mem) / double(1000000);
604 std::cout <<
" dt1 = " << dt_1 <<
", dt2 = " << dt_2 <<
", perc = " << perc
605 <<
". Mem saved = " << mem2 <<
" MB.\n";
624 size_t error_test_1 = 0;
631 std::vector<fe::QuadData> qds = quad.getQuadPoints(nodes);
637 if (std::abs(sum - 1. / 6.) >
tol) {
638 std::cout <<
"Error in order = " << n
639 <<
". Sum of quad weights is not "
640 "equal to volume of reference "
648 for (
size_t i = 0; i <= n; i++)
649 for (
size_t j = 0; j <= n; j++)
650 for (
size_t k = 0; k <= n; k++) {
664 qds = quad.getQuadPoints(nodes);
678 qds = quad.getQuadPoints(nodes);
698 qds = quad.getQuadPoints(nodes);
708 qds = quad.getQuadPoints(nodes);
718 size_t error_test_2 = 0;
720 static std::vector<util::Point> nodes;
721 static std::vector<size_t> elements;
722 static size_t num_vertex = 4;
724 static size_t num_elems = 0;
725 if (num_elems == 0) {
726 readNodes(filepath +
"tetMesh_nodes.csv", nodes);
727 num_elems =
readElements(filepath +
"tetMesh_elements.csv", elem_type,
732 for (
size_t i = 0; i <= n; i++)
733 for (
size_t j = 0; j <= n; j++)
734 for (
size_t k = 0; k <= n; k++) {
739 double I_exact = 1. / (double(i + 1) * double(j + 1) * double(k + 1));
740 double I_approx = 0.;
742 for (
size_t e = 0; e < num_elems; e++) {
743 std::vector<util::Point> enodes = {
744 nodes[elements[num_vertex * e + 0]],
745 nodes[elements[num_vertex * e + 1]],
746 nodes[elements[num_vertex * e + 2]],
747 nodes[elements[num_vertex * e + 3]]};
748 std::vector<fe::QuadData> qds = quad.getQuadPoints(enodes);
749 for (
auto qd : qds) {
750 I_approx += qd.d_w * std::pow(qd.d_p.d_x, i) *
751 std::pow(qd.d_p.d_y, j) * std::pow(qd.d_p.d_z, k);
755 std::cout <<
"Print " << i <<
" " << j <<
" " << k <<
"\n";
757 std::vector<size_t> enode_ids = {
758 elements[num_vertex * e + 0],
759 elements[num_vertex * e + 1],
760 elements[num_vertex * e + 2],
761 elements[num_vertex * e + 3]};
763 std::cout << qd.printStr() <<
"\n";
769 if (std::abs(I_exact - I_approx) >
tol) {
770 std::cout <<
"Error in order = " << n
771 <<
". Exact integration = " << I_exact
772 <<
" and approximate integration = " << I_approx
773 <<
" of polynomial of order (i = " << i <<
" + j = " << j
774 <<
" + k = " << k <<
") = " << i + j + k
775 <<
" over cubic domain [0,1]x[0,1]x[0,1] "
776 <<
"is not matching using quadrature points.\n";
784 std::cout <<
"**********************************\n";
785 std::cout <<
"Tetrahedron Quadrature Test\n";
786 std::cout <<
"**********************************\n";
788 std::cout <<
"Quad order = " << n <<
". ";
789 if (error_test_1 == 0)
790 std::cout <<
"TEST 1 : PASS. ";
792 std::cout <<
"TEST 1 : FAIL. ";
801 const double ptol = 1.0e-5;
803 const std::vector<util::Point> nodes = {
806 const std::vector<util::Point> u = {
811 for (
const auto &qd : qds) {
813 if (std::abs(e(0, 0) - 2.) > ptol || std::abs(e(1, 1) - 3.) > ptol ||
814 std::abs(e(0, 1)) > ptol)
817 std::cout <<
"**********************************\n";
818 std::cout <<
"Patch test (triangle, linear u)\n";
819 std::cout <<
"**********************************\n";
821 std::cout <<
"PATCH TRI : FAIL.\n";
824 std::cout <<
"PATCH TRI : PASS.\n";
828 const double ptol = 1.0e-5;
830 const std::vector<util::Point> nodes = {
833 const std::vector<util::Point> u = {
838 for (
const auto &qd : qds) {
840 if (std::abs(e(0, 0) - 2.) > ptol || std::abs(e(1, 1) - 3.) > ptol ||
841 std::abs(e(0, 1)) > ptol)
844 std::cout <<
"**********************************\n";
845 std::cout <<
"Patch test (quad, linear u)\n";
846 std::cout <<
"**********************************\n";
848 std::cout <<
"PATCH QUAD : FAIL.\n";
851 std::cout <<
"PATCH QUAD : PASS.\n";
855 const double ptol = 1.0e-5;
857 const std::vector<util::Point> nodes = {
860 const std::vector<util::Point> u = {
865 for (
const auto &qd : qds) {
867 if (std::abs(e(0, 0) - 2.) > ptol || std::abs(e(1, 1) - 3.) > ptol ||
868 std::abs(e(2, 2) - 4.) > ptol || std::abs(e(0, 1)) > ptol ||
869 std::abs(e(0, 2)) > ptol || std::abs(e(1, 2)) > ptol)
872 std::cout <<
"**********************************\n";
873 std::cout <<
"Patch test (tet, linear u)\n";
874 std::cout <<
"**********************************\n";
876 std::cout <<
"PATCH TET : FAIL.\n";
879 std::cout <<
"PATCH TET : PASS.\n";
883 const double ptol = 1.0e-5;
885 const std::vector<util::Point> nodes = {
888 const std::vector<util::Point> u = {
893 for (
const auto &qd : qds) {
895 if (std::abs(e(0, 0) - 2.) > ptol || std::abs(e(1, 1) - 3.) > ptol ||
896 std::abs(e(0, 1)) > ptol)
899 std::cout <<
"**********************************\n";
900 std::cout <<
"Patch test (distorted triangle, linear u)\n";
901 std::cout <<
"**********************************\n";
903 std::cout <<
"PATCH TRI DISTORTED : FAIL.\n";
906 std::cout <<
"PATCH TRI DISTORTED : PASS.\n";
std::vector< fe::QuadData > getQuadDatas(const std::vector< util::Point > &nodes)
Get quadrature data mapped to the physical element (N, dN/dx, x, w, J). Shared isoparametric map; typ...
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)
util::SymMatrix3 strainFromB(const fe::B &B, const std::vector< util::Point > &u)
void testPatchTriDistorted()
Perform test on quadrature points on line elements (NOT IMPLEMENTED)
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.
void testPatchTet()
Perform test on quadrature points on line elements (NOT IMPLEMENTED)
void testPatchQuad()
Perform test on quadrature points on line elements (NOT IMPLEMENTED)
void testPatchTri()
Perform test on quadrature points on line elements (NOT IMPLEMENTED)
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.
A structure to represent 3d matrices.