12#ifndef DUMUX_STAGGERED_NAVIERSTOKES_LOCAL_RESIDUAL_HH 
   13#define DUMUX_STAGGERED_NAVIERSTOKES_LOCAL_RESIDUAL_HH 
   17#include <dune/common/hybridutilities.hh> 
   29static constexpr bool isRotationalExtrusion = 
false;
 
   31template<
int radialAxis>
 
   41template<
class TypeTag, 
class DiscretizationMethod>
 
   44template<
class TypeTag>
 
   53    using GridVolumeVariables = 
typename GridVariables::GridVolumeVariables;
 
   54    using ElementVolumeVariables = 
typename GridVolumeVariables::LocalView;
 
   55    using VolumeVariables = 
typename GridVolumeVariables::VolumeVariables;
 
   57    using GridFluxVariablesCache = 
typename GridVariables::GridFluxVariablesCache;
 
   58    using ElementFluxVariablesCache = 
typename GridFluxVariablesCache::LocalView;
 
   60    using GridFaceVariables = 
typename GridVariables::GridFaceVariables;
 
   61    using ElementFaceVariables = 
typename GridFaceVariables::LocalView;
 
   67    using FVElementGeometry = 
typename GridGeometry::LocalView;
 
   68    using GridView = 
typename GridGeometry::GridView;
 
   69    using Element = 
typename GridView::template Codim<0>::Entity;
 
   70    using SubControlVolume = 
typename FVElementGeometry::SubControlVolume;
 
   71    using SubControlVolumeFace = 
typename FVElementGeometry::SubControlVolumeFace;
 
   81    using CellCenterResidual = CellCenterPrimaryVariables;
 
   82    using FaceResidual = FacePrimaryVariables;
 
   90    static constexpr auto cellCenterOffset = ModelTraits::numEq() - CellCenterPrimaryVariables::dimension;
 
   91    static_assert(
cellCenterOffset == ModelTraits::dim(), 
"cellCenterOffset must equal dim for staggered NavierStokes");
 
   94    using ParentType::ParentType;
 
   98                                                        const Element &element,
 
   99                                                        const FVElementGeometry& fvGeometry,
 
  100                                                        const ElementVolumeVariables& elemVolVars,
 
  101                                                        const ElementFaceVariables& elemFaceVars,
 
  102                                                        const SubControlVolumeFace &scvf,
 
  103                                                        const ElementFluxVariablesCache& elemFluxVarsCache)
 const 
  105        FluxVariables fluxVars;
 
  106        CellCenterPrimaryVariables flux = fluxVars.computeMassFlux(
problem, element, fvGeometry, elemVolVars,
 
  107                                                                   elemFaceVars, scvf, elemFluxVarsCache[scvf]);
 
  109        EnergyLocalResidual::heatFlux(flux, 
problem, element, fvGeometry, elemVolVars, elemFaceVars, scvf);
 
 
  116                                                          const Element &element,
 
  117                                                          const FVElementGeometry& fvGeometry,
 
  118                                                          const ElementVolumeVariables& elemVolVars,
 
  119                                                          const ElementFaceVariables& elemFaceVars,
 
  120                                                          const SubControlVolume &scv)
 const 
  122        CellCenterPrimaryVariables result(0.0);
 
  125        const auto sourceValues = 
problem.source(element, fvGeometry, elemVolVars, elemFaceVars, scv);
 
  128        for (
int i = 0; i < result.size(); ++i)
 
 
  137                                                           const SubControlVolume& scv,
 
  138                                                           const VolumeVariables& volVars)
 const 
  140        CellCenterPrimaryVariables storage;
 
  141        storage[Indices::conti0EqIdx - ModelTraits::dim()] = volVars.density();
 
  143        EnergyLocalResidual::fluidPhaseStorage(storage, volVars);
 
 
  150                                               const SubControlVolumeFace& scvf,
 
  151                                               const VolumeVariables& volVars,
 
  152                                               const ElementFaceVariables& elemFaceVars)
 const 
  154        FacePrimaryVariables storage(0.0);
 
  155        const Scalar velocity = elemFaceVars[scvf].velocitySelf();
 
  156        storage[0] = volVars.density() * velocity;
 
 
  162                                              const Element& element,
 
  163                                              const FVElementGeometry& fvGeometry,
 
  164                                              const SubControlVolumeFace& scvf,
 
  165                                              const ElementVolumeVariables& elemVolVars,
 
  166                                              const ElementFaceVariables& elemFaceVars)
 const 
  168        FacePrimaryVariables source(0.0);
 
  169        const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
 
  170        source += 
problem.gravity()[scvf.directionIndex()] * insideVolVars.density();
 
  171        source += 
