https://mooseframework.inl.gov
Loading...
Searching...
No Matches
LinearFVTKESourceSink.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11#include "Assembly.h"
12#include "SubProblem.h"
13#include "NavierStokesMethods.h"
14#include "TheWarehouse.h"
18
20
23{
25 params.addClassDescription("Elemental kernel to compute the production and destruction "
26 " terms of turbulent kinetic energy (TKE).");
27 params.addRequiredParam<MooseFunctorName>("u", "The velocity in the x direction.");
28 params.addParam<MooseFunctorName>("v", "The velocity in the y direction.");
29 params.addParam<MooseFunctorName>("w", "The velocity in the z direction.");
30 params.addRequiredParam<MooseFunctorName>(NS::TKED,
31 "Coupled turbulent kinetic energy dissipation rate.");
32 params.addRequiredParam<MooseFunctorName>(NS::density, "Fluid density");
33 params.addRequiredParam<MooseFunctorName>(NS::mu, "Dynamic viscosity.");
34 params.addRequiredParam<MooseFunctorName>(NS::mu_t, "Turbulent viscosity.");
35
36 params.addParam<std::vector<BoundaryName>>(
37 "walls", {}, "Boundaries that correspond to solid walls.");
38 MooseEnum wall_treatment("eq_newton eq_incremental eq_linearized neq", "neq");
39
40 params.addParam<MooseEnum>("wall_treatment",
41 wall_treatment,
42 "The method used for computing the wall functions "
43 "'eq_newton', 'eq_incremental', 'eq_linearized', 'neq'");
44 params.addParam<Real>("C_mu", 0.09, "Coupled turbulent kinetic energy closure.");
45 params.addParam<Real>("C_pl", 10.0, "Production Limiter Constant Multiplier.");
46
47 return params;
48}
49
52 _dim(_subproblem.mesh().dimension()),
53 _u_var(getFunctor<Real>("u")),
54 _v_var(params.isParamValid("v") ? &(getFunctor<Real>("v")) : nullptr),
55 _w_var(params.isParamValid("w") ? &(getFunctor<Real>("w")) : nullptr),
56 _epsilon(getFunctor<Real>(NS::TKED)),
57 _rho(getFunctor<Real>(NS::density)),
58 _mu(getFunctor<Real>(NS::mu)),
59 _mu_t(getFunctor<Real>(NS::mu_t)),
60 _wall_boundary_names(getParam<std::vector<BoundaryName>>("walls")),
61 _wall_treatment(getParam<MooseEnum>("wall_treatment").getEnum<NS::WallTreatmentEnum>()),
62 _C_mu(getParam<Real>("C_mu")),
63 _C_pl(getParam<Real>("C_pl"))
64{
65 // An informational message rather than a warning, because flows without walls are valid and
66 // warnings are treated as errors in the test suite
67 if (_wall_boundary_names.empty())
68 mooseInfo("No 'walls' were specified for the turbulent kinetic energy. "
69 "Wall-bounded flows need 'walls' for the wall treatment of this variable, "
70 "otherwise its production and destruction are not modified near walls.");
71
72 if (_dim >= 2 && !_v_var)
73 paramError("v", "In two or more dimensions, the v velocity must be supplied!");
74
75 if (_dim >= 3 && !_w_var)
76 paramError("w", "In three or more dimensions, the w velocity must be supplied!");
77
78 // // Strain tensor term requires velocity gradients;
79 if (dynamic_cast<const MooseLinearVariableFV<Real> *>(&_u_var))
80 requestVariableCellGradient(getParam<MooseFunctorName>("u"));
81 if (dynamic_cast<const MooseLinearVariableFV<Real> *>(_v_var))
82 requestVariableCellGradient(getParam<MooseFunctorName>("v"));
83 if (dynamic_cast<const MooseLinearVariableFV<Real> *>(_w_var))
84 requestVariableCellGradient(getParam<MooseFunctorName>("w"));
85}
86
87void
89{
91
92 // Unlike TKED, which is fixed by the wall function in wall-bounded cells, TKE is still solved
93 // for there; only its production and destruction are modified by this kernel. The turbulent
94 // transport kernels of TKE must therefore not skip wall-bounded cells.
95 // Kernels are registered in the warehouse under their elemental or flux system name
96 std::vector<LinearFVKernel *> kernels;
97 for (const auto & system : {"LinearFVElementalKernel", "LinearFVFluxKernel"})
98 {
99 std::vector<LinearFVKernel *> system_kernels;
101 .query()
102 .condition<AttribSystem>(system)
103 .condition<AttribSysNum>(_var.sys().number())
104 .condition<AttribVar>(_var.number())
105 .condition<AttribThread>(_tid)
106 .queryInto(system_kernels);
107 kernels.insert(kernels.end(), system_kernels.begin(), system_kernels.end());
108 }
109 for (const auto kernel : kernels)
110 if ((dynamic_cast<LinearFVTurbulentAdvection *>(kernel) ||
111 dynamic_cast<LinearFVTurbulentDiffusion *>(kernel) ||
112 dynamic_cast<LinearFVTurbulentTimeDerivative *>(kernel)) &&
113 !kernel->getParam<std::vector<BoundaryName>>("walls").empty())
114 kernel->paramError(
115 "walls",
116 "Walls should not be specified for turbulent kernels acting on the "
117 "turbulent kinetic energy variable '",
118 _var.name(),
119 "'. They are only used for the turbulent kinetic energy dissipation rate.");
120
125}
126
127Real
129{
130 /*
131 Matrix contribution:
132 - Computes near-wall TKE destruction
133 - Computes bulk TKE destruction
134 */
135
136 // Useful variables
137 const auto state = determineState();
138 const auto elem_arg = makeElemArg(_current_elem_info->elem());
139 const Real rho = _rho(elem_arg, state);
140
142 {
143
144 // Useful variables
145 const Real mu = _mu(elem_arg, state);
146 const Real TKE = _var.getElemValue(*_current_elem_info, state);
147
148 // Assembly variables
149 Real production = 0.0;
150 Real destruction = 0.0;
151 Real tot_weight = 0.0;
152 std::vector<Real> y_plus_vec, velocity_grad_norm_vec;
153
154 // Get near-wall element velocity vector
155 RealVectorValue velocity(_u_var(elem_arg, state));
156 if (_v_var)
157 velocity(1) = (*_v_var)(elem_arg, state);
158 if (_w_var)
159 velocity(2) = (*_w_var)(elem_arg, state);
160
161 // Get faceInfo and distance vector for between all walls and elements
162 const auto & face_info_vec = libmesh_map_find(_face_infos, _current_elem_info->elem());
163 const auto & distance_vec = libmesh_map_find(_dist, _current_elem_info->elem());
164 mooseAssert(distance_vec.size(), "Should have found a distance vector");
165 mooseAssert(distance_vec.size() == face_info_vec.size(),
166 "Should be as many distance vectors as face info vectors");
167
168 // Populate y+, near wall velocity gradient, and update weights
169 for (unsigned int i = 0; i < distance_vec.size(); i++)
170 {
171 const auto parallel_speed = NS::computeSpeed<Real>(
172 velocity - velocity * face_info_vec[i]->normal() * face_info_vec[i]->normal());
173 const auto distance = distance_vec[i];
174
175 Real y_plus;
176 if (_wall_treatment == NS::WallTreatmentEnum::NEQ) // Non-equilibrium --> Non-iterative
177 y_plus = distance * std::sqrt(std::sqrt(_C_mu) * TKE) * rho / mu;
178 else // Equilibrium --> Iterative
179 y_plus = NS::findyPlus<Real>(mu, rho, std::max(parallel_speed, 1e-10), distance);
180
181 y_plus_vec.push_back(y_plus);
182 const Real velocity_grad_norm = parallel_speed / distance;
183 velocity_grad_norm_vec.push_back(velocity_grad_norm);
184 tot_weight += 1.0;
185 }
186
187 // Compute near-wall production and destruction
188 for (unsigned int i = 0; i < y_plus_vec.size(); i++)
189 {
190 const auto y_plus = y_plus_vec[i];
191
192 const auto fi = face_info_vec[i];
193 const bool defined_on_elem_side = _var.hasFaceSide(*fi, true);
194 const Elem * const loc_elem = defined_on_elem_side ? &fi->elem() : fi->neighborPtr();
195 const Moose::FaceArg facearg = {
196 fi, Moose::FV::LimiterType::CentralDifference, false, false, loc_elem, nullptr};
197
198 const Real wall_mut = _mu_t(facearg, state);
199 const Real wall_mu = _mu(facearg, state);
200 const auto tau_w = (wall_mut + wall_mu) * velocity_grad_norm_vec[i];
201 const auto destruction_visc = 2.0 * wall_mu / Utility::pow<2>(distance_vec[i]) / tot_weight;
202 const auto destruction_log = std::pow(_C_mu, 0.75) * rho * std::pow(TKE, 0.5) /
203 (NS::von_karman_constant * distance_vec[i]) / tot_weight;
204
205 if (y_plus < 11.25)
206 destruction += destruction_visc;
207 else
208 {
209 destruction += destruction_log;
210 production += tau_w * std::pow(_C_mu, 0.25) / std::sqrt(TKE) /
211 (NS::von_karman_constant * distance_vec[i]) / tot_weight;
212 }
213 }
214
215 // Assign terms to matrix to solve implicitly (they get multiplied by TKE)
216 return (destruction - production) * _current_elem_volume;
217 }
218 else
219 {
220 // Compute destruction
221 const auto destruction =
222 rho * _epsilon(elem_arg, state) / _var.getElemValue(*_current_elem_info, state);
223
224 // Assign to matrix to solve implicitly
225 return destruction * _current_elem_volume;
226 }
227}
228
229Real
231{
232
233 // Useful variables
234 const auto state = determineState();
235 const auto elem_arg = makeElemArg(_current_elem_info->elem());
236
237 if (_wall_bounded.find(_current_elem_info->elem()) != _wall_bounded.end()) // Wall bounded
238 return 0.0; // Do nothing
239 else // Not wall bounded
240 {
241 // Compute TKE production
242 const auto subdomain_id = _current_elem_info->elem()->subdomain_id();
243 const auto coord_sys = _subproblem.getCoordSystem(subdomain_id);
244 const unsigned int rz_radial_coord =
246 const auto symmetric_strain_tensor_sq_norm = NS::computeShearStrainRateNormSquared<Real>(
247 _u_var, _v_var, _w_var, elem_arg, state, coord_sys, rz_radial_coord);
248
249 auto production = _mu_t(elem_arg, state) * symmetric_strain_tensor_sq_norm;
250
251 // k-Production limiter (needed for flows with stagnation zones)
252 const Real production_limit = _C_pl * _rho(elem_arg, state) * _epsilon(elem_arg, state);
253
254 // Apply production limiter
255 production = std::min(production, production_limit);
256
257 // Assign production to RHS
258 return production * _current_elem_volume;
259 }
260}
const double mu
const double rho
registerMooseObject("NavierStokesApp", LinearFVTKESourceSink)
virtual const std::set< SubdomainID > & blockIDs() const
const Elem * elem() const
TheWarehouse & theWarehouse() const
Moose::ElemArg makeElemArg(const Elem *elem, bool correct_skewnewss=false) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
const ElemInfo * _current_elem_info
static InputParameters validParams()
MooseLinearVariableFV< Real > & _var
void requestVariableCellGradient(const std::string &variable_name)
Kernel that adds contributions to the source and the sink of the turbulent kinetic energy discretized...
LinearFVTKESourceSink(const InputParameters &params)
Class constructor.
const Moose::Functor< Real > & _mu
Dynamic viscosity.
virtual Real computeRightHandSideContribution() override
const Moose::Functor< Real > & _epsilon
epsilon - dissipation rate of TKE
const Real _C_pl
Production Limiter Constant.
const NS::WallTreatmentEnum _wall_treatment
Method used for wall treatment.
std::unordered_set< const Elem * > _wall_bounded
std::map< const Elem *, std::vector< const FaceInfo * > > _face_infos
virtual void initialSetup() override
std::map< const Elem *, std::vector< Real > > _dist
static InputParameters validParams()
const Real _C_mu
C_mu constant.
const Moose::Functor< Real > * _w_var
z-velocity
const Moose::Functor< Real > & _rho
Density.
const Moose::Functor< Real > & _u_var
x-velocity
const std::vector< BoundaryName > & _wall_boundary_names
Wall boundaries.
const Moose::Functor< Real > * _v_var
y-velocity
const Moose::Functor< Real > & _mu_t
Turbulent dynamic viscosity.
virtual Real computeMatrixContribution() override
const unsigned int _dim
The dimension of the domain.
An advection kernel that implements the advection term for the turbulent variables limited for the fi...
Kernel that adds contributions from a diffusion term of the turbulent variables, limited in the near-...
Kernel that adds contributions from a time derivative term of the turbulent variables,...
const THREAD_ID _tid
FEProblemBase & _fe_problem
const std::string & name() const
void paramError(const std::string &param, Args... args) const
void mooseInfo(Args &&... args) const
Real getElemValue(const ElemInfo &elem_info, const StateArg &state) const
SystemBase & sys()
unsigned int number() const
virtual bool hasFaceSide(const FaceInfo &fi, const bool fi_elem_side) const override
virtual void initialSetup()
unsigned int getAxisymmetricRadialCoord() const
Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) const
unsigned int number() const
SubProblem & _subproblem
Query query()
Moose::StateArg determineState() const
MeshBase & mesh
void getWallBoundedElements(const std::vector< BoundaryName > &wall_boundary_name, const FEProblemBase &fe_problem, const SubProblem &subproblem, const std::set< SubdomainID > &block_ids, std::unordered_set< const Elem * > &wall_bounded)
Map marking wall bounded elements The map passed in wall_bounded_map gets cleared and re-populated.
void getWallDistance(const std::vector< BoundaryName > &wall_boundary_name, const FEProblemBase &fe_problem, const SubProblem &subproblem, const std::set< SubdomainID > &block_ids, std::map< const Elem *, std::vector< Real > > &dist_map)
Map storing wall ditance for near-wall marked elements The map passed in dist_map gets cleared and re...
static const std::string density
Definition NS.h:34
template Real computeSpeed< Real >(const libMesh::VectorValue< Real > &velocity)
static constexpr Real von_karman_constant
Definition NS.h:206
static const std::string TKED
Definition NS.h:182
static const std::string mu_t
Definition NS.h:129
static const std::string mu
Definition NS.h:127
template Real findyPlus< Real >(const Real &mu, const Real &rho, const Real &u, Real dist)
template Real computeShearStrainRateNormSquared< Real >(const Moose::Functor< Real > &u, const Moose::Functor< Real > *v, const Moose::Functor< Real > *w, const Moose::ElemArg &elem_arg, const Moose::StateArg &state, const Moose::CoordinateSystemType coord_sys, const unsigned int rz_radial_coord)
void getElementFaceArgs(const std::vector< BoundaryName > &wall_boundary_name, const FEProblemBase &fe_problem, const SubProblem &subproblem, const std::set< SubdomainID > &block_ids, std::map< const Elem *, std::vector< const FaceInfo * > > &face_info_map)
Map storing face arguments to wall bounded faces The map passed in face_info_map gets cleared and re-...
Real distance(const Point &p)