51template<
class MDTraits, 
class CouplingManager>
 
   54    using Scalar = 
typename MDTraits::Scalar;
 
   56    template<std::
size_t id> 
using SubDomainTypeTag = 
typename MDTraits::template SubDomain<id>::TypeTag;
 
   58    template<std::
size_t id> 
using Element = 
typename GridGeometry<id>::GridView::template Codim<0>::Entity;
 
   59    template<std::
size_t id> 
using FVElementGeometry = 
typename GridGeometry<id>::LocalView;
 
   60    template<std::
size_t id> 
using SubControlVolumeFace = 
typename GridGeometry<id>::LocalView::SubControlVolumeFace;
 
   61    template<std::
size_t id> 
using SubControlVolume = 
typename GridGeometry<id>::LocalView::SubControlVolume;
 
   68    template<std::
size_t id> 
using GlobalPosition = 
typename Element<id>::Geometry::GlobalCoordinate;
 
   69    template<std::
size_t id> 
using NumEqVector = 
typename Problem<id>::Traits::NumEqVector;
 
   81    static constexpr bool adapterUsed = ModelTraits<poreNetworkIndex>::numFluidPhases() > 1;
 
   86                  "All submodels must both be either isothermal or non-isothermal");
 
   89                                                                  FluidSystem<poreNetworkIndex>>::value,
 
   90                  "All submodels must use the same fluid system");
 
   92    using VelocityVector = GlobalPosition<freeFlowMomentumIndex>;
 
   98    template<std::
size_t i>
 
   99    static constexpr auto couplingPhaseIdx(Dune::index_constant<i> 
id, 
int coupledPhaseIdx = 0)
 
 
  100    { 
return IndexHelper::couplingPhaseIdx(
id, coupledPhaseIdx); }
 
  105    template<std::
size_t i>
 
  106    static constexpr auto couplingCompIdx(Dune::index_constant<i> 
id, 
int coupledCompIdx)
 
 
  107    { 
return IndexHelper::couplingCompIdx(
id, coupledCompIdx); }
 
  116    template<
class Context>
 
  117    static NumEqVector<freeFlowMomentumIndex> 
momentumCouplingCondition(
const FVElementGeometry<freeFlowMomentumIndex>& fvGeometry,
 
  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[0] = pnmPressure;
 
  138        momentumFlux[0] -= 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[0] *= 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;
 
 
  207    template<std::
size_t i, std::
size_t j, 
bool isNI = enableEnergyBalance, 
typename std::enable_if_t<isNI, 
int> = 0>
 
  209                                       Dune::index_constant<j> domainJ,
 
  210                                       const SubControlVolumeFace<freeFlowMassIndex>& scvf,
 
  211                                       const SubControlVolume<i>& scvI,
 
  212                                       const SubControlVolume<j>& scvJ,
 
  213                                       const VolumeVariables<i>& volVarsI,
 
  214                                       const VolumeVariables<j>& volVarsJ)
 
  218        const auto& freeFlowVolVars = std::get<const VolumeVariables<freeFlowMassIndex>&>(std::forward_as_tuple(volVarsI, volVarsJ));
 
  219        const auto& ffScv = std::get<const SubControlVolume<freeFlowMassIndex>&>(std::forward_as_tuple(scvI, scvJ));
 
  222        const Scalar tij = freeFlowVolVars.fluidThermalConductivity() / 
distance;
 
  224        const Scalar deltaT = volVarsJ.temperature() - volVarsI.temperature();
 
  226        return -deltaT * tij;
 
 
  233    template<
class Scv, 
class Scvf>
 
  234    static Scalar 
getDistance_(
const Scv& scv, 
const Scvf& scvf)
 
  236        return (scv.dofPosition() - scvf.ipGlobal()).two_norm();
 
 
 
  244template<
class MDTraits, 
class CouplingManager, 
bool enableEnergyBalance>
 
  249    using Scalar = 
typename MDTraits::Scalar;
 
  252    template<std::
size_t id>
 
  253    using SubDomainTypeTag = 
typename MDTraits::template SubDomain<id>::TypeTag;
 
  256    template<std::
size_t id> 
using Element = 
typename GridGeometry<id>::GridView::template Codim<0>::Entity;
 
  257    template<std::
