GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/discretization/cellcentered/mpfa/fvelementgeometry.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 239 244 98.0%
Functions: 65 69 94.2%
Branches: 429 614 69.9%

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-FileCopyrightText: 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 CCMpfaDiscretization
10 * \brief Stencil-local finite volume geometry (scvs and scvfs) for cell-centered mpfa models
11 * This builds up the sub control volumes and sub control volume faces
12 * for each element in the local scope we are restricting to, e.g. stencil or element.
13 */
14 #ifndef DUMUX_DISCRETIZATION_CCMPFA_FV_ELEMENT_GEOMETRY_HH
15 #define DUMUX_DISCRETIZATION_CCMPFA_FV_ELEMENT_GEOMETRY_HH
16
17 #include <optional>
18 #include <utility>
19
20 #include <dune/common/exceptions.hh>
21 #include <dune/common/iteratorrange.hh>
22 #include <dune/geometry/type.hh>
23
24 #include <dumux/common/parameters.hh>
25 #include <dumux/common/indextraits.hh>
26 #include <dumux/discretization/scvandscvfiterators.hh>
27
28 namespace Dumux {
29
30 #ifndef DOXYGEN
31 namespace Detail::Mpfa {
32
33 template<typename GridGeometry, typename SubControlVolumeFace>
34 16 typename SubControlVolumeFace::Traits::Geometry makeScvfGeometry(const GridGeometry& gridGeometry,
35 const SubControlVolumeFace& scvf)
36 {
37 static constexpr int dim = GridGeometry::GridView::dimension;
38
39 16 const auto& facetInfo = scvf.facetInfo();
40 16 const auto element = gridGeometry.element(facetInfo.elementIndex);
41 16 const auto elemGeo = element.geometry();
42 16 const auto refElement = referenceElement(elemGeo);
43
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 24 times.
40 for (const auto& is : intersections(gridGeometry.gridView(), element))
44 {
45
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 24 times.
40 if (is.indexInInside() == facetInfo.facetIndex)
46 {
47 16 const auto numCorners = is.geometry().corners();
48 16 const auto isPositions = GridGeometry::MpfaHelper::computeScvfCornersOnIntersection(
49 elemGeo, refElement, facetInfo.facetIndex, numCorners
50 );
51 return {
52 Dune::GeometryTypes::cube(dim-1),
53 16 GridGeometry::MpfaHelper::getScvfCorners(
54
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 isPositions, numCorners, facetInfo.facetCornerIndex
55 )
56 16 };
57 }
58 }
59 DUNE_THROW(Dune::InvalidStateException, "Could not construct scvf geometry");
60 }
61
62 template<typename GridGeometry, typename SubControlVolumeFace>
63 400 auto getVertexCorner(const GridGeometry& gridGeometry, const SubControlVolumeFace& scvf)
64 {
65 static constexpr int dim = GridGeometry::GridView::dimension;
66
67 400 const auto& facetInfo = scvf.facetInfo();
68 400 const auto element = gridGeometry.element(facetInfo.elementIndex);
69 400 const auto elemGeo = element.geometry();
70 400 const auto refElement = referenceElement(elemGeo);
71 400 return elemGeo.global(refElement.position(
72 400 refElement.subEntity(facetInfo.facetIndex, 1, facetInfo.facetCornerIndex, dim),
73 dim
74 400 ));
75 }
76
77 template<typename GridGeometry, typename SubControlVolumeFace>
78 894 auto getFacetCorner(const GridGeometry& gridGeometry, const SubControlVolumeFace& scvf)
79 {
80 894 const auto& facetInfo = scvf.facetInfo();
81
1/2
✓ Branch 2 taken 94 times.
✗ Branch 3 not taken.
894 const auto element = gridGeometry.element(facetInfo.elementIndex);
82
1/2
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
894 const auto elemGeo = element.geometry();
83 894 const auto refElement = referenceElement(elemGeo);
84 894 return elemGeo.global(refElement.position(facetInfo.facetIndex, 1));
85 94 }
86
87 } // namespace Detail::Mpfa
88 #endif // DOXYGEN
89
90 /*!
91 * \ingroup CCMpfaDiscretization
92 * \brief Stencil-local finite volume geometry (scvs and scvfs) for cell-centered mpfa models
93 * This builds up the sub control volumes and sub control volume faces
94 * for each element in the local scope we are restricting to, e.g. stencil or element.
95 * \tparam GG the finite volume grid geometry type
96 * \tparam enableGridGeometryCache if the grid geometry is cached or not
97 * \note This class is specialized for versions with and without caching the fv geometries on the grid view
98 */
99 template<class GG, bool enableGridGeometryCache>
100 class CCMpfaFVElementGeometry;
101
102 /*!
103 * \ingroup CCMpfaDiscretization
104 * \brief Stencil-local finite volume geometry (scvs and scvfs) for cell-centered mpfa models
105 * Specialization for grid caching enabled
106 * \note The finite volume geometries are stored in the corresponding FVGridGeometry
107 */
108 template<class GG>
109
22/56
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 6353050 times.
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 17 taken 216692 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 339 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 339 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 216353 times.
✓ Branch 30 taken 583053 times.
✓ Branch 31 taken 216353 times.
✓ Branch 32 taken 583053 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 158 times.
✓ Branch 39 taken 1 times.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✓ Branch 42 taken 159 times.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✓ Branch 46 taken 583053 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 583053 times.
✗ Branch 49 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✓ Branch 19 taken 216353 times.
✓ Branch 26 taken 158 times.
✗ Branch 35 not taken.
✓ Branch 6 taken 1 times.
13909638 class CCMpfaFVElementGeometry<GG, true>
110 {
111 using ThisType = CCMpfaFVElementGeometry<GG, true>;
112 using GridView = typename GG::GridView;
113 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
114
115 static constexpr int dim = GridView::dimension;
116 static constexpr int dimWorld = GridView::dimensionworld;
117
118 public:
119 //! export type of the element
120 using Element = typename GridView::template Codim<0>::Entity;
121 //! export type of subcontrol volume
122 using SubControlVolume = typename GG::SubControlVolume;
123 //! export type of subcontrol volume face
124 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
125 //! export type of finite volume grid geometry
126 using GridGeometry = GG;
127 //! the maximum number of scvs per element
128 static constexpr std::size_t maxNumElementScvs = 1;
129 //! the maximum number of scvfs per element (use cubes for maximum)
130 static constexpr std::size_t maxNumElementScvfs = dim == 3 ? 24 : 8;
131
132 //! Constructor
133 12988394 CCMpfaFVElementGeometry(const GridGeometry& gridGeometry)
134
14/24
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5056542 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1159990 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 216692 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 216511 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 583211 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 160 times.
✗ Branch 23 not taken.
✓ Branch 9 taken 26 times.
✓ Branch 12 taken 13056 times.
✓ Branch 15 taken 27 times.
✓ Branch 3 taken 1283454 times.
✓ Branch 25 taken 583053 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
12988394 : gridGeometryPtr_(&gridGeometry) {}
135
136 //! Get an element sub control volume with a global scv index
137 834799776 const SubControlVolume& scv(GridIndexType scvIdx) const
138 {
139
6/9
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1532 times.
✓ Branch 5 taken 55760 times.
✗ Branch 6 not taken.
✓ Branch 4 taken 375284 times.
✓ Branch 9 taken 14800 times.
✗ Branch 10 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9984 times.
477623699 return gridGeometry().scv(scvIdx);
140 }
141
142 //! Get an element sub control volume face with a global scvf index
143 1518738254 const SubControlVolumeFace& scvf(GridIndexType scvfIdx) const
144 {
145
7/8
✓ Branch 0 taken 36312 times.
✓ Branch 1 taken 216104 times.
✓ Branch 3 taken 1272 times.
✓ Branch 4 taken 168376 times.
✓ Branch 6 taken 768 times.
✗ Branch 7 not taken.
✓ Branch 5 taken 19048 times.
✓ Branch 2 taken 28832 times.
181202537 return gridGeometry().scvf(scvfIdx);
146 }
147
148 //! Get the scvf on the same face but from the other side
149 //! Note that e.g. the normals might be different in the case of surface grids
150 89652458 const SubControlVolumeFace& flipScvf(GridIndexType scvfIdx, unsigned int outsideScvIdx = 0) const
151 {
152 89652458 return gridGeometry().flipScvf(scvfIdx, outsideScvIdx);
153 }
154
155 //! iterator range for sub control volumes. Iterates over
156 //! all scvs of the bound element (not including neighbor scvs)
157 //! This is a free function found by means of ADL
158 //! To iterate over all sub control volumes of this FVElementGeometry use
159 //! for (auto&& scv : scvs(fvGeometry))
160 friend inline Dune::IteratorRange< ScvIterator<SubControlVolume, std::array<GridIndexType, 1>, ThisType> >
161 36555113 scvs(const CCMpfaFVElementGeometry& fvGeometry)
162 {
163 using ScvIterator = Dumux::ScvIterator<SubControlVolume, std::array<GridIndexType, 1>, ThisType>;
164 36555113 return Dune::IteratorRange<ScvIterator>(ScvIterator(fvGeometry.scvIndices_.begin(), fvGeometry),
165
4/4
✓ Branch 0 taken 286358 times.
✓ Branch 1 taken 286359 times.
✓ Branch 2 taken 7335 times.
✓ Branch 3 taken 7334 times.
37142499 ScvIterator(fvGeometry.scvIndices_.end(), fvGeometry));
166 }
167
168 //! iterator range for sub control volumes faces. Iterates over
169 //! all scvfs of the bound element (not including neighbor scvfs)
170 //! This is a free function found by means of ADL
171 //! To iterate over all sub control volume faces of this FVElementGeometry use
172 //! for (auto&& scvf : scvfs(fvGeometry))
173 friend inline Dune::IteratorRange< ScvfIterator<SubControlVolumeFace, std::vector<GridIndexType>, ThisType> >
174 46382802 scvfs(const CCMpfaFVElementGeometry& fvGeometry)
175 {
176 46382802 const auto& g = fvGeometry.gridGeometry();
177
2/2
✓ Branch 0 taken 38324472 times.
✓ Branch 1 taken 5750421 times.
67924031 const auto scvIdx = fvGeometry.scvIndices_[0];
178 using ScvfIterator = Dumux::ScvfIterator<SubControlVolumeFace, std::vector<GridIndexType>, ThisType>;
179 46382802 return Dune::IteratorRange<ScvfIterator>(ScvfIterator(g.scvfIndicesOfScv(scvIdx).begin(), fvGeometry),
180 46382802 ScvfIterator(g.scvfIndicesOfScv(scvIdx).end(), fvGeometry));
181 }
182
183 //! number of sub control volumes in this fv element geometry
184 std::size_t numScv() const
185 {
186 34932000 return scvIndices_.size();
187 }
188
189 //! number of sub control volumes in this fv element geometry
190 606886 std::size_t numScvf() const
191 {
192
1/2
✓ Branch 1 taken 27500 times.
✗ Branch 2 not taken.
606886 return gridGeometry().scvfIndicesOfScv(scvIndices_[0]).size();
193 }
194
195 /*!
196 * \brief bind the local view (r-value overload)
197 * This overload is called when an instance of this class is a temporary in the usage context
198 * This allows a usage like this: `const auto view = localView(...).bind(element);`
199 */
200 343 CCMpfaFVElementGeometry bind(const Element& element) &&
201 {
202
1/2
✓ Branch 1 taken 343 times.
✗ Branch 2 not taken.
343 this->bindElement(element);
203
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
343 return std::move(*this);
204 }
205
206 11996748 void bind(const Element& element) &
207 {
208
3/5
✓ Branch 1 taken 256 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 256 times.
✓ Branch 5 taken 653613 times.
✗ Branch 6 not taken.
11996748 this->bindElement(element);
209 654125 }
210
211 /*!
212 * \brief bind the local view (r-value overload)
213 * This overload is called when an instance of this class is a temporary in the usage context
214 * This allows a usage like this: `const auto view = localView(...).bindElement(element);`
215 */
216 5473440 CCMpfaFVElementGeometry bindElement(const Element& element) &&
217 {
218
2/4
✓ Branch 1 taken 4296966 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1176474 times.
✗ Branch 5 not taken.
5473440 this->bindElement(element);
219 5473440 return std::move(*this);
220 }
221
222 //! Bind only element-local
223 18958952 void bindElement(const Element& element) &
224 {
225
2/2
✓ Branch 0 taken 3993904 times.
✓ Branch 1 taken 10229865 times.
18958952 element_ = element;
226 37917904 scvIndices_[0] = gridGeometry().elementMapper().index(element);
227 18958952 }
228
229 //! Returns true if bind/bindElement has already been called
230 1 bool isBound() const
231
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 { return static_cast<bool>(element_); }
232
233 //! The bound element
234 5033025 const Element& element() const
235 5033025 { return *element_; }
236
237 //! The global finite volume geometry we are a restriction of
238 1841628859 const GridGeometry& gridGeometry() const
239
65/73
✓ Branch 1 taken 27500 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 312 times.
✓ Branch 13 taken 2841 times.
✓ Branch 14 taken 399843 times.
✓ Branch 19 taken 169108 times.
✓ Branch 20 taken 21979808 times.
✓ Branch 21 taken 3445980 times.
✓ Branch 22 taken 108000408 times.
✓ Branch 28 taken 464832 times.
✓ Branch 29 taken 890678 times.
✓ Branch 36 taken 974700 times.
✓ Branch 37 taken 5766280 times.
✓ Branch 38 taken 11054922 times.
✓ Branch 39 taken 3784277 times.
✓ Branch 40 taken 4919526 times.
✓ Branch 41 taken 1144004 times.
✓ Branch 43 taken 5968328 times.
✓ Branch 44 taken 71487398 times.
✓ Branch 47 taken 56884 times.
✓ Branch 48 taken 4957061 times.
✓ Branch 51 taken 937327 times.
✓ Branch 52 taken 13875650 times.
✓ Branch 53 taken 10968977 times.
✓ Branch 54 taken 7341258 times.
✓ Branch 3 taken 769 times.
✓ Branch 10 taken 6384 times.
✓ Branch 11 taken 65264 times.
✓ Branch 16 taken 810432 times.
✓ Branch 17 taken 25536 times.
✓ Branch 18 taken 2617088 times.
✓ Branch 30 taken 19056234 times.
✓ Branch 31 taken 5282226 times.
✓ Branch 33 taken 580130 times.
✓ Branch 34 taken 39500 times.
✓ Branch 35 taken 47676 times.
✓ Branch 46 taken 467152 times.
✓ Branch 6 taken 2768 times.
✗ Branch 7 not taken.
✓ Branch 12 taken 176640 times.
✓ Branch 42 taken 5823788 times.
✓ Branch 49 taken 23418190 times.
✓ Branch 55 taken 1653728 times.
✓ Branch 15 taken 890844 times.
✓ Branch 23 taken 19127748 times.
✓ Branch 45 taken 67221184 times.
✗ Branch 0 not taken.
✓ Branch 25 taken 10608 times.
✓ Branch 26 taken 673226 times.
✓ Branch 27 taken 10336 times.
✓ Branch 50 taken 1372178 times.
✓ Branch 56 taken 4640 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 27691 times.
✓ Branch 59 taken 225782 times.
✓ Branch 60 taken 294492 times.
✓ Branch 61 taken 598434 times.
✓ Branch 64 taken 583053 times.
✓ Branch 65 taken 4497900 times.
✓ Branch 68 taken 583053 times.
✓ Branch 69 taken 15776 times.
✗ Branch 72 not taken.
✓ Branch 73 taken 116963 times.
✓ Branch 74 taken 74520 times.
✓ Branch 75 taken 8424 times.
✓ Branch 8 taken 796356 times.
✗ Branch 24 not taken.
✓ Branch 32 taken 49891746 times.
✓ Branch 62 taken 3542 times.
✓ Branch 63 taken 7263263 times.
✓ Branch 66 taken 167904 times.
✗ Branch 9 not taken.
2467760258 { return *gridGeometryPtr_; }
240
241 //! Returns whether one of the geometry's scvfs lies on a boundary
242 1303191 bool hasBoundaryScvf() const
243
2/2
✓ Branch 0 taken 1012119 times.
✓ Branch 1 taken 291072 times.
1303191 { return gridGeometry().hasBoundaryScvf(scvIndices_[0]); }
244
245 //! Create the geometry of a given sub control volume
246 1 typename Element::Geometry geometry(const SubControlVolume& scv) const
247 1 { return gridGeometryPtr_->element(scv.dofIndex()).geometry(); }
248
249 //! Create the geometry of a given sub control volume face
250 8 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
251
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 { return Detail::Mpfa::makeScvfGeometry(gridGeometry(), scvf); }
252
253 //! Return the position of the scvf corner that coincides with an element vertex
254 typename SubControlVolumeFace::Traits::GlobalPosition vertexCorner(const SubControlVolumeFace& scvf) const
255 { return Detail::Mpfa::getVertexCorner(gridGeometry(), scvf); }
256
257 //! Return the corner of the scvf that is inside the facet the scvf is embedded in
258 typename SubControlVolumeFace::Traits::GlobalPosition facetCorner(const SubControlVolumeFace& scvf) const
259 { return Detail::Mpfa::getFacetCorner(gridGeometry(), scvf); }
260
261 private:
262
263 std::optional<Element> element_;
264 std::array<GridIndexType, 1> scvIndices_;
265 const GridGeometry* gridGeometryPtr_;
266 };
267
268 /*!
269 * \ingroup CCMpfaDiscretization
270 * \brief Stencil-local finite volume geometry (scvs and scvfs) for cell-centered TPFA models
271 * Specialization for grid caching disabled
272 */
273 template<class GG>
274 class CCMpfaFVElementGeometry<GG, false>
275 {
276 using ThisType = CCMpfaFVElementGeometry<GG, false>;
277 using GridView = typename GG::GridView;
278 using GridIndexType = typename IndexTraits<GridView>::GridIndex;
279 using MpfaHelper = typename GG::MpfaHelper;
280
281 static constexpr int dim = GridView::dimension;
282 static constexpr int dimWorld = GridView::dimensionworld;
283 using CoordScalar = typename GridView::ctype;
284
285 public:
286 //! export type of the element
287 using Element = typename GridView::template Codim<0>::Entity;
288 //! export type of subcontrol volume
289 using SubControlVolume = typename GG::SubControlVolume;
290 //! export type of subcontrol volume face
291 using SubControlVolumeFace = typename GG::SubControlVolumeFace;
292 //! export type of finite volume grid geometries
293 using GridGeometry = GG;
294 //! the maximum number of scvs per element
295 static constexpr std::size_t maxNumElementScvs = 1;
296 //! the maximum number of scvfs per element (use cubes for maximum)
297 static constexpr std::size_t maxNumElementScvfs = dim == 3 ? 24 : 8;
298
299 //! Constructor
300 1494227 CCMpfaFVElementGeometry(const GridGeometry& gridGeometry)
301
14/24
✓ Branch 1 taken 123 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4060 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 374955 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 35126 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 94 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 50000 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 964000 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 100 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 0 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 3 times.
✓ Branch 12 taken 65376 times.
✓ Branch 15 taken 2 times.
1494227 : gridGeometryPtr_(&gridGeometry) {}
302
303 //! Get an element sub control volume with a global scv index
304 //! We separate element and neighbor scvs to speed up mapping
305 230277335 const SubControlVolume& scv(GridIndexType scvIdx) const
306 {
307
51/54
✓ Branch 0 taken 2029208 times.
✓ Branch 1 taken 7346208 times.
✓ Branch 2 taken 8766530 times.
✓ Branch 3 taken 22315769 times.
✓ Branch 4 taken 5664441 times.
✓ Branch 5 taken 16604366 times.
✓ Branch 6 taken 1289652 times.
✓ Branch 7 taken 4243896 times.
✓ Branch 8 taken 8399458 times.
✓ Branch 9 taken 21770992 times.
✓ Branch 10 taken 6544008 times.
✓ Branch 11 taken 26896320 times.
✓ Branch 12 taken 479920 times.
✓ Branch 13 taken 2226988 times.
✓ Branch 14 taken 4984462 times.
✓ Branch 15 taken 13512910 times.
✓ Branch 16 taken 4032298 times.
✓ Branch 17 taken 12600022 times.
✓ Branch 18 taken 4334146 times.
✓ Branch 19 taken 20710673 times.
✓ Branch 20 taken 1093484 times.
✓ Branch 21 taken 2209782 times.
✓ Branch 22 taken 1054380 times.
✓ Branch 23 taken 1974080 times.
✓ Branch 24 taken 1545851 times.
✓ Branch 25 taken 364951 times.
✓ Branch 26 taken 1153190 times.
✓ Branch 27 taken 16226630 times.
✓ Branch 28 taken 1186962 times.
✓ Branch 29 taken 224772 times.
✓ Branch 30 taken 338608 times.
✓ Branch 31 taken 238016 times.
✓ Branch 32 taken 866506 times.
✓ Branch 33 taken 2133542 times.
✓ Branch 34 taken 230272 times.
✓ Branch 35 taken 1169886 times.
✓ Branch 36 taken 201968 times.
✓ Branch 37 taken 71198 times.
✓ Branch 38 taken 573834 times.
✓ Branch 39 taken 465956 times.
✓ Branch 40 taken 162072 times.
✓ Branch 41 taken 1334040 times.
✓ Branch 42 taken 201152 times.
✓ Branch 43 taken 262192 times.
✓ Branch 44 taken 5584 times.
✓ Branch 45 taken 5168 times.
✓ Branch 46 taken 10696 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 13056 times.
✓ Branch 49 taken 97376 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 96424 times.
✓ Branch 52 taken 13440 times.
✗ Branch 53 not taken.
230277335 if (scvIdx == scvIndices_[0])
308 55175178 return scvs_[0];
309 else
310 157913317 return neighborScvs_[findLocalIndex(scvIdx, neighborScvIndices_)];
311 }
312
313 //! Get an element sub control volume face with a global scvf index
314 //! We separate element and neighbor scvfs to speed up mapping
315 408812322 const SubControlVolumeFace& scvf(GridIndexType scvfIdx) const
316 {
317
2/2
✓ Branch 0 taken 89980003 times.
✓ Branch 1 taken 318832319 times.
408812322 auto it = std::find(scvfIndices_.begin(), scvfIndices_.end(), scvfIdx);
318
2/2
✓ Branch 0 taken 89980003 times.
✓ Branch 1 taken 318832319 times.
408812322 if (it != scvfIndices_.end())
319 89980003 return scvfs_[std::distance(scvfIndices_.begin(), it)];
320 else
321 318832319 return neighborScvfs_[findLocalIndex(scvfIdx, neighborScvfIndices_)];
322 }
323
324 //! Get the scvf on the same face but from the other side
325 //! Note that e.g. the normals might be different in the case of surface grids
326 31879480 const SubControlVolumeFace& flipScvf(GridIndexType scvfIdx, unsigned int outsideScvIdx = 0) const
327 {
328 31879480 return scvf( gridGeometry().flipScvfIdx(scvfIdx, outsideScvIdx) );
329 }
330
331 //! iterator range for sub control volumes. Iterates over
332 //! all scvs of the bound element (not including neighbor scvs)
333 //! This is a free function found by means of ADL
334 //! To iterate over all sub control volumes of this FVElementGeometry use
335 //! for (auto&& scv : scvs(fvGeometry))
336 friend inline Dune::IteratorRange<typename std::array<SubControlVolume, 1>::const_iterator>
337 6601476 scvs(const ThisType& g)
338 {
339 using IteratorType = typename std::array<SubControlVolume, 1>::const_iterator;
340
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
6601476 return Dune::IteratorRange<IteratorType>(g.scvs_.begin(), g.scvs_.end());
341 }
342
343 //! iterator range for sub control volumes faces. Iterates over
344 //! all scvfs of the bound element (not including neighbor scvfs)
345 //! This is a free function found by means of ADL
346 //! To iterate over all sub control volume faces of this FVElementGeometry use
347 //! for (auto&& scvf : scvfs(fvGeometry))
348 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
349 8754644 scvfs(const ThisType& g)
350 {
351 using IteratorType = typename std::vector<SubControlVolumeFace>::const_iterator;
352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
8754644 return Dune::IteratorRange<IteratorType>(g.scvfs_.begin(), g.scvfs_.end());
353 }
354
355 //! number of sub control volumes in this fv element geometry
356 std::size_t numScv() const
357 6604424 { return scvs_.size(); }
358
359 //! number of sub control volumes in this fv element geometry
360 1516075 std::size_t numScvf() const
361
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 300 times.
✓ Branch 3 taken 300 times.
✗ Branch 4 not taken.
✓ Branch 2 taken 2592 times.
✗ Branch 5 not taken.
1516075 { return scvfs_.size(); }
362
363 /*!
364 * \brief bind the local view (r-value overload)
365 * This overload is called when an instance of this class is a temporary in the usage context
366 * This allows a usage like this: `const auto view = localView(...).bindElement(element);`
367 */
368 91 CCMpfaFVElementGeometry bindElement(const Element& element) &&
369 {
370
1/2
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
91 this->bindElement_(element);
371 91 return std::move(*this);
372 }
373
374 215691 void bindElement(const Element& element) &
375 {
376
5/10
✓ Branch 1 taken 82825 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 66482 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 37704 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 10896 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 17784 times.
✗ Branch 14 not taken.
215691 this->bindElement_(element);
377 215691 }
378
379 /*!
380 * \brief bind the local view (r-value overload)
381 * This overload is called when an instance of this class is a temporary in the usage context
382 * This allows a usage like this: `const auto view = localView(...).bind(element);`
383 */
384 54373 CCMpfaFVElementGeometry bind(const Element& element) &&
385 {
386
3/6
✓ Branch 1 taken 4273 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 50000 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 100 times.
✗ Branch 8 not taken.
54373 this->bind_(element);
387 54373 return std::move(*this);
388 }
389
390 1456959 void bind(const Element& element) &
391 {
392
6/10
✓ Branch 1 taken 2729 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✓ Branch 5 taken 12812 times.
✓ Branch 9 taken 200 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1928 times.
✗ Branch 13 not taken.
✗ Branch 6 not taken.
✓ Branch 8 taken 164 times.
1456959 this->bind_(element);
393 17933 }
394
395 //! Returns true if bind/bindElement has already been called
396 1 bool isBound() const
397
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
2 { return static_cast<bool>(element_); }
398
399 //! The bound element
400 33025 const Element& element() const
401 33025 { return *element_; }
402
403 //! The global finite volume geometry we are a restriction of
404 437061907 const GridGeometry& gridGeometry() const
405
40/46
✓ Branch 6 taken 16632 times.
✓ Branch 7 taken 18991423 times.
✓ Branch 9 taken 2029770 times.
✓ Branch 10 taken 536224 times.
✓ Branch 15 taken 19172603 times.
✓ Branch 16 taken 434872 times.
✓ Branch 19 taken 7686 times.
✓ Branch 20 taken 161356 times.
✓ Branch 23 taken 1161972 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 299700 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 424828 times.
✓ Branch 29 taken 1293172 times.
✓ Branch 31 taken 76340 times.
✓ Branch 32 taken 1465052 times.
✓ Branch 8 taken 2017248 times.
✓ Branch 12 taken 18870083 times.
✓ Branch 13 taken 434872 times.
✓ Branch 17 taken 1087348 times.
✓ Branch 18 taken 48764 times.
✓ Branch 21 taken 1814794 times.
✓ Branch 14 taken 617976 times.
✓ Branch 22 taken 3766616 times.
✗ Branch 11 not taken.
✓ Branch 25 taken 442186 times.
✓ Branch 30 taken 3848 times.
✓ Branch 33 taken 109816 times.
✓ Branch 34 taken 592352 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 335384 times.
✓ Branch 38 taken 1804384 times.
✓ Branch 39 taken 145768 times.
✗ Branch 40 not taken.
✓ Branch 42 taken 145768 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 280 times.
✓ Branch 45 taken 336 times.
✓ Branch 46 taken 24336 times.
✓ Branch 47 taken 77688 times.
✓ Branch 5 taken 67268 times.
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 106152 times.
✓ Branch 2 taken 1898880 times.
✓ Branch 3 taken 312 times.
✓ Branch 4 taken 2760 times.
300728691 { return *gridGeometryPtr_; }
406
407 //! Returns whether one of the geometry's scvfs lies on a boundary
408 180764 bool hasBoundaryScvf() const
409
4/4
✓ Branch 0 taken 137920 times.
✓ Branch 1 taken 42228 times.
✓ Branch 2 taken 280 times.
✓ Branch 3 taken 336 times.
180764 { return hasBoundaryScvf_; }
410
411 //! Create the geometry of a given sub control volume
412 1 typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const
413 1 { return gridGeometryPtr_->element(scv.dofIndex()).geometry(); }
414
415 //! Create the geometry of a given sub control volume face
416 8 typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const
417
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 { return Detail::Mpfa::makeScvfGeometry(gridGeometry(), scvf); }
418
419 //! Return the position of the scvf corner that coincides with an element vertex
420 400 typename SubControlVolumeFace::Traits::GlobalPosition vertexCorner(const SubControlVolumeFace& scvf) const
421 400 { return Detail::Mpfa::getVertexCorner(gridGeometry(), scvf); }
422
423 //! Return the corner of the scvf that is inside the facet the scvf is embedded in
424 894 typename SubControlVolumeFace::Traits::GlobalPosition facetCorner(const SubControlVolumeFace& scvf) const
425
1/2
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
494 { return Detail::Mpfa::getFacetCorner(gridGeometry(), scvf); }
426
427 private:
428
429 //! Binding of an element preparing the geometries of the whole stencil
430 //! called by the local assembler to prepare element assembly
431 1511332 void bind_(const Element& element)
432 {
433 // make inside geometries
434 1511332 bindElement_(element);
435
436 // get some references for convenience
437 1511332 const auto globalI = gridGeometry().elementMapper().index(element);
438 1511332 const auto& assemblyMapI = gridGeometry().connectivityMap()[globalI];
439
440 // reserve memory
441 1511332 const auto numNeighbors = assemblyMapI.size();
442 1511332 const auto numNeighborScvfs = numNeighborScvfs_(assemblyMapI);
443 1511332 neighborScvs_.reserve(numNeighbors);
444 1511332 neighborScvIndices_.reserve(numNeighbors);
445 1511332 neighborScvfIndices_.reserve(numNeighborScvfs);
446 1511332 neighborScvfs_.reserve(numNeighborScvfs);
447
448 // make neighbor geometries
449 // use the assembly map to determine which faces are necessary
450
2/2
✓ Branch 0 taken 15717165 times.
✓ Branch 1 taken 1511332 times.
17228497 for (const auto& dataJ : assemblyMapI)
451
1/2
✓ Branch 1 taken 14721715 times.
✗ Branch 2 not taken.
30438880 makeNeighborGeometries(gridGeometry().element(dataJ.globalJ),
452 15717165 dataJ.globalJ,
453 15717165 dataJ.scvfsJ,
454 15717165 dataJ.additionalScvfs);
455
456 // //! TODO Check if user added additional DOF dependencies, i.e. the residual of DOF globalI depends
457 // //! on additional DOFs not included in the discretization schemes' occupation pattern
458 // const auto& additionalDofDependencies = problem.getAdditionalDofDependencies(globalI);
459 // if (!additionalDofDependencies.empty())
460 // {
461 // const auto newNumNeighbors = neighborScvs_.size() + additionalDofDependencies.size();
462 // neighborScvs_.reserve(newNumNeighbors);
463 // neighborScvIndices_.reserve(newNumNeighbors);
464 // for (auto globalJ : additionalDofDependencies)
465 // {
466 // neighborScvs_.emplace_back(gridGeometry().element(globalJ).geometry(), globalJ);
467 // neighborScvIndices_.emplace_back(globalJ);
468 // }
469 // }
470 1511332 }
471
472 //! Binding of an element preparing the geometries only inside the element
473 1727114 void bindElement_(const Element& element)
474 {
475 1727114 clear();
476
2/2
✓ Branch 0 taken 64714 times.
✓ Branch 1 taken 168515 times.
1727114 element_ = element;
477 1727114 makeElementGeometries(element);
478 1727114 }
479
480 //! Computes the number of neighboring scvfs that have to be prepared
481 template<class DataJContainer>
482 1511332 std::size_t numNeighborScvfs_(const DataJContainer& dataJContainer)
483 {
484 1511332 std::size_t numNeighborScvfs = 0;
485
2/2
✓ Branch 0 taken 15717165 times.
✓ Branch 1 taken 1511332 times.
17228497 for (const auto& dataJ : dataJContainer)
486 15717165 numNeighborScvfs += dataJ.scvfsJ.size() + dataJ.additionalScvfs.size();
487 return numNeighborScvfs;
488 }
489
490 //! create scvs and scvfs of the bound element
491 1727114 void makeElementGeometries(const Element& element)
492 {
493 // make the scv
494 1727114 const auto eIdx = gridGeometry().elementMapper().index(element);
495
1/2
✓ Branch 2 taken 1493885 times.
✗ Branch 3 not taken.
1727114 scvs_[0] = SubControlVolume(element.geometry(), eIdx);
496 1727114 scvIndices_[0] = eIdx;
497
498 // get data on the scv faces
499
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1727085 times.
1727114 const auto& scvFaceIndices = gridGeometry().scvfIndicesOfScv(eIdx);
500
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1727085 times.
1727114 const auto& neighborVolVarIndices = gridGeometry().neighborVolVarIndices(eIdx);
501
502 // the quadrature point parameterizaion to be used on scvfs
503
4/6
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1727085 times.
✓ Branch 3 taken 29 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 29 times.
✗ Branch 7 not taken.
1727114 static const auto q = getParam<CoordScalar>("MPFA.Q");
504
505 // reserve memory for the scv faces
506 1727114 const auto numLocalScvf = scvFaceIndices.size();
507 1727114 scvfIndices_.reserve(numLocalScvf);
508 1727114 scvfs_.reserve(numLocalScvf);
509
510 // for network grids we only want to do one scvf per half facet
511 // this approach assumes conforming grids at branching facets
512
1/2
✓ Branch 1 taken 156407 times.
✗ Branch 2 not taken.
1727114 std::vector<bool> finishedFacets;
513 if (dim < dimWorld)
514
1/2
✓ Branch 1 taken 156407 times.
✗ Branch 2 not taken.
156407 finishedFacets.resize(element.subEntities(1), false);
515
516 1727114 int scvfCounter = 0;
517
11/14
✓ Branch 1 taken 1727114 times.
✓ Branch 2 taken 731656 times.
✓ Branch 8 taken 4301984 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6466350 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1033610 times.
✗ Branch 13 not taken.
✓ Branch 5 taken 697783 times.
✓ Branch 6 taken 659501 times.
✓ Branch 7 taken 50315 times.
✓ Branch 14 taken 102023 times.
✓ Branch 15 taken 99237 times.
✓ Branch 4 taken 50315 times.
22711215 for (const auto& is : intersections(gridGeometry().gridView(), element))
518 {
519 // if we are dealing with a lower dimensional network
520 // only make a new scvf if we haven't handled it yet
521 if (dim < dimWorld)
522 {
523 625628 const auto indexInInside = is.indexInInside();
524
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 625628 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 625628 times.
625628 if (finishedFacets[indexInInside])
525 continue;
526 else
527 625628 finishedFacets[indexInInside] = true;
528 }
529
530 // if outside level > inside level, use the outside element in the following
531
9/13
✓ Branch 1 taken 4950916 times.
✓ Branch 2 taken 78719 times.
✓ Branch 4 taken 4848893 times.
✓ Branch 5 taken 102023 times.
✓ Branch 7 taken 4848893 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 10384 times.
✓ Branch 10 taken 4838509 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 0 taken 663934 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 99237 times.
15660337 bool useNeighbor = is.neighbor() && is.outside().level() > element.level();
532
2/2
✓ Branch 0 taken 10384 times.
✓ Branch 1 taken 4917228 times.
10777756 const auto& e = useNeighbor ? is.outside() : element;
533
3/4
✓ Branch 0 taken 10384 times.
✓ Branch 1 taken 5850144 times.
✓ Branch 3 taken 5860528 times.
✗ Branch 4 not taken.
10788140 const auto indexInElement = useNeighbor ? is.indexInOutside() : is.indexInInside();
534
1/2
✓ Branch 1 taken 5860528 times.
✗ Branch 2 not taken.
5860528 const auto eg = e.geometry();
535
1/2
✓ Branch 1 taken 5128872 times.
✗ Branch 2 not taken.
5860528 const auto refElement = referenceElement(eg);
536
537 // Set up a container with all relevant positions for scvf corner computation
538
1/2
✓ Branch 1 taken 199468 times.
✗ Branch 2 not taken.
5860528 const auto numCorners = is.geometry().corners();
539
1/2
✓ Branch 1 taken 201260 times.
✗ Branch 2 not taken.
5860528 const auto isPositions = MpfaHelper::computeScvfCornersOnIntersection(eg,
540 refElement,
541 indexInElement,
542 numCorners);
543
544 // make the scv faces belonging to each corner of the intersection
545
3/3
✓ Branch 1 taken 11519796 times.
✓ Branch 2 taken 5659268 times.
✓ Branch 0 taken 402520 times.
17581584 for (int c = 0; c < numCorners; ++c)
546 {
547 // get the global vertex index the scv face is connected to
548 11721056 auto vIdxLocal = refElement.subEntity(indexInElement, 1, c, dim);
549
1/2
✓ Branch 1 taken 11721056 times.
✗ Branch 2 not taken.
11721056 auto vIdxGlobal = gridGeometry().vertexMapper().subIndex(e, vIdxLocal, dim);
550
551 // do not build scvfs connected to a processor boundary
552
2/2
✓ Branch 0 taken 8832 times.
✓ Branch 1 taken 11712224 times.
11721056 if (gridGeometry().isGhostVertex(vIdxGlobal))
553 8832 continue;
554
555
2/2
✓ Branch 0 taken 10946320 times.
✓ Branch 1 taken 765904 times.
11712224 hasBoundaryScvf_ = (hasBoundaryScvf_ || is.boundary());
556 23424448 typename SubControlVolumeFace::FacetInfo facetInfo{
557
1/2
✓ Branch 1 taken 10257744 times.
✗ Branch 2 not taken.
11712224 gridGeometry().elementMapper().index(e),
558
2/2
✓ Branch 0 taken 20768 times.
✓ Branch 1 taken 11691456 times.
11712224 useNeighbor ? is.indexInOutside() : is.indexInInside(),
559 c
560 };
561
3/4
✓ Branch 0 taken 1127744 times.
✓ Branch 1 taken 729256 times.
✓ Branch 2 taken 1251256 times.
✗ Branch 3 not taken.
12963480 scvfs_.emplace_back(MpfaHelper(),
562
1/2
✓ Branch 1 taken 10460968 times.
✗ Branch 2 not taken.
12963480 MpfaHelper::getScvfCorners(isPositions, numCorners, c),
563 is,
564 std::move(facetInfo),
565 vIdxGlobal,
566 vIdxLocal,
567
2/2
✓ Branch 0 taken 5029224 times.
✓ Branch 1 taken 5431744 times.
11712224 scvFaceIndices[scvfCounter],
568 eIdx,
569 11712224 neighborVolVarIndices[scvfCounter],
570 q,
571
2/2
✓ Branch 0 taken 5029224 times.
✓ Branch 1 taken 5431744 times.
11712224 is.boundary());
572
573
1/2
✓ Branch 1 taken 11712224 times.
✗ Branch 2 not taken.
11712224 scvfIndices_.emplace_back(scvFaceIndices[scvfCounter]);
574 11712224 scvfCounter++;
575 }
576 }
577 1727114 }
578
579 //! create the scv and necessary scvfs of a neighboring element
580 template<typename IndexVector>
581 15717165 void makeNeighborGeometries(const Element& element,
582 GridIndexType eIdxGlobal,
583 const IndexVector& scvfIndices,
584 const IndexVector& additionalScvfs)
585 {
586 // create the neighbor scv if it doesn't exist yet
587
1/2
✓ Branch 2 taken 14721715 times.
✗ Branch 3 not taken.
15717165 neighborScvs_.emplace_back(element.geometry(), eIdxGlobal);
588 15717165 neighborScvIndices_.push_back(eIdxGlobal);
589
590 // get data on the scv faces
591
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 15717135 times.
15717165 const auto& scvFaceIndices = gridGeometry().scvfIndicesOfScv(eIdxGlobal);
592
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 15717135 times.
15717165 const auto& neighborVolVarIndices = gridGeometry().neighborVolVarIndices(eIdxGlobal);
593
594 // the quadrature point parameterizaion to be used on scvfs
595
5/6
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 15717135 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 2 times.
✓ Branch 6 taken 28 times.
✗ Branch 7 not taken.
15717165 static const auto q = getParam<CoordScalar>("MPFA.Q");
596
597 // for network grids we only want to do one scvf per half facet
598 // this approach assumes conforming grids at branching facets
599
1/2
✓ Branch 1 taken 992352 times.
✗ Branch 2 not taken.
15717165 std::vector<bool> finishedFacets;
600 if (dim < dimWorld)
601
1/2
✓ Branch 1 taken 992352 times.
✗ Branch 2 not taken.
992352 finishedFacets.resize(element.subEntities(1), false);
602
603 15717165 int scvfCounter = 0;
604
11/14
✓ Branch 1 taken 15717165 times.
✓ Branch 2 taken 3631840 times.
✓ Branch 8 taken 42647813 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 60696544 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5399210 times.
✗ Branch 13 not taken.
✓ Branch 5 taken 3560826 times.
✓ Branch 6 taken 4040422 times.
✓ Branch 7 taken 87490 times.
✓ Branch 14 taken 186694 times.
✓ Branch 15 taken 163266 times.
✓ Branch 4 taken 87490 times.
205673613 for (const auto& is : intersections(gridGeometry().gridView(), element))
605 {
606 // if we are dealing with a lower dimensional network
607 // only make a new scvf if we haven't handled it yet
608 if (dim < dimWorld)
609 {
610 3969408 auto indexInInside = is.indexInInside();
611
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3969408 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3969408 times.
3969408 if(finishedFacets[indexInInside])
612 continue;
613 else
614 3969408 finishedFacets[indexInInside] = true;
615 }
616
617 // if outside level > inside level, use the outside element in the following
618
9/13
✓ Branch 1 taken 46384110 times.
✓ Branch 2 taken 419805 times.
✓ Branch 4 taken 46197416 times.
✓ Branch 5 taken 186694 times.
✓ Branch 7 taken 46197416 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 69924 times.
✓ Branch 10 taken 46127492 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 0 taken 3489812 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 163266 times.
143180547 bool useNeighbor = is.neighbor() && is.outside().level() > element.level();
619
2/2
✓ Branch 0 taken 69924 times.
✓ Branch 1 taken 46547297 times.
97146318 const auto& e = useNeighbor ? is.outside() : element;
620
3/4
✓ Branch 0 taken 69924 times.
✓ Branch 1 taken 50529097 times.
✓ Branch 3 taken 50599021 times.
✗ Branch 4 not taken.
97216242 const auto indexInElement = useNeighbor ? is.indexInOutside() : is.indexInInside();
621
1/2
✓ Branch 1 taken 50599021 times.
✗ Branch 2 not taken.
50599021 const auto eg = e.geometry();
622
1/2
✓ Branch 1 taken 46967181 times.
✗ Branch 2 not taken.
50599021 const auto refElement = referenceElement(eg);
623
624 // Set up a container with all relevant positions for scvf corner computation
625
1/2
✓ Branch 1 taken 339880 times.
✗ Branch 2 not taken.
50599021 const auto numCorners = is.geometry().corners();
626
1/2
✓ Branch 1 taken 349960 times.
✗ Branch 2 not taken.
50599021 const auto isPositions = MpfaHelper::computeScvfCornersOnIntersection(eg,
627 refElement,
628 indexInElement,
629 numCorners);
630
631 // make the scv faces belonging to each corner of the intersection
632
3/3
✓ Branch 1 taken 100848082 times.
✓ Branch 2 taken 50249061 times.
✓ Branch 0 taken 699920 times.
151797063 for (int c = 0; c < numCorners; ++c)
633 {
634 // get the global vertex index the scv face is connected to
635 101198042 auto vIdxLocal = refElement.subEntity(indexInElement, 1, c, dim);
636
1/2
✓ Branch 1 taken 101198042 times.
✗ Branch 2 not taken.
101198042 auto vIdxGlobal = gridGeometry().vertexMapper().subIndex(e, vIdxLocal, dim);
637
638 // do not build scvfs connected to a processor boundary
639
2/2
✓ Branch 0 taken 22496 times.
✓ Branch 1 taken 101175546 times.
101198042 if (gridGeometry().isGhostVertex(vIdxGlobal))
640 60109070 continue;
641
642 // only build the scvf if it is in the list of necessary indices
643
2/2
✓ Branch 0 taken 60086574 times.
✓ Branch 1 taken 41088972 times.
101175546 if (!MpfaHelper::vectorContainsValue(scvfIndices, scvFaceIndices[scvfCounter])
644
3/4
✓ Branch 0 taken 60086574 times.
✓ Branch 1 taken 41088972 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 60086574 times.
101175546 && !MpfaHelper::vectorContainsValue(additionalScvfs, scvFaceIndices[scvfCounter]))
645 {
646 // increment counter either way
647 60086574 scvfCounter++;
648 60086574 continue;
649 }
650
651 // build scvf
652 82177944 typename SubControlVolumeFace::FacetInfo facetInfo{
653
1/2
✓ Branch 1 taken 38325100 times.
✗ Branch 2 not taken.
41088972 gridGeometry().elementMapper().index(e),
654
2/2
✓ Branch 0 taken 38294 times.
✓ Branch 1 taken 41050678 times.
41088972 useNeighbor ? is.indexInOutside() : is.indexInInside(),
655 c
656 };
657
3/4
✓ Branch 0 taken 1717368 times.
✓ Branch 1 taken 1387120 times.
✓ Branch 2 taken 2994064 times.
✗ Branch 3 not taken.
44083036 neighborScvfs_.emplace_back(MpfaHelper(),
658
1/2
✓ Branch 1 taken 38094908 times.
✗ Branch 2 not taken.
44083036 MpfaHelper::getScvfCorners(isPositions, numCorners, c),
659 is,
660 std::move(facetInfo),
661 vIdxGlobal,
662 vIdxLocal,
663
2/2
✓ Branch 0 taken 18895751 times.
✓ Branch 1 taken 19199157 times.
41088972 scvFaceIndices[scvfCounter],
664 eIdxGlobal,
665 41088972 neighborVolVarIndices[scvfCounter],
666 q,
667
2/2
✓ Branch 0 taken 18895751 times.
✓ Branch 1 taken 19199157 times.
41088972 is.boundary());
668
669
1/2
✓ Branch 1 taken 41088972 times.
✗ Branch 2 not taken.
41088972 neighborScvfIndices_.emplace_back(scvFaceIndices[scvfCounter]);
670
671 // increment counter
672 41088972 scvfCounter++;
673 }
674 }
675 15717165 }
676
677 //! map a global index to the local storage index
678
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 476745636 times.
476745636 unsigned int findLocalIndex(const GridIndexType idx,
679 const std::vector<GridIndexType>& indices) const
680 {
681
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 476745636 times.
476745636 auto it = std::find(indices.begin(), indices.end(), idx);
682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 476745636 times.
476745636 assert(it != indices.end() && "Could not find the scv/scvf! Make sure to properly bind this class!");
683 476745636 return std::distance(indices.begin(), it);
684 }
685
686 //! clear all containers
687 1727114 void clear()
688 {
689
2/2
✓ Branch 0 taken 232889 times.
✓ Branch 1 taken 1494225 times.
1727114 scvfIndices_.clear();
690
2/2
✓ Branch 0 taken 232889 times.
✓ Branch 1 taken 1494225 times.
1727114 scvfs_.clear();
691
692
2/2
✓ Branch 0 taken 17516 times.
✓ Branch 1 taken 1709598 times.
1727114 neighborScvIndices_.clear();
693
2/2
✓ Branch 0 taken 17516 times.
✓ Branch 1 taken 1709598 times.
1727114 neighborScvfIndices_.clear();
694
2/2
✓ Branch 0 taken 17516 times.
✓ Branch 1 taken 1709598 times.
1727114 neighborScvs_.clear();
695
2/2
✓ Branch 0 taken 17516 times.
✓ Branch 1 taken 1709598 times.
1727114 neighborScvfs_.clear();
696
697 1727114 hasBoundaryScvf_ = false;
698 1727114 }
699
700 const GridGeometry* gridGeometryPtr_;
701 std::optional<Element> element_;
702
703 // local storage after binding an element
704 std::array<GridIndexType, 1> scvIndices_;
705 std::vector<GridIndexType> scvfIndices_;
706 std::array<SubControlVolume, 1> scvs_;
707 std::vector<SubControlVolumeFace> scvfs_;
708
709 std::vector<GridIndexType> neighborScvIndices_;
710 std::vector<GridIndexType> neighborScvfIndices_;
711 std::vector<SubControlVolume> neighborScvs_;
712 std::vector<SubControlVolumeFace> neighborScvfs_;
713
714 bool hasBoundaryScvf_ = false;
715 };
716
717 } // end namespace
718
719 #endif
720