13#ifndef DUMUX_FLUX_PNM_ADVECTION_HH
14#define DUMUX_FLUX_PNM_ADVECTION_HH
21template<
class... TransmissibilityLawTypes>
32template<
class ScalarT,
class... TransmissibilityLawTypes>
50 template<
class Problem,
class Element,
class FVElementGeometry,
51 class ElementVolumeVariables,
class SubControlVolumeFace,
class ElemFluxVarsCache>
53 const Element& element,
54 const FVElementGeometry& fvGeometry,
55 const ElementVolumeVariables& elemVolVars,
56 const SubControlVolumeFace& scvf,
58 const ElemFluxVarsCache& elemFluxVarsCache)
60 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
63 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
64 const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx());
65 const auto& insideVolVars = elemVolVars[insideScv];
66 const auto& outsideVolVars = elemVolVars[outsideScv];
69 const Scalar deltaP = insideVolVars.pressure(phaseIdx) - outsideVolVars.pressure(phaseIdx);
70 const Scalar transmissibility = fluxVarsCache.transmissibility(phaseIdx);
72 assert(isfinite(transmissibility));
74 Scalar volumeFlow = transmissibility*deltaP;
77 static const bool enableGravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
80 const Scalar rho = 0.5*insideVolVars.density(phaseIdx) + 0.5*outsideVolVars.density(phaseIdx);
81 const Scalar g = problem.spatialParams().gravity(scvf.center()) * scvf.unitOuterNormal();
86 volumeFlow += transmissibility * fluxVarsCache.poreToPoreDistance() * rho * g;
95 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
97 const Element& element,
98 const FVElementGeometry& fvGeometry,
99 const typename FVElementGeometry::SubControlVolumeFace& scvf,
100 const ElementVolumeVariables& elemVolVars,
101 const FluxVariablesCache& fluxVarsCache,
104 if constexpr (ElementVolumeVariables::VolumeVariables::numFluidPhases() == 1)
105 return Transmissibility::singlePhaseTransmissibility(problem, element, fvGeometry, scvf, elemVolVars, fluxVarsCache, phaseIdx);
108 static_assert(ElementVolumeVariables::VolumeVariables::numFluidPhases() == 2);
110 const auto& spatialParams = problem.spatialParams();
111 using FluidSystem =
typename ElementVolumeVariables::VolumeVariables::FluidSystem;
112 const int wPhaseIdx = spatialParams.template wettingPhase<FluidSystem>(element, elemVolVars);
113 const bool invaded = fluxVarsCache.invaded();
115 if (phaseIdx == wPhaseIdx)
117 return invaded ? Transmissibility::wettingLayerTransmissibility(element, fvGeometry, scvf, fluxVarsCache)
118 : Transmissibility::singlePhaseTransmissibility(problem, element, fvGeometry, scvf, elemVolVars, fluxVarsCache, phaseIdx);
122 return invaded ? Transmissibility::nonWettingPhaseTransmissibility(element, fvGeometry, scvf, fluxVarsCache)
128 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
130 const Element& element,
131 const FVElementGeometry& fvGeometry,
132 const ElementVolumeVariables& elemVolVars,
133 const typename FVElementGeometry::SubControlVolumeFace& scvf,
134 const FluxVariablesCache& fluxVarsCache)
136 static_assert(ElementVolumeVariables::VolumeVariables::numFluidPhases() == 1);
148template <
class ScalarT,
class... TransmissibilityLawTypes>
164 using ParentType =
typename TransmissibilityCreepingFlow::SinglePhaseCache;
168 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
169 void fill(
const Problem& problem,
170 const Element& element,
171 const FVElementGeometry& fvGeometry,
172 const typename FVElementGeometry::SubControlVolumeFace& scvf,
173 const ElementVolumeVariables& elemVolVars,
174 const FluxVariablesCache& fluxVarsCache,
177 ParentType::fill(problem, element, fvGeometry,scvf, elemVolVars, fluxVarsCache, phaseIdx);
178 const auto elemSol =
elementSolution(element, elemVolVars, fvGeometry);
180 for (
const auto& scv : scvs(fvGeometry))
182 const auto localIdx = scv.indexInElement();
183 const Scalar throatToPoreAreaRatio = fluxVarsCache.throatCrossSectionalArea() / problem.spatialParams().poreCrossSectionalArea(element, scv, elemSol);
186 const Scalar momentumCoefficient = problem.spatialParams().momentumCoefficient(element, scv, elemSol);
189 const Scalar kineticEnergyCoefficient = problem.spatialParams().kineticEnergyCoefficient(element, scv, elemSol);
191 expansionCoefficient_[localIdx] = getExpansionCoefficient_(throatToPoreAreaRatio, momentumCoefficient, kineticEnergyCoefficient);
192 contractionCoefficient_[localIdx] = getContractionCoefficient_(throatToPoreAreaRatio, momentumCoefficient, kineticEnergyCoefficient);
197 {
return expansionCoefficient_[downstreamIdx]; }
200 {
return contractionCoefficient_[upstreamIdx]; }
204 Scalar getExpansionCoefficient_(
const Scalar throatToPoreAreaRatio,
const Scalar momentumCoefficient,
const Scalar kineticEnergyCoefficient)
const
206 Scalar expansionCoefficient = throatToPoreAreaRatio * throatToPoreAreaRatio * (2 * momentumCoefficient - kineticEnergyCoefficient)
207 + kineticEnergyCoefficient - 2 * momentumCoefficient * throatToPoreAreaRatio
208 - (1 - throatToPoreAreaRatio * throatToPoreAreaRatio);
213 Scalar getContractionCoefficient_(
const Scalar throatToPoreAreaRatio,
const Scalar momentumCoefficient,
const Scalar kineticEnergyCoefficient)
const
215 const Scalar contractionAreaRatio = getContractionAreaRatio_(throatToPoreAreaRatio);
216 Scalar contractionCoefficient = (1 - (throatToPoreAreaRatio * throatToPoreAreaRatio * kineticEnergyCoefficient - 2 * momentumCoefficient )
217 * contractionAreaRatio * contractionAreaRatio - 2 * contractionAreaRatio) / (contractionAreaRatio * contractionAreaRatio);
222 Scalar getContractionAreaRatio_(
const Scalar throatToPoreAreaRatio)
const
224 return 1.0-(1.0-throatToPoreAreaRatio)/(2.08*(1.0-throatToPoreAreaRatio)+0.5371);
227 std::array<Scalar, 2> expansionCoefficient_;
228 std::array<Scalar, 2> contractionCoefficient_;
239 template<
class Problem,
class Element,
class FVElementGeometry,
240 class ElementVolumeVariables,
class SubControlVolumeFace,
class ElemFluxVarsCache>
242 const Element& element,
243 const FVElementGeometry& fvGeometry,
244 const ElementVolumeVariables& elemVolVars,
245 const SubControlVolumeFace& scvf,
247 const ElemFluxVarsCache& elemFluxVarsCache)
249 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
252 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
253 const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx());
254 const auto& insideVolVars = elemVolVars[insideScv];
255 const auto& outsideVolVars = elemVolVars[outsideScv];
258 Scalar deltaP = insideVolVars.pressure(phaseIdx) - outsideVolVars.pressure(phaseIdx);
261 static const bool enableGravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
264 const Scalar rho = 0.5*insideVolVars.density(phaseIdx) + 0.5*outsideVolVars.density(phaseIdx);
267 const auto poreToPoreVector = fluxVarsCache.poreToPoreDistance() * scvf.unitOuterNormal();
268 const auto& gravityVector = problem.spatialParams().gravity(scvf.center());
270 deltaP += rho * (gravityVector * poreToPoreVector);
272 const Scalar creepingFlowTransmissibility = fluxVarsCache.transmissibility(phaseIdx);
273 const Scalar throatCrossSectionalArea = fluxVarsCache.throatCrossSectionalArea();
275 assert(isfinite(creepingFlowTransmissibility));
277 assert(scvf.insideScvIdx() == 0);
278 assert(scvf.outsideScvIdx() == 1);
281 const auto [upstreamIdx, downstreamIdx] = deltaP > 0 ? std::pair(0, 1) : std::pair(1, 0);
283 const Scalar contractionCoefficient = fluxVarsCache.singlePhaseFlowVariables().contractionCoefficient(upstreamIdx);
284 const Scalar expansionCoefficient = fluxVarsCache.singlePhaseFlowVariables().expansionCoefficient(downstreamIdx);
285 const Scalar mu = elemVolVars[upstreamIdx].viscosity();
296 const Scalar A = (contractionCoefficient * elemVolVars[upstreamIdx].density() + expansionCoefficient * elemVolVars[downstreamIdx].density())
297 / (2.0 * mu * mu * throatCrossSectionalArea * throatCrossSectionalArea);
298 const Scalar B = 1.0/creepingFlowTransmissibility;
300 const Scalar C = -abs(deltaP);
303 const auto discriminant = B*B - 4*A*C;
304 const auto q = (-B + sqrt(discriminant)) / (2*A);
307 if (upstreamIdx == 0)
314 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
316 const Element& element,
317 const FVElementGeometry& fvGeometry,
318 const typename FVElementGeometry::SubControlVolumeFace& scvf,
319 const ElementVolumeVariables& elemVolVars,
320 const FluxVariablesCache& fluxVarsCache,
323 static_assert(ElementVolumeVariables::VolumeVariables::numFluidPhases() == 1);
324 return Transmissibility::singlePhaseTransmissibility(problem, element, fvGeometry, scvf, elemVolVars, fluxVarsCache, phaseIdx);
327 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
329 const Element& element,
330 const FVElementGeometry& fvGeometry,
331 const ElementVolumeVariables& elemVolVars,
332 const typename FVElementGeometry::SubControlVolumeFace& scvf,
333 const FluxVariablesCache& fluxVarsCache)
335 static_assert(ElementVolumeVariables::VolumeVariables::numFluidPhases() == 1);
Hagen–Poiseuille-type flux law to describe the advective flux for pore-network models.
Definition: advection.hh:34
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:129
ScalarT Scalar
Export the Scalar type.
Definition: advection.hh:38
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:96
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:52
Definition: advection.hh:163
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:169
ScalarT Scalar
Definition: advection.hh:166
Scalar contractionCoefficient(int upstreamIdx) const
Definition: advection.hh:199
Scalar expansionCoefficient(int downstreamIdx) const
Definition: advection.hh:196
Inherit transmissibility from creeping flow transmissibility law to cache non-creeping flow-related p...
Definition: advection.hh:160
Non-creeping flow flux law to describe the advective flux for pore-network models based on El-Zehairy...
Definition: advection.hh:150
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:241
ScalarT Scalar
Export the Scalar type.
Definition: advection.hh:153
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:315
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:328
auto elementSolution(const Element &element, const SolutionVector &sol, const GridGeometry &gg) -> std::enable_if_t< GridGeometry::discMethod==DiscretizationMethods::cctpfa||GridGeometry::discMethod==DiscretizationMethods::ccmpfa, CCElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for cell-centered schemes.
Definition: cellcentered/elementsolution.hh:101
Definition: advection.hh:19
Definition: discretization/porenetwork/fvelementgeometry.hh:24
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Definition: advection.hh:22