27#include "bitpit_CG.hpp"
28#include "bitpit_containers.hpp"
29#include "bitpit_operators.hpp"
31#include "element_reference.hpp"
57 : dimension(_dimension), type(_type),
58 nVertices(_nVertices), nFaces(_nFaces), nEdges(_nEdges)
60 faceTypeStorage.fill(ElementType::UNDEFINED);
61 for (
int i = 0; i < MAX_ELEM_FACES; ++i) {
62 faceConnectStorage[i].fill(-1);
63 faceEdgeStorage[i].fill(-1);
66 edgeTypeStorage.fill(ElementType::UNDEFINED);
67 for (
int i = 0; i < MAX_ELEM_EDGES; ++i) {
68 edgeConnectStorage[i].fill(-1);
84 case (ElementType::VERTEX):
85 case (ElementType::LINE):
86 case (ElementType::TRIANGLE):
87 case (ElementType::PIXEL):
88 case (ElementType::QUAD):
89 case (ElementType::TETRA):
90 case (ElementType::VOXEL):
91 case (ElementType::HEXAHEDRON):
92 case (ElementType::PYRAMID):
93 case (ElementType::WEDGE):
112 case (ElementType::VERTEX):
113 return ReferenceVertexInfo::info;
115 case (ElementType::LINE):
116 return ReferenceLineInfo::info;
118 case (ElementType::TRIANGLE):
119 return ReferenceTriangleInfo::info;
121 case (ElementType::PIXEL):
122 return ReferencePixelInfo::info;
124 case (ElementType::QUAD):
125 return ReferenceQuadInfo::info;
127 case (ElementType::TETRA):
128 return ReferenceTetraInfo::info;
130 case (ElementType::VOXEL):
131 return ReferenceVoxelInfo::info;
133 case (ElementType::HEXAHEDRON):
134 return ReferenceHexahedronInfo::info;
136 case (ElementType::PYRAMID):
137 return ReferencePyramidInfo::info;
139 case (ElementType::WEDGE):
140 return ReferenceWedgeInfo::info;
144 throw std::runtime_error(
"Unsupported element");
153 const std::vector<const ReferenceElementInfo *> &edgesInfo)
155 for (
int k = 0; k < nFaces; ++k) {
158 int nFaceEdges = faceInfo.nFaces;
159 int faceEdgeCounter = 0;
160 for (
int i = 0; i < nFaceEdges; ++i) {
164 const int *localFaceEdgeConnect = faceInfo.faceConnectStorage[i].data();
166 std::set<int> faceEdgeConnect;
167 for (
int n = 0; n < faceEdgeInfo.nVertices; ++n) {
168 int localVertexId = localFaceEdgeConnect[n];
169 int vertexId = faceConnectStorage[k][localVertexId];
171 faceEdgeConnect.insert(vertexId);
175 for (
int j = 0; j < nEdges; ++j) {
180 if (guessEdgeInfo.type != faceEdgeInfo.type) {
186 const std::set<int> guessEdgeConnect = std::set<int>(edgeConnectStorage[j].begin(), edgeConnectStorage[j].begin() + guessEdgeInfo.nVertices);
187 if (faceEdgeConnect == guessEdgeConnect) {
188 faceEdgeStorage[k][faceEdgeCounter] = j;
194 assert(faceEdgeCounter == nFaceEdges);
234 double volume = evalVolume(vertexCoords);
236 double faceMaxArea = 0;
237 for (
int face = 0; face < nFaces; ++face) {
239 faceMaxArea = std::max(faceArea, faceMaxArea);
242 double length = volume / faceMaxArea;
258 for (
int i = 0; i < nFaces; ++i) {
274 double perimeter = 0;
275 for (
int i = 0; i < nEdges; ++i) {
295 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> faceVertexCoords;
296 for (
int n = 0; n < faceInfo.nVertices; ++n) {
297 faceVertexCoords[n] = vertexCoords[faceConnectStorage[face][n]];
300 return faceInfo.evalArea(faceVertexCoords.data());
315 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> edgeVertexCoords;
316 for (
int n = 0; n < edgeInfo.nVertices; ++n) {
317 edgeVertexCoords[n] = vertexCoords[edgeConnectStorage[edge][n]];
320 return edgeInfo.
evalLength(edgeVertexCoords.data());
333 std::array<double, 3> *projection,
double *distance)
const
335 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> faceVertexCoords;
337 *distance = std::numeric_limits<double>::max();
338 for (
int i = 0; i < nFaces; ++i) {
341 for (
int n = 0; n < faceInfo.nVertices; ++n) {
342 faceVertexCoords[n] = vertexCoords[faceConnectStorage[i][n]];
346 std::array<double, 3> faceProjection;
347 faceInfo.
evalPointProjection(point, faceVertexCoords.data(), &faceProjection, &faceDistance);
349 if (faceDistance < *distance) {
350 *distance = faceDistance;
351 *projection = faceProjection;
365 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> faceVertexCoords;
367 double distance = std::numeric_limits<double>::max();
368 for (
int i = 0; i < nFaces; ++i) {
371 for (
int n = 0; n < faceInfo.nVertices; ++n) {
372 faceVertexCoords[n] = vertexCoords[faceConnectStorage[i][n]];
375 distance = std::min(faceInfo.
evalPointDistance(point, faceVertexCoords.data()), distance);
401 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
403 for (
int k = 0; k < nEdges; ++k) {
404 edgesInfo[k] = &lineInfo;
406 edgeTypeStorage[k] = LINE;
409 edgeConnectStorage[0][0] = 0;
410 edgeConnectStorage[0][1] = 1;
412 edgeConnectStorage[1][0] = 1;
413 edgeConnectStorage[1][1] = 2;
415 edgeConnectStorage[2][0] = 2;
416 edgeConnectStorage[2][1] = 0;
418 edgeConnectStorage[3][0] = 3;
419 edgeConnectStorage[3][1] = 0;
421 edgeConnectStorage[4][0] = 3;
422 edgeConnectStorage[4][1] = 1;
424 edgeConnectStorage[5][0] = 3;
425 edgeConnectStorage[5][1] = 2;
428 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
430 for (
int k = 0; k < nFaces; ++k) {
431 facesInfo[k] = &triangleInfo;
433 faceTypeStorage[k] = TRIANGLE;
436 faceConnectStorage[0][0] = 1;
437 faceConnectStorage[0][1] = 0;
438 faceConnectStorage[0][2] = 2;
440 faceConnectStorage[1][0] = 0;
441 faceConnectStorage[1][1] = 3;
442 faceConnectStorage[1][2] = 2;
444 faceConnectStorage[2][0] = 3;
445 faceConnectStorage[2][1] = 1;
446 faceConnectStorage[2][2] = 2;
448 faceConnectStorage[3][0] = 0;
449 faceConnectStorage[3][1] = 1;
450 faceConnectStorage[3][2] = 3;
463 const std::array<double, 3> &V_A = vertexCoords[0];
464 const std::array<double, 3> &V_B = vertexCoords[1];
465 const std::array<double, 3> &V_C = vertexCoords[2];
466 const std::array<double, 3> &V_D = vertexCoords[3];
488 double inscribedRadius = 3 * volume / area;
490 double length = 4 * inscribedRadius * sqrt(3. / 2.);
515 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
517 for (
int k = 0; k < nEdges; ++k) {
518 edgesInfo[k] = &lineInfo;
520 edgeTypeStorage[k] = LINE;
523 edgeConnectStorage[0][0] = 0;
524 edgeConnectStorage[0][1] = 2;
526 edgeConnectStorage[1][0] = 1;
527 edgeConnectStorage[1][1] = 3;
529 edgeConnectStorage[2][0] = 0;
530 edgeConnectStorage[2][1] = 1;
532 edgeConnectStorage[3][0] = 2;
533 edgeConnectStorage[3][1] = 3;
535 edgeConnectStorage[4][0] = 0;
536 edgeConnectStorage[4][1] = 4;
538 edgeConnectStorage[5][0] = 1;
539 edgeConnectStorage[5][1] = 5;
541 edgeConnectStorage[6][0] = 2;
542 edgeConnectStorage[6][1] = 6;
544 edgeConnectStorage[7][0] = 3;
545 edgeConnectStorage[7][1] = 7;
547 edgeConnectStorage[8][0] = 4;
548 edgeConnectStorage[8][1] = 6;
550 edgeConnectStorage[9][0] = 5;
551 edgeConnectStorage[9][1] = 7;
553 edgeConnectStorage[10][0] = 4;
554 edgeConnectStorage[10][1] = 5;
556 edgeConnectStorage[11][0] = 6;
557 edgeConnectStorage[11][1] = 7;
560 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
562 for (
int k = 0; k < nFaces; ++k) {
563 facesInfo[k] = &pixelInfo;
565 faceTypeStorage[k] = PIXEL;
568 faceConnectStorage[0][0] = 2;
569 faceConnectStorage[0][1] = 0;
570 faceConnectStorage[0][2] = 6;
571 faceConnectStorage[0][3] = 4;
573 faceConnectStorage[1][0] = 1;
574 faceConnectStorage[1][1] = 3;
575 faceConnectStorage[1][2] = 5;
576 faceConnectStorage[1][3] = 7;
578 faceConnectStorage[2][0] = 0;
579 faceConnectStorage[2][1] = 1;
580 faceConnectStorage[2][2] = 4;
581 faceConnectStorage[2][3] = 5;
583 faceConnectStorage[3][0] = 3;
584 faceConnectStorage[3][1] = 2;
585 faceConnectStorage[3][2] = 7;
586 faceConnectStorage[3][3] = 6;
588 faceConnectStorage[4][0] = 2;
589 faceConnectStorage[4][1] = 3;
590 faceConnectStorage[4][2] = 0;
591 faceConnectStorage[4][3] = 1;
593 faceConnectStorage[5][0] = 7;
594 faceConnectStorage[5][1] = 6;
595 faceConnectStorage[5][2] = 5;
596 faceConnectStorage[5][3] = 4;
609 const std::array<double, 3> &V_A = vertexCoords[0];
610 const std::array<double, 3> &V_B = vertexCoords[1];
611 const std::array<double, 3> &V_C = vertexCoords[2];
612 const std::array<double, 3> &V_D = vertexCoords[4];
630 const std::array<double, 3> &V_A = vertexCoords[0];
631 const std::array<double, 3> &V_B = vertexCoords[1];
632 const std::array<double, 3> &V_C = vertexCoords[2];
633 const std::array<double, 3> &V_D = vertexCoords[4];
635 double sideLength_x =
norm2(V_B - V_A);
636 double sideLength_y =
norm2(V_C - V_A);
637 double sideLength_z =
norm2(V_D - V_A);
639 double size = std::min({sideLength_x, sideLength_y, sideLength_z});
664 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
666 for (
int k = 0; k < nEdges; ++k) {
667 edgesInfo[k] = &lineInfo;
669 edgeTypeStorage[k] = LINE;
672 edgeConnectStorage[0][0] = 1;
673 edgeConnectStorage[0][1] = 0;
675 edgeConnectStorage[1][0] = 1;
676 edgeConnectStorage[1][1] = 2;
678 edgeConnectStorage[2][0] = 2;
679 edgeConnectStorage[2][1] = 3;
681 edgeConnectStorage[3][0] = 3;
682 edgeConnectStorage[3][1] = 0;
684 edgeConnectStorage[4][0] = 4;
685 edgeConnectStorage[4][1] = 5;
687 edgeConnectStorage[5][0] = 5;
688 edgeConnectStorage[5][1] = 6;
690 edgeConnectStorage[6][0] = 6;
691 edgeConnectStorage[6][1] = 7;
693 edgeConnectStorage[7][0] = 7;
694 edgeConnectStorage[7][1] = 4;
696 edgeConnectStorage[8][0] = 0;
697 edgeConnectStorage[8][1] = 4;
699 edgeConnectStorage[9][0] = 1;
700 edgeConnectStorage[9][1] = 5;
702 edgeConnectStorage[10][0] = 2;
703 edgeConnectStorage[10][1] = 6;
705 edgeConnectStorage[11][0] = 3;
706 edgeConnectStorage[11][1] = 7;
709 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
711 for (
int k = 0; k < nFaces; ++k) {
712 facesInfo[k] = &quadInfo;
714 faceTypeStorage[k] = QUAD;
717 faceConnectStorage[0][0] = 1;
718 faceConnectStorage[0][1] = 0;
719 faceConnectStorage[0][2] = 3;
720 faceConnectStorage[0][3] = 2;
722 faceConnectStorage[1][0] = 4;
723 faceConnectStorage[1][1] = 5;
724 faceConnectStorage[1][2] = 6;
725 faceConnectStorage[1][3] = 7;
727 faceConnectStorage[2][0] = 7;
728 faceConnectStorage[2][1] = 3;
729 faceConnectStorage[2][2] = 0;
730 faceConnectStorage[2][3] = 4;
732 faceConnectStorage[3][0] = 5;
733 faceConnectStorage[3][1] = 1;
734 faceConnectStorage[3][2] = 2;
735 faceConnectStorage[3][3] = 6;
737 faceConnectStorage[4][0] = 4;
738 faceConnectStorage[4][1] = 0;
739 faceConnectStorage[4][2] = 1;
740 faceConnectStorage[4][3] = 5;
742 faceConnectStorage[5][0] = 6;
743 faceConnectStorage[5][1] = 2;
744 faceConnectStorage[5][2] = 3;
745 faceConnectStorage[5][3] = 7;
761 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> pyramidVertexCoords;
767 pyramidVertexCoords[4] = vertexCoords[0];
768 for (
int i = 1; i < nVertices; ++i) {
769 pyramidVertexCoords[4] += vertexCoords[i];
771 pyramidVertexCoords[4] = pyramidVertexCoords[4] / double(nVertices);
776 for (
int i = 0; i < nFaces; ++i) {
777 for (
int n = 0; n < quadInfo.nVertices; ++n) {
778 pyramidVertexCoords[quadInfo.nVertices - n - 1] = vertexCoords[faceConnectStorage[i][n]];
781 volume += pyramidInfo.
evalVolume(pyramidVertexCoords.data());
808 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
810 for (
int k = 0; k < nEdges; ++k) {
811 edgesInfo[k] = &lineInfo;
813 edgeTypeStorage[k] = LINE;
816 edgeConnectStorage[0][0] = 0;
817 edgeConnectStorage[0][1] = 1;
819 edgeConnectStorage[1][0] = 1;
820 edgeConnectStorage[1][1] = 2;
822 edgeConnectStorage[2][0] = 2;
823 edgeConnectStorage[2][1] = 3;
825 edgeConnectStorage[3][0] = 3;
826 edgeConnectStorage[3][1] = 0;
828 edgeConnectStorage[4][0] = 4;
829 edgeConnectStorage[4][1] = 0;
831 edgeConnectStorage[5][0] = 4;
832 edgeConnectStorage[5][1] = 1;
834 edgeConnectStorage[6][0] = 4;
835 edgeConnectStorage[6][1] = 2;
837 edgeConnectStorage[7][0] = 4;
838 edgeConnectStorage[7][1] = 3;
841 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
843 for (
int k = 0; k < nFaces; ++k) {
845 facesInfo[k] = &quadInfo;
847 faceTypeStorage[k] = ElementType::QUAD;
849 facesInfo[k] = &triangleInfo;
851 faceTypeStorage[k] = ElementType::TRIANGLE;
855 faceConnectStorage[0][0] = 0;
856 faceConnectStorage[0][1] = 3;
857 faceConnectStorage[0][2] = 2;
858 faceConnectStorage[0][3] = 1;
860 faceConnectStorage[1][0] = 3;
861 faceConnectStorage[1][1] = 0;
862 faceConnectStorage[1][2] = 4;
864 faceConnectStorage[2][0] = 0;
865 faceConnectStorage[2][1] = 1;
866 faceConnectStorage[2][2] = 4;
868 faceConnectStorage[3][0] = 1;
869 faceConnectStorage[3][1] = 2;
870 faceConnectStorage[3][2] = 4;
872 faceConnectStorage[4][0] = 2;
873 faceConnectStorage[4][1] = 3;
874 faceConnectStorage[4][2] = 4;
891 const std::array<double, 3> RA = vertexCoords[0] - vertexCoords[4];
892 const std::array<double, 3> DB = vertexCoords[3] - vertexCoords[1];
893 const std::array<double, 3> AC = vertexCoords[2] - vertexCoords[0];
894 const std::array<double, 3> AD = vertexCoords[1] - vertexCoords[0];
895 const std::array<double, 3> AB = vertexCoords[3] - vertexCoords[0];
923 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
925 for (
int k = 0; k < nEdges; ++k) {
926 edgeTypeStorage[k] = LINE;
927 edgesInfo[k] = &lineInfo;
930 edgeConnectStorage[0][0] = 1;
931 edgeConnectStorage[0][1] = 0;
933 edgeConnectStorage[1][0] = 1;
934 edgeConnectStorage[1][1] = 2;
936 edgeConnectStorage[2][0] = 2;
937 edgeConnectStorage[2][1] = 0;
939 edgeConnectStorage[3][0] = 3;
940 edgeConnectStorage[3][1] = 4;
942 edgeConnectStorage[4][0] = 4;
943 edgeConnectStorage[4][1] = 5;
945 edgeConnectStorage[5][0] = 5;
946 edgeConnectStorage[5][1] = 3;
948 edgeConnectStorage[6][0] = 3;
949 edgeConnectStorage[6][1] = 0;
951 edgeConnectStorage[7][0] = 4;
952 edgeConnectStorage[7][1] = 1;
954 edgeConnectStorage[8][0] = 5;
955 edgeConnectStorage[8][1] = 2;
958 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
960 for (
int k = 0; k < nFaces; ++k) {
961 if (k == 0 || k == 1) {
962 facesInfo[k] = &triangleInfo;
964 faceTypeStorage[k] = TRIANGLE;
966 facesInfo[k] = &quadInfo;
968 faceTypeStorage[k] = QUAD;
972 faceConnectStorage[0][0] = 0;
973 faceConnectStorage[0][1] = 1;
974 faceConnectStorage[0][2] = 2;
976 faceConnectStorage[1][0] = 4;
977 faceConnectStorage[1][1] = 3;
978 faceConnectStorage[1][2] = 5;
980 faceConnectStorage[2][0] = 4;
981 faceConnectStorage[2][1] = 1;
982 faceConnectStorage[2][2] = 0;
983 faceConnectStorage[2][3] = 3;
985 faceConnectStorage[3][0] = 1;
986 faceConnectStorage[3][1] = 4;
987 faceConnectStorage[3][2] = 5;
988 faceConnectStorage[3][3] = 2;
990 faceConnectStorage[4][0] = 3;
991 faceConnectStorage[4][1] = 0;
992 faceConnectStorage[4][2] = 2;
993 faceConnectStorage[4][3] = 5;
1010 std::array<int, 2> triaFaces = {{0, 1}};
1011 std::array<int, 3> quadFaces = {{2, 3, 4}};
1013 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> pyramidVertexCoords;
1014 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> tetraVertexCoords;
1022 pyramidVertexCoords[4] = vertexCoords[0];
1023 for (
int i = 1; i < nVertices; ++i) {
1024 pyramidVertexCoords[4] += vertexCoords[i];
1026 pyramidVertexCoords[4] = pyramidVertexCoords[4] / double(nVertices);
1029 tetraVertexCoords[3] = pyramidVertexCoords[4];
1034 for (
int i : triaFaces) {
1035 for (
int n = 0; n < triaInfo.nVertices; ++n) {
1036 tetraVertexCoords[triaInfo.nVertices - n - 1] = vertexCoords[faceConnectStorage[i][n]];
1039 volume += tetraInfo.
evalVolume(tetraVertexCoords.data());
1042 for (
int i : quadFaces) {
1043 for (
int n = 0; n < quadInfo.nVertices; ++n) {
1044 pyramidVertexCoords[quadInfo.nVertices - n - 1] = vertexCoords[faceConnectStorage[i][n]];
1047 volume += pyramidInfo.
evalVolume(pyramidVertexCoords.data());
1088 double area = evalArea(vertexCoords);
1090 double faceMaxLength = 0;
1091 for (
int face = 0; face < nFaces; ++face) {
1093 faceMaxLength = std::max(faceLength, faceMaxLength);
1096 double length = area / faceMaxLength;
1110 double perimeter = 0;
1111 for (
int i = 0; i < nFaces; ++i) {
1130 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> sideVertexCoords;
1131 for (
int n = 0; n < sideInfo.nVertices; ++n) {
1132 sideVertexCoords[n] = vertexCoords[faceConnectStorage[face][n]];
1135 return sideInfo.
evalLength(sideVertexCoords.data());
1148 std::array<double, 3> *projection,
double *distance)
const
1151 const std::array<double, 3> *ccwVertexCoords;
1152 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> ccwVertexCoordsStorage;
1170 const std::array<double, 3> *ccwVertexCoords;
1171 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> ccwVertexCoordsStorage;
1241 const std::array<double, 3> **ccwVertexCoords,
1242 std::array<double, 3> *ccwVertexCoordsStorage)
const
1246 *ccwVertexCoords = vertexCoords;
1251 for (
int i = 0; i < nVertices; ++i) {
1254 *ccwVertexCoords = ccwVertexCoordsStorage;
1277 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
1279 for (
int k = 0; k < nEdges; ++k) {
1280 edgesInfo[k] = &vertexInfo;
1282 edgeTypeStorage[k] = ElementType::VERTEX;
1283 edgeConnectStorage[k][0] = k;
1287 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
1289 for (
int k = 0; k < nFaces; ++k) {
1290 facesInfo[k] = &lineInfo;
1292 faceTypeStorage[k] = LINE;
1293 faceConnectStorage[k][0] = k;
1294 faceConnectStorage[k][1] = (k + 1) % nVertices;
1312 double area =
evalArea(vertexCoords);
1315 double inscribedRadius = 2 * area / perimeter;
1317 double length = 3. * inscribedRadius;
1330 const std::array<double, 3> &V_A = vertexCoords[0];
1331 const std::array<double, 3> &V_B = vertexCoords[1];
1332 const std::array<double, 3> &V_C = vertexCoords[2];
1351 const std::array<double, 3> &V_A = vertexCoords[0];
1352 const std::array<double, 3> &V_B = vertexCoords[1];
1353 const std::array<double, 3> &V_C = vertexCoords[2];
1355 std::array<double, 3> normal =
crossProduct(V_B - V_A, V_C - V_A);
1356 normal = normal /
norm2(normal);
1371 std::array<double, 3> *projection,
double *distance)
const
1374 *distance =
norm2(point - *projection);
1409 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
1411 for (
int k = 0; k < nEdges; ++k) {
1412 edgesInfo[k] = &vertexInfo;
1414 edgeTypeStorage[k] = ElementType::VERTEX;
1415 edgeConnectStorage[k][0] = k;
1419 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
1421 for (
int k = 0; k < nFaces; ++k) {
1422 facesInfo[k] = &lineInfo;
1424 faceTypeStorage[k] = LINE;
1427 faceConnectStorage[0][0] = 2;
1428 faceConnectStorage[0][1] = 0;
1430 faceConnectStorage[1][0] = 1;
1431 faceConnectStorage[1][1] = 3;
1433 faceConnectStorage[2][0] = 0;
1434 faceConnectStorage[2][1] = 1;
1436 faceConnectStorage[3][0] = 3;
1437 faceConnectStorage[3][1] = 2;
1453 const std::array<double, 3> &V_A = vertexCoords[0];
1454 const std::array<double, 3> &V_B = vertexCoords[1];
1455 const std::array<double, 3> &V_C = vertexCoords[2];
1457 double sideLength_x =
norm2(V_B - V_A);
1458 double sideLength_y =
norm2(V_C - V_A);
1460 double size = std::min(sideLength_x, sideLength_y);
1473 const std::array<double, 3> &V_A = vertexCoords[0];
1474 const std::array<double, 3> &V_B = vertexCoords[1];
1475 const std::array<double, 3> &V_C = vertexCoords[2];
1494 const std::array<double, 3> &V_A = vertexCoords[0];
1495 const std::array<double, 3> &V_B = vertexCoords[1];
1496 const std::array<double, 3> &V_C = vertexCoords[2];
1498 std::array<double, 3> normal =
crossProduct(V_B - V_A, V_C - V_A);
1499 normal = normal /
norm2(normal);
1525 static const std::array<int, 4> CCW_ORDERED_VERTICES = {{0, 1, 3, 2}};
1527 return CCW_ORDERED_VERTICES[n];
1551 static const std::array<int, 4> CCW_ORDERED_FACES = {{2, 1, 3, 0}};
1553 return CCW_ORDERED_FACES[n];
1576 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
1578 for (
int k = 0; k < nEdges; ++k) {
1579 edgesInfo[k] = &vertexInfo;
1581 edgeTypeStorage[k] = ElementType::VERTEX;
1582 edgeConnectStorage[k][0] = k;
1586 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
1588 for (
int k = 0; k < nFaces; ++k) {
1589 facesInfo[k] = &lineInfo;
1591 faceTypeStorage[k] = LINE;
1592 faceConnectStorage[k][0] = k;
1593 faceConnectStorage[k][1] = (k + 1) % nVertices;
1610 const std::array<double, 3> &V_A = vertexCoords[0];
1611 const std::array<double, 3> &V_B = vertexCoords[1];
1612 const std::array<double, 3> &V_C = vertexCoords[2];
1613 const std::array<double, 3> &V_D = vertexCoords[3];
1615 std::array<double, 3> mapping =
crossProduct(V_B - V_A, V_D - V_A);
1619 double area =
norm2(mapping);
1638 const std::array<double, 3> AB = vertexCoords[3] - vertexCoords[0];
1639 const std::array<double, 3> AD = vertexCoords[1] - vertexCoords[0];
1640 const std::array<double, 3> BC = vertexCoords[2] - vertexCoords[3];
1641 const std::array<double, 3> DC = vertexCoords[2] - vertexCoords[1];
1643 const double csi = point[0];
1644 const double eta = point[1];
1649 normal = normal / (-
norm2(normal));
1695 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
1697 for (
int k = 0; k < nEdges; ++k) {
1698 edgesInfo[k] = &vertexInfo;
1700 edgeTypeStorage[k] = ElementType::VERTEX;
1701 edgeConnectStorage[k][0] = k;
1705 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
1707 for (
int k = 0; k < nFaces; ++k) {
1708 facesInfo[k] = &vertexInfo;
1710 faceTypeStorage[k] = ElementType::VERTEX;
1711 faceConnectStorage[k][0] = k;
1737 const std::array<double, 3> &V_A = vertexCoords[0];
1738 const std::array<double, 3> &V_B = vertexCoords[1];
1740 double length =
norm2(V_B - V_A);
1756 const std::array<double, 3> &orientation,
1757 const std::array<double, 3> &point)
const
1761 const std::array<double, 3> tangent = vertexCoords[1] - vertexCoords[0];
1763 std::array<double, 3> normal =
crossProduct(tangent, orientation);
1764 normal = normal /
norm2(normal);
1779 std::array<double, 3> *projection,
double *distance)
const
1781 std::array<double, 2> lambda;
1838 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
1840 edgesInfo[0] =
this;
1842 edgeTypeStorage[0] = ElementType::VERTEX;
1844 edgeConnectStorage[0][0] = 0;
1847 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
1849 facesInfo[0] =
this;
1851 faceTypeStorage[0] = ElementType::VERTEX;
1853 faceConnectStorage[0][0] = 0;
1883 const std::array<double, 3> &orientation)
const
1887 std::array<double, 3> normal = orientation;
1888 normal = normal /
norm2(normal);
1903 std::array<double, 3> *projection,
double *distance)
const
1906 *projection = vertexCoords[0];
1918 return norm2(point - vertexCoords[0]);
The Reference0DElementInfo class allows to define information about reference zero-dimensional elemen...
Reference0DElementInfo(ElementType type)
The Reference1DElementInfo class allows to define information about reference one-dimensional element...
Reference1DElementInfo(ElementType type)
The Reference2DElementInfo class allows to define information about reference two-dimensional element...
virtual int getCCWOrderedVertex(int n) const
virtual int getCCWOrderedFace(int n) const
double evalPointDistance(const std::array< double, 3 > &point, const std::array< double, 3 > *vertexCoords) const override
double evalFaceLength(int face, const std::array< double, 3 > *vertexCoords) const
double evalSize(const std::array< double, 3 > *vertexCoords) const override
Reference2DElementInfo(ElementType type, int nVertices)
void evalPointProjection(const std::array< double, 3 > &point, const std::array< double, 3 > *vertexCoords, std::array< double, 3 > *projection, double *distance) const override
double evalPerimeter(const std::array< double, 3 > *vertexCoords) const
void getCCWVertexCoords(const std::array< double, 3 > *vertexCoords, const std::array< double, 3 > **ccwVertexCoords, std::array< double, 3 > *ccwVertexCoordsStorage) const
virtual bool areVerticesCCWOrdered() const
virtual bool areFacesCCWOrdered() const
The Reference3DElementInfo class allows to define information about reference three-dimensional eleme...
double evalSurfaceArea(const std::array< double, 3 > *vertexCoords) const
double evalSize(const std::array< double, 3 > *vertexCoords) const override
double evalEdgePerimeter(const std::array< double, 3 > *vertexCoords) const
double evalFaceArea(int face, const std::array< double, 3 > *vertexCoords) const
Reference3DElementInfo(ElementType type, int nVertices, int nFaces)
double evalPointDistance(const std::array< double, 3 > &point, const std::array< double, 3 > *vertexCoords) const override
void evalPointProjection(const std::array< double, 3 > &point, const std::array< double, 3 > *vertexCoords, std::array< double, 3 > *projection, double *distance) const override
double evalEdgeLength(int edge, const std::array< double, 3 > *vertexCoords) const
The ReferenceElementInfo class allows to define information about reference elements.
ReferenceElementInfo(int _dimension, ElementType _type, int _nVertices, int _nFaces, int _nEdges)
static bool hasInfo(ElementType type)
static BITPIT_PUBLIC_API const ReferenceElementInfo & getInfo(ElementType type)
void initializeFaceEdges(const std::vector< const ReferenceElementInfo * > &facesInfo, const std::vector< const ReferenceElementInfo * > &edgesInfo)
The ReferenceHexahedronInfo class defines the information about the reference hexahedron.
ReferenceHexahedronInfo()
double evalVolume(const std::array< double, 3 > *vertexCoords) const override
The ReferenceLineInfo class defines the information about the reference line.
std::array< double, 3 > evalNormal(const std::array< double, 3 > *vertexCoords, const std::array< double, 3 > &orientation={{0., 0., 1.}}, const std::array< double, 3 > &point={{0.5, 0.5, 0.5}}) const override
void evalPointProjection(const std::array< double, 3 > &point, const std::array< double, 3 > *vertexCoords, std::array< double, 3 > *projection, double *distance) const override
double evalLength(const std::array< double, 3 > *vertexCoords) const override
double evalPointDistance(const std::array< double, 3 > &point, const std::array< double, 3 > *vertexCoords) const override
double evalSize(const std::array< double, 3 > *vertexCoords) const override
The ReferencePixelInfo class defines the information about the reference pixel.
bool areVerticesCCWOrdered() const override
double evalSize(const std::array< double, 3 > *vertexCoords) const override
int getCCWOrderedVertex(int n) const override
std::array< double, 3 > evalNormal(const std::array< double, 3 > *vertexCoords, const std::array< double, 3 > &point={{0.5, 0.5, 0.5}}) const override
bool areFacesCCWOrdered() const override
int getCCWOrderedFace(int n) const override
double evalArea(const std::array< double, 3 > *vertexCoords) const override
The ReferencePyramidInfo class defines the information about the reference pyramid.
double evalVolume(const std::array< double, 3 > *vertexCoords) const override
The ReferenceQuadInfo class defines the information about the reference quadrangle.
double evalArea(const std::array< double, 3 > *vertexCoords) const override
std::array< double, 3 > evalNormal(const std::array< double, 3 > *vertexCoords, const std::array< double, 3 > &point={{0.5, 0.5, 0.5}}) const override
The ReferenceTetraInfo class defines the information about the reference tetrahedron.
double evalSize(const std::array< double, 3 > *vertexCoords) const override
double evalVolume(const std::array< double, 3 > *vertexCoords) const override
The ReferenceTriangleInfo class defines the information about the reference triangle.
double evalPointDistance(const std::array< double, 3 > &point, const std::array< double, 3 > *vertexCoords) const override
double evalArea(const std::array< double, 3 > *vertexCoords) const override
void evalPointProjection(const std::array< double, 3 > &point, const std::array< double, 3 > *vertexCoords, std::array< double, 3 > *projection, double *distance) const override
double evalSize(const std::array< double, 3 > *vertexCoords) const override
std::array< double, 3 > evalNormal(const std::array< double, 3 > *vertexCoords, const std::array< double, 3 > &point={{0.5, 0.5, 0.5}}) const override
The ReferenceVertexInfo class defines the information about the reference vertex.
std::array< double, 3 > evalNormal(const std::array< double, 3 > *vertexCoords, const std::array< double, 3 > &orientation={{1., 0., 0.}}) const override
double evalPointDistance(const std::array< double, 3 > &point, const std::array< double, 3 > *vertexCoords) const override
double evalSize(const std::array< double, 3 > *vertexCoords) const override
void evalPointProjection(const std::array< double, 3 > &point, const std::array< double, 3 > *vertexCoords, std::array< double, 3 > *projection, double *distance) const override
The ReferenceVoxelInfo class defines the information about the reference voxel.
double evalSize(const std::array< double, 3 > *vertexCoords) const override
double evalVolume(const std::array< double, 3 > *vertexCoords) const override
The ReferenceWedgeInfo class defines the information about the reference wedge.
double evalVolume(const std::array< double, 3 > *vertexCoords) const override
array3D projectPointTriangle(array3D const &, array3D const &, array3D const &, array3D const &)
array3D reconstructPointFromBarycentricSegment(array3D const &, array3D const &, std::array< double, 2 > const &)
double distancePointTriangle(array3D const &, array3D const &, array3D const &, array3D const &)
double distancePointSegment(array3D const &, array3D const &, array3D const &)
double distancePointPolygon(array3D const &, std::vector< array3D > const &, array3D &, int &)
std::array< T, 3 > crossProduct(const std::array< T, 3 > &x, const std::array< T, 3 > &y)
T dotProduct(const std::array< T, d > &x, const std::array< T, d > &y)
double norm2(const std::array< T, d > &x)
#define BITPIT_UNREACHABLE(str)
#define BITPIT_UNUSED(variable)