problem.source(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[Indices::velocity(scvf.directionIndex())];
 
  176        if constexpr (ModelTraits::dim() == 2 && Impl::isRotationalExtrusion<Extrusion>)
 
  178            if (scvf.directionIndex() == Extrusion::radialAxis)
 
  181                const auto r = scvf.center()[scvf.directionIndex()];
 
  182                source -= -2.0*insideVolVars.effectiveViscosity() * elemFaceVars[scvf].velocitySelf() / (r*r);
 
  187                const Scalar pressure =
 
  188                    normalizePressure ? insideVolVars.pressure() - 
problem.initial(scvf)[Indices::pressureIdx]
 
  189                                      : insideVolVars.pressure();
 
  191                source += pressure/r;
 
 
  200                                            const Element& element,
 
  201                                            const SubControlVolumeFace& scvf,
 
  202                                            const FVElementGeometry& fvGeometry,
 
  203                                            const ElementVolumeVariables& elemVolVars,
 
  204                                            const ElementFaceVariables& elemFaceVars,
 
  205                                            const ElementFluxVariablesCache& elemFluxVarsCache)
 const 
  207        FluxVariables fluxVars;
 
  208        return fluxVars.computeMomentumFlux(
problem, element, scvf, fvGeometry, elemVolVars, elemFaceVars, elemFluxVarsCache.gridFluxVarsCache());
 
 
  215                                                        const Element& element,
 
  216                                                        const FVElementGeometry& fvGeometry,
 
  217                                                        const SubControlVolumeFace& scvf,
 
  218                                                        const ElementVolumeVariables& elemVolVars,
 
  219                                                        const ElementFaceVariables& elemFaceVars,
 
  220                                                        const ElementBoundaryTypes& elemBcTypes,
 
  221                                                        const ElementFluxVariablesCache& elemFluxVarsCache)
 const 
  223        CellCenterResidual result(0.0);
 
  227            const auto bcTypes = 
problem.boundaryTypes(element, scvf);
 
  230            if (bcTypes.isSymmetry())
 
  237            static constexpr auto numEqCellCenter = CellCenterResidual::dimension;
 
  238            if (bcTypes.hasNeumann())
 
  240                const auto extrusionFactor = elemVolVars[scvf.insideScvIdx()].extrusionFactor();
 
  241                const auto neumannFluxes = 
problem.neumann(element, fvGeometry, elemVolVars, elemFaceVars, scvf);
 
  243                for (
int eqIdx = 0; eqIdx < numEqCellCenter; ++eqIdx)
 
  246                        result[eqIdx] = neumannFluxes[eqIdx + 
cellCenterOffset] * extrusionFactor * Extrusion::area(fvGeometry, scvf);
 
  251            incorporateWallFunction_(result, 
problem, element, fvGeometry, scvf, elemVolVars, elemFaceVars);
 
 
  261                                        const Element& element,
 
  262                                        const FVElementGeometry& fvGeometry,
 
  263                                        const SubControlVolumeFace& scvf,
 
  264                                        const ElementVolumeVariables& elemVolVars,
 
  265                                        const ElementFaceVariables& elemFaceVars,
 
  266                                        const ElementBoundaryTypes& elemBcTypes,
 
  267                                        const ElementFluxVariablesCache& elemFluxVarsCache)
 const 
  272            const auto bcTypes = 
problem.boundaryTypes(element, scvf);
 
  274            if(bcTypes.isDirichlet(Indices::velocity(scvf.directionIndex())))
 
  277                const Scalar velocity = elemFaceVars[scvf].velocitySelf();
 
  278                const Scalar dirichletValue = 
problem.dirichlet(element, scvf)[Indices::velocity(scvf.directionIndex())];
 
  279                residual = velocity - dirichletValue;
 
  281            else if(bcTypes.isSymmetry())
 
  285                const Scalar velocity = elemFaceVars[scvf].velocitySelf();
 
  286                const Scalar fixedValue = 0.0;
 
  287                residual = velocity - fixedValue;
 
 
  296                                            const Element& element,
 
  297                                            const FVElementGeometry& fvGeometry,
 
  298                                            const SubControlVolumeFace& scvf,
 
  299                                            const ElementVolumeVariables& elemVolVars,
 
  300                                            const ElementFaceVariables& elemFaceVars,
 
  301                                            const ElementBoundaryTypes& elemBcTypes,
 
  302                                            const ElementFluxVariablesCache& elemFluxVarsCache)
 const 
  304        FaceResidual result(0.0);
 
  308            FluxVariables fluxVars;
 
  311            const auto bcTypes = 
problem.boundaryTypes(element, scvf);
 
  312            if (bcTypes.isNeumann(Indices::velocity(scvf.directionIndex())))
 
  316                const auto extrusionFactor = elemVolVars[scvf.insideScvIdx()].extrusionFactor();
 
  317                result = 
