38 {
39
41
42 try {
43
44 moab::Core mb_instance;
45 moab::Interface &moab = mb_instance;
47
48
49 enum bases {
50 LEGENDREPOLYNOMIAL,
51 LOBATTOPOLYNOMIAL,
52 JACOBIPOLYNOMIAL,
53 INTEGRATEDJACOBIPOLYNOMIAL,
54 H1TET_AINSWORTH,
55 H1TET_BERNSTEIN_BEZIER,
56 HDIVTET_AINSWORTH,
57 HDIVTET_DEMKOWICZ,
58 HCURLTET_AINSWORTH,
59 HCURLTET_DEMKOWICZ,
60 L2TET,
61 H1TRI_AINSWORTH,
62 H1TRI_BERNSTEIN_BEZIER,
63 H1QUAD,
64 HDIVTRI_AINSWORTH,
65 HDIVTRI_DEMKOWICZ,
66 HCURLTRI_AINSWORTH,
67 HCURLTRI_DEMKOWICZ,
68 L2TRI,
69 H1EDGE_AINSWORTH,
70 H1EDGE_BERNSTEIN_BEZIER,
71 HCURLEDGE_AINSWORTH,
72 HCURLEDGE_DEMKOWICZ,
73 L2EDGE,
74 H1FLATPRIS,
75 H1FATPRISM,
76 LASTOP
77 };
78
79 const char *list[] = {"legendre",
80 "lobatto",
81 "jacobi",
82 "integrated_jacobi",
83 "h1tet_ainsworth",
84 "h1tet_bernstein_bezier",
85 "hdivtet_ainsworth",
86 "hdivtet_demkowicz",
87 "hcurltet_ainsworth",
88 "hcurltet_demkowicz",
89 "l2tet",
90 "h1tri_ainsworth",
91 "h1tri_bernstein_bezier",
92 "h1quad",
93 "hdivtri_ainsworth",
94 "hdivtri_demkowicz",
95 "hcurltri_ainsworth",
96 "hcurltri_demkowicz",
97 "l2tri",
98 "h1edge_ainsworth",
99 "h1edge_bernstein_bezier",
100 "hcurledge_ainsworth",
101 "hcurledge_demkowicz",
102 "l2edge",
103 "h1flatprism",
104 "h1fatprism"};
105
106 PetscBool flg;
107 PetscInt choice_value = LEGENDREPOLYNOMIAL;
109 &choice_value, &flg);
111 if (flg != PETSC_TRUE) {
113 }
114
116 pts_1d(0, 0) = -0.5;
117 pts_1d(0, 1) = 0.;
118 pts_1d(0, 2) = +0.5;
119
120 boost::shared_ptr<MatrixDouble> base_ptr(
new MatrixDouble);
121 boost::shared_ptr<MatrixDouble> diff_base_ptr(
new MatrixDouble);
122
123 const double eps = 1e-3;
124
125 if (choice_value == LEGENDREPOLYNOMIAL) {
126 double diff_s = 1;
129 4, &diff_s, 1, base_ptr, diff_base_ptr)));
131
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) {
142 }
143 if (fabs(2.25 - diff_sum) >
eps) {
145 }
146 }
147
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;
151 }
152
153 boost::shared_ptr<MatrixDouble> kernel_base_ptr(
new MatrixDouble);
154 boost::shared_ptr<MatrixDouble> diff_kernel_base_ptr(
new MatrixDouble);
155
156 if (choice_value == LOBATTOPOLYNOMIAL) {
157 double diff_s = 1;
160 7 + 2, &diff_s, 1, base_ptr, diff_base_ptr)));
163 pts_1d,
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)
175 << " " << std::endl;
176 }
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;
181 {
184 std::cout << sum << std::endl;
185 std::cout << diff_sum << std::endl;
186 if (fabs(9.39466 - sum) >
eps) {
188 }
189 if (fabs(14.0774 - diff_sum) >
eps) {
191 }
192 }
193 {
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) {
200 }
201 if (fabs(-101.678 * 4 - diff_sum) >
eps) {
203 }
204 }
205 }
206
207 if (choice_value == JACOBIPOLYNOMIAL) {
208
211 pts_1d.resize(1,
n,
false);
213 for (
int ii = 0; ii !=
n; ii++) {
214 pts_1d(0, ii) = (
double)ii / (
n - 1);
215 pts_1d_t(0, ii) = 1;
216 }
217
218 base_ptr->clear();
219 diff_base_ptr->clear();
220
221 double diff_x = 1;
222 double diff_t = 0;
224 pts_1d, pts_1d_t,
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;
232 }
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)) /
238 << std::endl;
239 }
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;
244 {
247 std::cout << sum << std::endl;
248 std::cout << diff_sum << std::endl;
249 if (fabs(23.2164 - sum) >
eps) {
251 }
252 if (fabs(167.995 - diff_sum) >
eps) {
254 }
255 }
256 }
257
258 if (choice_value == INTEGRATEDJACOBIPOLYNOMIAL) {
259
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);
267 }
268
269 base_ptr->clear();
270 diff_base_ptr->clear();
271
272 double diff_x = 1;
273 double diff_t = 0;
275 pts_1d, pts_1d_t,
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;
285 ;
286
287 }
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;
292 {
295 std::cout << sum << std::endl;
296 std::cout << diff_sum << std::endl;
297
298
299
300
301
302
303 }
304 }
305
308 tet_data.spacesOnEntities[
type].set(
L2);
309 tet_data.spacesOnEntities[
type].set(
H1);
310 tet_data.spacesOnEntities[
type].set(
HDIV);
311 tet_data.spacesOnEntities[
type].set(
HCURL);
312 }
313 tet_data.dataOnEntities[MBVERTEX].resize(1);
314 tet_data.dataOnEntities[MBVERTEX][0].getOrder() = 1;
315 tet_data.dataOnEntities[MBEDGE].resize(6);
316 for (int ee = 0; ee < 6; ee++) {
317 tet_data.dataOnEntities[MBEDGE][ee].getOrder() = 3;
318 tet_data.dataOnEntities[MBEDGE][ee].getSense() = 1;
319 }
320 tet_data.dataOnEntities[MBTRI].resize(4);
321 for (int ff = 0; ff < 4; ff++) {
322 tet_data.dataOnEntities[MBTRI][ff].getOrder() = 4;
323 tet_data.dataOnEntities[MBTRI][ff].getSense() = 1;
324 }
325 tet_data.dataOnEntities[MBTET].resize(1);
326 tet_data.dataOnEntities[MBTET][0].getOrder() = 5;
327 tet_data.dataOnEntities[MBVERTEX][0].getBBNodeOrder().resize(4, false);
328 std::fill(tet_data.dataOnEntities[MBVERTEX][0].getBBNodeOrder().begin(),
329 tet_data.dataOnEntities[MBVERTEX][0].getBBNodeOrder().end(), 5);
330
332 int tet_rule = 2;
334 pts_tet.resize(3, nb_gauss_pts, false);
335 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[tet_rule]->points[1], 4,
336 &pts_tet(0, 0), 1);
337 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[tet_rule]->points[2], 4,
338 &pts_tet(1, 0), 1);
339 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[tet_rule]->points[3], 4,
340 &pts_tet(2, 0), 1);
341 tet_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
342 false);
343 {
344 double *shape_ptr =
345 &*tet_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
346 cblas_dcopy(4 * nb_gauss_pts,
QUAD_3D_TABLE[tet_rule]->points, 1,
347 shape_ptr, 1);
348 }
349 tet_data.facesNodes.resize(4, 3);
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];
355 }
356 }
357
358 if (choice_value == H1TET_AINSWORTH) {
359
360 tet_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
361 false);
363 &*tet_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin(),
364 &pts_tet(0, 0), &pts_tet(1, 0), &pts_tet(2, 0), nb_gauss_pts);
366
368 pts_tet,
373 tet_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE),
377
378 double sum = 0, diff_sum = 0;
379 std::cout << "Edges\n";
380 for (int ee = 0; ee < 6; ee++) {
381 std::cout << tet_data.dataOnEntities[MBEDGE][ee].getN(
383 << std::endl;
384 std::cout << tet_data.dataOnEntities[MBEDGE][ee].getDiffN(
386 << std::endl;
389 diff_sum +=
sum_matrix(tet_data.dataOnEntities[MBEDGE][ee].getDiffN(
391 }
392 std::cout << "Faces\n";
393 for (int ff = 0; ff < 4; ff++) {
394 std::cout << tet_data.dataOnEntities[MBTRI][ff].getN(
396 << std::endl;
397 std::cout << tet_data.dataOnEntities[MBTRI][ff].getDiffN(
399 << std::endl;
402 diff_sum +=
sum_matrix(tet_data.dataOnEntities[MBTRI][ff].getDiffN(
404 }
405 std::cout << "Tets\n";
406 std::cout << tet_data.dataOnEntities[MBTET][0].getN(
408 << std::endl;
409 std::cout << tet_data.dataOnEntities[MBTET][0].getDiffN(
411 << std::endl;
416 std::cout << "sum " << sum << std::endl;
417 std::cout << "diff_sum " << diff_sum << std::endl;
418 if (fabs(1.3509 - sum) >
eps) {
420 }
421 if (fabs(0.233313 - diff_sum) >
eps) {
423 }
424 }
425
426 if (choice_value == H1TET_BERNSTEIN_BEZIER) {
427
428 tet_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
429 false);
431 &*tet_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin(),
432 &pts_tet(0, 0), &pts_tet(1, 0), &pts_tet(2, 0), nb_gauss_pts);
437 if (tet_data.dataOnEntities[MBVERTEX][0].getNSharedPtr(
NOBASE).get() ==
438 tet_data.dataOnEntities[MBVERTEX][0]
440 .get())
442
443 double sum = 0, diff_sum = 0;
444 std::cout << "Vertices\n";
445 std::cout << tet_data.dataOnEntities[MBVERTEX][0].getN("TEST_FIELD")
446 << std::endl;
447 std::cout << tet_data.dataOnEntities[MBVERTEX][0].getDiffN("TEST_FIELD")
448 << std::endl;
449 sum +=
450 sum_matrix(tet_data.dataOnEntities[MBVERTEX][0].getN(
"TEST_FIELD"));
452 tet_data.dataOnEntities[MBVERTEX][0].getDiffN("TEST_FIELD"));
453 std::cout << "Edges\n";
454 for (int ee = 0; ee < 6; ee++) {
455 std::cout << tet_data.dataOnEntities[MBEDGE][ee].getN("TEST_FIELD")
456 << std::endl;
457 std::cout << tet_data.dataOnEntities[MBEDGE][ee].getDiffN("TEST_FIELD")
458 << std::endl;
459 sum +=
460 sum_matrix(tet_data.dataOnEntities[MBEDGE][ee].getN(
"TEST_FIELD"));
462 tet_data.dataOnEntities[MBEDGE][ee].getDiffN("TEST_FIELD"));
463 }
464 std::cout << "Faces\n";
465 for (int ff = 0; ff < 4; ff++) {
466 std::cout << tet_data.dataOnEntities[MBTRI][ff].getN("TEST_FIELD")
467 << std::endl;
468 std::cout << tet_data.dataOnEntities[MBTRI][ff].getDiffN("TEST_FIELD")
469 << std::endl;
470 sum +=
471 sum_matrix(tet_data.dataOnEntities[MBTRI][ff].getN(
"TEST_FIELD"));
473 tet_data.dataOnEntities[MBTRI][ff].getDiffN("TEST_FIELD"));
474 }
475 std::cout << "Tets\n";
476 std::cout << tet_data.dataOnEntities[MBTET][0].getN("TEST_FIELD")
477 << std::endl;
478 std::cout << tet_data.dataOnEntities[MBTET][0].getDiffN("TEST_FIELD")
479 << std::endl;
480 sum +=
sum_matrix(tet_data.dataOnEntities[MBTET][0].getN(
"TEST_FIELD"));
481 diff_sum +=
482 sum_matrix(tet_data.dataOnEntities[MBTET][0].getDiffN(
"TEST_FIELD"));
483 std::cout << "sum " << sum << std::endl;
484 std::cout << "diff_sum " << diff_sum << std::endl;
485 if (fabs(4.38395 - sum) >
eps) {
487 }
488 if (fabs(diff_sum) >
eps) {
490 }
491 }
492
493 if (choice_value == HDIVTET_AINSWORTH) {
498 double sum = 0, diff_sum = 0;
499 std::cout << "Faces\n";
500 for (int ff = 0; ff < 4; ff++) {
501 std::cout << tet_data.dataOnEntities[MBTRI][ff].getN(
503 << std::endl;
504 std::cout << tet_data.dataOnEntities[MBTRI][ff].getDiffN(
506 << std::endl;
509 diff_sum +=
sum_matrix(tet_data.dataOnEntities[MBTRI][ff].getDiffN(
511 }
512 std::cout << "Tets\n";
513 std::cout << tet_data.dataOnEntities[MBTET][0].getN(
515 << std::endl;
516 std::cout << tet_data.dataOnEntities[MBTET][0].getDiffN(
518 << std::endl;
523 std::cout << "sum " << 1e8 * sum << std::endl;
524 std::cout << "diff_sum " << 1e8 * diff_sum << std::endl;
525 if (fabs(0.178713 - sum) >
eps) {
527 }
528 if (fabs(31.6048 - diff_sum) >
eps) {
530 }
531 }
532
533 if (choice_value == HDIVTET_DEMKOWICZ) {
538 double sum = 0, diff_sum = 0;
539 std::cout << "Faces\n";
540 for (int ff = 0; ff < 4; ff++) {
541 std::cout << tet_data.dataOnEntities[MBTRI][ff].getN(
543 << std::endl;
544 std::cout << tet_data.dataOnEntities[MBTRI][ff].getDiffN(
546 << std::endl;
551 }
552 std::cout << "Tets\n";
554 << std::endl;
555 std::cout << tet_data.dataOnEntities[MBTET][0].getDiffN(
557 << std::endl;
562 std::cout << "sum " << sum << std::endl;
563 std::cout << "diff_sum " << diff_sum << std::endl;
564 const double expected_result = -2.70651;
565 const double expected_diff_result = 289.421;
566 if (fabs((expected_result - sum) / expected_result) >
eps) {
568 }
569 if (fabs((expected_diff_result - diff_sum) / expected_diff_result) >
572 }
573 }
574
575 if (choice_value == HCURLTET_AINSWORTH) {
580 double sum = 0, diff_sum = 0;
581 std::cout << "Edges\n";
582 for (int ee = 0; ee < 6; ee++) {
583 std::cout << tet_data.dataOnEntities[MBEDGE][ee].getN(
585 << std::endl;
586 std::cout << tet_data.dataOnEntities[MBEDGE][ee].getDiffN(
588 << std::endl;
591 diff_sum +=
sum_matrix(tet_data.dataOnEntities[MBEDGE][ee].getDiffN(
593 }
594 std::cout << "Faces\n";
595 for (int ff = 0; ff < 4; ff++) {
596 std::cout << tet_data.dataOnEntities[MBTRI][ff].getN(
598 << std::endl;
599 std::cout << tet_data.dataOnEntities[MBTRI][ff].getDiffN(
601 << std::endl;
604 diff_sum +=
sum_matrix(tet_data.dataOnEntities[MBTRI][ff].getDiffN(
606 }
607 std::cout << "Tets\n";
608 std::cout << tet_data.dataOnEntities[MBTET][0].getN(
610 << std::endl;
611 std::cout << tet_data.dataOnEntities[MBTET][0].getDiffN(
613 << std::endl;
618 std::cout << "sum " << sum << std::endl;
619 std::cout << "diff_sum " << diff_sum << std::endl;
620 if (fabs(-1.7798 - sum) >
eps) {
622 }
623 if (fabs(-67.1793 - diff_sum) >
eps) {
625 }
626 }
627
628 if (choice_value == HCURLTET_DEMKOWICZ) {
632 double sum = 0, diff_sum = 0;
633 std::cout << "Edges\n";
634 for (int ee = 0; ee < 6; ee++) {
635 std::cout << tet_data.dataOnEntities[MBEDGE][ee].getN(
637 << std::endl;
638 std::cout << tet_data.dataOnEntities[MBEDGE][ee].getDiffN(
640 << std::endl;
643 diff_sum +=
sum_matrix(tet_data.dataOnEntities[MBEDGE][ee].getDiffN(
645 }
646 std::cout << "Faces\n";
647 for (int ff = 0; ff < 4; ff++) {
648 std::cout << tet_data.dataOnEntities[MBTRI][ff].getN(
650 << std::endl;
651 std::cout << tet_data.dataOnEntities[MBTRI][ff].getDiffN(
653 << std::endl;
658 }
659 std::cout << "Tets\n";
661 << std::endl;
662 std::cout << tet_data.dataOnEntities[MBTET][0].getDiffN(
664 << std::endl;
669 std::cout << "sum " << sum << std::endl;
670 std::cout << "diff_sum " << diff_sum << std::endl;
671 if (fabs(7.35513 - sum) >
eps) {
673 }
674 if (fabs(62.4549 - diff_sum) >
eps) {
676 }
677 }
678
679 if (choice_value == L2TET) {
684 double sum = 0, diff_sum = 0;
685 std::cout << "Tets\n";
686 std::cout << tet_data.dataOnEntities[MBTET][0].getN(
688 << std::endl;
689 std::cout << tet_data.dataOnEntities[MBTET][0].getDiffN(
691 << std::endl;
696 std::cout << "sum " << sum << std::endl;
697 std::cout << "diff_sum " << diff_sum << std::endl;
698 if (fabs(3.60352 - sum) >
eps) {
700 }
701 if (fabs(-36.9994 - diff_sum) >
eps) {
703 }
704 }
705
708 tri_data.spacesOnEntities[
type].set(
L2);
709 tri_data.spacesOnEntities[
type].set(
H1);
710 tri_data.spacesOnEntities[
type].set(
HDIV);
711 tri_data.spacesOnEntities[
type].set(
HCURL);
712 }
713 tri_data.dataOnEntities[MBVERTEX].resize(1);
714 tri_data.dataOnEntities[MBVERTEX][0].getOrder() = 1;
715 tri_data.dataOnEntities[MBEDGE].resize(3);
716 for (int ee = 0; ee < 3; ee++) {
717 tri_data.dataOnEntities[MBEDGE][ee].getOrder() = 3;
718 tri_data.dataOnEntities[MBEDGE][ee].getSense() = 1;
719 }
720 tri_data.dataOnEntities[MBTRI].resize(1);
721 tri_data.dataOnEntities[MBTRI][0].getOrder() = 4;
722 tri_data.dataOnEntities[MBVERTEX][0].getBBNodeOrder().resize(3, false);
723 std::fill(tri_data.dataOnEntities[MBVERTEX][0].getBBNodeOrder().begin(),
724 tri_data.dataOnEntities[MBVERTEX][0].getBBNodeOrder().end(), 4);
725
727 int tri_rule = 2;
729 pts_tri.resize(2, nb_gauss_pts, false);
730 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[tri_rule]->points[1], 3,
731 &pts_tri(0, 0), 1);
732 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[tri_rule]->points[2], 3,
733 &pts_tri(1, 0), 1);
734 tri_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
735 false);
736 {
737 double *shape_ptr =
738 &*tri_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
739 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[tri_rule]->points, 1,
740 shape_ptr, 1);
741 }
742 tri_data.dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2,
false);
744 &*tri_data.dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
746
747 if (choice_value == H1TRI_AINSWORTH) {
752 tri_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE),
755
756 double sum = 0, diff_sum = 0;
757 std::cout << "Edges\n";
758 for (int ee = 0; ee < 3; ee++) {
759 std::cout << tri_data.dataOnEntities[MBEDGE][ee].getN(
761 << std::endl;
762 std::cout << tri_data.dataOnEntities[MBEDGE][ee].getDiffN(
764 << std::endl;
767 diff_sum +=
sum_matrix(tri_data.dataOnEntities[MBEDGE][ee].getDiffN(
769 }
770 std::cout << "Face\n";
771 std::cout << tri_data.dataOnEntities[MBTRI][0].getN(
773 << std::endl;
774 std::cout << tri_data.dataOnEntities[MBTRI][0].getDiffN(
776 << std::endl;
781 std::cout << "sum " << sum << std::endl;
782 std::cout << "diff_sum " << diff_sum << std::endl;
783 if (fabs(0.805556 - sum) >
eps)
785
786 if (fabs(0.0833333 - diff_sum) >
eps)
788 }
789
790 if (choice_value == H1TRI_BERNSTEIN_BEZIER) {
795 if (tri_data.dataOnEntities[MBVERTEX][0].getNSharedPtr(
NOBASE).get() ==
796 tri_data.dataOnEntities[MBVERTEX][0]
798 .get())
800 "Pointers should be diffrent");
801
802 double sum = 0, diff_sum = 0;
803 std::cout << "Vertex\n";
804 std::cout << tri_data.dataOnEntities[MBVERTEX][0].getN("TET_FIELD")
805 << std::endl;
806 std::cout << tri_data.dataOnEntities[MBVERTEX][0].getDiffN("TET_FIELD")
807 << std::endl;
808 sum +=
sum_matrix(tri_data.dataOnEntities[MBVERTEX][0].getN(
"TET_FIELD"));
810 tri_data.dataOnEntities[MBVERTEX][0].getDiffN("TET_FIELD"));
811 std::cout << "Edges\n";
812 for (int ee = 0; ee < 3; ee++) {
813 std::cout << tri_data.dataOnEntities[MBEDGE][ee].getN("TET_FIELD")
814 << std::endl;
815 std::cout << tri_data.dataOnEntities[MBEDGE][ee].getDiffN("TET_FIELD")
816 << std::endl;
817 sum +=
818 sum_matrix(tri_data.dataOnEntities[MBEDGE][ee].getN(
"TET_FIELD"));
820 tri_data.dataOnEntities[MBEDGE][ee].getDiffN("TET_FIELD"));
821 }
822 std::cout << "Face\n";
823 std::cout << tri_data.dataOnEntities[MBTRI][0].getN("TET_FIELD")
824 << std::endl;
825 std::cout << tri_data.dataOnEntities[MBTRI][0].getDiffN("TET_FIELD")
826 << std::endl;
827 sum +=
sum_matrix(tri_data.dataOnEntities[MBTRI][0].getN(
"TET_FIELD"));
828 diff_sum +=
829 sum_matrix(tri_data.dataOnEntities[MBTRI][0].getDiffN(
"TET_FIELD"));
830 std::cout << "sum " << sum << std::endl;
831 std::cout << "diff_sum " << diff_sum << std::endl;
832 if (std::abs(3.01389 - sum) >
eps)
834
835 if (std::abs(diff_sum) >
eps)
837 "wrong result %3.4e != %3.4e", 0., diff_sum);
838 }
839
840 if (choice_value == HDIVTRI_AINSWORTH) {
845 tri_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE),
848
849 double sum = 0;
850 std::cout << "Face\n";
851 std::cout << tri_data.dataOnEntities[MBTRI][0].getN(
853 << std::endl;
856 std::cout << "sum " << sum << std::endl;
857 if (fabs(2.21296 - sum) >
eps)
859 }
860
861 if (choice_value == HDIVTRI_DEMKOWICZ) {
867 tri_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE),
871 double sum = 0;
872 std::cout << "Face\n";
874 << std::endl;
877 std::cout << "sum " << sum << std::endl;
878 const double expected_result = 28.25;
879 if (fabs((expected_result - sum) / expected_result) >
eps) {
881 }
882 }
883
884 if (choice_value == HCURLTRI_AINSWORTH) {
890 tri_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE),
894 double sum = 0;
895 std::cout << "Edges\n";
896 for (int ee = 0; ee < 3; ee++) {
897 std::cout << tri_data.dataOnEntities[MBEDGE][ee].getN(
899 << std::endl;
902 }
903 std::cout << "Face\n";
904 std::cout << tri_data.dataOnEntities[MBTRI][0].getN(
906 << std::endl;
909 std::cout << "sum " << sum << std::endl;
910 if (fabs(0.333333 - sum) >
eps) {
912 }
913 }
914
915 if (choice_value == HCURLTRI_DEMKOWICZ) {
920 tri_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE),
924 double sum = 0;
925 std::cout << "Edges\n";
926 for (int ee = 0; ee < 3; ee++) {
927 std::cout << tri_data.dataOnEntities[MBEDGE][ee].getN(
929 << std::endl;
932 }
933 std::cout << "Face\n";
935 << std::endl;
938 std::cout << "sum " << sum << std::endl;
939 if (fabs(1.04591 - sum) >
eps) {
941 }
942 }
943
944 if (choice_value == L2TRI) {
950 tri_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE),
954 double sum = 0;
955 std::cout << "Face\n";
956 std::cout << tri_data.dataOnEntities[MBTRI][0].getN(
958 << std::endl;
961 std::cout << "sum " << sum << std::endl;
962 if (fabs(0.671875 - sum) >
eps) {
964 }
965 }
966
969 edge_data.spacesOnEntities[
type].set(
L2);
970 edge_data.spacesOnEntities[
type].set(
H1);
971 edge_data.spacesOnEntities[
type].set(
HDIV);
972 edge_data.spacesOnEntities[
type].set(
HCURL);
973 }
974 edge_data.dataOnEntities[MBVERTEX].resize(1);
975 edge_data.dataOnEntities[MBVERTEX][0].getOrder() = 1;
976 edge_data.dataOnEntities[MBEDGE].resize(1);
977 edge_data.dataOnEntities[MBEDGE][0].getOrder() = 4;
978 edge_data.dataOnEntities[MBEDGE][0].getSense() = 1;
979 edge_data.dataOnEntities[MBVERTEX][0].getBBNodeOrder().resize(2, false);
980 std::fill(edge_data.dataOnEntities[MBVERTEX][0].getBBNodeOrder().begin(),
981 edge_data.dataOnEntities[MBVERTEX][0].getBBNodeOrder().end(), 4);
982
984 int edge_rule = 6;
986 pts_edge.resize(2, nb_gauss_pts, false);
987 cblas_dcopy(nb_gauss_pts, &
QUAD_1D_TABLE[edge_rule]->points[1], 2,
988 &pts_edge(0, 0), 1);
989 cblas_dcopy(nb_gauss_pts,
QUAD_1D_TABLE[edge_rule]->weights, 1,
990 &pts_edge(1, 0), 1);
991
992 edge_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 2,
993 false);
994 {
995 double *shape_ptr =
996 &*edge_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
997 cblas_dcopy(2 * nb_gauss_pts,
QUAD_1D_TABLE[edge_rule]->points, 1,
998 shape_ptr, 1);
999 }
1000
1001 if (choice_value == H1EDGE_AINSWORTH) {
1006 edge_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE),
1010 double sum = 0, diff_sum = 0;
1011 std::cout << "Edge\n";
1012 std::cout << edge_data.dataOnEntities[MBEDGE][0].getN(
1014 << std::endl;
1015 std::cout << edge_data.dataOnEntities[MBEDGE][0].getDiffN(
1017 << std::endl;
1020 diff_sum +=
sum_matrix(edge_data.dataOnEntities[MBEDGE][0].getDiffN(
1022 std::cout << "sum " << sum << std::endl;
1023 std::cout << "diff sum " << diff_sum << std::endl;
1024 if (std::abs(0.506122 - sum) >
eps)
1026
1027 if (std::abs(-0.571429 - diff_sum) >
eps)
1029 }
1030
1031 if (choice_value == H1EDGE_BERNSTEIN_BEZIER) {
1036 if (edge_data.dataOnEntities[MBVERTEX][0].getNSharedPtr(
NOBASE).get() ==
1037 edge_data.dataOnEntities[MBVERTEX][0]
1039 .get())
1041 "Should be diffrent pointers");
1042
1043 double sum = 0, diff_sum = 0;
1044 std::cout << "Vertex\n";
1045 std::cout << edge_data.dataOnEntities[MBVERTEX][0].getN("TET_FIELD")
1046 << std::endl;
1047 std::cout << edge_data.dataOnEntities[MBVERTEX][0].getDiffN("TET_FIELD")
1048 << std::endl;
1049 std::cout << "Edge\n";
1050 std::cout << edge_data.dataOnEntities[MBEDGE][0].getN("TET_FIELD")
1051 << std::endl;
1052 std::cout << edge_data.dataOnEntities[MBEDGE][0].getDiffN("TET_FIELD")
1053 << std::endl;
1054 sum +=
1055 sum_matrix(edge_data.dataOnEntities[MBVERTEX][0].getN(
"TET_FIELD"));
1057 edge_data.dataOnEntities[MBVERTEX][0].getDiffN("TET_FIELD"));
1058 sum +=
sum_matrix(edge_data.dataOnEntities[MBEDGE][0].getN(
"TET_FIELD"));
1059 diff_sum +=
1060 sum_matrix(edge_data.dataOnEntities[MBEDGE][0].getDiffN(
"TET_FIELD"));
1061 std::cout << "sum " << sum << std::endl;
1062 std::cout << "diff sum " << diff_sum << std::endl;
1063 if (std::abs(4 - sum) >
eps)
1065
1066 if (std::abs(diff_sum) >
eps)
1068 }
1069
1070 if (choice_value == HCURLEDGE_AINSWORTH) {
1072 pts_edge,
1076 edge_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE),
1080 std::cout << edge_data.dataOnEntities[MBEDGE][0].getN(
1082 << std::endl;
1083 double sum = 0;
1086 std::cout.precision(std::numeric_limits<double>::max_digits10 - 1);
1087 std::cout << "sum " << sum << std::endl;
1088 if (fabs(-4.174149659863944 - sum) >
eps) {
1090 }
1091 }
1092
1093 if (choice_value == HCURLEDGE_DEMKOWICZ) {
1098 edge_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE),
1102 std::cout << edge_data.dataOnEntities[MBEDGE][0].getN(
1104 << std::endl;
1107 std::cout.precision(std::numeric_limits<double>::max_digits10 - 1);
1108 std::cout << "sum " << sum << std::endl;
1109 if (std::fabs(4.571428571428571 - sum) >
eps) {
1111 }
1112 }
1113
1114 if (choice_value == L2EDGE) {
1116 pts_edge,
1120 pts_edge,
1124 pts_edge,
1127
1132 std::cout << "sum " << sum << std::endl;
1133 if (std::fabs(sum) >
eps) {
1134 SETERRQ(
1136 "Difference between ainsworth and demkowicz base should be zero");
1137 }
1138
1139 auto order = edge_data.dataOnEntities[MBEDGE][0].getOrder();
1140 auto &base =
1142
1143 if (base.size1() != pts_edge.size2())
1145 "wrong number of integration points");
1148 "wrong number of base functions");
1149
1150 double ort_sum = 0;
1151 for (auto gg = 0; gg != pts_edge.size2(); ++gg) {
1152 double w = pts_edge(1, gg);
1156 ort_sum += base(gg,
i) * base(gg,
j) *
w;
1157 }
1158 }
1159 }
1160 }
1161 std::cout << "ort sum " << ort_sum << std::endl;
1162 if (std::fabs(ort_sum) >
eps) {
1163 SETERRQ(
1165 "check orthogonality of base");
1166 }
1167
1168 auto &diff_base =
1170 double ort_diff_sum = 0;
1171 for (auto gg = 0; gg != pts_edge.size2(); ++gg) {
1172 double w = pts_edge(1, gg);
1176 ort_diff_sum += diff_base(gg,
i) * diff_base(gg,
j) *
w;
1177 }
1178 }
1179 }
1180 }
1181 std::cout << "ort diff sum " << ort_diff_sum << std::endl;
1182 if (std::fabs(ort_diff_sum) >
eps) {
1184 "check orthogonality of diff lobatto base");
1185 }
1186
1187 }
1188
1191 quad_data.spacesOnEntities[
type].set(
H1);
1192 }
1193 quad_data.dataOnEntities[MBVERTEX].resize(1);
1194 quad_data.dataOnEntities[MBVERTEX][0].getOrder() = 1;
1195 quad_data.dataOnEntities[MBEDGE].resize(4);
1196 for (int ee = 0; ee < 4; ee++) {
1197 quad_data.dataOnEntities[MBEDGE][ee].getOrder() = 4;
1198 quad_data.dataOnEntities[MBEDGE][ee].getSense() = 1;
1199 }
1200 quad_data.dataOnEntities[MBQUAD].resize(1);
1201 quad_data.dataOnEntities[MBQUAD][0].getOrder() = 6;
1202
1204 int rule_ksi = 6;
1205 int rule_eta = 4;
1207 rule_eta);
1208 nb_gauss_pts = pts_quad.size2();
1209 quad_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
1210 false);
1211 quad_data.dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(nb_gauss_pts,
1212 8, false);
1213 for (
int i = 0;
i < nb_gauss_pts; ++
i) {
1214 quad_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE)(
i, 0) =
1216 quad_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE)(
i, 1) =
1218 quad_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE)(
i, 2) =
1220 quad_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE)(
i, 3) =
1222
1223 quad_data.dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE)(
i, 0) =
1225 quad_data.dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE)(
i, 1) =
1227 quad_data.dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE)(
i, 2) =
1229 quad_data.dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE)(
i, 3) =
1231 quad_data.dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE)(
i, 4) =
1233 quad_data.dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE)(
i, 5) =
1235 quad_data.dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE)(
i, 6) =
1237 quad_data.dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE)(
i, 7) =
1239 }
1240
1241 if (choice_value == H1QUAD) {
1246 quad_data.dataOnEntities[MBVERTEX][0].getN(
NOBASE),
1250 double sum = 0, diff_sum = 0;
1251 for (int ee = 0; ee < 4; ee++) {
1254 diff_sum +=
sum_matrix(quad_data.dataOnEntities[MBEDGE][ee].getDiffN(
1256 }
1259 diff_sum +=
sum_matrix(quad_data.dataOnEntities[MBQUAD][0].getDiffN(
1261
1262 std::cout << sum << " " << diff_sum << endl;
1263
1264 if (std::abs(3.58249 - sum) >
eps)
1266
1267
1268 if (std::abs(-0.134694 - diff_sum) >
eps)
1270
1271 }
1272 }
1274
1276}
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
@ AINSWORTH_BERNSTEIN_BEZIER_BASE
@ L2
field with C-1 continuity
@ HCURL
field with continuous tangents
@ HDIV
field with continuous normal traction
@ CONTINUOUS
Regular field.
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
#define CHKERR
Inline error check.
#define NBEDGE_L2(P)
Number of base functions on edge from L2 space.
FTensor::Index< 'i', SPACE_DIM > i
const double n
refractive index of diffusive medium
FTensor::Index< 'j', 3 > j
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
UBlasMatrix< double > MatrixDouble
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
static QUAD *const QUAD_2D_TABLE[]
static QUAD *const QUAD_1D_TABLE[]
static QUAD *const QUAD_3D_TABLE[]
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Calculate base functions on tetrahedral.
MoFEMErrorCode getValue(MatrixDouble &pts, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
Class used to pass element data to calculate base functions on tet,triangle,edge.
data structure for finite element entity
MoFEMErrorCode getValue(MatrixDouble &pts_x, MatrixDouble &pts_t, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
Class used to give arguments to Legendre base functions.
Calculating Legendre base functions.
MoFEMErrorCode getValue(MatrixDouble &pts_x, MatrixDouble &pts_t, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
Context class for Kernel Lobatto basis function arguments.
Class for calculating Kernel Lobatto basis functions.
MoFEMErrorCode getValue(MatrixDouble &pts, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
Evaluate Kernel Lobatto basis functions at given points.
Context class for Legendre basis function arguments.
Class for calculating Legendre basis functions.
MoFEMErrorCode getValue(MatrixDouble &pts, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
Evaluate Legendre basis functions at given points.
Context class for Lobatto basis function arguments.
Class for calculating Lobatto basis functions.
MoFEMErrorCode getValue(MatrixDouble &pts, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
Evaluate Lobatto basis functions at given points.
Calculate base functions on triangle.
MoFEMErrorCode getValue(MatrixDouble &pts, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
Calculate base functions on tetrahedral.
MoFEMErrorCode getValue(MatrixDouble &pts, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
Calculate base functions on triangle.
MoFEMErrorCode getValue(MatrixDouble &pts, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
static double sum_matrix(MatrixDouble &m)
static MoFEMErrorCode check_same_matrix(const MatrixDouble &a, const MatrixDouble &b, const double eps)