3.4
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, DiscretizationMethod discMethod, ReferenceSystemFormulation referenceSystem>
38class FicksLawImplementation;
39
44template <class TypeTag, ReferenceSystemFormulation referenceSystem>
45class FicksLawImplementation<TypeTag, DiscretizationMethod::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:
165 // state the discretization method this implementation belongs to
167
168 //return the reference system
170 { return referenceSystem; }
171
172 // state the type for the corresponding cache and its filler
173 using Cache = MpfaFicksLawCache;
174
175 // export the diffusion container
177
184 static ComponentFluxVector flux(const Problem& problem,
185 const Element& element,
186 const FVElementGeometry& fvGeometry,
187 const ElementVolumeVariables& elemVolVars,
188 const SubControlVolumeFace& scvf,
189 const int phaseIdx,
190 const ElementFluxVariablesCache& elemFluxVarsCache)
191 {
192 // obtain this scvf's cache
193 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
194
195 ComponentFluxVector componentFlux(0.0);
196 for (int compIdx = 0; compIdx < numComponents; compIdx++)
197 {
198 if constexpr (!FluidSystem::isTracerFluidSystem())
199 if (compIdx == FluidSystem::getMainComponent(phaseIdx))
200 continue;
201
202 // calculate the density at the interface
203 const auto rho = interpolateDensity(elemVolVars, scvf, phaseIdx);
204
205 // compute the flux
206 if (fluxVarsCache.usesSecondaryIv())
207 componentFlux[compIdx] = rho*computeVolumeFlux(problem,
208 fluxVarsCache,
209 fluxVarsCache.diffusionSecondaryDataHandle(),
210 phaseIdx, compIdx);
211 else
212 componentFlux[compIdx] = rho*computeVolumeFlux(problem,
213 fluxVarsCache,
214 fluxVarsCache.diffusionPrimaryDataHandle(),
215 phaseIdx, compIdx);
216 }
217
218 // accumulate the phase component flux
219 for (int compIdx = 0; compIdx < numComponents; compIdx++)
220 if constexpr (!FluidSystem::isTracerFluidSystem())
221 if (compIdx != FluidSystem::getMainComponent(phaseIdx) && BalanceEqOpts::mainComponentIsBalanced(phaseIdx))
222 componentFlux[FluidSystem::getMainComponent(phaseIdx)] -= componentFlux[compIdx];
223
224 return componentFlux;
225 }
226
227private:
228 template< class Problem, class FluxVarsCache, class DataHandle >
229 static Scalar computeVolumeFlux(const Problem& problem,
230 const FluxVarsCache& cache,
231 const DataHandle& dataHandle,
232 int phaseIdx, int compIdx)
233 {
234 dataHandle.setPhaseIndex(phaseIdx);
235 dataHandle.setComponentIndex(compIdx);
236
237 const bool switchSign = cache.diffusionSwitchFluxSign(phaseIdx, compIdx);
238
239 const auto localFaceIdx = cache.ivLocalFaceIndex();
240 const auto idxInOutside = cache.indexInOutsideFaces();
241 const auto& xj = dataHandle.uj();
242 const auto& tij = dim == dimWorld ? dataHandle.T()[localFaceIdx]
243 : (!switchSign ? dataHandle.T()[localFaceIdx]
244 : dataHandle.tijOutside()[localFaceIdx][idxInOutside]);
245 Scalar scvfFlux = tij*xj;
246
247 // switch the sign if necessary
248 if (switchSign)
249 scvfFlux *= -1.0;
250
251 return scvfFlux;
252 }
253
255 static Scalar interpolateDensity(const ElementVolumeVariables& elemVolVars,
256 const SubControlVolumeFace& scvf,
257 const unsigned int phaseIdx)
258 {
259 // use arithmetic mean of the densities around the scvf
260 if (!scvf.boundary())
261 {
262 const Scalar rhoInside = massOrMolarDensity(elemVolVars[scvf.insideScvIdx()], referenceSystem, phaseIdx);
263
264 Scalar rho = rhoInside;
265 for (const auto outsideIdx : scvf.outsideScvIndices())
266 {
267 const Scalar rhoOutside = massOrMolarDensity(elemVolVars[outsideIdx], referenceSystem, phaseIdx);
268 rho += rhoOutside;
269 }
270 return rho/(scvf.outsideScvIndices().size()+1);
271 }
272 else
273 return massOrMolarDensity(elemVolVars[scvf.outsideScvIdx()], referenceSystem, phaseIdx);
274 }
275};
276
277} // end namespace
278
279#endif
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...
The available discretization methods in Dumux.
DiscretizationMethod
The available discretization methods in Dumux.
Definition: method.hh:37
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
forward declaration of the method-specific implemetation
Definition: flux/box/fickslaw.hh:43
static constexpr ReferenceSystemFormulation referenceSystemFormulation()
Definition: flux/ccmpfa/fickslaw.hh:169
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:184
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.