problem.neumann(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[Indices::velocity(scvf.directionIndex())]
 
  318                                         * extrusionFactor * Extrusion::area(fvGeometry, scvf);
 
  321                result += fluxVars.computeMomentumFlux(
problem, element, scvf, fvGeometry, elemVolVars, elemFaceVars, elemFluxVarsCache.gridFluxVarsCache());
 
  323            else if(bcTypes.isDirichlet(Indices::pressureIdx))
 
  327                result = fluxVars.computeMomentumFlux(
problem, element, scvf, fvGeometry, elemVolVars, elemFaceVars, elemFluxVarsCache.gridFluxVarsCache());
 
  330                result += fluxVars.inflowOutflowBoundaryFlux(
problem, scvf, fvGeometry, elemVolVars, elemFaceVars);
 
 
  339    template<
class ...Args, 
bool turbulenceModel = ModelTraits::usesTurbulenceModel(), std::enable_if_t<!turbulenceModel, int> = 0>
 
  340    void incorporateWallFunction_(Args&&... args)
 const 
  344    template<
bool turbulenceModel = ModelTraits::usesTurbulenceModel(), std::enable_if_t<turbulenceModel, 
int> = 0>
 
  345    void incorporateWallFunction_(CellCenterResidual& boundaryFlux,
 
  346                                  const Problem& problem,
 
  347                                  const Element& element,
 
  348                                  const FVElementGeometry& fvGeometry,
 
  349                                  const SubControlVolumeFace& scvf,
 
  350                                  const ElementVolumeVariables& elemVolVars,
 
  351                                  const ElementFaceVariables& elemFaceVars)
 const 
  353        static constexpr auto numEqCellCenter = CellCenterResidual::dimension;
 
  354        const auto extrusionFactor = elemVolVars[scvf.insideScvIdx()].extrusionFactor();
 
  357        for(
int eqIdx = 0; eqIdx < numEqCellCenter; ++eqIdx)
 
  360            if(problem.useWallFunction(element, scvf, eqIdx + cellCenterOffset))
 
  362                boundaryFlux[eqIdx] = problem.wallFunction(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[eqIdx]
 
  363                                                           * extrusionFactor * Extrusion::area(fvGeometry, scvf);
 
 
FacePrimaryVariables computeFluxForFace(const Problem &problem, const Element &element, const SubControlVolumeFace &scvf, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluate the momentum flux for the face control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:199
void evalDirichletBoundariesForFace(FaceResidual &residual, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const ElementBoundaryTypes &elemBcTypes, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluate Dirichlet (fixed value) boundary conditions for a face dof.
Definition freeflow/navierstokes/staggered/localresidual.hh:259
FacePrimaryVariables computeStorageForFace(const Problem &problem, const SubControlVolumeFace &scvf, const VolumeVariables &volVars, const ElementFaceVariables &elemFaceVars) const
Evaluate the storage term for the face control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:149
FacePrimaryVariables computeSourceForFace(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars) const
Evaluate the source term for the face control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:161
FreeFlowEnergyLocalResidual< GridGeometry, FluxVariables, ModelTraits::enableEnergyBalance(),(ModelTraits::numFluidComponents() > 1)> EnergyLocalResidual
Definition freeflow/navierstokes/staggered/localresidual.hh:87
FaceResidual computeBoundaryFluxForFace(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const ElementBoundaryTypes &elemBcTypes, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluate boundary fluxes for a face dof.
Definition freeflow/navierstokes/staggered/localresidual.hh:295
CellCenterResidual computeBoundaryFluxForCellCenter(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const SubControlVolumeFace &scvf, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const ElementBoundaryTypes &elemBcTypes, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluate boundary conditions for a cell center dof.
Definition freeflow/navierstokes/staggered/localresidual.hh:214
CellCenterPrimaryVariables computeFluxForCellCenter(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const SubControlVolumeFace &scvf, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluate fluxes entering or leaving the cell center control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:97
CellCenterPrimaryVariables computeStorageForCellCenter(const Problem &problem, const SubControlVolume &scv, const VolumeVariables &volVars) const
Evaluate the storage term for the cell center control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:136
CellCenterPrimaryVariables computeSourceForCellCenter(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const SubControlVolume &scv) const
Evaluate the source term for the cell center control volume.
Definition freeflow/navierstokes/staggered/localresidual.hh:115
static constexpr auto cellCenterOffset
Definition freeflow/navierstokes/staggered/localresidual.hh:90
Element-wise calculation of the Navier-Stokes residual for models using the staggered discretization.
Definition freeflow/navierstokes/localresidual.hh:23
const Problem & problem() const
the problem
Definition staggeredlocalresidual.hh:294
StaggeredLocalResidual(const Problem *problem, const TimeLoop *timeLoop=nullptr)
the constructor
Definition staggeredlocalresidual.hh:59
Defines all properties used in Dumux.
Helper classes to compute the integration elements.
Element-wise calculation of the local residual for non-isothermal free-flow models.
FreeFlowEnergyLocalResidualImplementation< GridGeometry, FluxVariables, typename GridGeometry::DiscretizationMethod, enableEneryBalance, isCompositional > FreeFlowEnergyLocalResidual
Element-wise calculation of the local residual for non-isothermal free-flow models.
Definition freeflow/nonisothermal/localresidual.hh:32
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:310
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
The available discretization methods in Dumux.
constexpr bool isRotationalExtrusion
Convenience trait to check whether the extrusion is rotational.
Definition extrusion.hh:172
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:166
Calculates the element-wise residual for the staggered FV scheme.