25#ifndef DUMUX_FLUX_PNM_ADVECTION_HH
26#define DUMUX_FLUX_PNM_ADVECTION_HH
33template<
class... TransmissibilityLawTypes>
44template<
class ScalarT,
class... TransmissibilityLawTypes>
62 template<
class Problem,
class Element,
class FVElementGeometry,
63 class ElementVolumeVariables,
class SubControlVolumeFace,
class ElemFluxVarsCache>
65 const Element& element,
66 const FVElementGeometry& fvGeometry,
67 const ElementVolumeVariables& elemVolVars,
68 const SubControlVolumeFace& scvf,
70 const ElemFluxVarsCache& elemFluxVarsCache)
72 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
75 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
76 const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx());
77 const auto& insideVolVars = elemVolVars[insideScv];
78 const auto& outsideVolVars = elemVolVars[outsideScv];
81 const Scalar deltaP = insideVolVars.pressure(phaseIdx) - outsideVolVars.pressure(phaseIdx);
82 const Scalar transmissibility = fluxVarsCache.transmissibility(phaseIdx);
84 assert(isfinite(transmissibility));
86 Scalar volumeFlow = transmissibility*deltaP;
89 static const bool enableGravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
92 const Scalar rho = 0.5*insideVolVars.density(phaseIdx) + 0.5*outsideVolVars.density(phaseIdx);
93 const Scalar g = problem.spatialParams().gravity(scvf.center()) * scvf.unitOuterNormal();
98 volumeFlow += transmissibility * fluxVarsCache.poreToPoreDistance() * rho * g;
107 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
109 const Element& element,
110 const FVElementGeometry& fvGeometry,
111 const typename FVElementGeometry::SubControlVolumeFace& scvf,
112 const ElementVolumeVariables& elemVolVars,
113 const FluxVariablesCache& fluxVarsCache,
116 if constexpr (ElementVolumeVariables::VolumeVariables::numFluidPhases() == 1)
117 return Transmissibility::singlePhaseTransmissibility(problem, element, fvGeometry, scvf, elemVolVars, fluxVarsCache, phaseIdx);
120 static_assert(ElementVolumeVariables::VolumeVariables::numFluidPhases() == 2);
122 const auto& spatialParams = problem.spatialParams();
123 using FluidSystem =
typename ElementVolumeVariables::VolumeVariables::FluidSystem;
124 const int wPhaseIdx = spatialParams.template wettingPhase<FluidSystem>(element, elemVolVars);
125 const bool invaded = fluxVarsCache.invaded();
127 if (phaseIdx == wPhaseIdx)
129 return invaded ? Transmissibility::wettingLayerTransmissibility(element, fvGeometry, scvf, fluxVarsCache)
130 : Transmissibility::singlePhaseTransmissibility(problem, element, fvGeometry, scvf, elemVolVars, fluxVarsCache, phaseIdx);
134 return invaded ? Transmissibility::nonWettingPhaseTransmissibility(element, fvGeometry, scvf, fluxVarsCache)
140 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
142 const Element& element,
143 const FVElementGeometry& fvGeometry,
144 const ElementVolumeVariables& elemVolVars,
145 const typename FVElementGeometry::SubControlVolumeFace& scvf,
146 const FluxVariablesCache& fluxVarsCache)
148 static_assert(ElementVolumeVariables::VolumeVariables::numFluidPhases() == 1);
160template <
class ScalarT,
class... TransmissibilityLawTypes>
176 using ParentType =
typename TransmissibilityCreepingFlow::SinglePhaseCache;
180 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
181 void fill(
const Problem& problem,
182 const Element& element,
183 const FVElementGeometry& fvGeometry,
184 const typename FVElementGeometry::SubControlVolumeFace& scvf,
185 const ElementVolumeVariables& elemVolVars,
186 const FluxVariablesCache& fluxVarsCache,
189 ParentType::fill(problem, element, fvGeometry,scvf, elemVolVars, fluxVarsCache, phaseIdx);
190 const auto elemSol =
elementSolution(element, elemVolVars, fvGeometry);
192 for (
const auto& scv : scvs(fvGeometry))
194 const auto localIdx = scv.indexInElement();
195 const Scalar throatToPoreAreaRatio = fluxVarsCache.throatCrossSectionalArea() / problem.spatialParams().poreCrossSectionalArea(element, scv, elemSol);
198 const Scalar momentumCoefficient = problem.spatialParams().momentumCoefficient(element, scv, elemSol);
201 const Scalar kineticEnergyCoefficient = problem.spatialParams().kineticEnergyCoefficient(element, scv, elemSol);
203 expansionCoefficient_[localIdx] = getExpansionCoefficient_(throatToPoreAreaRatio, momentumCoefficient, kineticEnergyCoefficient);
204 contractionCoefficient_[localIdx] = getContractionCoefficient_(throatToPoreAreaRatio, momentumCoefficient, kineticEnergyCoefficient);
209 {
return expansionCoefficient_[downstreamIdx]; }
212 {
return contractionCoefficient_[upstreamIdx]; }
216 Scalar getExpansionCoefficient_(
const Scalar throatToPoreAreaRatio,
const Scalar momentumCoefficient,
const Scalar kineticEnergyCoefficient)
const
218 Scalar expansionCoefficient = throatToPoreAreaRatio * throatToPoreAreaRatio * (2 * momentumCoefficient - kineticEnergyCoefficient)
219 + kineticEnergyCoefficient - 2 * momentumCoefficient * throatToPoreAreaRatio
220 - (1 - throatToPoreAreaRatio * throatToPoreAreaRatio);
225 Scalar getContractionCoefficient_(
const Scalar throatToPoreAreaRatio,
const Scalar momentumCoefficient,
const Scalar kineticEnergyCoefficient)
const
227 const Scalar contractionAreaRatio = getContractionAreaRatio_(throatToPoreAreaRatio);
228 Scalar contractionCoefficient = (1 - (throatToPoreAreaRatio * throatToPoreAreaRatio * kineticEnergyCoefficient - 2 * momentumCoefficient )
229 * contractionAreaRatio * contractionAreaRatio - 2 * contractionAreaRatio) / (contractionAreaRatio * contractionAreaRatio);
234 Scalar getContractionAreaRatio_(
const Scalar throatToPoreAreaRatio)
const
236 return 1.0-(1.0-throatToPoreAreaRatio)/(2.08*(1.0-throatToPoreAreaRatio)+0.5371);
239 std::array<Scalar, 2> expansionCoefficient_;
240 std::array<Scalar, 2> contractionCoefficient_;
251 template<
class Problem,
class Element,
class FVElementGeometry,
252 class ElementVolumeVariables,
class SubControlVolumeFace,
class ElemFluxVarsCache>
254 const Element& element,
255 const FVElementGeometry& fvGeometry,
256 const ElementVolumeVariables& elemVolVars,
257 const SubControlVolumeFace& scvf,
259 const ElemFluxVarsCache& elemFluxVarsCache)
261 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
264 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
265 const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx());
266 const auto& insideVolVars = elemVolVars[insideScv];
267 const auto& outsideVolVars = elemVolVars[outsideScv];
270 Scalar deltaP = insideVolVars.pressure(phaseIdx) - outsideVolVars.pressure(phaseIdx);
273 static const bool enableGravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
276 const Scalar rho = 0.5*insideVolVars.density(phaseIdx) + 0.5*outsideVolVars.density(phaseIdx);
279 const auto poreToPoreVector = fluxVarsCache.poreToPoreDistance() * scvf.unitOuterNormal();
280 const auto& gravityVector = problem.spatialParams().gravity(scvf.center());
282 deltaP += rho * (gravityVector * poreToPoreVector);
284 const Scalar creepingFlowTransmissibility = fluxVarsCache.transmissibility(phaseIdx);
285 const Scalar throatCrossSectionalArea = fluxVarsCache.throatCrossSectionalArea();
287 assert(isfinite(creepingFlowTransmissibility));
289 assert(scvf.insideScvIdx() == 0);
290 assert(scvf.outsideScvIdx() == 1);
293 const auto [upstreamIdx, downstreamIdx] = deltaP > 0 ? std::pair(0, 1) : std::pair(1, 0);
295 const Scalar contractionCoefficient = fluxVarsCache.singlePhaseFlowVariables().contractionCoefficient(upstreamIdx);
296 const Scalar expansionCoefficient = fluxVarsCache.singlePhaseFlowVariables().expansionCoefficient(downstreamIdx);
297 const Scalar mu = elemVolVars[upstreamIdx].viscosity();
308 const Scalar A = (contractionCoefficient * elemVolVars[upstreamIdx].density() + expansionCoefficient * elemVolVars[downstreamIdx].density())
309 / (2.0 * mu * mu * throatCrossSectionalArea * throatCrossSectionalArea);
310 const Scalar B = 1.0/creepingFlowTransmissibility;
312 const Scalar C = -abs(deltaP);
315 const auto discriminant = B*B - 4*A*C;
316 const auto q = (-B + sqrt(discriminant)) / (2*A);
319 if (upstreamIdx == 0)
326 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
328 const Element& element,
329 const FVElementGeometry& fvGeometry,
330 const typename FVElementGeometry::SubControlVolumeFace& scvf,
331 const ElementVolumeVariables& elemVolVars,
332 const FluxVariablesCache& fluxVarsCache,
335 static_assert(ElementVolumeVariables::VolumeVariables::numFluidPhases() == 1);
336 return Transmissibility::singlePhaseTransmissibility(problem, element, fvGeometry, scvf, elemVolVars, fluxVarsCache, phaseIdx);
339 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
341 const Element& element,
342 const FVElementGeometry& fvGeometry,
343 const ElementVolumeVariables& elemVolVars,
344 const typename FVElementGeometry::SubControlVolumeFace& scvf,
345 const FluxVariablesCache& fluxVarsCache)
347 static_assert(ElementVolumeVariables::VolumeVariables::numFluidPhases() == 1);
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
auto elementSolution(const Element &element, const SolutionVector &sol, const GridGeometry &gg) -> std::enable_if_t< GridGeometry::discMethod==DiscretizationMethods::box, BoxElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for box schemes.
Definition: box/elementsolution.hh:118
Definition: discretization/porenetwork/fvelementgeometry.hh:34
Definition: advection.hh:31
Definition: advection.hh:34
Hagen–Poiseuille-type flux law to describe the advective flux for pore-network models.
Definition: advection.hh:46
static std::array< Scalar, 2 > calculateTransmissibilities(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const typename FVElementGeometry::SubControlVolumeFace &scvf, const FluxVariablesCache &fluxVarsCache)
Definition: advection.hh:141
ScalarT Scalar
Export the Scalar type.
Definition: advection.hh:50
static Scalar calculateTransmissibility(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolumeFace &scvf, const ElementVolumeVariables &elemVolVars, const FluxVariablesCache &fluxVarsCache, const int phaseIdx)
Returns the throat conductivity.
Definition: advection.hh:108
static Scalar flux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf, const int phaseIdx, const ElemFluxVarsCache &elemFluxVarsCache)
Returns the advective flux of a fluid phase across the given sub-control volume face (corresponding t...
Definition: advection.hh:64
Non-creeping flow flux law to describe the advective flux for pore-network models based on El-Zehairy...
Definition: advection.hh:162
static Scalar flux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf, const int phaseIdx, const ElemFluxVarsCache &elemFluxVarsCache)
Returns the advective flux of a fluid phase across the given sub-control volume face (corresponding t...
Definition: advection.hh:253
ScalarT Scalar
Export the Scalar type.
Definition: advection.hh:165
static Scalar calculateTransmissibility(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolumeFace &scvf, const ElementVolumeVariables &elemVolVars, const FluxVariablesCache &fluxVarsCache, const int phaseIdx)
Definition: advection.hh:327
static std::array< Scalar, 2 > calculateTransmissibilities(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const typename FVElementGeometry::SubControlVolumeFace &scvf, const FluxVariablesCache &fluxVarsCache)
Definition: advection.hh:340
Inherit transmissibility from creeping flow transmissibility law to cache non-creeping flow-related p...
Definition: advection.hh:172
Definition: advection.hh:175
void fill(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolumeFace &scvf, const ElementVolumeVariables &elemVolVars, const FluxVariablesCache &fluxVarsCache, const int phaseIdx)
Definition: advection.hh:181
ScalarT Scalar
Definition: advection.hh:178
Scalar contractionCoefficient(int upstreamIdx) const
Definition: advection.hh:211
Scalar expansionCoefficient(int downstreamIdx) const
Definition: advection.hh:208