size_t id> 
using FVElementGeometry = 
typename GridGeometry<id>::LocalView;
 
  258    template<std::
size_t id> 
using SubControlVolumeFace = 
typename GridGeometry<id>::LocalView::SubControlVolumeFace;
 
  259    template<std::
size_t id> 
using SubControlVolume = 
typename GridGeometry<id>::LocalView::SubControlVolume;
 
  265                  "Pore-network model must not be compositional");
 
  268    using ParentType::ParentType;
 
  274    template<
class CouplingContext>
 
  276                                        Dune::index_constant<ParentType::freeFlowMassIndex> domainJ,
 
  277                                        const FVElementGeometry<ParentType::poreNetworkIndex>& fvGeometry,
 
  278                                        const SubControlVolume<ParentType::poreNetworkIndex>& scv,
 
  279                                        const ElementVolumeVariables<ParentType::poreNetworkIndex>& insideVolVars,
 
  280                                        const CouplingContext& context)
 
  282        Scalar massFlux(0.0);
 
  283        const auto& pnmVolVars = insideVolVars[scv.indexInElement()];
 
  285        for (
const auto& c : context)
 
  288            const Scalar normalFFVelocity = c.velocity * c.scvf.unitOuterNormal();
 
  292            const Scalar normalPNMVelocity = -normalFFVelocity;
 
  293            const bool pnmIsUpstream = std::signbit(normalFFVelocity);
 
  294            const Scalar area = c.scvf.area() * c.volVars.extrusionFactor();
 
  296            auto flux = massFlux_(domainI, domainJ, c.scvf, scv, c.scv, pnmVolVars, c.volVars, normalPNMVelocity, pnmIsUpstream);
 
 
  311    template<
class CouplingContext>
 
  313                                        Dune::index_constant<ParentType::poreNetworkIndex> domainJ,
 
  314                                        const FVElementGeometry<ParentType::freeFlowMassIndex>& fvGeometry,
 
  315                                        const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
 
  316                                        const ElementVolumeVariables<ParentType::freeFlowMassIndex>& insideVolVars,
 
  317                                        const CouplingContext& context)
 
  320        const Scalar normalFFVelocity = context.velocity * scvf.unitOuterNormal();
 
  321        const bool ffIsUpstream = !std::signbit(normalFFVelocity);
 
  322        const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
 
  323        const auto& ffVolVars = insideVolVars[scvf.insideScvIdx()];
 
  326        return massFlux_(domainI, domainJ, scvf, insideScv, context.scv, ffVolVars, context.volVars, normalFFVelocity, ffIsUpstream);
 
 
  332    template<
class CouplingContext, 
bool isNI = enableEnergyBalance, 
typename std::enable_if_t<isNI, 
int> = 0>
 
  334                                          Dune::index_constant<ParentType::freeFlowMassIndex> domainJ,
 
  335                                          const FVElementGeometry<ParentType::poreNetworkIndex>& fvGeometry,
 
  336                                          const SubControlVolume<ParentType::poreNetworkIndex>& scv,
 
  337                                          const ElementVolumeVariables<ParentType::poreNetworkIndex>& insideVolVars,
 
  338                                          const CouplingContext& context)
 
  340        Scalar energyFlux(0.0);
 
  343        const auto& pnmVolVars = insideVolVars[scv.indexInElement()];
 
  345        for(
const auto& c : context)
 
  348            const Scalar normalFFVelocity = c.velocity * c.scvf.unitOuterNormal();
 
  349            const bool pnmIsUpstream = std::signbit(normalFFVelocity);
 
  350            const Scalar normalPNMVelocity = -normalFFVelocity;
 
  351            const Scalar area = c.scvf.area() * c.volVars.extrusionFactor();
 
  353            auto flux = energyFlux_(domainI, domainJ, c.scvf, scv, c.scv, pnmVolVars, c.volVars, normalPNMVelocity, pnmIsUpstream);
 
 
  369    template<
