12#ifndef DUMUX_KEPSILON_PROBLEM_HH 
   13#define DUMUX_KEPSILON_PROBLEM_HH 
   35template<
class TypeTag>
 
   43    using GridView = 
typename GridGeometry::GridView;
 
   44    using Element = 
typename GridView::template Codim<0>::Entity;
 
   47    using GridFaceVariables = 
typename GridVariables::GridFaceVariables;
 
   48    using ElementFaceVariables = 
typename GridFaceVariables::LocalView;
 
   49    using GridVolumeVariables = 
typename GridVariables::GridVolumeVariables;
 
   50    using ElementVolumeVariables = 
typename GridVolumeVariables::LocalView;
 
   53    using SubControlVolumeFace = 
typename FVElementGeometry::SubControlVolumeFace;
 
   54    using GlobalPosition = 
typename SubControlVolumeFace::GlobalPosition;
 
   62    using Indices = 
typename ModelTraits::Indices;
 
   64    static constexpr bool enableEnergyBalance = ModelTraits::enableEnergyBalance();
 
   65    static constexpr bool isCompositional = ModelTraits::numFluidComponents() > 1;
 
   68    static constexpr auto cellCenterOffset = ModelTraits::numEq() - CellCenterPrimaryVariables::dimension;
 
   69    static_assert(cellCenterOffset == ModelTraits::dim(), 
"cellCenterOffset must equal dim for staggered NavierStokes");
 
   85            DUNE_THROW(Dune::NotImplemented, 
"\n Due to grid/geometric concerns, k-epsilon models should only be used for " 
   86                                          << 
" wall bounded flows with flat channel geometries. " 
   87                                          << 
"\n If your geometry is a flat channel, please set the runtime parameter RANS.IsFlatWallBounded to true. \n");
 
   92        matchingPointIdx_.resize(this->
gridGeometry().elementMapper().size(), 0);
 
   93        storedDissipation_.resize(this->
gridGeometry().elementMapper().size(), 0.0);
 
   94        storedTurbulentKineticEnergy_.resize(this->
gridGeometry().elementMapper().size(), 0.0);
 
   95        storedDynamicEddyViscosity_.resize(this->
gridGeometry().elementMapper().size(), 0.0);
 
   96        zeroEqDynamicEddyViscosity_.resize(this->
gridGeometry().elementMapper().size(), 0.0);
 
 
  104    template<
class SolutionVector>
 
  111        for (
const auto& element : elements(this->
gridGeometry().gridView()))
 
  113            unsigned int elementIdx = this->
gridGeometry().elementMapper().index(element);
 
  114            fvGeometry.bindElement(element);
 
  115            for (
auto&& scv : scvs(fvGeometry))
 
  117                const int dofIdx = scv.dofIndex();
 
  118                const auto& cellCenterPriVars = curSol[GridGeometry::cellCenterIdx()][dofIdx];
 
  122                storedDissipation_[elementIdx] = elemSol[0][Indices::dissipationEqIdx];
 
  123                storedTurbulentKineticEnergy_[elementIdx] = elemSol[0][Indices::turbulentKineticEnergyEqIdx];
 
  125                VolumeVariables volVars;
 
  126                volVars.update(elemSol, asImp_(), element, scv);
 
  127                storedDynamicEddyViscosity_[elementIdx] = volVars.calculateEddyViscosity();
 
  132        unsigned int numElementsInNearWallRegion = 0;
 
  133        for (
const auto& element : elements(this->
gridGeometry().gridView()))
 
  135            unsigned int elementIdx = this->
gridGeometry().elementMapper().index(element);
 
  136            unsigned int wallNormalAxis = asImp_().wallNormalAxis(elementIdx);
 
  137            unsigned int neighborIndex0 = asImp_().neighborIndex(elementIdx, 
wallNormalAxis, 0);
 
  138            unsigned int neighborIndex1 = asImp_().neighborIndex(elementIdx, 
wallNormalAxis, 1);
 
  140                                          ? numElementsInNearWallRegion + 1
 
  141                                          : numElementsInNearWallRegion + 0;
 
  146                matchingPointIdx_[asImp_().wallElementIndex(elementIdx)] = elementIdx;
 
  149        std::cout << 
