diff --git a/test/freeflow/rans/problem.hh b/test/freeflow/rans/problem.hh index 1c4246d16f06d6f19d23032e956206ee95770d0f..9f1ff50c567abf6577e764ffec09d937bf26a357 100644 --- a/test/freeflow/rans/problem.hh +++ b/test/freeflow/rans/problem.hh @@ -72,7 +72,6 @@ struct PipeLauferNILowReKEpsilon { using InheritsFrom = std::tuple; }; } // end namespace TTag - // the fluid system template struct FluidSystem @@ -181,9 +180,7 @@ public: } Scalar sandGrainRoughnessAtPos(const GlobalPosition &globalPos) const - { - return sandGrainRoughness_; - } + { return sandGrainRoughness_; } /*! * \brief Returns the temperature [K] within the domain for the isothermal model. @@ -224,10 +221,8 @@ public: else values.setDirichlet(Indices::temperatureIdx); #endif - // turbulence model-specific boundary types - static constexpr auto numEq = numTurbulenceEq(ModelTraits::turbulenceModel()); - setBcTypes_(values, globalPos, Dune::index_constant{}); + setBcTypes_(values, globalPos); return values; } @@ -245,11 +240,7 @@ public: const FVElementGeometry& fvGeometry, const SubControlVolume& scv, int pvIdx) const - { - using IsKOmegaKEpsilon = std::integral_constant; - return isDirichletCell_(element, fvGeometry, scv, pvIdx, IsKOmegaKEpsilon{}); - } + { return isDirichletCell_(element, fvGeometry, scv, pvIdx); } /*! * \brief Evaluate the boundary conditions for a dirichlet values at the boundary. @@ -277,31 +268,17 @@ public: * \param scv the sub control volume * \note used for cell-centered discretization schemes */ - template = 0> - PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const - { - const auto globalPos = scv.center(); - PrimaryVariables values(initialAtPos(globalPos)); - return values; - } - - /*! - * \brief Evaluate the boundary conditions for fixed values at cell centers - * - * \param element The finite element - * \param scv the sub control volume - * \note used for cell-centered discretization schemes - */ - template = 0> - PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const + PrimaryVariables dirichlet([[maybe_unused]] const Element& element, const SubControlVolume& scv) const { - using SetDirichletCellForBothTurbEq = std::integral_constant; - - return dirichletTurbulentTwoEq_(element, scv, SetDirichletCellForBothTurbEq{}); + if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::kepsilon + || ModelTraits::turbulenceModel() == TurbulenceModel::komega) + return dirichletTurbulentTwoEq_(element, scv); + else + { + const auto globalPos = scv.center(); + PrimaryVariables values(initialAtPos(globalPos)); + return values; + } } /*! @@ -319,187 +296,138 @@ public: : time() / initializationTime_ * inletVelocity_; if (isOnWallAtPos(globalPos)) values[Indices::velocityXIdx] = 0.0; - #if NONISOTHERMAL values[Indices::temperatureIdx] = isOnWallAtPos(globalPos) ? wallTemperature_ : inletTemperature_; #endif - // turbulence model-specific initial conditions - static constexpr auto numEq = numTurbulenceEq(ModelTraits::turbulenceModel()); - setInitialAtPos_(values, globalPos, Dune::index_constant{}); - + setInitialAtPos_(values, globalPos); return values; } // \} void setTimeLoop(TimeLoopPtr timeLoop) - { - timeLoop_ = timeLoop; - } + { timeLoop_ = timeLoop; } Scalar time() const - { - return timeLoop_->time(); - } + { return timeLoop_->time(); } private: bool isInlet_(const GlobalPosition& globalPos) const - { - return globalPos[0] < this->gridGeometry().bBoxMin()[0] + eps_; - } + { return globalPos[0] < this->gridGeometry().bBoxMin()[0] + eps_; } bool isOutlet_(const GlobalPosition& globalPos) const - { - return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; - } - - //! Initial conditions for the zero-eq turbulence model (none) - void setInitialAtPos_(PrimaryVariables& values, const GlobalPosition &globalPos, Dune::index_constant<0>) const {} - - //! Initial conditions for the one-eq turbulence model - void setInitialAtPos_(PrimaryVariables& values, const GlobalPosition &globalPos, Dune::index_constant<1>) const - { - values[Indices::viscosityTildeIdx] = viscosityTilde_; - if (isOnWallAtPos(globalPos)) - values[Indices::viscosityTildeIdx] = 0.0; - } + { return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; } //! Initial conditions for the komega, kepsilon and lowrekepsilon turbulence models - void setInitialAtPos_(PrimaryVariables& values, const GlobalPosition &globalPos, Dune::index_constant<2>) const + void setInitialAtPos_([[maybe_unused]] PrimaryVariables& values, + [[maybe_unused]] const GlobalPosition &globalPos) const { - values[Indices::turbulentKineticEnergyIdx] = turbulentKineticEnergy_; - values[Indices::dissipationIdx] = dissipation_; - if (isOnWallAtPos(globalPos)) + if constexpr (numTurbulenceEq(ModelTraits::turbulenceModel()) == 0) // zero equation models + return; + else if constexpr (numTurbulenceEq(ModelTraits::turbulenceModel()) == 1) // one equation models + { + values[Indices::viscosityTildeIdx] = viscosityTilde_; + if (isOnWallAtPos(globalPos)) + values[Indices::viscosityTildeIdx] = 0.0; + } + else // two equation models { - values[Indices::turbulentKineticEnergyIdx] = 0.0; - values[Indices::dissipationIdx] = 0.0; + static_assert(numTurbulenceEq(ModelTraits::turbulenceModel()) == 2, "Only reached by 2eq models"); + values[Indices::turbulentKineticEnergyIdx] = turbulentKineticEnergy_; + values[Indices::dissipationIdx] = dissipation_; + if (isOnWallAtPos(globalPos)) + { + values[Indices::turbulentKineticEnergyIdx] = 0.0; + values[Indices::dissipationIdx] = 0.0; + } } } - //! Boundary condition types for the zero-eq turbulence model (none) - void setBcTypes_(BoundaryTypes& values, const GlobalPosition& pos, Dune::index_constant<0>) const {} - //! Boundary condition types for the one-eq turbulence model - void setBcTypes_(BoundaryTypes& values, const GlobalPosition& pos, Dune::index_constant<1>) const + void setBcTypes_([[maybe_unused]] BoundaryTypes& values, + [[maybe_unused]] const GlobalPosition& pos) const { - if(isOutlet_(pos)) - values.setOutflow(Indices::viscosityTildeIdx); - else // walls and inflow - values.setDirichlet(Indices::viscosityTildeIdx); - } - - //! Boundary condition types for the komega, kepsilon and lowrekepsilon turbulence models - void setBcTypes_(BoundaryTypes& values,const GlobalPosition& pos, Dune::index_constant<2>) const - { - if(isOutlet_(pos)) + if constexpr (numTurbulenceEq(ModelTraits::turbulenceModel()) == 0) // zero equation models + return; + else if constexpr (numTurbulenceEq(ModelTraits::turbulenceModel()) == 1) // one equation models { - values.setOutflow(Indices::turbulentKineticEnergyEqIdx); - values.setOutflow(Indices::dissipationEqIdx); + if(isOutlet_(pos)) + values.setOutflow(Indices::viscosityTildeIdx); + else // walls and inflow + values.setDirichlet(Indices::viscosityTildeIdx); } - else + else // two equation models { - // walls and inflow - values.setDirichlet(Indices::turbulentKineticEnergyIdx); - values.setDirichlet(Indices::dissipationIdx); + static_assert(numTurbulenceEq(ModelTraits::turbulenceModel()) == 2, "Only reached by 2eq models"); + if(isOutlet_(pos)) + { + values.setOutflow(Indices::turbulentKineticEnergyEqIdx); + values.setOutflow(Indices::dissipationEqIdx); + } + else + { + // walls and inflow + values.setDirichlet(Indices::turbulentKineticEnergyIdx); + values.setDirichlet(Indices::dissipationIdx); + } } } - //! Forward to ParentType template - bool isDirichletCell_(const Element& element, + bool isDirichletCell_([[maybe_unused]] const Element& element, const FVElementGeometry& fvGeometry, - const SubControlVolume& scv, - int pvIdx, - std::false_type) const - { - return ParentType::isDirichletCell(element, fvGeometry, scv, pvIdx); - } - - //! Specialization for the KOmega and KEpsilon Models - template - bool isDirichletCell_(const Element& element, - const FVElementGeometry& fvGeometry, - const SubControlVolume& scv, - int pvIdx, - std::true_type) const - { - using SetDirichletCellForBothTurbEq = std::integral_constant; - return isDirichletCellTurbulentTwoEq_(element, fvGeometry, scv, pvIdx, SetDirichletCellForBothTurbEq{}); - } - - //! Specialization for the KEpsilon Model - template - bool isDirichletCellTurbulentTwoEq_(const Element& element, - const FVElementGeometry& fvGeometry, - const SubControlVolume& scv, - int pvIdx, - std::true_type) const + [[maybe_unused]] const SubControlVolume& scv, + const int& pvIdx) const { - const auto eIdx = this->gridGeometry().elementMapper().index(element); - - // set a fixed turbulent kinetic energy and dissipation near the wall - if (this->inNearWallRegion(eIdx)) - return pvIdx == Indices::turbulentKineticEnergyEqIdx || pvIdx == Indices::dissipationEqIdx; - - // set a fixed dissipation at the matching point - if (this->isMatchingPoint(eIdx)) - return pvIdx == Indices::dissipationEqIdx;// set a fixed dissipation (omega) for all cells at the wall - - return false; - } - - //! Specialization for the KOmega Model - template - bool isDirichletCellTurbulentTwoEq_(const Element& element, - const FVElementGeometry& fvGeometry, - const SubControlVolume& scv, - int pvIdx, - std::false_type) const - { - // set a fixed dissipation (omega) for all cells at the wall - for (const auto& scvf : scvfs(fvGeometry)) - if (isOnWallAtPos(scvf.center()) && pvIdx == Indices::dissipationIdx) - return true; - - return false; - - } - - //! Specialization for the kepsilon - template - PrimaryVariables dirichletTurbulentTwoEq_(const Element& element, - const SubControlVolume& scv, - std::true_type) const - { - const auto globalPos = scv.center(); - PrimaryVariables values(initialAtPos(globalPos)); - unsigned int elementIdx = this->gridGeometry().elementMapper().index(element); - - // fixed value for the turbulent kinetic energy - values[Indices::turbulentKineticEnergyEqIdx] = this->turbulentKineticEnergyWallFunction(elementIdx); - - // fixed value for the dissipation - values[Indices::dissipationEqIdx] = this->dissipationWallFunction(elementIdx); - - return values; + if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::kepsilon) + { + const auto eIdx = fvGeometry.gridGeometry().elementMapper().index(element); + // For the kepsilon model we set fixed values within the matching point and at the wall + if (this->inNearWallRegion(eIdx)) + return pvIdx == Indices::turbulentKineticEnergyEqIdx || pvIdx == Indices::dissipationEqIdx; + if (this->isMatchingPoint(eIdx)) + return pvIdx == Indices::dissipationEqIdx; + return false; + } + else if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::komega) + { + // For the komega model we set a fixed dissipation (omega) for all cells at the wall + for (const auto& scvf : scvfs(fvGeometry)) + if (isOnWallAtPos(scvf.center()) && pvIdx == Indices::dissipationIdx) + return true; + return false; + } + else + return ParentType::isDirichletCell(element, fvGeometry, scv, pvIdx); } - //! Specialization for the KOmega + //! Specialization for the kepsilon and komega template PrimaryVariables dirichletTurbulentTwoEq_(const Element& element, - const SubControlVolume& scv, - std::false_type) const + const SubControlVolume& scv) const { const auto globalPos = scv.center(); PrimaryVariables values(initialAtPos(globalPos)); unsigned int elementIdx = this->gridGeometry().elementMapper().index(element); - const auto wallDistance = ParentType::wallDistance_[elementIdx]; - using std::pow; - values[Indices::dissipationEqIdx] = 6.0 * ParentType::kinematicViscosity_[elementIdx] - / (ParentType::betaOmega() * pow(wallDistance, 2)); - return values; + if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::kepsilon) + { + // For the kepsilon model we set a fixed value for the turbulent kinetic energy and the dissipation + values[Indices::turbulentKineticEnergyEqIdx] = this->turbulentKineticEnergyWallFunction(elementIdx); + values[Indices::dissipationEqIdx] = this->dissipationWallFunction(elementIdx); + return values; + } + else + { + static_assert(ModelTraits::turbulenceModel() == TurbulenceModel::komega, "Only valid for Komega"); + // For the komega model we set a fixed value for the dissipation + const auto wallDistance = ParentType::wallDistance_[elementIdx]; + using std::pow; + values[Indices::dissipationEqIdx] = 6.0 * ParentType::kinematicViscosity_[elementIdx] + / (ParentType::betaOmega() * wallDistance * wallDistance); + return values; + } } Scalar eps_; diff --git a/test/freeflow/ransnc/problem.hh b/test/freeflow/ransnc/problem.hh index a304d53b40cf7e8dee7ba514d1a913b147353200..e5eb177b1910ba6dda8a3e6b9089407c3ca6df81 100644 --- a/test/freeflow/ransnc/problem.hh +++ b/test/freeflow/ransnc/problem.hh @@ -177,9 +177,7 @@ public: // \{ bool isOnWallAtPos(const GlobalPosition& globalPos) const - { - return globalPos[1] < eps_; - } + { return globalPos[1] < eps_; } /*! * \brief Returns the temperature within the domain in [K]. @@ -206,8 +204,7 @@ public: BoundaryTypes values; // turbulence model-specific boundary types - static constexpr auto numEq = numTurbulenceEq(ModelTraits::turbulenceModel()); - setBcTypes_(values, globalPos, Dune::index_constant{}); + setBcTypes_(values, globalPos); if(isInlet_(globalPos)) { @@ -254,11 +251,7 @@ public: const FVElementGeometry& fvGeometry, const SubControlVolume& scv, int pvIdx) const - { - using IsKOmegaKEpsilon = std::integral_constant; - return isDirichletCell_(element, fvGeometry, scv, pvIdx, IsKOmegaKEpsilon{}); - } + { return isDirichletCell_(element, fvGeometry, scv, pvIdx); } /*! * \brief Evaluate the boundary conditions for a dirichlet values at the boundary. @@ -278,7 +271,6 @@ public: { values[transportCompIdx] = (time() > 10.0) ? inletMoleFraction_ : 0.0; } - #if NONISOTHERMAL if (time() > 10.0 && isOnWallAtPos(globalPos)) { @@ -296,31 +288,17 @@ public: * \param scv the sub control volume * \note used for cell-centered discretization schemes */ - template = 0> - PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const + PrimaryVariables dirichlet([[maybe_unused]] const Element& element, const SubControlVolume& scv) const { - const auto globalPos = scv.center(); - PrimaryVariables values(initialAtPos(globalPos)); - return values; - } - - /*! - * \brief Evaluate the boundary conditions for fixed values at cell centers - * - * \param element The finite element - * \param scv the sub control volume - * \note used for cell-centered discretization schemes - */ - template = 0> - PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const - { - using SetDirichletCellForBothTurbEq = std::integral_constant; - - return dirichletTurbulentTwoEq_(element, scv, SetDirichletCellForBothTurbEq{}); + if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::kepsilon + || ModelTraits::turbulenceModel() == TurbulenceModel::komega) + return dirichletTurbulentTwoEq_(element, scv); + else + { + const auto globalPos = scv.center(); + PrimaryVariables values(initialAtPos(globalPos)); + return values; + } } /*! @@ -336,7 +314,6 @@ public: #if NONISOTHERMAL values[Indices::temperatureIdx] = temperature(); #endif - // block velocity profile values[Indices::velocityXIdx] = 0.0; if (!isOnWallAtPos(globalPos)) @@ -344,181 +321,134 @@ public: values[Indices::velocityYIdx] = 0.0; // turbulence model-specific initial conditions - static constexpr auto numEq = numTurbulenceEq(ModelTraits::turbulenceModel()); - setInitialAtPos_(values, globalPos, Dune::index_constant{}); - + setInitialAtPos_(values, globalPos); return values; } // \} void setTimeLoop(TimeLoopPtr timeLoop) - { - timeLoop_ = timeLoop; - } + { timeLoop_ = timeLoop; } Scalar time() const - { - return timeLoop_->time(); - } + { return timeLoop_->time(); } private: bool isInlet_(const GlobalPosition& globalPos) const - { - return globalPos[0] < eps_; - } + { return globalPos[0] < eps_; } bool isOutlet_(const GlobalPosition& globalPos) const - { - return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; - } - - //! Initial conditions for the zero-eq turbulence model (none) - void setInitialAtPos_(PrimaryVariables& values, const GlobalPosition &globalPos, Dune::index_constant<0>) const {} - - //! Initial conditions for the one-eq turbulence model - void setInitialAtPos_(PrimaryVariables& values, const GlobalPosition &globalPos, Dune::index_constant<1>) const - { - values[Indices::viscosityTildeIdx] = viscosityTilde_; - if (isOnWallAtPos(globalPos)) - values[Indices::viscosityTildeIdx] = 0.0; - } + { return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; } //! Initial conditions for the komega, kepsilon and lowrekepsilon turbulence models - void setInitialAtPos_(PrimaryVariables& values, const GlobalPosition &globalPos, Dune::index_constant<2>) const + void setInitialAtPos_([[maybe_unused]] PrimaryVariables& values, + [[maybe_unused]] const GlobalPosition &globalPos) const { - values[Indices::turbulentKineticEnergyIdx] = turbulentKineticEnergy_; - values[Indices::dissipationIdx] = dissipation_; - if (isOnWallAtPos(globalPos)) + if constexpr (numTurbulenceEq(ModelTraits::turbulenceModel()) == 0) // zero equation models + return; + else if constexpr (numTurbulenceEq(ModelTraits::turbulenceModel()) == 1) // one equation models { - values[Indices::turbulentKineticEnergyIdx] = 0.0; - values[Indices::dissipationIdx] = 0.0; + values[Indices::viscosityTildeIdx] = viscosityTilde_; + if (isOnWallAtPos(globalPos)) + values[Indices::viscosityTildeIdx] = 0.0; + } + else // two equation models + { + static_assert(numTurbulenceEq(ModelTraits::turbulenceModel()) == 2, "Only reached by 2eq models"); + values[Indices::turbulentKineticEnergyIdx] = turbulentKineticEnergy_; + values[Indices::dissipationIdx] = dissipation_; + if (isOnWallAtPos(globalPos)) + { + values[Indices::turbulentKineticEnergyIdx] = 0.0; + values[Indices::dissipationIdx] = 0.0; + } } } - //! Boundary condition types for the zero-eq turbulence model (none) - void setBcTypes_(BoundaryTypes& values, const GlobalPosition& pos, Dune::index_constant<0>) const {} - //! Boundary condition types for the one-eq turbulence model - void setBcTypes_(BoundaryTypes& values, const GlobalPosition& pos, Dune::index_constant<1>) const - { - if(isOutlet_(pos)) - values.setOutflow(Indices::viscosityTildeIdx); - else // walls and inflow - values.setDirichlet(Indices::viscosityTildeIdx); - } - - //! Boundary condition types for the komega, kepsilon and lowrekepsilon turbulence models - void setBcTypes_(BoundaryTypes& values,const GlobalPosition& pos, Dune::index_constant<2>) const + void setBcTypes_([[maybe_unused]] BoundaryTypes& values, + [[maybe_unused]] const GlobalPosition& pos) const { - if(isOutlet_(pos)) + if constexpr (numTurbulenceEq(ModelTraits::turbulenceModel()) == 0) // zero equation models + return; + else if constexpr (numTurbulenceEq(ModelTraits::turbulenceModel()) == 1) // one equation models { - values.setOutflow(Indices::turbulentKineticEnergyEqIdx); - values.setOutflow(Indices::dissipationEqIdx); + if(isOutlet_(pos)) + values.setOutflow(Indices::viscosityTildeIdx); + else // walls and inflow + values.setDirichlet(Indices::viscosityTildeIdx); } - else + else // two equation models { - // walls and inflow - values.setDirichlet(Indices::turbulentKineticEnergyIdx); - values.setDirichlet(Indices::dissipationIdx); + static_assert(numTurbulenceEq(ModelTraits::turbulenceModel()) == 2, "Only reached by 2eq models"); + if(isOutlet_(pos)) + { + values.setOutflow(Indices::turbulentKineticEnergyEqIdx); + values.setOutflow(Indices::dissipationEqIdx); + } + else + { + // walls and inflow + values.setDirichlet(Indices::turbulentKineticEnergyIdx); + values.setDirichlet(Indices::dissipationIdx); + } } } - //! Forward to ParentType template - bool isDirichletCell_(const Element& element, + bool isDirichletCell_([[maybe_unused]] const Element& element, const FVElementGeometry& fvGeometry, - const SubControlVolume& scv, - int pvIdx, - std::false_type) const + [[maybe_unused]] const SubControlVolume& scv, + const int& pvIdx) const { - return ParentType::isDirichletCell(element, fvGeometry, scv, pvIdx); - } - - //! Specialization for the KOmega and KEpsilon Models - template - bool isDirichletCell_(const Element& element, - const FVElementGeometry& fvGeometry, - const SubControlVolume& scv, - int pvIdx, - std::true_type) const - { - using SetDirichletCellForBothTurbEq = std::integral_constant; - return isDirichletCellTurbulentTwoEq_(element, fvGeometry, scv, pvIdx, SetDirichletCellForBothTurbEq{}); - } - - //! Specialization for the KEpsilon Model - template - bool isDirichletCellTurbulentTwoEq_(const Element& element, - const FVElementGeometry& fvGeometry, - const SubControlVolume& scv, - int pvIdx, - std::true_type) const - { - const auto eIdx = this->gridGeometry().elementMapper().index(element); - - // set a fixed turbulent kinetic energy and dissipation near the wall - if (this->inNearWallRegion(eIdx)) - return pvIdx == Indices::turbulentKineticEnergyEqIdx || pvIdx == Indices::dissipationEqIdx; - - // set a fixed dissipation at the matching point - if (this->isMatchingPoint(eIdx)) - return pvIdx == Indices::dissipationEqIdx;// set a fixed dissipation (omega) for all cells at the wall - - return false; - } - - //! Specialization for the KOmega Model - template - bool isDirichletCellTurbulentTwoEq_(const Element& element, - const FVElementGeometry& fvGeometry, - const SubControlVolume& scv, - int pvIdx, - std::false_type) const - { - // set a fixed dissipation (omega) for all cells at the wall - for (const auto& scvf : scvfs(fvGeometry)) - if (isOnWallAtPos(scvf.center()) && pvIdx == Indices::dissipationIdx) - return true; - - return false; - - } - - //! Specialization for the kepsilon - template - PrimaryVariables dirichletTurbulentTwoEq_(const Element& element, - const SubControlVolume& scv, - std::true_type) const - { - const auto globalPos = scv.center(); - PrimaryVariables values(initialAtPos(globalPos)); - unsigned int elementIdx = this->gridGeometry().elementMapper().index(element); - - // fixed value for the turbulent kinetic energy - values[Indices::turbulentKineticEnergyEqIdx] = this->turbulentKineticEnergyWallFunction(elementIdx); - - // fixed value for the dissipation - values[Indices::dissipationEqIdx] = this->dissipationWallFunction(elementIdx); - - return values; + if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::kepsilon) + { + const auto eIdx = fvGeometry.gridGeometry().elementMapper().index(element); + // For the kepsilon model we set fixed values within the matching point and at the wall + if (this->inNearWallRegion(eIdx)) + return pvIdx == Indices::turbulentKineticEnergyEqIdx || pvIdx == Indices::dissipationEqIdx; + if (this->isMatchingPoint(eIdx)) + return pvIdx == Indices::dissipationEqIdx; + return false; + } + else if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::komega) + { + // For the komega model we set a fixed dissipation (omega) for all cells at the wall + for (const auto& scvf : scvfs(fvGeometry)) + if (isOnWallAtPos(scvf.center()) && pvIdx == Indices::dissipationIdx) + return true; + return false; + } + else + return ParentType::isDirichletCell(element, fvGeometry, scv, pvIdx); } - //! Specialization for the KOmega + //! Specialization for the kepsilon and komega template PrimaryVariables dirichletTurbulentTwoEq_(const Element& element, - const SubControlVolume& scv, - std::false_type) const + const SubControlVolume& scv) const { const auto globalPos = scv.center(); PrimaryVariables values(initialAtPos(globalPos)); unsigned int elementIdx = this->gridGeometry().elementMapper().index(element); - const auto wallDistance = ParentType::wallDistance_[elementIdx]; - using std::pow; - values[Indices::dissipationEqIdx] = 6.0 * ParentType::kinematicViscosity_[elementIdx] - / (ParentType::betaOmega() * pow(wallDistance, 2)); - return values; + if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::kepsilon) + { + // For the kepsilon model we set a fixed value for the turbulent kinetic energy and the dissipation + values[Indices::turbulentKineticEnergyEqIdx] = this->turbulentKineticEnergyWallFunction(elementIdx); + values[Indices::dissipationEqIdx] = this->dissipationWallFunction(elementIdx); + return values; + } + else + { + static_assert(ModelTraits::turbulenceModel() == TurbulenceModel::komega, "Only valid for Komega"); + // For the komega model we set a fixed value for the dissipation + const auto wallDistance = ParentType::wallDistance_[elementIdx]; + using std::pow; + values[Indices::dissipationEqIdx] = 6.0 * ParentType::kinematicViscosity_[elementIdx] + / (ParentType::betaOmega() * wallDistance * wallDistance); + return values; + } } const Scalar eps_;