GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/multidomain/facet/box/fvgridgeometry.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 119 126 94.4%
Functions: 19 29 65.5%
Branches: 249 513 48.5%

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 FacetCoupling
10 * \brief Base class for the finite volume grid geometry for box models in the
11 * context of models considering coupling of different domains across the
12 * bulk grid facets. This builds up the sub control volumes and sub control
13 * volume faces for each element of the grid partition.
14 */
15 #ifndef DUMUX_FACETCOUPLING_BOX_GRID_FVGEOMETRY_HH
16 #define DUMUX_FACETCOUPLING_BOX_GRID_FVGEOMETRY_HH
17
18 #include <algorithm>
19 #include <utility>
20
21 #include <dune/grid/common/mcmgmapper.hh>
22 #include <dune/localfunctions/lagrange/lagrangelfecache.hh>
23
24 #include <dumux/common/indextraits.hh>
25 #include <dumux/discretization/method.hh>
26 #include <dumux/discretization/extrusion.hh>
27 #include <dumux/discretization/basegridgeometry.hh>
28 #include <dumux/discretization/box/boxgeometryhelper.hh>
29 #include <dumux/discretization/box/subcontrolvolume.hh>
30
31 #include <dumux/multidomain/facet/box/fvelementgeometry.hh>
32 #include <dumux/multidomain/facet/box/subcontrolvolumeface.hh>
33 #include <dumux/multidomain/facet/vertexmapper.hh>
34
35 namespace Dumux {
36
37 namespace Detail {
38 template<class GV, class T>
39 using BoxFacetCouplingGeometryHelper_t = Dune::Std::detected_or_t<
40 Dumux::BoxGeometryHelper<GV, GV::dimension, typename T::SubControlVolume, typename T::SubControlVolumeFace>,
41 SpecifiesGeometryHelper,
42 T
43 >;
44 } // end namespace Detail
45
46 /*!
47 * \ingroup FacetCoupling
48 * \brief The default traits for the finite volume grid geometry
49 * of the box scheme with coupling occurring across the element facets.
50 * Defines the scv and scvf types and the mapper types.
51 * \tparam the grid view type
52 */
53 template<class GridView>
54 struct BoxFacetCouplingDefaultGridGeometryTraits
55 {
56 // use a specialized version of the box scvf
57 using SubControlVolume = BoxSubControlVolume<GridView>;
58 using SubControlVolumeFace = BoxFacetCouplingSubControlVolumeFace<GridView>;
59
60 template<class GridGeometry, bool enableCache>
61 using LocalView = BoxFacetCouplingFVElementGeometry<GridGeometry, enableCache>;
62
63 // per default we use an mcmg mapper for the elements
64 using ElementMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
65 // the default vertex mapper is the enriched vertex dof mapper
66 using VertexMapper = EnrichedVertexDofMapper<GridView>;
67 // Mapper type for mapping edges
68 using FacetMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
69 };
70
71 /*!
72 * \ingroup FacetCoupling
73 * \brief Base class for the finite volume geometry vector for box schemes in the context
74 * of coupled models where the coupling occurs across the element facets. This builds
75 * up the sub control volumes and sub control volume faces.
76 * \note This class is specialized for versions with and without caching the fv geometries on the grid view
77 */
78 template<class Scalar,
79 class GridView,
80 bool enableGridGeometryCache = false,
81 class Traits = BoxFacetCouplingDefaultGridGeometryTraits<GridView> >
82 class BoxFacetCouplingFVGridGeometry;
83
84 /*!
85 * \ingroup FacetCoupling
86 * \brief Base class for the finite volume geometry vector for box schemes in the context
87 * of coupled models where the coupling occurs across the element facets. This builds
88 * up the sub control volumes and sub control volume faces.
89 * \note This class is specialized for versions with and without caching the fv geometries on the grid view
90 */
91 template<class Scalar, class GV, class Traits>
92 class BoxFacetCouplingFVGridGeometry<Scalar, GV, true, Traits>
93 : public BaseGridGeometry<GV, Traits>
94 {
95 using ThisType = BoxFacetCouplingFVGridGeometry<Scalar, GV, true, Traits>;
96 using ParentType = BaseGridGeometry<GV, Traits>;
97 using GridIndexType = typename IndexTraits<GV>::GridIndex;
98 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
99
100 using Element = typename GV::template Codim<0>::Entity;
101 using CoordScalar = typename GV::ctype;
102 static const int dim = GV::dimension;
103 static const int dimWorld = GV::dimensionworld;
104
105 public:
106 //! export the discretization method this geometry belongs to
107 using DiscretizationMethod = DiscretizationMethods::Box;
108 static constexpr DiscretizationMethod discMethod{};
109
110 //! export the type of the fv element geometry (the local view type)
111 using LocalView = typename Traits::template LocalView<ThisType, true>;
112 //! export the type of sub control volume
113 using SubControlVolume = typename Traits::SubControlVolume;
114 //! export the type of sub control volume
115 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
116 //! export the type of extrusion
117 using Extrusion = Extrusion_t<Traits>;
118 //! export dof mapper type
119 using DofMapper = typename Traits::VertexMapper;
120 //! export the finite element cache type
121 using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
122 //! export the grid view type
123 using GridView = GV;
124 //! export the geometry helper type
125 using GeometryHelper = Detail::BoxFacetCouplingGeometryHelper_t<GV, Traits>;
126
127 //! Constructor
128 template<class FacetGridView, class CodimOneGridAdapter>
129 2 BoxFacetCouplingFVGridGeometry(const GridView& gridView,
130 const FacetGridView& facetGridView,
131 const CodimOneGridAdapter& codimOneGridAdapter,
132 bool verbose = false)
133
5/12
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
2 : ParentType(gridView)
134 {
135
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 update_(facetGridView, codimOneGridAdapter, verbose);
136 2 }
137
138 //! the vertex mapper is the dofMapper
139 const DofMapper& dofMapper() const
140 { return this->vertexMapper(); }
141
142 //! The total number of sub control volumes
143 std::size_t numScv() const
144 { return numScv_; }
145
146 //! The total number of sun control volume faces
147 std::size_t numScvf() const
148 { return numScvf_; }
149
150 //! The total number of boundary sub control volume faces
151 //! For compatibility reasons with cc methods
152 std::size_t numBoundaryScvf() const
153 { return numBoundaryScvf_; }
154
155 //! The total number of degrees of freedom
156 std::size_t numDofs() const
157 4 { return this->vertexMapper().size(); }
158
159 /*!
160 * \brief update all fvElementGeometries (call this after grid adaption)
161 * \note This assumes conforming grids!
162 *
163 * \param gridView The grid view of a dim-dimensional grid.
164 *
165 * \param facetGridView The grid view of a (dim-1)-dimensional grid conforming
166 * with the facets of this grid view, indicating on which facets
167 * nodal dofs should be enriched.
168 * \param codimOneGridAdapter Adapter class that allows access to information on the d-
169 * dimensional grid for entities of the (d-1)-dimensional grid
170 * \param verbose Verbosity level for vertex enrichment
171 */
172 template<class FacetGridView, class CodimOneGridAdapter>
173 void update(const GridView& gridView,
174 const FacetGridView& facetGridView,
175 const CodimOneGridAdapter& codimOneGridAdapter,
176 bool verbose = false)
177 {
178 ParentType::update(gridView);
179 update_(facetGridView, codimOneGridAdapter, verbose);
180 }
181
182 //! update all fvElementGeometries (call this after grid adaption)
183 template<class FacetGridView, class CodimOneGridAdapter>
184 void update(GridView&& gridView,
185 const FacetGridView& facetGridView,
186 const CodimOneGridAdapter& codimOneGridAdapter,
187 bool verbose = false)
188 {
189 ParentType::update(std::move(gridView));
190 update_(facetGridView, codimOneGridAdapter, verbose);
191 }
192
193 //! The finite element cache for creating local FE bases
194 const FeCache& feCache() const
195 { return feCache_; }
196
197 //! Get the local scvs for an element
198 const std::vector<SubControlVolume>& scvs(GridIndexType eIdx) const
199
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 768 times.
1536 { return scvs_[eIdx]; }
200
201 //! Get the local scvfs for an element
202 const std::vector<SubControlVolumeFace>& scvfs(GridIndexType eIdx) const
203
7/14
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 768 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 768 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 768 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 768 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 768 times.
✓ Branch 17 taken 768 times.
✗ Branch 18 not taken.
5376 { return scvfs_[eIdx]; }
204
205 //! If a d.o.f. is on the boundary
206 bool dofOnBoundary(GridIndexType dofIdx) const
207 { return boundaryDofIndices_[dofIdx]; }
208
209 //! If a d.o.f. is on an interior boundary
210 bool dofOnInteriorBoundary(GridIndexType dofIdx) const
211 { return interiorBoundaryDofIndices_[dofIdx]; }
212
213 //! Periodic boundaries are not supported for the box facet coupling scheme
214 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
215 { return false; }
216
217 //! The index of the vertex / d.o.f. on the other side of the periodic boundary
218 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
219 { DUNE_THROW(Dune::InvalidStateException, "Periodic boundaries are not supported by the box facet coupling scheme"); }
220
221 //! Returns the map between dofs across periodic boundaries
222 [[deprecated("Will be removed after release 3.9. Implement periodicDofMap() if periodic bcs are supported.")]]
223 std::unordered_map<GridIndexType, GridIndexType> periodicVertexMap() const
224 { return std::unordered_map<GridIndexType, GridIndexType>(); }
225
226 private:
227
228 template<class FacetGridView, class CodimOneGridAdapter>
229 2 void update_(const FacetGridView& facetGridView,
230 const CodimOneGridAdapter& codimOneGridAdapter,
231 bool verbose = false)
232 {
233 // enrich the vertex mapper subject to the provided facet grid
234 4 this->vertexMapper().enrich(facetGridView, codimOneGridAdapter, verbose);
235
236 // resize containers
237 2 const auto numDof = numDofs();
238 4 const auto numElements = this->gridView().size(0);
239 2 scvs_.clear();
240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 scvfs_.clear();
241 2 scvs_.resize(numElements);
242 2 scvfs_.resize(numElements);
243 2 boundaryDofIndices_.assign(numDof, false);
244 2 interiorBoundaryDofIndices_.assign(numDof, false);
245
246 // Build the SCV and SCV faces
247 2 numScv_ = 0;
248 2 numScvf_ = 0;
249 2 numBoundaryScvf_ = 0;
250
10/12
✓ Branch 2 taken 491 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 491 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 491 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 491 times.
✓ Branch 11 taken 1 times.
✓ Branch 13 taken 491 times.
✗ Branch 14 not taken.
1968 for (const auto& element : elements(this->gridView()))
251 {
252
2/4
✓ Branch 1 taken 491 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 491 times.
✗ Branch 5 not taken.
1964 auto eIdx = this->elementMapper().index(element);
253
254 // keep track of number of scvs and scvfs
255
1/2
✓ Branch 1 taken 491 times.
✗ Branch 2 not taken.
982 numScv_ += element.subEntities(dim);
256
1/2
✓ Branch 1 taken 491 times.
✗ Branch 2 not taken.
982 numScvf_ += element.subEntities(dim-1);
257
258 // get the element geometry
259
2/4
✓ Branch 1 taken 491 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 491 times.
✗ Branch 5 not taken.
1473 auto elementGeometry = element.geometry();
260
1/2
✓ Branch 1 taken 491 times.
✗ Branch 2 not taken.
982 const auto refElement = referenceElement(elementGeometry);
261
262 // instantiate the geometry helper
263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 982 times.
982 GeometryHelper geometryHelper(elementGeometry);
264
265 // construct the sub control volumes
266
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 982 times.
1964 scvs_[eIdx].clear();
267
2/4
✓ Branch 1 taken 491 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 491 times.
✗ Branch 5 not taken.
1964 scvs_[eIdx].reserve(elementGeometry.corners());
268
4/4
✓ Branch 0 taken 3928 times.
✓ Branch 1 taken 982 times.
✓ Branch 2 taken 3928 times.
✓ Branch 3 taken 982 times.
8838 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
269
3/6
✓ Branch 1 taken 1964 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1964 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1964 times.
✗ Branch 8 not taken.
3928 scvs_[eIdx].emplace_back(geometryHelper.getScvCorners(scvLocalIdx),
270 scvLocalIdx,
271 eIdx,
272
2/4
✓ Branch 1 taken 1964 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1964 times.
✗ Branch 5 not taken.
7856 this->vertexMapper().subIndex(element, scvLocalIdx, dim));
273
274 // construct the sub control volume faces
275 982 LocalIndexType scvfLocalIdx = 0;
276 1964 scvfs_[eIdx].clear();
277
3/6
✓ Branch 1 taken 491 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 491 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 491 times.
✗ Branch 8 not taken.
1964 scvfs_[eIdx].reserve(element.subEntities(dim-1));
278
4/4
✓ Branch 1 taken 6383 times.
✓ Branch 2 taken 491 times.
✓ Branch 3 taken 2946 times.
✓ Branch 4 taken 491 times.
6874 for (; scvfLocalIdx < element.subEntities(dim-1); ++scvfLocalIdx)
279 {
280 // find the global and local scv indices this scvf is belonging to
281
2/6
✓ Branch 3 taken 5892 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5892 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
17676 std::vector<LocalIndexType> localScvIndices({static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
282
1/2
✓ Branch 2 taken 2946 times.
✗ Branch 3 not taken.
5892 static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
283
284 // create the sub-control volume face
285
1/2
✓ Branch 1 taken 5892 times.
✗ Branch 2 not taken.
5892 scvfs_[eIdx].emplace_back(geometryHelper,
286 element,
287 elementGeometry,
288 scvfLocalIdx,
289
1/2
✓ Branch 1 taken 5892 times.
✗ Branch 2 not taken.
5892 std::move(localScvIndices));
290 }
291
292 // construct the sub control volume faces on the domain/interior boundaries
293 // skip handled facets (necessary for e.g. Dune::FoamGrid)
294
1/4
✓ Branch 1 taken 982 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1964 std::vector<unsigned int> handledFacets;
295
11/18
✓ Branch 1 taken 982 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 982 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 491 times.
✓ Branch 8 taken 2455 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 491 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2455 times.
✓ Branch 13 taken 1964 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1964 times.
✓ Branch 17 taken 491 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1964 times.
✓ Branch 21 taken 491 times.
✗ Branch 22 not taken.
11784 for (const auto& intersection : intersections(this->gridView(), element))
296 {
297
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 3928 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1964 times.
13748 if (std::count(handledFacets.begin(), handledFacets.end(), intersection.indexInInside()))
298 continue;
299
300
2/4
✓ Branch 1 taken 3928 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3928 times.
✗ Branch 5 not taken.
5892 handledFacets.push_back(intersection.indexInInside());
301
302 // determine if all corners live on the facet grid
303
1/2
✓ Branch 1 taken 3928 times.
✗ Branch 2 not taken.
7856 const auto isGeometry = intersection.geometry();
304
2/3
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 3160 times.
✗ Branch 2 not taken.
3928 const auto numFaceCorners = isGeometry.corners();
305
2/3
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 3160 times.
✗ Branch 2 not taken.
3928 const auto idxInInside = intersection.indexInInside();
306
2/2
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 1196 times.
3928 const auto boundary = intersection.boundary();
307
308
3/8
✓ Branch 1 taken 3928 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3928 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1964 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
11784 std::vector<LocalIndexType> vIndicesLocal(numFaceCorners);
309
2/2
✓ Branch 0 taken 11784 times.
✓ Branch 1 taken 3928 times.
15712 for (int i = 0; i < numFaceCorners; ++i)
310 11784 vIndicesLocal[i] = static_cast<LocalIndexType>(refElement.subEntity(idxInInside, 1, i, dim));
311
312
4/12
✓ Branch 1 taken 3928 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3928 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3928 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3928 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
15712 std::vector<LocalIndexType> gridVertexIndices(numFaceCorners);
313
2/2
✓ Branch 0 taken 11784 times.
✓ Branch 1 taken 3928 times.
15712 for (int i = 0; i < numFaceCorners; ++i)
314
3/6
✓ Branch 1 taken 11784 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11784 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 11784 times.
✗ Branch 8 not taken.
35352 gridVertexIndices[i] = this->vertexMapper().vertexIndex(element, vIndicesLocal[i], dim);
315
316 // if the vertices compose a facet element, the intersection is on facet grid
317
1/2
✓ Branch 1 taken 3928 times.
✗ Branch 2 not taken.
3928 const bool isOnFacet = codimOneGridAdapter.composeFacetElement(gridVertexIndices);
318
319 // make sure there are no periodic boundaries
320
5/6
✓ Branch 0 taken 480 times.
✓ Branch 1 taken 3448 times.
✓ Branch 2 taken 240 times.
✓ Branch 3 taken 240 times.
✓ Branch 4 taken 240 times.
✗ Branch 5 not taken.
3928 if (boundary && intersection.neighbor())
321 DUNE_THROW(Dune::InvalidStateException, "Periodic boundaries are not supported by the box facet coupling scheme");
322
323
4/4
✓ Branch 0 taken 3800 times.
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 480 times.
✓ Branch 3 taken 3320 times.
3928 if (isOnFacet || boundary)
324 {
325 // keep track of number of faces
326 608 numScvf_ += numFaceCorners;
327 608 numBoundaryScvf_ += int(boundary)*numFaceCorners;
328
329
2/2
✓ Branch 0 taken 1824 times.
✓ Branch 1 taken 608 times.
2432 for (unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < numFaceCorners; ++isScvfLocalIdx)
330 {
331 // find the inside scv this scvf is belonging to (localIdx = element local vertex index)
332
3/8
✓ Branch 1 taken 1824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1824 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1824 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
7296 std::vector<LocalIndexType> localScvIndices = {vIndicesLocal[isScvfLocalIdx], vIndicesLocal[isScvfLocalIdx]};
333
334 // create the sub-control volume face
335
1/2
✓ Branch 1 taken 1824 times.
✗ Branch 2 not taken.
1824 scvfs_[eIdx].emplace_back(geometryHelper,
336 intersection,
337 isGeometry,
338 isScvfLocalIdx,
339 scvfLocalIdx,
340
1/2
✓ Branch 1 taken 1824 times.
✗ Branch 2 not taken.
1824 std::move(localScvIndices),
341 boundary,
342 isOnFacet);
343
344 // Mark vertices to be on domain and/or interior boundary
345
3/6
✓ Branch 1 taken 1824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1824 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1824 times.
✗ Branch 8 not taken.
5472 const auto dofIndex = this->vertexMapper().subIndex(element, vIndicesLocal[isScvfLocalIdx], dim);
346
5/8
✓ Branch 0 taken 1440 times.
✓ Branch 1 taken 384 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1440 times.
✓ Branch 4 taken 1440 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1440 times.
✗ Branch 7 not taken.
1824 if (boundary) boundaryDofIndices_[ dofIndex ] = boundary && !isOnFacet;
347
2/2
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 1440 times.
1824 if (isOnFacet) interiorBoundaryDofIndices_[ dofIndex ] = isOnFacet;
348
349 // increment local counter
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1824 times.
1824 scvfLocalIdx++;
351 }
352 }
353 }
354 }
355 2 }
356
357 const FeCache feCache_;
358
359 std::vector<std::vector<SubControlVolume>> scvs_;
360 std::vector<std::vector<SubControlVolumeFace>> scvfs_;
361
362 // TODO do we need those?
363 std::size_t numScv_;
364 std::size_t numScvf_;
365 std::size_t numBoundaryScvf_;
366
367 // vertices on domain/interior boundaries
368 std::vector<bool> boundaryDofIndices_;
369 std::vector<bool> interiorBoundaryDofIndices_;
370 };
371
372 /*!
373 * \ingroup FacetCoupling
374 * \brief Base class for the finite volume geometry vector for box schemes
375 * This builds up the sub control volumes and sub control volume faces
376 * \note For caching disabled we store only some essential index maps to build up local systems on-demand in
377 * the corresponding FVElementGeometry
378 */
379 template<class Scalar, class GV, class Traits>
380 class BoxFacetCouplingFVGridGeometry<Scalar, GV, false, Traits>
381 : public BaseGridGeometry<GV, Traits>
382 {
383 using ThisType = BoxFacetCouplingFVGridGeometry<Scalar, GV, false, Traits>;
384 using ParentType = BaseGridGeometry<GV, Traits>;
385 using GridIndexType = typename IndexTraits<GV>::GridIndex;
386 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
387
388 static const int dim = GV::dimension;
389 static const int dimWorld = GV::dimensionworld;
390
391 using Element = typename GV::template Codim<0>::Entity;
392 using Intersection = typename GV::Intersection;
393 using CoordScalar = typename GV::ctype;
394
395 public:
396 //! export the discretization method this geometry belongs to
397 using DiscretizationMethod = DiscretizationMethods::Box;
398 static constexpr DiscretizationMethod discMethod{};
399
400 //! export the type of the fv element geometry (the local view type)
401 using LocalView = typename Traits::template LocalView<ThisType, false>;
402 //! export the type of sub control volume
403 using SubControlVolume = typename Traits::SubControlVolume;
404 //! export the type of sub control volume
405 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
406 //! export the type of extrusion
407 using Extrusion = Extrusion_t<Traits>;
408 //! export dof mapper type
409 using DofMapper = typename Traits::VertexMapper;
410 //! export the finite element cache type
411 using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
412 //! export the grid view type
413 using GridView = GV;
414 //! export the geometry helper type
415 using GeometryHelper = Detail::BoxFacetCouplingGeometryHelper_t<GV, Traits>;
416
417 //! Constructor
418 template<class FacetGridView, class CodimOneGridAdapter>
419 24 BoxFacetCouplingFVGridGeometry(const GridView& gridView,
420 const FacetGridView& facetGridView,
421 const CodimOneGridAdapter& codimOneGridAdapter,
422 bool verbose = false)
423 : ParentType(gridView)
424
7/18
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 22 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 22 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 22 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 22 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 22 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 22 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
48 , facetMapper_(gridView, Dune::mcmgLayout(Dune::template Codim<1>()))
425 {
426
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
24 update_(facetGridView, codimOneGridAdapter, verbose);
427 24 }
428
429 //! the vertex mapper is the dofMapper
430 //! this is convenience to have better chance to have the same main files for box/tpfa/mpfa...
431 const DofMapper& dofMapper() const
432
12/44
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 76 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 76 times.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 11 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 11 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 2 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 2 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 2 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 2 times.
✗ Branch 33 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
25688092 { return this->vertexMapper(); }
433
434 //! The total number of sub control volumes
435 std::size_t numScv() const
436 { return numScv_; }
437
438 //! The total number of sun control volume faces
439 std::size_t numScvf() const
440 { return numScvf_; }
441
442 //! The total number of boundary sub control volume faces
443 //! For compatibility reasons with cc methods
444 std::size_t numBoundaryScvf() const
445 { return numBoundaryScvf_; }
446
447 //! The total number of degrees of freedom
448 std::size_t numDofs() const
449
22/39
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 21 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 21 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 19 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✓ Branch 22 taken 19 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 1 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 times.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 1 times.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 1 times.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 39 taken 1 times.
✗ Branch 40 not taken.
✓ Branch 42 taken 1 times.
✗ Branch 43 not taken.
✓ Branch 45 taken 1 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 1 times.
✗ Branch 49 not taken.
186 { return this->vertexMapper().size(); }
450
451 /*!
452 * \brief update all fvElementGeometries (call this after grid adaption)
453 * \note This assumes conforming grids!
454 *
455 * \param gridView The grid view of a dim-dimensional grid.
456 *
457 * \param facetGridView The grid view of a (dim-1)-dimensional grid conforming
458 * with the facets of this grid view, indicating on which facets
459 * nodal dofs should be enriched.
460 * \param codimOneGridAdapter Adapter class that allows access to information on the d-
461 * dimensional grid for entities of the (d-1)-dimensional grid
462 * \param verbose Verbosity level for vertex enrichment
463 */
464 template<class FacetGridView, class CodimOneGridAdapter>
465 void update(const GridView& gridView,
466 const FacetGridView& facetGridView,
467 const CodimOneGridAdapter& codimOneGridAdapter,
468 bool verbose = false)
469 {
470 ParentType::update(gridView);
471 updateFacetMapper_();
472 update_(facetGridView, codimOneGridAdapter, verbose);
473 }
474
475 //! update all fvElementGeometries (call this after grid adaption)
476 template<class FacetGridView, class CodimOneGridAdapter>
477 void update(GridView&& gridView,
478 const FacetGridView& facetGridView,
479 const CodimOneGridAdapter& codimOneGridAdapter,
480 bool verbose = false)
481 {
482 ParentType::update(std::move(gridView));
483 updateFacetMapper_();
484 update_(facetGridView, codimOneGridAdapter, verbose);
485 }
486
487 //! The finite element cache for creating local FE bases
488 const FeCache& feCache() const
489
4/7
✓ Branch 1 taken 4003560 times.
✓ Branch 2 taken 816696 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 64008 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 36690 times.
✗ Branch 9 not taken.
8936836 { return feCache_; }
490
491 //! If a d.o.f. is on the boundary
492 bool dofOnBoundary(unsigned int dofIdx) const
493
8/8
✓ Branch 0 taken 174865 times.
✓ Branch 1 taken 4074335 times.
✓ Branch 2 taken 174865 times.
✓ Branch 3 taken 4074335 times.
✓ Branch 4 taken 15209 times.
✓ Branch 5 taken 44575 times.
✓ Branch 6 taken 15209 times.
✓ Branch 7 taken 44575 times.
8617968 { return boundaryDofIndices_[dofIdx]; }
494
495 //! If a d.o.f. is on an interior boundary
496 bool dofOnInteriorBoundary(unsigned int dofIdx) const
497 { return interiorBoundaryDofIndices_[dofIdx]; }
498
499 //! returns true if an intersection is on an interior boundary
500 5478739 bool isOnInteriorBoundary(const Element& element, const Intersection& intersection) const
501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6216 times.
5478739 { return facetIsOnInteriorBoundary_[ facetMapper_.subIndex(element, intersection.indexInInside(), 1) ]; }
502
503 //! Periodic boundaries are not supported for the box facet coupling scheme
504 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
505 { return false; }
506
507 //! The index of the vertex / d.o.f. on the other side of the periodic boundary
508 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
509 { DUNE_THROW(Dune::InvalidStateException, "Periodic boundaries are not supported by the facet coupling scheme"); }
510
511 //! Returns the map between dofs across periodic boundaries
512 [[deprecated("Will be removed after release 3.9. Implement periodicDofMap() if periodic bcs are supported.")]]
513 std::unordered_map<GridIndexType, GridIndexType> periodicVertexMap() const
514 { return std::unordered_map<GridIndexType, GridIndexType>(); }
515
516 private:
517
518 void updateFacetMapper_()
519 {
520 facetMapper_.update(this->gridView());
521 }
522
523 template<class FacetGridView, class CodimOneGridAdapter>
524 24 void update_(const FacetGridView& facetGridView,
525 const CodimOneGridAdapter& codimOneGridAdapter,
526 bool verbose)
527 {
528 // enrich the vertex mapper subject to the provided facet grid
529 48 this->vertexMapper().enrich(facetGridView, codimOneGridAdapter, verbose);
530
531 // save global data on the grid's scvs and scvfs
532 // TODO do we need those information?
533 24 numScv_ = 0;
534 24 numScvf_ = 0;
535 24 numBoundaryScvf_ = 0;
536
537 24 const auto numDof = numDofs();
538 24 boundaryDofIndices_.assign(numDof, false);
539 24 interiorBoundaryDofIndices_.assign(numDof, false);
540 48 facetIsOnInteriorBoundary_.assign(this->gridView().size(1), false);
541
10/12
✓ Branch 2 taken 88 times.
✓ Branch 3 taken 22 times.
✓ Branch 4 taken 88 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 21 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 52427 times.
✓ Branch 9 taken 21 times.
✓ Branch 10 taken 52427 times.
✓ Branch 11 taken 21 times.
✓ Branch 13 taken 52427 times.
✗ Branch 14 not taken.
109108 for (const auto& element : elements(this->gridView()))
542 {
543
1/2
✓ Branch 1 taken 52427 times.
✗ Branch 2 not taken.
54530 numScv_ += element.subEntities(dim);
544
1/2
✓ Branch 1 taken 52427 times.
✗ Branch 2 not taken.
54530 numScvf_ += element.subEntities(dim-1);
545
546
2/4
✓ Branch 1 taken 52427 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 52427 times.
✗ Branch 5 not taken.
108884 const auto elementGeometry = element.geometry();
547
1/2
✓ Branch 1 taken 52427 times.
✗ Branch 2 not taken.
54530 const auto refElement = referenceElement(elementGeometry);
548
549 // store the sub control volume face indices on the domain/interior boundary
550 // skip handled facets (necessary for e.g. Dune::FoamGrid)
551
1/4
✓ Branch 1 taken 52515 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
109060 std::vector<unsigned int> handledFacets;
552
7/17
✓ Branch 1 taken 52515 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 52515 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 254159 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 13 taken 201436 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 201644 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 296 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 52427 times.
✗ Branch 22 not taken.
637768 for (const auto& intersection : intersections(this->gridView(), element))
553 {
554
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 201644 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 264 times.
✓ Branch 4 taken 201348 times.
419296 if (std::count(handledFacets.begin(), handledFacets.end(), intersection.indexInInside()))
555 64 continue;
556
557
2/4
✓ Branch 1 taken 201612 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 201612 times.
✗ Branch 5 not taken.
210112 handledFacets.push_back(intersection.indexInInside());
558
559 // determine if all corners live on the facet grid
560
1/2
✓ Branch 1 taken 201612 times.
✗ Branch 2 not taken.
418640 const auto isGeometry = intersection.geometry();
561
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 201612 times.
✗ Branch 2 not taken.
209584 const auto numFaceCorners = isGeometry.corners();
562
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 201612 times.
✗ Branch 2 not taken.
209584 const auto idxInInside = intersection.indexInInside();
563
1/2
✓ Branch 1 taken 264 times.
✗ Branch 2 not taken.
209584 const auto boundary = intersection.boundary();
564
565
2/4
✓ Branch 1 taken 201612 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 201612 times.
✗ Branch 5 not taken.
628752 std::vector<LocalIndexType> vIndicesLocal(numFaceCorners);
566
2/2
✓ Branch 0 taken 410932 times.
✓ Branch 1 taken 201612 times.
644168 for (int i = 0; i < numFaceCorners; ++i)
567 434584 vIndicesLocal[i] = static_cast<LocalIndexType>(refElement.subEntity(idxInInside, 1, i, dim));
568
569
4/12
✓ Branch 1 taken 201612 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 201612 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 201612 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 201612 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
838336 std::vector<GridIndexType> gridVertexIndices(numFaceCorners);
570
2/2
✓ Branch 0 taken 410932 times.
✓ Branch 1 taken 201612 times.
644168 for (int i = 0; i < numFaceCorners; ++i)
571
3/6
✓ Branch 1 taken 410932 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 410932 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 410932 times.
✗ Branch 8 not taken.
1303752 gridVertexIndices[i] = this->vertexMapper().vertexIndex(element, vIndicesLocal[i], dim);
572
573 // if all vertices are living on the facet grid, this is an interiour boundary
574
1/2
✓ Branch 1 taken 201612 times.
✗ Branch 2 not taken.
209584 const bool isOnFacet = codimOneGridAdapter.composeFacetElement(gridVertexIndices);
575
576 // make sure there are no periodic boundaries
577
5/6
✓ Branch 0 taken 4064 times.
✓ Branch 1 taken 197548 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 4032 times.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
209584 if (boundary && intersection.neighbor())
578 DUNE_THROW(Dune::InvalidStateException, "Periodic boundaries are not supported by the box facet coupling scheme");
579
580
2/2
✓ Branch 0 taken 5744 times.
✓ Branch 1 taken 195868 times.
209584 if (isOnFacet || boundary)
581 {
582 6712 numScvf_ += numFaceCorners;
583 6712 numBoundaryScvf_ += int(boundary)*numFaceCorners;
584
585 // Mark vertices to be on domain and/or interior boundary
586
2/2
✓ Branch 0 taken 12408 times.
✓ Branch 1 taken 5744 times.
21976 for (int i = 0; i < numFaceCorners; ++i)
587 {
588
3/6
✓ Branch 1 taken 12312 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12312 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12312 times.
✗ Branch 8 not taken.
45792 const auto dofIndex = this->vertexMapper().subIndex(element, vIndicesLocal[i], dim);
589
6/6
✓ Branch 0 taken 8872 times.
✓ Branch 1 taken 3536 times.
✓ Branch 2 taken 8776 times.
✓ Branch 3 taken 96 times.
✓ Branch 4 taken 8776 times.
✓ Branch 5 taken 96 times.
15264 if (boundary) boundaryDofIndices_[ dofIndex ] = boundary && !isOnFacet;
590
2/2
✓ Branch 0 taken 3632 times.
✓ Branch 1 taken 8776 times.
15264 if (isOnFacet)
591 {
592
2/4
✓ Branch 1 taken 3632 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3632 times.
✗ Branch 5 not taken.
8384 interiorBoundaryDofIndices_[ dofIndex ] = true;
593
1/2
✓ Branch 1 taken 3632 times.
✗ Branch 2 not taken.
4192 facetIsOnInteriorBoundary_[ facetMapper_.subIndex(element, idxInInside, 1) ] = true;
594 }
595 }
596 }
597 }
598 }
599 24 }
600
601 const FeCache feCache_;
602
603 // Information on the global number of geometries
604 // TODO do we need those information?
605 std::size_t numScv_;
606 std::size_t numScvf_;
607 std::size_t numBoundaryScvf_;
608
609 // vertices on domain/interior boundaries
610 std::vector<bool> boundaryDofIndices_;
611 std::vector<bool> interiorBoundaryDofIndices_;
612
613 // facet mapper and markers which facets lie on interior boundaries
614 typename Traits::FacetMapper facetMapper_;
615 std::vector<bool> facetIsOnInteriorBoundary_;
616 };
617
618 } // end namespace Dumux
619
620 #endif
621