"numElementsInNearWallRegion: " << numElementsInNearWallRegion << std::endl;
 
  152        for (
const auto& element : elements(this->
gridGeometry().gridView()))
 
  154            unsigned int elementIdx = this->
gridGeometry().elementMapper().index(element);
 
  159        static const auto enableZeroEqScaling
 
  161        if (enableZeroEqScaling)
 
  163            for (
const auto& element : elements(this->
gridGeometry().gridView()))
 
  165                unsigned int elementIdx = this->
gridGeometry().elementMapper().index(element);
 
  169                                       / zeroEqDynamicEddyViscosity_[matchingPointIndex];
 
  171                    && !std::isnan(scalingFactor) && !std::isinf(scalingFactor))
 
  173                    zeroEqDynamicEddyViscosity_[elementIdx] *= scalingFactor;
 
  176            for (
const auto& element : elements(this->
gridGeometry().gridView()))
 
  178                unsigned int elementIdx = this->
gridGeometry().elementMapper().index(element);
 
 
  193        unsigned int wallElementIdx = asImp_().wallElementIndex(elementIdx);
 
 
  208    const Scalar 
yPlus(
unsigned int elementIdx)
 const 
  210        return asImp_().wallDistance(elementIdx) * 
uStar(elementIdx)
 
  211             / asImp_().kinematicViscosity(elementIdx);
 
 
  218        return asImp_().wallDistance(elementIdx) * 
uStarNominal(elementIdx)
 
  219             / asImp_().kinematicViscosity(elementIdx);
 
 
  232        Scalar yPlusValue = 
yPlus(elementIdx);
 
  233        Scalar mixingLength = 0.0;
 
  234        if (yPlusValue > 0.0)
 
  236            mixingLength = asImp_().karmanConstant() * asImp_().wallDistance(elementIdx)
 
  237                           * (1.0 - exp(-yPlusValue / 26.0 ))
 
  238                           / sqrt(1.0 - exp(-0.26 * yPlusValue));
 
  241        unsigned int wallNormalAxis = asImp_().wallNormalAxis(elementIdx);
 
  244        return mixingLength * mixingLength * abs(
velocityGradient) * asImp_().storedDensity(elementIdx);
 
 
  248    const Scalar 
uStar(
unsigned int elementIdx)
 const 
  252        unsigned int wallElementIdx = asImp_().wallElementIndex(elementIdx);
 
  253        unsigned int wallNormalAxis = asImp_().wallNormalAxis(elementIdx);
 
 
  274               / asImp_().karmanConstant() / asImp_().wallDistance(elementIdx);
 
 
  290        Scalar velocityNominal = 
uStarNominal(elementIdx) * (1.0 / asImp_().karmanConstant() * log(
yPlusNominal(elementIdx)) + 5.0);
 
 
  296                         const SubControlVolumeFace& localSubFace,
 
  297                         const int& eqIdx)
 const 
  299        unsigned int elementIdx = asImp_().gridGeometry().elementMapper().index(element);
 
  300        auto bcTypes = asImp_().boundaryTypes(element, localSubFace);
 
  302        return bcTypes.hasWall()
 
  303            && bcTypes.isDirichlet(eqIdx)
 
 
  309                                      const FVElementGeometry& fvGeometry,
 
  310                                      const ElementVolumeVariables& elemVolVars,
 
  311                                      const ElementFaceVariables& elemFaceVars,
 
  312                                      const SubControlVolumeFace& scvf,
 
  313                                      const SubControlVolumeFace& localSubFace)
 const 
  315        unsigned int elementIdx = asImp_().gridGeometry().elementMapper().index(element);
 
 
  321    template<
bool eB = enableEnergyBalance, 
bool compositional = isCompositional,
 
  322             typename std::enable_if_t<eB && compositional, int> = 0>
 
  324                                            const FVElementGeometry& fvGeometry,
 
  325                                            const ElementVolumeVariables& elemVolVars,
 
  326                                            const ElementFaceVariables& elemFaceVars,
 
  327                                            const SubControlVolumeFace& scvf)
 const 
 
  334    template<
bool eB = enableEnergyBalance, 
bool compositional = isCompositional,
 
  335             typename std::enable_if_t<!eB && compositional, int> = 0>
 
  337                                            const FVElementGeometry& fvGeometry,
 
  338                                            const ElementVolumeVariables& elemVolVars,
 
  339                                            const ElementFaceVariables& elemFaceVars,
 
  340                                            const SubControlVolumeFace& scvf)
 const 
 
  344    template<
