GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/discretization/facecentered/staggered/fvgridgeometry.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 200 222 90.1%
Functions: 82 127 64.6%
Branches: 451 780 57.8%

Line Branch Exec Source
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 //
4 // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 /*!
8 * \file
9 * \ingroup FaceCenteredStaggeredDiscretization
10 * \copydoc Dumux::FaceCenteredStaggeredFVGridGeometry
11 */
12 #ifndef DUMUX_DISCRETIZATION_FACECENTERED_STAGGERED_FV_GRID_GEOMETRY
13 #define DUMUX_DISCRETIZATION_FACECENTERED_STAGGERED_FV_GRID_GEOMETRY
14
15 #include <memory>
16
17 #include <dune/common/rangeutilities.hh>
18 #include <dune/grid/common/scsgmapper.hh>
19
20 #include <dumux/common/defaultmappertraits.hh>
21 #include <dumux/common/indextraits.hh>
22 #include <dumux/common/intersectionmapper.hh>
23 #include <dumux/common/math.hh>
24
25 #include <dumux/discretization/basegridgeometry.hh>
26 #include <dumux/discretization/checkoverlapsize.hh>
27 #include <dumux/discretization/method.hh>
28 #include <dumux/discretization/extrusion.hh>
29
30 #include <dumux/discretization/facecentered/staggered/subcontrolvolume.hh>
31 #include <dumux/discretization/facecentered/staggered/subcontrolvolumeface.hh>
32 #include <dumux/discretization/facecentered/staggered/fvelementgeometry.hh>
33 #include <dumux/discretization/facecentered/staggered/geometryhelper.hh>
34 #include <dumux/discretization/facecentered/staggered/connectivitymap.hh>
35 #include <dumux/discretization/facecentered/staggered/normalaxis.hh>
36 #include <dumux/discretization/facecentered/staggered/localintersectionindexmapper.hh>
37
38 namespace Dumux {
39
40 /*!
41 * \ingroup FaceCenteredStaggeredDiscretization
42 * \brief The default traits for the face-center staggered finite volume grid geometry
43 * Defines the scv and scvf types and the mapper types
44 * \tparam GridView the grid view type
45 */
46 template<class GridView>
47 struct FaceCenteredStaggeredDefaultGridGeometryTraits : public DefaultMapperTraits<GridView>
48 {
49 using SubControlVolume = FaceCenteredStaggeredSubControlVolume<GridView>;
50 using SubControlVolumeFace = FaceCenteredStaggeredSubControlVolumeFace<GridView>;
51 using IntersectionMapper = ConformingGridIntersectionMapper<GridView>;
52 using LocalIntersectionMapper = FaceCenteredStaggeredLocalIntersectionIndexMapper<GridView>;
53 using GeometryHelper = FaceCenteredStaggeredGeometryHelper<GridView>;
54
55 template<class GridGeometry>
56 using ConnectivityMap = FaceCenteredStaggeredConnectivityMap<GridGeometry>;
57
58 template<class GridGeometry, bool enableCache>
59 using LocalView = FaceCenteredStaggeredFVElementGeometry<GridGeometry, enableCache>;
60
61 struct StaticInfo
62 {
63 static constexpr auto dim = GridView::Grid::dimension;
64 static constexpr auto numFacesPerElement = dim * 2;
65 static constexpr auto numScvsPerElement = numFacesPerElement;
66 static constexpr auto numLateralScvfsPerScv = 2 * (dim - 1);
67 static constexpr auto numLateralScvfsPerElement = numFacesPerElement*numLateralScvfsPerScv;
68 static constexpr auto minNumScvfsPerElement = numLateralScvfsPerElement // number of lateral faces
69 + numFacesPerElement; // number of central frontal faces
70 static constexpr auto maxNumScvfsPerElement = minNumScvfsPerElement
71 + numFacesPerElement; // number of potential frontal faces on boundary
72 };
73 };
74
75 /*!
76 * \ingroup FaceCenteredStaggeredDiscretization
77 * \brief Base class for the finite volume geometry vector for face-centered staggered models
78 * This builds up the sub control volumes and sub control volume faces
79 * for each element.
80 */
81 template<class GridView,
82 bool cachingEnabled = false,
83 class Traits = FaceCenteredStaggeredDefaultGridGeometryTraits<GridView>>
84 class FaceCenteredStaggeredFVGridGeometry;
85
86 /*!
87 * \ingroup FaceCenteredStaggeredDiscretization
88 * \brief Base class for the finite volume geometry vector for staggered models
89 * This builds up the sub control volumes and sub control volume faces
90 * for each element. Specialization in case the FVElementGeometries are stored.
91 */
92 template<class GV, class Traits>
93 class FaceCenteredStaggeredFVGridGeometry<GV, true, Traits>
94 : public BaseGridGeometry<GV, Traits>
95 {
96 using ThisType = FaceCenteredStaggeredFVGridGeometry<GV, true, Traits>;
97 using ParentType = BaseGridGeometry<GV, Traits>;
98 using GridIndexType = typename IndexTraits<GV>::GridIndex;
99 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
100 using SmallLocalIndexType = typename IndexTraits<GV>::SmallLocalIndex;
101 using Element = typename GV::template Codim<0>::Entity;
102
103 using IntersectionMapper = typename Traits::IntersectionMapper;
104 using ConnectivityMap = typename Traits::template ConnectivityMap<ThisType>;
105
106 using Scalar = typename GV::ctype;
107
108 static constexpr auto dim = Traits::StaticInfo::dim;
109 static constexpr auto numScvsPerElement = Traits::StaticInfo::numScvsPerElement;
110 static constexpr auto numLateralScvfsPerScv = Traits::StaticInfo::numLateralScvfsPerScv;
111 static constexpr auto numLateralScvfsPerElement = Traits::StaticInfo::numLateralScvfsPerElement;
112 static constexpr auto minNumScvfsPerElement = Traits::StaticInfo::minNumScvfsPerElement;
113 static constexpr auto maxNumScvfsPerElement = Traits::StaticInfo::maxNumScvfsPerElement;
114
115 using ScvfCornerStorage = typename Traits::SubControlVolumeFace::Traits::CornerStorage;
116 using ScvCornerStorage = typename Traits::SubControlVolume::Traits::CornerStorage;
117
118 public:
119 //! export the discretization method this geometry belongs to
120 using DiscretizationMethod = DiscretizationMethods::FCStaggered;
121 static constexpr DiscretizationMethod discMethod{};
122
123 static constexpr bool cachingEnabled = true;
124
125 //! export basic grid geometry type for the alternative constructor
126 using BasicGridGeometry = BasicGridGeometry_t<GV, Traits>;
127 //! export the type of the fv element geometry (the local view type)
128 using LocalView = typename Traits::template LocalView<ThisType, true>;
129 //! export the type of sub control volume
130 using SubControlVolume = typename Traits::SubControlVolume;
131 //! export the type of sub control volume
132 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
133 //! export the grid view type
134 using GridView = GV;
135 //! export the geometry helper type
136 using GeometryHelper = typename Traits::GeometryHelper;
137 //! export the local intersection mapper
138 using LocalIntersectionMapper = typename Traits::LocalIntersectionMapper;
139 //! export static information
140 using StaticInformation = typename Traits::StaticInfo;
141 //! export the type of extrusion
142 using Extrusion = Extrusion_t<Traits>;
143
144 //! Constructor with basic grid geometry used to share state with another grid geometry on the same grid view
145 58 FaceCenteredStaggeredFVGridGeometry(std::shared_ptr<BasicGridGeometry> gg, const std::string& paramGroup = "")
146 58 : ParentType(std::move(gg))
147
13/34
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 53 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 56 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 53 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 53 times.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 4 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
348 , intersectionMapper_(this->gridView())
148 {
149 // Check if the overlap size is what we expect
150
3/5
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
116 if (!CheckOverlapSize<DiscretizationMethod>::isValid(this->gridView()))
151 DUNE_THROW(Dune::InvalidStateException, "The staggered discretization method needs overlap of exactly 1 for parallel computations. "
152 << " Set the parameter \"Grid.Overlap\" in the input file.");
153
154
1/2
✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
58 update_();
155 58 }
156
157 //! Constructor from gridView
158 55 FaceCenteredStaggeredFVGridGeometry(const GridView& gridView, const std::string& paramGroup = "")
159
2/6
✓ Branch 2 taken 55 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 55 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
55 : FaceCenteredStaggeredFVGridGeometry(std::make_shared<BasicGridGeometry>(gridView), paramGroup)
160 55 {}
161
162 //! The total number of sub control volumes
163 std::size_t numScv() const
164
7/11
✓ Branch 2 taken 2574803 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2574803 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 148357 times.
✓ Branch 9 taken 182800 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 10 times.
✓ Branch 13 taken 102 times.
✗ Branch 14 not taken.
5481743 { return scvs_.size(); }
165
166 //! The total number of sub control volume faces
167 std::size_t numScvf() const
168 84 { return scvfs_.size(); }
169
170 //! The total number of boundary sub control volumes
171 std::size_t numBoundaryScv() const
172 { return numBoundaryScv_; }
173
174 //! The total number of boundary sub control volume faces
175 std::size_t numBoundaryScvf() const
176 { return numBoundaryScvf_; }
177
178 //! The total number of intersections
179 std::size_t numIntersections() const
180 { return intersectionMapper_.numIntersections(); }
181
182 //! the total number of dofs
183 std::size_t numDofs() const
184
35/55
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 53 times.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 14 times.
✓ Branch 12 taken 5 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 7 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 5 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 3 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 5 times.
✓ Branch 23 taken 10 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 9 times.
✓ Branch 26 taken 10 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 18 times.
✓ Branch 29 taken 8 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 17 times.
✓ Branch 32 taken 9 times.
✓ Branch 33 taken 12 times.
✓ Branch 34 taken 9 times.
✓ Branch 35 taken 11 times.
✓ Branch 36 taken 12 times.
✓ Branch 37 taken 10 times.
✓ Branch 38 taken 11 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 33 times.
✓ Branch 41 taken 3 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 33 times.
✓ Branch 44 taken 1 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 23 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 19 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 19 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 19 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 5 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 5 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 5 times.
✗ Branch 65 not taken.
1150 { return this->gridView().size(1); }
185
186 //! update all fvElementGeometries (call this after grid adaption)
187 void update(const GridView& gridView)
188 {
189 ParentType::update(gridView);
190 update_();
191 }
192
193 //! update all fvElementGeometries (call this after grid adaption)
194 void update(GridView&& gridView)
195 {
196 ParentType::update(std::move(gridView));
197 update_();
198 }
199
200 //! Get a sub control volume with a global scv index
201 const SubControlVolume& scv(GridIndexType scvIdx) const
202
106/114
✓ Branch 0 taken 10144 times.
✓ Branch 1 taken 5344 times.
✓ Branch 2 taken 10300 times.
✓ Branch 3 taken 5616 times.
✓ Branch 4 taken 156 times.
✓ Branch 5 taken 272 times.
✓ Branch 6 taken 21 times.
✓ Branch 7 taken 446899 times.
✓ Branch 8 taken 21 times.
✓ Branch 9 taken 446899 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 5825101 times.
✓ Branch 12 taken 3 times.
✓ Branch 13 taken 5825101 times.
✓ Branch 14 taken 30 times.
✓ Branch 15 taken 148785384 times.
✓ Branch 16 taken 47 times.
✓ Branch 17 taken 181705945 times.
✓ Branch 18 taken 17 times.
✓ Branch 19 taken 176774711 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 176774728 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 32920578 times.
✓ Branch 24 taken 5032 times.
✓ Branch 25 taken 441888 times.
✓ Branch 26 taken 542992 times.
✓ Branch 27 taken 126939188 times.
✓ Branch 28 taken 593390 times.
✓ Branch 29 taken 141036220 times.
✓ Branch 30 taken 71990 times.
✓ Branch 31 taken 15076880 times.
✓ Branch 32 taken 1276672 times.
✓ Branch 33 taken 104091566 times.
✓ Branch 34 taken 1280344 times.
✓ Branch 35 taken 103557626 times.
✓ Branch 36 taken 20232 times.
✓ Branch 37 taken 4020 times.
✓ Branch 38 taken 272812 times.
✓ Branch 39 taken 292406 times.
✓ Branch 40 taken 274126 times.
✓ Branch 41 taken 293696 times.
✓ Branch 42 taken 953114 times.
✓ Branch 43 taken 89098082 times.
✓ Branch 44 taken 1053808 times.
✓ Branch 45 taken 89189360 times.
✓ Branch 46 taken 104938 times.
✓ Branch 47 taken 1046008 times.
✓ Branch 48 taken 122748 times.
✓ Branch 49 taken 38411772 times.
✓ Branch 50 taken 119818 times.
✓ Branch 51 taken 37458332 times.
✓ Branch 52 taken 15364 times.
✓ Branch 53 taken 38946574 times.
✓ Branch 54 taken 63220 times.
✓ Branch 55 taken 44284118 times.
✓ Branch 56 taken 52796 times.
✓ Branch 57 taken 5413492 times.
✓ Branch 58 taken 3413768 times.
✓ Branch 59 taken 44020202 times.
✓ Branch 60 taken 3408892 times.
✓ Branch 61 taken 44564430 times.
✗ Branch 62 not taken.
✓ Branch 63 taken 32878210 times.
✓ Branch 64 taken 536160 times.
✓ Branch 65 taken 33235154 times.
✓ Branch 66 taken 631824 times.
✓ Branch 67 taken 1678208 times.
✓ Branch 68 taken 8624 times.
✓ Branch 69 taken 616392 times.
✓ Branch 70 taken 766376 times.
✓ Branch 71 taken 2911800 times.
✓ Branch 72 taken 764936 times.
✓ Branch 73 taken 2745344 times.
✓ Branch 74 taken 2817068 times.
✓ Branch 75 taken 9135164 times.
✓ Branch 76 taken 2526828 times.
✓ Branch 77 taken 5596408 times.
✓ Branch 78 taken 3431296 times.
✓ Branch 79 taken 77412 times.
✓ Branch 80 taken 784582 times.
✓ Branch 81 taken 1582450 times.
✓ Branch 82 taken 840518 times.
✓ Branch 83 taken 1598330 times.
✓ Branch 84 taken 21920 times.
✓ Branch 85 taken 47376 times.
✓ Branch 86 taken 7796 times.
✓ Branch 87 taken 82720 times.
✓ Branch 88 taken 16440 times.
✓ Branch 89 taken 32064 times.
✓ Branch 90 taken 83316 times.
✓ Branch 91 taken 5719680 times.
✓ Branch 92 taken 3360 times.
✓ Branch 93 taken 17232 times.
✓ Branch 94 taken 5684480 times.
✓ Branch 95 taken 99760 times.
✓ Branch 96 taken 10832 times.
✓ Branch 97 taken 24 times.
✓ Branch 98 taken 100960 times.
✓ Branch 99 taken 24 times.
✓ Branch 100 taken 1200 times.
✓ Branch 101 taken 21760 times.
✗ Branch 102 not taken.
✓ Branch 103 taken 1120 times.
✓ Branch 104 taken 21760 times.
✗ Branch 105 not taken.
✓ Branch 106 taken 1120 times.
✓ Branch 107 taken 4 times.
✗ Branch 108 not taken.
✓ Branch 109 taken 4 times.
✓ Branch 113 taken 40 times.
✗ Branch 114 not taken.
✓ Branch 116 taken 40 times.
✗ Branch 117 not taken.
4358807938 { return scvs_[scvIdx]; }
203
204 //! Iterator range for sub control volumes. Iterates over
205 //! all scvs of the element-local fvGeometry.
206 auto scvs(const LocalView& fvGeometry) const
207 {
208 314859920 auto begin = scvs_.cbegin() + numScvsPerElement*fvGeometry.elementIndex();
209 157429960 const auto end = begin + numScvsPerElement;
210 78714980 return Dune::IteratorRange<std::decay_t<decltype(begin)>>(begin, end);
211 }
212
213 //! Get a sub control volume face with a global scvf index
214 const SubControlVolumeFace& scvf(GridIndexType scvfIdx) const
215
6/6
✓ Branch 0 taken 368053260 times.
✓ Branch 1 taken 80071277 times.
✓ Branch 2 taken 441495768 times.
✓ Branch 3 taken 96150931 times.
✓ Branch 4 taken 73442508 times.
✓ Branch 5 taken 16079654 times.
1075299718 { return scvfs_[scvfIdx]; }
216
217 //! Get the global sub control volume face indices of an element
218 const std::vector<GridIndexType>& scvfIndicesOfElement(GridIndexType eIdx) const
219 1019511982 { return scvfIndicesOfElement_[eIdx]; }
220
221 /*!
222 * \brief Returns the connectivity map of which dofs have derivatives with respect
223 * to a given dof.
224 */
225 const ConnectivityMap& connectivityMap() const
226
1/2
✓ Branch 1 taken 60 times.
✗ Branch 2 not taken.
7487605 { return connectivityMap_; }
227
228 //! Returns whether one of the geometry's scvfs lies on a boundary
229 bool hasBoundaryScvf(GridIndexType eIdx) const
230 10976008 { return hasBoundaryScvf_[eIdx]; }
231
232 //! Return a reference to the intersection mapper
233 const IntersectionMapper& intersectionMapper() const
234 17104 { return intersectionMapper_; }
235
236 //! If a d.o.f. is on a periodic boundary
237 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
238
8/10
✓ Branch 1 taken 15696 times.
✓ Branch 2 taken 876 times.
✓ Branch 4 taken 15544 times.
✓ Branch 5 taken 792 times.
✓ Branch 7 taken 32 times.
✓ Branch 8 taken 90172 times.
✓ Branch 10 taken 136 times.
✓ Branch 11 taken 2584 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
125832 { return periodicFaceMap_.count(dofIdx); }
239
240 //! The index of the d.o.f. on the other side of the periodic boundary
241 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
242
5/14
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 136 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 136 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
156 { return periodicFaceMap_.at(dofIdx); }
243
244 //! Returns the map between dofs across periodic boundaries
245 const std::unordered_map<GridIndexType, GridIndexType>& periodicDofMap() const
246 592 { return periodicFaceMap_; }
247
248 //! Returns the map between dofs across periodic boundaries
249 [[deprecated("Will be removed after release 3.9. Use periodicDofMap() instead.")]]
250 const std::unordered_map<GridIndexType, GridIndexType>& periodicVertexMap() const
251 { return periodicDofMap(); }
252
253 private:
254
255 58 void update_()
256 {
257 // clear containers (necessary after grid refinement)
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 scvs_.clear();
259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 scvfs_.clear();
260 58 scvfIndicesOfElement_.clear();
261
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
116 intersectionMapper_.update(this->gridView());
262
263 // determine size of containers
264 116 const auto numElements = this->gridView().size(0);
265 58 scvfIndicesOfElement_.resize(numElements);
266 58 hasBoundaryScvf_.resize(numElements, false);
267
268 58 outSideBoundaryVolVarIdx_ = 0;
269 58 numBoundaryScv_ = 0;
270 58 numBoundaryScvf_ = 0;
271
272
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
118 GeometryHelper geometryHelper(this->gridView());
273
274 // get the global scvf indices first
275 58 GridIndexType numScvfs = 0;
276
10/12
✓ Branch 2 taken 329477 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 109 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1768 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 1768 times.
✓ Branch 11 taken 3 times.
✓ Branch 13 taken 1768 times.
✗ Branch 14 not taken.
662502 for (const auto& element : elements(this->gridView()))
277 {
278
3/4
✓ Branch 1 taken 1768 times.
✓ Branch 2 taken 109 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1768 times.
331190 assert(numScvsPerElement == element.subEntities(1));
279
280
15/18
✓ Branch 1 taken 1768 times.
✓ Branch 2 taken 328430 times.
✓ Branch 3 taken 1314648 times.
✓ Branch 4 taken 2204 times.
✓ Branch 5 taken 111 times.
✓ Branch 6 taken 1054 times.
✓ Branch 7 taken 436 times.
✓ Branch 8 taken 14672 times.
✓ Branch 9 taken 992 times.
✓ Branch 10 taken 5832 times.
✓ Branch 11 taken 992 times.
✓ Branch 12 taken 5832 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 7072 times.
✓ Branch 15 taken 5832 times.
✗ Branch 16 not taken.
✓ Branch 20 taken 1768 times.
✗ Branch 21 not taken.
2330616 for (const auto& intersection : intersections(this->gridView(), element))
281 {
282 // frontal scvf in element center
283 1326560 ++numScvfs;
284
285 // lateral scvfs
286 1326560 numScvfs += numLateralScvfsPerScv;
287
288 // handle physical domain boundary
289
3/3
✓ Branch 0 taken 12790 times.
✓ Branch 1 taken 1300706 times.
✓ Branch 2 taken 7232 times.
1327718 if (onDomainBoundary_(intersection))
290 {
291 14224 ++numBoundaryScv_; // frontal face
292 14222 numBoundaryScv_ += numLateralScvfsPerScv; // boundary scvs for lateral faces
293
294 // frontal scvf at boundary
295 14224 ++numScvfs;
296 }
297 }
298 }
299
300 // allocate memory
301 58 const auto numScvs = numElements*numScvsPerElement;
302
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
58 scvs_.resize(numScvs);
303
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
58 scvfs_.reserve(numScvfs);
304
305 // Build the scvs and scv faces
306 58 std::size_t globalScvfIdx = 0;
307
10/12
✓ Branch 2 taken 329477 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 109 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1768 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 1768 times.
✓ Branch 11 taken 3 times.
✓ Branch 13 taken 1768 times.
✗ Branch 14 not taken.
662502 for (const auto& element : elements(this->gridView()))
308 {
309
2/4
✓ Branch 1 taken 1768 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1768 times.
✗ Branch 5 not taken.
662380 const auto eIdx = this->elementMapper().index(element);
310
1/2
✓ Branch 1 taken 1877 times.
✗ Branch 2 not taken.
331190 auto& globalScvfIndices = scvfIndicesOfElement_[eIdx];
311
1/2
✓ Branch 1 taken 1877 times.
✗ Branch 2 not taken.
331190 globalScvfIndices.resize(minNumScvfsPerElement);
312
1/2
✓ Branch 1 taken 1877 times.
✗ Branch 2 not taken.
331190 globalScvfIndices.reserve(maxNumScvfsPerElement);
313
314 auto getGlobalScvIdx = [&](const auto elementIdx, const auto localScvIdx)
315 5300516 { return numScvsPerElement*elementIdx + localScvIdx; };
316
317 1877 LocalIntersectionMapper localIsMapper;
318
2/4
✓ Branch 1 taken 1877 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1877 times.
✗ Branch 5 not taken.
333067 localIsMapper.update(this->gridView(), element);
319
320
13/14
✓ Branch 1 taken 1768 times.
✓ Branch 2 taken 328430 times.
✓ Branch 3 taken 1314648 times.
✓ Branch 4 taken 2236 times.
✓ Branch 5 taken 141 times.
✓ Branch 6 taken 992 times.
✓ Branch 7 taken 436 times.
✓ Branch 8 taken 14672 times.
✓ Branch 9 taken 992 times.
✓ Branch 10 taken 5832 times.
✓ Branch 11 taken 992 times.
✓ Branch 13 taken 7072 times.
✓ Branch 14 taken 5832 times.
✗ Branch 15 not taken.
2000527 for (const auto& intersection : intersections(this->gridView(), element))
321 {
322
2/3
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 7104 times.
✗ Branch 2 not taken.
1326560 const auto& intersectionUnitOuterNormal = intersection.centerUnitOuterNormal();
323
2/4
✓ Branch 1 taken 12904 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7072 times.
✗ Branch 5 not taken.
1326996 const auto localScvIdx = localIsMapper.realToRefIdx(intersection.indexInInside());
324 1326560 auto localScvfIdx = localScvIdx*(1 + numLateralScvfsPerScv);
325
326 2653120 const auto globalScvIdx = getGlobalScvIdx(eIdx, localScvIdx);
327
2/4
✓ Branch 1 taken 12904 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12904 times.
✗ Branch 5 not taken.
2646048 const auto dofIndex = intersectionMapper().globalIntersectionIndex(element, intersection.indexInInside());
328
2/2
✓ Branch 0 taken 663280 times.
✓ Branch 1 taken 663280 times.
1326560 const auto localOppositeScvIdx = geometryHelper.localOppositeIdx(localScvIdx);
329
2/4
✓ Branch 1 taken 7072 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7072 times.
✗ Branch 5 not taken.
1333632 const auto& intersectionGeometry = intersection.geometry();
330
1/2
✓ Branch 1 taken 7072 times.
✗ Branch 2 not taken.
1333632 const auto& elementGeometry = element.geometry();
331
332
5/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1326560 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1319488 times.
✓ Branch 4 taken 7072 times.
✓ Branch 5 taken 436 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7072 times.
2653556 assert(localIsMapper.refToRealIdx(localScvIdx) == intersection.indexInInside());
333
334 // handle periodic boundaries
335
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 1313252 times.
✓ Branch 2 taken 7476 times.
1326560 if (onPeriodicBoundary_(intersection))
336 {
337
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
32 this->setPeriodic();
338
339
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
32 const auto& otherElement = intersection.outside();
340
341 32 SmallLocalIndexType otherIntersectionLocalIdx = 0;
342 32 bool periodicFaceFound = false;
343
344
7/15
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 128 times.
✓ Branch 4 taken 128 times.
✓ Branch 5 taken 32 times.
✓ Branch 6 taken 100 times.
✓ Branch 7 taken 28 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 128 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
388 for (const auto& otherIntersection : intersections(this->gridView(), otherElement))
345 {
346
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 28 times.
128 if (periodicFaceFound)
347 continue;
348
349
4/8
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 68 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
352 if (Dune::FloatCmp::eq(intersectionUnitOuterNormal*otherIntersection.centerUnitOuterNormal(), -1.0, 1e-7))
350 {
351
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
32 const auto periodicDofIdx = intersectionMapper().globalIntersectionIndex(otherElement, otherIntersectionLocalIdx);
352
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 periodicFaceMap_[dofIndex] = periodicDofIdx;
353 32 periodicFaceFound = true;
354 }
355
356 100 ++otherIntersectionLocalIdx;
357 }
358 }
359
360 // the sub control volume
361
5/7
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 12904 times.
✓ Branch 3 taken 436 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7072 times.
✗ Branch 6 not taken.
1334100 scvs_[globalScvIdx] = SubControlVolume(
362 elementGeometry,
363 intersectionGeometry,
364 globalScvIdx,
365 localScvIdx,
366 dofIndex,
367 1326560 Dumux::normalAxis(intersectionUnitOuterNormal),
368
2/4
✓ Branch 1 taken 12904 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12904 times.
✗ Branch 5 not taken.
2653120 this->elementMapper().index(element),
369 onDomainBoundary_(intersection)
370 );
371
372 // the frontal sub control volume face at the element center
373 3940968 scvfs_.emplace_back(elementGeometry,
374 intersectionGeometry,
375
1/2
✓ Branch 1 taken 13340 times.
✗ Branch 2 not taken.
1326560 std::array{globalScvIdx, getGlobalScvIdx(eIdx, localOppositeScvIdx)},
376 localScvfIdx,
377 globalScvfIdx,
378 intersectionUnitOuterNormal,
379 SubControlVolumeFace::FaceType::frontal,
380 SubControlVolumeFace::BoundaryType::interior
381 );
382
383 1326560 globalScvfIndices[localScvfIdx] = globalScvfIdx++;
384 1326560 ++localScvfIdx;
385
386 // the lateral sub control volume faces
387
3/4
✓ Branch 0 taken 2664176 times.
✓ Branch 1 taken 1326560 times.
✓ Branch 3 taken 2664176 times.
✗ Branch 4 not taken.
9291384 for (const auto lateralFacetIndex : Dune::transformedRangeView(geometryHelper.localLaterFaceIndices(localScvIdx),
388
2/4
✓ Branch 1 taken 15016 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15016 times.
✗ Branch 5 not taken.
2679192 [&](auto&& idx) { return localIsMapper.refToRealIdx(idx) ;})
389 )
390 {
391
1/2
✓ Branch 1 taken 2664176 times.
✗ Branch 2 not taken.
2678320 const auto& lateralIntersection = geometryHelper.intersection(lateralFacetIndex, element);
392
393 // helper lambda to get the lateral scvf's global inside and outside scv indices
394 2664176 const auto globalScvIndicesForLateralFace = [&]
395 {
396 2664176 const auto globalOutsideScvIdx = [&]
397 {
398
3/3
✓ Branch 0 taken 2636204 times.
✓ Branch 1 taken 27420 times.
✓ Branch 2 taken 552 times.
2664176 if (lateralIntersection.neighbor())
399 {
400
1/2
✓ Branch 2 taken 13632 times.
✗ Branch 3 not taken.
5233572 const auto parallelElemIdx = this->elementMapper().index(lateralIntersection.outside());
401 2633172 return getGlobalScvIdx(parallelElemIdx, localScvIdx);
402 }
403
1/2
✓ Branch 0 taken 552 times.
✗ Branch 1 not taken.
35544 else if (onDomainBoundary_(lateralIntersection))
404 30668 return numScvs + outSideBoundaryVolVarIdx_++;
405 else
406 46032 return globalScvIdx; // fallback for parallel, won't be used anyway
407
2/2
✓ Branch 1 taken 25576 times.
✓ Branch 2 taken 336 times.
2659636 }();
408
409 2664176 return std::array{globalScvIdx, globalOutsideScvIdx};
410
1/2
✓ Branch 1 taken 36992 times.
✗ Branch 2 not taken.
5328352 }();
411
412 7946832 const auto boundaryType = [&]
413 {
414
1/2
✓ Branch 0 taken 15016 times.
✗ Branch 1 not taken.
5305504 if (onProcessorBoundary_(lateralIntersection))
415 return SubControlVolumeFace::BoundaryType::processorBoundary;
416
3/3
✓ Branch 0 taken 2600400 times.
✓ Branch 1 taken 40040 times.
✓ Branch 2 taken 552 times.
5304832 else if (onDomainBoundary_(lateralIntersection))
417 return SubControlVolumeFace::BoundaryType::physicalBoundary;
418 else
419 return SubControlVolumeFace::BoundaryType::interior;
420
2/2
✓ Branch 0 taken 2625976 times.
✓ Branch 1 taken 336 times.
7946832 }();
421
422
4/9
✗ Branch 0 not taken.
✓ Branch 1 taken 14144 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2627184 times.
✓ Branch 4 taken 36992 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 14144 times.
✗ Branch 9 not taken.
5291360 scvfs_.emplace_back(
423 elementGeometry,
424 intersectionGeometry,
425 geometryHelper.facet(lateralFacetIndex, element).geometry(),
426 globalScvIndicesForLateralFace, // TODO higher order
427 localScvfIdx,
428 globalScvfIdx,
429 lateralIntersection.centerUnitOuterNormal(),
430 SubControlVolumeFace::FaceType::lateral,
431 boundaryType
432 );
433
434
2/2
✓ Branch 0 taken 48424 times.
✓ Branch 1 taken 2600736 times.
2664176 globalScvfIndices[localScvfIdx] = globalScvfIdx++;
435 2664176 ++localScvfIdx;
436
437
3/3
✓ Branch 0 taken 25576 times.
✓ Branch 1 taken 2601288 times.
✓ Branch 2 taken 14464 times.
2668716 if (onDomainBoundary_(lateralIntersection))
438 {
439 30668 ++numBoundaryScvf_;
440 92004 hasBoundaryScvf_[eIdx] = true;
441 }
442 } // end loop over lateral facets
443
444 } // end first loop over intersections
445
446 // do a second loop over all intersections to add frontal boundary faces
447 331190 int localScvfIdx = minNumScvfsPerElement;
448
15/18
✓ Branch 1 taken 1768 times.
✓ Branch 2 taken 328430 times.
✓ Branch 3 taken 1314648 times.
✓ Branch 4 taken 2204 times.
✓ Branch 5 taken 111 times.
✓ Branch 6 taken 1054 times.
✓ Branch 7 taken 436 times.
✓ Branch 8 taken 14672 times.
✓ Branch 9 taken 992 times.
✓ Branch 10 taken 5832 times.
✓ Branch 11 taken 992 times.
✓ Branch 12 taken 5832 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 7072 times.
✓ Branch 15 taken 5832 times.
✗ Branch 16 not taken.
✓ Branch 20 taken 1768 times.
✗ Branch 21 not taken.
2330616 for (const auto& intersection : intersections(this->gridView(), element))
449 {
450 // the frontal sub control volume face at a domain boundary (coincides with element face)
451
3/3
✓ Branch 0 taken 12790 times.
✓ Branch 1 taken 1300706 times.
✓ Branch 2 taken 7232 times.
1327718 if (onDomainBoundary_(intersection))
452 {
453
3/5
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 257 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 256 times.
✗ Branch 5 not taken.
14244 const auto localScvIdx = localIsMapper.realToRefIdx(intersection.indexInInside());
454 28448 const auto globalScvIdx = getGlobalScvIdx(eIdx, localScvIdx);
455 14224 ++numBoundaryScvf_;
456
457 // the frontal sub control volume face at the boundary
458
6/10
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 257 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 1414 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 256 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 256 times.
✗ Branch 11 not taken.
27033 scvfs_.emplace_back(
459 element.geometry(),
460 intersection.geometry(),
461 std::array{globalScvIdx, globalScvIdx}, // TODO outside boundary, periodic, parallel?
462 localScvfIdx,
463 globalScvfIdx,
464 intersection.centerUnitOuterNormal(),
465 SubControlVolumeFace::FaceType::frontal,
466 SubControlVolumeFace::BoundaryType::physicalBoundary
467 );
468
469
1/4
✓ Branch 1 taken 1434 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
14224 globalScvfIndices.push_back(globalScvfIdx);
470 14224 ++globalScvfIdx;
471 14224 ++localScvfIdx;
472 42672 hasBoundaryScvf_[eIdx] = true;
473 }
474 }
475 }
476
477
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
58 connectivityMap_.update(*this);
478 58 }
479
480 9217860 bool onDomainBoundary_(const typename GridView::Intersection& intersection) const
481 {
482
7/14
✓ Branch 0 taken 9159723 times.
✓ Branch 1 taken 58137 times.
✓ Branch 2 taken 122106 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5832 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 22848 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 22848 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5832 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
9343729 return !intersection.neighbor() && intersection.boundary();
483 }
484
485 2626312 bool onProcessorBoundary_(const typename GridView::Intersection& intersection) const
486 {
487
3/6
✓ Branch 0 taken 2636204 times.
✓ Branch 1 taken 12956 times.
✓ Branch 2 taken 25912 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2662116 return !intersection.neighbor() && !intersection.boundary();
488 }
489
490 1313220 bool onPeriodicBoundary_(const typename GridView::Intersection& intersection) const
491 {
492
3/6
✓ Branch 0 taken 1319052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6395 times.
✓ Branch 3 taken 6395 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1331842 return intersection.boundary() && intersection.neighbor();
493 }
494
495 // mappers
496 ConnectivityMap connectivityMap_;
497 IntersectionMapper intersectionMapper_;
498
499 std::vector<SubControlVolume> scvs_;
500 std::vector<SubControlVolumeFace> scvfs_;
501 GridIndexType numBoundaryScv_;
502 GridIndexType numBoundaryScvf_;
503 GridIndexType outSideBoundaryVolVarIdx_;
504 std::vector<bool> hasBoundaryScvf_;
505
506 std::vector<std::vector<GridIndexType>> scvfIndicesOfElement_;
507
508 // a map for periodic boundary vertices
509 std::unordered_map<GridIndexType, GridIndexType> periodicFaceMap_;
510 };
511
512 /*!
513 * \ingroup FaceCenteredStaggeredDiscretization
514 * \brief Base class for the finite volume geometry vector for face-centered staggered models
515 * This builds up the sub control volumes and sub control volume faces
516 * for each element. Specialization in case the FVElementGeometries are stored.
517 */
518 template<class GV, class Traits>
519 class FaceCenteredStaggeredFVGridGeometry<GV, false, Traits>
520 : public BaseGridGeometry<GV, Traits>
521 {
522 using ThisType = FaceCenteredStaggeredFVGridGeometry<GV, false, Traits>;
523 using ParentType = BaseGridGeometry<GV, Traits>;
524 using GridIndexType = typename IndexTraits<GV>::GridIndex;
525 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
526 using SmallLocalIndexType = typename IndexTraits<GV>::SmallLocalIndex;
527 using Element = typename GV::template Codim<0>::Entity;
528
529 using IntersectionMapper = typename Traits::IntersectionMapper;
530 using ConnectivityMap = typename Traits::template ConnectivityMap<ThisType>;
531
532 static constexpr auto dim = Traits::StaticInfo::dim;
533 static constexpr auto numScvsPerElement = Traits::StaticInfo::numScvsPerElement;
534 static constexpr auto numLateralScvfsPerScv = Traits::StaticInfo::numLateralScvfsPerScv;
535 static constexpr auto numLateralScvfsPerElement = Traits::StaticInfo::numLateralScvfsPerElement;
536 static constexpr auto minNumScvfsPerElement = Traits::StaticInfo::minNumScvfsPerElement;
537 static constexpr auto maxNumScvfsPerElement = Traits::StaticInfo::maxNumScvfsPerElement;
538
539 public:
540 //! export the discretization method this geometry belongs to
541 using DiscretizationMethod = DiscretizationMethods::FCStaggered;
542 static constexpr DiscretizationMethod discMethod{};
543
544 static constexpr bool cachingEnabled = false;
545
546 //! export basic grid geometry type for the alternative constructor
547 using BasicGridGeometry = BasicGridGeometry_t<GV, Traits>;
548 //! export the type of the fv element geometry (the local view type)
549 using LocalView = typename Traits::template LocalView<ThisType, false>;
550 //! export the type of sub control volume
551 using SubControlVolume = typename Traits::SubControlVolume;
552 //! export the type of sub control volume
553 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
554 //! export the grid view type
555 using GridView = GV;
556 //! export the geometry helper type
557 using GeometryHelper = typename Traits::GeometryHelper;
558 //! export the local intersection mapper
559 using LocalIntersectionMapper = typename Traits::LocalIntersectionMapper;
560 //! export static information
561 using StaticInformation = typename Traits::StaticInfo;
562 //! export the type of extrusion
563 using Extrusion = Extrusion_t<Traits>;
564
565 //! Constructor with basic grid geometry used to share state with another grid geometry on the same grid view
566 4 FaceCenteredStaggeredFVGridGeometry(std::shared_ptr<BasicGridGeometry> gg, const std::string& paramGroup = "")
567 4 : ParentType(std::move(gg))
568
10/25
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 1 times.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
24 , intersectionMapper_(this->gridView())
569 {
570 // Check if the overlap size is what we expect
571
1/5
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8 if (!CheckOverlapSize<DiscretizationMethod>::isValid(this->gridView()))
572 DUNE_THROW(Dune::InvalidStateException, "The staggered discretization method needs at least an overlap of 1 for parallel computations. "
573 << " Set the parameter \"Grid.Overlap\" in the input file.");
574
575
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 update_();
576 4 }
577
578 //! Constructor from gridView
579 1 FaceCenteredStaggeredFVGridGeometry(const GridView& gridView, const std::string& paramGroup = "")
580
2/6
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 : FaceCenteredStaggeredFVGridGeometry(std::make_shared<BasicGridGeometry>(gridView), paramGroup)
581 1 {}
582
583 //! The total number of sub control volumes
584 std::size_t numScv() const
585 { return numScvs_; }
586
587 //! The total number of sub control volume faces
588 std::size_t numScvf() const
589 { return numScvf_; }
590
591 //! The total number of boundary sub control volumes
592 std::size_t numBoundaryScv() const
593 { return numBoundaryScv_; }
594
595 //! The total number of boundary sub control volume faces
596 std::size_t numBoundaryScvf() const
597 { return numBoundaryScvf_; }
598
599 //! The total number of intersections
600 std::size_t numIntersections() const
601 { return intersectionMapper_.numIntersections(); }
602
603 //! the total number of dofs
604 std::size_t numDofs() const
605
13/23
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 3 times.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 3 times.
✓ Branch 32 taken 1 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 3 times.
✓ Branch 35 taken 1 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 3 times.
✓ Branch 38 taken 1 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 3 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 3 times.
✗ Branch 44 not taken.
66 { return this->gridView().size(1); }
606
607 /*!
608 * \brief Returns the connectivity map of which dofs have derivatives with respect
609 * to a given dof.
610 */
611 const ConnectivityMap& connectivityMap() const
612 248292 { return connectivityMap_; }
613
614 //! Returns whether one of the geometry's scvfs lies on a boundary
615 bool hasBoundaryScvf(GridIndexType eIdx) const
616 124144 { return hasBoundaryScvf_[eIdx]; }
617
618 //! Return a reference to the intersection mapper
619 const IntersectionMapper& intersectionMapper() const
620
2/4
✓ Branch 1 taken 839328 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 68160 times.
✗ Branch 5 not taken.
8256188 { return intersectionMapper_; }
621
622 //! Get the global sub control volume face indices of an element
623 const std::vector<GridIndexType>& scvfIndicesOfElement(GridIndexType eIdx) const
624 132838984 { return scvfIndicesOfElement_[eIdx]; }
625
626 //! Get the global sub control volume face indices of an element
627 GridIndexType outsideVolVarIndex(GridIndexType scvfIdx) const
628 422900 { return outsideVolVarIndices_.at(scvfIdx); }
629
630 //! update all fvElementGeometries (call this after grid adaption)
631 void update(const GridView& gridView)
632 {
633 ParentType::update(gridView);
634 update_();
635 }
636
637 //! update all fvElementGeometries (call this after grid adaption)
638 void update(GridView&& gridView)
639 {
640 ParentType::update(std::move(gridView));
641 update_();
642 }
643
644 //! If a d.o.f. is on a periodic boundary
645 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
646 { return periodicFaceMap_.count(dofIdx); }
647
648 //! The index of the d.o.f. on the other side of the periodic boundary
649 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
650 { return periodicFaceMap_.at(dofIdx); }
651
652 //! Returns the map between dofs across periodic boundaries
653 const std::unordered_map<GridIndexType, GridIndexType>& periodicDofMap() const
654 28 { return periodicFaceMap_; }
655
656 //! Returns the map between dofs across periodic boundaries
657 [[deprecated("Will be removed after release 3.9. Use periodicDofMap() instead.")]]
658 const std::unordered_map<GridIndexType, GridIndexType>& periodicVertexMap() const
659 { return periodicDofMap(); }
660
661 private:
662
663 4 void update_()
664 {
665
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
8 intersectionMapper_.update(this->gridView());
666
667 // clear local data
668 4 numScvf_ = 0;
669 4 numBoundaryScv_ = 0;
670 4 numBoundaryScvf_ = 0;
671 4 hasBoundaryScvf_.clear();
672 4 scvfIndicesOfElement_.clear();
673 4 outsideVolVarIndices_.clear();
674
675 // determine size of containers
676 8 const auto numElements = this->gridView().size(0);
677 4 scvfIndicesOfElement_.resize(numElements);
678 4 hasBoundaryScvf_.resize(numElements, false);
679 4 numScvs_ = numElements*numScvsPerElement;
680
681 8 GeometryHelper geometryHelper(this->gridView());
682
683 // get the global scv indices first
684 4 GridIndexType scvfIdx = 0;
685
686 4 GridIndexType neighborVolVarIdx = numScvs_;
687
688
9/13
✓ Branch 2 taken 1251 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1768 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 1768 times.
✓ Branch 11 taken 3 times.
✓ Branch 13 taken 1768 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1768 times.
✗ Branch 17 not taken.
4276 for (const auto& element : elements(this->gridView()))
689 {
690
2/4
✓ Branch 1 taken 1768 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1768 times.
✗ Branch 5 not taken.
6036 const auto eIdx = this->elementMapper().index(element);
691
2/4
✓ Branch 1 taken 1768 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1768 times.
3018 assert(numScvsPerElement == element.subEntities(1));
692
693 // the element-wise index sets for finite volume geometry
694
1/2
✓ Branch 1 taken 1768 times.
✗ Branch 2 not taken.
3018 auto& globalScvfIndices = scvfIndicesOfElement_[eIdx];
695
1/2
✓ Branch 1 taken 1768 times.
✗ Branch 2 not taken.
3018 globalScvfIndices.reserve(maxNumScvfsPerElement);
696
1/2
✓ Branch 1 taken 1768 times.
✗ Branch 2 not taken.
3018 globalScvfIndices.resize(minNumScvfsPerElement);
697
698 // keep track of frontal boundary scvfs
699 3018 std::size_t numFrontalBoundaryScvfs = 0;
700
701 using LocalIntersectionIndexMapper = FaceCenteredStaggeredLocalIntersectionIndexMapper<GridView>;
702 1768 LocalIntersectionIndexMapper localIsMapper;
703
2/4
✓ Branch 1 taken 1768 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1768 times.
✗ Branch 5 not taken.
4786 localIsMapper.update(this->gridView(), element);
704
705
7/15
✓ Branch 1 taken 1768 times.
✓ Branch 2 taken 1250 times.
✓ Branch 3 taken 5000 times.
✓ Branch 4 taken 1768 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 8840 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 13 taken 7072 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 7072 times.
✗ Branch 17 not taken.
26948 for (const auto& intersection : intersections(this->gridView(), element))
706 {
707
2/4
✓ Branch 1 taken 7072 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7072 times.
✗ Branch 5 not taken.
12072 const auto localScvIdx = localIsMapper.realToRefIdx(intersection.indexInInside());
708 12072 auto localScvfIdx = localScvIdx*(1 + numLateralScvfsPerScv);
709
710
3/6
✓ Branch 1 taken 7072 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7072 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 7072 times.
19144 assert(localIsMapper.refToRealIdx(localScvIdx) == intersection.indexInInside());
711 // the frontal sub control volume face at the element center
712 12072 globalScvfIndices[localScvfIdx] = scvfIdx++;
713 12072 ++localScvfIdx;
714
715 if constexpr(dim > 1)
716 {
717 // the lateral sub control volume faces
718
3/4
✓ Branch 0 taken 24144 times.
✓ Branch 1 taken 12072 times.
✓ Branch 3 taken 14144 times.
✗ Branch 4 not taken.
84504 for (const auto lateralFacetIndex : Dune::transformedRangeView(geometryHelper.localLaterFaceIndices(localScvIdx),
719
2/4
✓ Branch 1 taken 14144 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14144 times.
✗ Branch 5 not taken.
38288 [&](auto idx) { return localIsMapper.refToRealIdx(idx) ;})
720 )
721 {
722
4/4
✓ Branch 1 taken 14444 times.
✓ Branch 2 taken 9700 times.
✓ Branch 5 taken 512 times.
✓ Branch 6 taken 13632 times.
24144 if (onDomainBoundary_(geometryHelper.intersection(lateralFacetIndex, element)))
723 {
724
1/2
✓ Branch 1 taken 512 times.
✗ Branch 2 not taken.
812 outsideVolVarIndices_[scvfIdx] = neighborVolVarIdx++;
725 812 ++numBoundaryScvf_;
726 2436 hasBoundaryScvf_[eIdx] = true;
727 }
728
729 24144 globalScvfIndices[localScvfIdx] = scvfIdx++;
730 24144 ++localScvfIdx;
731 }
732 }
733
734 // handle physical domain boundary
735
3/3
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 5106 times.
✓ Branch 2 taken 6816 times.
12072 if (onDomainBoundary_(intersection))
736 {
737 406 ++numBoundaryScv_; // frontal face
738 406 numBoundaryScv_ += numLateralScvfsPerScv; // boundary scvs for lateral faces
739 406 ++numFrontalBoundaryScvfs;
740 406 ++numBoundaryScvf_;
741 1218 hasBoundaryScvf_[eIdx] = true;
742 }
743
744 // handle periodic boundaries
745
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 5000 times.
✓ Branch 2 taken 7072 times.
12072 if (onPeriodicBoundary_(intersection))
746 {
747 this->setPeriodic();
748
749 const auto& otherElement = intersection.outside();
750
751 SmallLocalIndexType otherIntersectionLocalIdx = 0;
752 bool periodicFaceFound = false;
753
754 for (const auto& otherIntersection : intersections(this->gridView(), otherElement))
755 {
756 if (periodicFaceFound)
757 continue;
758
759 if (Dune::FloatCmp::eq(intersection.centerUnitOuterNormal()*otherIntersection.centerUnitOuterNormal(), -1.0, 1e-7))
760 {
761 const auto periodicDofIdx = intersectionMapper().globalIntersectionIndex(otherElement, otherIntersectionLocalIdx);
762 const auto dofIndex = intersectionMapper().globalIntersectionIndex(element, localScvIdx);
763 periodicFaceMap_[dofIndex] = periodicDofIdx;
764 periodicFaceFound = true;
765 }
766
767 ++otherIntersectionLocalIdx;
768 }
769 }
770 }
771
772 // add global indices of frontal boundary scvfs last
773
2/2
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 3018 times.
3424 for (std::size_t i = 0; i < numFrontalBoundaryScvfs; ++i)
774
1/2
✓ Branch 1 taken 256 times.
✗ Branch 2 not taken.
406 globalScvfIndices.push_back(scvfIdx++);
775 }
776
777 // set number of subcontrolvolume faces
778 4 numScvf_ = scvfIdx;
779
780 4 connectivityMap_.update(*this);
781 4 }
782
783 15000 bool onDomainBoundary_(const typename GridView::Intersection& intersection) const
784 {
785
3/6
✓ Branch 0 taken 14775 times.
✓ Branch 1 taken 225 times.
✓ Branch 2 taken 450 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15225 return !intersection.neighbor() && intersection.boundary();
786 }
787
788 bool onProcessorBoundary_(const typename GridView::Intersection& intersection) const
789 {
790 return !intersection.neighbor() && !intersection.boundary();
791 }
792
793 5000 bool onPeriodicBoundary_(const typename GridView::Intersection& intersection) const
794 {
795
3/6
✓ Branch 0 taken 5000 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 75 times.
✓ Branch 3 taken 75 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
5150 return intersection.boundary() && intersection.neighbor();
796 }
797
798 // mappers
799 ConnectivityMap connectivityMap_;
800 IntersectionMapper intersectionMapper_;
801
802 //! Information on the global number of geometries
803 std::size_t numScvs_;
804 std::size_t numScvf_;
805 std::size_t numBoundaryScv_;
806 std::size_t numBoundaryScvf_;
807 std::vector<bool> hasBoundaryScvf_;
808
809 std::vector<std::vector<GridIndexType>> scvfIndicesOfElement_;
810
811 // a map for periodic boundary vertices
812 std::unordered_map<GridIndexType, GridIndexType> periodicFaceMap_;
813 std::unordered_map<GridIndexType, GridIndexType> outsideVolVarIndices_;
814 };
815
816 } // end namespace Dumux
817
818 #endif
819