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 PQ1BubbleDiscretization | ||
10 | * \brief Base class for the local finite volume geometry for the pq1bubble method | ||
11 | * This builds up the sub control volumes and sub control volume faces | ||
12 | * for an element. | ||
13 | */ | ||
14 | #ifndef DUMUX_DISCRETIZATION_PQ1BUBBLE_FV_ELEMENT_GEOMETRY_HH | ||
15 | #define DUMUX_DISCRETIZATION_PQ1BUBBLE_FV_ELEMENT_GEOMETRY_HH | ||
16 | |||
17 | #include <optional> | ||
18 | #include <utility> | ||
19 | |||
20 | #include <dune/common/exceptions.hh> | ||
21 | #include <dune/geometry/type.hh> | ||
22 | #include <dune/localfunctions/lagrange/pqkfactory.hh> | ||
23 | |||
24 | #include <dumux/common/indextraits.hh> | ||
25 | #include <dumux/discretization/scvandscvfiterators.hh> | ||
26 | |||
27 | #include <dumux/discretization/pq1bubble/geometryhelper.hh> | ||
28 | |||
29 | namespace Dumux { | ||
30 | |||
31 | /*! | ||
32 | * \ingroup PQ1BubbleDiscretization | ||
33 | * \brief Base class for the finite volume geometry vector for pq1bubble models | ||
34 | * This builds up the sub control volumes and sub control volume faces | ||
35 | * for each element. | ||
36 | * \tparam GG the finite volume grid geometry type | ||
37 | * \tparam enableGridGeometryCache if the grid geometry is cached or not | ||
38 | */ | ||
39 | template<class GG, bool enableGridGeometryCache> | ||
40 | class PQ1BubbleFVElementGeometry; | ||
41 | |||
42 | //! specialization in case the FVElementGeometries are stored | ||
43 | template<class GG> | ||
44 |
19/50✗ Branch 0 not taken.
✓ Branch 1 taken 52500 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4801 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 4800 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 19200 times.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 14400 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 7200 times.
✓ Branch 25 taken 14400 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 21600 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 7200 times.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 4 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 21600 times.
✗ Branch 37 not taken.
✓ Branch 39 taken 21600 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 21600 times.
✗ Branch 42 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✓ Branch 48 taken 1 times.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
|
258934 | class PQ1BubbleFVElementGeometry<GG, true> |
45 | { | ||
46 | using GridView = typename GG::GridView; | ||
47 | static constexpr int dim = GridView::dimension; | ||
48 | static constexpr int dimWorld = GridView::dimensionworld; | ||
49 | using GridIndexType = typename IndexTraits<GridView>::GridIndex; | ||
50 | using LocalIndexType = typename IndexTraits<GridView>::LocalIndex; | ||
51 | using CoordScalar = typename GridView::ctype; | ||
52 | using FeLocalBasis = typename GG::FeCache::FiniteElementType::Traits::LocalBasisType; | ||
53 | using GGCache = typename GG::Cache; | ||
54 | using GeometryHelper = typename GGCache::GeometryHelper; | ||
55 | public: | ||
56 | //! export the element type | ||
57 | using Element = typename GridView::template Codim<0>::Entity; | ||
58 | //! export type of subcontrol volume | ||
59 | using SubControlVolume = typename GG::SubControlVolume; | ||
60 | //! export type of subcontrol volume face | ||
61 | using SubControlVolumeFace = typename GG::SubControlVolumeFace; | ||
62 | //! export type of finite volume grid geometry | ||
63 | using GridGeometry = GG; | ||
64 | //! the maximum number of scvs per element (2^dim for cubes) | ||
65 | // ToDo get this from GG | ||
66 | static constexpr std::size_t maxNumElementScvs = (1<<dim) + 1; | ||
67 | |||
68 | //! Constructor | ||
69 | PQ1BubbleFVElementGeometry(const GGCache& ggCache) | ||
70 |
22/30✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 42002 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 6 times.
✓ Branch 10 taken 42002 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 6 times.
✓ Branch 13 taken 903 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 4801 times.
✓ Branch 16 taken 903 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 4801 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 21600 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 24 taken 21600 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 1 times.
✓ Branch 27 taken 21604 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 21604 times.
✗ Branch 31 not taken.
|
1450334 | : ggCache_(&ggCache) |
71 | {} | ||
72 | |||
73 | //! Get a sub control volume with a local scv index | ||
74 | ✗ | const SubControlVolume& scv(LocalIndexType scvIdx) const | |
75 | { | ||
76 |
18/24✓ Branch 3 taken 64230 times.
✓ Branch 4 taken 223914 times.
✓ Branch 5 taken 64230 times.
✓ Branch 6 taken 223914 times.
✓ Branch 7 taken 64230 times.
✓ Branch 8 taken 223914 times.
✓ Branch 9 taken 7400 times.
✓ Branch 10 taken 7400 times.
✓ Branch 11 taken 7400 times.
✓ Branch 12 taken 7400 times.
✓ Branch 13 taken 7400 times.
✓ Branch 14 taken 7400 times.
✓ Branch 15 taken 14800 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 14800 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 14800 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 14800 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 14800 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 14800 times.
✗ Branch 26 not taken.
|
207694584 | return ggCache_->scvs(eIdx_)[scvIdx]; |
77 | } | ||
78 | |||
79 | //! Get a sub control volume face with a local scvf index | ||
80 | const SubControlVolumeFace& scvf(LocalIndexType scvfIdx) const | ||
81 | { | ||
82 | return ggCache_->scvfs(eIdx_)[scvfIdx]; | ||
83 | } | ||
84 | |||
85 | //! iterator range for sub control volumes. Iterates over | ||
86 | //! all scvs of the bound element. | ||
87 | //! This is a free function found by means of ADL | ||
88 | //! To iterate over all sub control volumes of this FVElementGeometry use | ||
89 | //! for (auto&& scv : scvs(fvGeometry)) | ||
90 | friend inline Dune::IteratorRange<typename std::vector<SubControlVolume>::const_iterator> | ||
91 | ✗ | scvs(const PQ1BubbleFVElementGeometry& fvGeometry) | |
92 | { | ||
93 | using Iter = typename std::vector<SubControlVolume>::const_iterator; | ||
94 | 86974710 | const auto& s = fvGeometry.ggCache_->scvs(fvGeometry.eIdx_); | |
95 | 260924130 | return Dune::IteratorRange<Iter>(s.begin(), s.end()); | |
96 | } | ||
97 | |||
98 | //! iterator range for sub control volumes faces. Iterates over | ||
99 | //! all scvfs of the bound element. | ||
100 | //! This is a free function found by means of ADL | ||
101 | //! To iterate over all sub control volume faces of this FVElementGeometry use | ||
102 | //! for (auto&& scvf : scvfs(fvGeometry)) | ||
103 | friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator> | ||
104 | ✗ | scvfs(const PQ1BubbleFVElementGeometry& fvGeometry) | |
105 | { | ||
106 | using Iter = typename std::vector<SubControlVolumeFace>::const_iterator; | ||
107 | 5008336 | const auto& s = fvGeometry.ggCache_->scvfs(fvGeometry.eIdx_); | |
108 | 15025008 | return Dune::IteratorRange<Iter>(s.begin(), s.end()); | |
109 | } | ||
110 | |||
111 | //! Get a local finite element basis | ||
112 | 16958474 | const FeLocalBasis& feLocalBasis() const | |
113 | { | ||
114 | 35053148 | return gridGeometry().feCache().get(element_->type()).localBasis(); | |
115 | } | ||
116 | |||
117 | //! The total number of sub control volumes | ||
118 | ✗ | std::size_t numScv() const | |
119 | { | ||
120 |
12/17✓ Branch 0 taken 5 times.
✓ Branch 1 taken 826887 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 826887 times.
✓ Branch 5 taken 32640 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 32640 times.
✓ Branch 9 taken 43720 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 14400 times.
✓ Branch 12 taken 43720 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 14400 times.
✓ Branch 15 taken 21600 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 21600 times.
✗ Branch 19 not taken.
|
16107900 | return ggCache_->scvs(eIdx_).size(); |
121 | } | ||
122 | |||
123 | //! The total number of sub control volume faces | ||
124 | ✗ | std::size_t numScvf() const | |
125 | { | ||
126 |
2/10✗ Branch 0 not taken.
✓ Branch 1 taken 12000 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12000 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
231824 | return ggCache_->scvfs(eIdx_).size(); |
127 | } | ||
128 | |||
129 | /*! | ||
130 | * \brief bind the local view (r-value overload) | ||
131 | * This overload is called when an instance of this class is a temporary in the usage context | ||
132 | * This allows a usage like this: `const auto view = localView(...).bind(element);` | ||
133 | */ | ||
134 | PQ1BubbleFVElementGeometry bind(const Element& element) && | ||
135 | { | ||
136 |
1/2✓ Branch 1 taken 12000 times.
✗ Branch 2 not taken.
|
73012 | this->bindElement(element); |
137 |
1/2✓ Branch 0 taken 61012 times.
✗ Branch 1 not taken.
|
134024 | return std::move(*this); |
138 | } | ||
139 | |||
140 | //! this function is for compatibility reasons with cc methods | ||
141 | //! The pq1bubble stencil is always element-local so bind and bindElement | ||
142 | //! are identical. | ||
143 | void bind(const Element& element) & | ||
144 |
1/6✗ Branch 1 not taken.
✓ Branch 2 taken 14012 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
592315 | { this->bindElement(element); } |
145 | |||
146 | /*! | ||
147 | * \brief bind the local view (r-value overload) | ||
148 | * This overload is called when an instance of this class is a temporary in the usage context | ||
149 | * This allows a usage like this: `const auto view = localView(...).bindElement(element);` | ||
150 | */ | ||
151 | PQ1BubbleFVElementGeometry bindElement(const Element& element) && | ||
152 | { | ||
153 |
1/2✓ Branch 1 taken 36000 times.
✗ Branch 2 not taken.
|
561228 | this->bindElement(element); |
154 | 1086456 | return std::move(*this); | |
155 | } | ||
156 | |||
157 | //! Binding of an element, has to be called before using the fvgeometries | ||
158 | //! Prepares all the volume variables within the element | ||
159 | //! For compatibility reasons with the FVGeometry cache being disabled | ||
160 | 2157507 | void bindElement(const Element& element) & | |
161 | { | ||
162 |
2/2✓ Branch 0 taken 905736 times.
✓ Branch 1 taken 1117371 times.
|
2157507 | element_ = element; |
163 | // cache element index | ||
164 | 2157507 | eIdx_ = gridGeometry().elementMapper().index(element); | |
165 | 2157507 | } | |
166 | |||
167 | //! Returns true if bind/bindElement has already been called | ||
168 | bool isBound() const | ||
169 |
2/4✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
1282 | { return static_cast<bool>(element_); } |
170 | |||
171 | //! The bound element | ||
172 | const Element& element() const | ||
173 | 190819202 | { return *element_; } | |
174 | |||
175 | //! The grid geometry we are a restriction of | ||
176 | ✗ | const GridGeometry& gridGeometry() const | |
177 |
10/12✓ Branch 1 taken 570 times.
✓ Branch 2 taken 35022 times.
✓ Branch 3 taken 265576 times.
✓ Branch 4 taken 93118 times.
✓ Branch 5 taken 1950414 times.
✓ Branch 14 taken 4800 times.
✓ Branch 15 taken 7200 times.
✓ Branch 16 taken 4412 times.
✓ Branch 17 taken 9600 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 4412 times.
✗ Branch 20 not taken.
|
22566569 | { return ggCache_->gridGeometry(); } |
178 | |||
179 | //! Returns whether one of the geometry's scvfs lies on a boundary | ||
180 | ✗ | bool hasBoundaryScvf() const | |
181 |
4/8✓ Branch 0 taken 1362 times.
✓ Branch 1 taken 41413 times.
✓ Branch 2 taken 1362 times.
✓ Branch 3 taken 41413 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
85550 | { return ggCache_->hasBoundaryScvf(eIdx_); } |
182 | |||
183 | //! The bound element index | ||
184 | ✗ | std::size_t elementIndex() const | |
185 | 1613392 | { return eIdx_; } | |
186 | |||
187 | //! Geometry of a sub control volume | ||
188 | 8 | typename SubControlVolume::Traits::Geometry geometry(const SubControlVolume& scv) const | |
189 | { | ||
190 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (scv.isOverlapping()) |
191 | ✗ | DUNE_THROW(Dune::NotImplemented, "Geometry of overlapping scv"); | |
192 | |||
193 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
16 | assert(isBound()); |
194 | 16 | const auto geo = element().geometry(); | |
195 | 8 | const GeometryHelper helper(geo); | |
196 | return { | ||
197 | helper.getScvGeometryType(scv.indexInElement()), | ||
198 | helper.getScvCorners(scv.indexInElement()) | ||
199 | 8 | }; | |
200 | } | ||
201 | |||
202 | //! Geometry of a sub control volume face | ||
203 | 684 | typename SubControlVolumeFace::Traits::Geometry geometry(const SubControlVolumeFace& scvf) const | |
204 | { | ||
205 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 684 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 684 times.
|
1368 | assert(isBound()); |
206 |
2/4✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
|
1368 | const auto geo = element().geometry(); |
207 |
2/2✓ Branch 0 taken 664 times.
✓ Branch 1 taken 20 times.
|
684 | if (scvf.boundary()) |
208 | { | ||
209 | 664 | GeometryHelper helper(geo); | |
210 | 664 | const auto localScvfIdx = scvf.index() - helper.numInteriorScvf(); | |
211 | 664 | const auto [localFacetIndex, isScvfLocalIdx] | |
212 | 664 | = ggCache_->scvfBoundaryGeometryKeys(eIdx_)[localScvfIdx]; | |
213 | return { | ||
214 | helper.getBoundaryScvfGeometryType(isScvfLocalIdx), | ||
215 | helper.getBoundaryScvfCorners(localFacetIndex, isScvfLocalIdx) | ||
216 | 664 | }; | |
217 | } | ||
218 | else | ||
219 | { | ||
220 | 20 | GeometryHelper helper(geo); | |
221 | return { | ||
222 | helper.getInteriorScvfGeometryType(scvf.index()), | ||
223 | helper.getScvfCorners(scvf.index()) | ||
224 | 40 | }; | |
225 | } | ||
226 | } | ||
227 | |||
228 | private: | ||
229 | const GGCache* ggCache_; | ||
230 | GridIndexType eIdx_; | ||
231 | |||
232 | std::optional<Element> element_; | ||
233 | }; | ||
234 | |||
235 | } // end namespace Dumux | ||
236 | |||
237 | #endif | ||
238 |