452 enum { dim = GridView::dimension };
453 enum { dimWorld = GridView::dimensionworld };
454 enum { maxNC = dim < 3 ? 4 : 8 };
455 enum { maxNE = dim < 3 ? 4 : 12 };
456 enum { maxNF = dim < 3 ? 1 : 6 };
457 enum { maxBF = dim < 3 ? 8 : 24 };
458 using CoordScalar =
typename GridView::ctype;
459 using Element =
typename GridView::Traits::template Codim<0>::Entity;
462 using Entity =
typename GridView::Traits::template Codim<dim>::Entity;
465 using Geometry =
typename Element::Geometry;
466 using DimVector = Dune::FieldVector<Scalar, dimWorld>;
467 using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
468 using LocalPosition = Dune::FieldVector<CoordScalar, dim>;
469 using IntersectionIterator =
typename GridView::IntersectionIterator;
473#if HAVE_DUNE_LOCALFUNCTIONS
474 using LocalFiniteElementCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
475 using LocalFiniteElement =
typename LocalFiniteElementCache::FiniteElementType;
476 using LocalBasisTraits =
typename LocalFiniteElement::Traits::LocalBasisType::Traits;
477 using ShapeJacobian =
typename LocalBasisTraits::JacobianType;
480 Scalar quadrilateralArea(
const GlobalPosition& p0,
481 const GlobalPosition& p1,
482 const GlobalPosition& p2,
483 const GlobalPosition& p3)
485 return 0.5 * std::abs((p3[0] - p1[0]) * (p2[1] - p0[1]) -
486 (p3[1] - p1[1]) * (p2[0] - p0[0]));
489 void crossProduct(DimVector& c,
const DimVector& a,
const DimVector& b)
491 c[0] = a[1] * b[2] - a[2] * b[1];
492 c[1] = a[2] * b[0] - a[0] * b[2];
493 c[2] = a[0] * b[1] - a[1] * b[0];
496 Scalar pyramidVolume(
const GlobalPosition& p0,
497 const GlobalPosition& p1,
498 const GlobalPosition& p2,
499 const GlobalPosition& p3,
500 const GlobalPosition& p4)
502 DimVector a(p2); a -= p0;
503 DimVector b(p3); b -= p1;
506 crossProduct(n, a, b);
510 return 1.0 / 6.0 * (n * a);
513 Scalar prismVolume(
const GlobalPosition& p0,
514 const GlobalPosition& p1,
515 const GlobalPosition& p2,
516 const GlobalPosition& p3,
517 const GlobalPosition& p4,
518 const GlobalPosition& p5)
521 for (
unsigned k = 0; k < dimWorld; ++k) {
525 for (
unsigned k = 0; k < dimWorld; ++k) {
529 crossProduct(m, a, b);
531 for (
unsigned k = 0; k < dimWorld; ++k) {
532 a[k] = p1[k] - p0[k];
534 for (
unsigned k = 0; k < dimWorld; ++k) {
535 b[k] = p2[k] - p0[k];
538 crossProduct(n, a, b);
541 for (
unsigned k = 0; k < dimWorld; ++k) {
542 a[k] = p5[k] - p0[k];
545 return std::abs(1.0 / 6.0 * (n * a));
548 Scalar hexahedronVolume(
const GlobalPosition& p0,
549 const GlobalPosition& p1,
550 const GlobalPosition& p2,
551 const GlobalPosition& p3,
552 const GlobalPosition& p4,
553 const GlobalPosition& p5,
554 const GlobalPosition& p6,
555 const GlobalPosition& p7)
557 return prismVolume(p0, p1, p2, p4, p5, p6) +
558 prismVolume(p0, p2, p3, p4, p6, p7);
561 void normalOfQuadrilateral3D(DimVector& normal,
562 const GlobalPosition& p0,
563 const GlobalPosition& p1,
564 const GlobalPosition& p2,
565 const GlobalPosition& p3)
568 for (
unsigned k = 0; k < dimWorld; ++k) {
572 for (
unsigned k = 0; k < dimWorld; ++k) {
576 crossProduct(normal, a, b);
580 Scalar quadrilateralArea3D(
const GlobalPosition& p0,
581 const GlobalPosition& p1,
582 const GlobalPosition& p2,
583 const GlobalPosition& p3)
586 normalOfQuadrilateral3D(normal, p0, p1, p2, p3);
587 return normal.two_norm();
590 void getFaceIndices(
unsigned numElemVertices,
unsigned k,
unsigned& leftFace,
unsigned& rightFace)
592 static const unsigned edgeToFaceTet[2][6] = {
596 static const unsigned edgeToFacePyramid[2][8] = {
597 {1, 2, 3, 4, 1, 3, 4, 2},
598 {0, 0, 0, 0, 3, 2, 1, 4}
600 static const unsigned edgeToFacePrism[2][9] = {
601 {1, 0, 2, 0, 1, 2, 4, 4, 4},
602 {0, 2, 1, 3, 3, 3, 0, 1, 2}
604 static const unsigned edgeToFaceHex[2][12] = {
605 {0, 2, 3, 1, 4, 1, 2, 4, 0, 5, 5, 3},
606 {2, 1, 0, 3, 0, 4, 4, 3, 5, 1, 2, 5}
609 switch (numElemVertices) {
611 leftFace = edgeToFaceTet[0][k];
612 rightFace = edgeToFaceTet[1][k];
615 leftFace = edgeToFacePyramid[0][k];
616 rightFace = edgeToFacePyramid[1][k];
619 leftFace = edgeToFacePrism[0][k];
620 rightFace = edgeToFacePrism[1][k];
623 leftFace = edgeToFaceHex[0][k];
624 rightFace = edgeToFaceHex[1][k];
627 throw std::logic_error(
"Not implemented: VcfvStencil::getFaceIndices for "
628 + std::to_string(numElemVertices) +
" vertices");
633 void getEdgeIndices(
unsigned numElemVertices,
unsigned face,
unsigned vert,
634 unsigned& leftEdge,
unsigned& rightEdge)
636 static const int faceAndVertexToLeftEdgeTet[4][4] = {
642 static const int faceAndVertexToRightEdgeTet[4][4] = {
648 static const int faceAndVertexToLeftEdgePyramid[5][5] = {
655 static const int faceAndVertexToRightEdgePyramid[5][5] = {
662 static const int faceAndVertexToLeftEdgePrism[5][6] = {
663 { 3, 3, -1, 0, 1, -1},
664 { 4, -1, 4, 0, -1, 2},
665 {-1, 5, 5, -1, 1, 2},
666 { 3, 3, 5, -1, -1, -1},
667 {-1, -1, -1, 6, 6, 8}
669 static const int faceAndVertexToRightEdgePrism[5][6] = {
670 { 0, 1, -1, 6, 6, -1},
671 { 0, -1, 2, 7, -1, 7},
672 {-1, 1, 2, -1, 8, 8},
673 { 4, 5, 4, -1, -1, -1},
674 {-1, -1, -1, 7, 8, 7}
676 static const int faceAndVertexToLeftEdgeHex[6][8] = {
677 { 0, -1, 4, -1, 8, -1, 2, -1},
678 {-1, 5, -1, 3, -1, 1, -1, 9},
679 { 6, 1, -1, -1, 0, 10, -1, -1},
680 {-1, -1, 2, 7, -1, -1, 11, 3},
681 { 4, 6, 7, 5, -1, -1, -1, -1},
682 {-1, -1, -1, -1, 10, 9, 8, 11}
684 static const int faceAndVertexToRightEdgeHex[6][8] = {
685 { 4, -1, 2, -1, 0, -1, 8, -1},
686 {-1, 1, -1, 5, -1, 9, -1, 3},
687 { 0, 6, -1, -1, 10, 1, -1, -1},
688 {-1, -1, 7, 3, -1, -1, 2, 11},
689 { 6, 5, 4, 7, -1, -1, -1, -1},
690 {-1, -1, -1, -1, 8, 10, 11, 9}
693 switch (numElemVertices) {
695 leftEdge =
static_cast<unsigned>(faceAndVertexToLeftEdgeTet[face][vert]);
696 rightEdge =
static_cast<unsigned>(faceAndVertexToRightEdgeTet[face][vert]);
699 leftEdge =
static_cast<unsigned>(faceAndVertexToLeftEdgePyramid[face][vert]);
700 rightEdge =
static_cast<unsigned>(faceAndVertexToRightEdgePyramid[face][vert]);
703 leftEdge =
static_cast<unsigned>(faceAndVertexToLeftEdgePrism[face][vert]);
704 rightEdge =
static_cast<unsigned>(faceAndVertexToRightEdgePrism[face][vert]);
707 leftEdge =
static_cast<unsigned>(faceAndVertexToLeftEdgeHex[face][vert]);
708 rightEdge =
static_cast<unsigned>(faceAndVertexToRightEdgeHex[face][vert]);
711 throw std::logic_error(
"Not implemented: VcfvStencil::getFaceIndices for "
712 +std::to_string(numElemVertices)+
" vertices");
719 using Mapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
724 const GlobalPosition center()
const
725 {
return global(localGeometry_->center()); }
727 const GlobalPosition corner(
unsigned cornerIdx)
const
728 {
return global(localGeometry_->corner(cornerIdx)); }
730 const GlobalPosition global(
const LocalPosition& localPos)
const
731 {
return element_->geometry().global(localPos); }
733 const ScvLocalGeometry& localGeometry()
const
734 {
return *localGeometry_; }
736 const ScvLocalGeometry* localGeometry_;
737 const Element* element_;
742 const GlobalPosition& globalPos()
const
745 const GlobalPosition center()
const
748 Scalar volume()
const
751 const ScvLocalGeometry& localGeometry()
const
775 const DimVector& normal()
const
778 unsigned short interiorIndex()
const
781 unsigned short exteriorIndex()
const
787 const LocalPosition& localPos()
const
790 const GlobalPosition& integrationPos()
const
812 VcfvStencil(
const GridView& gridView,
const Mapper& mapper)
813 : gridView_(gridView)
814 , vertexMapper_(mapper )
815 , element_(*gridView.template begin<0>())
818 assert(
static_cast<int>(gridView.size(dimWorld)) ==
static_cast<int>(mapper.size()));
820 static bool localGeometriesInitialized =
false;
821 if (!localGeometriesInitialized) {
822 localGeometriesInitialized =
true;
824 VcfvScvGeometries<Scalar, 1, ElementType::cube>::init();
825 VcfvScvGeometries<Scalar, 2, ElementType::cube>::init();
826 VcfvScvGeometries<Scalar, 2, ElementType::simplex>::init();
827 VcfvScvGeometries<Scalar, 3, ElementType::cube>::init();
828 VcfvScvGeometries<Scalar, 3, ElementType::simplex>::init();
841 numVertices = e.subEntities(dim);
842 numEdges = e.subEntities(dim-1);
843 if constexpr (dim == 3) {
844 numFaces = e.subEntities(1);
850 numBoundarySegments_ = 0;
853 const Geometry& geometry = e.geometry();
854 geometryType_ = geometry.type();
855 const auto& referenceElement = Dune::ReferenceElements<CoordScalar,dim>::general(geometryType_);
856 for (
unsigned vertexIdx = 0; vertexIdx < numVertices; ++vertexIdx) {
857 subContVol[vertexIdx].local = referenceElement.position(
static_cast<int>(vertexIdx), dim);
858 subContVol[vertexIdx].global = geometry.corner(
static_cast<int>(vertexIdx));
862 void updatePrimaryTopology(
const Element& element)
870 void update(
const Element& e)
874 const Geometry& geometry = e.geometry();
875 geometryType_ = geometry.type();
877 const auto& referenceElement = Dune::ReferenceElements<CoordScalar,dim>::general(geometryType_);
879 elementVolume = geometry.volume();
880 elementLocal = referenceElement.position(0, 0);
881 elementGlobal = geometry.global(elementLocal);
884 for (
unsigned vert = 0; vert < numVertices; ++vert) {
885 subContVol[vert].local = referenceElement.position(
static_cast<int>(vert), dim);
886 subContVol[vert].global = geometry.global(subContVol[vert].local);
890 for (
unsigned edge = 0; edge < numEdges; ++edge) {
891 edgeCoord[edge] = geometry.global(referenceElement.position(
static_cast<int>(edge), dim - 1));
895 for (
unsigned face = 0; face < numFaces; ++face) {
896 faceCoord[face] = geometry.global(referenceElement.position(
static_cast<int>(face), 1));
904 fillSubContVolData_();
907 for (
unsigned k = 0; k < numEdges; ++k) {
909 static_cast<unsigned short>(referenceElement.subEntity(
static_cast<int>(k), dim - 1, 0, dim));
911 static_cast<unsigned short>(referenceElement.subEntity(
static_cast<int>(k), dim - 1, 1, dim));
912 if (numEdges == 4 && (i == 2 || j == 2)) {
915 subContVolFace[k].i = i;
916 subContVolFace[k].j = j;
923 LocalPosition ipLocal;
925 if constexpr (dim == 1) {
926 subContVolFace[k].ipLocal_ = 0.5;
927 subContVolFace[k].normal_ = 1.0;
928 subContVolFace[k].area_ = 1.0;
929 ipLocal = subContVolFace[k].ipLocal_;
931 else if constexpr (dim == 2) {
932 ipLocal = referenceElement.position(
static_cast<int>(k), dim - 1) + elementLocal;
934 subContVolFace[k].ipLocal_ = ipLocal;
935 for (
unsigned m = 0; m < dimWorld; ++m) {
936 diffVec[m] = elementGlobal[m] - edgeCoord[k][m];
938 subContVolFace[k].normal_[0] = diffVec[1];
939 subContVolFace[k].normal_[1] = -diffVec[0];
941 for (
unsigned m = 0; m < dimWorld; ++m) {
942 diffVec[m] = subContVol[j].global[m] - subContVol[i].global[m];
945 if (subContVolFace[k].normal_ * diffVec < 0) {
946 subContVolFace[k].normal_ *= -1;
949 subContVolFace[k].area_ = subContVolFace[k].normal_.two_norm();
950 subContVolFace[k].normal_ /= subContVolFace[k].area_;
952 else if constexpr (dim == 3) {
955 getFaceIndices(numVertices, k, leftFace, rightFace);
956 ipLocal = referenceElement.position(
static_cast<int>(k), dim - 1) +
958 referenceElement.position(
static_cast<int>(leftFace), 1) +
959 referenceElement.position(
static_cast<int>(rightFace), 1);
961 subContVolFace[k].ipLocal_ = ipLocal;
962 normalOfQuadrilateral3D(subContVolFace[k].normal_,
963 edgeCoord[k], faceCoord[rightFace],
964 elementGlobal, faceCoord[leftFace]);
965 subContVolFace[k].area_ = subContVolFace[k].normal_.two_norm();
966 subContVolFace[k].normal_ /= subContVolFace[k].area_;
970 subContVolFace[k].ipGlobal_ = geometry.global(ipLocal);
974 for (
const auto& intersection : intersections(gridView_, e)) {
975 if (!intersection.boundary()) {
979 const unsigned face =
static_cast<unsigned>(intersection.indexInInside());
980 const unsigned numVerticesOfFace =
static_cast<unsigned>(referenceElement.size(
static_cast<int>(face), 1, dim));
981 for (
unsigned vertInFace = 0; vertInFace < numVerticesOfFace; ++vertInFace) {
982 const unsigned short vertInElement =
static_cast<unsigned short>(referenceElement.subEntity(
static_cast<int>(face), 1,
static_cast<int>(vertInFace), dim));
983 const unsigned bfIdx = numBoundarySegments_;
984 ++numBoundarySegments_;
986 if constexpr (dim == 1) {
987 boundaryFace_[bfIdx].ipLocal_ = referenceElement.position(
static_cast<int>(vertInElement), dim);
988 boundaryFace_[bfIdx].area_ = 1.0;
990 else if constexpr (dim == 2) {
991 boundaryFace_[bfIdx].ipLocal_ =
992 referenceElement.position(
static_cast<int>(vertInElement), dim) +
993 referenceElement.position(
static_cast<int>(face), 1);
994 boundaryFace_[bfIdx].ipLocal_ *= 0.5;
995 boundaryFace_[bfIdx].area_ = 0.5 * intersection.geometry().volume();
997 else if constexpr (dim == 3) {
1000 getEdgeIndices(numVertices, face, vertInElement, leftEdge, rightEdge);
1001 boundaryFace_[bfIdx].ipLocal_ =
1002 referenceElement.position(
static_cast<int>(vertInElement), dim) +
1003 referenceElement.position(
static_cast<int>(face), 1) +
1004 referenceElement.position(
static_cast<int>(leftEdge), dim - 1) +
1005 referenceElement.position(
static_cast<int>(rightEdge), dim - 1);
1006 boundaryFace_[bfIdx].ipLocal_ *= 0.25;
1007 boundaryFace_[bfIdx].area_ =
1008 quadrilateralArea3D(subContVol[vertInElement].global,
1009 edgeCoord[rightEdge],
1011 edgeCoord[leftEdge]);
1014 throw std::logic_error(
"Not implemented:VcfvStencil for dim = " + std::to_string(dim));
1017 boundaryFace_[bfIdx].ipGlobal_ = geometry.global(boundaryFace_[bfIdx].ipLocal_);
1018 boundaryFace_[bfIdx].i = vertInElement;
1019 boundaryFace_[bfIdx].j = vertInElement;
1022 boundaryFace_[bfIdx].normal_ = intersection.centerUnitOuterNormal();
1026 updateScvGeometry(e);
1029 void updateScvGeometry(
const Element& element)
1031 auto geomType = element.geometry().type();
1034 if (geomType.isTriangle() || geomType.isTetrahedron()) {
1035 for (
unsigned vertIdx = 0; vertIdx < numVertices; ++vertIdx) {
1036 subContVol[vertIdx].geometry_.element_ = &element;
1037 subContVol[vertIdx].geometry_.localGeometry_ =
1038 &VcfvScvGeometries<Scalar, dim, ElementType::simplex>::get(vertIdx);
1041 else if (geomType.isLine() || geomType.isQuadrilateral() || geomType.isHexahedron()) {
1042 for (
unsigned vertIdx = 0; vertIdx < numVertices; ++vertIdx) {
1043 subContVol[vertIdx].geometry_.element_ = &element;
1044 subContVol[vertIdx].geometry_.localGeometry_ =
1045 &VcfvScvGeometries<Scalar, dim, ElementType::cube>::get(vertIdx);
1049 throw std::logic_error(
"Not implemented: SCV geometries for non hexahedron elements");
1053#if HAVE_DUNE_LOCALFUNCTIONS
1054 void updateCenterGradients()
1056 const auto& localFiniteElement = feCache_.get(element_.type());
1057 const auto& geom = element_.geometry();
1059 std::vector<ShapeJacobian> localJac;
1061 for (
unsigned scvIdx = 0; scvIdx < numVertices; ++scvIdx) {
1062 const auto& localCenter = subContVol[scvIdx].localGeometry().center();
1063 localFiniteElement.localBasis().evaluateJacobian(localCenter, localJac);
1064 const auto& globalPos = subContVol[scvIdx].geometry().center();
1066 const auto jacInvT = geom.jacobianInverseTransposed(globalPos);
1067 for (
unsigned vert = 0; vert < numVertices; ++vert) {
1068 jacInvT.mv(localJac[vert][0], subContVol[scvIdx].gradCenter[vert]);
1074 unsigned numDof()
const
1075 {
return numVertices; }
1077 unsigned numPrimaryDof()
const
1078 {
return numDof(); }
1080 Dune::PartitionType partitionType(
unsigned scvIdx)
const
1081 {
return element_.template subEntity<dim>(scvIdx)->partitionType(); }
1085 assert(scvIdx < numDof());
1086 return subContVol[scvIdx];
1089 unsigned numInteriorFaces()
const
1090 {
return numEdges; }
1092 unsigned numBoundaryFaces()
const
1093 {
return numBoundarySegments_; }
1096 {
return subContVolFace[faceIdx]; }
1099 {
return boundaryFace_[bfIdx]; }
1107 assert(dofIdx < numDof());
1109 return static_cast<unsigned>(vertexMapper_.subIndex(element_,
static_cast<int>(dofIdx), dim));
1118 assert(dofIdx < numDof());
1119 return element_.template subEntity<dim>(
static_cast<int>(dofIdx));
1123#if __GNUC__ || __clang__
1124#pragma GCC diagnostic push
1125#pragma GCC diagnostic ignored "-Wpragmas"
1126#pragma GCC diagnostic ignored "-Warray-bounds"
1128 void fillSubContVolData_()
1130 if constexpr (dim == 1) {
1132 subContVol[0].volume_ = 0.5 * elementVolume;
1133 subContVol[1].volume_ = 0.5 * elementVolume;
1135 else if constexpr (dim == 2) {
1136 switch (numVertices) {
1138 subContVol[0].volume_ = elementVolume / 3;
1139 subContVol[1].volume_ = elementVolume / 3;
1140 subContVol[2].volume_ = elementVolume / 3;
1143 subContVol[0].volume_ =
1144 quadrilateralArea(subContVol[0].global,
1148 subContVol[1].volume_ =
1149 quadrilateralArea(subContVol[1].global,
1153 subContVol[2].volume_ =
1154 quadrilateralArea(subContVol[2].global,
1158 subContVol[3].volume_ =
1159 quadrilateralArea(subContVol[3].global,
1165 throw std::logic_error(
"Not implemented:VcfvStencil dim = " + std::to_string(dim) +
1166 ", numVertices = " + std::to_string(numVertices));
1169 else if constexpr (dim == 3) {
1170 switch (numVertices) {
1172 for (
unsigned k = 0; k < numVertices; k++) {
1173 subContVol[k].volume_ = elementVolume / 4.0;
1177 subContVol[0].volume_ =
1178 hexahedronVolume(subContVol[0].global,
1186 subContVol[1].volume_ =
1187 hexahedronVolume(subContVol[1].global,
1195 subContVol[2].volume_ =
1196 hexahedronVolume(subContVol[2].global,
1204 subContVol[3].volume_ =
1205 hexahedronVolume(subContVol[3].global,
1213 subContVol[4].volume_ = elementVolume -
1214 subContVol[0].volume_ -
1215 subContVol[1].volume_ -
1216 subContVol[2].volume_ -
1217 subContVol[3].volume_;
1220 subContVol[0].volume_ =
1221 hexahedronVolume(subContVol[0].global,
1229 subContVol[1].volume_ =
1230 hexahedronVolume(subContVol[1].global,
1238 subContVol[2].volume_ =
1239 hexahedronVolume(subContVol[2].global,
1247 subContVol[3].volume_ =
1248 hexahedronVolume(edgeCoord[0],
1252 subContVol[3].global,
1256 subContVol[4].volume_ =
1257 hexahedronVolume(edgeCoord[1],
1261 subContVol[4].global,
1265 subContVol[5].volume_ =
1266 hexahedronVolume(edgeCoord[2],
1270 subContVol[5].global,
1276 subContVol[0].volume_ =
1277 hexahedronVolume(subContVol[0].global,
1285 subContVol[1].volume_ =
1286 hexahedronVolume(subContVol[1].global,
1294 subContVol[2].volume_ =
1295 hexahedronVolume(subContVol[2].global,
1303 subContVol[3].volume_ =
1304 hexahedronVolume(subContVol[3].global,
1312 subContVol[4].volume_ =
1313 hexahedronVolume(edgeCoord[0],
1317 subContVol[4].global,
1321 subContVol[5].volume_ =
1322 hexahedronVolume(edgeCoord[1],
1326 subContVol[5].global,
1330 subContVol[6].volume_ =
1331 hexahedronVolume(edgeCoord[2],
1335 subContVol[6].global,
1339 subContVol[7].volume_ =
1340 hexahedronVolume(edgeCoord[3],
1344 subContVol[7].global,
1350 throw std::logic_error(
"Not implemented:VcfvStencil for dim = " + std::to_string(dim) +
1351 ", numVertices = " + std::to_string(numVertices));
1355 throw std::logic_error(
"Not implemented:VcfvStencil for dim = " + std::to_string(dim));
1358#if __GNUC__ || __clang__
1359#pragma GCC diagnostic pop
1362 const GridView& gridView_;
1363 const Mapper& vertexMapper_;
1367#if HAVE_DUNE_LOCALFUNCTIONS
1368 static LocalFiniteElementCache feCache_;
1372 LocalPosition elementLocal;
1375 GlobalPosition elementGlobal;
1378 Scalar elementVolume;
1381 std::array<SubControlVolume, maxNC> subContVol{};
1384 std::array<SubControlVolumeFace, maxNE> subContVolFace{};
1387 std::array<BoundaryFace, maxBF> boundaryFace_{};
1389 unsigned numBoundarySegments_{};
1392 std::array<GlobalPosition, maxNE> edgeCoord{};
1395 std::array<GlobalPosition, maxNF> faceCoord{};
1398 unsigned numVertices{};
1401 unsigned numEdges{};
1404 unsigned numFaces{};
1406 Dune::GeometryType geometryType_;