3.5-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
box/maxwellstefanslaw.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 *****************************************************************************/
25#ifndef DUMUX_DISCRETIZATION_BOX_MAXWELL_STEFAN_LAW_HH
26#define DUMUX_DISCRETIZATION_BOX_MAXWELL_STEFAN_LAW_HH
27
28#include <dune/common/float_cmp.hh>
29#include <dune/common/fmatrix.hh>
30
35
40
41namespace Dumux {
42
43// forward declaration
44template <class TypeTag, class DiscretizationMethod, ReferenceSystemFormulation referenceSystem>
46
51template <class TypeTag, ReferenceSystemFormulation referenceSystem>
52class MaxwellStefansLawImplementation<TypeTag, DiscretizationMethods::Box, referenceSystem>
53{
59 using FVElementGeometry = typename GridGeometry::LocalView;
60 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
61 using Extrusion = Extrusion_t<GridGeometry>;
62 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
63 using ElementFluxVariablesCache = typename GetPropType<TypeTag, Properties::GridFluxVariablesCache>::LocalView;
65 using Element = typename GridView::template Codim<0>::Entity;
66
67 static constexpr auto numFluidPhases = GetPropType<TypeTag, Properties::ModelTraits>::numFluidPhases();
68 static constexpr auto numComponents = GetPropType<TypeTag, Properties::ModelTraits>::numFluidComponents();
69
70 using ComponentFluxVector = Dune::FieldVector<Scalar, numComponents>;
71 using ReducedComponentVector = Dune::FieldVector<Scalar, numComponents-1>;
72 using ReducedComponentMatrix = Dune::FieldMatrix<Scalar, numComponents-1, numComponents-1>;
73
74 static_assert(referenceSystem == ReferenceSystemFormulation::massAveraged, "only the mass averaged reference system is supported for the Maxwell-Stefan formulation");
75
76public:
78
79 //return the reference system
81 { return referenceSystem; }
82
88 static ComponentFluxVector flux(const Problem& problem,
89 const Element& element,
90 const FVElementGeometry& fvGeometry,
91 const ElementVolumeVariables& elemVolVars,
92 const SubControlVolumeFace& scvf,
93 const int phaseIdx,
94 const ElementFluxVariablesCache& elemFluxVarsCache)
95 {
96 //this is to calculate the maxwellStefan diffusion in a multicomponent system.
97 //see: Multicomponent Mass Transfer. R. Taylor u. R. Krishna. J. Wiley & Sons, New York 1993
98 ComponentFluxVector componentFlux(0.0);
99 ReducedComponentMatrix reducedDiffusionMatrix(0.0);
100 ReducedComponentVector reducedFlux(0.0);
101 ComponentFluxVector moleFrac(0.0);
102 ReducedComponentVector normalX(0.0);
103
104 // evaluate gradX at integration point and interpolate density
105 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
106 const auto& shapeValues = fluxVarsCache.shapeValues();
107
108 Scalar rho(0.0);
109 Scalar avgMolarMass(0.0);
110 for (auto&& scv : scvs(fvGeometry))
111 {
112 const auto& volVars = elemVolVars[scv];
113
114 // density interpolation
115 rho += volVars.density(phaseIdx)*shapeValues[scv.indexInElement()][0];
116 //average molar mass interpolation
117 avgMolarMass += volVars.averageMolarMass(phaseIdx)*shapeValues[scv.indexInElement()][0];
118 //interpolate the mole fraction for the diffusion matrix
119 for (int compIdx = 0; compIdx < numComponents; compIdx++)
120 {
121 moleFrac[compIdx] += volVars.moleFraction(phaseIdx, compIdx)*shapeValues[scv.indexInElement()][0];
122 }
123 }
124
125 reducedDiffusionMatrix = setupMSMatrix_(problem, element, fvGeometry, elemVolVars, scvf, phaseIdx, moleFrac, avgMolarMass);
126
127 for (int compIdx = 0; compIdx < numComponents-1; compIdx++)
128 {
129 Dune::FieldVector<Scalar, GridView::dimensionworld> gradX(0.0);
130 for (auto&& scv : scvs(fvGeometry))
131 {
132 const auto& volVars = elemVolVars[scv];
133
134 // the mole/mass fraction gradient
135 gradX.axpy(volVars.moleFraction(phaseIdx, compIdx), fluxVarsCache.gradN(scv.indexInElement()));
136 }
137
138 normalX[compIdx] = gradX *scvf.unitOuterNormal();
139 }
140 reducedDiffusionMatrix.solve(reducedFlux,normalX);
141 reducedFlux *= -1.0*rho*Extrusion::area(scvf);
142
143 for (int compIdx = 0; compIdx < numComponents-1; compIdx++)
144 {
145 componentFlux[compIdx] = reducedFlux[compIdx];
146 componentFlux[numComponents-1] -= reducedFlux[compIdx];
147 }
148 return componentFlux ;
149 }
150
151private:
152
153 static ReducedComponentMatrix setupMSMatrix_(const Problem& problem,
154 const Element& element,
155 const FVElementGeometry& fvGeometry,
156 const ElementVolumeVariables& elemVolVars,
157 const SubControlVolumeFace& scvf,
158 const int phaseIdx,
159 const ComponentFluxVector moleFrac,
160 const Scalar avgMolarMass)
161 {
162 ReducedComponentMatrix reducedDiffusionMatrix(0.0);
163
164 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
165 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
166
167 //this is to not devide by 0 if the saturation in 0 and the effectiveDiffusionCoefficient becomes zero due to that
168 if(Dune::FloatCmp::eq<Scalar>(insideVolVars.saturation(phaseIdx), 0) || Dune::FloatCmp::eq<Scalar>(outsideVolVars.saturation(phaseIdx), 0))
169 return reducedDiffusionMatrix;
170
171 for (int compIIdx = 0; compIIdx < numComponents-1; compIIdx++)
172 {
173 //calculate diffusivity for i,numComponents
174 const auto xi = moleFrac[compIIdx];
175 const auto Mn = FluidSystem::molarMass(numComponents-1);
176
177 auto tinInside = insideVolVars.effectiveDiffusionCoefficient(phaseIdx, compIIdx, numComponents-1);
178 auto tinOutside = outsideVolVars.effectiveDiffusionCoefficient(phaseIdx, compIIdx, numComponents-1);
179
180 // scale by extrusion factor
181 tinInside *= insideVolVars.extrusionFactor();
182 tinOutside *= outsideVolVars.extrusionFactor();
183
184 // the resulting averaged diffusion tensor
185 const auto tin = faceTensorAverage(tinInside, tinOutside, scvf.unitOuterNormal());
186
187 //begin the entrys of the diffusion matrix of the diagonal
188 reducedDiffusionMatrix[compIIdx][compIIdx] += xi*avgMolarMass/(tin*Mn);
189
190 // now set the rest of the entries (off-diagonal and additional entries for diagonal)
191 for (int compJIdx = 0; compJIdx < numComponents; compJIdx++)
192 {
193 //we don't want to calculate e.g. water in water diffusion
194 if (compIIdx == compJIdx)
195 continue;
196
197 //calculate diffusivity for compIIdx, compJIdx
198 const auto xj = moleFrac[compJIdx];
199 const auto Mi = FluidSystem::molarMass(compIIdx);
200 const auto Mj = FluidSystem::molarMass(compJIdx);
201
202 // effective diffusion tensors
203 auto tijInside = insideVolVars.effectiveDiffusionCoefficient(phaseIdx, compIIdx, compJIdx);
204 auto tijOutside = outsideVolVars.effectiveDiffusionCoefficient(phaseIdx, compIIdx, compJIdx);
205
206 // scale by extrusion factor
207 tijInside *= insideVolVars.extrusionFactor();
208 tijOutside *= outsideVolVars.extrusionFactor();
209
210 // the resulting averaged diffusion tensor
211 const auto tij = faceTensorAverage(tijInside, tijOutside, scvf.unitOuterNormal());
212
213 reducedDiffusionMatrix[compIIdx][compIIdx] += xj*avgMolarMass/(tij*Mi);
214 if (compJIdx < numComponents-1)
215 reducedDiffusionMatrix[compIIdx][compJIdx] +=xi*(avgMolarMass/(tin*Mn) - avgMolarMass/(tij*Mj));
216 }
217 }
218 return reducedDiffusionMatrix;
219 }
220
221};
222} // end namespace Dumux
223
224#endif
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Helper classes to compute the integration elements.
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 the Maxwell- Stefan diffusion law....
Classes related to flux variables caching.
A free function to average a Tensor at an interface.
ReferenceSystemFormulation
The formulations available for Fick's law related to the reference system.
Definition: referencesystemformulation.hh:45
Definition: adapt.hh:29
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition: extrusion.hh:177
Scalar faceTensorAverage(const Scalar T1, const Scalar T2, const Dune::FieldVector< Scalar, dim > &normal)
Average of a discontinuous scalar field at discontinuity interface (for compatibility reasons with th...
Definition: facetensoraverage.hh:41
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:150
Definition: box/maxwellstefanslaw.hh:45
static constexpr ReferenceSystemFormulation referenceSystemFormulation()
Definition: box/maxwellstefanslaw.hh:80
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: box/maxwellstefanslaw.hh:88
Container storing the diffusion coefficients required by the Maxwell- Stefan diffusion law....
Definition: maxwellstefandiffusioncoefficients.hh:45
Declares all properties used in Dumux.