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;
 
   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);
 
  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
Detail::Transmissibility< TransmissibilityLawTypes... > Transmissibility
Export the transmissibility law.
Definition advection.hh:41
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
Detail::Transmissibility< TransmissibilityLawTypes... > TransmissibilityCreepingFlow
Export the creeping flow transmissibility law.
Definition advection.hh:156
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
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:149
Definition advection.hh:19
Definition discretization/porenetwork/fvelementgeometry.hh:24
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Definition advection.hh:22