class CouplingContext, 
bool isNI = enableEnergyBalance, 
typename std::enable_if_t<isNI, 
int> = 0>
 
  371                                          Dune::index_constant<ParentType::poreNetworkIndex> domainJ,
 
  372                                          const FVElementGeometry<ParentType::freeFlowMassIndex>& fvGeometry,
 
  373                                          const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
 
  374                                          const ElementVolumeVariables<ParentType::freeFlowMassIndex>& insideVolVars,
 
  375                                          const CouplingContext& context)
 
  378        const Scalar normalFFVelocity = context.velocity * scvf.unitOuterNormal();
 
  379        const bool ffIsUpstream = !std::signbit(normalFFVelocity);
 
  380        const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
 
  382        const auto& ffVolVars = insideVolVars[scvf.insideScvIdx()];
 
  384        return energyFlux_(domainI, domainJ, scvf, insideScv, context.scv, ffVolVars, context.volVars, normalFFVelocity, ffIsUpstream);
 
 
  391    template<std::
size_t i, std::
size_t j>
 
  392    static Scalar massFlux_(Dune::index_constant<i> domainI,
 
  393                                   Dune::index_constant<j> domainJ,
 
  394                                   const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
 
  395                                   const SubControlVolume<i>& scvI,
 
  396                                   const SubControlVolume<j>& scvJ,
 
  397                                   const VolumeVariables<i>& insideVolVars,
 
  398                                   const VolumeVariables<j>& outsideVolVars,
 
  399                                   const Scalar velocity,
 
  400                                   const bool insideIsUpstream)
 
  404        const Scalar insideDensity = insideVolVars.density(couplingPhaseIdx(domainI));
 
  405        const Scalar outsideDensity = outsideVolVars.density(couplingPhaseIdx(domainJ));
 
  407        flux = ParentType::advectiveFlux(insideDensity, outsideDensity, velocity, insideIsUpstream);
 
  415    template<std::
size_t i, std::
size_t j, 
bool isNI = enableEnergyBalance, 
typename std::enable_if_t<isNI, 
int> = 0>
 
  416    static Scalar energyFlux_(Dune::index_constant<i> domainI,
 
  417                              Dune::index_constant<j> domainJ,
 
  418                              const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
 
  419                              const SubControlVolume<i>& scvI,
 
  420                              const SubControlVolume<j>& scvJ,
 
  421                              const VolumeVariables<i>& insideVolVars,
 
  422                              const VolumeVariables<j>& outsideVolVars,
 
  423                              const Scalar velocity,
 
  424                              const bool insideIsUpstream)
 
  429        const Scalar insideTerm = insideVolVars.density(couplingPhaseIdx(domainI)) * insideVolVars.enthalpy(couplingPhaseIdx(domainI));
 
  430        const Scalar outsideTerm = outsideVolVars.density(couplingPhaseIdx(domainJ)) * outsideVolVars.enthalpy(couplingPhaseIdx(domainJ));
 
  432        flux += ParentType::advectiveFlux(insideTerm, outsideTerm, velocity, insideIsUpstream);
 
  435        flux += ParentType::conductiveEnergyFlux(domainI, domainJ, scvf, scvI, scvJ, insideVolVars, outsideVolVars);
 
 
  445template<
class MDTraits, 
class CouplingManager, 
bool enableEnergyBalance>
 
  450    using Scalar = 
typename MDTraits::Scalar;
 
  453    template<std::
size_t id>
 
  454    using SubDomainTypeTag = 
typename MDTraits::template SubDomain<id>::TypeTag;
 
  457    template<std::
size_t id> 
using Element = 
typename GridGeometry<id>::GridView::template Codim<0>::Entity;
 
  458    template<std::
size_t id> 
using FVElementGeometry = 
typename GridGeometry<id>::LocalView;
 
  459    template<std::
size_t id> 
using SubControlVolumeFace = 
typename GridGeometry<id>::LocalView::SubControlVolumeFace;
 
  460    template<std::
size_t id> 
using SubControlVolume = 
typename GridGeometry<id>::LocalView::SubControlVolume;
 
  464    template<std::
size_t id> 
using FluidSystem = 
typename VolumeVariables<id>::FluidSystem;
 
  466    template<std::
size_t id> 
using NumEqVector = 
typename Problem<id>::Traits::NumEqVector;
 
  474                  "Models must have same number of components");
 
  477    using ParentType::ParentType;
 
  481    using NumCompVector = Dune::FieldVector<Scalar, numComponents>;
 
  486    template<
