diff --git a/doc/doxygen/modules.txt b/doc/doxygen/modules.txt index 475280dc7e6e65ccac1e1523a08f27c5e3f3f5aa..3958a6f442b9083c1cd0aef39e4a598c4776e3ab 100644 --- a/doc/doxygen/modules.txt +++ b/doc/doxygen/modules.txt @@ -196,6 +196,12 @@ * \brief Two-equation turbulence models * \copydetails ./freeflow/rans/model.hh */ + /*! + * \ingroup TwoEqModel + * \defgroup KEpsilonModel K-epsilon model + * \brief K-epsilon model + * \copydetails ./freeflow/rans/twoeq/kepsilon/model.hh + */ /*! * \ingroup TwoEqModel * \defgroup LowReKEpsilonModel Low-Re k-epsilon model diff --git a/dumux/freeflow/rans/twoeq/CMakeLists.txt b/dumux/freeflow/rans/twoeq/CMakeLists.txt index 445c7e40a012364eff119bcf5fe946d64761f461..ee8d7de6fc7399445c4ec478c02a4a856e8b926d 100644 --- a/dumux/freeflow/rans/twoeq/CMakeLists.txt +++ b/dumux/freeflow/rans/twoeq/CMakeLists.txt @@ -1 +1,2 @@ +add_subdirectory("kepsilon") add_subdirectory("lowrekepsilon") diff --git a/dumux/freeflow/rans/twoeq/kepsilon/CMakeLists.txt b/dumux/freeflow/rans/twoeq/kepsilon/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1f77d858e5177b169536da8dca85bb9d9f7052cb --- /dev/null +++ b/dumux/freeflow/rans/twoeq/kepsilon/CMakeLists.txt @@ -0,0 +1,11 @@ +#install headers +install(FILES +fluxvariables.hh +indices.hh +localresidual.hh +model.hh +# models.hh +problem.hh +volumevariables.hh +vtkoutputfields.hh +DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/freeflow/rans/twoeq/kepsilon) diff --git a/dumux/freeflow/rans/twoeq/kepsilon/fluxvariables.hh b/dumux/freeflow/rans/twoeq/kepsilon/fluxvariables.hh new file mode 100644 index 0000000000000000000000000000000000000000..ec1000024cefe7f6ae7190e203423d88153100cf --- /dev/null +++ b/dumux/freeflow/rans/twoeq/kepsilon/fluxvariables.hh @@ -0,0 +1,49 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + /*! + * \file + * \ingroup KEpsilonModel + * \copydoc Dumux::KEpsilonFluxVariables + */ +#ifndef DUMUX_KEPSILON_FLUXVARIABLES_HH +#define DUMUX_KEPSILON_FLUXVARIABLES_HH + +#include <dumux/common/properties.hh> +#include <dumux/freeflow/rans/twoeq/kepsilon/staggered/fluxvariables.hh> + +namespace Dumux +{ + +// forward declaration +template<class TypeTag, class BaseFluxVariables, DiscretizationMethod discMethod> +class KEpsilonFluxVariablesImpl; + +/*! + * \ingroup KEpsilonModel + * \brief The flux variables class for the k-epsilon model. + This is a convenience alias for that actual, + discretization-specific flux variables. + * \note Not all specializations are currently implemented + */ +template<class TypeTag, class BaseFluxVariables> +using KEpsilonFluxVariables = KEpsilonFluxVariablesImpl<TypeTag, BaseFluxVariables, GET_PROP_TYPE(TypeTag, FVGridGeometry)::discMethod>; + +} // end namespace + +#endif diff --git a/dumux/freeflow/rans/twoeq/kepsilon/indices.hh b/dumux/freeflow/rans/twoeq/kepsilon/indices.hh new file mode 100644 index 0000000000000000000000000000000000000000..98a2fb402e6950dcd15df878a8df6d75dec41180 --- /dev/null +++ b/dumux/freeflow/rans/twoeq/kepsilon/indices.hh @@ -0,0 +1,52 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \ingroup KEpsilonModel + * \copydoc Dumux::KEpsilonIndices + */ +#ifndef DUMUX_KEPSILON_INDICES_HH +#define DUMUX_KEPSILON_INDICES_HH + +#include <dumux/freeflow/navierstokes/indices.hh> + +namespace Dumux { + +// \{ +/*! + * \ingroup KEpsilonModel + * \brief The common indices for the isothermal k-epsilon model. + * + * \tparam dimension The dimension of the problem + * \tparam numComponents The number of considered transported components + */ +template<int dimension, int numComponents> +struct KEpsilonIndices : public NavierStokesIndices<dimension> +{ +public: + static constexpr auto turbulentKineticEnergyEqIdx = dimension + numComponents; + static constexpr auto turbulentKineticEnergyIdx = turbulentKineticEnergyEqIdx; + static constexpr auto dissipationEqIdx = turbulentKineticEnergyEqIdx + 1; + static constexpr auto dissipationIdx = dissipationEqIdx; +}; + +// \} +} // end namespace + +#endif diff --git a/dumux/freeflow/rans/twoeq/kepsilon/localresidual.hh b/dumux/freeflow/rans/twoeq/kepsilon/localresidual.hh new file mode 100644 index 0000000000000000000000000000000000000000..ac340be38d7e75eebef787d507a23b2ac2ef4e51 --- /dev/null +++ b/dumux/freeflow/rans/twoeq/kepsilon/localresidual.hh @@ -0,0 +1,51 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + /*! + * \file + * \ingroup KEpsilonModel + * \copydoc Dumux::KEpsilonResidual + */ +#ifndef DUMUX_KEPSILON_LOCAL_RESIDUAL_HH +#define DUMUX_KEPSILON_LOCAL_RESIDUAL_HH + +#include <dumux/common/properties.hh> +#include <dumux/discretization/methods.hh> +#include <dumux/freeflow/navierstokes/localresidual.hh> +#include <dumux/freeflow/rans/twoeq/kepsilon/staggered/localresidual.hh> + +namespace Dumux +{ + +// forward declaration +template<class TypeTag, class BaseLocalResidual, DiscretizationMethod discMethod> +class KEpsilonResidualImpl; + +/*! + * \ingroup KEpsilonModel + * \brief The local residual class for the k-epsilon model. + This is a convenience alias for the actual, + discretization-specific local residual. + * \note Not all specializations are currently implemented + */ +template<class TypeTag, class BaseLocalResidual> +using KEpsilonResidual = KEpsilonResidualImpl<TypeTag, BaseLocalResidual, GET_PROP_TYPE(TypeTag, FVGridGeometry)::discMethod>; + +} + +#endif diff --git a/dumux/freeflow/rans/twoeq/kepsilon/model.hh b/dumux/freeflow/rans/twoeq/kepsilon/model.hh new file mode 100644 index 0000000000000000000000000000000000000000..94f28bb80e95c47c06da955593dfaa59d3c3ae18 --- /dev/null +++ b/dumux/freeflow/rans/twoeq/kepsilon/model.hh @@ -0,0 +1,227 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \ingroup KEpsilonModel + * + * \brief A single-phase, isothermal k-epsilon model + * + * \copydoc RANSModel + * + * The k-epsilon models calculate the eddy viscosity with two additional PDEs, + * one for the turbulent kinetic energy (k) and for the dissipation (\f$ \varepsilon \f$). + * \todo fix everything below here + * The model uses the one proposed by Chien \cite Chien1982a. + * A good overview and additional models are given in Patel et al. \cite Patel1985a. + * + * The turbulent kinetic energy balance is identical with the one from the k-epsilon model, + * but the dissipation includes a dampening function (\f$ D_\varepsilon \f$): + * \f$ \varepsilon = \tilde{\varepsilon} + D_\varepsilon \f$: + * + * \f[ + * \frac{\partial \left( k \right)}{\partial t} + * + \nabla \cdot \left( \textbf{v} k \right) + * - \nabla \cdot \left( \left( \nu + \frac{\nu_\text{t}}{\sigma_\text{k}} \right) \nabla k \right) + * - 2 \nu_\text{t} \textbf{S} \cdot \textbf{S} + * + \tilde{\varepsilon} + * + D_\varepsilon + * = 0 + * \f]. + * + * The dissipation balance is changed by introducing additional functions + * (\f$ E_\text{k}\f$, \f$ f_1 \f$, and \f$ f_2 \f$) to account for a dampening towards the wall: + * \f[ + * \frac{\partial \left( \tilde{\varepsilon} \right)}{\partial t} + * + \nabla \cdot \left( \textbf{v} \tilde{\varepsilon} \right) + * - \nabla \cdot \left( \left( \nu + \frac{\nu_\text{t}}{\sigma_{\varepsilon}} \right) \nabla \tilde{\varepsilon} \right) + * - C_{1\tilde{\varepsilon}} f_1 \frac{\tilde{\varepsilon}}{k} 2 \nu_\text{t} \textbf{S} \cdot \textbf{S} + * + C_{2\tilde{\varepsilon}} f_2 \frac{\tilde{\varepsilon}^2}{k} + * - E_\text{k} + * = 0 + * \f]. + * + * The kinematic eddy viscosity \f$ \nu_\text{t} \f$ is dampened by \f$ f_\mu \f$: + * \f[ + * \nu_\text{t} = C_\mu f_\mu \frac{k^2}{\tilde{\varepsilon}} + * \f]. + * + * The auxiliary and dampening functions are defined as: + * \f[ D_\varepsilon = 2 \nu \nicefrac{k}{y^2} \f] + * \f[ E_\text{k} = -2 \nu \frac{\tilde{\varepsilon}}{y^2} \exp \left( -0.5 y^+ \right) \f] + * \f[ f_1 = 1 \f] + * \f[ f_2 = 1 - 0.22 \exp \left( - \left( \frac{\mathit{Re}_\text{t}}{6} \right)^2 \right) \f] + * \f[ f_\mu = 1 - \exp \left( -0.0115 y^+ \right) \f] + * \f[ \mathit{Re}_\text{t} = \frac{k^2}{\nu \tilde{\varepsilon}} \f] + * . + * + * Finally, the model is closed with the following constants: + * \f[ \sigma_\text{k} = 1.00 \f] + * \f[ \sigma_\varepsilon =1.30 \f] + * \f[ C_{1\tilde{\varepsilon}} = 1.35 \f] + * \f[ C_{2\tilde{\varepsilon}} = 1.80 \f] + * \f[ C_\mu = 0.09 \f] + */ + +#ifndef DUMUX_KEPSILON_MODEL_HH +#define DUMUX_KEPSILON_MODEL_HH + +#include <dumux/common/properties.hh> +#include <dumux/freeflow/properties.hh> +#include <dumux/freeflow/rans/model.hh> + +#include "fluxvariables.hh" +#include "indices.hh" +#include "localresidual.hh" +#include "volumevariables.hh" +#include "vtkoutputfields.hh" + +namespace Dumux +{ +namespace Properties { + +/*! + * \ingroup KEpsilonModel + * \brief Traits for the k-epsilon model + */ +template<int dimension> +struct KEpsilonModelTraits : RANSModelTraits<dimension> +{ + //! The dimension of the model + static constexpr int dim() { return dimension; } + + //! There are as many momentum balance equations as dimensions, + //! one mass balance equation and two turbulent transport equations + static constexpr int numEq() { return dim()+1+2; } + + //! The number of components + static constexpr int numComponents() { return 1; } + + //! the indices + using Indices = KEpsilonIndices<dim(), numComponents()>; +}; + +/////////////////////////////////////////////////////////////////////////// +// default property values for the isothermal k-epsilon model +/////////////////////////////////////////////////////////////////////////// + +//! The type tag for the single-phase, isothermal k-epsilon model +NEW_TYPE_TAG(KEpsilon, INHERITS_FROM(RANS)); + +//!< states some specifics of the isothermal k-epsilon model +SET_PROP(KEpsilon, ModelTraits) +{ +private: + using GridView = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::GridView; + static constexpr int dim = GridView::dimension; +public: + using type = KEpsilonModelTraits<dim>; +}; + +//! The flux variables +SET_PROP(KEpsilon, FluxVariables) +{ +private: + using BaseFluxVariables = NavierStokesFluxVariables<TypeTag>; +public: + using type = KEpsilonFluxVariables<TypeTag, BaseFluxVariables>; +}; + +//! The local residual +SET_PROP(KEpsilon, LocalResidual) +{ +private: + using BaseLocalResidual = NavierStokesResidual<TypeTag>; +public: + using type = KEpsilonResidual<TypeTag, BaseLocalResidual>; +}; + +//! Set the volume variables property +SET_PROP(KEpsilon, VolumeVariables) +{ +private: + using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); + + using Traits = NavierStokesVolumeVariablesTraits<PV, FSY, FST, MT>; + using NSVolVars = NavierStokesVolumeVariables<Traits>; +public: + using type = KEpsilonVolumeVariables<Traits, NSVolVars>; +}; + +//! The specific vtk output fields +SET_PROP(KEpsilon, VtkOutputFields) +{ +private: + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); +public: + using type = KEpsilonVtkOutputFields<FVGridGeometry>; +}; + +////////////////////////////////////////////////////////////////// +// default property values for the non-isothermal k-epsilon model +////////////////////////////////////////////////////////////////// + +//! The type tag for the single-phase, isothermal k-epsilon model +NEW_TYPE_TAG(KEpsilonNI, INHERITS_FROM(RANSNI)); + +//! The model traits of the non-isothermal model +SET_PROP(KEpsilonNI, ModelTraits) +{ +private: + using GridView = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::GridView; + static constexpr int dim = GridView::dimension; + using IsothermalTraits = KEpsilonModelTraits<dim>; +public: + using type = FreeflowNIModelTraits<IsothermalTraits>; +}; + +//! Set the volume variables property +SET_PROP(KEpsilonNI, VolumeVariables) +{ +private: + using PV = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using FSY = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FST = typename GET_PROP_TYPE(TypeTag, FluidState); + using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits); + + using Traits = NavierStokesVolumeVariablesTraits<PV, FSY, FST, MT>; + using NSVolVars = NavierStokesVolumeVariables<Traits>; +public: + using type = KEpsilonVolumeVariables<Traits, NSVolVars>; +}; + +//! The specific non-isothermal vtk output fields +SET_PROP(KEpsilonNI, VtkOutputFields) +{ +private: + using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using IsothermalFields = KEpsilonVtkOutputFields<FVGridGeometry>; +public: + using type = FreeflowNonIsothermalVtkOutputFields<IsothermalFields, ModelTraits>; +}; + +// \} +} + +} // end namespace + +#endif diff --git a/dumux/freeflow/rans/twoeq/kepsilon/problem.hh b/dumux/freeflow/rans/twoeq/kepsilon/problem.hh new file mode 100644 index 0000000000000000000000000000000000000000..db306e02dacf71993ca0d027952978715c763921 --- /dev/null +++ b/dumux/freeflow/rans/twoeq/kepsilon/problem.hh @@ -0,0 +1,134 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \ingroup KEpsilonModel + * \copydoc Dumux::KEpsilonProblem + */ +#ifndef DUMUX_REKEPSILON_PROBLEM_HH +#define DUMUX_REKEPSILON_PROBLEM_HH + +#include <dumux/common/properties.hh> +#include <dumux/common/staggeredfvproblem.hh> +#include <dumux/discretization/localview.hh> +#include <dumux/discretization/staggered/elementsolution.hh> +#include <dumux/discretization/methods.hh> +#include <dumux/freeflow/rans/problem.hh> + +#include "model.hh" + +namespace Dumux +{ + +/*! + * \ingroup KEpsilonModel + * \brief K-epsilon turbulence problem base class. + * + * This implements some base functionality for k-epsilon models. + */ +template<class TypeTag> +class KEpsilonProblem : public RANSProblem<TypeTag> +{ + using ParentType = RANSProblem<TypeTag>; + using Implementation = typename GET_PROP_TYPE(TypeTag, Problem); + + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; + + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables); + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + +public: + //! The constructor sets the gravity, if desired by the user. + KEpsilonProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry) + : ParentType(fvGridGeometry) + { + useStoredEddyViscosity_ = getParamFromGroup<bool>(this->paramGroup(), "RANS.UseStoredEddyViscosity", true); + } + + /*! + * \brief Correct size of the static (solution independent) wall variables + */ + void updateStaticWallProperties() + { + ParentType::updateStaticWallProperties(); + + // update size and initial values of the global vectors + storedDissipationTilde_.resize(this->fvGridGeometry().elementMapper().size(), 0.0); + storedDynamicEddyViscosity_.resize(this->fvGridGeometry().elementMapper().size(), 0.0); + storedTurbulentKineticEnergy_.resize(this->fvGridGeometry().elementMapper().size(), 0.0); + } + + /*! + * \brief Update the dynamic (solution dependent) relations to the walls + * + * \param curSol The solution vector. + */ + void updateDynamicWallProperties(const SolutionVector& curSol) + { + ParentType::updateDynamicWallProperties(curSol); + + for (const auto& element : elements(this->fvGridGeometry().gridView())) + { + unsigned int elementID = this->fvGridGeometry().elementMapper().index(element); + + auto fvGeometry = localView(this->fvGridGeometry()); + fvGeometry.bindElement(element); + for (auto&& scv : scvs(fvGeometry)) + { + const int dofIdx = scv.dofIndex(); + const auto& cellCenterPriVars = curSol[FVGridGeometry::cellCenterIdx()][dofIdx]; + PrimaryVariables priVars = makePriVarsFromCellCenterPriVars<PrimaryVariables>(cellCenterPriVars); + auto elemSol = elementSolution<typename FVGridGeometry::LocalView>(std::move(priVars)); + // NOTE: first update the turbulence quantities + storedDissipationTilde_[elementID] = elemSol[0][Indices::dissipationEqIdx]; + storedTurbulentKineticEnergy_[elementID] = elemSol[0][Indices::turbulentKineticEnergyEqIdx]; + // NOTE: then update the volVars + VolumeVariables volVars; + volVars.update(elemSol, asImp_(), element, scv); + storedDynamicEddyViscosity_[elementID] = volVars.calculateEddyViscosity(); + } + } + } + +public: + std::vector<Scalar> storedDissipationTilde_; + std::vector<Scalar> storedDynamicEddyViscosity_; + std::vector<Scalar> storedTurbulentKineticEnergy_; + bool useStoredEddyViscosity_; + +private: + //! Returns the implementation of the problem (i.e. static polymorphism) + Implementation &asImp_() + { return *static_cast<Implementation *>(this); } + + //! \copydoc asImp_() + const Implementation &asImp_() const + { return *static_cast<const Implementation *>(this); } +}; + +} + +#endif diff --git a/dumux/freeflow/rans/twoeq/kepsilon/staggered/CMakeLists.txt b/dumux/freeflow/rans/twoeq/kepsilon/staggered/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..bbbf90a8c6582d728da226f48e959d3d1a164feb --- /dev/null +++ b/dumux/freeflow/rans/twoeq/kepsilon/staggered/CMakeLists.txt @@ -0,0 +1,5 @@ +#install headers +install(FILES +fluxvariables.hh +localresidual.hh +DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/freeflow/rans/twoeq/kepsilon/staggered) diff --git a/dumux/freeflow/rans/twoeq/kepsilon/staggered/fluxvariables.hh b/dumux/freeflow/rans/twoeq/kepsilon/staggered/fluxvariables.hh new file mode 100644 index 0000000000000000000000000000000000000000..157ab58f3d49992823e77ca6e1cba9943d1df7f0 --- /dev/null +++ b/dumux/freeflow/rans/twoeq/kepsilon/staggered/fluxvariables.hh @@ -0,0 +1,172 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + /*! + * \file + * \ingroup KEpsilonModel + * \copydoc Dumux::KEpsilonFluxVariablesImpl + */ +#ifndef DUMUX_KEPSILON_STAGGERED_FLUXVARIABLES_HH +#define DUMUX_KEPSILON_STAGGERED_FLUXVARIABLES_HH + +#include <numeric> +#include <dumux/common/properties.hh> +#include <dumux/discretization/fluxvariablesbase.hh> +#include <dumux/discretization/methods.hh> +#include <dumux/freeflow/navierstokes/fluxvariables.hh> +#include <dumux/freeflow/rans/twoeq/kepsilon/fluxvariables.hh> + +namespace Dumux +{ + +// forward declaration +template<class TypeTag, class BaseFluxVariables, DiscretizationMethod discMethod> +class KEpsilonFluxVariablesImpl; + +/*! + * \ingroup KEpsilonModel + * \brief The flux variables class for the k-epsilon model using the staggered grid discretization. + */ +template<class TypeTag, class BaseFluxVariables> +class KEpsilonFluxVariablesImpl<TypeTag, BaseFluxVariables, DiscretizationMethod::staggered> +: public BaseFluxVariables +{ + using ParentType = BaseFluxVariables; + + using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables); + + using GridVolumeVariables = typename GridVariables::GridVolumeVariables; + using ElementVolumeVariables = typename GridVolumeVariables::LocalView; + using VolumeVariables = typename GridVolumeVariables::VolumeVariables; + + using GridFluxVariablesCache = typename GridVariables::GridFluxVariablesCache; + using FluxVariablesCache = typename GridFluxVariablesCache::FluxVariablesCache; + + using GridFaceVariables = typename GridVariables::GridFaceVariables; + using ElementFaceVariables = typename GridFaceVariables::LocalView; + using FaceVariables = typename GridFaceVariables::FaceVariables; + + using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using Element = typename GridView::template Codim<0>::Entity; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; + using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables); + + enum { + turbulentKineticEnergyEqIdx = Indices::turbulentKineticEnergyEqIdx, + dissipationEqIdx = Indices::dissipationEqIdx, + }; + +public: + + /*! + * \brief Computes the flux for the cell center residual. + */ + CellCenterPrimaryVariables computeMassFlux(const Problem& problem, + const Element &element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const ElementFaceVariables& elemFaceVars, + const SubControlVolumeFace &scvf, + const FluxVariablesCache& fluxVarsCache) + { + CellCenterPrimaryVariables flux = ParentType::computeMassFlux(problem, element, fvGeometry, + elemVolVars, elemFaceVars, scvf, fluxVarsCache); + + // calculate advective flux + auto upwindTermK = [](const auto& volVars) + { + return volVars.turbulentKineticEnergy(); + }; + auto upwindTermEpsilon = [](const auto& volVars) + { + return volVars.dissipationTilde(); + }; + + flux[turbulentKineticEnergyEqIdx - ModelTraits::dim()] + = ParentType::advectiveFluxForCellCenter(problem, elemVolVars, elemFaceVars, scvf, upwindTermK); + flux[dissipationEqIdx - ModelTraits::dim()] + = ParentType::advectiveFluxForCellCenter(problem, elemVolVars, elemFaceVars, scvf, upwindTermEpsilon); + + // calculate diffusive flux + const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx()); + const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx()); + const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()]; + const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()]; + + // effective diffusion coefficients + Scalar insideCoeff_k = insideVolVars.kinematicViscosity() + + insideVolVars.kinematicEddyViscosity() / insideVolVars.sigmaK(); + Scalar outsideCoeff_k = outsideVolVars.kinematicViscosity() + + outsideVolVars.kinematicEddyViscosity() / outsideVolVars.sigmaK(); + Scalar insideCoeff_e = insideVolVars.kinematicViscosity() + + insideVolVars.kinematicEddyViscosity() / insideVolVars.sigmaEpsilon(); + Scalar outsideCoeff_e = outsideVolVars.kinematicViscosity() + + outsideVolVars.kinematicEddyViscosity() / outsideVolVars.sigmaEpsilon(); + + // scale by extrusion factor + insideCoeff_k *= insideVolVars.extrusionFactor(); + outsideCoeff_k *= outsideVolVars.extrusionFactor(); + insideCoeff_e *= insideVolVars.extrusionFactor(); + outsideCoeff_e *= outsideVolVars.extrusionFactor(); + + // average and distance + Scalar coeff_k = (insideCoeff_k + outsideCoeff_k) * 0.5; + Scalar coeff_e = (insideCoeff_e + outsideCoeff_e) * 0.5; + Scalar distance = 0.0; + + // adapt boundary handling + if (scvf.boundary()) + { + distance = (insideScv.dofPosition() - scvf.ipGlobal()).two_norm(); + coeff_k = insideCoeff_k; + coeff_e = insideCoeff_e; + } + else + { + distance = (outsideScv.dofPosition() - insideScv.dofPosition()).two_norm(); + } + + const auto bcTypes = problem.boundaryTypes(element, scvf); + if (!(scvf.boundary() && (bcTypes.isOutflow(turbulentKineticEnergyEqIdx) + || bcTypes.isSymmetry()))) + { + flux[turbulentKineticEnergyEqIdx - ModelTraits::dim()] + += coeff_k / distance + * (insideVolVars.turbulentKineticEnergy() - outsideVolVars.turbulentKineticEnergy()) + * scvf.area(); + } + if (!(scvf.boundary() && (bcTypes.isOutflow(dissipationEqIdx) + || bcTypes.isSymmetry()))) + { + flux[dissipationEqIdx - ModelTraits::dim()] + += coeff_e / distance + * (insideVolVars.dissipationTilde() - outsideVolVars.dissipationTilde()) + * scvf.area(); + } + return flux; + } +}; + +} // end namespace + +#endif diff --git a/dumux/freeflow/rans/twoeq/kepsilon/staggered/localresidual.hh b/dumux/freeflow/rans/twoeq/kepsilon/staggered/localresidual.hh new file mode 100644 index 0000000000000000000000000000000000000000..608a0274b54a28d546ca8f8bb5ca5cf244ae799e --- /dev/null +++ b/dumux/freeflow/rans/twoeq/kepsilon/staggered/localresidual.hh @@ -0,0 +1,128 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ + /*! + * \file + * \ingroup KepsilonModel + * \copydoc Dumux::KepsilonResidualImpl + */ +#ifndef DUMUX_STAGGERED_KEPSILON_LOCAL_RESIDUAL_HH +#define DUMUX_STAGGERED_KEPSILON_LOCAL_RESIDUAL_HH + +#include <dune/common/hybridutilities.hh> +#include <dumux/common/properties.hh> +#include <dumux/discretization/methods.hh> +#include <dumux/freeflow/navierstokes/localresidual.hh> + +namespace Dumux { + +// forward declaration +template<class TypeTag, class BaseLocalResidual, DiscretizationMethod discMethod> +class KEpsilonResidualImpl; + +/*! + * \ingroup KEpsilonModel + * \brief Element-wise calculation of the residual for k-epsilon models using the staggered discretization + */ +template<class TypeTag, class BaseLocalResidual> +class KEpsilonResidualImpl<TypeTag, BaseLocalResidual, DiscretizationMethod::staggered> +: public BaseLocalResidual +{ + using ParentType = BaseLocalResidual; + + using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables); + + using GridVolumeVariables = typename GridVariables::GridVolumeVariables; + using ElementVolumeVariables = typename GridVolumeVariables::LocalView; + using VolumeVariables = typename GridVolumeVariables::VolumeVariables; + + using GridFluxVariablesCache = typename GridVariables::GridFluxVariablesCache; + using ElementFluxVariablesCache = typename GridFluxVariablesCache::LocalView; + using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); + + using GridFaceVariables = typename GridVariables::GridFaceVariables; + using ElementFaceVariables = typename GridFaceVariables::LocalView; + + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Element = typename GridView::template Codim<0>::Entity; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using CellCenterPrimaryVariables = typename GET_PROP_TYPE(TypeTag, CellCenterPrimaryVariables); + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); + +public: + using ParentType::ParentType; + + //! Evaluate fluxes entering or leaving the cell center control volume. + CellCenterPrimaryVariables computeStorageForCellCenter(const Problem& problem, + const SubControlVolume& scv, + const VolumeVariables& volVars) const + { + CellCenterPrimaryVariables storage = ParentType::computeStorageForCellCenter(problem, scv, volVars); + + static constexpr int turbulentKineticEnergyEqIdx = Indices::turbulentKineticEnergyEqIdx - ModelTraits::dim(); + static constexpr int dissipationEqIdx = Indices::dissipationEqIdx - ModelTraits::dim(); + storage[turbulentKineticEnergyEqIdx] = volVars.turbulentKineticEnergy(); + storage[dissipationEqIdx] = volVars.dissipationTilde(); + + return storage; + } + + CellCenterPrimaryVariables computeSourceForCellCenter(const Problem& problem, + const Element &element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const ElementFaceVariables& elemFaceVars, + const SubControlVolume &scv) const + { + CellCenterPrimaryVariables source = ParentType::computeSourceForCellCenter(problem, element, fvGeometry, + elemVolVars, elemFaceVars, scv); + + const auto& volVars = elemVolVars[scv]; + + static constexpr int turbulentKineticEnergyEqIdx = Indices::turbulentKineticEnergyEqIdx - ModelTraits::dim(); + static constexpr int dissipationEqIdx = Indices::dissipationEqIdx - ModelTraits::dim(); + + // production + source[turbulentKineticEnergyEqIdx] += 2.0 * volVars.kinematicEddyViscosity() + * volVars.stressTensorScalarProduct(); + source[dissipationEqIdx] += volVars.cOneEpsilon() * volVars.fOne() + * volVars.dissipationTilde() / volVars.turbulentKineticEnergy() + * 2.0 * volVars.kinematicEddyViscosity() + * volVars.stressTensorScalarProduct(); + + // destruction + source[turbulentKineticEnergyEqIdx] -= volVars.dissipationTilde(); + source[dissipationEqIdx] -= volVars.cTwoEpsilon() * volVars.fTwo() + * volVars.dissipationTilde() * volVars.dissipationTilde() + / volVars.turbulentKineticEnergy(); + + // dampening functions + source[turbulentKineticEnergyEqIdx] -= volVars.dValue(); + source[dissipationEqIdx] += volVars.eValue(); + + return source; + } +}; +} + +#endif diff --git a/dumux/freeflow/rans/twoeq/kepsilon/volumevariables.hh b/dumux/freeflow/rans/twoeq/kepsilon/volumevariables.hh new file mode 100644 index 0000000000000000000000000000000000000000..83fa48cc592d7f660a1d9b5175ae63f553663cbc --- /dev/null +++ b/dumux/freeflow/rans/twoeq/kepsilon/volumevariables.hh @@ -0,0 +1,293 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \ingroup KEpsilonModel + * + * \copydoc Dumux::KEpsilonVolumeVariables + */ +#ifndef DUMUX_KEPSILON_VOLUME_VARIABLES_HH +#define DUMUX_KEPSILON_VOLUME_VARIABLES_HH + +#include <dumux/common/properties.hh> +#include <dumux/common/parameters.hh> +#include <dumux/material/fluidstates/immiscible.hh> +#include <dumux/freeflow/rans/volumevariables.hh> + +namespace Dumux +{ + +/*! + * \ingroup KEpsilonModel + * \brief Volume variables for the isothermal single-phase k-epsilon model. + */ +template <class Traits, class NSVolumeVariables> +class KEpsilonVolumeVariables +: public RANSVolumeVariables< Traits, KEpsilonVolumeVariables<Traits, NSVolumeVariables> > +, public NSVolumeVariables +{ + using ThisType = KEpsilonVolumeVariables<Traits, NSVolumeVariables>; + using RANSParentType = RANSVolumeVariables<Traits, ThisType>; + using NavierStokesParentType = NSVolumeVariables; + + using Scalar = typename Traits::PrimaryVariables::value_type; + + static constexpr bool enableEnergyBalance = Traits::ModelTraits::enableEnergyBalance(); + static constexpr int fluidSystemPhaseIdx = Traits::ModelTraits::Indices::fluidSystemPhaseIdx; + +public: + //! export the underlying fluid system + using FluidSystem = typename Traits::FluidSystem; + //! export the indices type + using Indices = typename Traits::ModelTraits::Indices; + + /*! + * \brief Update all quantities for a given control volume + * + * \param elemSol A vector containing all primary variables connected to the element + * \param problem The object specifying the problem which ought to + * be simulated + * \param element An element which contains part of the control volume + * \param scv The sub-control volume + */ + template<class ElementSolution, class Problem, class Element, class SubControlVolume> + void update(const ElementSolution &elemSol, + const Problem &problem, + const Element &element, + const SubControlVolume& scv) + { + NavierStokesParentType::update(elemSol, problem, element, scv); + updateRANSProperties(elemSol, problem, element, scv); + } + + /*! + * \brief Update all turbulent quantities for a given control volume + * + * Wall and roughness related quantities are stored. Eddy viscosity is set. + * + * \param elemSol A vector containing all primary variables connected to the element + * \param problem The object specifying the problem which ought to be simulated + * \param element An element which contains part of the control volume + * \param scv The sub-control volume + */ + template<class ElementSolution, class Problem, class Element, class SubControlVolume> + void updateRANSProperties(const ElementSolution &elemSol, + const Problem &problem, + const Element &element, + const SubControlVolume& scv) + { + RANSParentType::updateRANSProperties(elemSol, problem, element, scv); + turbulentKineticEnergy_ = elemSol[0][Indices::turbulentKineticEnergyIdx]; + dissipationTilde_ = elemSol[0][Indices::dissipationIdx]; + storedDissipationTilde_ = problem.storedDissipationTilde_[RANSParentType::elementID()]; + storedTurbulentKineticEnergy_ = problem.storedTurbulentKineticEnergy_[RANSParentType::elementID()]; + stressTensorScalarProduct_ = problem.stressTensorScalarProduct_[RANSParentType::elementID()]; + if (problem.useStoredEddyViscosity_) + dynamicEddyViscosity_ = problem.storedDynamicEddyViscosity_[RANSParentType::elementID()]; + else + dynamicEddyViscosity_ = calculateEddyViscosity(); + calculateEddyDiffusivity(problem); + } + + /*! + * \brief Return the dynamic eddy viscosity \f$\mathrm{[Pa s]}\f$ of the flow + */ + Scalar dynamicEddyViscosity() const + { return dynamicEddyViscosity_; } + + /*! + * \brief Return the effective dynamic viscosity \f$\mathrm{[Pa s]}\f$ of the fluid within the + * control volume. + */ + Scalar effectiveViscosity() const + { return NavierStokesParentType::viscosity() + dynamicEddyViscosity(); } + + /*! + * \brief Returns the effective thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ + * of the fluid-flow in the sub-control volume. + */ + template<bool eB = enableEnergyBalance, typename std::enable_if_t<eB, int> = 0> + Scalar effectiveThermalConductivity() const + { + return NavierStokesParentType::thermalConductivity() + + RANSParentType::eddyThermalConductivity(); + } + + /*! + * \brief Returns the dynamic eddy viscosity \f$\mathrm{[Pa s]}\f$. + */ + Scalar calculateEddyViscosity() + { + return cMu() * fMu() * turbulentKineticEnergy() * turbulentKineticEnergy() + / dissipationTilde() * NavierStokesParentType::density(); + } + + /*! + * \brief Calculates the eddy diffusivity \f$\mathrm{[m^2/s]}\f$ based + * on the kinematic eddy viscosity and the turbulent schmidt number + */ + template<class Problem> + void calculateEddyDiffusivity(const Problem& problem) + { + static const auto turbulentSchmidtNumber + = getParamFromGroup<Scalar>(problem.paramGroup(), + "RANS.TurbulentSchmidtNumber", 1.0); + eddyDiffusivity_ = RANSParentType::kinematicEddyViscosity() / turbulentSchmidtNumber; + } + + /*! + * \brief Returns the turbulent kinetic energy \f$ m^2/s^2 \f$ + */ + Scalar turbulentKineticEnergy() const + { + return turbulentKineticEnergy_; + } + + /*! + * \brief Returns an effective dissipation \f$ m^2/s^3 \f$ + */ + Scalar dissipationTilde() const + { + return dissipationTilde_; + } + + /*! + * \brief Returns the turbulent kinetic energy \f$ m^2/s^2 \f$ + */ + Scalar storedTurbulentKineticEnergy() const + { + return storedTurbulentKineticEnergy_; + } + + /*! + * \brief Returns an effective dissipation \f$ m^2/s^3 \f$ + */ + Scalar storedDissipationTilde() const + { + return storedDissipationTilde_; + } + + /*! + * \brief Returns the scalar product of the stress tensor + */ + Scalar stressTensorScalarProduct() const + { + return stressTensorScalarProduct_; + } + + //! \brief Returns the \$f Re_\textrm{T} \$f value + const Scalar reT() const + { + return turbulentKineticEnergy() * turbulentKineticEnergy() + / RANSParentType::kinematicViscosity() / dissipationTilde(); + } + + //! \brief Returns the \$f Re_\textrm{y} \$f value + const Scalar reY() const + { + using std::sqrt; + return sqrt(turbulentKineticEnergy()) * RANSParentType::wallDistance() + / RANSParentType::kinematicViscosity(); + } + + //! \brief Returns the \$f C_\mu \$f constant + const Scalar cMu() const + { return 0.09; } + + //! \brief Returns the \$f \sigma_\textrm{k} \$f constant + const Scalar sigmaK() const + { return 1.0; } + + //! \brief Returns the \$f \sigma_\varepsilon \$f constant + const Scalar sigmaEpsilon() const + { return 1.3; } + + //! \brief Returns the \$f C_{1\tilde{\varepsilon}} \$f constant + const Scalar cOneEpsilon() const + { return 1.35; } + + //! \brief Returns the \$f C_{2\tilde{\varepsilon}} \$f constant + const Scalar cTwoEpsilon() const + { return 1.8; } + + //! \brief Returns the \$f D \$f value + const Scalar dValue() const + { + return 2.0 * RANSParentType::kinematicViscosity() * turbulentKineticEnergy() + / RANSParentType::wallDistance() / RANSParentType::wallDistance(); + } + + //! \brief Returns the \$f f_\mu \$f value + const Scalar fMu() const + { + using std::exp; + using std::pow; + return 1.0 - exp(-0.0115 * RANSParentType::yPlus()); + } + + //! \brief Returns the \$f f_1 \$f value + const Scalar fOne() const + { return 1.0; } + + //! \brief Returns the \$f f_2 \$f value + const Scalar fTwo() const + { + using std::exp; + return 1.0 - 0.22 * exp(-1.0 * (reT() * reT() / 6.0 / 6.0)); + } + + //! \brief Returns the \$f E \$f value + const Scalar eValue() const + { + using std::exp; + return -2.0 * RANSParentType::kinematicViscosity() * dissipationTilde() + / RANSParentType::wallDistance() / RANSParentType::wallDistance() + * exp(-0.5 * RANSParentType::yPlus()); + } + + /*! + * \brief Returns the eddy diffusivity \f$\mathrm{[m^2/s]}\f$ + */ + Scalar eddyDiffusivity() const + { return eddyDiffusivity_; } + + /*! + * \brief Returns the effective diffusion coefficient \f$\mathrm{[m^2/s]}\f$ + * + * \param compIIdx the index of the component which diffusive + * \param compJIdx the index of the component with respect to which compIIdx diffuses + */ + Scalar effectiveDiffusivity(int compIIdx, int compJIdx = fluidSystemPhaseIdx) const + { + return NavierStokesParentType::diffusionCoefficient(compIIdx, compJIdx) + eddyDiffusivity(); + } + +protected: + Scalar dynamicEddyViscosity_; + Scalar eddyDiffusivity_; + Scalar turbulentKineticEnergy_; + Scalar dissipationTilde_; + Scalar storedTurbulentKineticEnergy_; + Scalar storedDissipationTilde_; + Scalar stressTensorScalarProduct_; +}; + +} + +#endif diff --git a/dumux/freeflow/rans/twoeq/kepsilon/vtkoutputfields.hh b/dumux/freeflow/rans/twoeq/kepsilon/vtkoutputfields.hh new file mode 100644 index 0000000000000000000000000000000000000000..3250528b447e47246fcd2895c19c70d5cb321218 --- /dev/null +++ b/dumux/freeflow/rans/twoeq/kepsilon/vtkoutputfields.hh @@ -0,0 +1,61 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \ingroup KEpsilonModel + * \copydoc Dumux::KEpsilonVtkOutputFields + */ +#ifndef DUMUX_KEPSILON_VTK_OUTPUT_FIELDS_HH +#define DUMUX_KEPSILON_VTK_OUTPUT_FIELDS_HH + +#include <dumux/freeflow/rans/vtkoutputfields.hh> + +namespace Dumux +{ + +/*! + * \ingroup KEpsilonModel + * \brief Adds vtk output fields for the k-epsilon turbulence model + */ +template<class FVGridGeometry> +class KEpsilonVtkOutputFields : public RANSVtkOutputFields<FVGridGeometry> +{ + enum { dim = FVGridGeometry::GridView::dimension }; + +public: + //! Initialize the Reynolds-averaged Navier-Stokes specific vtk output fields. + template <class VtkOutputModule> + static void init(VtkOutputModule& vtk) + { + RANSVtkOutputFields<FVGridGeometry>::init(vtk); + add(vtk); + } + + //! Add the KEpsilon specific vtk output fields. + template <class VtkOutputModule> + static void add(VtkOutputModule& vtk) + { + vtk.addVolumeVariable([](const auto& v){ return v.turbulentKineticEnergy(); }, "k"); + vtk.addVolumeVariable([](const auto& v){ return v.dissipationTilde(); }, "epsilon"); + } +}; + +} // end namespace Dumux + +#endif diff --git a/test/freeflow/rans/CMakeLists.txt b/test/freeflow/rans/CMakeLists.txt index 4b69582c8c6def5e2ca12331bdd3a37bc9030087..1be433a716a78c7d57817170c2ff4986a10b1854 100644 --- a/test/freeflow/rans/CMakeLists.txt +++ b/test/freeflow/rans/CMakeLists.txt @@ -10,6 +10,16 @@ dune_add_test(NAME test_pipe_laufer_zeroeq ${CMAKE_CURRENT_BINARY_DIR}/pipe_laufer_reference-00044.vtu --command "${CMAKE_CURRENT_BINARY_DIR}/test_pipe_laufer_zeroeq test_pipe_laufer_reference.input") +dune_add_test(NAME test_pipe_laufer_kepsilon + SOURCES test_pipe_laufer.cc + CMAKE_GUARD HAVE_UMFPACK + COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/test/references/pipe_laufer_lowrekepsilon.vtu + ${CMAKE_CURRENT_BINARY_DIR}/pipe_laufer_reference-00064.vtu + --command "${CMAKE_CURRENT_BINARY_DIR}/test_pipe_laufer_kepsilon test_pipe_laufer_reference.input") +target_compile_definitions(test_pipe_laufer_kepsilon PUBLIC "KEPSILON=1") + dune_add_test(NAME test_pipe_laufer_lowrekepsilon SOURCES test_pipe_laufer.cc CMAKE_GUARD HAVE_UMFPACK diff --git a/test/freeflow/rans/pipelauferproblem.hh b/test/freeflow/rans/pipelauferproblem.hh index 20d939fe8e8599f572a04ff7c01f055226849369..b718aba8c7847ab97886ba19f7b11558154290f2 100644 --- a/test/freeflow/rans/pipelauferproblem.hh +++ b/test/freeflow/rans/pipelauferproblem.hh @@ -27,6 +27,7 @@ #ifndef DUMUX_PIPE_LAUFER_PROBLEM_HH #define DUMUX_PIPE_LAUFER_PROBLEM_HH +#include <dumux/discretization/staggered/freeflow/properties.hh> #include <dumux/freeflow/turbulenceproperties.hh> #include <dumux/material/fluidsystems/1pgas.hh> #include <dumux/material/components/air.hh> @@ -34,11 +35,13 @@ #if LOWREKEPSILON #include <dumux/freeflow/rans/twoeq/lowrekepsilon/model.hh> #include <dumux/freeflow/rans/twoeq/lowrekepsilon/problem.hh> +#elif KEPSILON +#include <dumux/freeflow/rans/twoeq/kepsilon/model.hh> +#include <dumux/freeflow/rans/twoeq/kepsilon/problem.hh> #else #include <dumux/freeflow/rans/zeroeq/model.hh> #include <dumux/freeflow/rans/zeroeq/problem.hh> #endif -#include <dumux/discretization/staggered/freeflow/properties.hh> namespace Dumux { @@ -52,6 +55,8 @@ NEW_TYPE_TAG(PipeLauferProblem, INHERITS_FROM(StaggeredFreeFlowModel, ZeroEqNI)) #else #if LOWREKEPSILON NEW_TYPE_TAG(PipeLauferProblem, INHERITS_FROM(StaggeredFreeFlowModel, LowReKEpsilon)); +#elif KEPSILON +NEW_TYPE_TAG(PipeLauferProblem, INHERITS_FROM(StaggeredFreeFlowModel, KEpsilon)); #else NEW_TYPE_TAG(PipeLauferProblem, INHERITS_FROM(StaggeredFreeFlowModel, ZeroEq)); #endif @@ -89,6 +94,10 @@ template <class TypeTag> class PipeLauferProblem : public LowReKEpsilonProblem<TypeTag> { using ParentType = LowReKEpsilonProblem<TypeTag>; +#elif KEPSILON +class PipeLauferProblem : public KEpsilonProblem<TypeTag> +{ + using ParentType = KEpsilonProblem<TypeTag>; #else class PipeLauferProblem : public ZeroEqProblem<TypeTag> { @@ -197,7 +206,7 @@ public: values.setOutflow(Indices::energyBalanceIdx); #endif -#if LOWREKEPSILON +#if LOWREKEPSILON || KEPSILON values.setOutflow(Indices::turbulentKineticEnergyEqIdx); values.setOutflow(Indices::dissipationEqIdx); #endif @@ -211,7 +220,7 @@ public: values.setDirichlet(Indices::temperatureIdx); #endif -#if LOWREKEPSILON +#if LOWREKEPSILON || KEPSILON values.setDirichlet(Indices::turbulentKineticEnergyIdx); values.setDirichlet(Indices::dissipationIdx); #endif @@ -271,7 +280,7 @@ public: } #endif -#if LOWREKEPSILON +#if LOWREKEPSILON || KEPSILON if (time() < eps_ && startWithZeroVelocity_) { values[Indices::velocityXIdx] = 0.0;