Line | Branch | Exec | Source |
---|---|---|---|
1 | // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- | ||
2 | // vi: set et ts=4 sw=4 sts=4: | ||
3 | // | ||
4 | // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder | ||
5 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
6 | // | ||
7 | /*! | ||
8 | * \file | ||
9 | * \ingroup FaceCenteredStaggeredDiscretization | ||
10 | * \brief Geometry helper for face-centered staggered scheme. | ||
11 | */ | ||
12 | #ifndef DUMUX_DISCRETIZATION_FACECENTERED_STAGGERED_GEOMETRY_HELPER_HH | ||
13 | #define DUMUX_DISCRETIZATION_FACECENTERED_STAGGERED_GEOMETRY_HELPER_HH | ||
14 | |||
15 | #include <array> | ||
16 | #include <cassert> | ||
17 | #include <dune/common/exceptions.hh> | ||
18 | #include <dumux/common/indextraits.hh> | ||
19 | #include <dumux/discretization/facecentered/staggered/gridsupportsconcavecorners.hh> | ||
20 | |||
21 | namespace Dumux { | ||
22 | /*! | ||
23 | * \ingroup FaceCenteredStaggeredDiscretization | ||
24 | * \brief Face centered staggered geometry helper | ||
25 | */ | ||
26 | template<class GridView> | ||
27 |
1/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
4 | class FaceCenteredStaggeredGeometryHelper |
28 | { | ||
29 | using GridIndexType = typename IndexTraits<GridView>::GridIndex; | ||
30 | using SmallLocalIndexType = typename IndexTraits<GridView>::SmallLocalIndex; | ||
31 | using Element = typename GridView::template Codim<0>::Entity; | ||
32 | using Facet = typename GridView::template Codim<1>::Entity; | ||
33 | |||
34 | public: | ||
35 | static constexpr auto dim = GridView::Grid::dimension; | ||
36 | static constexpr auto numElementFaces = dim * 2; | ||
37 | static constexpr auto numLateralFacesPerScv = 2 * (dim - 1); | ||
38 | |||
39 | 122 | FaceCenteredStaggeredGeometryHelper(const GridView& gridView) : gridView_(gridView) {} | |
40 | |||
41 | //! Returns the local index of the opposing face. | ||
42 | static constexpr SmallLocalIndexType localOppositeIdx(const SmallLocalIndexType ownLocalFaceIndex) | ||
43 | { | ||
44 |
6/6✓ Branch 0 taken 652544 times.
✓ Branch 1 taken 652544 times.
✓ Branch 2 taken 491351 times.
✓ Branch 3 taken 491351 times.
✓ Branch 4 taken 3570140 times.
✓ Branch 5 taken 3570140 times.
|
9428070 | return isOdd_(ownLocalFaceIndex) ? (ownLocalFaceIndex - 1) : (ownLocalFaceIndex + 1); |
45 | } | ||
46 | |||
47 | //! Return the local index of a lateral orthogonal scvf | ||
48 | 321034032 | static constexpr int lateralOrthogonalScvfLocalIndex(const SmallLocalIndexType ownLocalScvfIndex) | |
49 | { | ||
50 | if constexpr(GridView::Grid::dimension == 1) | ||
51 | { | ||
52 | ✗ | assert(false && "There are no lateral scvfs in 1D"); | |
53 | return -1; | ||
54 | } | ||
55 | |||
56 | if constexpr (GridView::Grid::dimension == 2) | ||
57 | { | ||
58 |
8/9✓ Branch 0 taken 39642866 times.
✓ Branch 1 taken 39796388 times.
✓ Branch 2 taken 39615585 times.
✓ Branch 3 taken 39949740 times.
✓ Branch 4 taken 39697655 times.
✓ Branch 5 taken 39846517 times.
✓ Branch 6 taken 39670446 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 39899611 times.
|
318118808 | switch (ownLocalScvfIndex) |
59 | { | ||
60 | case 1: return 7; | ||
61 | 39642866 | case 7: return 1; | |
62 | 39796388 | case 2: return 10; | |
63 | 39615585 | case 10: return 2; | |
64 | 39949740 | case 4: return 8; | |
65 | 39697655 | case 8: return 4; | |
66 | 39846517 | case 5: return 11; | |
67 | 39670446 | case 11: return 5; | |
68 | ✗ | default: | |
69 | { | ||
70 | ✗ | assert(false && "No lateral orthogonal scvf found"); | |
71 | return -1; | ||
72 | } | ||
73 | } | ||
74 | } | ||
75 | else | ||
76 | { | ||
77 |
24/25✓ Branch 0 taken 129434 times.
✓ Branch 1 taken 111480 times.
✓ Branch 2 taken 130122 times.
✓ Branch 3 taken 111480 times.
✓ Branch 4 taken 125390 times.
✓ Branch 5 taken 111480 times.
✓ Branch 6 taken 124718 times.
✓ Branch 7 taken 108080 times.
✓ Branch 8 taken 129044 times.
✓ Branch 9 taken 110488 times.
✓ Branch 10 taken 132076 times.
✓ Branch 11 taken 110368 times.
✓ Branch 12 taken 127232 times.
✓ Branch 13 taken 108080 times.
✓ Branch 14 taken 124328 times.
✓ Branch 15 taken 127484 times.
✓ Branch 16 taken 123440 times.
✓ Branch 17 taken 127484 times.
✓ Branch 18 taken 122768 times.
✓ Branch 19 taken 131276 times.
✓ Branch 20 taken 126552 times.
✓ Branch 21 taken 128172 times.
✓ Branch 22 taken 122768 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 111480 times.
|
2915224 | switch (ownLocalScvfIndex) |
78 | { | ||
79 | case 1: return 11; | ||
80 | 129434 | case 11: return 1; | |
81 | 111480 | case 2: return 16; | |
82 | 130122 | case 16: return 2; | |
83 | 111480 | case 3: return 21; | |
84 | 125390 | case 21: return 3; | |
85 | 111480 | case 4: return 26; | |
86 | 124718 | case 26: return 4; | |
87 | 108080 | case 6: return 12; | |
88 | 129044 | case 12: return 6; | |
89 | 110488 | case 7: return 17; | |
90 | 132076 | case 17: return 7; | |
91 | 110368 | case 8: return 22; | |
92 | 127232 | case 22: return 8; | |
93 | 108080 | case 9: return 27; | |
94 | 124328 | case 27: return 9; | |
95 | 127484 | case 13: return 23; | |
96 | 123440 | case 23: return 13; | |
97 | 127484 | case 14: return 28; | |
98 | 122768 | case 28: return 14; | |
99 | 131276 | case 18: return 24; | |
100 | 126552 | case 24: return 18; | |
101 | 128172 | case 19: return 29; | |
102 | 122768 | case 29: return 19; | |
103 | |||
104 | ✗ | default: | |
105 | { | ||
106 | ✗ | assert(false && "No lateral orthogonal scvf found"); | |
107 | return -1; | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | |||
113 | //! Returns the local indices of the faces lateral to the own one. | ||
114 | 5592 | static constexpr auto localLaterFaceIndices(const SmallLocalIndexType ownLocalFaceIndex) | |
115 | { | ||
116 | 9284096 | constexpr auto table = [] | |
117 | { | ||
118 | using Table = std::array<std::array<SmallLocalIndexType, numLateralFacesPerScv>, numElementFaces>; | ||
119 | if constexpr (dim == 1) | ||
120 | return Table{}; | ||
121 | else if constexpr (dim == 2) | ||
122 | return Table {{ {2,3}, {2,3}, {0,1}, {0,1} }}; | ||
123 | else | ||
124 | return Table {{ {2,3,4,5}, {2,3,4,5}, {0,1,4,5}, {0,1,4,5}, {0,1,2,3}, {0,1,2,3} }}; | ||
125 | }(); | ||
126 | |||
127 | 18568320 | return table[ownLocalFaceIndex]; | |
128 | } | ||
129 | |||
130 | //! Returns an element's facet based on the local facet index. | ||
131 | static Facet facet(const SmallLocalIndexType localFacetIdx, const Element& element) | ||
132 | { | ||
133 |
4/9✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 640 times.
✓ Branch 4 taken 992 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2544 times.
✓ Branch 7 taken 1791376 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
18657984 | return element.template subEntity <1> (localFacetIdx); |
134 | } | ||
135 | |||
136 | //! Returns an element's intersection based on the local facet index. | ||
137 | 18579376 | auto intersection(const SmallLocalIndexType localFacetIdx, const Element& element) const | |
138 | { | ||
139 |
10/14✗ Branch 0 not taken.
✓ Branch 1 taken 42146808 times.
✓ Branch 2 taken 4269540 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22848 times.
✓ Branch 5 taken 1308 times.
✓ Branch 6 taken 79488 times.
✓ Branch 7 taken 4267360 times.
✓ Branch 8 taken 79488 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2583264 times.
✓ Branch 11 taken 56640 times.
✓ Branch 13 taken 56640 times.
✗ Branch 14 not taken.
|
67589932 | for (const auto& intersection : intersections(gridView(), element)) |
140 | { | ||
141 |
5/5✓ Branch 0 taken 16872432 times.
✓ Branch 1 taken 29598376 times.
✓ Branch 2 taken 16872432 times.
✓ Branch 3 taken 27037960 times.
✓ Branch 4 taken 2560416 times.
|
88674256 | if (intersection.indexInInside() == localFacetIdx) |
142 | 37181600 | return intersection; | |
143 | } | ||
144 | ✗ | DUNE_THROW(Dune::InvalidStateException, "localFacetIdx " << localFacetIdx << " out of range"); | |
145 | } | ||
146 | |||
147 | //! Returns true if the IP of an scvf lies on a concave corner | ||
148 | template<class FVElementGeometry, class SubControlVolumeFace> | ||
149 | 1131140 | static bool scvfIntegrationPointInConcaveCorner(const FVElementGeometry& fvGeometry, const SubControlVolumeFace& scvf) | |
150 | { | ||
151 |
2/6✗ Branch 0 not taken.
✓ Branch 1 taken 1131140 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 127941128 times.
|
129072268 | assert (scvf.isLateral()); |
152 | |||
153 | using Grid = typename FVElementGeometry::GridGeometry::Grid; | ||
154 | if constexpr (!GridSupportsConcaveCorners<Grid>::value) | ||
155 | ✗ | return false; | |
156 | else | ||
157 | { | ||
158 |
1/2✓ Branch 0 taken 1131140 times.
✗ Branch 1 not taken.
|
1131140 | if (scvf.boundary()) |
159 | return false; | ||
160 | |||
161 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 1131140 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1131140 times.
|
2262280 | const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx()); |
162 | 2262280 | const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx()); | |
163 | 1131140 | int onBoundaryCounter = 0; | |
164 | 1131140 | onBoundaryCounter += static_cast<int>(insideScv.boundary()); | |
165 | 1131140 | onBoundaryCounter += static_cast<int>(outsideScv.boundary()); | |
166 | 1131140 | return onBoundaryCounter == 1; | |
167 | } | ||
168 | } | ||
169 | |||
170 | template<class SubControlVolumeFace, class SubControlVolume> | ||
171 | ✗ | static SmallLocalIndexType localIndexOutsideScvfWithSameIntegrationPoint(const SubControlVolumeFace& scvf, | |
172 | const SubControlVolume& scv) | ||
173 | { | ||
174 | // In 2D there are 3 non-boundary faces per scv. In 3D, there are 5. | ||
175 | // This number of scvfs per scv is used as an offset to find the indexes in the outside half-scv. | ||
176 | 15488 | const SmallLocalIndexType offset = (dim == 2) ? 3 : 5; | |
177 | // For half-scvs with odd indexes, the outside half-scv has scvf local indexes with + offset. | ||
178 | // For half-scvs with even indexes, the outside half-scv has scvf local indexes have a - offset. | ||
179 |
2/2✓ Branch 0 taken 10144 times.
✓ Branch 1 taken 5344 times.
|
15488 | return isOdd_(scv.indexInElement()) ? scvf.localIndex() - offset : scvf.localIndex() + offset; |
180 | } | ||
181 | |||
182 | const GridView& gridView() const | ||
183 | 18579376 | { return gridView_; } | |
184 | |||
185 | private: | ||
186 | |||
187 | static constexpr bool isOdd_(int number) | ||
188 | { return number % 2; } | ||
189 | |||
190 | GridView gridView_; | ||
191 | }; | ||
192 | |||
193 | } // end namespace Dumux | ||
194 | |||
195 | #endif | ||
196 |