25#ifndef DUMUX_FLUX_PNM_ADVECTION_HH
26#define DUMUX_FLUX_PNM_ADVECTION_HH
33template<
class... TransmissibilityLawTypes>
45template<
class ScalarT,
class... TransmissibilityLawTypes>
63 template<
class Problem,
class Element,
class FVElementGeometry,
64 class ElementVolumeVariables,
class SubControlVolumeFace,
class ElemFluxVarsCache>
66 const Element& element,
67 const FVElementGeometry& fvGeometry,
68 const ElementVolumeVariables& elemVolVars,
69 const SubControlVolumeFace& scvf,
71 const ElemFluxVarsCache& elemFluxVarsCache)
73 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
76 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
77 const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx());
78 const auto& insideVolVars = elemVolVars[insideScv];
79 const auto& outsideVolVars = elemVolVars[outsideScv];
82 const Scalar deltaP = insideVolVars.pressure(phaseIdx) - outsideVolVars.pressure(phaseIdx);
83 const Scalar transmissibility = fluxVarsCache.transmissibility(phaseIdx);
85 assert(isfinite(transmissibility));
87 Scalar volumeFlow = transmissibility*deltaP;
90 static const bool enableGravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
93 const Scalar rho = 0.5*insideVolVars.density(phaseIdx) + 0.5*outsideVolVars.density(phaseIdx);
94 const Scalar g = problem.spatialParams().gravity(scvf.center()) * scvf.unitOuterNormal();
99 volumeFlow += transmissibility * fluxVarsCache.poreToPoreDistance() * rho * g;
108 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
110 const Element& element,
111 const FVElementGeometry& fvGeometry,
112 const typename FVElementGeometry::SubControlVolumeFace& scvf,
113 const ElementVolumeVariables& elemVolVars,
114 const FluxVariablesCache& fluxVarsCache,
117 if constexpr (ElementVolumeVariables::VolumeVariables::numFluidPhases() == 1)
118 return Transmissibility::singlePhaseTransmissibility(problem, element, fvGeometry, scvf, elemVolVars, fluxVarsCache, phaseIdx);
121 static_assert(ElementVolumeVariables::VolumeVariables::numFluidPhases() == 2);
123 const auto& spatialParams = problem.spatialParams();
124 using FluidSystem =
typename ElementVolumeVariables::VolumeVariables::FluidSystem;
125 const int wPhaseIdx = spatialParams.template wettingPhase<FluidSystem>(element, elemVolVars);
126 const bool invaded = fluxVarsCache.invaded();
128 if (phaseIdx == wPhaseIdx)
130 return invaded ? Transmissibility::wettingLayerTransmissibility(element, fvGeometry, scvf, fluxVarsCache)
131 : Transmissibility::singlePhaseTransmissibility(problem, element, fvGeometry, scvf, elemVolVars, fluxVarsCache, phaseIdx);
135 return invaded ? Transmissibility::nonWettingPhaseTransmissibility(element, fvGeometry, scvf, fluxVarsCache)
141 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
143 const Element& element,
144 const FVElementGeometry& fvGeometry,
145 const ElementVolumeVariables& elemVolVars,
146 const typename FVElementGeometry::SubControlVolumeFace& scvf,
147 const FluxVariablesCache& fluxVarsCache)
149 static_assert(ElementVolumeVariables::VolumeVariables::numFluidPhases() == 1);
162template <
class ScalarT,
class... TransmissibilityLawTypes>
178 using ParentType =
typename TransmissibilityCreepingFlow::SinglePhaseCache;
182 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
183 void fill(
const Problem& problem,
184 const Element& element,
185 const FVElementGeometry& fvGeometry,
186 const typename FVElementGeometry::SubControlVolumeFace& scvf,
187 const ElementVolumeVariables& elemVolVars,
188 const FluxVariablesCache& fluxVarsCache,
191 ParentType::fill(problem, element, fvGeometry,scvf, elemVolVars, fluxVarsCache, phaseIdx);
192 const auto elemSol =
elementSolution(element, elemVolVars, fvGeometry);
194 for (
const auto& scv : scvs(fvGeometry))
196 const auto localIdx = scv.indexInElement();
197 const Scalar throatToPoreAreaRatio = fluxVarsCache.throatCrossSectionalArea() / problem.spatialParams().poreCrossSectionalArea(element, scv, elemSol);
200 const Scalar momentumCoefficient = problem.spatialParams().momentumCoefficient(element, scv, elemSol);
203 const Scalar kineticEnergyCoefficient = problem.spatialParams().kineticEnergyCoefficient(element, scv, elemSol);
205 expansionCoefficient_[localIdx] = getExpansionCoefficient_(throatToPoreAreaRatio, momentumCoefficient, kineticEnergyCoefficient);
206 contractionCoefficient_[localIdx] = getContractionCoefficient_(throatToPoreAreaRatio, momentumCoefficient, kineticEnergyCoefficient);
211 {
return expansionCoefficient_[downstreamIdx]; }
214 {
return contractionCoefficient_[upstreamIdx]; }
218 Scalar getExpansionCoefficient_(
const Scalar throatToPoreAreaRatio,
const Scalar momentumCoefficient,
const Scalar kineticEnergyCoefficient)
const
220 Scalar expansionCoefficient = throatToPoreAreaRatio * throatToPoreAreaRatio * (2 * momentumCoefficient - kineticEnergyCoefficient)
221 + kineticEnergyCoefficient - 2 * momentumCoefficient * throatToPoreAreaRatio
222 - (1 - throatToPoreAreaRatio * throatToPoreAreaRatio);
227 Scalar getContractionCoefficient_(
const Scalar throatToPoreAreaRatio,
const Scalar momentumCoefficient,
const Scalar kineticEnergyCoefficient)
const
229 const Scalar contractionAreaRatio = getContractionAreaRatio_(throatToPoreAreaRatio);
230 Scalar contractionCoefficient = (1 - (throatToPoreAreaRatio * throatToPoreAreaRatio * kineticEnergyCoefficient - 2 * momentumCoefficient )
231 * contractionAreaRatio * contractionAreaRatio - 2 * contractionAreaRatio) / (contractionAreaRatio * contractionAreaRatio);
236 Scalar getContractionAreaRatio_(
const Scalar throatToPoreAreaRatio)
const
238 return 1.0-(1.0-throatToPoreAreaRatio)/(2.08*(1.0-throatToPoreAreaRatio)+0.5371);
241 std::array<Scalar, 2> expansionCoefficient_;
242 std::array<Scalar, 2> contractionCoefficient_;
253 template<
class Problem,
class Element,
class FVElementGeometry,
254 class ElementVolumeVariables,
class SubControlVolumeFace,
class ElemFluxVarsCache>
256 const Element& element,
257 const FVElementGeometry& fvGeometry,
258 const ElementVolumeVariables& elemVolVars,
259 const SubControlVolumeFace& scvf,
261 const ElemFluxVarsCache& elemFluxVarsCache)
263 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
266 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
267 const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx());
268 const auto& insideVolVars = elemVolVars[insideScv];
269 const auto& outsideVolVars = elemVolVars[outsideScv];
272 Scalar deltaP = insideVolVars.pressure(phaseIdx) - outsideVolVars.pressure(phaseIdx);
275 static const bool enableGravity = getParamFromGroup<bool>(problem.paramGroup(),
"Problem.EnableGravity");
278 const Scalar rho = 0.5*insideVolVars.density(phaseIdx) + 0.5*outsideVolVars.density(phaseIdx);
281 const auto poreToPoreVector = fluxVarsCache.poreToPoreDistance() * scvf.unitOuterNormal();
282 const auto& gravityVector = problem.spatialParams().gravity(scvf.center());
284 deltaP += rho * (gravityVector * poreToPoreVector);
286 const Scalar creepingFlowTransmissibility = fluxVarsCache.transmissibility(phaseIdx);
287 const Scalar throatCrossSectionalArea = fluxVarsCache.throatCrossSectionalArea();
289 assert(isfinite(creepingFlowTransmissibility));
291 assert(scvf.insideScvIdx() == 0);
292 assert(scvf.outsideScvIdx() == 1);
295 const auto [upstreamIdx, downstreamIdx] = deltaP > 0 ? std::pair(0, 1) : std::pair(1, 0);
297 const Scalar contractionCoefficient = fluxVarsCache.singlePhaseFlowVariables().contractionCoefficient(upstreamIdx);
298 const Scalar expansionCoefficient = fluxVarsCache.singlePhaseFlowVariables().expansionCoefficient(downstreamIdx);
299 const Scalar mu = elemVolVars[upstreamIdx].viscosity();
310 const Scalar A = (contractionCoefficient * elemVolVars[upstreamIdx].density() + expansionCoefficient * elemVolVars[downstreamIdx].density())
311 / (2.0 * mu * mu * throatCrossSectionalArea * throatCrossSectionalArea);
312 const Scalar B = 1.0/creepingFlowTransmissibility;
314 const Scalar C = -abs(deltaP);
317 const auto discriminant = B*B - 4*A*C;
318 const auto q = (-B + sqrt(discriminant)) / (2*A);
321 if (upstreamIdx == 0)
328 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
330 const Element& element,
331 const FVElementGeometry& fvGeometry,
332 const typename FVElementGeometry::SubControlVolumeFace& scvf,
333 const ElementVolumeVariables& elemVolVars,
334 const FluxVariablesCache& fluxVarsCache,
337 static_assert(ElementVolumeVariables::VolumeVariables::numFluidPhases() == 1);
338 return Transmissibility::singlePhaseTransmissibility(problem, element, fvGeometry, scvf, elemVolVars, fluxVarsCache, phaseIdx);
341 template<
class Problem,
class Element,
class FVElementGeometry,
class ElementVolumeVariables,
class FluxVariablesCache>
343 const Element& element,
344 const FVElementGeometry& fvGeometry,
345 const ElementVolumeVariables& elemVolVars,
346 const typename FVElementGeometry::SubControlVolumeFace& scvf,
347 const FluxVariablesCache& fluxVarsCache)
349 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
Definition: advection.hh:47
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:142
ScalarT Scalar
Export the Scalar type.
Definition: advection.hh:51
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:109
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:65
Definition: advection.hh:164
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:255
ScalarT Scalar
Export the Scalar type.
Definition: advection.hh:167
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:329
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:342
Inherit transmissibility from creeping flow transmissibility law to cache non-creeping flow-related p...
Definition: advection.hh:174
Definition: advection.hh:177
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:183
ScalarT Scalar
Definition: advection.hh:180
Scalar contractionCoefficient(int upstreamIdx) const
Definition: advection.hh:213
Scalar expansionCoefficient(int downstreamIdx) const
Definition: advection.hh:210