Loading...
Searching...
No Matches
element_reference.cpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#include <set>
26
27#include "bitpit_CG.hpp"
28#include "bitpit_containers.hpp"
29#include "bitpit_operators.hpp"
30
31#include "element_reference.hpp"
32
33namespace bitpit {
34
56ReferenceElementInfo::ReferenceElementInfo(int _dimension, ElementType _type, int _nVertices, int _nFaces, int _nEdges)
57 : dimension(_dimension), type(_type),
58 nVertices(_nVertices), nFaces(_nFaces), nEdges(_nEdges)
59{
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);
64 }
65
66 edgeTypeStorage.fill(ElementType::UNDEFINED);
67 for (int i = 0; i < MAX_ELEM_EDGES; ++i) {
68 edgeConnectStorage[i].fill(-1);
69 }
70}
71
80{
81
82 switch (type) {
83
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):
94 return true;
95
96 default:
97 return false;
98
99 }
100}
101
109{
110 switch (type) {
111
112 case (ElementType::VERTEX):
113 return ReferenceVertexInfo::info;
114
115 case (ElementType::LINE):
116 return ReferenceLineInfo::info;
117
118 case (ElementType::TRIANGLE):
119 return ReferenceTriangleInfo::info;
120
121 case (ElementType::PIXEL):
122 return ReferencePixelInfo::info;
123
124 case (ElementType::QUAD):
125 return ReferenceQuadInfo::info;
126
127 case (ElementType::TETRA):
128 return ReferenceTetraInfo::info;
129
130 case (ElementType::VOXEL):
131 return ReferenceVoxelInfo::info;
132
133 case (ElementType::HEXAHEDRON):
134 return ReferenceHexahedronInfo::info;
135
136 case (ElementType::PYRAMID):
137 return ReferencePyramidInfo::info;
138
139 case (ElementType::WEDGE):
140 return ReferenceWedgeInfo::info;
141
142 default:
143 BITPIT_UNREACHABLE("Unsupported element");
144 throw std::runtime_error("Unsupported element");
145
146 }
147}
148
152void ReferenceElementInfo::initializeFaceEdges(const std::vector<const ReferenceElementInfo *> &facesInfo,
153 const std::vector<const ReferenceElementInfo *> &edgesInfo)
154{
155 for (int k = 0; k < nFaces; ++k) {
156 const ReferenceElementInfo &faceInfo = *(facesInfo[k]);
157
158 int nFaceEdges = faceInfo.nFaces;
159 int faceEdgeCounter = 0;
160 for (int i = 0; i < nFaceEdges; ++i) {
161 const ReferenceElementInfo &faceEdgeInfo = *(edgesInfo[i]);
162
163 // Connectivity of the edge associated to the face
164 const int *localFaceEdgeConnect = faceInfo.faceConnectStorage[i].data();
165
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];
170
171 faceEdgeConnect.insert(vertexId);
172 }
173
174 // Search the edge that has the same connectivity of the face edge
175 for (int j = 0; j < nEdges; ++j) {
176 const ReferenceElementInfo &guessEdgeInfo = *(edgesInfo[j]);
177
178 // If face edge and the guess edge have a different type, the
179 // two edge cannot be the same.
180 if (guessEdgeInfo.type != faceEdgeInfo.type) {
181 continue;
182 }
183
184 // If the connecitivity of the face edge and the one of the
185 // guess edge are the same, the two edges coincides.
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;
189 ++faceEdgeCounter;
190 }
191 }
192 }
193
194 assert(faceEdgeCounter == nFaceEdges);
195 }
196}
197
218 : ReferenceElementInfo(3, type, nVertices, nFaces, nVertices + nFaces - 2)
219{
220}
221
232double Reference3DElementInfo::evalSize(const std::array<double, 3> *vertexCoords) const
233{
234 double volume = evalVolume(vertexCoords);
235
236 double faceMaxArea = 0;
237 for (int face = 0; face < nFaces; ++face) {
238 double faceArea = evalFaceArea(face, vertexCoords);
239 faceMaxArea = std::max(faceArea, faceMaxArea);
240 }
241
242 double length = volume / faceMaxArea;
243
244 return length;
245}
246
255double Reference3DElementInfo::evalSurfaceArea(const std::array<double, 3> *vertexCoords) const
256{
257 double area = 0;
258 for (int i = 0; i < nFaces; ++i) {
259 area += evalFaceArea(i, vertexCoords);
260 }
261
262 return area;
263}
264
272double Reference3DElementInfo::evalEdgePerimeter(const std::array<double, 3> *vertexCoords) const
273{
274 double perimeter = 0;
275 for (int i = 0; i < nEdges; ++i) {
276 perimeter += evalEdgeLength(i, vertexCoords);
277 }
278
279 return perimeter;
280}
281
290double Reference3DElementInfo::evalFaceArea(int face, const std::array<double, 3> *vertexCoords) const
291{
292 ElementType faceType = faceTypeStorage[face];
293 const Reference2DElementInfo &faceInfo = static_cast<const Reference2DElementInfo &>(getInfo(faceType));
294
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]];
298 }
299
300 return faceInfo.evalArea(faceVertexCoords.data());
301}
302
311double Reference3DElementInfo::evalEdgeLength(int edge, const std::array<double, 3> *vertexCoords) const
312{
313 const ReferenceLineInfo &edgeInfo = static_cast<const ReferenceLineInfo &>(getInfo(ElementType::LINE));
314
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]];
318 }
319
320 return edgeInfo.evalLength(edgeVertexCoords.data());
321}
322
332void Reference3DElementInfo::evalPointProjection(const std::array<double, 3> &point, const std::array<double, 3> *vertexCoords,
333 std::array<double, 3> *projection, double *distance) const
334{
335 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> faceVertexCoords;
336
337 *distance = std::numeric_limits<double>::max();
338 for (int i = 0; i < nFaces; ++i) {
339 ElementType faceType = faceTypeStorage[i];
340 const Reference2DElementInfo &faceInfo = static_cast<const Reference2DElementInfo &>(getInfo(faceType));
341 for (int n = 0; n < faceInfo.nVertices; ++n) {
342 faceVertexCoords[n] = vertexCoords[faceConnectStorage[i][n]];
343 }
344
345 double faceDistance;
346 std::array<double, 3> faceProjection;
347 faceInfo.evalPointProjection(point, faceVertexCoords.data(), &faceProjection, &faceDistance);
348
349 if (faceDistance < *distance) {
350 *distance = faceDistance;
351 *projection = faceProjection;
352 }
353 }
354}
355
363double Reference3DElementInfo::evalPointDistance(const std::array<double, 3> &point, const std::array<double, 3> *vertexCoords) const
364{
365 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> faceVertexCoords;
366
367 double distance = std::numeric_limits<double>::max();
368 for (int i = 0; i < nFaces; ++i) {
369 ElementType faceType = faceTypeStorage[i];
370 const Reference2DElementInfo &faceInfo = static_cast<const Reference2DElementInfo &>(getInfo(faceType));
371 for (int n = 0; n < faceInfo.nVertices; ++n) {
372 faceVertexCoords[n] = vertexCoords[faceConnectStorage[i][n]];
373 }
374
375 distance = std::min(faceInfo.evalPointDistance(point, faceVertexCoords.data()), distance);
376 }
377
378 return distance;
379}
380
389const ReferenceTetraInfo ReferenceTetraInfo::info;
390
395 : Reference3DElementInfo(ElementType::TETRA, 4, 4)
396{
397 const ReferenceLineInfo lineInfo;
398 const ReferenceTriangleInfo triangleInfo;
399
400 // Edge data
401 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
402
403 for (int k = 0; k < nEdges; ++k) {
404 edgesInfo[k] = &lineInfo;
405
406 edgeTypeStorage[k] = LINE;
407 }
408
409 edgeConnectStorage[0][0] = 0;
410 edgeConnectStorage[0][1] = 1;
411
412 edgeConnectStorage[1][0] = 1;
413 edgeConnectStorage[1][1] = 2;
414
415 edgeConnectStorage[2][0] = 2;
416 edgeConnectStorage[2][1] = 0;
417
418 edgeConnectStorage[3][0] = 3;
419 edgeConnectStorage[3][1] = 0;
420
421 edgeConnectStorage[4][0] = 3;
422 edgeConnectStorage[4][1] = 1;
423
424 edgeConnectStorage[5][0] = 3;
425 edgeConnectStorage[5][1] = 2;
426
427 // Face data
428 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
429
430 for (int k = 0; k < nFaces; ++k) {
431 facesInfo[k] = &triangleInfo;
432
433 faceTypeStorage[k] = TRIANGLE;
434 }
435
436 faceConnectStorage[0][0] = 1;
437 faceConnectStorage[0][1] = 0;
438 faceConnectStorage[0][2] = 2;
439
440 faceConnectStorage[1][0] = 0;
441 faceConnectStorage[1][1] = 3;
442 faceConnectStorage[1][2] = 2;
443
444 faceConnectStorage[2][0] = 3;
445 faceConnectStorage[2][1] = 1;
446 faceConnectStorage[2][2] = 2;
447
448 faceConnectStorage[3][0] = 0;
449 faceConnectStorage[3][1] = 1;
450 faceConnectStorage[3][2] = 3;
451
452 initializeFaceEdges(facesInfo, edgesInfo);
453}
454
461double ReferenceTetraInfo::evalVolume(const std::array<double, 3> *vertexCoords) const
462{
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];
467
468 double volume = std::abs(dotProduct(V_A - V_D, crossProduct(V_B - V_D, V_C - V_D))) / 6.;
469
470 return volume;
471}
472
483double ReferenceTetraInfo::evalSize(const std::array<double, 3> *vertexCoords) const
484{
485 double volume = evalVolume(vertexCoords);
486 double area = evalSurfaceArea(vertexCoords);
487
488 double inscribedRadius = 3 * volume / area;
489
490 double length = 4 * inscribedRadius * sqrt(3. / 2.);
491
492 return length;
493}
494
503const ReferenceVoxelInfo ReferenceVoxelInfo::info;
504
509 : Reference3DElementInfo(ElementType::VOXEL, 8, 6)
510{
511 const ReferenceLineInfo lineInfo;
512 const ReferencePixelInfo pixelInfo;
513
514 // Edge data
515 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
516
517 for (int k = 0; k < nEdges; ++k) {
518 edgesInfo[k] = &lineInfo;
519
520 edgeTypeStorage[k] = LINE;
521 }
522
523 edgeConnectStorage[0][0] = 0;
524 edgeConnectStorage[0][1] = 2;
525
526 edgeConnectStorage[1][0] = 1;
527 edgeConnectStorage[1][1] = 3;
528
529 edgeConnectStorage[2][0] = 0;
530 edgeConnectStorage[2][1] = 1;
531
532 edgeConnectStorage[3][0] = 2;
533 edgeConnectStorage[3][1] = 3;
534
535 edgeConnectStorage[4][0] = 0;
536 edgeConnectStorage[4][1] = 4;
537
538 edgeConnectStorage[5][0] = 1;
539 edgeConnectStorage[5][1] = 5;
540
541 edgeConnectStorage[6][0] = 2;
542 edgeConnectStorage[6][1] = 6;
543
544 edgeConnectStorage[7][0] = 3;
545 edgeConnectStorage[7][1] = 7;
546
547 edgeConnectStorage[8][0] = 4;
548 edgeConnectStorage[8][1] = 6;
549
550 edgeConnectStorage[9][0] = 5;
551 edgeConnectStorage[9][1] = 7;
552
553 edgeConnectStorage[10][0] = 4;
554 edgeConnectStorage[10][1] = 5;
555
556 edgeConnectStorage[11][0] = 6;
557 edgeConnectStorage[11][1] = 7;
558
559 // Face data
560 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
561
562 for (int k = 0; k < nFaces; ++k) {
563 facesInfo[k] = &pixelInfo;
564
565 faceTypeStorage[k] = PIXEL;
566 }
567
568 faceConnectStorage[0][0] = 2;
569 faceConnectStorage[0][1] = 0;
570 faceConnectStorage[0][2] = 6;
571 faceConnectStorage[0][3] = 4;
572
573 faceConnectStorage[1][0] = 1;
574 faceConnectStorage[1][1] = 3;
575 faceConnectStorage[1][2] = 5;
576 faceConnectStorage[1][3] = 7;
577
578 faceConnectStorage[2][0] = 0;
579 faceConnectStorage[2][1] = 1;
580 faceConnectStorage[2][2] = 4;
581 faceConnectStorage[2][3] = 5;
582
583 faceConnectStorage[3][0] = 3;
584 faceConnectStorage[3][1] = 2;
585 faceConnectStorage[3][2] = 7;
586 faceConnectStorage[3][3] = 6;
587
588 faceConnectStorage[4][0] = 2;
589 faceConnectStorage[4][1] = 3;
590 faceConnectStorage[4][2] = 0;
591 faceConnectStorage[4][3] = 1;
592
593 faceConnectStorage[5][0] = 7;
594 faceConnectStorage[5][1] = 6;
595 faceConnectStorage[5][2] = 5;
596 faceConnectStorage[5][3] = 4;
597
598 initializeFaceEdges(facesInfo, edgesInfo);
599}
600
607double ReferenceVoxelInfo::evalVolume(const std::array<double, 3> *vertexCoords) const
608{
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];
613
614 double volume = std::abs(dotProduct(V_D - V_A, crossProduct(V_B - V_A, V_C - V_A)));
615
616 return volume;
617}
618
628double ReferenceVoxelInfo::evalSize(const std::array<double, 3> *vertexCoords) const
629{
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];
634
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);
638
639 double size = std::min({sideLength_x, sideLength_y, sideLength_z});
640
641 return size;
642}
643
652const ReferenceHexahedronInfo ReferenceHexahedronInfo::info;
653
658 : Reference3DElementInfo(ElementType::HEXAHEDRON, 8, 6)
659{
660 const ReferenceLineInfo lineInfo;
661 const ReferenceQuadInfo quadInfo;
662
663 // Edge data
664 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
665
666 for (int k = 0; k < nEdges; ++k) {
667 edgesInfo[k] = &lineInfo;
668
669 edgeTypeStorage[k] = LINE;
670 }
671
672 edgeConnectStorage[0][0] = 1;
673 edgeConnectStorage[0][1] = 0;
674
675 edgeConnectStorage[1][0] = 1;
676 edgeConnectStorage[1][1] = 2;
677
678 edgeConnectStorage[2][0] = 2;
679 edgeConnectStorage[2][1] = 3;
680
681 edgeConnectStorage[3][0] = 3;
682 edgeConnectStorage[3][1] = 0;
683
684 edgeConnectStorage[4][0] = 4;
685 edgeConnectStorage[4][1] = 5;
686
687 edgeConnectStorage[5][0] = 5;
688 edgeConnectStorage[5][1] = 6;
689
690 edgeConnectStorage[6][0] = 6;
691 edgeConnectStorage[6][1] = 7;
692
693 edgeConnectStorage[7][0] = 7;
694 edgeConnectStorage[7][1] = 4;
695
696 edgeConnectStorage[8][0] = 0;
697 edgeConnectStorage[8][1] = 4;
698
699 edgeConnectStorage[9][0] = 1;
700 edgeConnectStorage[9][1] = 5;
701
702 edgeConnectStorage[10][0] = 2;
703 edgeConnectStorage[10][1] = 6;
704
705 edgeConnectStorage[11][0] = 3;
706 edgeConnectStorage[11][1] = 7;
707
708 // Face data
709 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
710
711 for (int k = 0; k < nFaces; ++k) {
712 facesInfo[k] = &quadInfo;
713
714 faceTypeStorage[k] = QUAD;
715 }
716
717 faceConnectStorage[0][0] = 1;
718 faceConnectStorage[0][1] = 0;
719 faceConnectStorage[0][2] = 3;
720 faceConnectStorage[0][3] = 2;
721
722 faceConnectStorage[1][0] = 4;
723 faceConnectStorage[1][1] = 5;
724 faceConnectStorage[1][2] = 6;
725 faceConnectStorage[1][3] = 7;
726
727 faceConnectStorage[2][0] = 7;
728 faceConnectStorage[2][1] = 3;
729 faceConnectStorage[2][2] = 0;
730 faceConnectStorage[2][3] = 4;
731
732 faceConnectStorage[3][0] = 5;
733 faceConnectStorage[3][1] = 1;
734 faceConnectStorage[3][2] = 2;
735 faceConnectStorage[3][3] = 6;
736
737 faceConnectStorage[4][0] = 4;
738 faceConnectStorage[4][1] = 0;
739 faceConnectStorage[4][2] = 1;
740 faceConnectStorage[4][3] = 5;
741
742 faceConnectStorage[5][0] = 6;
743 faceConnectStorage[5][1] = 2;
744 faceConnectStorage[5][2] = 3;
745 faceConnectStorage[5][3] = 7;
746
747 initializeFaceEdges(facesInfo, edgesInfo);
748}
749
759double ReferenceHexahedronInfo::evalVolume(const std::array<double, 3> *vertexCoords) const
760{
761 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> pyramidVertexCoords;
762
763 const ReferenceQuadInfo &quadInfo = static_cast<const ReferenceQuadInfo &>(getInfo(ElementType::QUAD));
764 const ReferencePyramidInfo &pyramidInfo = static_cast<const ReferencePyramidInfo &>(getInfo(ElementType::PYRAMID));
765
766 // The centroid is the apex of all the pyramids
767 pyramidVertexCoords[4] = vertexCoords[0];
768 for (int i = 1; i < nVertices; ++i) {
769 pyramidVertexCoords[4] += vertexCoords[i];
770 }
771 pyramidVertexCoords[4] = pyramidVertexCoords[4] / double(nVertices);
772
773 // Sum the volume of the pyramids having a face as the base and the
774 // centroid as the apex.
775 double volume = 0.;
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]];
779 }
780
781 volume += pyramidInfo.evalVolume(pyramidVertexCoords.data());
782 }
783
784 return volume;
785}
786
795const ReferencePyramidInfo ReferencePyramidInfo::info;
796
801 : Reference3DElementInfo(ElementType::PYRAMID, 5, 5)
802{
803 const ReferenceLineInfo lineInfo;
804 const ReferenceTriangleInfo triangleInfo;
805 const ReferenceQuadInfo quadInfo;
806
807 // Edge data
808 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
809
810 for (int k = 0; k < nEdges; ++k) {
811 edgesInfo[k] = &lineInfo;
812
813 edgeTypeStorage[k] = LINE;
814 }
815
816 edgeConnectStorage[0][0] = 0;
817 edgeConnectStorage[0][1] = 1;
818
819 edgeConnectStorage[1][0] = 1;
820 edgeConnectStorage[1][1] = 2;
821
822 edgeConnectStorage[2][0] = 2;
823 edgeConnectStorage[2][1] = 3;
824
825 edgeConnectStorage[3][0] = 3;
826 edgeConnectStorage[3][1] = 0;
827
828 edgeConnectStorage[4][0] = 4;
829 edgeConnectStorage[4][1] = 0;
830
831 edgeConnectStorage[5][0] = 4;
832 edgeConnectStorage[5][1] = 1;
833
834 edgeConnectStorage[6][0] = 4;
835 edgeConnectStorage[6][1] = 2;
836
837 edgeConnectStorage[7][0] = 4;
838 edgeConnectStorage[7][1] = 3;
839
840 // Face data
841 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
842
843 for (int k = 0; k < nFaces; ++k) {
844 if (k == 0) {
845 facesInfo[k] = &quadInfo;
846
847 faceTypeStorage[k] = ElementType::QUAD;
848 } else {
849 facesInfo[k] = &triangleInfo;
850
851 faceTypeStorage[k] = ElementType::TRIANGLE;
852 }
853 }
854
855 faceConnectStorage[0][0] = 0;
856 faceConnectStorage[0][1] = 3;
857 faceConnectStorage[0][2] = 2;
858 faceConnectStorage[0][3] = 1;
859
860 faceConnectStorage[1][0] = 3;
861 faceConnectStorage[1][1] = 0;
862 faceConnectStorage[1][2] = 4;
863
864 faceConnectStorage[2][0] = 0;
865 faceConnectStorage[2][1] = 1;
866 faceConnectStorage[2][2] = 4;
867
868 faceConnectStorage[3][0] = 1;
869 faceConnectStorage[3][1] = 2;
870 faceConnectStorage[3][2] = 4;
871
872 faceConnectStorage[4][0] = 2;
873 faceConnectStorage[4][1] = 3;
874 faceConnectStorage[4][2] = 4;
875
876 initializeFaceEdges(facesInfo, edgesInfo);
877}
878
889double ReferencePyramidInfo::evalVolume(const std::array<double, 3> *vertexCoords) const
890{
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];
896
897 double volume = dotProduct(RA, crossProduct(DB, AC)) / 6. + dotProduct(AC, crossProduct(AD, AB)) / 12.;
898
899 return volume;
900}
901
910const ReferenceWedgeInfo ReferenceWedgeInfo::info;
911
916 : Reference3DElementInfo(ElementType::WEDGE, 6, 5)
917{
918 const ReferenceLineInfo lineInfo;
919 const ReferenceTriangleInfo triangleInfo;
920 const ReferenceQuadInfo quadInfo;
921
922 // Edge data
923 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
924
925 for (int k = 0; k < nEdges; ++k) {
926 edgeTypeStorage[k] = LINE;
927 edgesInfo[k] = &lineInfo;
928 }
929
930 edgeConnectStorage[0][0] = 1;
931 edgeConnectStorage[0][1] = 0;
932
933 edgeConnectStorage[1][0] = 1;
934 edgeConnectStorage[1][1] = 2;
935
936 edgeConnectStorage[2][0] = 2;
937 edgeConnectStorage[2][1] = 0;
938
939 edgeConnectStorage[3][0] = 3;
940 edgeConnectStorage[3][1] = 4;
941
942 edgeConnectStorage[4][0] = 4;
943 edgeConnectStorage[4][1] = 5;
944
945 edgeConnectStorage[5][0] = 5;
946 edgeConnectStorage[5][1] = 3;
947
948 edgeConnectStorage[6][0] = 3;
949 edgeConnectStorage[6][1] = 0;
950
951 edgeConnectStorage[7][0] = 4;
952 edgeConnectStorage[7][1] = 1;
953
954 edgeConnectStorage[8][0] = 5;
955 edgeConnectStorage[8][1] = 2;
956
957 // Face data
958 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
959
960 for (int k = 0; k < nFaces; ++k) {
961 if (k == 0 || k == 1) {
962 facesInfo[k] = &triangleInfo;
963
964 faceTypeStorage[k] = TRIANGLE;
965 } else {
966 facesInfo[k] = &quadInfo;
967
968 faceTypeStorage[k] = QUAD;
969 }
970 }
971
972 faceConnectStorage[0][0] = 0;
973 faceConnectStorage[0][1] = 1;
974 faceConnectStorage[0][2] = 2;
975
976 faceConnectStorage[1][0] = 4;
977 faceConnectStorage[1][1] = 3;
978 faceConnectStorage[1][2] = 5;
979
980 faceConnectStorage[2][0] = 4;
981 faceConnectStorage[2][1] = 1;
982 faceConnectStorage[2][2] = 0;
983 faceConnectStorage[2][3] = 3;
984
985 faceConnectStorage[3][0] = 1;
986 faceConnectStorage[3][1] = 4;
987 faceConnectStorage[3][2] = 5;
988 faceConnectStorage[3][3] = 2;
989
990 faceConnectStorage[4][0] = 3;
991 faceConnectStorage[4][1] = 0;
992 faceConnectStorage[4][2] = 2;
993 faceConnectStorage[4][3] = 5;
994
995 initializeFaceEdges(facesInfo, edgesInfo);
996}
997
1008double ReferenceWedgeInfo::evalVolume(const std::array<double, 3> *vertexCoords) const
1009{
1010 std::array<int, 2> triaFaces = {{0, 1}};
1011 std::array<int, 3> quadFaces = {{2, 3, 4}};
1012
1013 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> pyramidVertexCoords;
1014 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> tetraVertexCoords;
1015
1016 const ReferenceTriangleInfo &triaInfo = static_cast<const ReferenceTriangleInfo &>(getInfo(ElementType::TRIANGLE));
1017 const ReferenceQuadInfo &quadInfo = static_cast<const ReferenceQuadInfo &>(getInfo(ElementType::QUAD));
1018 const ReferenceTetraInfo &tetraInfo = static_cast<const ReferenceTetraInfo &>(getInfo(ElementType::TETRA));
1019 const ReferencePyramidInfo &pyramidInfo = static_cast<const ReferencePyramidInfo &>(getInfo(ElementType::PYRAMID));
1020
1021 // The centroid is the apex of all the pyramids
1022 pyramidVertexCoords[4] = vertexCoords[0];
1023 for (int i = 1; i < nVertices; ++i) {
1024 pyramidVertexCoords[4] += vertexCoords[i];
1025 }
1026 pyramidVertexCoords[4] = pyramidVertexCoords[4] / double(nVertices);
1027
1028 // The centroid is the apex of all the tetras
1029 tetraVertexCoords[3] = pyramidVertexCoords[4];
1030
1031 // Sum the volume of the pyramids/tetra having a face as the base and the
1032 // centroid as the apex.
1033 double volume = 0.;
1034 for (int i : triaFaces) {
1035 for (int n = 0; n < triaInfo.nVertices; ++n) {
1036 tetraVertexCoords[triaInfo.nVertices - n - 1] = vertexCoords[faceConnectStorage[i][n]];
1037 }
1038
1039 volume += tetraInfo.evalVolume(tetraVertexCoords.data());
1040 }
1041
1042 for (int i : quadFaces) {
1043 for (int n = 0; n < quadInfo.nVertices; ++n) {
1044 pyramidVertexCoords[quadInfo.nVertices - n - 1] = vertexCoords[faceConnectStorage[i][n]];
1045 }
1046
1047 volume += pyramidInfo.evalVolume(pyramidVertexCoords.data());
1048 }
1049
1050 return volume;
1051}
1052
1072 : ReferenceElementInfo(2, type, nVertices, nVertices, nVertices)
1073{
1074}
1075
1086double Reference2DElementInfo::evalSize(const std::array<double, 3> *vertexCoords) const
1087{
1088 double area = evalArea(vertexCoords);
1089
1090 double faceMaxLength = 0;
1091 for (int face = 0; face < nFaces; ++face) {
1092 double faceLength = evalFaceLength(face, vertexCoords);
1093 faceMaxLength = std::max(faceLength, faceMaxLength);
1094 }
1095
1096 double length = area / faceMaxLength;
1097
1098 return length;
1099}
1100
1108double Reference2DElementInfo::evalPerimeter(const std::array<double, 3> *vertexCoords) const
1109{
1110 double perimeter = 0;
1111 for (int i = 0; i < nFaces; ++i) {
1112 perimeter += evalFaceLength(i, vertexCoords);
1113 }
1114
1115 return perimeter;
1116}
1117
1126double Reference2DElementInfo::evalFaceLength(int face, const std::array<double, 3> *vertexCoords) const
1127{
1128 const ReferenceLineInfo &sideInfo = static_cast<const ReferenceLineInfo &>(getInfo(ElementType::LINE));
1129
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]];
1133 }
1134
1135 return sideInfo.evalLength(sideVertexCoords.data());
1136}
1137
1147void Reference2DElementInfo::evalPointProjection(const std::array<double, 3> &point, const std::array<double, 3> *vertexCoords,
1148 std::array<double, 3> *projection, double *distance) const
1149{
1150 // Get vertices ordered counter-clockwise
1151 const std::array<double, 3> *ccwVertexCoords;
1152 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> ccwVertexCoordsStorage;
1153 getCCWVertexCoords(vertexCoords, &ccwVertexCoords, ccwVertexCoordsStorage.data());
1154
1155 // Evaluate projection
1156 int projectionFlag;
1157 *distance = CGElem::distancePointPolygon(point, nVertices, ccwVertexCoords, *projection, projectionFlag);
1158}
1159
1167double Reference2DElementInfo::evalPointDistance(const std::array<double, 3> &point, const std::array<double, 3> *vertexCoords) const
1168{
1169 // Get vertices ordered counter-clockwise
1170 const std::array<double, 3> *ccwVertexCoords;
1171 std::array<std::array<double, 3>, MAX_ELEM_VERTICES> ccwVertexCoordsStorage;
1172 getCCWVertexCoords(vertexCoords, &ccwVertexCoords, ccwVertexCoordsStorage.data());
1173
1174 // Evaluate distance
1175 return CGElem::distancePointPolygon(point, nVertices, ccwVertexCoords);
1176}
1177
1185{
1186 return true;
1187}
1188
1198{
1199 return n;
1200}
1201
1209{
1210 return true;
1211}
1212
1222{
1223 return n;
1224}
1225
1240void Reference2DElementInfo::getCCWVertexCoords(const std::array<double, 3> *vertexCoords,
1241 const std::array<double, 3> **ccwVertexCoords,
1242 std::array<double, 3> *ccwVertexCoordsStorage) const
1243{
1244 // Early return if vertex are already ordered
1245 if (areVerticesCCWOrdered()) {
1246 *ccwVertexCoords = vertexCoords;
1247 return;
1248 }
1249
1250 // Order vertices
1251 for (int i = 0; i < nVertices; ++i) {
1252 ccwVertexCoordsStorage[i] = vertexCoords[getCCWOrderedVertex(i)];
1253 }
1254 *ccwVertexCoords = ccwVertexCoordsStorage;
1255}
1256
1265const ReferenceTriangleInfo ReferenceTriangleInfo::info;
1266
1271 : Reference2DElementInfo(ElementType::TRIANGLE, 3)
1272{
1273 const ReferenceVertexInfo vertexInfo;
1274 const ReferenceLineInfo lineInfo;
1275
1276 // Edge data
1277 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
1278
1279 for (int k = 0; k < nEdges; ++k) {
1280 edgesInfo[k] = &vertexInfo;
1281
1282 edgeTypeStorage[k] = ElementType::VERTEX;
1283 edgeConnectStorage[k][0] = k;
1284 }
1285
1286 // Face data
1287 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
1288
1289 for (int k = 0; k < nFaces; ++k) {
1290 facesInfo[k] = &lineInfo;
1291
1292 faceTypeStorage[k] = LINE;
1293 faceConnectStorage[k][0] = k;
1294 faceConnectStorage[k][1] = (k + 1) % nVertices;
1295 }
1296
1297 initializeFaceEdges(facesInfo, edgesInfo);
1298}
1299
1310double ReferenceTriangleInfo::evalSize(const std::array<double, 3> *vertexCoords) const
1311{
1312 double area = evalArea(vertexCoords);
1313 double perimeter = evalPerimeter(vertexCoords);
1314
1315 double inscribedRadius = 2 * area / perimeter;
1316
1317 double length = 3. * inscribedRadius;
1318
1319 return length;
1320}
1321
1328double ReferenceTriangleInfo::evalArea(const std::array<double, 3> *vertexCoords) const
1329{
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];
1333
1334 double area = 0.5 * norm2(crossProduct(V_B - V_A, V_C - V_A));
1335
1336 return area;
1337}
1338
1347std::array<double, 3> ReferenceTriangleInfo::evalNormal(const std::array<double, 3> *vertexCoords, const std::array<double, 3> &point) const
1348{
1349 BITPIT_UNUSED(point);
1350
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];
1354
1355 std::array<double, 3> normal = crossProduct(V_B - V_A, V_C - V_A);
1356 normal = normal / norm2(normal);
1357
1358 return normal;
1359}
1360
1370void ReferenceTriangleInfo::evalPointProjection(const std::array<double, 3> &point, const std::array<double, 3> *vertexCoords,
1371 std::array<double, 3> *projection, double *distance) const
1372{
1373 *projection = CGElem::projectPointTriangle(point, vertexCoords[0], vertexCoords[1], vertexCoords[2]);
1374 *distance = norm2(point - *projection);
1375}
1376
1384double ReferenceTriangleInfo::evalPointDistance(const std::array<double, 3> &point, const std::array<double, 3> *vertexCoords) const
1385{
1386 return CGElem::distancePointTriangle(point, vertexCoords[0], vertexCoords[1], vertexCoords[2]);
1387}
1388
1397const ReferencePixelInfo ReferencePixelInfo::info;
1398
1404{
1405 const ReferenceVertexInfo vertexInfo;
1406 const ReferenceLineInfo lineInfo;
1407
1408 // Edge data
1409 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
1410
1411 for (int k = 0; k < nEdges; ++k) {
1412 edgesInfo[k] = &vertexInfo;
1413
1414 edgeTypeStorage[k] = ElementType::VERTEX;
1415 edgeConnectStorage[k][0] = k;
1416 }
1417
1418 // Face data
1419 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
1420
1421 for (int k = 0; k < nFaces; ++k) {
1422 facesInfo[k] = &lineInfo;
1423
1424 faceTypeStorage[k] = LINE;
1425 }
1426
1427 faceConnectStorage[0][0] = 2;
1428 faceConnectStorage[0][1] = 0;
1429
1430 faceConnectStorage[1][0] = 1;
1431 faceConnectStorage[1][1] = 3;
1432
1433 faceConnectStorage[2][0] = 0;
1434 faceConnectStorage[2][1] = 1;
1435
1436 faceConnectStorage[3][0] = 3;
1437 faceConnectStorage[3][1] = 2;
1438
1439 initializeFaceEdges(facesInfo, edgesInfo);
1440}
1441
1451double ReferencePixelInfo::evalSize(const std::array<double, 3> *vertexCoords) const
1452{
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];
1456
1457 double sideLength_x = norm2(V_B - V_A);
1458 double sideLength_y = norm2(V_C - V_A);
1459
1460 double size = std::min(sideLength_x, sideLength_y);
1461
1462 return size;
1463}
1464
1471double ReferencePixelInfo::evalArea(const std::array<double, 3> *vertexCoords) const
1472{
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];
1476
1477 double area = norm2(crossProduct(V_B - V_A, V_C - V_A));
1478
1479 return area;
1480}
1481
1490std::array<double, 3> ReferencePixelInfo::evalNormal(const std::array<double, 3> *vertexCoords, const std::array<double, 3> &point) const
1491{
1492 BITPIT_UNUSED(point);
1493
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];
1497
1498 std::array<double, 3> normal = crossProduct(V_B - V_A, V_C - V_A);
1499 normal = normal / norm2(normal);
1500
1501 return normal;
1502}
1503
1511{
1512 return false;
1513}
1514
1524{
1525 static const std::array<int, 4> CCW_ORDERED_VERTICES = {{0, 1, 3, 2}};
1526
1527 return CCW_ORDERED_VERTICES[n];
1528}
1529
1537{
1538 return false;
1539}
1540
1550{
1551 static const std::array<int, 4> CCW_ORDERED_FACES = {{2, 1, 3, 0}};
1552
1553 return CCW_ORDERED_FACES[n];
1554}
1555
1564const ReferenceQuadInfo ReferenceQuadInfo::info;
1565
1571{
1572 const ReferenceVertexInfo vertexInfo;
1573 const ReferenceLineInfo lineInfo;
1574
1575 // Edge data
1576 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
1577
1578 for (int k = 0; k < nEdges; ++k) {
1579 edgesInfo[k] = &vertexInfo;
1580
1581 edgeTypeStorage[k] = ElementType::VERTEX;
1582 edgeConnectStorage[k][0] = k;
1583 }
1584
1585 // Face data
1586 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
1587
1588 for (int k = 0; k < nFaces; ++k) {
1589 facesInfo[k] = &lineInfo;
1590
1591 faceTypeStorage[k] = LINE;
1592 faceConnectStorage[k][0] = k;
1593 faceConnectStorage[k][1] = (k + 1) % nVertices;
1594 }
1595
1596 initializeFaceEdges(facesInfo, edgesInfo);
1597}
1598
1608double ReferenceQuadInfo::evalArea(const std::array<double, 3> *vertexCoords) const
1609{
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];
1614
1615 std::array<double, 3> mapping = crossProduct(V_B - V_A, V_D - V_A);
1616 mapping += 0.5 * crossProduct(V_B - V_A, V_C - V_D);
1617 mapping += 0.5 * crossProduct(V_C - V_B, V_D - V_A);
1618
1619 double area = norm2(mapping);
1620
1621 return area;
1622}
1623
1636std::array<double, 3> ReferenceQuadInfo::evalNormal(const std::array<double, 3> *vertexCoords, const std::array<double, 3> &point) const
1637{
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];
1642
1643 const double csi = point[0];
1644 const double eta = point[1];
1645
1646 std::array<double, 3> normal = crossProduct(AB, AD);
1647 normal += csi * crossProduct(AB, DC);
1648 normal += eta * crossProduct(BC, AD);
1649 normal = normal / (- norm2(normal));
1650
1651 return normal;
1652}
1653
1675
1684const ReferenceLineInfo ReferenceLineInfo::info;
1685
1691{
1692 const ReferenceVertexInfo vertexInfo;
1693
1694 // Edge data
1695 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
1696
1697 for (int k = 0; k < nEdges; ++k) {
1698 edgesInfo[k] = &vertexInfo;
1699
1700 edgeTypeStorage[k] = ElementType::VERTEX;
1701 edgeConnectStorage[k][0] = k;
1702 }
1703
1704 // Face data
1705 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
1706
1707 for (int k = 0; k < nFaces; ++k) {
1708 facesInfo[k] = &vertexInfo;
1709
1710 faceTypeStorage[k] = ElementType::VERTEX;
1711 faceConnectStorage[k][0] = k;
1712 }
1713
1714 initializeFaceEdges(facesInfo, edgesInfo);
1715}
1716
1724double ReferenceLineInfo::evalSize(const std::array<double, 3> *vertexCoords) const
1725{
1726 return evalLength(vertexCoords);
1727}
1728
1735double ReferenceLineInfo::evalLength(const std::array<double, 3> *vertexCoords) const
1736{
1737 const std::array<double, 3> &V_A = vertexCoords[0];
1738 const std::array<double, 3> &V_B = vertexCoords[1];
1739
1740 double length = norm2(V_B - V_A);
1741
1742 return length;
1743}
1744
1755std::array<double, 3> ReferenceLineInfo::evalNormal(const std::array<double, 3> *vertexCoords,
1756 const std::array<double, 3> &orientation,
1757 const std::array<double, 3> &point) const
1758{
1759 BITPIT_UNUSED(point);
1760
1761 const std::array<double, 3> tangent = vertexCoords[1] - vertexCoords[0];
1762
1763 std::array<double, 3> normal = crossProduct(tangent, orientation);
1764 normal = normal / norm2(normal);
1765
1766 return normal;
1767}
1768
1778void ReferenceLineInfo::evalPointProjection(const std::array<double, 3> &point, const std::array<double, 3> *vertexCoords,
1779 std::array<double, 3> *projection, double *distance) const
1780{
1781 std::array<double, 2> lambda;
1782 *distance = CGElem::distancePointSegment(point, vertexCoords[0], vertexCoords[1], lambda);
1783
1784 *projection = CGElem::reconstructPointFromBarycentricSegment(vertexCoords[0], vertexCoords[1], lambda);
1785}
1786
1794double ReferenceLineInfo::evalPointDistance(const std::array<double, 3> &point, const std::array<double, 3> *vertexCoords) const
1795{
1796 return CGElem::distancePointSegment(point, vertexCoords[0], vertexCoords[1]);
1797}
1798
1820
1829const ReferenceVertexInfo ReferenceVertexInfo::info;
1830
1836{
1837 // Edge data
1838 std::vector<const ReferenceElementInfo *> edgesInfo(nEdges);
1839
1840 edgesInfo[0] = this;
1841
1842 edgeTypeStorage[0] = ElementType::VERTEX;
1843
1844 edgeConnectStorage[0][0] = 0;
1845
1846 // Face data
1847 std::vector<const ReferenceElementInfo *> facesInfo(nFaces);
1848
1849 facesInfo[0] = this;
1850
1851 faceTypeStorage[0] = ElementType::VERTEX;
1852
1853 faceConnectStorage[0][0] = 0;
1854
1855 initializeFaceEdges(facesInfo, edgesInfo);
1856}
1857
1865double ReferenceVertexInfo::evalSize(const std::array<double, 3> *vertexCoords) const
1866{
1867 BITPIT_UNUSED(vertexCoords);
1868
1869 return 0.;
1870}
1871
1882std::array<double, 3> ReferenceVertexInfo::evalNormal(const std::array<double, 3> *vertexCoords,
1883 const std::array<double, 3> &orientation) const
1884{
1885 BITPIT_UNUSED(vertexCoords);
1886
1887 std::array<double, 3> normal = orientation;
1888 normal = normal / norm2(normal);
1889
1890 return normal;
1891}
1892
1902void ReferenceVertexInfo::evalPointProjection(const std::array<double, 3> &point, const std::array<double, 3> *vertexCoords,
1903 std::array<double, 3> *projection, double *distance) const
1904{
1905 *distance = evalPointDistance(point, vertexCoords);
1906 *projection = vertexCoords[0];
1907}
1908
1916double ReferenceVertexInfo::evalPointDistance(const std::array<double, 3> &point, const std::array<double, 3> *vertexCoords) const
1917{
1918 return norm2(point - vertexCoords[0]);
1919}
1920
1921}
The Reference0DElementInfo class allows to define information about reference zero-dimensional elemen...
The Reference1DElementInfo class allows to define information about reference one-dimensional element...
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
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.
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 &)
Definition CG_elem.cpp:1049
array3D reconstructPointFromBarycentricSegment(array3D const &, array3D const &, std::array< double, 2 > const &)
Definition CG_elem.cpp:828
double distancePointTriangle(array3D const &, array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:1409
double distancePointSegment(array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:1381
double distancePointPolygon(array3D const &, std::vector< array3D > const &, array3D &, int &)
Definition CG_elem.cpp:1498
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)
Definition compiler.hpp:53
#define BITPIT_UNUSED(variable)
Definition compiler.hpp:63
--- layout: doxygen_footer ---