Line | Branch | Exec | Source |
---|---|---|---|
1 | // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- | ||
2 | // vi: set et ts=4 sw=4 sts=4: | ||
3 | // | ||
4 | // SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder | ||
5 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
6 | // | ||
7 | /*! | ||
8 | * \file | ||
9 | * \ingroup BoxDiscretization | ||
10 | * \brief Base class for the finite volume geometry vector for box models | ||
11 | * This builds up the sub control volumes and sub control volume faces | ||
12 | * for each element of the grid partition. | ||
13 | */ | ||
14 | #ifndef DUMUX_DISCRETIZATION_BOX_GRID_FVGEOMETRY_HH | ||
15 | #define DUMUX_DISCRETIZATION_BOX_GRID_FVGEOMETRY_HH | ||
16 | |||
17 | #include <utility> | ||
18 | #include <unordered_map> | ||
19 | #include <array> | ||
20 | #include <vector> | ||
21 | |||
22 | #include <dune/localfunctions/lagrange/lagrangelfecache.hh> | ||
23 | |||
24 | #include <dumux/discretization/method.hh> | ||
25 | #include <dumux/common/indextraits.hh> | ||
26 | #include <dumux/common/defaultmappertraits.hh> | ||
27 | #include <dumux/discretization/basegridgeometry.hh> | ||
28 | #include <dumux/discretization/box/boxgeometryhelper.hh> | ||
29 | #include <dumux/discretization/box/fvelementgeometry.hh> | ||
30 | #include <dumux/discretization/box/subcontrolvolume.hh> | ||
31 | #include <dumux/discretization/box/subcontrolvolumeface.hh> | ||
32 | #include <dumux/discretization/extrusion.hh> | ||
33 | |||
34 | #include <dumux/io/grid/periodicgridtraits.hh> | ||
35 | |||
36 | namespace Dumux { | ||
37 | |||
38 | namespace Detail { | ||
39 | template<class GV, class T> | ||
40 | using BoxGeometryHelper_t = Dune::Std::detected_or_t< | ||
41 | Dumux::BoxGeometryHelper<GV, GV::dimension, typename T::SubControlVolume, typename T::SubControlVolumeFace>, | ||
42 | SpecifiesGeometryHelper, | ||
43 | T | ||
44 | >; | ||
45 | } // end namespace Detail | ||
46 | |||
47 | /*! | ||
48 | * \ingroup BoxDiscretization | ||
49 | * \brief The default traits for the box finite volume grid geometry | ||
50 | * Defines the scv and scvf types and the mapper types | ||
51 | * \tparam the grid view type | ||
52 | */ | ||
53 | template<class GridView, class MapperTraits = DefaultMapperTraits<GridView>> | ||
54 | struct BoxDefaultGridGeometryTraits | ||
55 | : public MapperTraits | ||
56 | { | ||
57 | using SubControlVolume = BoxSubControlVolume<GridView>; | ||
58 | using SubControlVolumeFace = BoxSubControlVolumeFace<GridView>; | ||
59 | |||
60 | template<class GridGeometry, bool enableCache> | ||
61 | using LocalView = BoxFVElementGeometry<GridGeometry, enableCache>; | ||
62 | }; | ||
63 | |||
64 | /*! | ||
65 | * \ingroup BoxDiscretization | ||
66 | * \brief Base class for the finite volume geometry vector for box schemes | ||
67 | * This builds up the sub control volumes and sub control volume faces | ||
68 | * \note This class is specialized for versions with and without caching the fv geometries on the grid view | ||
69 | */ | ||
70 | template<class Scalar, | ||
71 | class GridView, | ||
72 | bool enableGridGeometryCache = false, | ||
73 | class Traits = BoxDefaultGridGeometryTraits<GridView> > | ||
74 | class BoxFVGridGeometry; | ||
75 | |||
76 | /*! | ||
77 | * \ingroup BoxDiscretization | ||
78 | * \brief Base class for the finite volume geometry vector for box schemes | ||
79 | * This builds up the sub control volumes and sub control volume faces | ||
80 | * \note For caching enabled we store the fv geometries for the whole grid view which is memory intensive but faster | ||
81 | */ | ||
82 | template<class Scalar, class GV, class Traits> | ||
83 | class BoxFVGridGeometry<Scalar, GV, true, Traits> | ||
84 | : public BaseGridGeometry<GV, Traits> | ||
85 | { | ||
86 | using ThisType = BoxFVGridGeometry<Scalar, GV, true, Traits>; | ||
87 | using ParentType = BaseGridGeometry<GV, Traits>; | ||
88 | using GridIndexType = typename IndexTraits<GV>::GridIndex; | ||
89 | using LocalIndexType = typename IndexTraits<GV>::LocalIndex; | ||
90 | |||
91 | using Element = typename GV::template Codim<0>::Entity; | ||
92 | using CoordScalar = typename GV::ctype; | ||
93 | static const int dim = GV::dimension; | ||
94 | static const int dimWorld = GV::dimensionworld; | ||
95 | |||
96 | public: | ||
97 | //! export the discretization method this geometry belongs to | ||
98 | using DiscretizationMethod = DiscretizationMethods::Box; | ||
99 | static constexpr DiscretizationMethod discMethod{}; | ||
100 | |||
101 | //! export basic grid geometry type for the alternative constructor | ||
102 | using BasicGridGeometry = BasicGridGeometry_t<GV, Traits>; | ||
103 | //! export the type of the fv element geometry (the local view type) | ||
104 | using LocalView = typename Traits::template LocalView<ThisType, true>; | ||
105 | //! export the type of sub control volume | ||
106 | using SubControlVolume = typename Traits::SubControlVolume; | ||
107 | //! export the type of sub control volume | ||
108 | using SubControlVolumeFace = typename Traits::SubControlVolumeFace; | ||
109 | //! export the type of extrusion | ||
110 | using Extrusion = Extrusion_t<Traits>; | ||
111 | //! export dof mapper type | ||
112 | using DofMapper = typename Traits::VertexMapper; | ||
113 | //! export the finite element cache type | ||
114 | using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>; | ||
115 | //! export the grid view type | ||
116 | using GridView = GV; | ||
117 | //! export whether the grid(geometry) supports periodicity | ||
118 | using SupportsPeriodicity = typename PeriodicGridTraits<typename GV::Grid>::SupportsPeriodicity; | ||
119 | |||
120 | //! Constructor with basic grid geometry used to share state with another grid geometry on the same grid view | ||
121 | 59 | BoxFVGridGeometry(std::shared_ptr<BasicGridGeometry> gg) | |
122 | : ParentType(std::move(gg)) | ||
123 | 59 | , cache_(*this) | |
124 |
3/6✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 52 times.
✓ Branch 6 taken 52 times.
✗ Branch 7 not taken.
|
59 | , periodicGridTraits_(this->gridView().grid()) |
125 | { | ||
126 |
1/2✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
|
59 | update_(); |
127 | 59 | } | |
128 | |||
129 | //! Constructor | ||
130 | 57 | BoxFVGridGeometry(const GridView& gridView) | |
131 |
1/2✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
|
57 | : BoxFVGridGeometry(std::make_shared<BasicGridGeometry>(gridView)) |
132 | 57 | {} | |
133 | |||
134 | //! the vertex mapper is the dofMapper | ||
135 | //! this is convenience to have better chance to have the same main files for box/tpfa/mpfa... | ||
136 | 109126110 | const DofMapper& dofMapper() const | |
137 |
8/18✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 711 times.
✓ Branch 3 taken 5 times.
✓ Branch 5 taken 4377 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 5 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 2 times.
✓ Branch 16 taken 9 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 14 taken 15 times.
✗ Branch 17 not taken.
|
109126120 | { return this->vertexMapper(); } |
138 | |||
139 | //! The total number of sub control volumes | ||
140 | std::size_t numScv() const | ||
141 | { return numScv_; } | ||
142 | |||
143 | //! The total number of sun control volume faces | ||
144 | std::size_t numScvf() const | ||
145 | { return numScvf_; } | ||
146 | |||
147 | //! The total number of boundary sub control volume faces | ||
148 | //! For compatibility reasons with cc methods | ||
149 | 20 | std::size_t numBoundaryScvf() const | |
150 |
12/24✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 3 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 3 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
|
10 | { return numBoundaryScvf_; } |
151 | |||
152 | //! The total number of degrees of freedom | ||
153 | 318 | std::size_t numDofs() const | |
154 |
21/27✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 13 times.
✓ Branch 10 taken 4 times.
✓ Branch 11 taken 1 times.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 1 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 21 taken 1 times.
✓ Branch 22 taken 1 times.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 6 taken 12 times.
✓ Branch 9 taken 4 times.
✓ Branch 12 taken 3 times.
✓ Branch 8 taken 1 times.
✓ Branch 15 taken 2 times.
✓ Branch 18 taken 1 times.
✓ Branch 19 taken 1 times.
✓ Branch 7 taken 2 times.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
|
270 | { return this->vertexMapper().size(); } |
155 | |||
156 | |||
157 | //! update all fvElementGeometries (call this after grid adaption) | ||
158 | void update(const GridView& gridView) | ||
159 | { | ||
160 | ParentType::update(gridView); | ||
161 | update_(); | ||
162 | } | ||
163 | |||
164 | //! update all fvElementGeometries (call this after grid adaption) | ||
165 | void update(GridView&& gridView) | ||
166 | { | ||
167 | ParentType::update(std::move(gridView)); | ||
168 | update_(); | ||
169 | } | ||
170 | |||
171 | //! The finite element cache for creating local FE bases | ||
172 | 61291891 | const FeCache& feCache() const | |
173 |
7/13✓ Branch 13 taken 9920 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 9920 times.
✗ Branch 17 not taken.
✓ Branch 9 taken 22120 times.
✗ Branch 10 not taken.
✓ Branch 3 taken 28948 times.
✓ Branch 4 taken 8697 times.
✓ Branch 6 taken 56184 times.
✗ Branch 7 not taken.
✗ Branch 5 not taken.
✓ Branch 1 taken 4887560 times.
✗ Branch 2 not taken.
|
61291891 | { return feCache_; } |
174 | |||
175 | //! If a vertex / d.o.f. is on the boundary | ||
176 | 22491761 | bool dofOnBoundary(GridIndexType dofIdx) const | |
177 |
6/6✓ Branch 0 taken 2364666 times.
✓ Branch 1 taken 19698976 times.
✓ Branch 2 taken 159134 times.
✓ Branch 3 taken 127962 times.
✓ Branch 4 taken 48808 times.
✓ Branch 5 taken 92215 times.
|
22491761 | { return boundaryDofIndices_[dofIdx]; } |
178 | |||
179 | //! If a vertex / d.o.f. is on a periodic boundary | ||
180 | 358583 | bool dofOnPeriodicBoundary(GridIndexType dofIdx) const | |
181 |
0/7✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 5 not taken.
|
717166 | { return periodicDofMap_.count(dofIdx); } |
182 | |||
183 | //! The index of the vertex / d.o.f. on the other side of the periodic boundary | ||
184 | ✗ | GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const | |
185 | ✗ | { return periodicDofMap_.at(dofIdx); } | |
186 | |||
187 | //! Returns the map between dofs across periodic boundaries | ||
188 | const std::unordered_map<GridIndexType, GridIndexType>& periodicDofMap() const | ||
189 | 3570 | { return periodicDofMap_; } | |
190 | |||
191 | //! local view of this object (constructed with the internal cache) | ||
192 | 13178220 | friend inline LocalView localView(const BoxFVGridGeometry& gg) | |
193 |
29/45✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 711 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 32 times.
✓ Branch 8 taken 4 times.
✓ Branch 10 taken 1182336 times.
✓ Branch 11 taken 2690 times.
✓ Branch 13 taken 444393 times.
✓ Branch 14 taken 945663 times.
✓ Branch 16 taken 473 times.
✓ Branch 17 taken 673344 times.
✓ Branch 19 taken 210899 times.
✓ Branch 20 taken 23852 times.
✓ Branch 22 taken 5 times.
✓ Branch 23 taken 8 times.
✓ Branch 27 taken 2 times.
✓ Branch 28 taken 3 times.
✓ Branch 30 taken 2 times.
✗ Branch 31 not taken.
✓ Branch 33 taken 1 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 39 taken 3200 times.
✗ Branch 40 not taken.
✓ Branch 42 taken 9600 times.
✗ Branch 43 not taken.
✓ Branch 45 taken 3200 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 9600 times.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✓ Branch 51 taken 1 times.
✓ Branch 18 taken 1 times.
✓ Branch 21 taken 22 times.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 24 not taken.
✓ Branch 3 taken 926074 times.
✓ Branch 25 taken 1189858 times.
✗ Branch 26 not taken.
✗ Branch 29 not taken.
|
10911938 | { return { gg.cache_ }; } |
194 | |||
195 | private: | ||
196 | |||
197 | class BoxGridGeometryCache | ||
198 | { | ||
199 | friend class BoxFVGridGeometry; | ||
200 | public: | ||
201 | //! export the geometry helper type | ||
202 | using GeometryHelper = Detail::BoxGeometryHelper_t<GV, Traits>; | ||
203 | |||
204 | 52 | explicit BoxGridGeometryCache(const BoxFVGridGeometry& gg) | |
205 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
52 | : gridGeometry_(&gg) |
206 | {} | ||
207 | |||
208 | 67564745 | const BoxFVGridGeometry& gridGeometry() const | |
209 |
32/46✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 7 taken 9773783 times.
✓ Branch 8 taken 2565 times.
✓ Branch 10 taken 232416 times.
✓ Branch 11 taken 131816 times.
✓ Branch 13 taken 5020153 times.
✓ Branch 14 taken 8216 times.
✓ Branch 16 taken 4562888 times.
✓ Branch 17 taken 131816 times.
✓ Branch 19 taken 4366642 times.
✓ Branch 20 taken 42076 times.
✓ Branch 25 taken 1093766 times.
✓ Branch 26 taken 14000 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 10909 times.
✓ Branch 34 taken 948 times.
✓ Branch 35 taken 75820 times.
✓ Branch 36 taken 950 times.
✓ Branch 37 taken 18252 times.
✓ Branch 46 taken 9920 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 9920 times.
✗ Branch 50 not taken.
✓ Branch 53 taken 3200 times.
✗ Branch 54 not taken.
✓ Branch 56 taken 3200 times.
✗ Branch 57 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 764951 times.
✓ Branch 9 taken 62023 times.
✓ Branch 12 taken 5462 times.
✓ Branch 15 taken 213072 times.
✓ Branch 18 taken 1379696 times.
✓ Branch 23 taken 1182327 times.
✓ Branch 24 taken 48540 times.
✗ Branch 27 not taken.
✓ Branch 32 taken 1548 times.
✓ Branch 33 taken 41654 times.
✓ Branch 38 taken 22120 times.
✗ Branch 39 not taken.
✓ Branch 42 taken 7200 times.
✗ Branch 43 not taken.
✗ Branch 1 not taken.
✗ Branch 30 not taken.
|
65534613 | { return *gridGeometry_; } |
210 | |||
211 | //! Get the global sub control volume indices of an element | ||
212 | 1181662374 | const std::vector<SubControlVolume>& scvs(GridIndexType eIdx) const | |
213 |
15/20✓ Branch 2 taken 106937616 times.
✓ Branch 3 taken 71985391 times.
✓ Branch 4 taken 82909803 times.
✓ Branch 5 taken 83644311 times.
✓ Branch 10 taken 162489 times.
✓ Branch 11 taken 389438 times.
✓ Branch 13 taken 676064 times.
✓ Branch 14 taken 1189858 times.
✓ Branch 16 taken 9600 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 9600 times.
✗ Branch 20 not taken.
✓ Branch 6 taken 65421791 times.
✓ Branch 7 taken 65138583 times.
✓ Branch 1 taken 34130965 times.
✗ Branch 0 not taken.
✓ Branch 8 taken 2430 times.
✓ Branch 9 taken 4887560 times.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
|
1195717234 | { return scvs_[eIdx]; } |
214 | |||
215 | //! Get the global sub control volume face indices of an element | ||
216 | 43751818 | const std::vector<SubControlVolumeFace>& scvfs(GridIndexType eIdx) const | |
217 |
2/4✓ Branch 1 taken 21309 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3200 times.
✗ Branch 5 not taken.
|
42420359 | { return scvfs_[eIdx]; } |
218 | |||
219 | //! Returns whether one of the geometry's scvfs lies on a boundary | ||
220 | 2291779 | bool hasBoundaryScvf(GridIndexType eIdx) const | |
221 |
12/12✓ Branch 0 taken 214192 times.
✓ Branch 1 taken 1733943 times.
✓ Branch 2 taken 302372 times.
✓ Branch 3 taken 23020 times.
✓ Branch 4 taken 6778 times.
✓ Branch 5 taken 1804 times.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 28 times.
✓ Branch 8 taken 432 times.
✓ Branch 9 taken 592 times.
✓ Branch 10 taken 6778 times.
✓ Branch 11 taken 1804 times.
|
2291779 | { return hasBoundaryScvf_[eIdx]; } |
222 | |||
223 | //! Returns local mappings for constructing boundary scvf geometries | ||
224 | 73556 | const std::vector<std::array<LocalIndexType, 2>>& scvfBoundaryGeometryKeys(GridIndexType eIdx) const | |
225 |
2/4✓ Branch 5 taken 10860 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 10860 times.
✗ Branch 9 not taken.
|
73556 | { return scvfBoundaryGeometryKeys_.at(eIdx); } |
226 | |||
227 | private: | ||
228 | 59 | void clear_() | |
229 | { | ||
230 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
|
59 | scvs_.clear(); |
231 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
|
59 | scvfs_.clear(); |
232 | 59 | hasBoundaryScvf_.clear(); | |
233 | 59 | scvfBoundaryGeometryKeys_.clear(); | |
234 | 59 | } | |
235 | |||
236 | std::vector<std::vector<SubControlVolume>> scvs_; | ||
237 | std::vector<std::vector<SubControlVolumeFace>> scvfs_; | ||
238 | std::vector<bool> hasBoundaryScvf_; | ||
239 | std::unordered_map<GridIndexType, std::vector<std::array<LocalIndexType, 2>>> scvfBoundaryGeometryKeys_; | ||
240 | |||
241 | const BoxFVGridGeometry* gridGeometry_; | ||
242 | }; | ||
243 | |||
244 | public: | ||
245 | //! the cache type (only the caching implementation has this) | ||
246 | //! this alias should only be used by the local view implementation | ||
247 | using Cache = BoxGridGeometryCache; | ||
248 | |||
249 | private: | ||
250 | using GeometryHelper = typename Cache::GeometryHelper; | ||
251 | |||
252 | 59 | void update_() | |
253 | { | ||
254 | 59 | cache_.clear_(); | |
255 | |||
256 | 59 | const auto numElements = this->gridView().size(0); | |
257 | 59 | cache_.scvs_.resize(numElements); | |
258 | 59 | cache_.scvfs_.resize(numElements); | |
259 | 59 | cache_.hasBoundaryScvf_.resize(numElements, false); | |
260 | |||
261 | 59 | boundaryDofIndices_.assign(numDofs(), false); | |
262 | |||
263 | 59 | numScv_ = 0; | |
264 | 59 | numScvf_ = 0; | |
265 | 59 | numBoundaryScvf_ = 0; | |
266 | // Build the SCV and SCV faces | ||
267 |
6/9✓ Branch 1 taken 125865 times.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 41382 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 41382 times.
✓ Branch 11 taken 11 times.
|
284529 | for (const auto& element : elements(this->gridView())) |
268 | { | ||
269 | // fill the element map with seeds | ||
270 |
3/5✓ Branch 1 taken 41382 times.
✓ Branch 2 taken 7018 times.
✓ Branch 4 taken 41382 times.
✗ Branch 5 not taken.
✗ Branch 3 not taken.
|
183900 | const auto eIdx = this->elementMapper().index(element); |
271 | |||
272 | // count | ||
273 |
1/2✓ Branch 1 taken 41382 times.
✗ Branch 2 not taken.
|
183900 | numScv_ += element.subEntities(dim); |
274 |
1/2✓ Branch 1 taken 48400 times.
✗ Branch 2 not taken.
|
183900 | numScvf_ += element.subEntities(dim-1); |
275 | |||
276 | // get the element geometry | ||
277 |
1/2✓ Branch 1 taken 48400 times.
✗ Branch 2 not taken.
|
183900 | auto elementGeometry = element.geometry(); |
278 |
1/2✓ Branch 1 taken 41382 times.
✗ Branch 2 not taken.
|
183900 | const auto refElement = referenceElement(elementGeometry); |
279 | |||
280 | // instantiate the geometry helper | ||
281 | 183900 | GeometryHelper geometryHelper(elementGeometry); | |
282 | |||
283 | // construct the sub control volumes | ||
284 |
2/3✓ Branch 1 taken 41382 times.
✓ Branch 2 taken 7018 times.
✗ Branch 3 not taken.
|
183900 | cache_.scvs_[eIdx].resize(elementGeometry.corners()); |
285 |
3/3✓ Branch 1 taken 181219 times.
✓ Branch 2 taken 7018 times.
✓ Branch 0 taken 657611 times.
|
961237 | for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx) |
286 | { | ||
287 |
1/2✓ Branch 1 taken 170257 times.
✗ Branch 2 not taken.
|
777337 | const auto dofIdxGlobal = this->vertexMapper().subIndex(element, scvLocalIdx, dim); |
288 | |||
289 |
1/2✓ Branch 1 taken 149323 times.
✗ Branch 2 not taken.
|
1286324 | cache_.scvs_[eIdx][scvLocalIdx] = SubControlVolume( |
290 |
1/2✓ Branch 1 taken 20934 times.
✗ Branch 2 not taken.
|
1045687 | geometryHelper.getScvCorners(scvLocalIdx), |
291 | scvLocalIdx, | ||
292 | eIdx, | ||
293 | dofIdxGlobal | ||
294 | ); | ||
295 | } | ||
296 | |||
297 | // construct the sub control volume faces | ||
298 | 183900 | LocalIndexType scvfLocalIdx = 0; | |
299 |
2/4✓ Branch 1 taken 48400 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41382 times.
✗ Branch 5 not taken.
|
233864 | cache_.scvfs_[eIdx].resize(element.subEntities(dim-1)); |
300 |
5/5✓ Branch 0 taken 372898 times.
✓ Branch 1 taken 531508 times.
✓ Branch 2 taken 76328 times.
✓ Branch 3 taken 184373 times.
✓ Branch 4 taken 41382 times.
|
1431140 | for (; scvfLocalIdx < element.subEntities(dim-1); ++scvfLocalIdx) |
301 | { | ||
302 | // find the global and local scv indices this scvf is belonging to | ||
303 |
1/2✓ Branch 2 taken 813511 times.
✗ Branch 3 not taken.
|
1922822 | std::vector<LocalIndexType> localScvIndices({static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 0, dim)), |
304 |
1/2✓ Branch 2 taken 205347 times.
✗ Branch 3 not taken.
|
961411 | static_cast<LocalIndexType>(refElement.subEntity(scvfLocalIdx, dim-1, 1, dim))}); |
305 | |||
306 |
1/2✓ Branch 1 taken 813511 times.
✗ Branch 2 not taken.
|
961411 | const auto& corners = geometryHelper.getScvfCorners(scvfLocalIdx); |
307 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 65572 times.
|
961411 | cache_.scvfs_[eIdx][scvfLocalIdx] = SubControlVolumeFace( |
308 | corners, | ||
309 |
2/2✓ Branch 1 taken 256240 times.
✓ Branch 2 taken 65572 times.
|
1922822 | geometryHelper.normal(corners, localScvIndices), |
310 | element, | ||
311 | elementGeometry, | ||
312 | scvfLocalIdx, | ||
313 | std::move(localScvIndices), | ||
314 | false | ||
315 | ); | ||
316 | } | ||
317 | |||
318 | // construct the sub control volume faces on the domain boundary | ||
319 |
9/11✓ Branch 2 taken 291794 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 114728 times.
✓ Branch 6 taken 395695 times.
✓ Branch 7 taken 323744 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 17316 times.
✓ Branch 10 taken 230100 times.
✓ Branch 1 taken 90895 times.
✓ Branch 11 taken 638 times.
✓ Branch 12 taken 20942 times.
|
1878602 | for (const auto& intersection : intersections(this->gridView(), element)) |
320 | { | ||
321 |
4/4✓ Branch 1 taken 152548 times.
✓ Branch 2 taken 212205 times.
✓ Branch 0 taken 11661 times.
✓ Branch 3 taken 20942 times.
|
494050 | if (intersection.boundary() && !intersection.neighbor()) |
322 | { | ||
323 | 26305 | const auto isGeometry = intersection.geometry(); | |
324 | 26305 | cache_.hasBoundaryScvf_[eIdx] = true; | |
325 | |||
326 | // count | ||
327 | 26305 | numScvf_ += isGeometry.corners(); | |
328 | 26305 | numBoundaryScvf_ += isGeometry.corners(); | |
329 | |||
330 |
3/3✓ Branch 0 taken 52076 times.
✓ Branch 1 taken 29731 times.
✓ Branch 2 taken 5754 times.
|
109891 | for (unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < isGeometry.corners(); ++isScvfLocalIdx) |
331 | { | ||
332 | // find the scvs this scvf is belonging to | ||
333 |
1/3✓ Branch 1 taken 17576 times.
✗ Branch 2 not taken.
✗ Branch 0 not taken.
|
83586 | const LocalIndexType insideScvIdx = static_cast<LocalIndexType>(refElement.subEntity(intersection.indexInInside(), 1, isScvfLocalIdx, dim)); |
334 |
1/4✓ Branch 1 taken 66098 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
83586 | std::vector<LocalIndexType> localScvIndices = {insideScvIdx, insideScvIdx}; |
335 | |||
336 |
4/6✓ Branch 0 taken 17884 times.
✓ Branch 1 taken 48214 times.
✓ Branch 3 taken 32328 times.
✓ Branch 4 taken 21036 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
|
154372 | cache_.scvfs_[eIdx].emplace_back( |
337 |
2/4✓ Branch 1 taken 26228 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4078 times.
✗ Branch 5 not taken.
|
139526 | geometryHelper.getBoundaryScvfCorners(intersection.indexInInside(), isScvfLocalIdx), |
338 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 66098 times.
✗ Branch 2 not taken.
|
83586 | intersection.centerUnitOuterNormal(), |
339 | intersection, | ||
340 | isGeometry, | ||
341 | isScvfLocalIdx, | ||
342 | scvfLocalIdx, | ||
343 | std::move(localScvIndices), | ||
344 |
2/3✓ Branch 0 taken 17884 times.
✓ Branch 1 taken 48214 times.
✗ Branch 2 not taken.
|
83586 | true |
345 | ); | ||
346 | |||
347 |
3/7✓ Branch 1 taken 66098 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 66098 times.
✓ Branch 6 taken 1272 times.
✗ Branch 7 not taken.
✗ Branch 5 not taken.
|
83586 | cache_.scvfBoundaryGeometryKeys_[eIdx].emplace_back(std::array<LocalIndexType, 2>{{ |
348 |
1/2✓ Branch 1 taken 23870 times.
✗ Branch 2 not taken.
|
29300 | static_cast<LocalIndexType>(intersection.indexInInside()), |
349 | static_cast<LocalIndexType>(isScvfLocalIdx) | ||
350 | }}); | ||
351 | |||
352 | // increment local counter | ||
353 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8822 times.
|
83586 | scvfLocalIdx++; |
354 | } | ||
355 | |||
356 | // add all vertices on the intersection to the set of | ||
357 | // boundary vertices | ||
358 | 26305 | const auto fIdx = intersection.indexInInside(); | |
359 | 26305 | const auto numFaceVerts = refElement.size(fIdx, 1, dim); | |
360 |
2/2✓ Branch 1 taken 66098 times.
✓ Branch 2 taken 21463 times.
|
109891 | for (int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx) |
361 | { | ||
362 | 83586 | const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim); | |
363 |
1/2✓ Branch 1 taken 66098 times.
✗ Branch 2 not taken.
|
83586 | const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim); |
364 | 83586 | boundaryDofIndices_[vIdxGlobal] = true; | |
365 | } | ||
366 | 12833 | } | |
367 | |||
368 | // inform the grid geometry if we have periodic boundaries | ||
369 |
1/2✓ Branch 1 taken 417645 times.
✗ Branch 2 not taken.
|
715801 | else if (periodicGridTraits_.isPeriodic(intersection)) |
370 | { | ||
371 | this->setPeriodic(); | ||
372 | |||
373 | // find the mapped periodic vertex of all vertices on periodic boundaries | ||
374 | const auto fIdx = intersection.indexInInside(); | ||
375 | const auto numFaceVerts = refElement.size(fIdx, 1, dim); | ||
376 | const auto eps = 1e-7*(elementGeometry.corner(1) - elementGeometry.corner(0)).two_norm(); | ||
377 | for (int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx) | ||
378 | { | ||
379 | const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim); | ||
380 | const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim); | ||
381 | const auto vPos = elementGeometry.corner(vIdx); | ||
382 | |||
383 | const auto& outside = intersection.outside(); | ||
384 | const auto outsideGeometry = outside.geometry(); | ||
385 | for (const auto& isOutside : intersections(this->gridView(), outside)) | ||
386 | { | ||
387 | // only check periodic vertices of the periodic neighbor | ||
388 | if (periodicGridTraits_.isPeriodic(isOutside)) | ||
389 | { | ||
390 | const auto fIdxOutside = isOutside.indexInInside(); | ||
391 | const auto numFaceVertsOutside = refElement.size(fIdxOutside, 1, dim); | ||
392 | for (int localVIdxOutside = 0; localVIdxOutside < numFaceVertsOutside; ++localVIdxOutside) | ||
393 | { | ||
394 | const auto vIdxOutside = refElement.subEntity(fIdxOutside, 1, localVIdxOutside, dim); | ||
395 | const auto vPosOutside = outsideGeometry.corner(vIdxOutside); | ||
396 | const auto shift = std::abs((this->bBoxMax()-this->bBoxMin())*intersection.centerUnitOuterNormal()); | ||
397 | if (std::abs((vPosOutside-vPos).two_norm() - shift) < eps) | ||
398 | periodicDofMap_[vIdxGlobal] = this->vertexMapper().subIndex(outside, vIdxOutside, dim); | ||
399 | } | ||
400 | } | ||
401 | } | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | } | ||
406 | |||
407 | // error check: periodic boundaries currently don't work for box in parallel | ||
408 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
59 | if (this->isPeriodic() && this->gridView().comm().size() > 1) |
409 |
0/20✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
|
6 | DUNE_THROW(Dune::NotImplemented, "Periodic boundaries for box method for parallel simulations!"); |
410 | 59 | } | |
411 | |||
412 | const FeCache feCache_; | ||
413 | |||
414 | std::size_t numScv_; | ||
415 | std::size_t numScvf_; | ||
416 | std::size_t numBoundaryScvf_; | ||
417 | |||
418 | // vertices on the boundary | ||
419 | std::vector<bool> boundaryDofIndices_; | ||
420 | |||
421 | // a map for periodic boundary vertices | ||
422 | std::unordered_map<GridIndexType, GridIndexType> periodicDofMap_; | ||
423 | |||
424 | Cache cache_; | ||
425 | |||
426 | PeriodicGridTraits<typename GridView::Grid> periodicGridTraits_; | ||
427 | }; | ||
428 | |||
429 | /*! | ||
430 | * \ingroup BoxDiscretization | ||
431 | * \brief Base class for the finite volume geometry vector for box schemes | ||
432 | * This builds up the sub control volumes and sub control volume faces | ||
433 | * \note For caching disabled we store only some essential index maps to build up local systems on-demand in | ||
434 | * the corresponding FVElementGeometry | ||
435 | */ | ||
436 | template<class Scalar, class GV, class Traits> | ||
437 | class BoxFVGridGeometry<Scalar, GV, false, Traits> | ||
438 | : public BaseGridGeometry<GV, Traits> | ||
439 | { | ||
440 | using ThisType = BoxFVGridGeometry<Scalar, GV, false, Traits>; | ||
441 | using ParentType = BaseGridGeometry<GV, Traits>; | ||
442 | using GridIndexType = typename IndexTraits<GV>::GridIndex; | ||
443 | |||
444 | static const int dim = GV::dimension; | ||
445 | static const int dimWorld = GV::dimensionworld; | ||
446 | |||
447 | using Element = typename GV::template Codim<0>::Entity; | ||
448 | using CoordScalar = typename GV::ctype; | ||
449 | |||
450 | public: | ||
451 | //! export the discretization method this geometry belongs to | ||
452 | using DiscretizationMethod = DiscretizationMethods::Box; | ||
453 | static constexpr DiscretizationMethod discMethod{}; | ||
454 | |||
455 | //! export basic grid geometry type for the alternative constructor | ||
456 | using BasicGridGeometry = BasicGridGeometry_t<GV, Traits>; | ||
457 | //! export the type of the fv element geometry (the local view type) | ||
458 | using LocalView = typename Traits::template LocalView<ThisType, false>; | ||
459 | //! export the type of sub control volume | ||
460 | using SubControlVolume = typename Traits::SubControlVolume; | ||
461 | //! export the type of sub control volume | ||
462 | using SubControlVolumeFace = typename Traits::SubControlVolumeFace; | ||
463 | //! export the type of extrusion | ||
464 | using Extrusion = Extrusion_t<Traits>; | ||
465 | //! export dof mapper type | ||
466 | using DofMapper = typename Traits::VertexMapper; | ||
467 | //! export the finite element cache type | ||
468 | using FeCache = Dune::LagrangeLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>; | ||
469 | //! export the grid view type | ||
470 | using GridView = GV; | ||
471 | //! export whether the grid(geometry) supports periodicity | ||
472 | using SupportsPeriodicity = typename PeriodicGridTraits<typename GV::Grid>::SupportsPeriodicity; | ||
473 | |||
474 | //! Constructor with basic grid geometry used to share state with another grid geometry on the same grid view | ||
475 | 128 | BoxFVGridGeometry(std::shared_ptr<BasicGridGeometry> gg) | |
476 | : ParentType(std::move(gg)) | ||
477 | 128 | , cache_(*this) | |
478 |
3/7✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 128 times.
✓ Branch 6 taken 127 times.
✗ Branch 7 not taken.
✗ Branch 5 not taken.
|
128 | , periodicGridTraits_(this->gridView().grid()) |
479 | { | ||
480 |
1/2✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
|
128 | update_(); |
481 | 128 | } | |
482 | |||
483 | //! Constructor | ||
484 | 128 | BoxFVGridGeometry(const GridView& gridView) | |
485 |
1/2✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
|
128 | : BoxFVGridGeometry(std::make_shared<BasicGridGeometry>(gridView)) |
486 | 128 | {} | |
487 | |||
488 | //! the vertex mapper is the dofMapper | ||
489 | //! this is convenience to have better chance to have the same main files for box/tpfa/mpfa... | ||
490 | 104502269 | const DofMapper& dofMapper() const | |
491 |
12/21✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1463 times.
✓ Branch 3 taken 14 times.
✓ Branch 5 taken 19496 times.
✓ Branch 6 taken 12 times.
✓ Branch 8 taken 26 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 11 times.
✓ Branch 13 taken 8 times.
✓ Branch 15 taken 33 times.
✓ Branch 16 taken 16 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✓ Branch 14 taken 66 times.
✗ Branch 4 not taken.
✗ Branch 7 not taken.
✗ Branch 20 not taken.
✗ Branch 17 not taken.
|
104502315 | { return this->vertexMapper(); } |
492 | |||
493 | //! The total number of sub control volumes | ||
494 | std::size_t numScv() const | ||
495 | { return numScv_; } | ||
496 | |||
497 | //! The total number of sun control volume faces | ||
498 | std::size_t numScvf() const | ||
499 | { return numScvf_; } | ||
500 | |||
501 | //! The total number of boundary sub control volume faces | ||
502 | //! For compatibility reasons with cc methods | ||
503 | std::size_t numBoundaryScvf() const | ||
504 | { return numBoundaryScvf_; } | ||
505 | |||
506 | //! The total number of degrees of freedom | ||
507 | 13935 | std::size_t numDofs() const | |
508 |
16/18✓ Branch 2 taken 29 times.
✓ Branch 3 taken 398 times.
✓ Branch 5 taken 92 times.
✓ Branch 6 taken 6 times.
✓ Branch 9 taken 36 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 4 times.
✓ Branch 13 taken 8 times.
✓ Branch 7 taken 11462 times.
✓ Branch 1 taken 1126 times.
✓ Branch 8 taken 23 times.
✓ Branch 11 taken 4 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 1 times.
✓ Branch 4 taken 10 times.
✓ Branch 0 taken 8 times.
✓ Branch 16 taken 6 times.
✗ Branch 17 not taken.
|
13820 | { return this->vertexMapper().size(); } |
509 | |||
510 | |||
511 | //! update all fvElementGeometries (call this after grid adaption) | ||
512 | void update(const GridView& gridView) | ||
513 | { | ||
514 | ParentType::update(gridView); | ||
515 | update_(); | ||
516 | } | ||
517 | |||
518 | //! update all fvElementGeometries (call this after grid adaption) | ||
519 | 10 | void update(GridView&& gridView) | |
520 | { | ||
521 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
10 | ParentType::update(std::move(gridView)); |
522 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
10 | update_(); |
523 | 8 | } | |
524 | |||
525 | //! The finite element cache for creating local FE bases | ||
526 | 67793140 | const FeCache& feCache() const | |
527 |
1/2✓ Branch 1 taken 5362908 times.
✗ Branch 2 not taken.
|
67793140 | { return feCache_; } |
528 | |||
529 | //! If a vertex / d.o.f. is on the boundary | ||
530 | 15278768 | bool dofOnBoundary(GridIndexType dofIdx) const | |
531 |
6/6✓ Branch 0 taken 1610508 times.
✓ Branch 1 taken 12927978 times.
✓ Branch 2 taken 317719 times.
✓ Branch 3 taken 179735 times.
✓ Branch 4 taken 68122 times.
✓ Branch 5 taken 174706 times.
|
15278768 | { return boundaryDofIndices_[dofIdx]; } |
532 | |||
533 | //! If a vertex / d.o.f. is on a periodic boundary | ||
534 | 662929 | bool dofOnPeriodicBoundary(GridIndexType dofIdx) const | |
535 |
2/4✓ Branch 3 taken 1200 times.
✓ Branch 4 taken 400 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
1325858 | { return periodicDofMap_.count(dofIdx); } |
536 | |||
537 | //! The index of the vertex / d.o.f. on the other side of the periodic boundary | ||
538 | 1204 | GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const | |
539 |
2/6✓ Branch 2 taken 1200 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1200 times.
✗ Branch 6 not taken.
✗ Branch 1 not taken.
✗ Branch 4 not taken.
|
1204 | { return periodicDofMap_.at(dofIdx); } |
540 | |||
541 | //! Returns the map between dofs across periodic boundaries | ||
542 | const std::unordered_map<GridIndexType, GridIndexType>& periodicDofMap() const | ||
543 | 14803 | { return periodicDofMap_; } | |
544 | |||
545 | //! local view of this object (constructed with the internal cache) | ||
546 | 5405932 | friend inline LocalView localView(const BoxFVGridGeometry& gg) | |
547 |
15/23✓ Branch 1 taken 267 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11376 times.
✓ Branch 5 taken 4466 times.
✓ Branch 7 taken 2324442 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1732932 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 108849 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 387697 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 32261 times.
✗ Branch 20 not taken.
✓ Branch 6 taken 16 times.
✓ Branch 3 taken 5541 times.
✗ Branch 0 not taken.
✓ Branch 9 taken 2 times.
✓ Branch 12 taken 30330 times.
✓ Branch 15 taken 1 times.
✓ Branch 18 taken 2 times.
✓ Branch 22 taken 604311 times.
✗ Branch 23 not taken.
|
5405932 | { return { gg.cache_ }; } |
548 | |||
549 | private: | ||
550 | |||
551 | class BoxGridGeometryCache | ||
552 | { | ||
553 | friend class BoxFVGridGeometry; | ||
554 | public: | ||
555 | //! export the geometry helper type | ||
556 | using GeometryHelper = Detail::BoxGeometryHelper_t<GV, Traits>; | ||
557 | |||
558 | 128 | explicit BoxGridGeometryCache(const BoxFVGridGeometry& gg) | |
559 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
|
128 | : gridGeometry_(&gg) |
560 | {} | ||
561 | |||
562 | 95545429 | const BoxFVGridGeometry& gridGeometry() const | |
563 |
12/14✓ Branch 1 taken 5961337 times.
✓ Branch 2 taken 3750701 times.
✓ Branch 3 taken 4139071 times.
✓ Branch 4 taken 5034879 times.
✓ Branch 5 taken 203879 times.
✓ Branch 6 taken 1418494 times.
✓ Branch 7 taken 16434 times.
✓ Branch 8 taken 5850 times.
✓ Branch 0 taken 2480 times.
✓ Branch 9 taken 58416 times.
✓ Branch 10 taken 12077286 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2999526 times.
✗ Branch 14 not taken.
|
95337697 | { return *gridGeometry_; } |
564 | |||
565 | private: | ||
566 | const BoxFVGridGeometry* gridGeometry_; | ||
567 | }; | ||
568 | |||
569 | public: | ||
570 | //! the cache type (only the caching implementation has this) | ||
571 | //! this alias should only be used by the local view implementation | ||
572 | using Cache = BoxGridGeometryCache; | ||
573 | |||
574 | private: | ||
575 | |||
576 | 138 | void update_() | |
577 | { | ||
578 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
144 | boundaryDofIndices_.assign(numDofs(), false); |
579 | |||
580 | // save global data on the grid's scvs and scvfs | ||
581 | // TODO do we need those information? | ||
582 | 138 | numScv_ = 0; | |
583 | 138 | numScvf_ = 0; | |
584 | 138 | numBoundaryScvf_ = 0; | |
585 |
10/12✓ Branch 2 taken 29563 times.
✓ Branch 3 taken 20 times.
✓ Branch 5 taken 10033 times.
✓ Branch 6 taken 1 times.
✓ Branch 8 taken 8723 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 8723 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 8723 times.
✓ Branch 14 taken 6 times.
✓ Branch 1 taken 56148 times.
✓ Branch 4 taken 12813 times.
|
208013 | for (const auto& element : elements(this->gridView())) |
586 | { | ||
587 |
1/2✓ Branch 1 taken 8723 times.
✗ Branch 2 not taken.
|
104344 | numScv_ += element.subEntities(dim); |
588 |
1/2✓ Branch 1 taken 11535 times.
✗ Branch 2 not taken.
|
104344 | numScvf_ += element.subEntities(dim-1); |
589 | |||
590 |
1/2✓ Branch 1 taken 21535 times.
✗ Branch 2 not taken.
|
104344 | const auto elementGeometry = element.geometry(); |
591 | 104344 | const auto refElement = referenceElement(elementGeometry); | |
592 | |||
593 | // store the sub control volume face indices on the domain boundary | ||
594 |
12/13✓ Branch 1 taken 259617 times.
✓ Branch 2 taken 36745 times.
✓ Branch 6 taken 42877 times.
✓ Branch 7 taken 137614 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 14294 times.
✓ Branch 0 taken 56064 times.
✓ Branch 3 taken 34 times.
✓ Branch 4 taken 34150 times.
✓ Branch 5 taken 219193 times.
✓ Branch 11 taken 78 times.
✓ Branch 12 taken 5660 times.
✓ Branch 10 taken 96575 times.
|
921597 | for (const auto& intersection : intersections(this->gridView(), element)) |
595 | { | ||
596 |
4/4✓ Branch 0 taken 5307 times.
✓ Branch 1 taken 96912 times.
✓ Branch 2 taken 185168 times.
✓ Branch 3 taken 5860 times.
|
300921 | if (intersection.boundary() && !intersection.neighbor()) |
597 | { | ||
598 |
1/3✓ Branch 1 taken 1070 times.
✗ Branch 2 not taken.
✗ Branch 0 not taken.
|
12859 | const auto isGeometry = intersection.geometry(); |
599 | 12859 | numScvf_ += isGeometry.corners(); | |
600 |
1/3✓ Branch 1 taken 1070 times.
✗ Branch 2 not taken.
✗ Branch 0 not taken.
|
12859 | numBoundaryScvf_ += isGeometry.corners(); |
601 | |||
602 | // add all vertices on the intersection to the set of | ||
603 | // boundary vertices | ||
604 | 12859 | const auto fIdx = intersection.indexInInside(); | |
605 | 12859 | const auto numFaceVerts = refElement.size(fIdx, 1, dim); | |
606 |
2/2✓ Branch 1 taken 28178 times.
✓ Branch 2 taken 12859 times.
|
41037 | for (int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx) |
607 | { | ||
608 | 28178 | const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim); | |
609 |
1/2✓ Branch 1 taken 12214 times.
✗ Branch 2 not taken.
|
28178 | const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim); |
610 | 28178 | boundaryDofIndices_[vIdxGlobal] = true; | |
611 | } | ||
612 | 4795 | } | |
613 | |||
614 | // inform the grid geometry if we have periodic boundaries | ||
615 |
3/4✓ Branch 1 taken 150961 times.
✓ Branch 2 taken 39600 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40000 times.
|
438843 | else if (periodicGridTraits_.isPeriodic(intersection)) |
616 | { | ||
617 | 200 | this->setPeriodic(); | |
618 | |||
619 | // find the mapped periodic vertex of all vertices on periodic boundaries | ||
620 | 200 | const auto fIdx = intersection.indexInInside(); | |
621 | 200 | const auto numFaceVerts = refElement.size(fIdx, 1, dim); | |
622 | 400 | const auto eps = 1e-7*(elementGeometry.corner(1) - elementGeometry.corner(0)).two_norm(); | |
623 |
2/2✓ Branch 0 taken 400 times.
✓ Branch 1 taken 200 times.
|
600 | for (int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx) |
624 | { | ||
625 | 400 | const auto vIdx = refElement.subEntity(fIdx, 1, localVIdx, dim); | |
626 |
1/2✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
|
400 | const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim); |
627 | 400 | const auto vPos = elementGeometry.corner(vIdx); | |
628 | |||
629 | 400 | const auto& outside = intersection.outside(); | |
630 | 400 | const auto outsideGeometry = outside.geometry(); | |
631 |
3/4✓ Branch 0 taken 1600 times.
✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 400 times.
|
3200 | for (const auto& isOutside : intersections(this->gridView(), outside)) |
632 | { | ||
633 | // only check periodic vertices of the periodic neighbor | ||
634 |
3/4✓ Branch 1 taken 400 times.
✓ Branch 2 taken 1192 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1600 times.
|
3600 | if (periodicGridTraits_.isPeriodic(isOutside)) |
635 | { | ||
636 | 400 | const auto fIdxOutside = isOutside.indexInInside(); | |
637 | 400 | const auto numFaceVertsOutside = refElement.size(fIdxOutside, 1, dim); | |
638 |
2/2✓ Branch 1 taken 800 times.
✓ Branch 2 taken 400 times.
|
1200 | for (int localVIdxOutside = 0; localVIdxOutside < numFaceVertsOutside; ++localVIdxOutside) |
639 | { | ||
640 | 800 | const auto vIdxOutside = refElement.subEntity(fIdxOutside, 1, localVIdxOutside, dim); | |
641 | 800 | const auto vPosOutside = outsideGeometry.corner(vIdxOutside); | |
642 | 2400 | const auto shift = std::abs((this->bBoxMax()-this->bBoxMin())*intersection.centerUnitOuterNormal()); | |
643 |
2/2✓ Branch 0 taken 400 times.
✓ Branch 1 taken 400 times.
|
1600 | if (std::abs((vPosOutside-vPos).two_norm() - shift) < eps) |
644 |
2/4✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 400 times.
✗ Branch 5 not taken.
|
400 | periodicDofMap_[vIdxGlobal] = this->vertexMapper().subIndex(outside, vIdxOutside, dim); |
645 | } | ||
646 | } | ||
647 | } | ||
648 | } | ||
649 | } | ||
650 | } | ||
651 | } | ||
652 | |||
653 | // error check: periodic boundaries currently don't work for box in parallel | ||
654 |
3/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
138 | if (this->isPeriodic() && this->gridView().comm().size() > 1) |
655 |
0/20✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
|
27 | DUNE_THROW(Dune::NotImplemented, "Periodic boundaries for box method for parallel simulations!"); |
656 | 138 | } | |
657 | |||
658 | const FeCache feCache_; | ||
659 | |||
660 | // Information on the global number of geometries | ||
661 | // TODO do we need those information? | ||
662 | std::size_t numScv_; | ||
663 | std::size_t numScvf_; | ||
664 | std::size_t numBoundaryScvf_; | ||
665 | |||
666 | // vertices on the boundary | ||
667 | std::vector<bool> boundaryDofIndices_; | ||
668 | |||
669 | // a map for periodic boundary vertices | ||
670 | std::unordered_map<GridIndexType, GridIndexType> periodicDofMap_; | ||
671 | |||
672 | Cache cache_; | ||
673 | |||
674 | PeriodicGridTraits<typename GridView::Grid> periodicGridTraits_; | ||
675 | }; | ||
676 | |||
677 | } // end namespace Dumux | ||
678 | |||
679 | #endif | ||
680 |