13#ifndef DUMUX_MD_FREEFLOW_PORENETWORK_COUPLINGCONDITIONS_HH
14#define DUMUX_MD_FREEFLOW_PORENETWORK_COUPLINGCONDITIONS_HH
18#include <dune/common/exceptions.hh>
30template<
class MDTraits,
class CouplingManager,
bool enableEnergyBalance,
bool isCompositional>
38template<
class MDTraits,
class CouplingManager>
50template<
class MDTraits,
class CouplingManager>
53 using Scalar =
typename MDTraits::Scalar;
55 template<std::
size_t id>
using SubDomainTypeTag =
typename MDTraits::template SubDomain<id>::TypeTag;
57 template<std::
size_t id>
using Element =
typename GridGeometry<id>::GridView::template Codim<0>::Entity;
58 template<std::
size_t id>
using FVElementGeometry =
typename GridGeometry<id>::LocalView;
59 template<std::
size_t id>
using SubControlVolumeFace =
typename GridGeometry<id>::LocalView::SubControlVolumeFace;
60 template<std::
size_t id>
using SubControlVolume =
typename GridGeometry<id>::LocalView::SubControlVolume;
67 template<std::
size_t id>
using GlobalPosition =
typename Element<id>::Geometry::GlobalCoordinate;
68 template<std::
size_t id>
using NumEqVector =
typename Problem<id>::Traits::NumEqVector;
80 static constexpr bool adapterUsed = ModelTraits<poreNetworkIndex>::numFluidPhases() > 1;
85 "All submodels must both be either isothermal or non-isothermal");
88 FluidSystem<poreNetworkIndex>>::value,
89 "All submodels must use the same fluid system");
91 using VelocityVector = GlobalPosition<freeFlowMomentumIndex>;
97 template<std::
size_t i>
98 static constexpr auto couplingPhaseIdx(Dune::index_constant<i>
id,
int coupledPhaseIdx = 0)
99 {
return IndexHelper::couplingPhaseIdx(
id, coupledPhaseIdx); }
104 template<std::
size_t i>
106 {
return IndexHelper::couplingCompIdx(
id, coupledCompIdx); }
116 template<
class Context>
118 const SubControlVolumeFace<freeFlowMomentumIndex>& scvf,
119 const ElementVolumeVariables<freeFlowMomentumIndex>& elemVolVars,
120 const Context& context)
122 NumEqVector<freeFlowMomentumIndex> momentumFlux(0.0);
124 const auto [pnmPressure, pnmViscosity] = [&]
126 for (
const auto& scv : scvs(context.fvGeometry))
128 if (scv.dofIndex() == context.poreNetworkDofIdx)
129 return std::make_pair(context.elemVolVars[scv].pressure(pnmPhaseIdx), context.elemVolVars[scv].viscosity(pnmPhaseIdx));
131 DUNE_THROW(Dune::InvalidStateException,
"No coupled scv found");
135 momentumFlux[scvf.normalAxis()] = pnmPressure;
138 momentumFlux[scvf.normalAxis()] -= elemVolVars.gridVolVars().problem().referencePressure(fvGeometry.element(), fvGeometry, scvf);
143 const auto& scv = fvGeometry.scv(scvf.insideScvIdx());
144 const auto& frontalInternalScvf = (*scvfs(fvGeometry, scv).begin());
150 momentumFlux[scvf.normalAxis()] *= scvf.directionSign();
155 template<
class Context>
157 const SubControlVolumeFace<freeFlowMomentumIndex>& scvf,
158 const Context& context)
160 const auto& pnmElement = context.fvGeometry.element();
161 const auto& pnmFVGeometry = context.fvGeometry;
162 const auto& pnmScvf = pnmFVGeometry.scvf(0);
163 const auto& pnmElemVolVars = context.elemVolVars;
164 const auto& pnmElemFluxVarsCache = context.elemFluxVarsCache;
165 const auto& pnmProblem = pnmElemVolVars.gridVolVars().problem();
168 const Scalar area = pnmElemFluxVarsCache[pnmScvf].throatCrossSectionalArea(pnmPhaseIdx);
174 PNMFluxVariables fluxVars;
175 fluxVars.init(pnmProblem, pnmElement, pnmFVGeometry, pnmElemVolVars, pnmScvf, pnmElemFluxVarsCache);
177 const Scalar flux = fluxVars.advectiveFlux(pnmPhaseIdx, [pnmPhaseIdx](
const auto& volVars){
return volVars.mobility(pnmPhaseIdx);});
180 VelocityVector velocity = (pnmElement.geometry().corner(1) - pnmElement.geometry().corner(0));
181 velocity /= velocity.two_norm();
182 velocity *= flux / area;
188 return VelocityVector(0.0);
194 static Scalar
advectiveFlux(
const Scalar insideQuantity,
const Scalar outsideQuantity,
const Scalar volumeFlow,
bool insideIsUpstream)
196 const Scalar upwindWeight = 1.0;
199 return (upwindWeight * insideQuantity + (1.0 - upwindWeight) * outsideQuantity) * volumeFlow;
201 return (upwindWeight * outsideQuantity + (1.0 - upwindWeight) * insideQuantity) * volumeFlow;
209 template<
class Scv,
class Scvf>
212 return (scv.dofPosition() - scvf.ipGlobal()).two_norm();
220template<
class MDTraits,
class CouplingManager,
bool enableEnergyBalance>
225 using Scalar =
typename MDTraits::Scalar;
228 template<std::
size_t id>
229 using SubDomainTypeTag =
typename MDTraits::template SubDomain<id>::TypeTag;
232 template<std::
size_t id>
using Element =
typename GridGeometry<id>::GridView::template Codim<0>::Entity;
233 template<std::
size_t id>
using FVElementGeometry =
typename GridGeometry<id>::LocalView;
234 template<std::
size_t id>
using SubControlVolumeFace =
typename GridGeometry<id>::LocalView::SubControlVolumeFace;
235 template<std::
size_t id>
using SubControlVolume =
typename GridGeometry<id>::LocalView::SubControlVolume;
241 "Pore-network model must not be compositional");
244 using ParentType::ParentType;
245 using ParentType::couplingPhaseIdx;
250 template<
class CouplingContext>
252 Dune::index_constant<ParentType::freeFlowMassIndex> domainJ,
253 const FVElementGeometry<ParentType::poreNetworkIndex>& fvGeometry,
254 const SubControlVolume<ParentType::poreNetworkIndex>& scv,
255 const ElementVolumeVariables<ParentType::poreNetworkIndex>& insideVolVars,
256 const CouplingContext& context)
258 Scalar massFlux(0.0);
260 for (
const auto& c : context)
263 const Scalar normalFFVelocity = c.velocity * c.scvf.unitOuterNormal();
264 const bool pnmIsUpstream = std::signbit(normalFFVelocity);
268 const Scalar area = c.scvf.area() * c.volVars.extrusionFactor();
271 massFlux += ParentType::advectiveFlux(pnmDensity, ffDensity, normalFFVelocity*area, pnmIsUpstream);
280 template<
class CouplingContext>
282 Dune::index_constant<ParentType::poreNetworkIndex> domainJ,
283 const FVElementGeometry<ParentType::freeFlowMassIndex>& fvGeometry,
284 const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
285 const ElementVolumeVariables<ParentType::freeFlowMassIndex>& insideVolVars,
286 const CouplingContext& context)
289 const Scalar normalFFVelocity = context.velocity * scvf.unitOuterNormal();
290 const bool ffIsUpstream = !std::signbit(normalFFVelocity);
296 return ParentType::advectiveFlux(ffDensity, pnmDensity, normalFFVelocity, ffIsUpstream);
The interface of the coupling manager for multi domain problems.
Definition: multidomain/couplingmanager.hh:37
static Scalar massCouplingCondition(Dune::index_constant< ParentType::poreNetworkIndex > domainI, Dune::index_constant< ParentType::freeFlowMassIndex > domainJ, const FVElementGeometry< ParentType::poreNetworkIndex > &fvGeometry, const SubControlVolume< ParentType::poreNetworkIndex > &scv, const ElementVolumeVariables< ParentType::poreNetworkIndex > &insideVolVars, const CouplingContext &context)
Returns the mass flux across the coupling boundary as seen from the pore-network domain.
Definition: freeflowporenetwork/couplingconditions.hh:251
static Scalar massCouplingCondition(Dune::index_constant< ParentType::freeFlowMassIndex > domainI, Dune::index_constant< ParentType::poreNetworkIndex > domainJ, const FVElementGeometry< ParentType::freeFlowMassIndex > &fvGeometry, const SubControlVolumeFace< ParentType::freeFlowMassIndex > &scvf, const ElementVolumeVariables< ParentType::freeFlowMassIndex > &insideVolVars, const CouplingContext &context)
Returns the mass flux across the coupling boundary as seen from the free-flow domain.
Definition: freeflowporenetwork/couplingconditions.hh:281
A base class which provides some common methods used for free-flow/pore-network coupling.
Definition: freeflowporenetwork/couplingconditions.hh:52
static NumEqVector< freeFlowMomentumIndex > momentumCouplingCondition(const FVElementGeometry< freeFlowMomentumIndex > &fvGeometry, const SubControlVolumeFace< freeFlowMomentumIndex > &scvf, const ElementVolumeVariables< freeFlowMomentumIndex > &elemVolVars, const Context &context)
Returns the momentum flux across the coupling boundary.
Definition: freeflowporenetwork/couplingconditions.hh:117
static Scalar advectiveFlux(const Scalar insideQuantity, const Scalar outsideQuantity, const Scalar volumeFlow, bool insideIsUpstream)
Evaluate an advective flux across the interface and consider upwinding.
Definition: freeflowporenetwork/couplingconditions.hh:194
static VelocityVector interfaceThroatVelocity(const FVElementGeometry< freeFlowMomentumIndex > &fvGeometry, const SubControlVolumeFace< freeFlowMomentumIndex > &scvf, const Context &context)
Definition: freeflowporenetwork/couplingconditions.hh:156
static constexpr auto freeFlowMassIndex
Definition: freeflowporenetwork/couplingconditions.hh:74
static constexpr auto couplingPhaseIdx(Dune::index_constant< i > id, int coupledPhaseIdx=0)
Returns the corresponding phase index needed for coupling.
Definition: freeflowporenetwork/couplingconditions.hh:98
static constexpr auto poreNetworkIndex
Definition: freeflowporenetwork/couplingconditions.hh:75
Scalar getDistance_(const Scv &scv, const Scvf &scvf) const
Returns the distance between an scvf and the corresponding scv center.
Definition: freeflowporenetwork/couplingconditions.hh:210
static constexpr auto freeFlowMomentumIndex
Definition: freeflowporenetwork/couplingconditions.hh:73
static constexpr auto couplingCompIdx(Dune::index_constant< i > id, int coupledCompIdx)
Returns the corresponding component index needed for coupling.
Definition: freeflowporenetwork/couplingconditions.hh:105
Definition: freeflowporenetwork/couplingconditions.hh:31
Helper class for calculating the velocity gradients for the Navier-Stokes model using the staggered g...
Definition: momentum/velocitygradients.hh:46
static auto velocityGradII(const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolumeFace &scvf, const ElemVolVars &elemVolVars)
Returns the in-axis velocity gradient.
Definition: momentum/velocitygradients.hh:146
Defines all properties used in Dumux.
Fick's law specialized for different discretization schemes. This file contains the data which is req...
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:296
Index helpers for the free-flow/porous-medium-flow coupling.
Define some often used mathematical functions.
Traits for the free-flow/porous-medium-flow coupling.
static constexpr auto freeFlowMassIndex
Definition: multidomain/boundary/freeflowporenetwork/couplingmanager.hh:35
static constexpr auto freeFlowMomentumIndex
Definition: multidomain/boundary/freeflowporenetwork/couplingmanager.hh:34
static constexpr auto poreNetworkIndex
Definition: multidomain/boundary/freeflowporenetwork/couplingmanager.hh:36
Helper struct to choose the correct index for phases and components. This is need if the porous-mediu...
Definition: indexhelper.hh:30
This structs helps to check if the two sub models use the same fluidsystem. Specialization for the ca...
Definition: multidomain/boundary/freeflowporousmedium/traits.hh:30
Free functions to evaluate the transmissibilities associated with flux evaluations across sub-control...