12#ifndef DUMUX_DISCRETIZATION_CC_TPFA_FACET_COUPLING_DARCYS_LAW_HH 
   13#define DUMUX_DISCRETIZATION_CC_TPFA_FACET_COUPLING_DARCYS_LAW_HH 
   18#include <dune/common/float_cmp.hh> 
   32template<
class ScalarType, 
class Gr
idGeometry, 
bool isNetwork>
 
   41template<
class AdvectionType, 
class Gr
idGeometry, 
bool isNetwork>
 
   50template<
class ScalarType, 
class Gr
idGeometry>
 
   53                                                                      int(GridGeometry::GridView::dimensionworld) ) >;
 
   59template<
class AdvectionType, 
class Gr
idGeometry>
 
   62    using Scalar = 
typename AdvectionType::Scalar;
 
   63    using FVElementGeometry = 
typename GridGeometry::LocalView;
 
   64    using SubControlVolumeFace = 
typename GridGeometry::SubControlVolumeFace;
 
   65    using Element = 
typename GridGeometry::GridView::template Codim<0>::Entity;
 
   85    template< 
class Problem, 
class ElementVolumeVariables >
 
   87                         const Element& element,
 
   88                         const FVElementGeometry& fvGeometry,
 
   89                         const ElementVolumeVariables& elemVolVars,
 
   90                         const SubControlVolumeFace &scvf)
 
   92        tij_ = AdvectionType::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g_);
 
 
  119    std::array<Scalar, 3> tij_;
 
  120    GravityCoefficients g_;
 
 
  127template<
class ScalarType, 
class Gr
idGeometry>
 
  128class CCTpfaFacetCouplingDarcysLawImpl<ScalarType, GridGeometry, false>
 
  130    using ThisType = CCTpfaFacetCouplingDarcysLawImpl<ScalarType, GridGeometry, false>;
 
  131    using TpfaDarcysLaw = CCTpfaDarcysLaw<ScalarType, GridGeometry, false>;
 
  133    using FVElementGeometry = 
typename GridGeometry::LocalView;
 
  134    using SubControlVolume = 
typename GridGeometry::SubControlVolume;
 
  135    using SubControlVolumeFace = 
typename GridGeometry::SubControlVolumeFace;
 
  138    using GridView = 
typename GridGeometry::GridView;
 
  139    using Element = 
typename GridView::template Codim<0>::Entity;
 
  140    using GlobalPosition = 
typename Element::Geometry::GlobalCoordinate;
 
  144    using Scalar = ScalarType;
 
  146    using DiscretizationMethod = DiscretizationMethods::CCTpfa;
 
  147    static constexpr DiscretizationMethod discMethod{};
 
  149    using Cache = CCTpfaFacetCouplingDarcysLawCache<ThisType, GridGeometry, 
false>;
 
  151    using TijContainer = 
typename Cache::AdvectionTransmissibilityContainer;
 
  155    template< 
class Problem, 
class ElementVolumeVariables, 
class ElementFluxVarsCache >
 
  156    static Scalar flux(
const Problem& problem,
 
  157                       const Element& element,
 
  158                       const FVElementGeometry& fvGeometry,
 
  159                       const ElementVolumeVariables& elemVolVars,
 
  160                       const SubControlVolumeFace& scvf,
 
  162                       const ElementFluxVarsCache& elemFluxVarsCache)
 
  164        if (!problem.couplingManager().isOnInteriorBoundary(element, scvf))
 
  165            return TpfaDarcysLaw::flux(problem, element, fvGeometry, elemVolVars, scvf, phaseIdx, elemFluxVarsCache);
 
  168        const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
 
  169        const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
 
  170        const auto pInside = insideVolVars.pressure(phaseIdx);
 
  171        const auto pFacet = facetVolVars.pressure(phaseIdx);
 
  174        const auto& fluxVarsCache = elemFluxVarsCache[scvf];
 
  175        Scalar flux = fluxVarsCache.advectionTijInside()*pInside + fluxVarsCache.advectionTijFacet()*pFacet;
 
  182            const auto& g = problem.spatialParams().gravity(scvf.ipGlobal());
 
  183            const auto rho = 0.5*(insideVolVars.density(phaseIdx) + facetVolVars.density(phaseIdx));
 
  184            const auto rhoTimesArea = rho*Extrusion::area(fvGeometry, scvf);
 
  185            const auto alpha_inside = rhoTimesArea*insideVolVars.extrusionFactor()
 
  186                                      *
