Line | Branch | Exec | Source |
---|---|---|---|
1 | // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- | ||
2 | // vi: set et ts=4 sw=4 sts=4: | ||
3 | // | ||
4 | // SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder | ||
5 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
6 | // | ||
7 | /*! | ||
8 | * \file | ||
9 | * \ingroup RANSModel | ||
10 | * | ||
11 | * \copydoc Dumux::RANSVolumeVariables | ||
12 | */ | ||
13 | #ifndef DUMUX_RANS_VOLUME_VARIABLES_HH | ||
14 | #define DUMUX_RANS_VOLUME_VARIABLES_HH | ||
15 | |||
16 | #include <dune/common/fvector.hh> | ||
17 | #include <dune/common/fmatrix.hh> | ||
18 | |||
19 | #include <dumux/common/parameters.hh> | ||
20 | |||
21 | namespace Dumux { | ||
22 | |||
23 | /*! | ||
24 | * \ingroup RANSModel | ||
25 | * \brief Volume variables for the isothermal single-phase Reynolds-Averaged Navier-Stokes models. | ||
26 | */ | ||
27 | template <class Traits, class NSVolumeVariables> | ||
28 | class RANSVolumeVariables | ||
29 | : public NSVolumeVariables | ||
30 | { | ||
31 | using NavierStokesParentType = NSVolumeVariables; | ||
32 | |||
33 | using Scalar = typename Traits::PrimaryVariables::value_type; | ||
34 | |||
35 | enum { dimWorld = Traits::ModelTraits::dim() }; | ||
36 | using DimVector = Dune::FieldVector<Scalar, dimWorld>; | ||
37 | using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>; | ||
38 | |||
39 | static constexpr bool enableEnergyBalance = Traits::ModelTraits::enableEnergyBalance(); | ||
40 | |||
41 | public: | ||
42 | |||
43 | /*! | ||
44 | * \brief Update all quantities for a given control volume | ||
45 | * | ||
46 | * \param elemSol A vector containing all primary variables connected to the element | ||
47 | * \param problem The object specifying the problem which ought to | ||
48 | * be simulated | ||
49 | * \param element An element which contains part of the control volume | ||
50 | * \param scv The sub-control volume | ||
51 | */ | ||
52 | template<class ElementSolution, class Problem, class Element, class SubControlVolume> | ||
53 | 70712512 | void updateNavierStokesVolVars(const ElementSolution &elemSol, | |
54 | const Problem &problem, | ||
55 | const Element &element, | ||
56 | const SubControlVolume& scv) | ||
57 | { | ||
58 | 98292464 | NavierStokesParentType::update(elemSol, problem, element, scv); | |
59 | } | ||
60 | |||
61 | /*! | ||
62 | * \brief Update all turbulent quantities for a given control volume | ||
63 | * | ||
64 | * Wall related quantities are stored and the calculateEddyViscosity(...) | ||
65 | * function of the turbulence model implementation is called. | ||
66 | * | ||
67 | * \param elemSol A vector containing all primary variables connected to the element | ||
68 | * \param problem The object specifying the problem which ought to be simulated | ||
69 | * \param element An element which contains part of the control volume | ||
70 | * \param scv The sub-control volume | ||
71 | */ | ||
72 | template<class ElementSolution, class Problem, class Element, class SubControlVolume> | ||
73 | 98295864 | void updateRANSProperties(const ElementSolution &elemSol, | |
74 | const Problem &problem, | ||
75 | const Element &element, | ||
76 | const SubControlVolume& scv) | ||
77 | { | ||
78 | using std::abs; | ||
79 | using std::max; | ||
80 | using std::sqrt; | ||
81 | |||
82 | // calculate characteristic properties of the turbulent flow | ||
83 | 98295864 | elementIdx_ = problem.gridGeometry().elementMapper().index(element); | |
84 | 98295864 | wallDistance_ = problem.wallDistance(elementIdx_); | |
85 | 98295864 | ccVelocityVector_ = problem.ccVelocityVector(elementIdx_); | |
86 | 98295864 | velocityGradientTensor_ = problem.velocityGradientTensor(elementIdx_); | |
87 | |||
88 | 98295864 | karmanConstant_ = problem.karmanConstant(); | |
89 | 98295864 | velocityMaximum_ = problem.velocityMaximum(elementIdx_); | |
90 | 98295864 | velocityMinimum_ = problem.velocityMinimum(elementIdx_); | |
91 |
2/2✓ Branch 1 taken 85352816 times.
✓ Branch 2 taken 12939648 times.
|
98295864 | if (problem.isFlatWallBounded()) |
92 | { | ||
93 | 85356216 | const auto flowDirectionAxis = problem.flowDirectionAxis(elementIdx_); | |
94 | 85356216 | const auto wallNormalAxis = problem.wallNormalAxis(elementIdx_); | |
95 | 85356216 | velocityMaximum_ = problem.velocityMaximum(problem.wallElementIndex(elementIdx_)); | |
96 | 85356216 | velocityMinimum_ = problem.velocityMinimum(problem.wallElementIndex(elementIdx_)); | |
97 | 85356216 | uStar_ = sqrt(problem.kinematicViscosity(problem.wallElementIndex(elementIdx_)) | |
98 |
2/2✓ Branch 1 taken 136136 times.
✓ Branch 2 taken 85216680 times.
|
85356216 | * abs(problem.velocityGradient(problem.wallElementIndex(elementIdx_), flowDirectionAxis, wallNormalAxis))); |
99 |
2/2✓ Branch 0 taken 136136 times.
✓ Branch 1 taken 85216680 times.
|
85356216 | uStar_ = max(uStar_, 1e-10); // zero values lead to numerical problems in some turbulence models |
100 | 85356216 | yPlus_ = wallDistance_ * uStar_ / problem.kinematicViscosity(elementIdx_); | |
101 | 85356216 | uPlus_ = problem.ccVelocity(elementIdx_, flowDirectionAxis) / uStar_; | |
102 | } | ||
103 | 98295864 | } | |
104 | |||
105 | /*! | ||
106 | * \brief Return the element Idx of the control volume. | ||
107 | */ | ||
108 | 251097357 | unsigned int elementIdx() const | |
109 | 126804393 | { return elementIdx_; } | |
110 | |||
111 | /*! | ||
112 | * \brief Return the velocity vector \f$\mathrm{[m/s]}\f$ at the control volume center. | ||
113 | */ | ||
114 | 30003172 | DimVector ccVelocityVector() const | |
115 | 29938056 | { return ccVelocityVector_; } | |
116 | |||
117 | /*! | ||
118 | * \brief Return the maximum velocity vector \f$\mathrm{[m/s]}\f$ of the wall segment. | ||
119 | */ | ||
120 | 245468 | DimVector velocityMaximum() const | |
121 | 245468 | { return velocityMaximum_; } | |
122 | |||
123 | /*! | ||
124 | * \brief Return the minimum velocity vector \f$\mathrm{[m/s]}\f$ of the wall segment. | ||
125 | */ | ||
126 | DimVector velocityMinimum() const | ||
127 | { return velocityMinimum_; } | ||
128 | |||
129 | /*! | ||
130 | * \brief Return the velocity gradients \f$\mathrm{[1/s]}\f$ at the control volume center. | ||
131 | */ | ||
132 | 5753084 | DimMatrix velocityGradients() const | |
133 |
4/8✓ Branch 0 taken 5261698 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 150 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 150 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 150 times.
✗ Branch 7 not taken.
|
5694020 | { return velocityGradientTensor_; } |
134 | |||
135 | /*! | ||
136 | * \brief Return the wall distance \f$\mathrm{[m]}\f$ of the control volume. | ||
137 | */ | ||
138 | 103604132 | Scalar wallDistance() const | |
139 |
4/4✓ Branch 0 taken 23821428 times.
✓ Branch 1 taken 16956 times.
✓ Branch 2 taken 150822 times.
✓ Branch 3 taken 27660626 times.
|
98375808 | { return wallDistance_; } |
140 | |||
141 | /*! | ||
142 | * \brief Return the Karman constant | ||
143 | */ | ||
144 | 55622896 | Scalar karmanConstant() const | |
145 |
4/4✓ Branch 0 taken 23821428 times.
✓ Branch 1 taken 16956 times.
✓ Branch 2 taken 150822 times.
✓ Branch 3 taken 27660626 times.
|
55622896 | { return karmanConstant_; } |
146 | |||
147 | /*! | ||
148 | * \brief Return the wall friction velocity \f$\mathrm{[m/s]}\f$ | ||
149 | */ | ||
150 | 5262148 | Scalar uStar() const | |
151 | ✗ | { return uStar_; } | |
152 | |||
153 | /*! | ||
154 | * \brief Return the dimensionless wall distance \f$\mathrm{[-]}\f$. | ||
155 | */ | ||
156 | 5307400 | Scalar yPlus() const | |
157 | 5307400 | { return yPlus_; } | |
158 | |||
159 | /*! | ||
160 | * \brief Return the dimensionless velocity \f$\mathrm{[-]}\f$. | ||
161 | */ | ||
162 | 206156 | Scalar uPlus() const | |
163 | 206156 | { return uPlus_; } | |
164 | |||
165 | /*! | ||
166 | * \brief Return the dynamic eddy viscosity \f$\mathrm{[Pa s]}\f$ of the flow within the | ||
167 | * control volume. | ||
168 | */ | ||
169 | 652912104 | Scalar dynamicEddyViscosity() const | |
170 |
4/4✓ Branch 0 taken 2306480 times.
✓ Branch 1 taken 49092622 times.
✓ Branch 2 taken 9856414 times.
✓ Branch 3 taken 1018606 times.
|
458018758 | { return dynamicEddyViscosity_; } |
171 | |||
172 | /*! | ||
173 | * \brief Return the effective dynamic viscosity \f$\mathrm{[Pa s]}\f$ of the fluid within the | ||
174 | * control volume. | ||
175 | */ | ||
176 | 361385012 | Scalar effectiveViscosity() const | |
177 | 361385012 | { return NavierStokesParentType::viscosity() + dynamicEddyViscosity(); } | |
178 | |||
179 | /*! | ||
180 | * \brief Return the kinematic eddy viscosity \f$\mathrm{[m^2/s]}\f$ of the flow within the | ||
181 | * control volume. | ||
182 | */ | ||
183 | 167514748 | Scalar kinematicEddyViscosity() const | |
184 |
2/2✓ Branch 0 taken 1173870 times.
✓ Branch 1 taken 19016484 times.
|
122772368 | { return dynamicEddyViscosity() / NavierStokesParentType::density(); } |
185 | |||
186 | /*! | ||
187 | * \brief Return the kinematic viscosity \f$\mathrm{[m^2/s]}\f$ of the fluid within the | ||
188 | * control volume. | ||
189 | */ | ||
190 | 58950064 | Scalar kinematicViscosity() const | |
191 |
7/28✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 25 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 25 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 25 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 25 times.
✗ Branch 27 not taken.
✓ Branch 0 taken 150822 times.
✓ Branch 1 taken 27660626 times.
✓ Branch 2 taken 33032 times.
✗ Branch 3 not taken.
|
48816304 | { return NavierStokesParentType::viscosity() / NavierStokesParentType::density(); } |
192 | |||
193 | /*! | ||
194 | * \brief Calculates the eddy diffusivity \f$\mathrm{[m^2/s]}\f$ based | ||
195 | * on the kinematic eddy viscosity and the turbulent Schmidt number | ||
196 | */ | ||
197 | template<class Problem> | ||
198 | 98292464 | void calculateEddyDiffusivity(const Problem& problem) | |
199 | { | ||
200 | 196584928 | eddyDiffusivity_ = kinematicEddyViscosity() | |
201 | 98292464 | / problem.turbulentSchmidtNumber(); | |
202 | } | ||
203 | |||
204 | /*! | ||
205 | * \brief Calculates the eddy thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ based | ||
206 | * on the kinematic eddy viscosity and the turbulent Prandtl number | ||
207 | */ | ||
208 | template<class Problem, bool eB = enableEnergyBalance, typename std::enable_if_t<eB, int> = 0> | ||
209 | 42908482 | void calculateEddyThermalConductivity(const Problem& problem) | |
210 | { | ||
211 | 85816964 | eddyThermalConductivity_ = kinematicEddyViscosity() | |
212 | 42908482 | * NavierStokesParentType::density() | |
213 | 42908482 | * NavierStokesParentType::heatCapacity() | |
214 | 42908482 | / problem.turbulentPrandtlNumber(); | |
215 | 42908482 | } | |
216 | |||
217 | //! \brief Eddy thermal conductivity is zero for isothermal model | ||
218 | template<class Problem, bool eB = enableEnergyBalance, typename std::enable_if_t<!eB, int> = 0> | ||
219 | 55385682 | void calculateEddyThermalConductivity(const Problem& problem) | |
220 | 55384282 | { eddyThermalConductivity_ = 0.0; } | |
221 | |||
222 | /*! | ||
223 | * \brief Returns the eddy diffusivity \f$\mathrm{[m^2/s]}\f$ | ||
224 | */ | ||
225 | 142590190 | Scalar eddyDiffusivity() const | |
226 | 142590190 | { return eddyDiffusivity_; } | |
227 | |||
228 | /*! | ||
229 | * \brief Returns the eddy thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ | ||
230 | */ | ||
231 | 116248282 | Scalar eddyThermalConductivity() const | |
232 | 116153000 | { return eddyThermalConductivity_; } | |
233 | |||
234 | /*! | ||
235 | * \brief Returns the binary diffusion coefficients for a phase in \f$[m^2/s]\f$. | ||
236 | */ | ||
237 | 142590190 | Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const | |
238 |
2/2✓ Branch 1 taken 2458440 times.
✓ Branch 2 taken 70024800 times.
|
72565390 | { return NavierStokesParentType::diffusionCoefficient(0, compIIdx, compJIdx) + eddyDiffusivity(); } |
239 | |||
240 | /*! | ||
241 | * \brief Returns the effective thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ | ||
242 | * of the fluid-flow in the sub-control volume. | ||
243 | */ | ||
244 | template<bool eB = enableEnergyBalance, typename std::enable_if_t<eB, int> = 0> | ||
245 | 116248282 | Scalar effectiveThermalConductivity() const | |
246 | { | ||
247 | 116153000 | return NavierStokesParentType::thermalConductivity() + eddyThermalConductivity(); | |
248 | } | ||
249 | |||
250 | protected: | ||
251 | /*! | ||
252 | * \brief Sets the dynamic eddy viscosity \f$\mathrm{[Pa s]}\f$ | ||
253 | */ | ||
254 | 104808789 | Scalar setDynamicEddyViscosity_(Scalar value) | |
255 | 104808789 | { return dynamicEddyViscosity_ = value; } | |
256 | |||
257 | DimVector ccVelocityVector_; | ||
258 | DimVector velocityMaximum_; | ||
259 | DimVector velocityMinimum_; | ||
260 | DimMatrix velocityGradientTensor_; | ||
261 | std::size_t elementIdx_; | ||
262 | Scalar wallDistance_; | ||
263 | Scalar karmanConstant_; | ||
264 | Scalar uStar_ = 0.0; | ||
265 | Scalar yPlus_ = 0.0; | ||
266 | Scalar uPlus_ = 0.0; | ||
267 | Scalar dynamicEddyViscosity_ = 0.0; | ||
268 | Scalar eddyDiffusivity_ = 0.0; | ||
269 | Scalar eddyThermalConductivity_ = 0.0; | ||
270 | }; | ||
271 | } // end namespace Dumux | ||
272 | |||
273 | #endif | ||
274 |