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 to be used when the | ||
11 | * sizes are known at compile time, e.g. for non-boundary interaction volumes | ||
12 | * on structured grids. | ||
13 | */ | ||
14 | #ifndef DUMUX_DISCRETIZATION_CC_MPFA_O_STATIC_INTERACTIONVOLUME_HH | ||
15 | #define DUMUX_DISCRETIZATION_CC_MPFA_O_STATIC_INTERACTIONVOLUME_HH | ||
16 | |||
17 | #include <dune/common/fmatrix.hh> | ||
18 | #include <dune/common/fvector.hh> | ||
19 | #include <dune/common/exceptions.hh> | ||
20 | |||
21 | #include <dumux/common/math.hh> | ||
22 | |||
23 | #include <dumux/discretization/cellcentered/mpfa/interactionvolumebase.hh> | ||
24 | #include <dumux/discretization/cellcentered/mpfa/dualgridindexset.hh> | ||
25 | #include <dumux/discretization/cellcentered/mpfa/localfacedata.hh> | ||
26 | #include <dumux/discretization/cellcentered/mpfa/methods.hh> | ||
27 | |||
28 | #include "localassembler.hh" | ||
29 | #include "localsubcontrolentities.hh" | ||
30 | #include "interactionvolumeindexset.hh" | ||
31 | #include "interactionvolume.hh" | ||
32 | #include "scvgeometryhelper.hh" | ||
33 | |||
34 | namespace Dumux { | ||
35 | |||
36 | //! Forward declaration of the o-method's static interaction volume | ||
37 | template< class Traits > class CCMpfaOStaticInteractionVolume; | ||
38 | |||
39 | /*! | ||
40 | * \ingroup CCMpfaDiscretization | ||
41 | * \brief The default interaction volume traits class for the mpfa-o method | ||
42 | * with known size of the interaction volumes at compile time. It uses | ||
43 | * statically sized containers for the iv-local data structures and static | ||
44 | * matrices and vectors. | ||
45 | * | ||
46 | * \tparam NI The type used for the dual grid's nodal index sets | ||
47 | * \tparam S The Type used for scalar values | ||
48 | * \tparam C The number of sub-control volumes (cells) in the ivs | ||
49 | * \tparam F The number of sub-control volume faces in the ivs | ||
50 | */ | ||
51 | template< class NI, class S, int C, int F > | ||
52 | struct CCMpfaODefaultStaticInteractionVolumeTraits | ||
53 | { | ||
54 | private: | ||
55 | using GridIndexType = typename NI::GridIndexType; | ||
56 | using LocalIndexType = typename NI::LocalIndexType; | ||
57 | |||
58 | static constexpr int dim = NI::Traits::GridView::dimension; | ||
59 | static constexpr int dimWorld = NI::Traits::GridView::dimensionworld; | ||
60 | |||
61 | using DimVector = Dune::FieldVector<S, dim>; | ||
62 | using FaceOmegas = Dune::ReservedVector<DimVector, 2>; | ||
63 | |||
64 | //! Matrix/Vector traits to be used by the data handle | ||
65 | struct MVTraits | ||
66 | { | ||
67 | using OmegaStorage = std::array< FaceOmegas, F >; | ||
68 | |||
69 | using AMatrix = Dune::FieldMatrix< S, F, F >; | ||
70 | using BMatrix = Dune::FieldMatrix< S, F, C >; | ||
71 | using CMatrix = Dune::FieldMatrix< S, F, F >; | ||
72 | using DMatrix = Dune::FieldMatrix< S, F, C >; | ||
73 | using TMatrix = Dune::FieldMatrix< S, F, C >; | ||
74 | using CellVector = Dune::FieldVector< S, C >; | ||
75 | using FaceVector = Dune::FieldVector< S, F >; | ||
76 | }; | ||
77 | |||
78 | public: | ||
79 | //! export the type of grid view | ||
80 | using GridView = typename NI::Traits::GridView; | ||
81 | //! export the type for the interaction volume index set | ||
82 | using IndexSet = CCMpfaOInteractionVolumeIndexSet< NI >; | ||
83 | //! export the type of interaction-volume local scvs | ||
84 | using LocalScvType = CCMpfaOInteractionVolumeLocalScv< IndexSet, S, dim, dimWorld >; | ||
85 | //! export the type of interaction-volume local scvfs | ||
86 | using LocalScvfType = CCMpfaOInteractionVolumeLocalScvf< IndexSet >; | ||
87 | //! export the type of used for the iv-local face data | ||
88 | using LocalFaceData = InteractionVolumeLocalFaceData<GridIndexType, LocalIndexType>; | ||
89 | //! export the matrix/vector traits to be used by the iv | ||
90 | using MatVecTraits = MVTraits; | ||
91 | //! export the number of scvs in the interaction volumes | ||
92 | static constexpr int numScvs = C; | ||
93 | //! export the number of scvfs in the interaction volumes | ||
94 | static constexpr int numScvfs = F; | ||
95 | |||
96 | //! the type of assembler used for the o-method's iv-local eq systems | ||
97 | template<class Problem, class FVElementGeometry, class ElemVolVars> | ||
98 | using LocalAssembler = MpfaOInteractionVolumeAssembler<Problem, FVElementGeometry, ElemVolVars>; | ||
99 | }; | ||
100 | |||
101 | /*! | ||
102 | * \ingroup CCMpfaDiscretization | ||
103 | * \brief Class for the interaction volume of the mpfa-o method. | ||
104 | * This implementation creates static objects of the local geometries | ||
105 | * and can only be used for interior interaction volumes with a static | ||
106 | * size known at compile time. This size has to match the sizes of the | ||
107 | * vectors/matrices defined in the traits class in case static types are used. | ||
108 | * | ||
109 | * \tparam Traits The type traits class to be used | ||
110 | */ | ||
111 | template< class Traits > | ||
112 | class CCMpfaOStaticInteractionVolume | ||
113 | : public CCMpfaInteractionVolumeBase< Traits > | ||
114 | { | ||
115 | using GridView = typename Traits::GridView; | ||
116 | using Element = typename GridView::template Codim<0>::Entity; | ||
117 | |||
118 | using IndexSet = typename Traits::IndexSet; | ||
119 | using GridIndexType = typename IndexSet::GridIndexType; | ||
120 | using LocalIndexType = typename IndexSet::LocalIndexType; | ||
121 | using Stencil = typename IndexSet::NodalGridStencilType; | ||
122 | |||
123 | using LocalScvType = typename Traits::LocalScvType; | ||
124 | using LocalScvfType = typename Traits::LocalScvfType; | ||
125 | using LocalFaceData = typename Traits::LocalFaceData; | ||
126 | |||
127 | static constexpr int numScvf = Traits::numScvfs; | ||
128 | static constexpr int numScv = Traits::numScvs; | ||
129 | |||
130 | public: | ||
131 | //! This does not work on surface grids | ||
132 | static_assert(int(GridView::dimension)==int(GridView::dimensionworld), "static iv does not work on surface grids"); | ||
133 | |||
134 | //! export the standard o-methods dirichlet data | ||
135 | //! this is fake Dirichlet data as this implementation cannot be used on boundaries | ||
136 | struct DirichletData | ||
137 | { | ||
138 | ✗ | GridIndexType volVarIndex() const | |
139 | ✗ | { DUNE_THROW(Dune::InvalidStateException, "Static interaction volume cannot be used on boundaries!"); } | |
140 | }; | ||
141 | |||
142 | //! publicly state the mpfa-scheme this interaction volume is associated with | ||
143 | static constexpr MpfaMethods MpfaMethod = MpfaMethods::oMethod; | ||
144 | |||
145 | //! Sets up the local scope for a given iv index set | ||
146 | template< class Problem, class FVElementGeometry > | ||
147 | 47265 | void bind(const IndexSet& indexSet, | |
148 | const Problem& problem, | ||
149 | const FVElementGeometry& fvGeometry) | ||
150 | { | ||
151 | // for the o-scheme, the stencil is equal to the scv | ||
152 | // index set of the dual grid's nodal index set | ||
153 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 47265 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 47265 times.
|
94530 | assert(indexSet.numScvs() == numScv); |
154 | 47265 | stencil_ = &indexSet.nodalIndexSet().gridScvIndices(); | |
155 | |||
156 | // set up stuff related to sub-control volumes | ||
157 |
2/2✓ Branch 0 taken 189060 times.
✓ Branch 1 taken 47265 times.
|
236325 | for (LocalIndexType scvIdxLocal = 0; scvIdxLocal < numScv; scvIdxLocal++) |
158 | { | ||
159 |
4/4✓ Branch 2 taken 46920 times.
✓ Branch 3 taken 140760 times.
✓ Branch 4 taken 46920 times.
✓ Branch 5 taken 140760 times.
|
378120 | elements_[scvIdxLocal] = fvGeometry.gridGeometry().element( stencil()[scvIdxLocal] ); |
160 | 189060 | scvs_[scvIdxLocal] = LocalScvType(fvGeometry.gridGeometry().mpfaHelper(), | |
161 | fvGeometry, | ||
162 |
4/4✓ Branch 0 taken 46920 times.
✓ Branch 1 taken 140760 times.
✓ Branch 2 taken 46920 times.
✓ Branch 3 taken 140760 times.
|
378120 | fvGeometry.scv( stencil()[scvIdxLocal] ), |
163 | scvIdxLocal, | ||
164 | indexSet); | ||
165 | } | ||
166 | |||
167 | // set up quantities related to sub-control volume faces | ||
168 |
2/2✓ Branch 0 taken 189060 times.
✓ Branch 1 taken 47265 times.
|
236325 | for (LocalIndexType faceIdxLocal = 0; faceIdxLocal < numScvf; ++faceIdxLocal) |
169 | { | ||
170 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1380 times.
|
189060 | const auto& scvf = fvGeometry.scvf(indexSet.gridScvfIndex(faceIdxLocal)); |
171 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 189060 times.
|
189060 | assert(!scvf.boundary()); |
172 | |||
173 | // the neighboring scvs in local indices (order: 0 - inside scv, 1..n - outside scvs) | ||
174 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 189060 times.
|
189060 | const auto& neighborScvIndicesLocal = indexSet.neighboringLocalScvIndices(faceIdxLocal); |
175 | |||
176 | // create iv-local scvf objects | ||
177 | 378120 | scvfs_[faceIdxLocal] = LocalScvfType(scvf, neighborScvIndicesLocal, faceIdxLocal, /*isDirichlet*/false); | |
178 | 378120 | localFaceData_[faceIdxLocal*2] = LocalFaceData(faceIdxLocal, neighborScvIndicesLocal[0], scvf.index()); | |
179 | |||
180 | // add local face data objects for the outside face | ||
181 | 189060 | const auto outsideLocalScvIdx = neighborScvIndicesLocal[1]; | |
182 |
1/2✓ Branch 0 taken 283590 times.
✗ Branch 1 not taken.
|
283590 | for (int coord = 0; coord < GridView::dimension; ++coord) |
183 | { | ||
184 |
2/2✓ Branch 1 taken 189060 times.
✓ Branch 2 taken 94530 times.
|
283590 | if (indexSet.localScvfIndex(outsideLocalScvIdx, coord) == faceIdxLocal) |
185 | { | ||
186 | 189060 | const auto globalScvfIdx = indexSet.nodalIndexSet().gridScvfIndex(outsideLocalScvIdx, coord); | |
187 | 189060 | const auto& flipScvf = fvGeometry.scvf(globalScvfIdx); | |
188 | 189060 | localFaceData_[faceIdxLocal*2+1] = LocalFaceData(faceIdxLocal, // iv-local scvf idx | |
189 | outsideLocalScvIdx, // iv-local scv index | ||
190 | 0, // scvf-local index in outside faces | ||
191 | flipScvf.index()); // global scvf index | ||
192 | 189060 | break; // go to next outside face | |
193 | } | ||
194 | } | ||
195 | |||
196 | // make sure we found it | ||
197 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 189060 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 189060 times.
|
378120 | assert(localFaceData_[faceIdxLocal*2+1].ivLocalInsideScvIndex() == outsideLocalScvIdx); |
198 | } | ||
199 | 47265 | } | |
200 | |||
201 | //! returns the number of primary scvfs of this interaction volume | ||
202 | static constexpr std::size_t numFaces() | ||
203 | { return numScvf; } | ||
204 | |||
205 | //! returns the number of intermediate unknowns within this interaction volume | ||
206 | static constexpr std::size_t numUnknowns() | ||
207 | { return numScvf; } | ||
208 | |||
209 | //! returns the number of (in this context) known solution values within this interaction volume | ||
210 | static constexpr std::size_t numKnowns() | ||
211 | { return numScv; } | ||
212 | |||
213 | //! returns the number of scvs embedded in this interaction volume | ||
214 | static constexpr std::size_t numScvs() | ||
215 | { return numScv; } | ||
216 | |||
217 | //! returns the cell-stencil of this interaction volume | ||
218 | ✗ | const Stencil& stencil() const | |
219 | ✗ | { return *stencil_; } | |
220 | |||
221 | //! returns the grid element corresponding to a given iv-local scv idx | ||
222 | const Element& element(LocalIndexType ivLocalScvIdx) const | ||
223 | 11310864 | { return elements_[ivLocalScvIdx]; } | |
224 | |||
225 | //! returns the local scvf entity corresponding to a given iv-local scvf idx | ||
226 | const LocalScvfType& localScvf(LocalIndexType ivLocalScvfIdx) const | ||
227 |
16/16✓ Branch 2 taken 1885144 times.
✓ Branch 3 taken 1885144 times.
✓ Branch 4 taken 1885144 times.
✓ Branch 5 taken 1885144 times.
✓ Branch 6 taken 1885144 times.
✓ Branch 7 taken 1885144 times.
✓ Branch 8 taken 1885144 times.
✓ Branch 9 taken 1885144 times.
✓ Branch 14 taken 942572 times.
✓ Branch 15 taken 942572 times.
✓ Branch 16 taken 942572 times.
✓ Branch 17 taken 942572 times.
✓ Branch 18 taken 942572 times.
✓ Branch 19 taken 942572 times.
✓ Branch 20 taken 942572 times.
✓ Branch 21 taken 942572 times.
|
32990020 | { return scvfs_[ivLocalScvfIdx]; } |
228 | |||
229 | //! returns the local scv entity corresponding to a given iv-local scv idx | ||
230 | const LocalScvType& localScv(LocalIndexType ivLocalScvIdx) const | ||
231 |
28/28✓ Branch 2 taken 237360 times.
✓ Branch 3 taken 712080 times.
✓ Branch 4 taken 237360 times.
✓ Branch 5 taken 712080 times.
✓ Branch 6 taken 237360 times.
✓ Branch 7 taken 712080 times.
✓ Branch 8 taken 237360 times.
✓ Branch 9 taken 712080 times.
✓ Branch 12 taken 237360 times.
✓ Branch 13 taken 712080 times.
✓ Branch 14 taken 237360 times.
✓ Branch 15 taken 712080 times.
✓ Branch 16 taken 237360 times.
✓ Branch 17 taken 712080 times.
✓ Branch 18 taken 237360 times.
✓ Branch 19 taken 712080 times.
✓ Branch 20 taken 118680 times.
✓ Branch 21 taken 356040 times.
✓ Branch 22 taken 118680 times.
✓ Branch 23 taken 356040 times.
✓ Branch 24 taken 118680 times.
✓ Branch 25 taken 356040 times.
✓ Branch 26 taken 118680 times.
✓ Branch 27 taken 356040 times.
✓ Branch 28 taken 59340 times.
✓ Branch 29 taken 178020 times.
✓ Branch 30 taken 59340 times.
✓ Branch 31 taken 178020 times.
|
27334588 | { return scvs_[ivLocalScvIdx]; } |
232 | |||
233 | //! returns a reference to the container with the local face data | ||
234 | const std::array<LocalFaceData, numScvf*2>& localFaceData() const | ||
235 |
6/6✓ Branch 0 taken 1898880 times.
✓ Branch 1 taken 2108768 times.
✓ Branch 2 taken 233926 times.
✓ Branch 4 taken 949440 times.
✓ Branch 5 taken 1054384 times.
✓ Branch 6 taken 116963 times.
|
6833647 | { return localFaceData_; } |
236 | |||
237 | //! Returns a reference to the information container on Dirichlet BCs within this iv. | ||
238 | //! Here, we return an empty container as this implementation cannot be used on boundaries. | ||
239 | const std::array<DirichletData, 0>& dirichletData() const | ||
240 | 708646 | { return dirichletData_; } | |
241 | |||
242 | //! returns the geometry of the i-th local scv | ||
243 | template< class FVElementGeometry > | ||
244 | auto getScvGeometry(LocalIndexType ivLocalScvIdx, const FVElementGeometry& fvGeometry) const | ||
245 | { return CCMpfaOScvGeometryHelper<LocalScvType>::computeScvGeometry(ivLocalScvIdx, *this, fvGeometry); } | ||
246 | |||
247 | //! returns the number of interaction volumes living around a vertex | ||
248 | template< class NI > | ||
249 | ✗ | static constexpr std::size_t numIVAtVertex(const NI& nodalIndexSet) | |
250 | ✗ | { return 1; } | |
251 | |||
252 | //! adds the iv index sets living around a vertex to a given container | ||
253 | //! and stores the the corresponding index in a map for each scvf | ||
254 | template< class IvIndexSetContainer, | ||
255 | class ScvfIndexMap, | ||
256 | class NodalIndexSet, | ||
257 | class FlipScvfIndexSet > | ||
258 | static void addIVIndexSets(IvIndexSetContainer& ivIndexSetContainer, | ||
259 | ScvfIndexMap& scvfIndexMap, | ||
260 | const NodalIndexSet& nodalIndexSet, | ||
261 | const FlipScvfIndexSet& flipScvfIndexSet) | ||
262 | { | ||
263 | // reuse the standard o-method's implementation of this | ||
264 | 690 | CCMpfaOInteractionVolume<Traits>::addIVIndexSets(ivIndexSetContainer, | |
265 | scvfIndexMap, | ||
266 | nodalIndexSet, | ||
267 | flipScvfIndexSet); | ||
268 | } | ||
269 | |||
270 | private: | ||
271 | // pointer to cell stencil (in iv index set) | ||
272 | const Stencil * stencil_ = nullptr; | ||
273 | |||
274 | // Variables defining the local scope | ||
275 | std::array<Element, numScv> elements_; | ||
276 | std::array<LocalScvType, numScv> scvs_; | ||
277 | std::array<LocalScvfType, numScvf> scvfs_; | ||
278 | std::array<LocalFaceData, numScvf*2> localFaceData_; | ||
279 | |||
280 | // Dummy dirichlet data container (compatibility with dynamic o-iv) | ||
281 | std::array<DirichletData, 0> dirichletData_; | ||
282 | }; | ||
283 | |||
284 | } // end namespace Dumux | ||
285 | |||
286 | #endif | ||
287 |