class CouplingContext>
 
  488                                               Dune::index_constant<ParentType::freeFlowMassIndex> domainJ,
 
  489                                               const FVElementGeometry<ParentType::poreNetworkIndex>& fvGeometry,
 
  490                                               const SubControlVolume<ParentType::poreNetworkIndex>& scv,
 
  491                                               const ElementVolumeVariables<ParentType::poreNetworkIndex>& insideVolVars,
 
  492                                               const CouplingContext& context)
 
  495        const auto& pnmVolVars = insideVolVars[scv.indexInElement()];
 
  497        for (
const auto& c : context)
 
  500            const Scalar normalFFVelocity = c.velocity * c.scvf.unitOuterNormal();
 
  501            const bool pnmIsUpstream = std::signbit(normalFFVelocity);
 
  502            const Scalar normalPNMVelocity = -normalFFVelocity;
 
  503            const Scalar area = c.scvf.area() * c.volVars.extrusionFactor();
 
  505            auto flux = massFlux_(domainI, domainJ, c.scvf, scv, c.scv, pnmVolVars, c.volVars, normalPNMVelocity, pnmIsUpstream);
 
 
  521    template<
class CouplingContext>
 
  523                                               Dune::index_constant<ParentType::poreNetworkIndex> domainJ,
 
  524                                               const FVElementGeometry<ParentType::freeFlowMassIndex>& fvGeometry,
 
  525                                               const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
 
  526                                               const ElementVolumeVariables<ParentType::freeFlowMassIndex>& insideVolVars,
 
  527                                               const CouplingContext& context)
 
  530        const Scalar normalFFVelocity = context.velocity * scvf.unitOuterNormal();
 
  531        const bool ffIsUpstream = !std::signbit(normalFFVelocity);
 
  532        const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
 
  533        const auto& ffVolVars = insideVolVars[scvf.insideScvIdx()];
 
  535        return massFlux_(domainI, domainJ, scvf, insideScv, context.scv, ffVolVars, context.volVars, normalFFVelocity, ffIsUpstream);
 
 
  541    template<
class CouplingContext, 
bool isNI = enableEnergyBalance, 
typename std::enable_if_t<isNI, 
int> = 0>
 
  543                                          Dune::index_constant<ParentType::freeFlowMassIndex> domainJ,
 
  544                                          const FVElementGeometry<ParentType::poreNetworkIndex>& fvGeometry,
 
  545                                          const SubControlVolume<ParentType::poreNetworkIndex>& scv,
 
  546                                          const ElementVolumeVariables<ParentType::poreNetworkIndex>& insideVolVars,
 
  547                                          const CouplingContext& context)
 
  549        Scalar energyFlux(0.0);
 
  552        const auto& pnmVolVars = insideVolVars[scv.indexInElement()];
 
  554        for(
const auto& c : context)
 
  557            const Scalar normalFFVelocity = c.velocity * c.scvf.unitOuterNormal();
 
  558            const bool pnmIsUpstream = std::signbit(normalFFVelocity);
 
  559            const Scalar normalPNMVelocity = -normalFFVelocity;
 
  560            const Scalar area = c.scvf.area() * c.volVars.extrusionFactor();
 
  562            auto flux = energyFlux_(domainI, domainJ, c.scvf, scv, c.scv, pnmVolVars, c.volVars, normalPNMVelocity, pnmIsUpstream);
 
 
  577    template<
class CouplingContext, 
bool isNI = enableEnergyBalance, 
typename std::enable_if_t<isNI, 
int> = 0>
 
  579                                          Dune::index_constant<ParentType::poreNetworkIndex> domainJ,
 
  580                                          const FVElementGeometry<ParentType::freeFlowMassIndex>& fvGeometry,
 
  581                                          const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
 
  582                                          const ElementVolumeVariables<ParentType::freeFlowMassIndex>& insideVolVars,
 
  583                                          const CouplingContext& context)
 
  586        const Scalar normalFFVelocity = context.velocity * scvf.unitOuterNormal();
 
  587        const bool ffIsUpstream = !std::signbit(normalFFVelocity);
 
  588        const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
 
  590        const auto& ffVolVars = insideVolVars[scvf.insideScvIdx()];
 
  592        return energyFlux_(domainI, domainJ, scvf, insideScv, context.scv, ffVolVars, context.volVars, normalFFVelocity, ffIsUpstream);
 
 
  599    template<std::
