3.5-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
flux/ccmpfa/fickslaw.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_CC_MPFA_FICKS_LAW_HH
25#define DUMUX_DISCRETIZATION_CC_MPFA_FICKS_LAW_HH
26
27#include <dune/common/fvector.hh>
30
33
34namespace Dumux {
35
37template<class TypeTag, class DiscretizationMethod, ReferenceSystemFormulation referenceSystem>
38class FicksLawImplementation;
39
44template <class TypeTag, ReferenceSystemFormulation referenceSystem>
45class FicksLawImplementation<TypeTag, DiscretizationMethods::CCMpfa, referenceSystem>
46{
50 using Element = typename GridView::template Codim<0>::Entity;
51
52 static constexpr int dim = GridView::dimension;
53 static constexpr int dimWorld = GridView::dimensionworld;
54
56 using FVElementGeometry = typename GridGeometry::LocalView;
58 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
59 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
60 using ElementFluxVariablesCache = typename GetPropType<TypeTag, Properties::GridFluxVariablesCache>::LocalView;
63
64 static constexpr int numComponents = GetPropType<TypeTag, Properties::ModelTraits>::numFluidComponents();
66 using ComponentFluxVector = Dune::FieldVector<Scalar, numComponents>;
67
69 class MpfaFicksLawCacheFiller
70 {
71 public:
74 template<class FluxVariablesCacheFiller>
75 static void fill(FluxVariablesCache& scvfFluxVarsCache,
76 unsigned int phaseIdx, unsigned int compIdx,
77 const Problem& problem,
78 const Element& element,
79 const FVElementGeometry& fvGeometry,
80 const ElementVolumeVariables& elemVolVars,
81 const SubControlVolumeFace& scvf,
82 const FluxVariablesCacheFiller& fluxVarsCacheFiller)
83 {
84 // get interaction volume related data from the filler class & upate the cache
85 if (fvGeometry.gridGeometry().vertexUsesSecondaryInteractionVolume(scvf.vertexIndex()))
86 scvfFluxVarsCache.updateDiffusion(fluxVarsCacheFiller.secondaryInteractionVolume(),
87 fluxVarsCacheFiller.secondaryIvLocalFaceData(),
88 fluxVarsCacheFiller.secondaryIvDataHandle(),
89 phaseIdx, compIdx);
90 else
91 scvfFluxVarsCache.updateDiffusion(fluxVarsCacheFiller.primaryInteractionVolume(),
92 fluxVarsCacheFiller.primaryIvLocalFaceData(),
93 fluxVarsCacheFiller.primaryIvDataHandle(),
94 phaseIdx, compIdx);
95 }
96 };
97
99 class MpfaFicksLawCache
100 {
102 using Stencil = typename DualGridNodalIndexSet::NodalGridStencilType;
103
104 static constexpr int numPhases = GetPropType<TypeTag, Properties::ModelTraits>::numFluidPhases();
105 static constexpr bool considerSecondaryIVs = GridGeometry::MpfaHelper::considerSecondaryIVs();
106 using PrimaryDataHandle = typename ElementFluxVariablesCache::PrimaryIvDataHandle::DiffusionHandle;
107 using SecondaryDataHandle = typename ElementFluxVariablesCache::SecondaryIvDataHandle::DiffusionHandle;
108
110 template< bool doSecondary = considerSecondaryIVs, std::enable_if_t<doSecondary, int> = 0 >
111 void setHandlePointer_(const SecondaryDataHandle& dataHandle)
112 { secondaryHandlePtr_ = &dataHandle; }
113
115 void setHandlePointer_(const PrimaryDataHandle& dataHandle)
116 { primaryHandlePtr_ = &dataHandle; }
117
118 public:
119 // export filler type
120 using Filler = MpfaFicksLawCacheFiller;
121
130 template<class IV, class LocalFaceData, class DataHandle>
131 void updateDiffusion(const IV& iv,
132 const LocalFaceData& localFaceData,
133 const DataHandle& dataHandle,
134 unsigned int phaseIdx, unsigned int compIdx)
135 {
136 stencil_[phaseIdx][compIdx] = &iv.stencil();
137 switchFluxSign_[phaseIdx][compIdx] = localFaceData.isOutsideFace();
138 setHandlePointer_(dataHandle.diffusionHandle());
139 }
140
142 const Stencil& diffusionStencil(unsigned int phaseIdx, unsigned int compIdx) const
143 { return *stencil_[phaseIdx][compIdx]; }
144
146 const PrimaryDataHandle& diffusionPrimaryDataHandle() const { return *primaryHandlePtr_; }
147 const SecondaryDataHandle& diffusionSecondaryDataHandle() const { return *secondaryHandlePtr_; }
148
150 bool diffusionSwitchFluxSign(unsigned int phaseIdx, unsigned int compIdx) const
151 { return switchFluxSign_[phaseIdx][compIdx]; }
152
153
154 private:
156 std::array< std::array<bool, numComponents>, numPhases > switchFluxSign_;
157 std::array< std::array<const Stencil*, numComponents>, numPhases > stencil_;
158
160 const PrimaryDataHandle* primaryHandlePtr_;
161 const SecondaryDataHandle* secondaryHandlePtr_;
162 };
163
164public:
166 // state the discretization method this implementation belongs to
167 static constexpr DiscretizationMethod discMethod{};
168
169 //return the reference system
171 { return referenceSystem; }
172
173 // state the type for the corresponding cache and its filler
174 using Cache = MpfaFicksLawCache;
175
176 // export the diffusion container
178
185 static ComponentFluxVector flux(const Problem& problem,
186 const Element& element,
187 const FVElementGeometry& fvGeometry,
188 const ElementVolumeVariables& elemVolVars,
189 const SubControlVolumeFace& scvf,
190 const int phaseIdx,
191 const ElementFluxVariablesCache& elemFluxVarsCache)
192 {
193 // obtain this scvf's cache
194 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
195
196 ComponentFluxVector componentFlux(0.0);
197 for (int compIdx = 0; compIdx < numComponents; compIdx++)
198 {
199 if constexpr (!FluidSystem::isTracerFluidSystem())
200 if (compIdx == FluidSystem::getMainComponent(phaseIdx))
201 continue;
202
203 // calculate the density at the interface
204 const auto rho = interpolateDensity(elemVolVars, scvf, phaseIdx);
205
206 // compute the flux
207 if (fluxVarsCache.usesSecondaryIv())
208 componentFlux[compIdx] = rho*computeVolumeFlux(problem,
209 fluxVarsCache,
210 fluxVarsCache.diffusionSecondaryDataHandle(),
211 phaseIdx, compIdx);
212 else
213 componentFlux[compIdx] = rho*computeVolumeFlux(problem,
214 fluxVarsCache,
215 fluxVarsCache.diffusionPrimaryDataHandle(),
216 phaseIdx, compIdx);
217 }
218
219 // accumulate the phase component flux
220 for (int compIdx = 0; compIdx < numComponents; compIdx++)
221 if constexpr (!FluidSystem::isTracerFluidSystem())
222 if (compIdx != FluidSystem::getMainComponent(phaseIdx) && BalanceEqOpts::mainComponentIsBalanced(phaseIdx))
223 componentFlux[FluidSystem::getMainComponent(phaseIdx)] -= componentFlux[compIdx];
224
225 return componentFlux;
226 }
227
228private:
229 template< class Problem, class FluxVarsCache, class DataHandle >
230 static Scalar computeVolumeFlux(const Problem& problem,
231 const FluxVarsCache& cache,
232 const DataHandle& dataHandle,
233 int phaseIdx, int compIdx)
234 {
235 dataHandle.setPhaseIndex(phaseIdx);
236 dataHandle.setComponentIndex(compIdx);
237
238 const bool switchSign = cache.diffusionSwitchFluxSign(phaseIdx, compIdx);
239
240 const auto localFaceIdx = cache.ivLocalFaceIndex();
241 const auto idxInOutside = cache.indexInOutsideFaces();
242 const auto& xj = dataHandle.uj();
243 const auto& tij = dim == dimWorld ? dataHandle.T()[localFaceIdx]
244 : (!switchSign ? dataHandle.T()[localFaceIdx]
245 : dataHandle.tijOutside()[localFaceIdx][idxInOutside]);
246 Scalar scvfFlux = tij*xj;
247
248 // switch the sign if necessary
249 if (switchSign)
250 scvfFlux *= -1.0;
251
252 return scvfFlux;
253 }
254
256 static Scalar interpolateDensity(const ElementVolumeVariables& elemVolVars,
257 const SubControlVolumeFace& scvf,
258 const unsigned int phaseIdx)
259 {
260 // use arithmetic mean of the densities around the scvf
261 if (!scvf.boundary())
262 {
263 const Scalar rhoInside = massOrMolarDensity(elemVolVars[scvf.insideScvIdx()], referenceSystem, phaseIdx);
264
265 Scalar rho = rhoInside;
266 for (const auto outsideIdx : scvf.outsideScvIndices())
267 {
268 const Scalar rhoOutside = massOrMolarDensity(elemVolVars[outsideIdx], referenceSystem, phaseIdx);
269 rho += rhoOutside;
270 }
271 return rho/(scvf.outsideScvIndices().size()+1);
272 }
273 else
274 return massOrMolarDensity(elemVolVars[scvf.outsideScvIdx()], referenceSystem, phaseIdx);
275 }
276};
277
278} // end namespace
279
280#endif
The available discretization methods in Dumux.
The reference frameworks and formulations available for splitting total fluxes into a advective and d...
Container storing the diffusion coefficients required by Fick's law. Uses the minimal possible contai...
VolumeVariables::PrimaryVariables::value_type massOrMolarDensity(const VolumeVariables &volVars, ReferenceSystemFormulation referenceSys, const int phaseIdx)
evaluates the density to be used in Fick's law based on the reference system
Definition: referencesystemformulation.hh:55
ReferenceSystemFormulation
The formulations available for Fick's law related to the reference system.
Definition: referencesystemformulation.hh:45
Definition: adapt.hh:29
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:150
Definition: method.hh:61
forward declaration of the method-specific implemetation
Definition: flux/box/fickslaw.hh:44
static ComponentFluxVector flux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf, const int phaseIdx, const ElementFluxVariablesCache &elemFluxVarsCache)
Returns the diffusive fluxes of all components within a fluid phase across the given sub-control volu...
Definition: flux/ccmpfa/fickslaw.hh:185
static constexpr ReferenceSystemFormulation referenceSystemFormulation()
Definition: flux/ccmpfa/fickslaw.hh:170
Container storing the diffusion coefficients required by Fick's law. Uses the minimal possible contai...
Definition: fickiandiffusioncoefficients.hh:44
Declares all properties used in Dumux.