3.2-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
staggered/freeflow/elementvolumevariables.hh
Go to the documentation of this file.
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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
24#ifndef DUMUX_DISCRETIZATION_STAGGERED_ELEMENT_VOLUMEVARIABLES_HH
25#define DUMUX_DISCRETIZATION_STAGGERED_ELEMENT_VOLUMEVARIABLES_HH
26
27#include <algorithm>
28#include <cassert>
29#include <vector>
30
31#include <dune/common/exceptions.hh>
34
35namespace Dumux {
36
41template<class GVV, bool cachingEnabled>
43{};
44
50template<class GVV>
51class StaggeredElementVolumeVariables<GVV, /*cachingEnabled*/true>
52{
53public:
56
58 using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
59
62 : gridVolVarsPtr_(&gridVolVars)
63 , numScv_(gridVolVars.problem().gridGeometry().numScv())
64 {}
65
67 template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
68 const VolumeVariables& operator [](const SubControlVolume& scv) const
69 {
70 if (scv.dofIndex() < numScv_)
71 return gridVolVars().volVars(scv.dofIndex());
72 else
73 return boundaryVolumeVariables_[getLocalIdx_(scv.dofIndex())];
74 }
75
78 const VolumeVariables& operator [](const std::size_t scvIdx) const
79 {
80 if (scvIdx < numScv_)
81 return gridVolVars().volVars(scvIdx);
82 else
83 return boundaryVolumeVariables_[getLocalIdx_(scvIdx)];
84 }
85
88 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
89 void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
90 const FVElementGeometry& fvGeometry,
91 const SolutionVector& sol)
92 {
93 // forward to the actual method
94 bind(element, fvGeometry, sol[FVElementGeometry::GridGeometry::cellCenterIdx()]);
95 }
96
99 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<!isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
100 void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
101 const FVElementGeometry& fvGeometry,
102 const SolutionVector& sol)
103 {
104 if (!fvGeometry.hasBoundaryScvf())
105 return;
106
107 clear_();
108 boundaryVolVarIndices_.reserve(fvGeometry.numScvf());
109 boundaryVolumeVariables_.reserve(fvGeometry.numScvf());
110
111 // handle the boundary volume variables
112 for (auto&& scvf : scvfs(fvGeometry))
113 {
114 // if we are not on a boundary, skip the rest
115 if (!scvf.boundary())
116 continue;
117
118 const auto& problem = gridVolVars().problem();
119 auto boundaryPriVars = gridVolVars().getBoundaryPriVars(problem, sol, element, scvf);
120 const auto elemSol = elementSolution<FVElementGeometry>(std::move(boundaryPriVars));
121 auto&& scvI = fvGeometry.scv(scvf.insideScvIdx());
122
123 VolumeVariables volVars;
124 volVars.update(elemSol,
125 problem,
126 element,
127 scvI);
128
129 boundaryVolumeVariables_.emplace_back(std::move(volVars));
130 boundaryVolVarIndices_.push_back(scvf.outsideScvIdx());
131 }
132 }
133
135 template<class FVElementGeometry, class SolutionVector>
136 void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
137 const FVElementGeometry& fvGeometry,
138 const SolutionVector& sol)
139 {}
140
143 { return *gridVolVarsPtr_; }
144
145private:
146
148 void clear_()
149 {
150 boundaryVolVarIndices_.clear();
151 boundaryVolumeVariables_.clear();
152 }
153
154 const GridVolumeVariables* gridVolVarsPtr_;
155
157 int getLocalIdx_(const int volVarIdx) const
158 {
159 auto it = std::find(boundaryVolVarIndices_.begin(), boundaryVolVarIndices_.end(), volVarIdx);
160 assert(it != boundaryVolVarIndices_.end() && "Could not find the current volume variables for volVarIdx!");
161 return std::distance(boundaryVolVarIndices_.begin(), it);
162 }
163
164 std::vector<std::size_t> boundaryVolVarIndices_;
165 std::vector<VolumeVariables> boundaryVolumeVariables_;
166 const std::size_t numScv_;
167};
168
169
175template<class GVV>
176class StaggeredElementVolumeVariables<GVV, /*cachingEnabled*/false>
177{
178 using PrimaryVariables = typename GVV::VolumeVariables::PrimaryVariables;
179
180public:
183
185 using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
186
189 : gridVolVarsPtr_(&gridVolVars) {}
190
193 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
194 void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
195 const FVElementGeometry& fvGeometry,
196 const SolutionVector& sol)
197 {
198 // forward to the actual method
199 bind(element, fvGeometry, sol[FVElementGeometry::GridGeometry::cellCenterIdx()]);
200 }
201
204 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<!isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
205 void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
206 const FVElementGeometry& fvGeometry,
207 const SolutionVector& sol)
208 {
209 clear_();
210
211 const auto& problem = gridVolVars().problem();
212 const auto& gridGeometry = fvGeometry.gridGeometry();
213 const auto globalI = gridGeometry.elementMapper().index(element);
214 const auto& map = gridGeometry.connectivityMap();
215 constexpr auto cellCenterIdx = FVElementGeometry::GridGeometry::cellCenterIdx();
216 const auto& connectivityMapI = map(cellCenterIdx, cellCenterIdx, globalI);
217 const auto numDofs = connectivityMapI.size();
218
219 auto&& scvI = fvGeometry.scv(globalI);
220
221 // resize local containers to the required size (for internal elements)
222 volumeVariables_.resize(numDofs+1);
223 volVarIndices_.resize(numDofs+1);
224 int localIdx = 0;
225
226 // Lambda to update the volume variables of the given index
227 auto doVolVarUpdate = [&](int globalJ)
228 {
229 const auto& elementJ = gridGeometry.element(globalJ);
230 auto&& scvJ = fvGeometry.scv(globalJ);
231 const auto elemSol = makeElementSolutionFromCellCenterPrivars<PrimaryVariables>(sol[globalJ]);
232 volumeVariables_[localIdx].update(elemSol,
233 problem,
234 elementJ,
235 scvJ);
236 volVarIndices_[localIdx] = scvJ.dofIndex();
237 ++localIdx;
238 };
239
240 // Update the volume variables of the element at hand
241 doVolVarUpdate(globalI);
242
243 // Update the volume variables of the neighboring elements
244 for (const auto& globalJ : connectivityMapI)
245 doVolVarUpdate(globalJ);
246
247 if (fvGeometry.hasBoundaryScvf())
248 {
249 // Update boundary volume variables
250 for (auto&& scvf : scvfs(fvGeometry))
251 {
252 // if we are not on a boundary, skip to the next scvf
253 if (!scvf.boundary())
254 continue;
255
256 volumeVariables_.resize(localIdx+1);
257 volVarIndices_.resize(localIdx+1);
258
259 auto boundaryPriVars = gridVolVars().getBoundaryPriVars(problem, sol, element, scvf);
260 auto elemSol = elementSolution<FVElementGeometry>(std::move(boundaryPriVars));
261 volumeVariables_[localIdx].update(elemSol,
262 problem,
263 element,
264 scvI);
265 volVarIndices_[localIdx] = scvf.outsideScvIdx();
266 ++localIdx;
267 }
268 }
269 }
270
273 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
274 void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
275 const FVElementGeometry& fvGeometry,
276 const SolutionVector& sol)
277 {
278 // forward to the actual method
279 bindElement(element, fvGeometry, sol[FVElementGeometry::GridGeometry::cellCenterIdx()]);
280 }
281
284 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<!isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
285 void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
286 const FVElementGeometry& fvGeometry,
287 const SolutionVector& sol)
288 {
289 clear_();
290
291 const auto globalI = fvGeometry.gridGeometry().elementMapper().index(element);
292 volumeVariables_.resize(1);
293 volVarIndices_.resize(1);
294
295 // update the volume variables of the element
296 auto&& scv = fvGeometry.scv(globalI);
297
298 const auto elemSol = makeElementSolutionFromCellCenterPrivars<PrimaryVariables>(sol[globalI]);
299 volumeVariables_[0].update(elemSol,
300 gridVolVars().problem(),
301 element,
302 scv);
303 volVarIndices_[0] = scv.dofIndex();
304 }
305
307 template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
308 const VolumeVariables& operator [](const SubControlVolume& scv) const
309 { return volumeVariables_[getLocalIdx_(scv.dofIndex())]; }
310
312 template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
313 VolumeVariables& operator [](const SubControlVolume& scv)
314 { return volumeVariables_[getLocalIdx_(scv.dofIndex())]; }
315
317 const VolumeVariables& operator [](std::size_t scvIdx) const
318 { return volumeVariables_[getLocalIdx_(scvIdx)]; }
319
321 VolumeVariables& operator [](std::size_t scvIdx)
322 { return volumeVariables_[getLocalIdx_(scvIdx)]; }
323
326 { return *gridVolVarsPtr_; }
327
328private:
330 void clear_()
331 {
332 volVarIndices_.clear();
333 volumeVariables_.clear();
334 }
335
336 const GridVolumeVariables* gridVolVarsPtr_;
337
338 int getLocalIdx_(const int volVarIdx) const
339 {
340 auto it = std::find(volVarIndices_.begin(), volVarIndices_.end(), volVarIdx);
341 assert(it != volVarIndices_.end() && "Could not find the current volume variables for volVarIdx!");
342 return std::distance(volVarIndices_.begin(), it);
343 }
344
345 std::vector<std::size_t> volVarIndices_;
346 std::vector<VolumeVariables> volumeVariables_;
347};
348
349} // end namespace Dumux
350
351#endif
Type traits to be used with vector types.
Definition: adapt.hh:29
Base class for the element volume variables vector for the staggered model.
Definition: staggered/freeflow/elementvolumevariables.hh:43
typename GridVolumeVariables::VolumeVariables VolumeVariables
export type of the volume variables
Definition: staggered/freeflow/elementvolumevariables.hh:58
const GridVolumeVariables & gridVolVars() const
The global volume variables object we are a restriction of.
Definition: staggered/freeflow/elementvolumevariables.hh:142
GVV GridVolumeVariables
export type of the grid volume variables
Definition: staggered/freeflow/elementvolumevariables.hh:55
StaggeredElementVolumeVariables(const GridVolumeVariables &gridVolVars)
Constructor.
Definition: staggered/freeflow/elementvolumevariables.hh:61
void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol)
function to prepare the vol vars within the element
Definition: staggered/freeflow/elementvolumevariables.hh:136
void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol)
Definition: staggered/freeflow/elementvolumevariables.hh:89
GVV GridVolumeVariables
export type of the grid volume variables
Definition: staggered/freeflow/elementvolumevariables.hh:182
StaggeredElementVolumeVariables(const GridVolumeVariables &gridVolVars)
Constructor.
Definition: staggered/freeflow/elementvolumevariables.hh:188
typename GridVolumeVariables::VolumeVariables VolumeVariables
export type of the volume variables
Definition: staggered/freeflow/elementvolumevariables.hh:185
const GridVolumeVariables & gridVolVars() const
The global volume variables object we are a restriction of.
Definition: staggered/freeflow/elementvolumevariables.hh:325
void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol)
Definition: staggered/freeflow/elementvolumevariables.hh:194
void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol)
Definition: staggered/freeflow/elementvolumevariables.hh:274
The local element solution class for staggered methods.