size_t i, std::
size_t j>
 
  600    static NumCompVector massFlux_(Dune::index_constant<i> domainI,
 
  601                                   Dune::index_constant<j> domainJ,
 
  602                                   const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
 
  603                                   const SubControlVolume<i>& scvI,
 
  604                                   const SubControlVolume<j>& scvJ,
 
  605                                   const VolumeVariables<i>& insideVolVars,
 
  606                                   const VolumeVariables<j>& outsideVolVars,
 
  607                                   const Scalar velocity,
 
  608                                   const bool insideIsUpstream)
 
  610        NumCompVector flux(0.0);
 
  612        auto moleOrMassFraction = [&](
const auto& volVars, 
int phaseIdx, 
int compIdx)
 
  613        { 
return useMoles ? volVars.moleFraction(phaseIdx, compIdx) : volVars.massFraction(phaseIdx, compIdx); };
 
  615        auto moleOrMassDensity = [&](
const auto& volVars, 
int phaseIdx)
 
  616        { 
return useMoles ? volVars.molarDensity(phaseIdx) : volVars.density(phaseIdx); };
 
  619        auto insideTerm = [&](
int compIdx)
 
  620        { 
return moleOrMassFraction(insideVolVars, couplingPhaseIdx(domainI), compIdx) * moleOrMassDensity(insideVolVars, couplingPhaseIdx(domainI)); };
 
  622        auto outsideTerm = [&](
int compIdx)
 
  623        { 
return moleOrMassFraction(outsideVolVars, couplingPhaseIdx(domainJ), compIdx) * moleOrMassDensity(outsideVolVars, couplingPhaseIdx(domainJ)); };
 
  626        for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
 
  628            const int domainICompIdx = couplingCompIdx(domainI, compIdx);
 
  629            const int domainJCompIdx = couplingCompIdx(domainJ, compIdx);
 
  631            assert(FluidSystem<i>::componentName(domainICompIdx) == FluidSystem<j>::componentName(domainJCompIdx));
 
  633            flux[domainICompIdx] += ParentType::advectiveFlux(insideTerm(domainICompIdx), outsideTerm(domainJCompIdx), velocity, insideIsUpstream);
 
  637        NumCompVector diffusiveFlux = diffusiveMolecularFlux_(domainI, domainJ, scvf, scvI, scvJ, insideVolVars, outsideVolVars);
 
  642            for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
 
  644                const int domainICompIdx = couplingCompIdx(domainI, compIdx);
 
  645                diffusiveFlux[domainICompIdx] /= FluidSystem<i>::molarMass(domainICompIdx);
 
  650            for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
 
  652                const int domainICompIdx = couplingCompIdx(domainI, compIdx);
 
  653                diffusiveFlux[domainICompIdx] *= FluidSystem<i>::molarMass(domainICompIdx);
 
  658        flux += diffusiveFlux;
 
  661        if (replaceCompEqIdx < numComponents)
 
  662            flux[replaceCompEqIdx] = std::accumulate(flux.begin(), flux.end(), 0.0);
 
  670    template<std::
size_t i, std::
size_t j, 
bool isNI = enableEnergyBalance, 
typename std::enable_if_t<isNI, 
int> = 0>
 
  671    static Scalar energyFlux_(Dune::index_constant<i> domainI,
 
  672                              Dune::index_constant<j> domainJ,
 
  673                              const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
 
  674                              const SubControlVolume<i>& scvI,
 
  675                              const SubControlVolume<j>& scvJ,
 
  676                              const VolumeVariables<i>& insideVolVars,
 
  677                              const VolumeVariables<j>& outsideVolVars,
 
  678                              const Scalar velocity,
 
  679                              const bool insideIsUpstream)
 
  684        const Scalar insideTerm = insideVolVars.density(couplingPhaseIdx(domainI)) * insideVolVars.enthalpy(couplingPhaseIdx(domainI));
 
  685        const Scalar outsideTerm = outsideVolVars.density(couplingPhaseIdx(domainJ)) * outsideVolVars.enthalpy(couplingPhaseIdx(domainJ));
 
  687        flux += ParentType::advectiveFlux(insideTerm, outsideTerm, velocity, insideIsUpstream);
 
  690        flux += ParentType::conductiveEnergyFlux(domainI, domainJ, scvf, scvI, scvJ, insideVolVars, outsideVolVars);
 
  700    template<std::
