13#ifndef DUMUX_DISCRETIZATION_CC_TPFA_MAXWELL_STEFAN_LAW_HH
14#define DUMUX_DISCRETIZATION_CC_TPFA_MAXWELL_STEFAN_LAW_HH
16#include <dune/common/fmatrix.hh>
17#include <dune/common/float_cmp.hh>
31template <
class TypeTag,
class DiscretizationMethod, ReferenceSystemFormulation referenceSystem>
32class MaxwellStefansLawImplementation;
38template <
class TypeTag, ReferenceSystemFormulation referenceSystem>
44 using FVElementGeometry =
typename GridGeometry::LocalView;
45 using SubControlVolume =
typename GridGeometry::SubControlVolume;
46 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
48 using GridView =
typename GridGeometry::GridView;
51 using Element =
typename GridView::template Codim<0>::Entity;
53 using ElementFluxVariablesCache =
typename GridFluxVariablesCache::LocalView;
54 using FluxVariablesCache =
typename GridFluxVariablesCache::FluxVariablesCache;
57 static const int dim = GridView::dimension;
58 static const int dimWorld = GridView::dimensionworld;
65 using ComponentFluxVector = Dune::FieldVector<Scalar, numComponents>;
66 using ReducedComponentVector = Dune::FieldVector<Scalar, numComponents-1>;
67 using ReducedComponentMatrix = Dune::FieldMatrix<Scalar, numComponents-1, numComponents-1>;
76 {
return referenceSystem; }
90 static ComponentFluxVector
flux(
const Problem& problem,
91 const Element& element,
92 const FVElementGeometry& fvGeometry,
93 const ElementVolumeVariables& elemVolVars,
94 const SubControlVolumeFace& scvf,
96 const ElementFluxVariablesCache& elemFluxVarsCache)
100 ComponentFluxVector componentFlux(0.0);
101 ReducedComponentVector moleFracInside(0.0);
102 ReducedComponentVector moleFracOutside(0.0);
103 ReducedComponentVector reducedFlux(0.0);
104 ReducedComponentMatrix reducedDiffusionMatrixInside(0.0);
105 ReducedComponentMatrix reducedDiffusionMatrixOutside(0.0);
108 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
109 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
110 const auto rhoInside = insideVolVars.density(phaseIdx);
111 const auto rhoOutside = outsideVolVars.density(phaseIdx);
113 for (
int compIdx = 0; compIdx < numComponents-1; compIdx++)
116 const auto xInside = insideVolVars.moleFraction(phaseIdx, compIdx);
118 const auto xOutside = outsideVolVars.moleFraction(phaseIdx, compIdx);
120 moleFracInside[compIdx] = xInside;
121 moleFracOutside[compIdx] = xOutside;
125 if(!(Dune::FloatCmp::eq<Scalar>(insideVolVars.saturation(phaseIdx), 0) || Dune::FloatCmp::eq<Scalar>(outsideVolVars.saturation(phaseIdx), 0)))
127 const auto insideScvIdx = scvf.insideScvIdx();
128 const auto& insideScv = fvGeometry.scv(insideScvIdx);
129 const Scalar omegai = calculateOmega_(scvf,
131 insideVolVars.extrusionFactor());
134 reducedDiffusionMatrixInside = setupMSMatrix_(problem, element, fvGeometry, insideVolVars, insideScv, phaseIdx);
137 if (scvf.boundary() || scvf.numOutsideScvs() > 1)
139 moleFracOutside -= moleFracInside;
140 reducedDiffusionMatrixInside.solve(reducedFlux, moleFracOutside);
141 reducedFlux *= omegai*rhoInside;
146 const auto outsideScvIdx = scvf.outsideScvIdx();
147 const auto& outsideScv = fvGeometry.scv(outsideScvIdx);
149 reducedDiffusionMatrixOutside = setupMSMatrix_(problem, element, fvGeometry, outsideVolVars, outsideScv, phaseIdx);
153 omegaj = -1.0*calculateOmega_(scvf,
155 outsideVolVars.extrusionFactor());
157 omegaj = calculateOmega_(fvGeometry.flipScvf(scvf.index()),
159 outsideVolVars.extrusionFactor());
161 reducedDiffusionMatrixInside.invert();
162 reducedDiffusionMatrixOutside.invert();
163 reducedDiffusionMatrixInside *= omegai*rhoInside;
164 reducedDiffusionMatrixOutside *= omegaj*rhoOutside;
167 ReducedComponentVector helperVector(0.0);
168 ReducedComponentVector gradientVectori(0.0);
169 ReducedComponentVector gradientVectorj(0.0);
171 reducedDiffusionMatrixInside.mv(moleFracInside, gradientVectori);
172 reducedDiffusionMatrixOutside.mv(moleFracOutside, gradientVectorj);
174 auto gradientVectorij = (gradientVectori + gradientVectorj);
177 reducedDiffusionMatrixOutside += reducedDiffusionMatrixInside;
179 reducedDiffusionMatrixOutside.solve(helperVector, gradientVectorij);
182 helperVector -=moleFracInside;
183 reducedDiffusionMatrixInside.mv(helperVector, reducedFlux);
186 reducedFlux *= -Extrusion::area(fvGeometry, scvf);
187 for (
int compIdx = 0; compIdx < numComponents-1; compIdx++)
189 componentFlux[compIdx] = reducedFlux[compIdx];
190 componentFlux[numComponents-1] -=reducedFlux[compIdx];
193 return componentFlux ;
197 static Scalar calculateOmega_(
const SubControlVolumeFace& scvf,
198 const SubControlVolume &scv,
199 const Scalar extrusionFactor)
201 auto distanceVector = scvf.ipGlobal();
202 distanceVector -= scv.center();
203 distanceVector /= distanceVector.two_norm2();
205 Scalar omega = (distanceVector * scvf.unitOuterNormal());
206 omega *= extrusionFactor;
211 static ReducedComponentMatrix setupMSMatrix_(
const Problem& problem,
212 const Element& element,
213 const FVElementGeometry& fvGeometry,
214 const VolumeVariables& volVars,
215 const SubControlVolume& scv,
218 ReducedComponentMatrix reducedDiffusionMatrix(0.0);
221 if(Dune::FloatCmp::eq<Scalar>(volVars.saturation(phaseIdx), 0))
222 return reducedDiffusionMatrix;
224 const auto avgMolarMass = volVars.averageMolarMass(phaseIdx);
226 for (
int compIIdx = 0; compIIdx < numComponents-1; compIIdx++)
228 const auto xi = volVars.moleFraction(phaseIdx, compIIdx);
230 const auto Mn = FluidSystem::molarMass(numComponents-1);
231 Scalar tin = volVars.effectiveDiffusionCoefficient(phaseIdx, compIIdx, numComponents-1);
234 reducedDiffusionMatrix[compIIdx][compIIdx] += xi*avgMolarMass/(tin*Mn);
237 for (
int compJIdx = 0; compJIdx < numComponents; compJIdx++)
240 if (compJIdx == compIIdx)
243 const auto xj = volVars.moleFraction(phaseIdx, compJIdx);
244 const auto Mi = FluidSystem::molarMass(compIIdx);
245 const auto Mj = FluidSystem::molarMass(compJIdx);
246 Scalar tij = volVars.effectiveDiffusionCoefficient(phaseIdx, compIIdx, compJIdx);
247 reducedDiffusionMatrix[compIIdx][compIIdx] += xj*avgMolarMass/(tij*Mi);
249 if (compJIdx < numComponents-1)
250 reducedDiffusionMatrix[compIIdx][compJIdx] += xi*(avgMolarMass/(tin*Mn) - avgMolarMass/(tij*Mj));
253 return reducedDiffusionMatrix;
Container storing the diffusion coefficients required by the Maxwell- Stefan diffusion law....
Definition: maxwellstefandiffusioncoefficients.hh:33
static constexpr ReferenceSystemFormulation referenceSystemFormulation()
Definition: cctpfa/maxwellstefanslaw.hh:75
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: cctpfa/maxwellstefanslaw.hh:90
Definition: box/maxwellstefanslaw.hh:33
Defines all properties used in Dumux.
Helper classes to compute the integration elements.
Classes related to flux variables caching.
ReferenceSystemFormulation
The formulations available for Fick's law related to the reference system.
Definition: referencesystemformulation.hh:33
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:296
Container storing the diffusion coefficients required by the Maxwell- Stefan diffusion law....
The available discretization methods in Dumux.
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition: extrusion.hh:166
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
The empty filler class corresponding to EmptyCache.
Definition: fluxvariablescaching.hh:20
Definition: fluxvariablescaching.hh:55