453 enum { dim = GridView::dimension };
454 enum { dimWorld = GridView::dimensionworld };
455 enum { maxNC = dim < 3 ? 4 : 8 };
456 enum { maxNE = dim < 3 ? 4 : 12 };
457 enum { maxNF = dim < 3 ? 1 : 6 };
458 enum { maxBF = dim < 3 ? 8 : 24 };
459 using CoordScalar =
typename GridView::ctype;
460 using Element =
typename GridView::Traits::template Codim<0>::Entity;
463 using Entity =
typename GridView::Traits::template Codim<dim>::Entity;
466 using Geometry =
typename Element::Geometry;
467 using DimVector = Dune::FieldVector<Scalar, dimWorld>;
468 using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
469 using LocalPosition = Dune::FieldVector<CoordScalar, dim>;
470 using IntersectionIterator =
typename GridView::IntersectionIterator;
474#if HAVE_DUNE_LOCALFUNCTIONS
475 using LocalFiniteElementCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
476 using LocalFiniteElement =
typename LocalFiniteElementCache::FiniteElementType;
477 using LocalBasisTraits =
typename LocalFiniteElement::Traits::LocalBasisType::Traits;
478 using ShapeJacobian =
typename LocalBasisTraits::JacobianType;
481 Scalar quadrilateralArea(
const GlobalPosition& p0,
482 const GlobalPosition& p1,
483 const GlobalPosition& p2,
484 const GlobalPosition& p3)
486 return 0.5 * std::abs((p3[0] - p1[0]) * (p2[1] - p0[1]) -
487 (p3[1] - p1[1]) * (p2[0] - p0[0]));
490 void crossProduct(DimVector& c,
const DimVector& a,
const DimVector& b)
492 c[0] = a[1] * b[2] - a[2] * b[1];
493 c[1] = a[2] * b[0] - a[0] * b[2];
494 c[2] = a[0] * b[1] - a[1] * b[0];
497 Scalar pyramidVolume(
const GlobalPosition& p0,
498 const GlobalPosition& p1,
499 const GlobalPosition& p2,
500 const GlobalPosition& p3,
501 const GlobalPosition& p4)
503 DimVector a(p2); a -= p0;
504 DimVector b(p3); b -= p1;
507 crossProduct(n, a, b);
511 return 1.0 / 6.0 * (n * a);
514 Scalar prismVolume(
const GlobalPosition& p0,
515 const GlobalPosition& p1,
516 const GlobalPosition& p2,
517 const GlobalPosition& p3,
518 const GlobalPosition& p4,
519 const GlobalPosition& p5)
522 for (
unsigned k = 0; k < dimWorld; ++k) {
526 for (
unsigned k = 0; k < dimWorld; ++k) {
530 crossProduct(m, a, b);
532 for (
unsigned k = 0; k < dimWorld; ++k) {
533 a[k] = p1[k] - p0[k];
535 for (
unsigned k = 0; k < dimWorld; ++k) {
536 b[k] = p2[k] - p0[k];
539 crossProduct(n, a, b);
542 for (
unsigned k = 0; k < dimWorld; ++k) {
543 a[k] = p5[k] - p0[k];
546 return std::abs(1.0 / 6.0 * (n * a));
549 Scalar hexahedronVolume(
const GlobalPosition& p0,
550 const GlobalPosition& p1,
551 const GlobalPosition& p2,
552 const GlobalPosition& p3,
553 const GlobalPosition& p4,
554 const GlobalPosition& p5,
555 const GlobalPosition& p6,
556 const GlobalPosition& p7)
558 return prismVolume(p0, p1, p2, p4, p5, p6) +
559 prismVolume(p0, p2, p3, p4, p6, p7);
562 void normalOfQuadrilateral3D(DimVector& normal,
563 const GlobalPosition& p0,
564 const GlobalPosition& p1,
565 const GlobalPosition& p2,
566 const GlobalPosition& p3)
569 for (
unsigned k = 0; k < dimWorld; ++k) {
573 for (
unsigned k = 0; k < dimWorld; ++k) {
577 crossProduct(normal, a, b);
581 Scalar quadrilateralArea3D(
const GlobalPosition& p0,
582 const GlobalPosition& p1,
583 const GlobalPosition& p2,
584 const GlobalPosition& p3)
587 normalOfQuadrilateral3D(normal, p0, p1, p2, p3);
588 return normal.two_norm();
591 void getFaceIndices(
unsigned numElemVertices,
unsigned k,
unsigned& leftFace,
unsigned& rightFace)
593 static const unsigned edgeToFaceTet[2][6] = {
597 static const unsigned edgeToFacePyramid[2][8] = {
598 {1, 2, 3, 4, 1, 3, 4, 2},
599 {0, 0, 0, 0, 3, 2, 1, 4}
601 static const unsigned edgeToFacePrism[2][9] = {
602 {1, 0, 2, 0, 1, 2, 4, 4, 4},
603 {0, 2, 1, 3, 3, 3, 0, 1, 2}
605 static const unsigned edgeToFaceHex[2][12] = {
606 {0, 2, 3, 1, 4, 1, 2, 4, 0, 5, 5, 3},
607 {2, 1, 0, 3, 0, 4, 4, 3, 5, 1, 2, 5}
610 switch (numElemVertices) {
612 leftFace = edgeToFaceTet[0][k];
613 rightFace = edgeToFaceTet[1][k];
616 leftFace = edgeToFacePyramid[0][k];
617 rightFace = edgeToFacePyramid[1][k];
620 leftFace = edgeToFacePrism[0][k];
621 rightFace = edgeToFacePrism[1][k];
624 leftFace = edgeToFaceHex[0][k];
625 rightFace = edgeToFaceHex[1][k];
628 throw std::logic_error(
"Not implemented: VcfvStencil::getFaceIndices for "
629 + std::to_string(numElemVertices) +
" vertices");
634 void getEdgeIndices(
unsigned numElemVertices,
unsigned face,
unsigned vert,
635 unsigned& leftEdge,
unsigned& rightEdge)
637 static const int faceAndVertexToLeftEdgeTet[4][4] = {
643 static const int faceAndVertexToRightEdgeTet[4][4] = {
649 static const int faceAndVertexToLeftEdgePyramid[5][5] = {
656 static const int faceAndVertexToRightEdgePyramid[5][5] = {
663 static const int faceAndVertexToLeftEdgePrism[5][6] = {
664 { 3, 3, -1, 0, 1, -1},
665 { 4, -1, 4, 0, -1, 2},
666 {-1, 5, 5, -1, 1, 2},
667 { 3, 3, 5, -1, -1, -1},
668 {-1, -1, -1, 6, 6, 8}
670 static const int faceAndVertexToRightEdgePrism[5][6] = {
671 { 0, 1, -1, 6, 6, -1},
672 { 0, -1, 2, 7, -1, 7},
673 {-1, 1, 2, -1, 8, 8},
674 { 4, 5, 4, -1, -1, -1},
675 {-1, -1, -1, 7, 8, 7}
677 static const int faceAndVertexToLeftEdgeHex[6][8] = {
678 { 0, -1, 4, -1, 8, -1, 2, -1},
679 {-1, 5, -1, 3, -1, 1, -1, 9},
680 { 6, 1, -1, -1, 0, 10, -1, -1},
681 {-1, -1, 2, 7, -1, -1, 11, 3},
682 { 4, 6, 7, 5, -1, -1, -1, -1},
683 {-1, -1, -1, -1, 10, 9, 8, 11}
685 static const int faceAndVertexToRightEdgeHex[6][8] = {
686 { 4, -1, 2, -1, 0, -1, 8, -1},
687 {-1, 1, -1, 5, -1, 9, -1, 3},
688 { 0, 6, -1, -1, 10, 1, -1, -1},
689 {-1, -1, 7, 3, -1, -1, 2, 11},
690 { 6, 5, 4, 7, -1, -1, -1, -1},
691 {-1, -1, -1, -1, 8, 10, 11, 9}
694 switch (numElemVertices) {
696 leftEdge =
static_cast<unsigned>(faceAndVertexToLeftEdgeTet[face][vert]);
697 rightEdge =
static_cast<unsigned>(faceAndVertexToRightEdgeTet[face][vert]);
700 leftEdge =
static_cast<unsigned>(faceAndVertexToLeftEdgePyramid[face][vert]);
701 rightEdge =
static_cast<unsigned>(faceAndVertexToRightEdgePyramid[face][vert]);
704 leftEdge =
static_cast<unsigned>(faceAndVertexToLeftEdgePrism[face][vert]);
705 rightEdge =
static_cast<unsigned>(faceAndVertexToRightEdgePrism[face][vert]);
708 leftEdge =
static_cast<unsigned>(faceAndVertexToLeftEdgeHex[face][vert]);
709 rightEdge =
static_cast<unsigned>(faceAndVertexToRightEdgeHex[face][vert]);
712 throw std::logic_error(
"Not implemented: VcfvStencil::getFaceIndices for "
713 +std::to_string(numElemVertices)+
" vertices");
720 using Mapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
725 const GlobalPosition center()
const
726 {
return global(localGeometry_->center()); }
728 const GlobalPosition corner(
unsigned cornerIdx)
const
729 {
return global(localGeometry_->corner(cornerIdx)); }
731 const GlobalPosition global(
const LocalPosition& localPos)
const
732 {
return element_->geometry().global(localPos); }
734 const ScvLocalGeometry& localGeometry()
const
735 {
return *localGeometry_; }
737 const ScvLocalGeometry* localGeometry_;
738 const Element* element_;
743 const GlobalPosition& globalPos()
const
746 const GlobalPosition center()
const
749 Scalar volume()
const
752 const ScvLocalGeometry& localGeometry()
const
776 const DimVector& normal()
const
779 unsigned short interiorIndex()
const
782 unsigned short exteriorIndex()
const
788 const LocalPosition& localPos()
const
791 const GlobalPosition& integrationPos()
const
813 VcfvStencil(
const GridView& gridView,
const Mapper& mapper)
814 : gridView_(gridView)
815 , vertexMapper_(mapper )
816 , element_(*gridView.template begin<0>())
819 assert(
static_cast<int>(gridView.size(dimWorld)) ==
static_cast<int>(mapper.size()));
821 static bool localGeometriesInitialized =
false;
822 if (!localGeometriesInitialized) {
823 localGeometriesInitialized =
true;
825 VcfvScvGeometries<Scalar, 1, ElementType::cube>::init();
826 VcfvScvGeometries<Scalar, 2, ElementType::cube>::init();
827 VcfvScvGeometries<Scalar, 2, ElementType::simplex>::init();
828 VcfvScvGeometries<Scalar, 3, ElementType::cube>::init();
829 VcfvScvGeometries<Scalar, 3, ElementType::simplex>::init();
842 numVertices = e.subEntities(dim);
843 numEdges = e.subEntities(dim-1);
844 if constexpr (dim == 3) {
845 numFaces = e.subEntities(1);
851 numBoundarySegments_ = 0;
854 const Geometry& geometry = e.geometry();
855 geometryType_ = geometry.type();
856 const auto& referenceElement = Dune::ReferenceElements<CoordScalar,dim>::general(geometryType_);
858 assert(numVertices ==
static_cast<unsigned>(referenceElement.size(dim)));
859 numVertices = std::min(numVertices,
static_cast<unsigned>(referenceElement.size(dim)));
860 for (
unsigned vertexIdx = 0; vertexIdx < numVertices; ++vertexIdx) {
861 subContVol[vertexIdx].local = referenceElement.position(
static_cast<int>(vertexIdx), dim);
862 subContVol[vertexIdx].global = geometry.corner(
static_cast<int>(vertexIdx));
866 void updatePrimaryTopology(
const Element& element)
874 void update(
const Element& e)
878 const Geometry& geometry = e.geometry();
879 geometryType_ = geometry.type();
881 const auto& referenceElement = Dune::ReferenceElements<CoordScalar,dim>::general(geometryType_);
883 elementVolume = geometry.volume();
884 elementLocal = referenceElement.position(0, 0);
885 elementGlobal = geometry.global(elementLocal);
888 for (
unsigned vert = 0; vert < numVertices; ++vert) {
889 subContVol[vert].local = referenceElement.position(
static_cast<int>(vert), dim);
890 subContVol[vert].global = geometry.global(subContVol[vert].local);
894 for (
unsigned edge = 0; edge < numEdges; ++edge) {
895 edgeCoord[edge] = geometry.global(referenceElement.position(
static_cast<int>(edge), dim - 1));
899 for (
unsigned face = 0; face < numFaces; ++face) {
900 faceCoord[face] = geometry.global(referenceElement.position(
static_cast<int>(face), 1));
908 fillSubContVolData_();
911 for (
unsigned k = 0; k < numEdges; ++k) {
913 static_cast<unsigned short>(referenceElement.subEntity(
static_cast<int>(k), dim - 1, 0, dim));
915 static_cast<unsigned short>(referenceElement.subEntity(
static_cast<int>(k), dim - 1, 1, dim));
916 if (numEdges == 4 && (i == 2 || j == 2)) {
919 subContVolFace[k].i = i;
920 subContVolFace[k].j = j;
927 LocalPosition ipLocal;
929 if constexpr (dim == 1) {
930 subContVolFace[k].ipLocal_ = 0.5;
931 subContVolFace[k].normal_ = 1.0;
932 subContVolFace[k].area_ = 1.0;
933 ipLocal = subContVolFace[k].ipLocal_;
935 else if constexpr (dim == 2) {
936 ipLocal = referenceElement.position(
static_cast<int>(k), dim - 1) + elementLocal;
938 subContVolFace[k].ipLocal_ = ipLocal;
939 for (
unsigned m = 0; m < dimWorld; ++m) {
940 diffVec[m] = elementGlobal[m] - edgeCoord[k][m];
942 subContVolFace[k].normal_[0] = diffVec[1];
943 subContVolFace[k].normal_[1] = -diffVec[0];
945 for (
unsigned m = 0; m < dimWorld; ++m) {
946 diffVec[m] = subContVol[j].global[m] - subContVol[i].global[m];
949 if (subContVolFace[k].normal_ * diffVec < 0) {
950 subContVolFace[k].normal_ *= -1;
953 subContVolFace[k].area_ = subContVolFace[k].normal_.two_norm();
954 subContVolFace[k].normal_ /= subContVolFace[k].area_;
956 else if constexpr (dim == 3) {
959 getFaceIndices(numVertices, k, leftFace, rightFace);
960 ipLocal = referenceElement.position(
static_cast<int>(k), dim - 1) +
962 referenceElement.position(
static_cast<int>(leftFace), 1) +
963 referenceElement.position(
static_cast<int>(rightFace), 1);
965 subContVolFace[k].ipLocal_ = ipLocal;
966 normalOfQuadrilateral3D(subContVolFace[k].normal_,
967 edgeCoord[k], faceCoord[rightFace],
968 elementGlobal, faceCoord[leftFace]);
969 subContVolFace[k].area_ = subContVolFace[k].normal_.two_norm();
970 subContVolFace[k].normal_ /= subContVolFace[k].area_;
974 subContVolFace[k].ipGlobal_ = geometry.global(ipLocal);
978 for (
const auto& intersection : intersections(gridView_, e)) {
979 if (!intersection.boundary()) {
983 const unsigned face =
static_cast<unsigned>(intersection.indexInInside());
984 const unsigned numVerticesOfFace =
static_cast<unsigned>(referenceElement.size(
static_cast<int>(face), 1, dim));
985 for (
unsigned vertInFace = 0; vertInFace < numVerticesOfFace; ++vertInFace) {
986 const unsigned short vertInElement =
static_cast<unsigned short>(referenceElement.subEntity(
static_cast<int>(face), 1,
static_cast<int>(vertInFace), dim));
987 const unsigned bfIdx = numBoundarySegments_;
988 ++numBoundarySegments_;
990 if constexpr (dim == 1) {
991 boundaryFace_[bfIdx].ipLocal_ = referenceElement.position(
static_cast<int>(vertInElement), dim);
992 boundaryFace_[bfIdx].area_ = 1.0;
994 else if constexpr (dim == 2) {
995 boundaryFace_[bfIdx].ipLocal_ =
996 referenceElement.position(
static_cast<int>(vertInElement), dim) +
997 referenceElement.position(
static_cast<int>(face), 1);
998 boundaryFace_[bfIdx].ipLocal_ *= 0.5;
999 boundaryFace_[bfIdx].area_ = 0.5 * intersection.geometry().volume();
1001 else if constexpr (dim == 3) {
1004 getEdgeIndices(numVertices, face, vertInElement, leftEdge, rightEdge);
1005 boundaryFace_[bfIdx].ipLocal_ =
1006 referenceElement.position(
static_cast<int>(vertInElement), dim) +
1007 referenceElement.position(
static_cast<int>(face), 1) +
1008 referenceElement.position(
static_cast<int>(leftEdge), dim - 1) +
1009 referenceElement.position(
static_cast<int>(rightEdge), dim - 1);
1010 boundaryFace_[bfIdx].ipLocal_ *= 0.25;
1011 boundaryFace_[bfIdx].area_ =
1012 quadrilateralArea3D(subContVol[vertInElement].global,
1013 edgeCoord[rightEdge],
1015 edgeCoord[leftEdge]);
1018 throw std::logic_error(
"Not implemented:VcfvStencil for dim = " + std::to_string(dim));
1021 boundaryFace_[bfIdx].ipGlobal_ = geometry.global(boundaryFace_[bfIdx].ipLocal_);
1022 boundaryFace_[bfIdx].i = vertInElement;
1023 boundaryFace_[bfIdx].j = vertInElement;
1026 boundaryFace_[bfIdx].normal_ = intersection.centerUnitOuterNormal();
1030 updateScvGeometry(e);
1033 void updateScvGeometry(
const Element& element)
1035 auto geomType = element.geometry().type();
1038 if (geomType.isTriangle() || geomType.isTetrahedron()) {
1039 for (
unsigned vertIdx = 0; vertIdx < numVertices; ++vertIdx) {
1040 subContVol[vertIdx].geometry_.element_ = &element;
1041 subContVol[vertIdx].geometry_.localGeometry_ =
1042 &VcfvScvGeometries<Scalar, dim, ElementType::simplex>::get(vertIdx);
1045 else if (geomType.isLine() || geomType.isQuadrilateral() || geomType.isHexahedron()) {
1046 for (
unsigned vertIdx = 0; vertIdx < numVertices; ++vertIdx) {
1047 subContVol[vertIdx].geometry_.element_ = &element;
1048 subContVol[vertIdx].geometry_.localGeometry_ =
1049 &VcfvScvGeometries<Scalar, dim, ElementType::cube>::get(vertIdx);
1053 throw std::logic_error(
"Not implemented: SCV geometries for non hexahedron elements");
1057#if HAVE_DUNE_LOCALFUNCTIONS
1058 void updateCenterGradients()
1060 const auto& localFiniteElement = feCache_.get(element_.type());
1061 const auto& geom = element_.geometry();
1063 std::vector<ShapeJacobian> localJac;
1065 for (
unsigned scvIdx = 0; scvIdx < numVertices; ++scvIdx) {
1066 const auto& localCenter = subContVol[scvIdx].localGeometry().center();
1067 localFiniteElement.localBasis().evaluateJacobian(localCenter, localJac);
1068 const auto& globalPos = subContVol[scvIdx].geometry().center();
1070 const auto jacInvT = geom.jacobianInverseTransposed(globalPos);
1071 for (
unsigned vert = 0; vert < numVertices; ++vert) {
1072 jacInvT.mv(localJac[vert][0], subContVol[scvIdx].gradCenter[vert]);
1078 unsigned numDof()
const
1079 {
return numVertices; }
1081 unsigned numPrimaryDof()
const
1082 {
return numDof(); }
1084 Dune::PartitionType partitionType(
unsigned scvIdx)
const
1085 {
return element_.template subEntity<dim>(scvIdx)->partitionType(); }
1089 assert(scvIdx < numDof());
1090 return subContVol[scvIdx];
1093 unsigned numInteriorFaces()
const
1094 {
return numEdges; }
1096 unsigned numBoundaryFaces()
const
1097 {
return numBoundarySegments_; }
1100 {
return subContVolFace[faceIdx]; }
1103 {
return boundaryFace_[bfIdx]; }
1111 assert(dofIdx < numDof());
1113 return static_cast<unsigned>(vertexMapper_.subIndex(element_,
static_cast<int>(dofIdx), dim));
1122 assert(dofIdx < numDof());
1123 return element_.template subEntity<dim>(
static_cast<int>(dofIdx));
1127#if __GNUC__ || __clang__
1128#pragma GCC diagnostic push
1129#pragma GCC diagnostic ignored "-Wpragmas"
1130#pragma GCC diagnostic ignored "-Warray-bounds"
1132 void fillSubContVolData_()
1134 if constexpr (dim == 1) {
1136 subContVol[0].volume_ = 0.5 * elementVolume;
1137 subContVol[1].volume_ = 0.5 * elementVolume;
1139 else if constexpr (dim == 2) {
1140 switch (numVertices) {
1142 subContVol[0].volume_ = elementVolume / 3;
1143 subContVol[1].volume_ = elementVolume / 3;
1144 subContVol[2].volume_ = elementVolume / 3;
1147 subContVol[0].volume_ =
1148 quadrilateralArea(subContVol[0].global,
1152 subContVol[1].volume_ =
1153 quadrilateralArea(subContVol[1].global,
1157 subContVol[2].volume_ =
1158 quadrilateralArea(subContVol[2].global,
1162 subContVol[3].volume_ =
1163 quadrilateralArea(subContVol[3].global,
1169 throw std::logic_error(
"Not implemented:VcfvStencil dim = " + std::to_string(dim) +
1170 ", numVertices = " + std::to_string(numVertices));
1173 else if constexpr (dim == 3) {
1174 switch (numVertices) {
1176 for (
unsigned k = 0; k < numVertices; k++) {
1177 subContVol[k].volume_ = elementVolume / 4.0;
1181 subContVol[0].volume_ =
1182 hexahedronVolume(subContVol[0].global,
1190 subContVol[1].volume_ =
1191 hexahedronVolume(subContVol[1].global,
1199 subContVol[2].volume_ =
1200 hexahedronVolume(subContVol[2].global,
1208 subContVol[3].volume_ =
1209 hexahedronVolume(subContVol[3].global,
1217 subContVol[4].volume_ = elementVolume -
1218 subContVol[0].volume_ -
1219 subContVol[1].volume_ -
1220 subContVol[2].volume_ -
1221 subContVol[3].volume_;
1224 subContVol[0].volume_ =
1225 hexahedronVolume(subContVol[0].global,
1233 subContVol[1].volume_ =
1234 hexahedronVolume(subContVol[1].global,
1242 subContVol[2].volume_ =
1243 hexahedronVolume(subContVol[2].global,
1251 subContVol[3].volume_ =
1252 hexahedronVolume(edgeCoord[0],
1256 subContVol[3].global,
1260 subContVol[4].volume_ =
1261 hexahedronVolume(edgeCoord[1],
1265 subContVol[4].global,
1269 subContVol[5].volume_ =
1270 hexahedronVolume(edgeCoord[2],
1274 subContVol[5].global,
1280 subContVol[0].volume_ =
1281 hexahedronVolume(subContVol[0].global,
1289 subContVol[1].volume_ =
1290 hexahedronVolume(subContVol[1].global,
1298 subContVol[2].volume_ =
1299 hexahedronVolume(subContVol[2].global,
1307 subContVol[3].volume_ =
1308 hexahedronVolume(subContVol[3].global,
1316 subContVol[4].volume_ =
1317 hexahedronVolume(edgeCoord[0],
1321 subContVol[4].global,
1325 subContVol[5].volume_ =
1326 hexahedronVolume(edgeCoord[1],
1330 subContVol[5].global,
1334 subContVol[6].volume_ =
1335 hexahedronVolume(edgeCoord[2],
1339 subContVol[6].global,
1343 subContVol[7].volume_ =
1344 hexahedronVolume(edgeCoord[3],
1348 subContVol[7].global,
1354 throw std::logic_error(
"Not implemented:VcfvStencil for dim = " + std::to_string(dim) +
1355 ", numVertices = " + std::to_string(numVertices));
1359 throw std::logic_error(
"Not implemented:VcfvStencil for dim = " + std::to_string(dim));
1362#if __GNUC__ || __clang__
1363#pragma GCC diagnostic pop
1366 const GridView& gridView_;
1367 const Mapper& vertexMapper_;
1371#if HAVE_DUNE_LOCALFUNCTIONS
1372 static LocalFiniteElementCache feCache_;
1376 LocalPosition elementLocal;
1379 GlobalPosition elementGlobal;
1382 Scalar elementVolume;
1385 std::array<SubControlVolume, maxNC> subContVol{};
1388 std::array<SubControlVolumeFace, maxNE> subContVolFace{};
1391 std::array<BoundaryFace, maxBF> boundaryFace_{};
1393 unsigned numBoundarySegments_{};
1396 std::array<GlobalPosition, maxNE> edgeCoord{};
1399 std::array<GlobalPosition, maxNF> faceCoord{};
1402 unsigned numVertices{};
1405 unsigned numEdges{};
1408 unsigned numFaces{};
1410 Dune::GeometryType geometryType_;