bool eB = enableEnergyBalance, 
bool compositional = isCompositional,
 
  345             typename std::enable_if_t<eB && !compositional, int> = 0>
 
  347                                            const FVElementGeometry& fvGeometry,
 
  348                                            const ElementVolumeVariables& elemVolVars,
 
  349                                            const ElementFaceVariables& elemFaceVars,
 
  350                                            const SubControlVolumeFace& scvf)
 const 
 
  354    template<
bool eB = enableEnergyBalance, 
bool compositional = isCompositional,
 
  355             typename std::enable_if_t<!eB && !compositional, int> = 0>
 
  357                                            const FVElementGeometry& fvGeometry,
 
  358                                            const ElementVolumeVariables& elemVolVars,
 
  359                                            const ElementFaceVariables& elemFaceVars,
 
  360                                            const SubControlVolumeFace& scvf)
 const 
  361    { 
return CellCenterPrimaryVariables(0.0); }
 
 
  365                                                     const FVElementGeometry& fvGeometry,
 
  366                                                     const ElementVolumeVariables& elemVolVars,
 
  367                                                     const ElementFaceVariables& elemFaceVars,
 
  368                                                     const SubControlVolumeFace& scvf)
 const 
  371        auto wallFunctionFlux = CellCenterPrimaryVariables(0.0);
 
  372        unsigned int elementIdx = asImp_().gridGeometry().elementMapper().index(element);
 
  375        for (
int compIdx = 0; compIdx < ModelTraits::numFluidComponents(); ++compIdx)
 
  377            if (ModelTraits::replaceCompEqIdx() == compIdx)
 
  380            Scalar schmidtNumber = elemVolVars[scvf.insideScvIdx()].kinematicViscosity()
 
  381                                   / elemVolVars[scvf.insideScvIdx()].diffusionCoefficient(0, 0, compIdx);
 
  382            Scalar moleToMassConversionFactor = ModelTraits::useMoles()
 
  383                                                ? 1.0 : FluidSystem::molarMass(compIdx);
 
  384            wallFunctionFlux[compIdx] +=
 
  385                -1.0 * (asImp_().dirichlet(element, scvf)[Indices::conti0EqIdx + compIdx]
 
  386                        - elemVolVars[scvf.insideScvIdx()].moleFraction(compIdx))
 
  387                * elemVolVars[scvf.insideScvIdx()].molarDensity()
 
  388                * moleToMassConversionFactor
 
  390                / asImp_().turbulentSchmidtNumber()
 
  391                / (1. / asImp_().karmanConstant() * log(
yPlusNominal(elementIdx) * 9.793)
 
  395        if (ModelTraits::replaceCompEqIdx() < ModelTraits::numFluidComponents())
 
  397            wallFunctionFlux[ModelTraits::replaceCompEqIdx()] =
 
  398                -std::accumulate(wallFunctionFlux.begin(), wallFunctionFlux.end(), 0.0);
 
  401        return wallFunctionFlux;
 
 
  406                                                  const FVElementGeometry& fvGeometry,
 
  407                                                  const ElementVolumeVariables& elemVolVars,
 
  408                                                  const ElementFaceVariables& elemFaceVars,
 
  409                                                  const SubControlVolumeFace& scvf)
 const 
  412        auto wallFunctionFlux = CellCenterPrimaryVariables(0.0);
 
  413        unsigned int elementIdx = asImp_().gridGeometry().elementMapper().index(element);
 
  415        Scalar prandtlNumber = elemVolVars[scvf.insideScvIdx()].kinematicViscosity()
 
  416                               * elemVolVars[scvf.insideScvIdx()].density()
 
  417                               * elemVolVars[scvf.insideScvIdx()].heatCapacity()
 
  418                               / elemVolVars[scvf.insideScvIdx()].thermalConductivity();
 
  419        wallFunctionFlux[Indices::energyEqIdx - cellCenterOffset] +=
 
  420            -1.0 * (asImp_().dirichlet(element, scvf)[Indices::temperatureIdx]
 
  421                    - elemVolVars[scvf.insideScvIdx()].temperature())
 
  422            * elemVolVars[scvf.insideScvIdx()].density()
 
  423            * elemVolVars[scvf.insideScvIdx()].heatCapacity()
 
  425            / asImp_().turbulentPrandtlNumber()
 
  426            / (1. / asImp_().karmanConstant() * log(
yPlusNominal(elementIdx) * 9.793)
 
  429        return wallFunctionFlux;
 
 
  433    const Scalar 
pFunction(Scalar molecularNumber, Scalar turbulentNumber)
 const 
  438               * (pow(molecularNumber / turbulentNumber, 0.75) - 1.0)
 
  439               * (1.0 + 0.28 * exp(-0.007 * molecularNumber / turbulentNumber));
 
 
  459    { 
return storedDissipation_[elementIdx]; }
 
 
  462    { 
return storedTurbulentKineticEnergy_[elementIdx]; }
 
 
  465    { 
return storedDynamicEddyViscosity_[elementIdx]; }
 
 
  468    { 
return zeroEqDynamicEddyViscosity_[elementIdx]; }
 
 
  471    { 
return matchingPointIdx_[elementIdx]; }
 
 
  474    std::vector<unsigned int> matchingPointIdx_;
 
  475    std::vector<Scalar> storedDissipation_;
 
  476    std::vector<Scalar> storedTurbulentKineticEnergy_;
 
  477    std::vector<Scalar> storedDynamicEddyViscosity_;
 
  478    std::vector<Scalar> zeroEqDynamicEddyViscosity_;
 
  481    Implementation &asImp_()
 
  482    { 
return *
static_cast<Implementation *
>(
this); }
 
  485    const Implementation &asImp_()
 const 
  486    { 
return *
static_cast<const Implementation *
>(
this); }
 
 
const std::string & paramGroup() const
The parameter group in which to retrieve runtime parameters.
Definition common/fvproblem.hh:524
const GridGeometry & gridGeometry() const
The finite volume grid geometry.
Definition common/fvproblem.hh:520
unsigned int wallElementIndex(const int elementIdx) const
Definition freeflow/rans/problem.hh:242
int flowDirectionAxis(const int elementIdx) const
Definition freeflow/rans/problem.hh:232
void updateDynamicWallProperties(const SolutionVector &curSol)
Update the dynamic (solution dependent) turbulence parameters.
Definition freeflow/rans/problem.hh:131
void updateStaticWallProperties()
Update the static (solution independent) relations to the walls and neighbors.
Definition freeflow/rans/problem.hh:115
Scalar velocityGradient(const int elementIdx, const int i, const int j) const
Definition freeflow/rans/problem.hh:280
Scalar kinematicViscosity(const int elementIdx) const
Definition freeflow/rans/problem.hh:295
Scalar turbulentSchmidtNumber() const
Return the turbulent Schmidt number  which is used to convert the eddy viscosity to an eddy diffusivi...
Definition freeflow/rans/problem.hh:215
Scalar storedDensity(const int elementIdx) const
Definition freeflow/rans/problem.hh:292
Scalar turbulentPrandtlNumber() const
Return the turbulent Prandtl number  which is used to convert the eddy viscosity to an eddy thermal c...
Definition freeflow/rans/problem.hh:204
int wallNormalAxis(const int elementIdx) const
Definition freeflow/rans/problem.hh:222
RANSProblemBase(std::shared_ptr< const GridGeometry > gridGeometry, const std::string ¶mGroup="")
The constructor.
Definition freeflow/rans/problem.hh:90
bool isFlatWallBounded() const
Returns whether a given sub control volume face is on a wall.
Definition freeflow/rans/problem.hh:184
const Scalar tangentialMomentumWallFunction(unsigned int elementIdx, Scalar velocity) const
Returns the nominal wall shear stress (accounts for poor approximation of viscous sublayer)
Definition freeflow/rans/twoeq/kepsilon/problem.hh:287
Scalar yPlusThreshold() const
Definition freeflow/rans/twoeq/kepsilon/problem.hh:446
void updateDynamicWallProperties(const SolutionVector &curSol)
Update the dynamic (solution dependent) relations to the walls.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:105
const Scalar yPlus(unsigned int elementIdx) const
Returns the  value at an element center.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:208
bool useStoredEddyViscosity() const
Definition freeflow/rans/twoeq/kepsilon/problem.hh:452
unsigned int matchingPointIdx(const int elementIdx) const
Definition freeflow/rans/twoeq/kepsilon/problem.hh:470
const Scalar zeroEqEddyViscosityModel(unsigned int elementIdx) const
Returns the kinematic eddy viscosity of a 0-Eq. model.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:225
const Scalar cMu() const
Returns the  constant.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:443
bool inNearWallRegion(unsigned int elementIdx) const
Returns if an element is located in the near-wall region.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:191
CellCenterPrimaryVariables wallFunction(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const SubControlVolumeFace &scvf) const
Returns the flux for non-isothermal and compositional RANS models.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:323
Scalar storedTurbulentKineticEnergy(const int elementIdx) const
Definition freeflow/rans/twoeq/kepsilon/problem.hh:461
Scalar storedDissipation(const int elementIdx) const
Definition freeflow/rans/twoeq/kepsilon/problem.hh:458
Scalar zeroEqDynamicEddyViscosity(const int elementIdx) const
Definition freeflow/rans/twoeq/kepsilon/problem.hh:467
CellCenterPrimaryVariables wallFunctionEnergy(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const SubControlVolumeFace &scvf) const
Returns the energy wall-function flux.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:405
FacePrimaryVariables wallFunction(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const SubControlVolumeFace &scvf, const SubControlVolumeFace &localSubFace) const
Returns an additional wall function momentum flux (only needed for RANS models)
Definition freeflow/rans/twoeq/kepsilon/problem.hh:308
const Scalar uStarNominal(unsigned int elementIdx) const
Returns the nominal wall shear stress velocity (accounts for poor approximation of viscous sublayer)
Definition freeflow/rans/twoeq/kepsilon/problem.hh:260
const Scalar uStar(unsigned int elementIdx) const
Returns the wall shear stress velocity.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:248
const Scalar dissipationWallFunction(unsigned int elementIdx) const
Returns the dissipation calculated from the wall function consideration.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:271
RANSProblemImpl(std::shared_ptr< const GridGeometry > gridGeometry, const std::string ¶mGroup="")
The constructor sets the gravity, if desired by the user.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:74
const Scalar yPlusNominal(unsigned int elementIdx) const
Returns the nominal  value at an element center.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:216
Scalar storedDynamicEddyViscosity(const int elementIdx) const
Definition freeflow/rans/twoeq/kepsilon/problem.hh:464
const Scalar pFunction(Scalar molecularNumber, Scalar turbulentNumber) const
Returns the value of the P-function after Jayatilleke Versteeg2009a.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:433
CellCenterPrimaryVariables wallFunctionComponent(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFaceVariables &elemFaceVars, const SubControlVolumeFace &scvf) const
Returns the component wall-function flux.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:364
void updateStaticWallProperties()
Correct size of the static (solution independent) wall variables.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:81
bool useWallFunction(const Element &element, const SubControlVolumeFace &localSubFace, const int &eqIdx) const
Checks whether a wall function should be used.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:295
bool isMatchingPoint(unsigned int elementIdx) const
Returns if an element is the matching point.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:202
const Scalar turbulentKineticEnergyWallFunction(unsigned int elementIdx) const
Returns the turbulentKineticEnergy calculated from the wall function consideration.
Definition freeflow/rans/twoeq/kepsilon/problem.hh:280
Defines all properties used in Dumux.
the turbulence-model-specfic RANS problem
A single-phase, isothermal k-epsilon model.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:26
auto elementSolution(const Element &element, const SolutionVector &sol, const GridGeometry &gg) -> std::enable_if_t< GridGeometry::discMethod==DiscretizationMethods::cctpfa||GridGeometry::discMethod==DiscretizationMethods::ccmpfa, CCElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for cell-centered schemes.
Definition cellcentered/elementsolution.hh:101
TurbulenceModel
The available free flow turbulence models in Dumux.
Definition turbulencemodel.hh:26
@ kepsilon
Definition turbulencemodel.hh:27
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:149
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
PrimaryVariables makePriVarsFromCellCenterPriVars(const CellCenterPrimaryVariables &cellCenterPriVars)
Helper function to create a PrimaryVariables object from CellCenterPrimaryVariables.
Definition staggered/elementsolution.hh:29
Free function to get the local view of a grid cache object.
The available discretization methods in Dumux.
The local element solution class for staggered methods.
Base class for all staggered fv problems.
The available free flow turbulence models in Dumux.