25#ifndef DUMUX_MD_FREEFLOW_PORENETWORK_COUPLINGCONDITIONS_HH
26#define DUMUX_MD_FREEFLOW_PORENETWORK_COUPLINGCONDITIONS_HH
30#include <dune/common/exceptions.hh>
42template<
class MDTraits,
class CouplingManager,
bool enableEnergyBalance,
bool isCompositional>
50template<
class MDTraits,
class CouplingManager>
62template<
class MDTraits,
class CouplingManager>
65 using Scalar =
typename MDTraits::Scalar;
67 template<std::
size_t id>
using SubDomainTypeTag =
typename MDTraits::template SubDomain<id>::TypeTag;
69 template<std::
size_t id>
using Element =
typename GridGeometry<id>::GridView::template Codim<0>::Entity;
70 template<std::
size_t id>
using FVElementGeometry =
typename GridGeometry<id>::LocalView;
71 template<std::
size_t id>
using SubControlVolumeFace =
typename GridGeometry<id>::LocalView::SubControlVolumeFace;
72 template<std::
size_t id>
using SubControlVolume =
typename GridGeometry<id>::LocalView::SubControlVolume;
79 template<std::
size_t id>
using GlobalPosition =
typename Element<id>::Geometry::GlobalCoordinate;
80 template<std::
size_t id>
using NumEqVector =
typename Problem<id>::Traits::NumEqVector;
92 static constexpr bool adapterUsed = ModelTraits<poreNetworkIndex>::numFluidPhases() > 1;
97 "All submodels must both be either isothermal or non-isothermal");
100 FluidSystem<poreNetworkIndex>>::value,
101 "All submodels must use the same fluid system");
103 using VelocityVector = GlobalPosition<freeFlowMomentumIndex>;
109 template<std::
size_t i>
110 static constexpr auto couplingPhaseIdx(Dune::index_constant<i>
id,
int coupledPhaseIdx = 0)
111 {
return IndexHelper::couplingPhaseIdx(
id, coupledPhaseIdx); }
116 template<std::
size_t i>
118 {
return IndexHelper::couplingCompIdx(
id, coupledCompIdx); }
128 template<
class Context>
130 const SubControlVolumeFace<freeFlowMomentumIndex>& scvf,
131 const ElementVolumeVariables<freeFlowMomentumIndex>& elemVolVars,
132 const Context& context)
134 NumEqVector<freeFlowMomentumIndex> momentumFlux(0.0);
136 const auto [pnmPressure, pnmViscosity] = [&]
138 for (
const auto& scv : scvs(context.fvGeometry))
140 if (scv.dofIndex() == context.poreNetworkDofIdx)
141 return std::make_pair(context.elemVolVars[scv].pressure(pnmPhaseIdx), context.elemVolVars[scv].viscosity(pnmPhaseIdx));
143 DUNE_THROW(Dune::InvalidStateException,
"No coupled scv found");
147 momentumFlux[scvf.normalAxis()] = pnmPressure;
150 momentumFlux[scvf.normalAxis()] -= elemVolVars.gridVolVars().problem().referencePressure(fvGeometry.element(), fvGeometry, scvf);
155 const auto& scv = fvGeometry.scv(scvf.insideScvIdx());
156 const auto& frontalInternalScvf = (*scvfs(fvGeometry, scv).begin());
162 momentumFlux[scvf.normalAxis()] *= scvf.directionSign();
167 template<
class Context>
169 const SubControlVolumeFace<freeFlowMomentumIndex>& scvf,
170 const Context& context)
172 const auto& pnmElement = context.fvGeometry.element();
173 const auto& pnmFVGeometry = context.fvGeometry;
174 const auto& pnmScvf = pnmFVGeometry.scvf(0);
175 const auto& pnmElemVolVars = context.elemVolVars;
176 const auto& pnmElemFluxVarsCache = context.elemFluxVarsCache;
177 const auto& pnmProblem = pnmElemVolVars.gridVolVars().problem();
180 const Scalar area = pnmElemFluxVarsCache[pnmScvf].throatCrossSectionalArea(pnmPhaseIdx);
186 PNMFluxVariables fluxVars;
187 fluxVars.init(pnmProblem, pnmElement, pnmFVGeometry, pnmElemVolVars, pnmScvf, pnmElemFluxVarsCache);
189 const Scalar flux = fluxVars.advectiveFlux(pnmPhaseIdx, [pnmPhaseIdx](
const auto& volVars){
return volVars.mobility(pnmPhaseIdx);});
192 VelocityVector velocity = (pnmElement.geometry().corner(1) - pnmElement.geometry().corner(0));
193 velocity /= velocity.two_norm();
194 velocity *= flux / area;
200 return VelocityVector(0.0);
206 static Scalar
advectiveFlux(
const Scalar insideQuantity,
const Scalar outsideQuantity,
const Scalar volumeFlow,
bool insideIsUpstream)
208 const Scalar upwindWeight = 1.0;
211 return (upwindWeight * insideQuantity + (1.0 - upwindWeight) * outsideQuantity) * volumeFlow;
213 return (upwindWeight * outsideQuantity + (1.0 - upwindWeight) * insideQuantity) * volumeFlow;
221 template<
class Scv,
class Scvf>
224 return (scv.dofPosition() - scvf.ipGlobal()).two_norm();
232template<
class MDTraits,
class CouplingManager,
bool enableEnergyBalance>
237 using Scalar =
typename MDTraits::Scalar;
240 template<std::
size_t id>
241 using SubDomainTypeTag =
typename MDTraits::template SubDomain<id>::TypeTag;
244 template<std::
size_t id>
using Element =
typename GridGeometry<id>::GridView::template Codim<0>::Entity;
245 template<std::
size_t id>
using FVElementGeometry =
typename GridGeometry<id>::LocalView;
246 template<std::
size_t id>
using SubControlVolumeFace =
typename GridGeometry<id>::LocalView::SubControlVolumeFace;
247 template<std::
size_t id>
using SubControlVolume =
typename GridGeometry<id>::LocalView::SubControlVolume;
253 "Pore-network model must not be compositional");
256 using ParentType::ParentType;
257 using ParentType::couplingPhaseIdx;
262 template<
class CouplingContext>
264 Dune::index_constant<ParentType::freeFlowMassIndex> domainJ,
265 const FVElementGeometry<ParentType::poreNetworkIndex>& fvGeometry,
266 const SubControlVolume<ParentType::poreNetworkIndex>& scv,
267 const ElementVolumeVariables<ParentType::poreNetworkIndex>& insideVolVars,
268 const CouplingContext& context)
270 Scalar massFlux(0.0);
272 for (
const auto& c : context)
275 const Scalar normalFFVelocity = c.velocity * c.scvf.unitOuterNormal();
276 const bool pnmIsUpstream = std::signbit(normalFFVelocity);
280 const Scalar area = c.scvf.area() * c.volVars.extrusionFactor();
283 massFlux += ParentType::advectiveFlux(pnmDensity, ffDensity, normalFFVelocity*area, pnmIsUpstream);
292 template<
class CouplingContext>
294 Dune::index_constant<ParentType::poreNetworkIndex> domainJ,
295 const FVElementGeometry<ParentType::freeFlowMassIndex>& fvGeometry,
296 const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
297 const ElementVolumeVariables<ParentType::freeFlowMassIndex>& insideVolVars,
298 const CouplingContext& context)
301 const Scalar normalFFVelocity = context.velocity * scvf.unitOuterNormal();
302 const bool ffIsUpstream = !std::signbit(normalFFVelocity);
308 return ParentType::advectiveFlux(ffDensity, pnmDensity, normalFFVelocity, ffIsUpstream);
Define some often used mathematical functions.
Fick's law specialized for different discretization schemes. This file contains the data which is req...
Index helpers for the free-flow/porous-medium-flow coupling.
Adaption of the non-isothermal two-phase two-component flow model to problems with CO2.
Definition: adapt.hh:29
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:180
static constexpr auto freeFlowMassIndex
Definition: multidomain/boundary/freeflowporenetwork/couplingmanager.hh:47
static constexpr auto freeFlowMomentumIndex
Definition: multidomain/boundary/freeflowporenetwork/couplingmanager.hh:46
static constexpr auto poreNetworkIndex
Definition: multidomain/boundary/freeflowporenetwork/couplingmanager.hh:48
Traits class encapsulating model specifications.
Definition: common/properties.hh:51
Property to specify the type of a problem which has to be solved.
Definition: common/properties.hh:55
Definition: common/properties.hh:100
The type for a global container for the volume variables.
Definition: common/properties.hh:107
Container storing the different types of flux variables.
Definition: common/properties.hh:111
The type for the calculation the advective fluxes.
Definition: common/properties.hh:139
The type of the fluid system to use.
Definition: common/properties.hh:160
Helper class for calculating the velocity gradients for the Navier-Stokes model using the staggered g...
Definition: momentum/velocitygradients.hh:58
static auto velocityGradII(const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolumeFace &scvf, const ElemVolVars &elemVolVars)
Returns the in-axis velocity gradient.
Definition: momentum/velocitygradients.hh:158
Definition: freeflowporenetwork/couplingconditions.hh:43
A base class which provides some common methods used for free-flow/pore-network coupling.
Definition: freeflowporenetwork/couplingconditions.hh:64
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:129
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:206
static VelocityVector interfaceThroatVelocity(const FVElementGeometry< freeFlowMomentumIndex > &fvGeometry, const SubControlVolumeFace< freeFlowMomentumIndex > &scvf, const Context &context)
Definition: freeflowporenetwork/couplingconditions.hh:168
static constexpr auto freeFlowMassIndex
Definition: freeflowporenetwork/couplingconditions.hh:86
static constexpr auto couplingPhaseIdx(Dune::index_constant< i > id, int coupledPhaseIdx=0)
Returns the corresponding phase index needed for coupling.
Definition: freeflowporenetwork/couplingconditions.hh:110
static constexpr auto poreNetworkIndex
Definition: freeflowporenetwork/couplingconditions.hh:87
Scalar getDistance_(const Scv &scv, const Scvf &scvf) const
Returns the distance between an scvf and the corresponding scv center.
Definition: freeflowporenetwork/couplingconditions.hh:222
static constexpr auto freeFlowMomentumIndex
Definition: freeflowporenetwork/couplingconditions.hh:85
static constexpr auto couplingCompIdx(Dune::index_constant< i > id, int coupledCompIdx)
Returns the corresponding component index needed for coupling.
Definition: freeflowporenetwork/couplingconditions.hh:117
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:263
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:293
Helper struct to choose the correct index for phases and components. This is need if the porous-mediu...
Definition: indexhelper.hh:42
This structs helps to check if the two sub models use the same fluidsystem. Specialization for the ca...
Definition: multidomain/boundary/freeflowporousmedium/traits.hh:42
The interface of the coupling manager for multi domain problems.
Definition: multidomain/couplingmanager.hh:60
Declares all properties used in Dumux.
Free functions to evaluate the transmissibilities associated with flux evaluations across sub-control...
Traits for the free-flow/porous-medium-flow coupling.