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 CCMpfaDiscretization | ||
10 | * \brief Class for the interaction volume of the mpfa-o scheme. | ||
11 | */ | ||
12 | #ifndef DUMUX_DISCRETIZATION_CC_MPFA_O_INTERACTIONVOLUME_HH | ||
13 | #define DUMUX_DISCRETIZATION_CC_MPFA_O_INTERACTIONVOLUME_HH | ||
14 | |||
15 | #include <type_traits> | ||
16 | |||
17 | #include <dune/common/dynmatrix.hh> | ||
18 | #include <dune/common/dynvector.hh> | ||
19 | #include <dune/common/fvector.hh> | ||
20 | #include <dune/common/reservedvector.hh> | ||
21 | |||
22 | #include <dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh> | ||
23 | #include <dumux/discretization/cellcentered/mpfa/localfacedata.hh> | ||
24 | #include <dumux/discretization/cellcentered/mpfa/methods.hh> | ||
25 | |||
26 | #include "localassembler.hh" | ||
27 | #include "localsubcontrolentities.hh" | ||
28 | #include "interactionvolumeindexset.hh" | ||
29 | #include "scvgeometryhelper.hh" | ||
30 | |||
31 | namespace Dumux { | ||
32 | |||
33 | //! Forward declaration of the o-method's interaction volume | ||
34 | template< class Traits > class CCMpfaOInteractionVolume; | ||
35 | |||
36 | /*! | ||
37 | * \ingroup CCMpfaDiscretization | ||
38 | * \brief The default interaction volume traits class for the mpfa-o method. | ||
39 | * This uses dynamic types types for matrices/vectors in order to work | ||
40 | * on general grids. For interaction volumes known at compile time use | ||
41 | * the static interaction volume implementation. | ||
42 | * | ||
43 | * \tparam NodalIndexSet The type used for the dual grid's nodal index sets | ||
44 | * \tparam Scalar The Type used for scalar values | ||
45 | */ | ||
46 | template< class NodalIndexSet, class Scalar > | ||
47 | struct CCMpfaODefaultInteractionVolumeTraits | ||
48 | { | ||
49 | private: | ||
50 | using GridIndexType = typename NodalIndexSet::GridIndexType; | ||
51 | using LocalIndexType = typename NodalIndexSet::LocalIndexType; | ||
52 | |||
53 | static constexpr int dim = NodalIndexSet::Traits::GridView::dimension; | ||
54 | static constexpr int dimWorld = NodalIndexSet::Traits::GridView::dimensionworld; | ||
55 | |||
56 | using DimVector = Dune::FieldVector<Scalar, dim>; | ||
57 | using FaceOmegas = typename std::conditional< (dim<dimWorld), | ||
58 | std::vector<DimVector>, | ||
59 | Dune::ReservedVector<DimVector, 2> >::type; | ||
60 | |||
61 | //! Matrix/Vector traits to be used by the data handle | ||
62 | struct MVTraits | ||
63 | { | ||
64 | using OmegaStorage = std::vector< FaceOmegas >; | ||
65 | |||
66 | using AMatrix = Dune::DynamicMatrix< Scalar >; | ||
67 | using BMatrix = Dune::DynamicMatrix< Scalar >; | ||
68 | using CMatrix = Dune::DynamicMatrix< Scalar >; | ||
69 | using DMatrix = Dune::DynamicMatrix< Scalar >; | ||
70 | using TMatrix = Dune::DynamicMatrix< Scalar >; | ||
71 | using CellVector = Dune::DynamicVector< Scalar >; | ||
72 | using FaceVector = Dune::DynamicVector< Scalar >; | ||
73 | }; | ||
74 | |||
75 | public: | ||
76 | //! export the type of grid view | ||
77 | using GridView = typename NodalIndexSet::Traits::GridView; | ||
78 | //! export the type for the interaction volume index set | ||
79 | using IndexSet = CCMpfaOInteractionVolumeIndexSet< NodalIndexSet >; | ||
80 | //! export the type of interaction-volume local scvs | ||
81 | using LocalScvType = CCMpfaOInteractionVolumeLocalScv< IndexSet, Scalar, dim, dimWorld >; | ||
82 | //! export the type of interaction-volume local scvfs | ||
83 | using LocalScvfType = CCMpfaOInteractionVolumeLocalScvf< IndexSet >; | ||
84 | //! export the type of used for the iv-local face data | ||
85 | using LocalFaceData = InteractionVolumeLocalFaceData<GridIndexType, LocalIndexType>; | ||
86 | //! export the matrix/vector traits to be used by the iv | ||
87 | using MatVecTraits = MVTraits; | ||
88 | |||
89 | //! the type of assembler used for the o-method's iv-local eq systems | ||
90 | template<class Problem, class FVElementGeometry, class ElemVolVars> | ||
91 | using LocalAssembler = MpfaOInteractionVolumeAssembler<Problem, FVElementGeometry, ElemVolVars>; | ||
92 | }; | ||
93 | |||
94 | /*! | ||
95 | * \ingroup CCMpfaDiscretization | ||
96 | * \brief Class for the interaction volume of the mpfa-o method. | ||
97 | * This implementation creates dynamic objects of the local geometries | ||
98 | * and can be used at boundaries and on unstructured grids. | ||
99 | */ | ||
100 | template< class Traits > | ||
101 | 27719982 | class CCMpfaOInteractionVolume | |
102 | : public CCMpfaInteractionVolumeBase< Traits > | ||
103 | { | ||
104 | using GridView = typename Traits::GridView; | ||
105 | using Element = typename GridView::template Codim<0>::Entity; | ||
106 | |||
107 | using IndexSet = typename Traits::IndexSet; | ||
108 | using GridIndexType = typename IndexSet::GridIndexType; | ||
109 | using LocalIndexType = typename IndexSet::LocalIndexType; | ||
110 | using Stencil = typename IndexSet::NodalGridStencilType; | ||
111 | |||
112 | using LocalScvType = typename Traits::LocalScvType; | ||
113 | using LocalScvfType = typename Traits::LocalScvfType; | ||
114 | using LocalFaceData = typename Traits::LocalFaceData; | ||
115 | |||
116 | public: | ||
117 | //! Data attached to scvf touching Dirichlet boundaries. | ||
118 | //! For the default o-scheme, we only store the corresponding vol vars index. | ||
119 | class DirichletData | ||
120 | { | ||
121 | GridIndexType volVarIndex_; | ||
122 | public: | ||
123 | //! Constructor | ||
124 | 448724 | DirichletData(const GridIndexType index) : volVarIndex_(index) {} | |
125 | |||
126 | //! Return corresponding vol var index | ||
127 | ✗ | GridIndexType volVarIndex() const { return volVarIndex_; } | |
128 | }; | ||
129 | |||
130 | //! publicly state the mpfa-scheme this interaction volume is associated with | ||
131 | static constexpr MpfaMethods MpfaMethod = MpfaMethods::oMethod; | ||
132 | |||
133 | //! Sets up the local scope for a given iv index set | ||
134 | template< class Problem, class FVElementGeometry > | ||
135 | 4619997 | void bind(const IndexSet& indexSet, | |
136 | const Problem& problem, | ||
137 | const FVElementGeometry& fvGeometry) | ||
138 | { | ||
139 | // for the o-scheme, the stencil is equal to the scv | ||
140 | // index set of the dual grid's nodal index set | ||
141 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4619997 times.
|
4619997 | stencil_ = &indexSet.nodalIndexSet().gridScvIndices(); |
142 | |||
143 | // number of interaction-volume-local scvs(=node-local for o-scheme) and scvfs | ||
144 | 4619997 | numFaces_ = indexSet.numFaces(); | |
145 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4619997 times.
|
4619997 | const auto numLocalScvs = indexSet.numScvs(); |
146 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4619997 times.
|
4619997 | const auto numGlobalScvfs = indexSet.nodalIndexSet().numScvfs(); |
147 | |||
148 | // reserve memory for local entities | ||
149 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4619997 times.
|
4619997 | elements_.clear(); elements_.reserve(numLocalScvs); |
150 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4619997 times.
|
4619997 | scvs_.clear(); scvs_.reserve(numLocalScvs); |
151 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4619997 times.
|
4619997 | scvfs_.clear(); scvfs_.reserve(numFaces_); |
152 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4619997 times.
|
4619997 | localFaceData_.clear(); localFaceData_.reserve(numGlobalScvfs); |
153 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4619997 times.
|
4619997 | dirichletData_.clear(); dirichletData_.reserve(numFaces_); |
154 | |||
155 | // set up stuff related to sub-control volumes | ||
156 |
2/2✓ Branch 0 taken 15725952 times.
✓ Branch 1 taken 4619997 times.
|
20345949 | for (LocalIndexType scvIdxLocal = 0; scvIdxLocal < numLocalScvs; scvIdxLocal++) |
157 | { | ||
158 |
1/2✓ Branch 3 taken 10610246 times.
✗ Branch 4 not taken.
|
32772294 | elements_.emplace_back(fvGeometry.gridGeometry().element( stencil()[scvIdxLocal] )); |
159 | 15725952 | scvs_.emplace_back(fvGeometry.gridGeometry().mpfaHelper(), | |
160 | fvGeometry, | ||
161 |
4/4✓ Branch 0 taken 939722 times.
✓ Branch 1 taken 2321844 times.
✓ Branch 2 taken 939722 times.
✓ Branch 3 taken 2321844 times.
|
31451904 | fvGeometry.scv( stencil()[scvIdxLocal] ), |
162 | scvIdxLocal, | ||
163 | indexSet); | ||
164 | } | ||
165 | |||
166 | // keep track of the number of unknowns etc | ||
167 | 4619997 | numUnknowns_ = 0; | |
168 | 4619997 | numKnowns_ = numLocalScvs; | |
169 | |||
170 | // set up quantities related to sub-control volume faces | ||
171 |
2/2✓ Branch 0 taken 17391007 times.
✓ Branch 1 taken 4619997 times.
|
22011004 | for (LocalIndexType faceIdxLocal = 0; faceIdxLocal < numFaces_; ++faceIdxLocal) |
172 | { | ||
173 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 13887885 times.
|
17391007 | const auto& scvf = fvGeometry.scvf(indexSet.gridScvfIndex(faceIdxLocal)); |
174 | |||
175 | // the neighboring scvs in local indices (order: 0 - inside scv, 1..n - outside scvs) | ||
176 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17391007 times.
|
17391007 | const auto& neighborScvIndicesLocal = indexSet.neighboringLocalScvIndices(faceIdxLocal); |
177 | 17391007 | const auto numNeighborScvs = neighborScvIndicesLocal.size(); | |
178 | 33061977 | localFaceData_.emplace_back(faceIdxLocal, neighborScvIndicesLocal[0], scvf.index()); | |
179 | |||
180 | // create iv-local scvf object | ||
181 |
2/2✓ Branch 0 taken 3354970 times.
✓ Branch 1 taken 14036037 times.
|
17391007 | if (scvf.boundary()) |
182 | { | ||
183 |
10/10✓ Branch 0 taken 36216 times.
✓ Branch 1 taken 5518 times.
✓ Branch 2 taken 174900 times.
✓ Branch 3 taken 925306 times.
✓ Branch 4 taken 2425188 times.
✓ Branch 5 taken 929782 times.
✓ Branch 6 taken 2278706 times.
✓ Branch 7 taken 17792 times.
✓ Branch 8 taken 23036 times.
✓ Branch 9 taken 12932 times.
|
9313188 | if (problem.boundaryTypes(elements_[neighborScvIndicesLocal[0]], scvf).hasOnlyDirichlet()) |
184 | { | ||
185 | 402710 | scvfs_.emplace_back(scvf, neighborScvIndicesLocal, numKnowns_++, /*isDirichlet*/true); | |
186 | 805420 | dirichletData_.emplace_back(scvf.outsideScvIdx()); | |
187 | } | ||
188 | else | ||
189 | 2952260 | scvfs_.emplace_back(scvf, neighborScvIndicesLocal, numUnknowns_++, /*isDirichlet*/false); | |
190 | } | ||
191 | else | ||
192 | { | ||
193 | 14036037 | scvfs_.emplace_back(scvf, neighborScvIndicesLocal, numUnknowns_++, /*isDirichlet*/false); | |
194 | |||
195 | // add local face data objects for the outside faces | ||
196 |
2/2✓ Branch 0 taken 14060897 times.
✓ Branch 1 taken 14036037 times.
|
28096934 | for (LocalIndexType i = 1; i < numNeighborScvs; ++i) |
197 | { | ||
198 | // loop over scvfs in outside scv until we find the one coinciding with current scvf | ||
199 | 14060897 | const auto outsideLocalScvIdx = neighborScvIndicesLocal[i]; | |
200 | 42182691 | const auto& flipScvfIndex = fvGeometry.gridGeometry().flipScvfIndexSet()[scvf.index()][i-1]; | |
201 | 14060897 | const auto& flipScvf = fvGeometry.scvf(flipScvfIndex); | |
202 | 42182691 | localFaceData_.emplace_back(faceIdxLocal, // iv-local scvf idx | |
203 | outsideLocalScvIdx, // iv-local scv index | ||
204 | 14060897 | i-1, // scvf-local index in outside faces | |
205 | flipScvf.index()); // global scvf index | ||
206 | } | ||
207 | } | ||
208 | } | ||
209 | 4619997 | } | |
210 | |||
211 | //! returns the number of primary scvfs of this interaction volume | ||
212 | ✗ | std::size_t numFaces() const | |
213 | ✗ | { return numFaces_; } | |
214 | |||
215 | //! returns the number of intermediate unknowns within this interaction volume | ||
216 | ✗ | std::size_t numUnknowns() const | |
217 | ✗ | { return numUnknowns_; } | |
218 | |||
219 | //! returns the number of (in this context) known solution values within this interaction volume | ||
220 | ✗ | std::size_t numKnowns() const | |
221 | ✗ | { return numKnowns_; } | |
222 | |||
223 | //! returns the number of scvs embedded in this interaction volume | ||
224 | std::size_t numScvs() const | ||
225 |
9/9✓ Branch 0 taken 297485744 times.
✓ Branch 1 taken 64239529 times.
✓ Branch 2 taken 116655068 times.
✓ Branch 3 taken 29917002 times.
✓ Branch 4 taken 1486825 times.
✓ Branch 5 taken 767040 times.
✓ Branch 6 taken 5536 times.
✓ Branch 7 taken 400 times.
✓ Branch 8 taken 121 times.
|
510557144 | { return scvs_.size(); } |
226 | |||
227 | //! returns the cell-stencil of this interaction volume | ||
228 | ✗ | const Stencil& stencil() const | |
229 | ✗ | { return *stencil_; } | |
230 | |||
231 | //! returns the grid element corresponding to a given iv-local scv idx | ||
232 | const Element& element(LocalIndexType ivLocalScvIdx) const | ||
233 | 1165203352 | { return elements_[ivLocalScvIdx]; } | |
234 | |||
235 | //! returns the local scvf entity corresponding to a given iv-local scvf idx | ||
236 | const LocalScvfType& localScvf(LocalIndexType ivLocalScvfIdx) const | ||
237 |
34/34✓ Branch 0 taken 1313786 times.
✓ Branch 1 taken 829920 times.
✓ Branch 2 taken 1313786 times.
✓ Branch 3 taken 829920 times.
✓ Branch 4 taken 145242048 times.
✓ Branch 5 taken 142700884 times.
✓ Branch 6 taken 153615362 times.
✓ Branch 7 taken 151074198 times.
✓ Branch 8 taken 143860174 times.
✓ Branch 9 taken 143860174 times.
✓ Branch 10 taken 304509362 times.
✓ Branch 11 taken 143979966 times.
✓ Branch 12 taken 169022502 times.
✓ Branch 13 taken 8493106 times.
✓ Branch 14 taken 20960 times.
✓ Branch 15 taken 20960 times.
✓ Branch 16 taken 2254864 times.
✓ Branch 17 taken 2254864 times.
✓ Branch 18 taken 14552674 times.
✓ Branch 19 taken 14552674 times.
✓ Branch 20 taken 13058274 times.
✓ Branch 21 taken 13058274 times.
✓ Branch 22 taken 11523014 times.
✓ Branch 23 taken 11523014 times.
✓ Branch 24 taken 10783510 times.
✓ Branch 25 taken 10783510 times.
✓ Branch 30 taken 2233904 times.
✓ Branch 31 taken 2233904 times.
✓ Branch 32 taken 2233904 times.
✓ Branch 33 taken 2233904 times.
✓ Branch 34 taken 739504 times.
✓ Branch 35 taken 739504 times.
✓ Branch 36 taken 739504 times.
✓ Branch 37 taken 739504 times.
|
2421506908 | { return scvfs_[ivLocalScvfIdx]; } |
238 | |||
239 | //! returns the local scv entity corresponding to a given iv-local scv idx | ||
240 | const LocalScvType& localScv(LocalIndexType ivLocalScvIdx) const | ||
241 |
46/50✓ Branch 2 taken 3486924 times.
✓ Branch 3 taken 9998456 times.
✓ Branch 4 taken 3488684 times.
✓ Branch 5 taken 10002776 times.
✓ Branch 6 taken 4491228 times.
✓ Branch 7 taken 10999488 times.
✓ Branch 8 taken 4490908 times.
✓ Branch 9 taken 10999200 times.
✓ Branch 10 taken 378272 times.
✓ Branch 11 taken 393328 times.
✓ Branch 12 taken 376832 times.
✓ Branch 13 taken 389296 times.
✓ Branch 14 taken 1769862 times.
✓ Branch 15 taken 5064028 times.
✓ Branch 16 taken 1816582 times.
✓ Branch 17 taken 5118076 times.
✓ Branch 18 taken 1746958 times.
✓ Branch 19 taken 5046864 times.
✓ Branch 20 taken 2547918 times.
✓ Branch 21 taken 5838832 times.
✓ Branch 22 taken 847680 times.
✓ Branch 23 taken 846016 times.
✓ Branch 24 taken 273056 times.
✓ Branch 25 taken 273056 times.
✓ Branch 26 taken 273056 times.
✓ Branch 27 taken 273056 times.
✓ Branch 28 taken 282232 times.
✓ Branch 29 taken 291720 times.
✓ Branch 30 taken 282232 times.
✓ Branch 31 taken 291720 times.
✓ Branch 32 taken 97240 times.
✓ Branch 33 taken 109704 times.
✓ Branch 34 taken 97240 times.
✓ Branch 35 taken 109704 times.
✓ Branch 36 taken 18926 times.
✓ Branch 37 taken 21026 times.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✓ Branch 42 taken 829664 times.
✓ Branch 43 taken 819168 times.
✓ Branch 44 taken 829664 times.
✓ Branch 45 taken 819168 times.
✓ Branch 46 taken 273056 times.
✓ Branch 47 taken 273056 times.
✓ Branch 48 taken 273056 times.
✓ Branch 49 taken 273056 times.
✓ Branch 50 taken 278304 times.
✓ Branch 51 taken 273056 times.
|
2438850706 | { return scvs_[ivLocalScvIdx]; } |
242 | |||
243 | //! returns a reference to the container with the local face data | ||
244 | const std::vector<LocalFaceData>& localFaceData() const | ||
245 |
8/8✓ Branch 0 taken 126787168 times.
✓ Branch 1 taken 286715434 times.
✓ Branch 2 taken 86552590 times.
✓ Branch 3 taken 112854452 times.
✓ Branch 4 taken 16360351 times.
✓ Branch 5 taken 1396216 times.
✓ Branch 6 taken 19436464 times.
✓ Branch 7 taken 2403401 times.
|
732319612 | { return localFaceData_; } |
246 | |||
247 | //! returns a reference to the information container on Dirichlet BCs within this iv | ||
248 | const std::vector<DirichletData>& dirichletData() const | ||
249 | 94908746 | { return dirichletData_; } | |
250 | |||
251 | //! returns the geometry of the i-th local scv | ||
252 | template< class FVElementGeometry > | ||
253 | auto getScvGeometry(LocalIndexType ivLocalScvIdx, const FVElementGeometry& fvGeometry) const | ||
254 |
1/2✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
|
400 | { return CCMpfaOScvGeometryHelper<LocalScvType>::computeScvGeometry(ivLocalScvIdx, *this, fvGeometry); } |
255 | |||
256 | //! returns the number of interaction volumes living around a vertex | ||
257 | template< class NI > | ||
258 | ✗ | static constexpr std::size_t numIVAtVertex(const NI& nodalIndexSet) | |
259 | ✗ | { return 1; } | |
260 | |||
261 | //! adds the iv index sets living around a vertex to a given container | ||
262 | //! and stores the the corresponding index in a map for each scvf | ||
263 | template< class IvIndexSetContainer, | ||
264 | class ScvfIndexMap, | ||
265 | class NodalIndexSet, | ||
266 | class FlipScvfIndexSet > | ||
267 | 79874 | static void addIVIndexSets(IvIndexSetContainer& ivIndexSetContainer, | |
268 | ScvfIndexMap& scvfIndexMap, | ||
269 | const NodalIndexSet& nodalIndexSet, | ||
270 | const FlipScvfIndexSet& flipScvfIndexSet) | ||
271 | { | ||
272 | // the global index of the iv index set that is about to be created | ||
273 | 79874 | const auto curGlobalIndex = ivIndexSetContainer.size(); | |
274 | |||
275 | // make the one index set for this node | ||
276 | 79874 | ivIndexSetContainer.emplace_back(nodalIndexSet, flipScvfIndexSet); | |
277 | |||
278 | // store the index mapping | ||
279 |
4/4✓ Branch 0 taken 630616 times.
✓ Branch 1 taken 79024 times.
✓ Branch 2 taken 630616 times.
✓ Branch 3 taken 79024 times.
|
1593016 | for (const auto scvfIdx : nodalIndexSet.gridScvfIndices()) |
280 | 1273520 | scvfIndexMap[scvfIdx] = curGlobalIndex; | |
281 | 79874 | } | |
282 | |||
283 | private: | ||
284 | // pointer to cell stencil (in iv index set) | ||
285 | const Stencil* stencil_; | ||
286 | |||
287 | // Variables defining the local scope | ||
288 | std::vector<Element> elements_; | ||
289 | std::vector<LocalScvType> scvs_; | ||
290 | std::vector<LocalScvfType> scvfs_; | ||
291 | std::vector<LocalFaceData> localFaceData_; | ||
292 | std::vector<DirichletData> dirichletData_; | ||
293 | |||
294 | // sizes involved in the local system equations | ||
295 | std::size_t numFaces_; | ||
296 | std::size_t numUnknowns_; | ||
297 | std::size_t numKnowns_; | ||
298 | }; | ||
299 | |||
300 | } // end namespace Dumux | ||
301 | |||
302 | #endif | ||
303 |