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 DiamondDiscretization | ||
10 | * \copydoc Dumux::DiamondGeometryHelper | ||
11 | */ | ||
12 | #ifndef DUMUX_DISCRETIZATION_FACECENTERED_DIAMOND_GEOMETRY_HELPER_HH | ||
13 | #define DUMUX_DISCRETIZATION_FACECENTERED_DIAMOND_GEOMETRY_HELPER_HH | ||
14 | |||
15 | #include <array> | ||
16 | |||
17 | #include <dune/common/reservedvector.hh> | ||
18 | #include <dune/common/fvector.hh> | ||
19 | #include <dune/geometry/multilineargeometry.hh> | ||
20 | #include <dune/geometry/type.hh> | ||
21 | |||
22 | #include <dumux/common/math.hh> | ||
23 | |||
24 | namespace Dumux { | ||
25 | |||
26 | //! Traits for an efficient corner storage for fc diamond method | ||
27 | template <class ct> | ||
28 | struct FCDiamondMLGeometryTraits : public Dune::MultiLinearGeometryTraits<ct> | ||
29 | { | ||
30 | // we use static vectors to store the corners as we know | ||
31 | // the maximum number of corners in advance (2^dim) | ||
32 | template< int mydim, int cdim > | ||
33 | struct CornerStorage | ||
34 | { | ||
35 | using Type = Dune::ReservedVector< Dune::FieldVector< ct, cdim >, (1<<mydim)>; | ||
36 | }; | ||
37 | }; | ||
38 | |||
39 | namespace Detail::FCDiamond { | ||
40 | |||
41 | template<Dune::GeometryType::Id gt> | ||
42 | struct ScvCorners; | ||
43 | |||
44 | template<> | ||
45 | struct ScvCorners<Dune::GeometryTypes::triangle> | ||
46 | { | ||
47 | static constexpr Dune::GeometryType type() | ||
48 | { return Dune::GeometryTypes::triangle; } | ||
49 | |||
50 | using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim) | ||
51 | static constexpr std::array<std::array<Key, 3>, 3> keys = {{ | ||
52 | { Key{0, 2}, Key{1, 2}, Key{0, 0} }, | ||
53 | { Key{2, 2}, Key{0, 2}, Key{0, 0} }, | ||
54 | { Key{1, 2}, Key{2, 2}, Key{0, 0} } | ||
55 | }}; | ||
56 | }; | ||
57 | |||
58 | template<> | ||
59 | struct ScvCorners<Dune::GeometryTypes::quadrilateral> | ||
60 | { | ||
61 | static constexpr Dune::GeometryType type() | ||
62 | { return Dune::GeometryTypes::triangle; } | ||
63 | |||
64 | using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim) | ||
65 | static constexpr std::array<std::array<Key, 3>, 4> keys = {{ | ||
66 | { Key{2, 2}, Key{0, 2}, Key{0, 0} }, | ||
67 | { Key{1, 2}, Key{3, 2}, Key{0, 0} }, | ||
68 | { Key{0, 2}, Key{1, 2}, Key{0, 0} }, | ||
69 | { Key{3, 2}, Key{2, 2}, Key{0, 0} } | ||
70 | }}; | ||
71 | }; | ||
72 | |||
73 | template<> | ||
74 | struct ScvCorners<Dune::GeometryTypes::tetrahedron> | ||
75 | { | ||
76 | static constexpr Dune::GeometryType type() | ||
77 | { return Dune::GeometryTypes::tetrahedron; } | ||
78 | |||
79 | using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim) | ||
80 | static constexpr std::array<std::array<Key, 4>, 4> keys = {{ | ||
81 | { Key{0, 3}, Key{1, 3}, Key{2, 3}, Key{0, 0} }, | ||
82 | { Key{1, 3}, Key{0, 3}, Key{3, 3}, Key{0, 0} }, | ||
83 | { Key{0, 3}, Key{2, 3}, Key{3, 3}, Key{0, 0} }, | ||
84 | { Key{2, 3}, Key{1, 3}, Key{3, 3}, Key{0, 0} } | ||
85 | }}; | ||
86 | }; | ||
87 | |||
88 | template<> | ||
89 | struct ScvCorners<Dune::GeometryTypes::hexahedron> | ||
90 | { | ||
91 | static constexpr Dune::GeometryType type() | ||
92 | { return Dune::GeometryTypes::pyramid; } | ||
93 | |||
94 | using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim) | ||
95 | static constexpr std::array<std::array<Key, 5>, 6> keys = {{ | ||
96 | { Key{4, 3}, Key{0, 3}, Key{6, 3}, Key{2, 3}, Key{0, 0} }, | ||
97 | { Key{1, 3}, Key{5, 3}, Key{3, 3}, Key{7, 3}, Key{0, 0} }, | ||
98 | { Key{4, 3}, Key{5, 3}, Key{0, 3}, Key{1, 3}, Key{0, 0} }, | ||
99 | { Key{2, 3}, Key{3, 3}, Key{6, 3}, Key{7, 3}, Key{0, 0} }, | ||
100 | { Key{0, 3}, Key{1, 3}, Key{2, 3}, Key{3, 3}, Key{0, 0} }, | ||
101 | { Key{6, 3}, Key{7, 3}, Key{4, 3}, Key{5, 3}, Key{0, 0} } | ||
102 | }}; | ||
103 | }; | ||
104 | |||
105 | template<Dune::GeometryType::Id gt> | ||
106 | struct ScvfCorners; | ||
107 | |||
108 | template<> | ||
109 | struct ScvfCorners<Dune::GeometryTypes::triangle> | ||
110 | { | ||
111 | static constexpr Dune::GeometryType type() | ||
112 | { return Dune::GeometryTypes::line; } | ||
113 | |||
114 | using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim) | ||
115 | static constexpr std::array<std::array<Key, 2>, 3> keys = {{ | ||
116 | { Key{0, 2}, Key{0, 0} }, | ||
117 | { Key{1, 2}, Key{0, 0} }, | ||
118 | { Key{2, 2}, Key{0, 0} } | ||
119 | }}; | ||
120 | }; | ||
121 | |||
122 | template<> | ||
123 | struct ScvfCorners<Dune::GeometryTypes::quadrilateral> | ||
124 | { | ||
125 | static constexpr Dune::GeometryType type() | ||
126 | { return Dune::GeometryTypes::line; } | ||
127 | |||
128 | using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim) | ||
129 | static constexpr std::array<std::array<Key, 2>, 4> keys = {{ | ||
130 | { Key{0, 2}, Key{0, 0} }, | ||
131 | { Key{1, 2}, Key{0, 0} }, | ||
132 | { Key{2, 2}, Key{0, 0} }, | ||
133 | { Key{3, 2}, Key{0, 0} } | ||
134 | }}; | ||
135 | }; | ||
136 | |||
137 | template<> | ||
138 | struct ScvfCorners<Dune::GeometryTypes::tetrahedron> | ||
139 | { | ||
140 | static constexpr Dune::GeometryType type() | ||
141 | { return Dune::GeometryTypes::triangle; } | ||
142 | |||
143 | using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim) | ||
144 | static constexpr std::array<std::array<Key, 3>, 6> keys = {{ | ||
145 | { Key{0, 3}, Key{1, 3}, Key{0, 0} }, | ||
146 | { Key{2, 3}, Key{0, 3}, Key{0, 0} }, | ||
147 | { Key{1, 3}, Key{2, 3}, Key{0, 0} }, | ||
148 | { Key{0, 3}, Key{3, 3}, Key{0, 0} }, | ||
149 | { Key{1, 3}, Key{3, 3}, Key{0, 0} }, | ||
150 | { Key{2, 3}, Key{3, 3}, Key{0, 0} } | ||
151 | }}; | ||
152 | }; | ||
153 | |||
154 | template<> | ||
155 | struct ScvfCorners<Dune::GeometryTypes::hexahedron> | ||
156 | { | ||
157 | static constexpr Dune::GeometryType type() | ||
158 | { return Dune::GeometryTypes::triangle; } | ||
159 | |||
160 | using Key = std::pair<std::uint8_t, std::uint8_t>; // (i, codim) | ||
161 | static constexpr std::array<std::array<Key, 3>, 12> keys = {{ | ||
162 | { Key{0, 3}, Key{4, 3}, Key{0, 0} }, | ||
163 | { Key{1, 3}, Key{5, 3}, Key{0, 0} }, | ||
164 | { Key{2, 3}, Key{6, 3}, Key{0, 0} }, | ||
165 | { Key{3, 3}, Key{7, 3}, Key{0, 0} }, | ||
166 | { Key{0, 3}, Key{2, 3}, Key{0, 0} }, | ||
167 | { Key{1, 3}, Key{3, 3}, Key{0, 0} }, | ||
168 | { Key{0, 3}, Key{1, 3}, Key{0, 0} }, | ||
169 | { Key{2, 3}, Key{3, 3}, Key{0, 0} }, | ||
170 | { Key{4, 3}, Key{6, 3}, Key{0, 0} }, | ||
171 | { Key{5, 3}, Key{7, 3}, Key{0, 0} }, | ||
172 | { Key{4, 3}, Key{5, 3}, Key{0, 0} }, | ||
173 | { Key{6, 3}, Key{7, 3}, Key{0, 0} } | ||
174 | }}; | ||
175 | }; | ||
176 | |||
177 | // convert key array to global corner storage | ||
178 | template<class S, class Geo, class KeyArray, std::size_t... I> | ||
179 | 1573212 | S keyToCornerStorageImpl(const Geo& geo, const KeyArray& key, std::index_sequence<I...>) | |
180 | { | ||
181 | using Dune::referenceElement; | ||
182 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
1573212 | const auto ref = referenceElement(geo); |
183 | // key is a pair of a local sub-entity index (first) and the sub-entity's codim (second) | ||
184 |
23/34✗ Branch 0 not taken.
✓ Branch 1 taken 786606 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 786606 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 786606 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 168836 times.
✓ Branch 8 taken 617770 times.
✓ Branch 9 taken 168836 times.
✓ Branch 10 taken 617770 times.
✓ Branch 11 taken 168836 times.
✓ Branch 12 taken 617770 times.
✓ Branch 13 taken 84436 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 470080 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 470080 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 385656 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 12 times.
✓ Branch 22 taken 54118 times.
✓ Branch 23 taken 12 times.
✓ Branch 24 taken 54118 times.
✓ Branch 25 taken 12 times.
✓ Branch 26 taken 54118 times.
✓ Branch 27 taken 12 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 36474 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 36462 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 36462 times.
|
6577084 | return { geo.global(ref.position(key[I].first, key[I].second))... }; |
185 | } | ||
186 | |||
187 | // convert key array to global corner storage | ||
188 | template<class S, class Geo, class T, std::size_t N, class Indices = std::make_index_sequence<N>> | ||
189 | S keyToCornerStorage(const Geo& geo, const std::array<T, N>& key) | ||
190 | { | ||
191 | 786606 | return keyToCornerStorageImpl<S>(geo, key, Indices{}); | |
192 | } | ||
193 | |||
194 | // boundary corners for the i-th facet | ||
195 | template<class S, class Geo, std::size_t... ii> | ||
196 | 332 | S boundaryCornerStorageImpl(const Geo& geo, unsigned int i, std::index_sequence<ii...>) | |
197 | { | ||
198 | using Dune::referenceElement; | ||
199 | 332 | const auto ref = referenceElement(geo); | |
200 | // simply the vertices of the facet i | ||
201 | 380 | return { geo.global(ref.position(ref.subEntity(i, 1, ii, Geo::mydimension), Geo::mydimension))... }; | |
202 | } | ||
203 | |||
204 | // boundary corners for the i-th facet | ||
205 | template<class S, std::size_t numCorners, class Geo> | ||
206 | S boundaryCornerStorage(const Geo& geo, unsigned int i) | ||
207 | { | ||
208 | 166 | return boundaryCornerStorageImpl<S>(geo, i, std::make_index_sequence<numCorners>{}); | |
209 | } | ||
210 | |||
211 | template<class IndexType, Dune::GeometryType::Id gt> | ||
212 | struct InsideOutsideScv; | ||
213 | |||
214 | template<class IndexType> | ||
215 | struct InsideOutsideScv<IndexType, Dune::GeometryTypes::triangle> | ||
216 | { | ||
217 | static constexpr std::array<std::array<IndexType, 2>, 3> pairs = {{ | ||
218 | {0, 1}, {0, 2}, {1, 2} | ||
219 | }}; | ||
220 | }; | ||
221 | |||
222 | template<class IndexType> | ||
223 | struct InsideOutsideScv<IndexType, Dune::GeometryTypes::quadrilateral> | ||
224 | { | ||
225 | static constexpr std::array<std::array<IndexType, 2>, 4> pairs = {{ | ||
226 | {0, 2}, {1, 2}, {0, 3}, {1, 3} | ||
227 | }}; | ||
228 | }; | ||
229 | |||
230 | template<class IndexType> | ||
231 | struct InsideOutsideScv<IndexType, Dune::GeometryTypes::tetrahedron> | ||
232 | { | ||
233 | static constexpr std::array<std::array<IndexType, 2>, 6> pairs = {{ | ||
234 | {0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}, | ||
235 | }}; | ||
236 | }; | ||
237 | |||
238 | template<class IndexType> | ||
239 | struct InsideOutsideScv<IndexType, Dune::GeometryTypes::hexahedron> | ||
240 | { | ||
241 | static constexpr std::array<std::array<IndexType, 2>, 12> pairs = {{ | ||
242 | {0, 2}, {1, 2}, {0, 3}, {1, 3}, {0, 4}, {1, 4}, | ||
243 | {2, 4}, {3, 4}, {0, 5}, {1, 5}, {2, 5}, {3, 5} | ||
244 | }}; | ||
245 | }; | ||
246 | |||
247 | } // end namespace Detail::FCDiamond | ||
248 | |||
249 | /*! | ||
250 | * \ingroup DiamondDiscretization | ||
251 | * \brief Helper class to construct SCVs and SCVFs for the diamond scheme | ||
252 | */ | ||
253 | template <class GridView, class ScvType, class ScvfType> | ||
254 | class DiamondGeometryHelper | ||
255 | { | ||
256 | using Element = typename GridView::template Codim<0>::Entity; | ||
257 | |||
258 | static constexpr auto dim = GridView::dimension; | ||
259 | static constexpr auto dimWorld = GridView::dimensionworld; | ||
260 | |||
261 | using ScvCornerStorage = typename ScvType::Traits::CornerStorage; | ||
262 | using LocalIndexType = typename ScvType::Traits::LocalIndexType; | ||
263 | using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage; | ||
264 | |||
265 | // for the normal | ||
266 | using ctype = typename GridView::ctype; | ||
267 | using GlobalPosition = typename Dune::FieldVector<ctype, GridView::dimensionworld>; | ||
268 | |||
269 | public: | ||
270 | 98738 | DiamondGeometryHelper(const typename Element::Geometry& geo) | |
271 |
4/6✓ Branch 0 taken 4 times.
✓ Branch 1 taken 10278 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
98738 | : geo_(geo) |
272 | {} | ||
273 | |||
274 | //! Create a corner storage with the scv corners for a given face (codim-1) index | ||
275 | 252046 | ScvCornerStorage getScvCorners(unsigned int localFacetIndex) const | |
276 | { | ||
277 |
1/2✓ Branch 1 taken 34274 times.
✗ Branch 2 not taken.
|
370732 | const auto type = geo_.type(); |
278 |
2/3✓ Branch 0 taken 251970 times.
✓ Branch 1 taken 34302 times.
✗ Branch 2 not taken.
|
370732 | if (type == Dune::GeometryTypes::triangle) |
279 | { | ||
280 | using Corners = Detail::FCDiamond::ScvCorners<Dune::GeometryTypes::triangle>; | ||
281 |
2/4✓ Branch 1 taken 20514 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20514 times.
✗ Branch 5 not taken.
|
214764 | return Detail::FCDiamond::keyToCornerStorage<ScvCornerStorage>(geo_, Corners::keys[localFacetIndex]); |
282 | } | ||
283 |
2/3✓ Branch 0 taken 165130 times.
✓ Branch 1 taken 13772 times.
✗ Branch 2 not taken.
|
263350 | else if (type == Dune::GeometryTypes::quadrilateral) |
284 | { | ||
285 | using Corners = Detail::FCDiamond::ScvCorners<Dune::GeometryTypes::quadrilateral>; | ||
286 |
2/4✓ Branch 1 taken 13760 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13760 times.
✗ Branch 5 not taken.
|
418400 | return Detail::FCDiamond::keyToCornerStorage<ScvCornerStorage>(geo_, Corners::keys[localFacetIndex]); |
287 | } | ||
288 |
2/2✓ Branch 0 taken 54106 times.
✓ Branch 1 taken 12 times.
|
54150 | else if (type == Dune::GeometryTypes::tetrahedron) |
289 | { | ||
290 | using Corners = Detail::FCDiamond::ScvCorners<Dune::GeometryTypes::tetrahedron>; | ||
291 | 35328 | return Detail::FCDiamond::keyToCornerStorage<ScvCornerStorage>(geo_, Corners::keys[localFacetIndex]); | |
292 | } | ||
293 |
2/2✓ Branch 0 taken 36450 times.
✓ Branch 1 taken 12 times.
|
36486 | else if (type == Dune::GeometryTypes::hexahedron) |
294 | { | ||
295 | using Corners = Detail::FCDiamond::ScvCorners<Dune::GeometryTypes::hexahedron>; | ||
296 | 72972 | return Detail::FCDiamond::keyToCornerStorage<ScvCornerStorage>(geo_, Corners::keys[localFacetIndex]); | |
297 | } | ||
298 | else | ||
299 | ✗ | DUNE_THROW(Dune::NotImplemented, "Scv geometries for type " << type); | |
300 | } | ||
301 | |||
302 | //! Create a corner storage with the scvf corners for a given edge (codim-2) index | ||
303 | 297224 | ScvfCornerStorage getScvfCorners(unsigned int localEdgeIndex) const | |
304 | { | ||
305 |
1/2✓ Branch 1 taken 34274 times.
✗ Branch 2 not taken.
|
415922 | const auto type = geo_.type(); |
306 |
2/3✓ Branch 0 taken 297224 times.
✓ Branch 1 taken 34274 times.
✗ Branch 2 not taken.
|
415922 | if (type == Dune::GeometryTypes::triangle) |
307 | { | ||
308 | using Corners = Detail::FCDiamond::ScvfCorners<Dune::GeometryTypes::triangle>; | ||
309 |
2/4✓ Branch 1 taken 20514 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20514 times.
✗ Branch 5 not taken.
|
214716 | return Detail::FCDiamond::keyToCornerStorage<ScvfCornerStorage>(geo_, Corners::keys[localEdgeIndex]); |
310 | } | ||
311 |
2/3✓ Branch 0 taken 210380 times.
✓ Branch 1 taken 13760 times.
✗ Branch 2 not taken.
|
308564 | else if (type == Dune::GeometryTypes::quadrilateral) |
312 | { | ||
313 | using Corners = Detail::FCDiamond::ScvfCorners<Dune::GeometryTypes::quadrilateral>; | ||
314 |
2/4✓ Branch 1 taken 13760 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13760 times.
✗ Branch 5 not taken.
|
418336 | return Detail::FCDiamond::keyToCornerStorage<ScvfCornerStorage>(geo_, Corners::keys[localEdgeIndex]); |
315 | } | ||
316 |
1/2✓ Branch 0 taken 99372 times.
✗ Branch 1 not taken.
|
99396 | else if (type == Dune::GeometryTypes::tetrahedron) |
317 | { | ||
318 | using Corners = Detail::FCDiamond::ScvfCorners<Dune::GeometryTypes::tetrahedron>; | ||
319 | 52944 | return Detail::FCDiamond::keyToCornerStorage<ScvfCornerStorage>(geo_, Corners::keys[localEdgeIndex]); | |
320 | } | ||
321 |
1/2✓ Branch 0 taken 72900 times.
✗ Branch 1 not taken.
|
72924 | else if (type == Dune::GeometryTypes::hexahedron) |
322 | { | ||
323 | using Corners = Detail::FCDiamond::ScvfCorners<Dune::GeometryTypes::hexahedron>; | ||
324 | 145848 | return Detail::FCDiamond::keyToCornerStorage<ScvfCornerStorage>(geo_, Corners::keys[localEdgeIndex]); | |
325 | } | ||
326 | else | ||
327 | ✗ | DUNE_THROW(Dune::NotImplemented, "Scvf geometries for type " << type); | |
328 | } | ||
329 | |||
330 | //! Create the sub control volume face geometries on the boundary for a given face index | ||
331 | 160 | ScvfCornerStorage getBoundaryScvfCorners(unsigned int localFacetIndex) const | |
332 | { | ||
333 | 166 | const auto type = geo_.type(); | |
334 |
1/4✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
172 | if (type == Dune::GeometryTypes::triangle || type == Dune::GeometryTypes::quadrilateral) |
335 | 160 | return Detail::FCDiamond::boundaryCornerStorage<ScvfCornerStorage, 2>(geo_, localFacetIndex); | |
336 |
0/2✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
6 | else if (type == Dune::GeometryTypes::tetrahedron) |
337 | ✗ | return Detail::FCDiamond::boundaryCornerStorage<ScvfCornerStorage, 3>(geo_, localFacetIndex); | |
338 |
0/2✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
6 | else if (type == Dune::GeometryTypes::hexahedron) |
339 | 6 | return Detail::FCDiamond::boundaryCornerStorage<ScvfCornerStorage, 4>(geo_, localFacetIndex); | |
340 | else | ||
341 | ✗ | DUNE_THROW(Dune::NotImplemented, "Boundary scvf geometries for type " << type); | |
342 | } | ||
343 | |||
344 | 84406 | GlobalPosition facetCenter(unsigned int localFacetIndex) const | |
345 | { | ||
346 |
0/4✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
84406 | return geo_.global(referenceElement(geo_).position(localFacetIndex, 1)); |
347 | } | ||
348 | |||
349 | 297224 | std::array<LocalIndexType, 2> getInsideOutsideScvForScvf(unsigned int localEdgeIndex) | |
350 | { | ||
351 | 415910 | const auto type = geo_.type(); | |
352 |
1/2✓ Branch 0 taken 297224 times.
✗ Branch 1 not taken.
|
415910 | if (type == Dune::GeometryTypes::triangle) |
353 | 214716 | return Detail::FCDiamond::InsideOutsideScv<LocalIndexType, Dune::GeometryTypes::triangle>::pairs[localEdgeIndex]; | |
354 |
1/2✓ Branch 0 taken 210380 times.
✗ Branch 1 not taken.
|
308552 | else if (type == Dune::GeometryTypes::quadrilateral) |
355 | 418336 | return Detail::FCDiamond::InsideOutsideScv<LocalIndexType, Dune::GeometryTypes::quadrilateral>::pairs[localEdgeIndex]; | |
356 |
1/2✓ Branch 0 taken 99372 times.
✗ Branch 1 not taken.
|
99384 | else if (type == Dune::GeometryTypes::tetrahedron) |
357 | 52944 | return Detail::FCDiamond::InsideOutsideScv<LocalIndexType, Dune::GeometryTypes::tetrahedron>::pairs[localEdgeIndex]; | |
358 |
1/2✓ Branch 0 taken 72900 times.
✗ Branch 1 not taken.
|
72912 | else if (type == Dune::GeometryTypes::hexahedron) |
359 | 145824 | return Detail::FCDiamond::InsideOutsideScv<LocalIndexType, Dune::GeometryTypes::hexahedron>::pairs[localEdgeIndex]; | |
360 | else | ||
361 | ✗ | DUNE_THROW(Dune::NotImplemented, "Inside outside scv pairs for type " << type); | |
362 | } | ||
363 | |||
364 | //! number of interior sub control volume faces (number of codim-2 entities) | ||
365 | ✗ | std::size_t numInteriorScvf() | |
366 | { | ||
367 |
4/4✓ Branch 6 taken 297224 times.
✓ Branch 7 taken 67187 times.
✓ Branch 8 taken 297224 times.
✓ Branch 9 taken 67187 times.
|
364411 | return referenceElement(geo_).size(2); |
368 | } | ||
369 | |||
370 | //! number of sub control volumes (number of codim-1 entities) | ||
371 | ✗ | std::size_t numScv() | |
372 | { | ||
373 |
18/18✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 20 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 251964 times.
✓ Branch 7 taken 67191 times.
✓ Branch 8 taken 251964 times.
✓ Branch 9 taken 67191 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 4 times.
✓ Branch 12 taken 14 times.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 14 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 14 times.
✓ Branch 17 taken 4 times.
|
319317 | return referenceElement(geo_).size(1); |
374 | } | ||
375 | |||
376 | template<int d = dimWorld, std::enable_if_t<(d==3), int> = 0> | ||
377 | 99384 | GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair) | |
378 | { | ||
379 | 695688 | auto normal = Dumux::crossProduct(p[1]-p[0], p[2]-p[0]); | |
380 | 198768 | normal /= normal.two_norm(); | |
381 | |||
382 | 99384 | const auto ref = referenceElement(geo_); | |
383 | 99384 | const auto v = facetCenter_(scvPair[1], ref) - facetCenter_(scvPair[0], ref); | |
384 | |||
385 | 99384 | const auto s = v*normal; | |
386 |
4/4✓ Branch 0 taken 40868 times.
✓ Branch 1 taken 58516 times.
✓ Branch 2 taken 40868 times.
✓ Branch 3 taken 58516 times.
|
198768 | if (std::signbit(s)) |
387 | normal *= -1; | ||
388 | |||
389 | 99384 | return normal; | |
390 | } | ||
391 | |||
392 | template<int d = dimWorld, std::enable_if_t<(d==2), int> = 0> | ||
393 | 316526 | GlobalPosition normal(const ScvfCornerStorage& p, const std::array<LocalIndexType, 2>& scvPair) | |
394 | { | ||
395 | //! obtain normal vector by 90° counter-clockwise rotation of t | ||
396 | 949578 | const auto t = p[1] - p[0]; | |
397 | 949578 | GlobalPosition normal({-t[1], t[0]}); | |
398 | 633052 | normal /= normal.two_norm(); | |
399 | |||
400 | 316526 | const auto ref = referenceElement(geo_); | |
401 | 316526 | const auto v = facetCenter_(scvPair[1], ref) - facetCenter_(scvPair[0], ref); | |
402 | |||
403 | 316526 | const auto s = v*normal; | |
404 |
4/4✓ Branch 0 taken 147208 times.
✓ Branch 1 taken 169318 times.
✓ Branch 2 taken 147208 times.
✓ Branch 3 taken 169318 times.
|
633052 | if (std::signbit(s)) |
405 | normal *= -1; | ||
406 | |||
407 | 316526 | return normal; | |
408 | } | ||
409 | |||
410 | const typename Element::Geometry& elementGeometry() const | ||
411 | { return geo_; } | ||
412 | |||
413 | private: | ||
414 | template<class RefElement> | ||
415 | ✗ | GlobalPosition facetCenter_(unsigned int localFacetIndex, const RefElement& ref) const | |
416 | { | ||
417 | 1169468 | return geo_.global(ref.position(localFacetIndex, 1)); | |
418 | } | ||
419 | |||
420 | const typename Element::Geometry& geo_; //!< Reference to the element geometry | ||
421 | }; | ||
422 | |||
423 | } // end namespace Dumux | ||
424 | |||
425 | #endif | ||
426 |