vtmv(scvf.unitOuterNormal(), insideVolVars.permeability(), g);
 
  188            flux += alpha_inside;
 
  189            if (!scvf.boundary())
 
  191                const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
 
  194                if ( problem.interiorBoundaryTypes(element, scvf).hasOnlyNeumann() )
 
  197                    const auto alpha_facet = rhoTimesArea*insideVolVars.extrusionFactor()
 
  198                                             *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), g);
 
  199                    const auto alpha_outside = rhoTimesArea*outsideVolVars.extrusionFactor()
 
  200                                               *
vtmv(scvf.unitOuterNormal(), outsideVolVars.permeability(), g);
 
  202                    flux -= fluxVarsCache.gravityCoefficients()[0]*(xi*alpha_inside - alpha_facet + (1.0 - xi)*alpha_outside);
 
  203                    flux += fluxVarsCache.gravityCoefficients()[1]*(xi*alpha_outside - alpha_facet + (1.0 - xi)*alpha_inside);
 
  207                flux += fluxVarsCache.advectionTijOutside()*outsideVolVars.pressure(phaseIdx);
 
  213            return scvf.boundary() ? flux
 
  214                                   : flux + fluxVarsCache.advectionTijOutside()*elemVolVars[scvf.outsideScvIdx()].pressure(phaseIdx);
 
  219    template< 
class Problem, 
class ElementVolumeVariables >
 
  220    static TijContainer calculateTransmissibility(
const Problem& problem,
 
  221                                                  const Element& element,
 
  222                                                  const FVElementGeometry& fvGeometry,
 
  223                                                  const ElementVolumeVariables& elemVolVars,
 
  224                                                  const SubControlVolumeFace& scvf)
 
  226        typename Cache::GravityCoefficients g;
 
  227        return calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g);
 
  232    template< 
class Problem, 
class ElementVolumeVariables >
 
  233    static TijContainer calculateTransmissibility(
const Problem& problem,
 
  234                                                  const Element& element,
 
  235                                                  const FVElementGeometry& fvGeometry,
 
  236                                                  const ElementVolumeVariables& elemVolVars,
 
  237                                                  const SubControlVolumeFace& scvf,
 
  238                                                  typename Cache::GravityCoefficients& g)
 
  241        if (!problem.couplingManager().isCoupled(element, scvf))
 
  244            tij[Cache::insideTijIdx] = TpfaDarcysLaw::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf);
 
  251        const auto insideScvIdx = scvf.insideScvIdx();
 
  252        const auto& insideScv = fvGeometry.scv(insideScvIdx);
 
  253        const auto& insideVolVars = elemVolVars[insideScvIdx];
 
  254        const auto wIn = Extrusion::area(fvGeometry, scvf)
 
  256                                                      insideVolVars.permeability(),
 
  257                                                      insideVolVars.extrusionFactor());
 
  260        const auto iBcTypes = problem.interiorBoundaryTypes(element, scvf);
 
  263        if (iBcTypes.hasOnlyNeumann())
 
  265            const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
 
  266            const auto wFacet = 2.0*Extrusion::area(fvGeometry, scvf)*insideVolVars.extrusionFactor()
 
  267                                   /facetVolVars.extrusionFactor()
 
  268                                   *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), scvf.unitOuterNormal());
 
  277            if (!scvf.boundary())
 
  279                const auto outsideScvIdx = scvf.outsideScvIdx();
 
  280                const auto& outsideVolVars = elemVolVars[outsideScvIdx];
 
  281                const auto wOut = -1.0*Extrusion::area(fvGeometry, scvf)
 
  283                                                               outsideVolVars.permeability(),
 
  284                                                               outsideVolVars.extrusionFactor());
 
  286                if ( !Dune::FloatCmp::eq(xi, 1.0, 1e-6) )
 
  293                    const Scalar xiMinusOne = (xi - 1.0);
 
  294                    const Scalar a01 = xiMinusOne*wOut;
 
  295                    const Scalar a11 = xi*wOut + wFacet;
 
  296                    const Scalar detA = (xi*wIn + wFacet)*a11 - xiMinusOne*wIn*a01;
 
  297                    g[0] = wIn*a11/detA; g[1] = -wIn*a01/detA;
 
  300                    const Scalar factor = wIn * wFacet / ( wIn * wOut * ( 2.0 * xi - 1.0 ) + wFacet * ( xi * ( wIn + wOut ) + wFacet ) );
 
  301                    tij[Cache::insideTijIdx]  = factor * ( wOut * xi + wFacet );
 
  302                    tij[Cache::outsideTijIdx] = factor * ( wOut * ( 1.0 - xi ) );
 
  303                    tij[Cache::facetTijIdx]   = factor * ( - wOut - wFacet );
 
  307                    g[0] = wIn/(wIn+wFacet); g[1] = 0.0;
 
  308                    tij[Cache::insideTijIdx] = wFacet*g[0];
 
  309                    tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
 
  310                    tij[Cache::outsideTijIdx] = 0.0;
 
  316                tij[Cache::insideTijIdx] = wFacet*wIn/(wIn+wFacet);
 
  317                tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
 
  318                tij[Cache::outsideTijIdx] = 0.0;
 
  321        else if (iBcTypes.hasOnlyDirichlet())
 
  323            tij[Cache::insideTijIdx] = wIn;
 
  324            tij[Cache::outsideTijIdx] = 0.0;
 
  325            tij[Cache::facetTijIdx] = -wIn;
 
  328            DUNE_THROW(Dune::NotImplemented, 
"Interior boundary types other than pure Dirichlet or Neumann");
 
  338template<
