78                            const typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity& element,
 
   79                            const FVElementGeometry& fvGeometry,
 
   80                            const ElementVolumeVariables& elemVolVars,
 
   81                            const typename FVElementGeometry::SubControlVolumeFace& scvf)
 
   83        using Scalar = 
typename NumEqVector::value_type;
 
   84        using FluidSystem = 
typename ElementVolumeVariables::VolumeVariables::FluidSystem;
 
   89        const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
 
   90        const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
 
   92        const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
 
   93        const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx());
 
   95        const auto gradVelocity = [&]()
 
   98            const auto velocityXLeft   = insideVolVars.velocity(0);
 
   99            const auto velocityYLeft   = insideVolVars.velocity(1);
 
  100            const auto velocityXRight  = outsideVolVars.velocity(0);
 
  101            const auto velocityYRight  = outsideVolVars.velocity(1);
 
  105            const auto& cellCenterToCellCenter = outsideScv.center() - insideScv.center();
 
  106            const auto distance = cellCenterToCellCenter.two_norm();
 
  107            const auto& 
unitNormal = scvf.unitOuterNormal();
 
  109            return std::array<Scalar, 2>{
 
  110                (velocityXRight-velocityXLeft)*direction/
distance,
 
  111                (velocityYRight-velocityYLeft)*direction/
distance 
  116        const auto waterDepthLeft  = insideVolVars.waterDepth();
 
  117        const auto waterDepthRight = outsideVolVars.waterDepth();
 
  118        const auto averageDepth = 2.0*(waterDepthLeft*waterDepthRight)/(waterDepthLeft + waterDepthRight);
 
  120        const Scalar effectiveKinematicViscosity = [&]()
 
  126                problem.paramGroup(), 
"ShallowWater.TurbulentViscosity", insideVolVars.viscosity()/insideVolVars.density()
 
  131                problem.paramGroup(), 
"ShallowWater.UseMixingLengthTurbulenceModel", 
false 
  135            if (!useMixingLengthTurbulenceModel)
 
  136                return backgroundKinematicViscosity;
 
  138            using SpatialParams = 
typename Problem::SpatialParams;
 
  139            using E = 
typename FVElementGeometry::GridGeometry::GridView::template Codim<0>::Entity;
 
  140            using SCV = 
typename FVElementGeometry::SubControlVolume;
 
  141            if constexpr (!Detail::implementsFrictionLaw<SpatialParams, E, SCV>())
 
  142                DUNE_THROW(Dune::IOError, 
"Mixing length turbulence model enabled but spatial parameters do not implement the frictionLaw interface!");
 
  148                static const auto turbConstV = 
getParamFromGroup<Scalar>(problem.paramGroup(), 
"ShallowWater.VerticalCoefficientOfMixingLengthModel", 1.0);
 
  149                static const auto turbConstH = 
getParamFromGroup<Scalar>(problem.paramGroup(), 
"ShallowWater.HorizontalCoefficientOfMixingLengthModel", 0.1);
 
  157                constexpr Scalar kappa = 0.41;
 
  159                const Scalar ustar = [&]()
 
  163                    const auto& bottomShearStressInside = problem.spatialParams().frictionLaw(element, insideScv).bottomShearStress(insideVolVars);
 
  164                    const auto& bottomShearStressOutside = problem.spatialParams().frictionLaw(element, outsideScv).bottomShearStress(outsideVolVars);
 
  165                    const auto bottomShearStressInsideMag = bottomShearStressInside.two_norm();
 
  166                    const auto bottomShearStressOutsideMag = bottomShearStressOutside.two_norm();
 
  170                    const auto averageBottomShearStress = 2.0*(bottomShearStressInsideMag*bottomShearStressOutsideMag)
 
  171                            / max(1.0e-8,bottomShearStressInsideMag + bottomShearStressOutsideMag);
 
  175                    static_assert(!FluidSystem::isCompressible(0),
 
  176                        "The shallow water model assumes incompressible fluids" 
  180                    return sqrt(averageBottomShearStress/insideVolVars.density());
 
  183                const auto turbViscosityV = turbConstV * (kappa/6.0) * ustar * averageDepth;
 
  210                const auto [gradU, gradV] = gradVelocity;
 
  211                const auto mixingLengthSquared = turbConstH * turbConstH * averageDepth * averageDepth;
 
  212                const auto turbViscosityH = mixingLengthSquared * sqrt(2.0*gradU*gradU + 2.0*gradV*gradV);
 
  215                return backgroundKinematicViscosity + sqrt(turbViscosityV*turbViscosityV + turbViscosityH*turbViscosityH);
 
  222        const auto freeSurfaceInside = insideVolVars.waterDepth() + insideVolVars.bedSurface();
 
  223        const auto freeSurfaceOutside = outsideVolVars.waterDepth() + outsideVolVars.bedSurface();
 
  224        const auto interfaceWaterDepth = max(min(freeSurfaceInside , freeSurfaceOutside) - max(insideVolVars.bedSurface(),outsideVolVars.bedSurface()),0.0);
 
  225        const auto& [gradU, gradV] = gradVelocity;
 
  226        const auto uViscousFlux = effectiveKinematicViscosity * interfaceWaterDepth * gradU;
 
  227        const auto vViscousFlux = effectiveKinematicViscosity * interfaceWaterDepth * gradV;
 
  230        localFlux[1] = -uViscousFlux * scvf.area();
 
  231        localFlux[2] = -vViscousFlux * scvf.area();