size_t i, std::
size_t j>
 
  701    static NumCompVector diffusiveMolecularFlux_(Dune::index_constant<i> domainI,
 
  702                                                 Dune::index_constant<j> domainJ,
 
  703                                                 const SubControlVolumeFace<ParentType::freeFlowMassIndex>& scvf,
 
  704                                                 const SubControlVolume<i>& scvI,
 
  705                                                 const SubControlVolume<j>& scvJ,
 
  706                                                 const VolumeVariables<i>& volVarsI,
 
  707                                                 const VolumeVariables<j>& volVarsJ)
 
  709        NumCompVector diffusiveFlux(0.0);
 
  710        const Scalar avgDensity = 0.5*(
massOrMolarDensity(volVarsI, referenceSystemFormulation, couplingPhaseIdx(domainI))
 
  711                                     + 
massOrMolarDensity(volVarsJ, referenceSystemFormulation, couplingPhaseIdx(domainJ)));
 
  713        const auto& freeFlowVolVars = std::get<const VolumeVariables<ParentType::freeFlowMassIndex>&>(std::forward_as_tuple(volVarsI, volVarsJ));
 
  714        const auto& ffScv = std::get<const SubControlVolume<ParentType::freeFlowMassIndex>&>(std::forward_as_tuple(scvI, scvJ));
 
  715        const Scalar 
distance = ParentType::getDistance_(ffScv, scvf);
 
  717        for (
int compIdx = 1; compIdx < numComponents; ++compIdx)
 
  719            const int freeFlowMainCompIdx = couplingPhaseIdx(ParentType::freeFlowMassIndex);
 
  720            const int domainICompIdx = couplingCompIdx(domainI, compIdx);
 
  721            const int domainJCompIdx = couplingCompIdx(domainJ, compIdx);
 
  723            assert(FluidSystem<i>::componentName(domainICompIdx) == FluidSystem<j>::componentName(domainJCompIdx));
 
  725            const Scalar massOrMoleFractionI = 
massOrMoleFraction(volVarsI, referenceSystemFormulation, couplingPhaseIdx(domainI), domainICompIdx);
 
  726            const Scalar massOrMoleFractionJ = 
massOrMoleFraction(volVarsJ, referenceSystemFormulation, couplingPhaseIdx(domainJ), domainJCompIdx);
 
  727            const Scalar deltaMassOrMoleFrac = massOrMoleFractionJ - massOrMoleFractionI;
 
  729            const Scalar tij = freeFlowVolVars.effectiveDiffusionCoefficient(couplingPhaseIdx(ParentType::freeFlowMassIndex),
 
  731                                                                             couplingCompIdx(ParentType::freeFlowMassIndex, compIdx))
 
  733            diffusiveFlux[domainICompIdx] += -avgDensity * tij * deltaMassOrMoleFrac;
 
  736        const Scalar cumulativeFlux = std::accumulate(diffusiveFlux.begin(), diffusiveFlux.end(), 0.0);
 
  737        diffusiveFlux[couplingCompIdx(domainI, 0)] = -cumulativeFlux;
 
  739        return diffusiveFlux;
 
  742    static Scalar getComponentEnthalpy_(
const VolumeVariables<ParentType::freeFlowMassIndex>& volVars, 
int phaseIdx, 
int compIdx)
 
  744        return FluidSystem<ParentType::freeFlowMassIndex>::componentEnthalpy(volVars.fluidState(), 0, compIdx);
 
  747    static Scalar getComponentEnthalpy_(
const VolumeVariables<ParentType::poreNetworkIndex>& volVars, 
int phaseIdx, 
int compIdx)
 
  749        return FluidSystem<ParentType::poreNetworkIndex>::componentEnthalpy(volVars.fluidState(), phaseIdx, compIdx);