class AdvectionType, 
class Gr
idGeometry>
 
  341    using Scalar = 
typename AdvectionType::Scalar;
 
  342    using FVElementGeometry = 
typename GridGeometry::LocalView;
 
  343    using SubControlVolumeFace = 
typename GridGeometry::SubControlVolumeFace;
 
  344    using Element = 
typename GridGeometry::GridView::template Codim<0>::Entity;
 
  363    template< 
class Problem, 
class ElementVolumeVariables >
 
  365                         const Element& element,
 
  366                         const FVElementGeometry& fvGeometry,
 
  367                         const ElementVolumeVariables& elemVolVars,
 
  368                         const SubControlVolumeFace &scvf)
 
  370        tij_ = AdvectionType::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g_);
 
 
  393    AdvectionTransmissibilityContainer tij_;
 
  394    GravityCoefficients g_;
 
 
  401template<
class ScalarType, 
class Gr
idGeometry>
 
  402class CCTpfaFacetCouplingDarcysLawImpl<ScalarType, GridGeometry, true>
 
  404    using ThisType = CCTpfaFacetCouplingDarcysLawImpl<ScalarType, GridGeometry, true>;
 
  405    using TpfaDarcysLaw = CCTpfaDarcysLaw<ScalarType, GridGeometry, true>;
 
  407    using FVElementGeometry = 
typename GridGeometry::LocalView;
 
  408    using SubControlVolume = 
typename GridGeometry::SubControlVolume;
 
  409    using SubControlVolumeFace = 
typename GridGeometry::SubControlVolumeFace;
 
  412    using GridView = 
typename GridGeometry::GridView;
 
  413    using Element = 
typename GridView::template Codim<0>::Entity;
 
  414    using GlobalPosition = 
typename Element::Geometry::GlobalCoordinate;
 
  418    using Scalar = ScalarType;
 
  420    using DiscretizationMethod = DiscretizationMethods::CCTpfa;
 
  421    static constexpr DiscretizationMethod discMethod{};
 
  423    using Cache = CCTpfaFacetCouplingDarcysLawCache<ThisType, GridGeometry, 
true>;
 
  425    using TijContainer = 
typename Cache::AdvectionTransmissibilityContainer;
 
  428    template< 
