55 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
56 using SubControlVolumeFace =
typename FVElementGeometry::SubControlVolumeFace;
60 using Element =
typename GridView::template Codim<0>::Entity;
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>;
75 {
return referenceSystem; }
77 static ComponentFluxVector
flux(
const Problem& problem,
78 const Element& element,
79 const FVElementGeometry& fvGeometry,
80 const ElementVolumeVariables& elemVolVars,
81 const SubControlVolumeFace& scvf,
83 const ElementFluxVariablesCache& elemFluxVarsCache)
87 ComponentFluxVector componentFlux(0.0);
88 ReducedComponentMatrix reducedDiffusionMatrix(0.0);
89 ReducedComponentVector reducedFlux(0.0);
90 ComponentFluxVector moleFrac(0.0);
91 ReducedComponentVector normalX(0.0);
94 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
95 const auto& shapeValues = fluxVarsCache.shapeValues();
98 Scalar avgMolarMass(0.0);
99 for (
auto&& scv : scvs(fvGeometry))
101 const auto& volVars = elemVolVars[scv];
104 rho += volVars.density(phaseIdx)*shapeValues[scv.indexInElement()][0];
106 avgMolarMass += volVars.averageMolarMass(phaseIdx)*shapeValues[scv.indexInElement()][0];
108 for (
int compIdx = 0; compIdx < numComponents; compIdx++)
110 moleFrac[compIdx] += volVars.moleFraction(phaseIdx, compIdx)*shapeValues[scv.indexInElement()][0];
114 reducedDiffusionMatrix = setupMSMatrix_(problem, element, fvGeometry, elemVolVars, scvf, phaseIdx, moleFrac, avgMolarMass);
116 for (
int compIdx = 0; compIdx < numComponents-1; compIdx++)
118 Dune::FieldVector<Scalar, GridView::dimensionworld> gradX(0.0);
119 for (
auto&& scv : scvs(fvGeometry))
121 const auto& volVars = elemVolVars[scv];
124 gradX.axpy(volVars.moleFraction(phaseIdx, compIdx), fluxVarsCache.gradN(scv.indexInElement()));
127 normalX[compIdx] = gradX *scvf.unitOuterNormal();
129 reducedDiffusionMatrix.solve(reducedFlux,normalX);
130 reducedFlux *= -1.0*rho*scvf.area();
132 for (
int compIdx = 0; compIdx < numComponents-1; compIdx++)
134 componentFlux[compIdx] = reducedFlux[compIdx];
135 componentFlux[numComponents-1] -= reducedFlux[compIdx];
137 return componentFlux ;
142 static ReducedComponentMatrix setupMSMatrix_(
const Problem& problem,
143 const Element& element,
144 const FVElementGeometry& fvGeometry,
145 const ElementVolumeVariables& elemVolVars,
146 const SubControlVolumeFace& scvf,
148 const ComponentFluxVector moleFrac,
149 const Scalar avgMolarMass)
151 ReducedComponentMatrix reducedDiffusionMatrix(0.0);
153 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
154 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
155 const auto insideScvIdx = scvf.insideScvIdx();
156 const auto outsideScvIdx = scvf.outsideScvIdx();
159 if(Dune::FloatCmp::eq<Scalar>(insideVolVars.saturation(phaseIdx), 0) || Dune::FloatCmp::eq<Scalar>(outsideVolVars.saturation(phaseIdx), 0))
160 return reducedDiffusionMatrix;
162 for (
int compIIdx = 0; compIIdx < numComponents-1; compIIdx++)
168 const auto xi = moleFrac[compIIdx];
169 const auto Mn = FluidSystem::molarMass(numComponents-1);
170 auto tinInside = getDiffusionCoefficient(phaseIdx, compIIdx, numComponents-1, problem, element, insideVolVars, fvGeometry.scv(insideScvIdx));
171 tinInside = EffDiffModel::effectiveDiffusivity(insideVolVars.porosity(), insideVolVars.saturation(phaseIdx), tinInside);
172 auto tinOutside = getDiffusionCoefficient(phaseIdx, compIIdx, numComponents-1, problem, element, outsideVolVars, fvGeometry.scv(outsideScvIdx));
173 tinOutside = EffDiffModel::effectiveDiffusivity(outsideVolVars.porosity(), outsideVolVars.saturation(phaseIdx), tinOutside);
176 tinInside *= insideVolVars.extrusionFactor();
177 tinOutside *= outsideVolVars.extrusionFactor();
180 const auto tin = problem.spatialParams().harmonicMean(tinInside, tinOutside, scvf.unitOuterNormal());
183 reducedDiffusionMatrix[compIIdx][compIIdx] += xi*avgMolarMass/(tin*Mn);
186 for (
int compJIdx = 0; compJIdx < numComponents; compJIdx++)
189 if (compIIdx == compJIdx)
193 const auto xj = moleFrac[compJIdx];
194 const auto Mi = FluidSystem::molarMass(compIIdx);
195 const auto Mj = FluidSystem::molarMass(compJIdx);
196 auto tijInside = getDiffusionCoefficient(phaseIdx, compIIdx, compJIdx, problem, element, insideVolVars, fvGeometry.scv(insideScvIdx));
197 tijInside = EffDiffModel::effectiveDiffusivity(insideVolVars.porosity(), insideVolVars.saturation(phaseIdx), tijInside);
198 auto tijOutside = getDiffusionCoefficient(phaseIdx, compIIdx, compJIdx, problem, element, outsideVolVars, fvGeometry.scv(outsideScvIdx));
199 tijOutside = EffDiffModel::effectiveDiffusivity(outsideVolVars.porosity(), outsideVolVars.saturation(phaseIdx), tijOutside);
202 tijInside *= insideVolVars.extrusionFactor();
203 tijOutside *= outsideVolVars.extrusionFactor();
206 const auto tij = problem.spatialParams().harmonicMean(tijInside, tijOutside, scvf.unitOuterNormal());
208 reducedDiffusionMatrix[compIIdx][compIIdx] += xj*avgMolarMass/(tij*Mi);
209 if (compJIdx < numComponents-1)
210 reducedDiffusionMatrix[compIIdx][compJIdx] +=xi*(avgMolarMass/(tin*Mn) - avgMolarMass/(tij*Mj));
213 return reducedDiffusionMatrix;
217 template <class T = TypeTag, typename std::enable_if_t<GetPropType<T, Properties::FluidSystem>::isTracerFluidSystem(),
int> =0 >
218 static Scalar getDiffusionCoefficient(
const int phaseIdx,
221 const Problem& problem,
222 const Element& element,
223 const VolumeVariables& volVars,
224 const SubControlVolume& scv)
226 return FluidSystem::binaryDiffusionCoefficient(compIIdx,
233 template <class T = TypeTag, typename std::enable_if_t<!GetPropType<T, Properties::FluidSystem>::isTracerFluidSystem(),
int> =0 >
234 static Scalar getDiffusionCoefficient(
const int phaseIdx,
237 const Problem& problem,
238 const Element& element,
239 const VolumeVariables& volVars,
240 const SubControlVolume& scv)
242 auto fluidState = volVars.fluidState();
243 typename FluidSystem::ParameterCache paramCache;
244 paramCache.updateAll(fluidState);
245 return FluidSystem::binaryDiffusionCoefficient(fluidState,