13#ifndef DUMUX_MD_FREEFLOW_POROUSMEDIUM_COUPLINGCONDITIONS_STAGGERED_TPFA_HH
14#define DUMUX_MD_FREEFLOW_POROUSMEDIUM_COUPLINGCONDITIONS_STAGGERED_TPFA_HH
18#include <dune/common/exceptions.hh>
48 harmonic, arithmetic, ffOnly, pmOnly
57 if (diffusionCoefficientAveragingType ==
"Harmonic")
59 else if (diffusionCoefficientAveragingType ==
"Arithmetic")
61 else if (diffusionCoefficientAveragingType ==
"FreeFlowOnly")
63 else if (diffusionCoefficientAveragingType ==
"PorousMediumOnly")
66 DUNE_THROW(Dune::IOError,
"Unknown DiffusionCoefficientAveragingType");
71template<
class MDTraits,
class CouplingManager,
bool enableEnergyBalance,
bool isCompositional>
79template<
class MDTraits,
class CouplingManager>
91template<
class MDTraits,
class CouplingManager>
94 using Scalar =
typename MDTraits::Scalar;
96 template<std::
size_t id>
using SubDomainTypeTag =
typename MDTraits::template SubDomain<id>::TypeTag;
98 template<std::
size_t id>
using Element =
typename GridGeometry<id>::GridView::template Codim<0>::Entity;
99 template<std::
size_t id>
using FVElementGeometry =
typename GridGeometry<id>::LocalView;
100 template<std::
size_t id>
using SubControlVolumeFace =
typename GridGeometry<id>::LocalView::SubControlVolumeFace;
101 template<std::
size_t id>
using SubControlVolume =
typename GridGeometry<id>::LocalView::SubControlVolume;
108 template<std::
size_t id>
using GlobalPosition =
typename Element<id>::Geometry::GlobalCoordinate;
109 template<std::
size_t id>
using NumEqVector =
typename Problem<id>::Traits::NumEqVector;
121 static constexpr bool adapterUsed = ModelTraits<porousMediumIndex>::numFluidPhases() > 1;
126 "All submodels must both be either isothermal or non-isothermal");
129 FluidSystem<porousMediumIndex>>::value,
130 "All submodels must use the same fluid system");
138 template<std::
size_t i>
139 static constexpr auto couplingPhaseIdx(Dune::index_constant<i>
id,
int coupledPhaseIdx = 0)
140 {
return IndexHelper::couplingPhaseIdx(
id, coupledPhaseIdx); }
145 template<std::
size_t i>
147 {
return IndexHelper::couplingCompIdx(
id, coupledCompIdx); }
152 template<
class Context>
154 const SubControlVolumeFace<freeFlowMomentumIndex>& scvf,
155 const Context& context)
156 {
return context.volVars.permeability(); }
165 template<
class Context>
167 const SubControlVolumeFace<freeFlowMomentumIndex>& scvf,
168 const ElementVolumeVariables<freeFlowMomentumIndex>& elemVolVars,
169 const Context& context)
172 NumEqVector<freeFlowMomentumIndex> momentumFlux(0.0);
174 if (!scvf.isFrontal())
179 if(numPhasesDarcy > 1)
180 momentumFlux[scvf.normalAxis()] = context.volVars.pressure(pmPhaseIdx);
187 momentumFlux[scvf.normalAxis()] -= elemVolVars.gridVolVars().problem().referencePressure(fvGeometry.element(), fvGeometry, scvf);
189 momentumFlux[scvf.normalAxis()] *= scvf.directionSign();
197 static Scalar
advectiveFlux(
const Scalar insideQuantity,
const Scalar outsideQuantity,
const Scalar volumeFlow,
bool insideIsUpstream)
199 const Scalar upwindWeight = 1.0;
202 return (upwindWeight * insideQuantity + (1.0 - upwindWeight) * outsideQuantity) * volumeFlow;
204 return (upwindWeight * outsideQuantity + (1.0 - upwindWeight) * insideQuantity) * volumeFlow;
212 template<std::
size_t i, std::
size_t j>
214 Dune::index_constant<j> domainJ,
215 const Scalar insideDistance,
216 const Scalar outsideDistance,
217 const Scalar avgQuantityI,
218 const Scalar avgQuantityJ,
219 const DiffusionCoefficientAveragingType diffCoeffAvgType)
const
221 const Scalar totalDistance = insideDistance + outsideDistance;
222 if(diffCoeffAvgType == DiffusionCoefficientAveragingType::harmonic)
224 return harmonicMean(avgQuantityI, avgQuantityJ, insideDistance, outsideDistance)
227 else if(diffCoeffAvgType == DiffusionCoefficientAveragingType::arithmetic)
229 return arithmeticMean(avgQuantityI, avgQuantityJ, insideDistance, outsideDistance)
232 else if(diffCoeffAvgType == DiffusionCoefficientAveragingType::ffOnly)
234 ? avgQuantityI / totalDistance
235 : avgQuantityJ / totalDistance;
239 ? avgQuantityI / totalDistance
240 : avgQuantityJ / totalDistance;
246 template<
class Scv,
class Scvf>
249 return (scv.dofPosition() - scvf.ipGlobal()).two_norm();
255 template<std::
size_t i, std::
size_t j,
bool isNI = enableEnergyBalance,
typename std::enable_if_t<isNI,
int> = 0>
257 Dune::index_constant<j> domainJ,
258 const FVElementGeometry<i>& fvGeometryI,
259 const FVElementGeometry<j>& fvGeometryJ,
260 const SubControlVolumeFace<i>& scvfI,
261 const SubControlVolume<i>& scvI,
262 const SubControlVolume<j>& scvJ,
263 const VolumeVariables<i>& volVarsI,
264 const VolumeVariables<j>& volVarsJ,
265 const DiffusionCoefficientAveragingType diffCoeffAvgType)
const
267 const Scalar insideDistance =
getDistance_(scvI, scvfI);
268 const Scalar outsideDistance =
getDistance_(scvJ, scvfI);
270 const Scalar deltaT = volVarsJ.temperature() - volVarsI.temperature();
273 insideDistance, outsideDistance,
274 volVarsI.effectiveThermalConductivity(), volVarsJ.effectiveThermalConductivity(),
278 return -tij * deltaT;
284 template<
class CouplingContext>
286 const SubControlVolumeFace<freeFlowMomentumIndex>& scvf,
287 const ElementVolumeVariables<freeFlowMomentumIndex>& elemVolVars,
288 const CouplingContext& context)
290 GlobalPosition<freeFlowMomentumIndex> velocity(0.0);
291 const auto& scv = fvGeometry.scv(scvf.insideScvIdx());
292 velocity[scv.dofAxis()] = elemVolVars[scv].velocity();
293 const auto& pmScvf = context.fvGeometry.scvf(context.porousMediumScvfIdx);
301 const SubControlVolumeFace<porousMediumIndex>& scvf,
302 const VolumeVariables<porousMediumIndex>& volVars,
303 const typename Element<freeFlowMomentumIndex>::Geometry::GlobalCoordinate& couplingPhaseVelocity,
306 DUNE_THROW(Dune::NotImplemented,
"Forchheimer's law pressure reconstruction");
313 const SubControlVolumeFace<porousMediumIndex>& scvf,
314 const VolumeVariables<porousMediumIndex>& volVars,
315 const typename Element<freeFlowMomentumIndex>::Geometry::GlobalCoordinate& gravity,
316 const typename Element<freeFlowMomentumIndex>::Geometry::GlobalCoordinate& couplingPhaseVelocity,
320 const Scalar couplingPhaseCellCenterPressure = volVars.pressure(pmPhaseIdx);
321 const Scalar couplingPhaseMobility = volVars.mobility(pmPhaseIdx);
322 const Scalar couplingPhaseDensity = volVars.density(pmPhaseIdx);
323 const auto K = volVars.permeability();
329 const auto alpha =
vtmv(scvf.unitOuterNormal(), K, gravity);
331 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
334 return (-1/couplingPhaseMobility * (scvf.unitOuterNormal() * couplingPhaseVelocity) + couplingPhaseDensity * alpha)/ti
335 + couplingPhaseCellCenterPressure;
343template<
class MDTraits,
class CouplingManager,
bool enableEnergyBalance>
348 using Scalar =
typename MDTraits::Scalar;
351 template<std::
size_t id>
352 using SubDomainTypeTag =
typename MDTraits::template SubDomain<id>::TypeTag;
355 template<std::
size_t id>
using Element =
typename GridGeometry<id>::GridView::template Codim<0>::Entity;
356 template<std::
size_t id>
using FVElementGeometry =
typename GridGeometry<id>::LocalView;
357 template<std::
size_t id>
using SubControlVolumeFace =
typename GridGeometry<id>::LocalView::SubControlVolumeFace;
358 template<std::
size_t id>
using SubControlVolume =
typename GridGeometry<id>::LocalView::SubControlVolume;
364 "Darcy Model must not be compositional");
369 using ParentType::ParentType;
370 using ParentType::couplingPhaseIdx;
375 template<std::
size_t i, std::
size_t j,
class CouplingContext>
377 Dune::index_constant<j> domainJ,
378 const FVElementGeometry<i>& fvGeometry,
379 const SubControlVolumeFace<i>& scvf,
380 const ElementVolumeVariables<i>& insideVolVars,
381 const CouplingContext& context)
383 const Scalar normalVelocity = context.velocity * scvf.unitOuterNormal();
384 const Scalar darcyDensity = insideVolVars[scvf.insideScvIdx()].density(couplingPhaseIdx(ParentType::porousMediumIndex));
385 const Scalar stokesDensity = context.volVars.density();
386 const bool insideIsUpstream = normalVelocity > 0.0;
387 return ParentType::advectiveFlux(darcyDensity, stokesDensity, normalVelocity, insideIsUpstream);
393 template<
bool isNI = enableEnergyBalance,
typename std::enable_if_t<isNI,
int> = 0>
395 const FVElementGeometry<ParentType::porousMediumIndex>& fvGeometry,
396 const ElementVolumeVariables<ParentType::porousMediumIndex>& darcyElemVolVars,
397 const SubControlVolumeFace<ParentType::porousMediumIndex>& scvf,
398 const DiffusionCoefficientAveragingType diffCoeffAvgType = DiffusionCoefficientAveragingType::ffOnly)
const
400 DUNE_THROW(Dune::NotImplemented,
"Energy coupling condition");
406 template<
bool isNI = enableEnergyBalance,
typename std::enable_if_t<isNI,
int> = 0>
408 const FVElementGeometry<ParentType::freeFlowMassIndex>& fvGeometry,
409 const ElementVolumeVariables<ParentType::freeFlowMassIndex>& stokesElemVolVars,
410 const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
411 const DiffusionCoefficientAveragingType diffCoeffAvgType = DiffusionCoefficientAveragingType::ffOnly)
const
413 DUNE_THROW(Dune::NotImplemented,
"Energy coupling condition");
423 template<std::
size_t i, std::
size_t j,
bool isNI = enableEnergyBalance,
typename std::enable_if_t<isNI,
int> = 0>
424 Scalar energyFlux_(Dune::index_constant<i> domainI,
425 Dune::index_constant<j> domainJ,
426 const FVElementGeometry<i>& insideFvGeometry,
427 const FVElementGeometry<j>& outsideFvGeometry,
428 const SubControlVolumeFace<i>& scvf,
429 const VolumeVariables<i>& insideVolVars,
430 const VolumeVariables<j>& outsideVolVars,
431 const Scalar velocity,
432 const bool insideIsUpstream,
433 const DiffusionCoefficientAveragingType diffCoeffAvgType)
const
437 const auto& insideScv = (*scvs(insideFvGeometry).begin());
438 const auto& outsideScv = (*scvs(outsideFvGeometry).begin());
441 const Scalar insideTerm = insideVolVars.density(couplingPhaseIdx(domainI)) * insideVolVars.enthalpy(couplingPhaseIdx(domainI));
442 const Scalar outsideTerm = outsideVolVars.density(couplingPhaseIdx(domainJ)) * outsideVolVars.enthalpy(couplingPhaseIdx(domainJ));
444 flux += this->advectiveFlux(insideTerm, outsideTerm, velocity, insideIsUpstream);
446 flux += this->conductiveEnergyFlux_(domainI, domainJ, insideFvGeometry, outsideFvGeometry, scvf, insideScv, outsideScv, insideVolVars, outsideVolVars, diffCoeffAvgType);
The interface of the coupling manager for multi domain problems.
Definition: multidomain/couplingmanager.hh:37
forward declaration of the method-specific implementation
Definition: flux/ccmpfa/darcyslaw.hh:27
static Scalar massCouplingCondition(Dune::index_constant< i > domainI, Dune::index_constant< j > domainJ, const FVElementGeometry< i > &fvGeometry, const SubControlVolumeFace< i > &scvf, const ElementVolumeVariables< i > &insideVolVars, const CouplingContext &context)
Returns the mass flux across the coupling boundary as seen from the Darcy domain.
Definition: couplingconditions_staggered_cctpfa.hh:376
Scalar energyCouplingCondition(const Element< ParentType::freeFlowMassIndex > &element, const FVElementGeometry< ParentType::freeFlowMassIndex > &fvGeometry, const ElementVolumeVariables< ParentType::freeFlowMassIndex > &stokesElemVolVars, const SubControlVolumeFace< ParentType::freeFlowMassIndex > &scvf, const DiffusionCoefficientAveragingType diffCoeffAvgType=DiffusionCoefficientAveragingType::ffOnly) const
Returns the energy flux across the coupling boundary as seen from the free-flow domain.
Definition: couplingconditions_staggered_cctpfa.hh:407
Scalar energyCouplingCondition(const Element< ParentType::porousMediumIndex > &element, const FVElementGeometry< ParentType::porousMediumIndex > &fvGeometry, const ElementVolumeVariables< ParentType::porousMediumIndex > &darcyElemVolVars, const SubControlVolumeFace< ParentType::porousMediumIndex > &scvf, const DiffusionCoefficientAveragingType diffCoeffAvgType=DiffusionCoefficientAveragingType::ffOnly) const
Returns the energy flux across the coupling boundary as seen from the Darcy domain.
Definition: couplingconditions_staggered_cctpfa.hh:394
A base class which provides some common methods used for Stokes-Darcy coupling.
Definition: couplingconditions_staggered_cctpfa.hh:93
static Scalar computeCouplingPhasePressureAtInterface_(const FVElementGeometry< porousMediumIndex > &fvGeometry, const SubControlVolumeFace< porousMediumIndex > &scvf, const VolumeVariables< porousMediumIndex > &volVars, const typename Element< freeFlowMomentumIndex >::Geometry::GlobalCoordinate &couplingPhaseVelocity, ForchheimersLaw)
Returns the pressure at the interface using Forchheimers's law for reconstruction.
Definition: couplingconditions_staggered_cctpfa.hh:300
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: couplingconditions_staggered_cctpfa.hh:197
Scalar getDistance_(const Scv &scv, const Scvf &scvf) const
Returns the distance between an scvf and the corresponding scv center.
Definition: couplingconditions_staggered_cctpfa.hh:247
static constexpr auto freeFlowMomentumIndex
Definition: couplingconditions_staggered_cctpfa.hh:112
Scalar transmissibility_(Dune::index_constant< i > domainI, Dune::index_constant< j > domainJ, const Scalar insideDistance, const Scalar outsideDistance, const Scalar avgQuantityI, const Scalar avgQuantityJ, const DiffusionCoefficientAveragingType diffCoeffAvgType) const
Returns the transmissibility used for either molecular diffusion or thermal conductivity.
Definition: couplingconditions_staggered_cctpfa.hh:213
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: couplingconditions_staggered_cctpfa.hh:166
static constexpr auto freeFlowMassIndex
Definition: couplingconditions_staggered_cctpfa.hh:113
static constexpr auto porousMediumIndex
Definition: couplingconditions_staggered_cctpfa.hh:114
static Scalar pressureAtInterface_(const FVElementGeometry< freeFlowMomentumIndex > &fvGeometry, const SubControlVolumeFace< freeFlowMomentumIndex > &scvf, const ElementVolumeVariables< freeFlowMomentumIndex > &elemVolVars, const CouplingContext &context)
Returns the pressure at the interface.
Definition: couplingconditions_staggered_cctpfa.hh:285
Scalar conductiveEnergyFlux_(Dune::index_constant< i > domainI, Dune::index_constant< j > domainJ, const FVElementGeometry< i > &fvGeometryI, const FVElementGeometry< j > &fvGeometryJ, const SubControlVolumeFace< i > &scvfI, const SubControlVolume< i > &scvI, const SubControlVolume< j > &scvJ, const VolumeVariables< i > &volVarsI, const VolumeVariables< j > &volVarsJ, const DiffusionCoefficientAveragingType diffCoeffAvgType) const
Returns the conductive energy flux across the interface.
Definition: couplingconditions_staggered_cctpfa.hh:256
static constexpr auto couplingCompIdx(Dune::index_constant< i > id, int coupledCompIdx)
Returns the corresponding component index needed for coupling.
Definition: couplingconditions_staggered_cctpfa.hh:146
static constexpr auto couplingPhaseIdx(Dune::index_constant< i > id, int coupledPhaseIdx=0)
Returns the corresponding phase index needed for coupling.
Definition: couplingconditions_staggered_cctpfa.hh:139
static Scalar computeCouplingPhasePressureAtInterface_(const FVElementGeometry< porousMediumIndex > &fvGeometry, const SubControlVolumeFace< porousMediumIndex > &scvf, const VolumeVariables< porousMediumIndex > &volVars, const typename Element< freeFlowMomentumIndex >::Geometry::GlobalCoordinate &gravity, const typename Element< freeFlowMomentumIndex >::Geometry::GlobalCoordinate &couplingPhaseVelocity, DarcysLaw)
Returns the pressure at the interface using Darcy's law for reconstruction.
Definition: couplingconditions_staggered_cctpfa.hh:312
static auto darcyPermeability(const FVElementGeometry< freeFlowMomentumIndex > &fvGeometry, const SubControlVolumeFace< freeFlowMomentumIndex > &scvf, const Context &context)
Returns the intrinsic permeability of the coupled Darcy element.
Definition: couplingconditions_staggered_cctpfa.hh:153
Definition: couplingconditions_staggered_cctpfa.hh:72
forward declare
Definition: forchheimerslaw_fwd.hh:27
Defines all properties used in Dumux.
Darcy's law specialized for different discretization schemes This file contains the data which is req...
Fick's law specialized for different discretization schemes. This file contains the data which is req...
Forchheimer's law specialized for different discretization schemes This file contains the data which ...
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
constexpr Scalar harmonicMean(Scalar x, Scalar y, Scalar wx=1.0, Scalar wy=1.0) noexcept
Calculate the (weighted) harmonic mean of two scalar values.
Definition: math.hh:57
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
constexpr Scalar arithmeticMean(Scalar x, Scalar y, Scalar wx=1.0, Scalar wy=1.0) noexcept
Calculate the (weighted) arithmetic mean of two scalar values.
Definition: math.hh:38
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
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
This structs holds a set of options which allow to modify the Stokes-Darcy coupling mechanism during ...
Definition: couplingconditions_staggered_cctpfa.hh:40
static DiffusionCoefficientAveragingType stringToEnum(DiffusionCoefficientAveragingType, const std::string &diffusionCoefficientAveragingType)
Convenience function to convert user input given as std::string to the corresponding enum class used ...
Definition: couplingconditions_staggered_cctpfa.hh:55
DiffusionCoefficientAveragingType
Defines which kind of averanging of diffusion coefficients (moleculat diffusion or thermal conductanc...
Definition: couplingconditions_staggered_cctpfa.hh:47
Free functions to evaluate the transmissibilities associated with flux evaluations across sub-control...