class Problem, 
class ElementVolumeVariables, 
class ElementFluxVarsCache >
 
  429    static Scalar flux(
const Problem& problem,
 
  430                       const Element& element,
 
  431                       const FVElementGeometry& fvGeometry,
 
  432                       const ElementVolumeVariables& elemVolVars,
 
  433                       const SubControlVolumeFace& scvf,
 
  435                       const ElementFluxVarsCache& elemFluxVarsCache)
 
  437        if (!problem.couplingManager().isOnInteriorBoundary(element, scvf))
 
  438            return TpfaDarcysLaw::flux(problem, element, fvGeometry, elemVolVars, scvf, phaseIdx, elemFluxVarsCache);
 
  444        if (Dune::FloatCmp::ne(xi, 1.0, 1e-6))
 
  445            DUNE_THROW(Dune::InvalidStateException, 
"Xi != 1.0 cannot be used on surface grids");
 
  448        const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
 
  449        const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
 
  450        const auto pInside = insideVolVars.pressure(phaseIdx);
 
  451        const auto pFacet = facetVolVars.pressure(phaseIdx);
 
  454        const auto& fluxVarsCache = elemFluxVarsCache[scvf];
 
  455        Scalar flux = fluxVarsCache.advectionTijInside()*pInside + fluxVarsCache.advectionTijFacet()*pFacet;
 
  461            const auto& g = problem.spatialParams().gravity(scvf.ipGlobal());
 
  462            const auto rho = 0.5*(insideVolVars.density(phaseIdx) + facetVolVars.density(phaseIdx));
 
  463            const auto rhoTimesArea = rho*Extrusion::area(fvGeometry, scvf);
 
  464            const auto alpha_inside = rhoTimesArea*insideVolVars.extrusionFactor()
 
  465                                      *
vtmv(scvf.unitOuterNormal(), insideVolVars.permeability(), g);
 
  467            flux += alpha_inside;
 
  470            if ( !scvf.boundary() && problem.interiorBoundaryTypes(element, scvf).hasOnlyNeumann() )
 
  472                const auto alpha_facet = rhoTimesArea*insideVolVars.extrusionFactor()
 
  473                                         *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), g);
 
  475                flux -= fluxVarsCache.gravityCoefficients()[0]*(alpha_inside - alpha_facet);
 
  484    template< 
class Problem, 
class ElementVolumeVariables >
 
  485    static TijContainer calculateTransmissibility(
const Problem& problem,
 
  486                                                  const Element& element,
 
  487                                                  const FVElementGeometry& fvGeometry,
 
  488                                                  const ElementVolumeVariables& elemVolVars,
 
  489                                                  const SubControlVolumeFace& scvf)
 
  491        typename Cache::GravityCoefficients g;
 
  492        return calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf, g);
 
  497    template< 
class Problem, 
class ElementVolumeVariables >
 
  498    static TijContainer calculateTransmissibility(
const Problem& problem,
 
  499                                                  const Element& element,
 
  500                                                  const FVElementGeometry& fvGeometry,
 
  501                                                  const ElementVolumeVariables& elemVolVars,
 
  502                                                  const SubControlVolumeFace& scvf,
 
  503                                                  typename Cache::GravityCoefficients& g)
 
  506        if (!problem.couplingManager().isCoupled(element, scvf))
 
  509            tij[Cache::insideTijIdx] = TpfaDarcysLaw::calculateTransmissibility(problem, element, fvGeometry, elemVolVars, scvf);
 
  519        if (Dune::FloatCmp::ne(xi, 1.0, 1e-6))
 
  520            DUNE_THROW(Dune::InvalidStateException, 
"Xi != 1.0 cannot be used on surface grids");
 
  522        const auto area = Extrusion::area(fvGeometry, scvf);
 
  523        const auto insideScvIdx = scvf.insideScvIdx();
 
  524        const auto& insideScv = fvGeometry.scv(insideScvIdx);
 
  525        const auto& insideVolVars = elemVolVars[insideScvIdx];
 
  526        const auto wIn = area*
computeTpfaTransmissibility(fvGeometry, scvf, insideScv, insideVolVars.permeability(), insideVolVars.extrusionFactor());
 
  529        const auto iBcTypes = problem.interiorBoundaryTypes(element, scvf);
 
  532        if (iBcTypes.hasOnlyNeumann())
 
  534            const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf);
 
  539            const auto wFacet = 2.0*area*insideVolVars.extrusionFactor()
 
  540                                        /sqrt(facetVolVars.extrusionFactor())
 
  541                                        *
