38int main(
int argc,
char *argv[]) {
44 moab::Core mb_instance;
45 moab::Interface &moab = mb_instance;
53 INTEGRATEDJACOBIPOLYNOMIAL,
55 H1TET_BERNSTEIN_BEZIER,
62 H1TRI_BERNSTEIN_BEZIER,
70 H1EDGE_BERNSTEIN_BEZIER,
79 const char *list[] = {
"legendre",
84 "h1tet_bernstein_bezier",
91 "h1tri_bernstein_bezier",
99 "h1edge_bernstein_bezier",
100 "hcurledge_ainsworth",
101 "hcurledge_demkowicz",
107 PetscInt choice_value = LEGENDREPOLYNOMIAL;
109 &choice_value, &flg);
111 if (flg != PETSC_TRUE) {
120 boost::shared_ptr<MatrixDouble> base_ptr(
new MatrixDouble);
121 boost::shared_ptr<MatrixDouble> diff_base_ptr(
new MatrixDouble);
123 const double eps = 1e-3;
125 if (choice_value == LEGENDREPOLYNOMIAL) {
129 4, &diff_s, 1, base_ptr, diff_base_ptr)));
132 std::cout <<
"LegendrePolynomial\n";
133 std::cout << pts_1d << std::endl;
134 std::cout << *base_ptr << std::endl;
135 std::cout << *diff_base_ptr << std::endl;
138 std::cout << sum << std::endl;
139 std::cout << diff_sum << std::endl;
140 if (fabs(2.04688 - sum) >
eps) {
143 if (fabs(2.25 - diff_sum) >
eps) {
148 pts_1d.resize(1, 11,
false);
149 for (
int ii = 0; ii != 11; ii++) {
150 pts_1d(0, ii) = 2 * ((
double)ii / 10) - 1;
153 boost::shared_ptr<MatrixDouble> kernel_base_ptr(
new MatrixDouble);
154 boost::shared_ptr<MatrixDouble> diff_kernel_base_ptr(
new MatrixDouble);
156 if (choice_value == LOBATTOPOLYNOMIAL) {
160 7 + 2, &diff_s, 1, base_ptr, diff_base_ptr)));
165 7, &diff_s, 1, kernel_base_ptr, diff_kernel_base_ptr)));
167 for (
int ii = 0; ii != 11; ii++) {
168 double s = pts_1d(0, ii);
169 std::cerr <<
"lobatto_plot " << s <<
" " << (*base_ptr)(ii, 1) <<
" "
170 << (*diff_base_ptr)(ii, 1) <<
" " << (*kernel_base_ptr)(ii, 1)
171 <<
" " << (*diff_kernel_base_ptr)(ii, 1) <<
" "
172 << (*kernel_base_ptr)(ii, 1) * (1 - s * s) <<
" "
173 << (*kernel_base_ptr)(ii, 1) * (-2 * s) +
174 (*diff_kernel_base_ptr)(ii, 1) * (1 - s * s)
177 std::cout <<
"LobattoPolynomial\n";
178 std::cout << pts_1d << std::endl;
179 std::cout << *base_ptr << std::endl;
180 std::cout << *diff_base_ptr << std::endl;
184 std::cout << sum << std::endl;
185 std::cout << diff_sum << std::endl;
186 if (fabs(9.39466 - sum) >
eps) {
189 if (fabs(14.0774 - diff_sum) >
eps) {
195 double diff_sum =
sum_matrix(*diff_kernel_base_ptr);
196 std::cout << sum << std::endl;
197 std::cout << diff_sum << std::endl;
198 if (fabs(-13.9906 * 4 - sum) >
eps) {
201 if (fabs(-101.678 * 4 - diff_sum) >
eps) {
207 if (choice_value == JACOBIPOLYNOMIAL) {
211 pts_1d.resize(1,
n,
false);
213 for (
int ii = 0; ii !=
n; ii++) {
214 pts_1d(0, ii) = (
double)ii / (
n - 1);
219 diff_base_ptr->clear();
226 5, &diff_x, &diff_t, 1, 0, base_ptr, diff_base_ptr)));
228 for (
int ii = 0; ii !=
n; ii++) {
229 double s = pts_1d(0, ii);
230 std::cerr <<
"jacobi_plot " << s <<
" " << (*base_ptr)(ii, 4) <<
" "
231 << (*diff_base_ptr)(ii, 4) << std::endl;
233 for (
int ii = 0; ii !=
n - 1; ii++) {
234 double s = (pts_1d(0, ii) + pts_1d(0, ii + 1)) / 2;
235 std::cerr <<
"jacobi_diff_plot_fd " << s <<
" "
236 << ((*base_ptr)(ii + 1, 4) - (*base_ptr)(ii, 4)) /
240 std::cout <<
"JacobiPolynomial\n";
241 std::cout << pts_1d << std::endl;
242 std::cout << *base_ptr << std::endl;
243 std::cout << *diff_base_ptr << std::endl;
247 std::cout << sum << std::endl;
248 std::cout << diff_sum << std::endl;
249 if (fabs(23.2164 - sum) >
eps) {
252 if (fabs(167.995 - diff_sum) >
eps) {
258 if (choice_value == INTEGRATEDJACOBIPOLYNOMIAL) {
262 pts_1d.resize(1,
n,
false);
264 for (
int ii = 0; ii !=
n; ii++) {
265 pts_1d(0, ii) = (
double)ii / 20.;
266 pts_1d_t(0, ii) = 1 - pts_1d(0, ii);
270 diff_base_ptr->clear();
277 6, &diff_x, &diff_t, 1, 1, base_ptr, diff_base_ptr)));
279 for (
int ii = 0; ii !=
n; ii++) {
280 double s = pts_1d(0, ii);
281 std::cerr <<
"integrated_jacobi_plot " << s <<
" " << (
double)ii / 20.
282 <<
" " << (*base_ptr)(ii, 1) <<
" " << (*base_ptr)(ii, 2)
283 <<
" " << (*base_ptr)(ii, 3) <<
" " << (*base_ptr)(ii, 4)
284 <<
" " << (*base_ptr)(ii, 5) << endl;
288 std::cout <<
"IntegratedJacobiPolynomial\n";
289 std::cout << pts_1d << std::endl;
290 std::cout << *base_ptr << std::endl;
291 std::cout << *diff_base_ptr << std::endl;
295 std::cout << sum << std::endl;
296 std::cout << diff_sum << std::endl;
316 for (
int ee = 0; ee < 6; ee++) {
321 for (
int ff = 0; ff < 4; ff++) {
327 tet_data.
dataOnEntities[MBVERTEX][0].getBBNodeOrder().resize(4,
false);
328 std::fill(tet_data.
dataOnEntities[MBVERTEX][0].getBBNodeOrder().begin(),
334 pts_tet.resize(3, nb_gauss_pts,
false);
335 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[tet_rule]->points[1], 4,
337 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[tet_rule]->points[2], 4,
339 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[tet_rule]->points[3], 4,
346 cblas_dcopy(4 * nb_gauss_pts,
QUAD_3D_TABLE[tet_rule]->points, 1,
350 const int cannonical_tet_face[4][3] = {
351 {0, 1, 3}, {1, 2, 3}, {0, 3, 2}, {0, 2, 1}};
352 for (
int ff = 0; ff < 4; ff++) {
353 for (
int nn = 0; nn < 3; nn++) {
354 tet_data.
facesNodes(ff, nn) = cannonical_tet_face[ff][nn];
358 if (choice_value == H1TET_AINSWORTH) {
364 &pts_tet(0, 0), &pts_tet(1, 0), &pts_tet(2, 0), nb_gauss_pts);
378 double sum = 0, diff_sum = 0;
379 std::cout <<
"Edges\n";
380 for (
int ee = 0; ee < 6; ee++) {
392 std::cout <<
"Faces\n";
393 for (
int ff = 0; ff < 4; ff++) {
405 std::cout <<
"Tets\n";
416 std::cout <<
"sum " << sum << std::endl;
417 std::cout <<
"diff_sum " << diff_sum << std::endl;
418 if (fabs(1.3509 - sum) >
eps) {
421 if (fabs(0.233313 - diff_sum) >
eps) {
426 if (choice_value == H1TET_BERNSTEIN_BEZIER) {
431 const int bb_order = tet_data.
dataOnEntities[MBTET][0].getOrder();
432 for (
int ee = 0; ee < 6; ee++)
434 for (
int ff = 0; ff < 4; ff++)
436 std::fill(tet_data.
dataOnEntities[MBVERTEX][0].getBBNodeOrder().begin(),
444 &pts_tet(0, 0), &pts_tet(1, 0), &pts_tet(2, 0), nb_gauss_pts);
455 double sum = 0, diff_sum = 0;
456 std::cout <<
"Vertices\n";
457 std::cout << tet_data.
dataOnEntities[MBVERTEX][0].getN(
"TEST_FIELD")
459 std::cout << tet_data.
dataOnEntities[MBVERTEX][0].getDiffN(
"TEST_FIELD")
465 std::cout <<
"Edges\n";
466 for (
int ee = 0; ee < 6; ee++) {
467 std::cout << tet_data.
dataOnEntities[MBEDGE][ee].getN(
"TEST_FIELD")
469 std::cout << tet_data.
dataOnEntities[MBEDGE][ee].getDiffN(
"TEST_FIELD")
476 std::cout <<
"Faces\n";
477 for (
int ff = 0; ff < 4; ff++) {
478 std::cout << tet_data.
dataOnEntities[MBTRI][ff].getN(
"TEST_FIELD")
480 std::cout << tet_data.
dataOnEntities[MBTRI][ff].getDiffN(
"TEST_FIELD")
487 std::cout <<
"Tets\n";
490 std::cout << tet_data.
dataOnEntities[MBTET][0].getDiffN(
"TEST_FIELD")
495 std::cout <<
"sum " << sum << std::endl;
496 std::cout <<
"diff_sum " << diff_sum << std::endl;
499 if (fabs(
static_cast<double>(pts_tet.size2()) - sum) >
eps) {
501 "wrong result %3.4e != %3.4e",
502 static_cast<double>(pts_tet.size2()), sum);
504 if (fabs(diff_sum) >
eps) {
511 auto check_l2_bb = [&](
const int l2_order) {
517 for (
auto &ptr : l2_ent_data.getBBAlphaIndicesByOrderArray())
519 for (
auto &ptr : l2_ent_data.getBBNByOrderArray())
521 for (
auto &ptr : l2_ent_data.getBBDiffNByOrderArray())
523 l2_ent_data.getOrder() = l2_order;
532 std::cout <<
"L2 order " << l2_order <<
"\n" <<
n << std::endl;
533 if (
n.size1() != pts_tet.size2() ||
535 diff_n.size1() != pts_tet.size2() ||
538 "wrong size of L2 BB base for order %d", l2_order);
539 for (
unsigned int gg = 0; gg !=
n.size1(); ++gg) {
541 for (
unsigned int bb = 0; bb !=
n.size2(); ++bb)
542 row_sum +=
n(gg, bb);
543 if (fabs(1. - row_sum) >
eps)
545 "L2 BB base of order %d does not sum to one at point %d: "
547 l2_order, gg, row_sum);
551 "L2 BB base gradients of order %d do not sum to zero",
556 CHKERR check_l2_bb(bb_order);
560 if (choice_value == HDIVTET_AINSWORTH) {
565 double sum = 0, diff_sum = 0;
566 std::cout <<
"Faces\n";
567 for (
int ff = 0; ff < 4; ff++) {
579 std::cout <<
"Tets\n";
590 std::cout <<
"sum " << 1e8 * sum << std::endl;
591 std::cout <<
"diff_sum " << 1e8 * diff_sum << std::endl;
592 if (fabs(0.178713 - sum) >
eps) {
595 if (fabs(31.6048 - diff_sum) >
eps) {
600 if (choice_value == HDIVTET_DEMKOWICZ) {
605 double sum = 0, diff_sum = 0;
606 std::cout <<
"Faces\n";
607 for (
int ff = 0; ff < 4; ff++) {
619 std::cout <<
"Tets\n";
629 std::cout <<
"sum " << sum << std::endl;
630 std::cout <<
"diff_sum " << diff_sum << std::endl;
631 const double expected_result = -2.70651;
632 const double expected_diff_result = 289.421;
633 if (fabs((expected_result - sum) / expected_result) >
eps) {
636 if (fabs((expected_diff_result - diff_sum) / expected_diff_result) >
642 if (choice_value == HCURLTET_AINSWORTH) {
647 double sum = 0, diff_sum = 0;
648 std::cout <<
"Edges\n";
649 for (
int ee = 0; ee < 6; ee++) {
661 std::cout <<
"Faces\n";
662 for (
int ff = 0; ff < 4; ff++) {
674 std::cout <<
"Tets\n";
685 std::cout <<
"sum " << sum << std::endl;
686 std::cout <<
"diff_sum " << diff_sum << std::endl;
687 if (fabs(-1.7798 - sum) >
eps) {
690 if (fabs(-67.1793 - diff_sum) >
eps) {
695 if (choice_value == HCURLTET_DEMKOWICZ) {
699 double sum = 0, diff_sum = 0;
700 std::cout <<
"Edges\n";
701 for (
int ee = 0; ee < 6; ee++) {
713 std::cout <<
"Faces\n";
714 for (
int ff = 0; ff < 4; ff++) {
726 std::cout <<
"Tets\n";
736 std::cout <<
"sum " << sum << std::endl;
737 std::cout <<
"diff_sum " << diff_sum << std::endl;
738 if (fabs(7.35513 - sum) >
eps) {
741 if (fabs(62.4549 - diff_sum) >
eps) {
746 if (choice_value == L2TET) {
751 double sum = 0, diff_sum = 0;
752 std::cout <<
"Tets\n";
763 std::cout <<
"sum " << sum << std::endl;
764 std::cout <<
"diff_sum " << diff_sum << std::endl;
765 if (fabs(3.60352 - sum) >
eps) {
768 if (fabs(-36.9994 - diff_sum) >
eps) {
783 for (
int ee = 0; ee < 3; ee++) {
789 tri_data.
dataOnEntities[MBVERTEX][0].getBBNodeOrder().resize(3,
false);
790 std::fill(tri_data.
dataOnEntities[MBVERTEX][0].getBBNodeOrder().begin(),
796 pts_tri.resize(2, nb_gauss_pts,
false);
797 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[tri_rule]->points[1], 3,
799 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[tri_rule]->points[2], 3,
806 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[tri_rule]->points, 1,
814 if (choice_value == H1TRI_AINSWORTH) {
823 double sum = 0, diff_sum = 0;
824 std::cout <<
"Edges\n";
825 for (
int ee = 0; ee < 3; ee++) {
837 std::cout <<
"Face\n";
848 std::cout <<
"sum " << sum << std::endl;
849 std::cout <<
"diff_sum " << diff_sum << std::endl;
850 if (fabs(0.805556 - sum) >
eps)
853 if (fabs(0.0833333 - diff_sum) >
eps)
857 if (choice_value == H1TRI_BERNSTEIN_BEZIER) {
859 const int bb_order = tri_data.
dataOnEntities[MBTRI][0].getOrder();
860 for (
int ee = 0; ee < 3; ee++)
862 std::fill(tri_data.
dataOnEntities[MBVERTEX][0].getBBNodeOrder().begin(),
874 "Pointers should be diffrent");
876 double sum = 0, diff_sum = 0;
877 std::cout <<
"Vertex\n";
878 std::cout << tri_data.
dataOnEntities[MBVERTEX][0].getN(
"TET_FIELD")
880 std::cout << tri_data.
dataOnEntities[MBVERTEX][0].getDiffN(
"TET_FIELD")
885 std::cout <<
"Edges\n";
886 for (
int ee = 0; ee < 3; ee++) {
887 std::cout << tri_data.
dataOnEntities[MBEDGE][ee].getN(
"TET_FIELD")
889 std::cout << tri_data.
dataOnEntities[MBEDGE][ee].getDiffN(
"TET_FIELD")
896 std::cout <<
"Face\n";
899 std::cout << tri_data.
dataOnEntities[MBTRI][0].getDiffN(
"TET_FIELD")
904 std::cout <<
"sum " << sum << std::endl;
905 std::cout <<
"diff_sum " << diff_sum << std::endl;
907 if (std::abs(
static_cast<double>(pts_tri.size2()) - sum) >
eps)
909 "wrong result %3.4e != %3.4e",
910 static_cast<double>(pts_tri.size2()), sum);
912 if (std::abs(diff_sum) >
eps)
914 "wrong result %3.4e != %3.4e", 0., diff_sum);
917 auto check_l2_bb = [&](
const int l2_order) {
923 for (
auto &ptr : l2_ent_data.getBBAlphaIndicesByOrderArray())
925 for (
auto &ptr : l2_ent_data.getBBNByOrderArray())
927 for (
auto &ptr : l2_ent_data.getBBDiffNByOrderArray())
929 l2_ent_data.getOrder() = l2_order;
938 std::cout <<
"L2 order " << l2_order <<
"\n" <<
n << std::endl;
939 if (
n.size1() != pts_tri.size2() ||
941 diff_n.size1() != pts_tri.size2() ||
944 "wrong size of L2 BB base for order %d", l2_order);
945 for (
unsigned int gg = 0; gg !=
n.size1(); ++gg) {
947 for (
unsigned int bb = 0; bb !=
n.size2(); ++bb)
948 row_sum +=
n(gg, bb);
949 if (std::abs(1. - row_sum) >
eps)
951 "L2 BB base of order %d does not sum to one at point %d: "
953 l2_order, gg, row_sum);
957 "L2 BB base gradients of order %d do not sum to zero",
962 CHKERR check_l2_bb(bb_order);
966 if (choice_value == HDIVTRI_AINSWORTH) {
976 std::cout <<
"Face\n";
982 std::cout <<
"sum " << sum << std::endl;
983 if (fabs(2.21296 - sum) >
eps)
987 if (choice_value == HDIVTRI_DEMKOWICZ) {
998 std::cout <<
"Face\n";
1003 std::cout <<
"sum " << sum << std::endl;
1004 const double expected_result = 28.25;
1005 if (fabs((expected_result - sum) / expected_result) >
eps) {
1010 if (choice_value == HCURLTRI_AINSWORTH) {
1021 std::cout <<
"Edges\n";
1022 for (
int ee = 0; ee < 3; ee++) {
1029 std::cout <<
"Face\n";
1035 std::cout <<
"sum " << sum << std::endl;
1036 if (fabs(0.333333 - sum) >
eps) {
1041 if (choice_value == HCURLTRI_DEMKOWICZ) {
1051 std::cout <<
"Edges\n";
1052 for (
int ee = 0; ee < 3; ee++) {
1059 std::cout <<
"Face\n";
1064 std::cout <<
"sum " << sum << std::endl;
1065 if (fabs(1.04591 - sum) >
eps) {
1070 if (choice_value == L2TRI) {
1081 std::cout <<
"Face\n";
1087 std::cout <<
"sum " << sum << std::endl;
1088 if (fabs(0.671875 - sum) >
eps) {
1105 edge_data.
dataOnEntities[MBVERTEX][0].getBBNodeOrder().resize(2,
false);
1106 std::fill(edge_data.
dataOnEntities[MBVERTEX][0].getBBNodeOrder().begin(),
1107 edge_data.
dataOnEntities[MBVERTEX][0].getBBNodeOrder().end(), 4);
1112 pts_edge.resize(2, nb_gauss_pts,
false);
1113 cblas_dcopy(nb_gauss_pts, &
QUAD_1D_TABLE[edge_rule]->points[1], 2,
1114 &pts_edge(0, 0), 1);
1115 cblas_dcopy(nb_gauss_pts,
QUAD_1D_TABLE[edge_rule]->weights, 1,
1116 &pts_edge(1, 0), 1);
1123 cblas_dcopy(2 * nb_gauss_pts,
QUAD_1D_TABLE[edge_rule]->points, 1,
1127 if (choice_value == H1EDGE_AINSWORTH) {
1136 double sum = 0, diff_sum = 0;
1137 std::cout <<
"Edge\n";
1148 std::cout <<
"sum " << sum << std::endl;
1149 std::cout <<
"diff sum " << diff_sum << std::endl;
1150 if (std::abs(0.506122 - sum) >
eps)
1153 if (std::abs(-0.571429 - diff_sum) >
eps)
1157 if (choice_value == H1EDGE_BERNSTEIN_BEZIER) {
1167 "Should be diffrent pointers");
1169 double sum = 0, diff_sum = 0;
1170 std::cout <<
"Vertex\n";
1171 std::cout << edge_data.
dataOnEntities[MBVERTEX][0].getN(
"TET_FIELD")
1173 std::cout << edge_data.
dataOnEntities[MBVERTEX][0].getDiffN(
"TET_FIELD")
1175 std::cout <<
"Edge\n";
1176 std::cout << edge_data.
dataOnEntities[MBEDGE][0].getN(
"TET_FIELD")
1178 std::cout << edge_data.
dataOnEntities[MBEDGE][0].getDiffN(
"TET_FIELD")
1187 std::cout <<
"sum " << sum << std::endl;
1188 std::cout <<
"diff sum " << diff_sum << std::endl;
1189 if (std::abs(4 - sum) >
eps)
1192 if (std::abs(diff_sum) >
eps)
1196 if (choice_value == HCURLEDGE_AINSWORTH) {
1212 std::cout.precision(std::numeric_limits<double>::max_digits10 - 1);
1213 std::cout <<
"sum " << sum << std::endl;
1214 if (fabs(-4.174149659863944 - sum) >
eps) {
1219 if (choice_value == HCURLEDGE_DEMKOWICZ) {
1233 std::cout.precision(std::numeric_limits<double>::max_digits10 - 1);
1234 std::cout <<
"sum " << sum << std::endl;
1235 if (std::fabs(4.571428571428571 - sum) >
eps) {
1240 if (choice_value == L2EDGE) {
1258 std::cout <<
"sum " << sum << std::endl;
1259 if (std::fabs(sum) >
eps) {
1262 "Difference between ainsworth and demkowicz base should be zero");
1269 if (base.size1() != pts_edge.size2())
1271 "wrong number of integration points");
1274 "wrong number of base functions");
1277 for (
auto gg = 0; gg != pts_edge.size2(); ++gg) {
1278 double w = pts_edge(1, gg);
1282 ort_sum += base(gg,
i) * base(gg,
j) * w;
1287 std::cout <<
"ort sum " << ort_sum << std::endl;
1288 if (std::fabs(ort_sum) >
eps) {
1291 "check orthogonality of base");
1296 double ort_diff_sum = 0;
1297 for (
auto gg = 0; gg != pts_edge.size2(); ++gg) {
1298 double w = pts_edge(1, gg);
1302 ort_diff_sum += diff_base(gg,
i) * diff_base(gg,
j) * w;
1307 std::cout <<
"ort diff sum " << ort_diff_sum << std::endl;
1308 if (std::fabs(ort_diff_sum) >
eps) {
1310 "check orthogonality of diff lobatto base");
1322 for (
int ee = 0; ee < 4; ee++) {
1334 nb_gauss_pts = pts_quad.size2();
1339 for (
int i = 0;
i < nb_gauss_pts; ++
i) {
1367 if (choice_value == H1QUAD) {
1376 double sum = 0, diff_sum = 0;
1377 for (
int ee = 0; ee < 4; ee++) {
1388 std::cout << sum <<
" " << diff_sum << endl;
1390 if (std::abs(3.58249 - sum) >
eps)
1394 if (std::abs(-0.134694 - diff_sum) >
eps)