GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/discretization/box/fvgridgeometry.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 175 177 98.9%
Functions: 103 106 97.2%
Branches: 357 603 59.2%

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