vtmv(scvf.unitOuterNormal(), facetVolVars.permeability(), scvf.unitOuterNormal());
 
  544            g[0] = wIn/(wIn+wFacet);
 
  545            tij[Cache::insideTijIdx] = wFacet*g[0];
 
  546            tij[Cache::facetTijIdx] = -tij[Cache::insideTijIdx];
 
  548        else if (iBcTypes.hasOnlyDirichlet())
 
  550            tij[Cache::insideTijIdx] = wIn;
 
  551            tij[Cache::facetTijIdx] = -wIn;
 
  554            DUNE_THROW(Dune::NotImplemented, 
"Interior boundary types other than pure Dirichlet or Neumann");
 
const GravityCoefficients & gravityCoefficients() const
return the coefficients for the computation of gravity at the scvf
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:115
std::array< Scalar, 3 > AdvectionTransmissibilityContainer
Export transmissibility storage type.
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:79
Scalar advectionTijInside() const
returns the transmissibility associated with the inside cell
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:103
std::array< Scalar, 2 > GravityCoefficients
Export the type used for the gravity coefficients.
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:82
static constexpr int insideTijIdx
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:74
TpfaDarcysLawCacheFiller< GridGeometry > Filler
export the corresponding filler class
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:69
static constexpr int outsideTijIdx
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:75
void updateAdvection(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf)
update subject to a given problem
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:86
static constexpr int facetTijIdx
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:76
Scalar advectionTijOutside() const
returns the transmissibility associated with the outside cell
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:107
Scalar advectionTijFacet() const
returns the transmissibility associated with the outside cell
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:111
Scalar advectionTij() const
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:99
static constexpr int facetTijIdx
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:354
std::array< Scalar, 1 > GravityCoefficients
Export the type used for the gravity coefficients.
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:360
TpfaDarcysLawCacheFiller< GridGeometry > Filler
export the corresponding filler class
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:348
std::array< Scalar, 2 > AdvectionTransmissibilityContainer
Export transmissibility storage type.
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:357
Scalar advectionTij() const
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:377
Scalar advectionTijInside() const
returns the transmissibility associated with the inside cell
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:381
static constexpr int insideTijIdx
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:353
void updateAdvection(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf)
update subject to a given problem
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:364
const GravityCoefficients & gravityCoefficients() const
return the coefficients for the computation of gravity at the scvf
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:389
Scalar advectionTijFacet() const
returns the transmissibility associated with the outside cell
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:385
The cache corresponding to tpfa Darcy's Law with facet coupling.
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:42
Forward declaration of the implementation.
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:33
Class that fills the cache corresponding to tpfa Darcy's Law.
Definition flux/cctpfa/darcyslaw.hh:58
Defines all properties used in Dumux.
Helper classes to compute the integration elements.
Darcy's law for cell-centered finite volume schemes with two-point flux approximation.
Tensor::field_type computeTpfaTransmissibility(const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolumeFace &scvf, const typename FVElementGeometry::SubControlVolume &scv, const Tensor &T, typename FVElementGeometry::SubControlVolume::Traits::Scalar extrusionFactor)
Free function to evaluate the Tpfa transmissibility associated with the flux (in the form of flux = T...
Definition tpfa/computetransmissibility.hh:36
Dune::DenseMatrix< MAT >::value_type vtmv(const Dune::DenseVector< V1 > &v1, const Dune::DenseMatrix< MAT > &M, const Dune::DenseVector< V2 > &v2)
Evaluates the scalar product of a vector v2, projected by a matrix M, with a vector v1.
Definition math.hh:880
CCTpfaFacetCouplingDarcysLawImpl< ScalarType, GridGeometry,(int(GridGeometry::GridView::dimension)< int(GridGeometry::GridView::dimensionworld)) > CCTpfaFacetCouplingDarcysLaw
Darcy's law for cell-centered finite volume schemes with two-point flux approximation in the context ...
Definition multidomain/facet/cellcentered/tpfa/darcyslaw.hh:51
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:149
Define some often used mathematical functions.
The available discretization methods in Dumux.
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:166
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Free functions to evaluate the transmissibilities associated with flux evaluations across sub-control...