3.6-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#include <utility>
31
32#include <dune/common/exceptions.hh>
35
36namespace Dumux {
37
42template<class GVV, bool cachingEnabled>
44{};
45
51template<class GVV>
52class StaggeredElementVolumeVariables<GVV, /*cachingEnabled*/true>
53{
54public:
57
59 using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
60
63 : gridVolVarsPtr_(&gridVolVars)
64 , numScv_(gridVolVars.problem().gridGeometry().numScv())
65 {}
66
68 template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
69 const VolumeVariables& operator [](const SubControlVolume& scv) const
70 {
71 if (scv.dofIndex() < numScv_)
72 return gridVolVars().volVars(scv.dofIndex());
73 else
74 return boundaryVolumeVariables_[getLocalIdx_(scv.dofIndex())];
75 }
76
79 const VolumeVariables& operator [](const std::size_t scvIdx) const
80 {
81 if (scvIdx < numScv_)
82 return gridVolVars().volVars(scvIdx);
83 else
84 return boundaryVolumeVariables_[getLocalIdx_(scvIdx)];
85 }
86
92 template<class FVElementGeometry, class SolutionVector>
93 StaggeredElementVolumeVariables bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
94 const FVElementGeometry& fvGeometry,
95 const SolutionVector& sol) &&
96 {
97 this->bind_(element, fvGeometry, sol);
98 return std::move(*this);
99 }
100
101 template<class FVElementGeometry, class SolutionVector>
102 void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
103 const FVElementGeometry& fvGeometry,
104 const SolutionVector& sol) &
105 { this->bind_(element, fvGeometry, sol); }
106
112 template<class FVElementGeometry, class SolutionVector>
113 StaggeredElementVolumeVariables bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
114 const FVElementGeometry& fvGeometry,
115 const SolutionVector& sol) &&
116 {
117 this->bindElement_(element, fvGeometry, sol);
118 return std::move(*this);
119 }
120
121 template<class FVElementGeometry, class SolutionVector>
122 void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
123 const FVElementGeometry& fvGeometry,
124 const SolutionVector& sol) &
125 { this->bindElement_(element, fvGeometry, sol); }
126
129 { return *gridVolVarsPtr_; }
130
131private:
132
134 void clear_()
135 {
136 boundaryVolVarIndices_.clear();
137 boundaryVolumeVariables_.clear();
138 }
139
142 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
143 void bind_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
144 const FVElementGeometry& fvGeometry,
145 const SolutionVector& sol)
146 {
147 // forward to the actual method
148 bind_(element, fvGeometry, sol[FVElementGeometry::GridGeometry::cellCenterIdx()]);
149 }
150
153 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<!isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
154 void bind_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
155 const FVElementGeometry& fvGeometry,
156 const SolutionVector& sol)
157 {
158 if (!fvGeometry.hasBoundaryScvf())
159 return;
160
161 clear_();
162 boundaryVolVarIndices_.reserve(fvGeometry.numScvf());
163 boundaryVolumeVariables_.reserve(fvGeometry.numScvf());
164
165 // handle the boundary volume variables
166 for (auto&& scvf : scvfs(fvGeometry))
167 {
168 // if we are not on a boundary, skip the rest
169 if (!scvf.boundary())
170 continue;
171
172 const auto& problem = gridVolVars().problem();
173 auto boundaryPriVars = gridVolVars().getBoundaryPriVars(problem, sol, element, scvf);
174 const auto elemSol = elementSolution<FVElementGeometry>(std::move(boundaryPriVars));
175 auto&& scvI = fvGeometry.scv(scvf.insideScvIdx());
176
177 VolumeVariables volVars;
178 volVars.update(elemSol,
179 problem,
180 element,
181 scvI);
182
183 boundaryVolumeVariables_.emplace_back(std::move(volVars));
184 boundaryVolVarIndices_.push_back(scvf.outsideScvIdx());
185 }
186 }
187
189 template<class FVElementGeometry, class SolutionVector>
190 void bindElement_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
191 const FVElementGeometry& fvGeometry,
192 const SolutionVector& sol)
193 {}
194
195 const GridVolumeVariables* gridVolVarsPtr_;
196
198 int getLocalIdx_(const int volVarIdx) const
199 {
200 auto it = std::find(boundaryVolVarIndices_.begin(), boundaryVolVarIndices_.end(), volVarIdx);
201 assert(it != boundaryVolVarIndices_.end() && "Could not find the current volume variables for volVarIdx!");
202 return std::distance(boundaryVolVarIndices_.begin(), it);
203 }
204
205 std::vector<std::size_t> boundaryVolVarIndices_;
206 std::vector<VolumeVariables> boundaryVolumeVariables_;
207 const std::size_t numScv_;
208};
209
210
216template<class GVV>
217class StaggeredElementVolumeVariables<GVV, /*cachingEnabled*/false>
218{
219 using PrimaryVariables = typename GVV::VolumeVariables::PrimaryVariables;
220
221public:
224
226 using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
227
230 : gridVolVarsPtr_(&gridVolVars) {}
231
237 template<class FVElementGeometry, class SolutionVector>
238 StaggeredElementVolumeVariables bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
239 const FVElementGeometry& fvGeometry,
240 const SolutionVector& sol) &&
241 {
242 this->bind_(element, fvGeometry, sol);
243 return std::move(*this);
244 }
245
246 template<class FVElementGeometry, class SolutionVector>
247 void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
248 const FVElementGeometry& fvGeometry,
249 const SolutionVector& sol) &
250 { this->bind_(element, fvGeometry, sol); }
251
257 template<class FVElementGeometry, class SolutionVector>
258 StaggeredElementVolumeVariables bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
259 const FVElementGeometry& fvGeometry,
260 const SolutionVector& sol) &&
261 {
262 this->bindElement_(element, fvGeometry, sol);
263 return std::move(*this);
264 }
265
266 template<class FVElementGeometry, class SolutionVector>
267 void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
268 const FVElementGeometry& fvGeometry,
269 const SolutionVector& sol) &
270 { this->bindElement_(element, fvGeometry, sol); }
271
273 template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
274 const VolumeVariables& operator [](const SubControlVolume& scv) const
275 { return volumeVariables_[getLocalIdx_(scv.dofIndex())]; }
276
278 template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
279 VolumeVariables& operator [](const SubControlVolume& scv)
280 { return volumeVariables_[getLocalIdx_(scv.dofIndex())]; }
281
283 const VolumeVariables& operator [](std::size_t scvIdx) const
284 { return volumeVariables_[getLocalIdx_(scvIdx)]; }
285
287 VolumeVariables& operator [](std::size_t scvIdx)
288 { return volumeVariables_[getLocalIdx_(scvIdx)]; }
289
292 { return *gridVolVarsPtr_; }
293
294private:
297 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
298 void bind_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
299 const FVElementGeometry& fvGeometry,
300 const SolutionVector& sol)
301 {
302 // forward to the actual method
303 bind_(element, fvGeometry, sol[FVElementGeometry::GridGeometry::cellCenterIdx()]);
304 }
305
308 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<!isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
309 void bind_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
310 const FVElementGeometry& fvGeometry,
311 const SolutionVector& sol)
312 {
313 clear_();
314
315 const auto& problem = gridVolVars().problem();
316 const auto& gridGeometry = fvGeometry.gridGeometry();
317 const auto globalI = gridGeometry.elementMapper().index(element);
318 const auto& map = gridGeometry.connectivityMap();
319 constexpr auto cellCenterIdx = FVElementGeometry::GridGeometry::cellCenterIdx();
320 const auto& connectivityMapI = map(cellCenterIdx, cellCenterIdx, globalI);
321 const auto numDofs = connectivityMapI.size();
322
323 auto&& scvI = fvGeometry.scv(globalI);
324
325 // resize local containers to the required size (for internal elements)
326 volumeVariables_.resize(numDofs+1);
327 volVarIndices_.resize(numDofs+1);
328 int localIdx = 0;
329
330 // Lambda to update the volume variables of the given index
331 auto doVolVarUpdate = [&](int globalJ)
332 {
333 const auto& elementJ = gridGeometry.element(globalJ);
334 auto&& scvJ = fvGeometry.scv(globalJ);
335 const auto elemSol = makeElementSolutionFromCellCenterPrivars<PrimaryVariables>(sol[globalJ]);
336 volumeVariables_[localIdx].update(elemSol,
337 problem,
338 elementJ,
339 scvJ);
340 volVarIndices_[localIdx] = scvJ.dofIndex();
341 ++localIdx;
342 };
343
344 // Update the volume variables of the element at hand
345 doVolVarUpdate(globalI);
346
347 // Update the volume variables of the neighboring elements
348 for (const auto& globalJ : connectivityMapI)
349 doVolVarUpdate(globalJ);
350
351 if (fvGeometry.hasBoundaryScvf())
352 {
353 // Update boundary volume variables
354 for (auto&& scvf : scvfs(fvGeometry))
355 {
356 // if we are not on a boundary, skip to the next scvf
357 if (!scvf.boundary())
358 continue;
359
360 volumeVariables_.resize(localIdx+1);
361 volVarIndices_.resize(localIdx+1);
362
363 auto boundaryPriVars = gridVolVars().getBoundaryPriVars(problem, sol, element, scvf);
364 auto elemSol = elementSolution<FVElementGeometry>(std::move(boundaryPriVars));
365 volumeVariables_[localIdx].update(elemSol,
366 problem,
367 element,
368 scvI);
369 volVarIndices_[localIdx] = scvf.outsideScvIdx();
370 ++localIdx;
371 }
372 }
373 }
374
377 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
378 void bindElement_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
379 const FVElementGeometry& fvGeometry,
380 const SolutionVector& sol)
381 {
382 // forward to the actual method
383 bindElement_(element, fvGeometry, sol[FVElementGeometry::GridGeometry::cellCenterIdx()]);
384 }
385
388 template<class FVElementGeometry, class SolutionVector, typename std::enable_if_t<!isMultiTypeBlockVector<SolutionVector>::value, int> = 0>
389 void bindElement_(const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
390 const FVElementGeometry& fvGeometry,
391 const SolutionVector& sol)
392 {
393 clear_();
394
395 const auto globalI = fvGeometry.gridGeometry().elementMapper().index(element);
396 volumeVariables_.resize(1);
397 volVarIndices_.resize(1);
398
399 // update the volume variables of the element
400 auto&& scv = fvGeometry.scv(globalI);
401
402 const auto elemSol = makeElementSolutionFromCellCenterPrivars<PrimaryVariables>(sol[globalI]);
403 volumeVariables_[0].update(elemSol,
404 gridVolVars().problem(),
405 element,
406 scv);
407 volVarIndices_[0] = scv.dofIndex();
408 }
409
411 void clear_()
412 {
413 volVarIndices_.clear();
414 volumeVariables_.clear();
415 }
416
417 const GridVolumeVariables* gridVolVarsPtr_;
418
419 int getLocalIdx_(const int volVarIdx) const
420 {
421 auto it = std::find(volVarIndices_.begin(), volVarIndices_.end(), volVarIdx);
422 assert(it != volVarIndices_.end() && "Could not find the current volume variables for volVarIdx!");
423 return std::distance(volVarIndices_.begin(), it);
424 }
425
426 std::vector<std::size_t> volVarIndices_;
427 std::vector<VolumeVariables> volumeVariables_;
428};
429
430} // end namespace Dumux
431
432#endif
Type traits to be used with vector types.
static ctype distance(const Dune::FieldVector< ctype, dimWorld > &a, const Dune::FieldVector< ctype, dimWorld > &b)
Compute the shortest distance between two points.
Definition: distance.hh:294
Adaption of the non-isothermal two-phase two-component flow model to problems with CO2.
Definition: adapt.hh:29
Base class for the element volume variables vector for the staggered model.
Definition: staggered/freeflow/elementvolumevariables.hh:44
typename GridVolumeVariables::VolumeVariables VolumeVariables
export type of the volume variables
Definition: staggered/freeflow/elementvolumevariables.hh:59
const GridVolumeVariables & gridVolVars() const
The global volume variables object we are a restriction of.
Definition: staggered/freeflow/elementvolumevariables.hh:128
void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol) &
Definition: staggered/freeflow/elementvolumevariables.hh:122
GVV GridVolumeVariables
export type of the grid volume variables
Definition: staggered/freeflow/elementvolumevariables.hh:56
StaggeredElementVolumeVariables bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol) &&
bind the local view (r-value overload) This overload is called when an instance of this class is a te...
Definition: staggered/freeflow/elementvolumevariables.hh:113
StaggeredElementVolumeVariables(const GridVolumeVariables &gridVolVars)
Constructor.
Definition: staggered/freeflow/elementvolumevariables.hh:62
StaggeredElementVolumeVariables bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol) &&
bind the local view (r-value overload) This overload is called when an instance of this class is a te...
Definition: staggered/freeflow/elementvolumevariables.hh:93
void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol) &
Definition: staggered/freeflow/elementvolumevariables.hh:102
GVV GridVolumeVariables
export type of the grid volume variables
Definition: staggered/freeflow/elementvolumevariables.hh:223
StaggeredElementVolumeVariables bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol) &&
bind the local view (r-value overload) This overload is called when an instance of this class is a te...
Definition: staggered/freeflow/elementvolumevariables.hh:238
StaggeredElementVolumeVariables bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol) &&
bind the local view (r-value overload) This overload is called when an instance of this class is a te...
Definition: staggered/freeflow/elementvolumevariables.hh:258
void bind(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol) &
Definition: staggered/freeflow/elementvolumevariables.hh:247
StaggeredElementVolumeVariables(const GridVolumeVariables &gridVolVars)
Constructor.
Definition: staggered/freeflow/elementvolumevariables.hh:229
void bindElement(const typename FVElementGeometry::GridGeometry::GridView::template Codim< 0 >::Entity &element, const FVElementGeometry &fvGeometry, const SolutionVector &sol) &
Definition: staggered/freeflow/elementvolumevariables.hh:267
typename GridVolumeVariables::VolumeVariables VolumeVariables
export type of the volume variables
Definition: staggered/freeflow/elementvolumevariables.hh:226
const GridVolumeVariables & gridVolVars() const
The global volume variables object we are a restriction of.
Definition: staggered/freeflow/elementvolumevariables.hh:291
The local element solution class for staggered methods.