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 |