From bc692e2e4d5f11f2d9644dcfd4a2c2bd29051e19 Mon Sep 17 00:00:00 2001 From: Ned Coltman <edward.coltman@iws.uni-stuttgart.de> Date: Thu, 30 Mar 2023 19:43:39 +0200 Subject: [PATCH] [exercises][ff-pm][turbulence] Include the SST model and update the isOnWall stuff --- .../turbulence/freeflowsubproblem.hh | 102 +++++++++++-- .../models/plotFluxes.py | 2 +- .../turbulence/freeflowsubproblem.hh | 136 +++++++++++++++--- .../turbulence/properties.hh | 4 +- 4 files changed, 215 insertions(+), 29 deletions(-) diff --git a/exercises/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh b/exercises/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh index 289141a6..5a68f513 100644 --- a/exercises/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh +++ b/exercises/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh @@ -20,8 +20,8 @@ * \file * \brief The free-flow sub problem */ -#ifndef DUMUX_FREEFLOW1P2C_SUBPROBLEM_HH -#define DUMUX_FREEFLOW1P2C_SUBPROBLEM_HH +#ifndef DUMUX_FREEFLOW_TURBULENCE_SUBPROBLEM_HH +#define DUMUX_FREEFLOW_TURBULENCE_SUBPROBLEM_HH #include <dumux/common/properties.hh> #include <dumux/common/boundarytypes.hh> @@ -46,6 +46,7 @@ class FreeFlowSubProblem : public NavierStokesStaggeredProblem<TypeTag> using ParentType = NavierStokesStaggeredProblem<TypeTag>; using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + static constexpr auto dimWorld = GridView::dimensionworld; using Scalar = GetPropType<TypeTag, Properties::Scalar>; using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>; using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; @@ -56,6 +57,7 @@ class FreeFlowSubProblem : public NavierStokesStaggeredProblem<TypeTag> using FVGridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; using FVElementGeometry = typename FVGridGeometry::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; using Element = typename GridView::template Codim<0>::Entity; using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView; @@ -87,7 +89,23 @@ public: refTemperature_ = getParamFromGroup<Scalar>(this->paramGroup(), "Problem.RefTemperature"); diffCoeffAvgType_ = StokesDarcyCouplingOptions::stringToEnum(DiffusionCoefficientAveragingType{}, - getParamFromGroup<std::string>(this->paramGroup(), "Problem.InterfaceDiffusionCoefficientAvg")); + getParamFromGroup<std::string>(this->paramGroup(), + "Problem.InterfaceDiffusionCoefficientAvg")); + +// TODO: // ******************** uncomment this section for the first task 3.A ****************** // +// FluidSystem::init(); +// Dumux::TurbulenceProperties<Scalar, dimWorld, true> turbulenceProperties; +// FluidState fluidState; +// const auto phaseIdx = 0; +// fluidState.setPressure(phaseIdx, refPressure_); +// fluidState.setTemperature(this->spatialParams().temperatureAtPos({})); +// fluidState.setMassFraction(phaseIdx, phaseIdx, 1.0); +// Scalar density = FluidSystem::density(fluidState, phaseIdx); +// Scalar kinematicViscosity = FluidSystem::viscosity(fluidState, phaseIdx) / density; +// Scalar diameter = this->gridGeometry().bBoxMax()[1] - this->gridGeometry().bBoxMin()[1]; +// turbulentKineticEnergy_ = turbulenceProperties.turbulentKineticEnergy(refVelocity_, diameter, kinematicViscosity); +// dissipation_ = turbulenceProperties.dissipationRate(refVelocity_, diameter, kinematicViscosity); +// // ************************************************************************************* // } /*! @@ -113,7 +131,8 @@ public: } // TODO: dumux-course-task 3.A -// set boundary conditions for the turbulence model at the wall (values.setWall()) at the upper and lower boundary +// set wall conditions for the turbulence model at the wall (values.setWall()) at the upper and lower boundary +// set boundary conditions for the turbulence model primary variables everywhere (outflow on right boundary, otherwise dirichlet) if (onLowerBoundary_(globalPos)) { values.setDirichlet(Indices::velocityXIdx); @@ -153,16 +172,65 @@ public: } /*! - * \brief Evaluate the boundary conditions for a Dirichlet control volume. + * \brief Evaluate the boundary conditions for dirichlet values at the boundary. * - * \param element The element - * \param scvf The subcontrolvolume face + * \param element The finite element + * \param scvf the sub control volume face + * \note used for cell-centered discretization schemes */ - PrimaryVariables dirichletAtPos(const GlobalPosition& pos) const + PrimaryVariables dirichlet(const Element& element, const SubControlVolumeFace& scvf) const { - PrimaryVariables values(0.0); - values = initialAtPos(pos); + const auto globalPos = scvf.ipGlobal(); + PrimaryVariables values(initialAtPos(globalPos)); + return values; + } + + /*! + * \brief Returns whether a fixed Dirichlet value shall be used at a given cell. + * + * \param element The finite element + * \param fvGeometry The finite-volume geometry + * \param scv The sub control volume + * \param pvIdx The primary variable index in the solution vector + */ + template<class Element, class FVElementGeometry, class SubControlVolume> + bool isDirichletCell(const Element& element, + const FVElementGeometry& fvGeometry, + const SubControlVolume& scv, + int pvIdx) const + { + if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::sst) + { + // For the komega model we set a fixed dissipation (omega) for all cells at the wall + for (const auto& scvf : scvfs(fvGeometry)) + if (this->boundaryTypes(element, scvf).hasWall() && pvIdx == Indices::dissipationIdx) + return true; + } + return false; + } + /*! + * \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 + */ + PrimaryVariables dirichlet([[maybe_unused]] const Element& element, const SubControlVolume& scv) const + { + const auto globalPos = scv.center(); + PrimaryVariables values(initialAtPos(globalPos)); + unsigned int elementIdx = this->gridGeometry().elementMapper().index(element); + + if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::sst) + { + // 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; + } return values; } @@ -220,6 +288,18 @@ public: values[Indices::velocityXIdx] = refVelocity(); values[Indices::temperatureIdx] = refTemperature(); + // TODO: dumux-course-task 3.A + // Set initial conditions for the TKE and the Dissipation. Values calculated in the constructor +// values[Indices::turbulentKineticEnergyIdx] = TODO??; +// values[Indices::dissipationIdx] = TODO??; +// // TODO: dumux-course-task 3.B +// // Remove the condition `onUpperBoundary_(globalPos)` here. +// if(onUpperBoundary_(globalPos) || onLowerBoundary_(globalPos)) +// { +// values[Indices::turbulentKineticEnergyIdx] = 0.0; +// values[Indices::dissipationIdx] = 0.0; +// } + // TODO: dumux-course-task 3.B // Remove the condition `onUpperBoundary_(globalPos)` here. if(onUpperBoundary_(globalPos) || onLowerBoundary_(globalPos)) @@ -317,6 +397,8 @@ private: Scalar refPressure_; Scalar refMoleFrac_; Scalar refTemperature_; + Scalar turbulentKineticEnergy_; + Scalar dissipation_; TimeLoopPtr timeLoop_; diff --git a/exercises/solution/exercise-coupling-ff-pm/models/plotFluxes.py b/exercises/solution/exercise-coupling-ff-pm/models/plotFluxes.py index a3955cee..667b97bf 120000 --- a/exercises/solution/exercise-coupling-ff-pm/models/plotFluxes.py +++ b/exercises/solution/exercise-coupling-ff-pm/models/plotFluxes.py @@ -1 +1 @@ -/home/nedc/DUMUX_summerschool/dumux-course/exercises/exercise-coupling-ff-pm/models/plotFluxes.py \ No newline at end of file +../../../exercise-coupling-ff-pm/models/plotFluxes.py \ No newline at end of file diff --git a/exercises/solution/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh b/exercises/solution/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh index 41fae5c3..66dbbc3b 100644 --- a/exercises/solution/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh +++ b/exercises/solution/exercise-coupling-ff-pm/turbulence/freeflowsubproblem.hh @@ -20,22 +20,25 @@ * \file * \brief The free-flow sub problem */ -#ifndef DUMUX_FREEFLOW_TURBULENCE_SUBPROBLEM_HH -#define DUMUX_FREEFLOW_TURBULENCE_SUBPROBLEM_HH +#ifndef DUMUX_FREEFLOW_TURBULENCE_SUBPROBLEM_SOL_HH +#define DUMUX_FREEFLOW_TURBULENCE_SUBPROBLEM_SOL_HH -#if EXNUMBER >= 1 -#include <dumux/freeflow/rans/problem.hh> -#include <dumux/freeflow/rans/boundarytypes.hh> -#else -#include <dumux/freeflow/navierstokes/staggered/problem.hh> -#endif #include <dumux/common/timeloop.hh> #include <dumux/common/properties.hh> #include <dumux/common/boundarytypes.hh> #include <dumux/common/numeqvector.hh> #include <dumux/multidomain/boundary/stokesdarcy/couplingdata.hh> + +#if EXNUMBER >= 1 +#include <dumux/freeflow/turbulencemodel.hh> +#include <dumux/freeflow/turbulenceproperties.hh> +#include <dumux/freeflow/rans/twoeq/sst/problem.hh> +#include <dumux/freeflow/rans/boundarytypes.hh> +#else +#include <dumux/freeflow/navierstokes/staggered/problem.hh> #include <dumux/freeflow/navierstokes/boundarytypes.hh> +#endif namespace Dumux { @@ -54,6 +57,7 @@ class FreeFlowSubProblem : public NavierStokesStaggeredProblem<TypeTag> #endif using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + static constexpr auto dimWorld = GridView::dimensionworld; using Scalar = GetPropType<TypeTag, Properties::Scalar>; using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>; using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; @@ -61,11 +65,11 @@ class FreeFlowSubProblem : public NavierStokesStaggeredProblem<TypeTag> #if EXNUMBER >= 1 using BoundaryTypes = Dumux::RANSBoundaryTypes<ModelTraits, ModelTraits::numEq()>; #else - using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, - Properties::ModelTraits>::numEq()>; + using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; #endif using FVGridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; using FVElementGeometry = typename FVGridGeometry::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; using Element = typename GridView::template Codim<0>::Entity; using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView; @@ -98,6 +102,21 @@ public: diffCoeffAvgType_ = StokesDarcyCouplingOptions::stringToEnum(DiffusionCoefficientAveragingType{}, getParamFromGroup<std::string>(this->paramGroup(), "Problem.InterfaceDiffusionCoefficientAvg")); +#if EXNUMBER >=1 + FluidSystem::init(); + Dumux::TurbulenceProperties<Scalar, dimWorld, true> turbulenceProperties; + FluidState fluidState; + const auto phaseIdx = 0; + fluidState.setPressure(phaseIdx, refPressure_); + fluidState.setTemperature(this->spatialParams().temperatureAtPos({})); + fluidState.setMassFraction(phaseIdx, phaseIdx, refMoleFrac_); + Scalar density = FluidSystem::density(fluidState, phaseIdx); + Scalar kinematicViscosity = FluidSystem::viscosity(fluidState, phaseIdx) / density; + Scalar diameter = this->gridGeometry().bBoxMax()[1] - this->gridGeometry().bBoxMin()[1]; + turbulentKineticEnergy_ = turbulenceProperties.turbulentKineticEnergy(refVelocity_, diameter, kinematicViscosity); + dissipation_ = turbulenceProperties.dissipationRate(refVelocity_, diameter, kinematicViscosity); +#endif + } /*! @@ -114,6 +133,20 @@ public: const auto& globalPos = scvf.center(); +#if EXNUMBER >=1 + if(onRightBoundary_(globalPos)) + { + values.setOutflow(Indices::turbulentKineticEnergyEqIdx); + values.setOutflow(Indices::dissipationEqIdx); + } + else + { + // walls and inflow + values.setDirichlet(Indices::turbulentKineticEnergyIdx); + values.setDirichlet(Indices::dissipationIdx); + } +#endif + if (onLeftBoundary_(globalPos)) { values.setDirichlet(Indices::velocityXIdx); @@ -169,20 +202,70 @@ public: values.setCouplingNeumann(Indices::momentumYBalanceIdx); values.setBeaversJoseph(Indices::momentumXBalanceIdx); } + return values; } /*! - * \brief Evaluate the boundary conditions for a Dirichlet control volume. + * \brief Evaluate the boundary conditions for a dirichlet values at the boundary. * - * \param element The element - * \param scvf The subcontrolvolume face + * \param element The finite element + * \param scvf the sub control volume face + * \note used for cell-centered discretization schemes */ - PrimaryVariables dirichletAtPos(const GlobalPosition& pos) const + PrimaryVariables dirichlet(const Element& element, const SubControlVolumeFace& scvf) const { - PrimaryVariables values(0.0); - values = initialAtPos(pos); + const auto globalPos = scvf.ipGlobal(); + PrimaryVariables values(initialAtPos(globalPos)); + return values; + } + /*! + * \brief Returns whether a fixed Dirichlet value shall be used at a given cell. + * + * \param element The finite element + * \param fvGeometry The finite-volume geometry + * \param scv The sub control volume + * \param pvIdx The primary variable index in the solution vector + */ + template<class Element, class FVElementGeometry, class SubControlVolume> + bool isDirichletCell(const Element& element, + const FVElementGeometry& fvGeometry, + const SubControlVolume& scv, + int pvIdx) const + { + if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::sst) + { + // For the komega model we set a fixed dissipation (omega) for all cells at the wall + for (const auto& scvf : scvfs(fvGeometry)) + if (this->boundaryTypes(element, scvf).hasWall() && pvIdx == Indices::dissipationIdx) + return true; + } + return false; + } + + /*! + * \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 + */ + PrimaryVariables dirichlet([[maybe_unused]] const Element& element, const SubControlVolume& scv) const + { + const auto globalPos = scv.center(); + PrimaryVariables values(initialAtPos(globalPos)); + unsigned int elementIdx = this->gridGeometry().elementMapper().index(element); + + if constexpr (ModelTraits::turbulenceModel() == TurbulenceModel::sst) + { + // 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; + } return values; } @@ -240,6 +323,25 @@ public: values[Indices::velocityXIdx] = refVelocity(); values[Indices::temperatureIdx] = refTemperature(); +#if EXNUMBER >= 1 + values[Indices::turbulentKineticEnergyIdx] = turbulentKineticEnergy_; + values[Indices::dissipationIdx] = dissipation_; +#endif + +#if EXNUMBER == 1 + if (onLowerBoundary_(globalPos) || onUpperBoundary_(globalPos)) + { + values[Indices::turbulentKineticEnergyIdx] = 0.0; + values[Indices::dissipationIdx] = 0.0; + } +#elif EXNUMBER >= 2 + if (onLowerBoundary_(globalPos) || onUpperBoundary_(globalPos)) + { + values[Indices::turbulentKineticEnergyIdx] = 0.0; + values[Indices::dissipationIdx] = 0.0; + } +#endif + #if EXNUMBER >= 2 if(onLowerBoundary_(globalPos)) values[Indices::velocityXIdx] = 0.0; @@ -340,6 +442,8 @@ private: Scalar refPressure_; Scalar refMoleFrac_; Scalar refTemperature_; + Scalar turbulentKineticEnergy_; + Scalar dissipation_; TimeLoopPtr timeLoop_; diff --git a/exercises/solution/exercise-coupling-ff-pm/turbulence/properties.hh b/exercises/solution/exercise-coupling-ff-pm/turbulence/properties.hh index 5389371e..3b6b962a 100644 --- a/exercises/solution/exercise-coupling-ff-pm/turbulence/properties.hh +++ b/exercises/solution/exercise-coupling-ff-pm/turbulence/properties.hh @@ -43,7 +43,7 @@ #include <dumux/discretization/staggered/freeflow/properties.hh> #if EXNUMBER >= 1 -#include <dumux/freeflow/compositional/zeroeqncmodel.hh> +#include <dumux/freeflow/compositional/sstncmodel.hh> #else #include <dumux/freeflow/compositional/navierstokesncmodel.hh> #endif @@ -56,7 +56,7 @@ namespace Dumux::Properties { namespace TTag { struct PorousMediumModel { using InheritsFrom = std::tuple<TwoPTwoCNI, CCTpfaModel>; }; #if EXNUMBER >= 1 -struct FreeflowModel { using InheritsFrom = std::tuple<ZeroEqNCNI, StaggeredFreeFlowModel>; }; +struct FreeflowModel { using InheritsFrom = std::tuple<SSTNCNI, StaggeredFreeFlowModel>; }; #else struct FreeflowModel { using InheritsFrom = std::tuple<NavierStokesNCNI, StaggeredFreeFlowModel>; }; #endif -- GitLab