https://mooseframework.inl.gov
Loading...
Searching...
No Matches
LinearFVTKEDSourceSink.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://www.mooseframework.org
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
16
19{
21 params.addClassDescription("Elemental kernel to compute the production and destruction "
22 " terms of turbulent kinetic energy dissipation (TKED).");
23 params.addRequiredParam<MooseFunctorName>("u", "The velocity in the x direction.");
24 params.addParam<MooseFunctorName>("v", "The velocity in the y direction.");
25 params.addParam<MooseFunctorName>("w", "The velocity in the z direction.");
26 params.addRequiredParam<MooseFunctorName>(NS::TKE, "Coupled turbulent kinetic energy.");
27 params.addRequiredParam<MooseFunctorName>(NS::density, "fluid density");
28 params.addRequiredParam<MooseFunctorName>(NS::mu, "Dynamic viscosity.");
29 params.addRequiredParam<MooseFunctorName>(NS::mu_t, "Turbulent viscosity.");
30
31 params.addParam<std::vector<BoundaryName>>(
32 "walls", {}, "Boundaries that correspond to solid walls.");
33 MooseEnum wall_treatment("eq_newton eq_incremental eq_linearized neq", "neq");
34 params.addParam<MooseEnum>("wall_treatment",
35 wall_treatment,
36 "The method used for computing the wall functions "
37 "'eq_newton', 'eq_incremental', 'eq_linearized', 'neq'");
38
39 params.addParam<MooseFunctorName>("C1_eps", 1.44, "First epsilon coefficient");
40 params.addParam<MooseFunctorName>("C2_eps", 1.92, "Second epsilon coefficient");
41 params.addParam<Real>("C_mu", 0.09, "Coupled turbulent kinetic energy closure.");
42 params.addParam<Real>("C_pl", 10.0, "Production limiter constant multiplier.");
43
44 return params;
45}
46
49 _dim(_subproblem.mesh().dimension()),
50 _u_var(getFunctor<Real>("u")),
51 _v_var(params.isParamValid("v") ? &(getFunctor<Real>("v")) : nullptr),
52 _w_var(params.isParamValid("w") ? &(getFunctor<Real>("w")) : nullptr),
53 _k(getFunctor<Real>(NS::TKE)),
54 _rho(getFunctor<Real>(NS::density)),
55 _mu(getFunctor<Real>(NS::mu)),
56 _mu_t(getFunctor<Real>(NS::mu_t)),
57 _wall_boundary_names(getParam<std::vector<BoundaryName>>("walls")),
58 _wall_treatment(getParam<MooseEnum>("wall_treatment").getEnum<NS::WallTreatmentEnum>()),
59 _C1_eps(getFunctor<Real>("C1_eps")),
60 _C2_eps(getFunctor<Real>("C2_eps")),
61 _C_mu(getParam<Real>("C_mu")),
62 _C_pl(getParam<Real>("C_pl"))
63{
64 if (_dim >= 2 && !_v_var)
65 paramError("v", "In two or more dimensions, the v velocity must be supplied!");
66
67 if (_dim >= 3 && !_w_var)
68 paramError("w", "In three or more dimensions, the w velocity must be supplied!");
69
70 // Strain tensor term requires velocity gradients;
71 if (dynamic_cast<const MooseLinearVariableFV<Real> *>(&_u_var))
72 requestVariableCellGradient(getParam<MooseFunctorName>("u"));
73 if (dynamic_cast<const MooseLinearVariableFV<Real> *>(_v_var))
74 requestVariableCellGradient(getParam<MooseFunctorName>("v"));
75 if (dynamic_cast<const MooseLinearVariableFV<Real> *>(_w_var))
76 requestVariableCellGradient(getParam<MooseFunctorName>("w"));
77}
78
79void
88
89Real
91{
93 // TKED value for near wall element will be directly assigned for this cell
94 return 1.0;
95 else
96 {
97 // Convenient definitions
98 const auto state = determineState();
99 const auto elem_arg = makeElemArg(_current_elem_info->elem());
100 const Real rho = _rho(elem_arg, state);
101 const Real TKE = _k(elem_arg, state);
102 const auto epsilon = _var.getElemValue(*_current_elem_info, state);
103
104 // Compute destruction
105 const auto destruction = _C2_eps(elem_arg, state) * rho * epsilon / TKE;
106
107 // Assign to matrix (term gets multiplied by TKED)
108 return destruction * _current_elem_volume;
109 }
110}
111
112Real
114{
116 {
117 // Convenient definitions
118 const auto state = determineState();
119 const auto elem_arg = makeElemArg(_current_elem_info->elem());
120 const Real rho = _rho(elem_arg, state);
121 const Real mu = _mu(elem_arg, state);
122 const Real TKE = _k(elem_arg, state);
123
124 // Convenient variables
125 Real destruction = 0.0;
126 std::vector<Real> y_plus_vec, velocity_grad_norm_vec;
127 Real tot_weight = 0.0;
128
129 // Get velocity vector
130 RealVectorValue velocity(_u_var(elem_arg, state));
131 if (_v_var)
132 velocity(1) = (*_v_var)(elem_arg, state);
133 if (_w_var)
134 velocity(2) = (*_w_var)(elem_arg, state);
135
136 // Get near wall faceInfo and distances from cell center to every wall
137 const auto & face_info_vec = libmesh_map_find(_face_infos, _current_elem_info->elem());
138 const auto & distance_vec = libmesh_map_find(_dist, _current_elem_info->elem());
139 mooseAssert(distance_vec.size(), "Should have found a distance vector");
140 mooseAssert(distance_vec.size() == face_info_vec.size(),
141 "Should be as many distance vectors as face info vectors");
142
143 // Update y+ and wall face cell
144 for (unsigned int i = 0; i < distance_vec.size(); i++)
145 {
146 const auto distance = distance_vec[i];
147 mooseAssert(distance > 0, "Should be at a non-zero distance");
148
149 Real y_plus;
150 if (_wall_treatment == NS::WallTreatmentEnum::NEQ) // Non-equilibrium / Non-iterative
151 y_plus = distance * std::sqrt(std::sqrt(_C_mu) * TKE) * rho / mu;
152 else // Equilibrium / Iterative
153 {
154 const auto parallel_speed = NS::computeSpeed<Real>(
155 velocity - velocity * face_info_vec[i]->normal() * face_info_vec[i]->normal());
156 y_plus = NS::findyPlus<Real>(mu, rho, std::max(parallel_speed, 1e-10), distance);
157 }
158
159 y_plus_vec.push_back(y_plus);
160 tot_weight += 1.0;
161 }
162
163 // Compute near wall epsilon value
164 for (const auto i : index_range(y_plus_vec))
165 {
166 const auto y_plus = y_plus_vec[i];
167
168 if (y_plus < 11.25)
169 destruction += 2.0 * TKE * mu / rho / Utility::pow<2>(distance_vec[i]) / tot_weight;
170 else
171 destruction += std::pow(_C_mu, 0.75) * std::pow(TKE, 1.5) /
172 (NS::von_karman_constant * distance_vec[i]) / tot_weight;
173 }
174
175 // Assign the computed value of TKED for element near the wall
176 return destruction;
177 }
178 else
179 {
180 // Convenient definitions
181 const auto state = determineState();
182 const auto elem_arg = makeElemArg(_current_elem_info->elem());
183 const Real rho = _rho(elem_arg, state);
184 const Real TKE = _k(elem_arg, state);
185 const Real TKED = _var.getElemValue(*_current_elem_info, state);
186
187 // Compute production of TKE
188 const auto subdomain_id = _current_elem_info->elem()->subdomain_id();
189 const auto coord_sys = _subproblem.getCoordSystem(subdomain_id);
190 const unsigned int rz_radial_coord =
192 const auto symmetric_strain_tensor_sq_norm = NS::computeShearStrainRateNormSquared<Real>(
193 _u_var, _v_var, _w_var, elem_arg, state, coord_sys, rz_radial_coord);
194 Real production = _mu_t(elem_arg, state) * symmetric_strain_tensor_sq_norm;
195
196 // Limit TKE production (needed for flows with stagnation zones)
197 const Real production_limit = _C_pl * rho * TKED;
198 production = std::min(production, production_limit);
199
200 // Compute production - recasted with mu_t definition to avoid division by epsilon
201 const auto production_epsilon = _C1_eps(elem_arg, state) * production * TKED / TKE;
202
203 // Assign to matrix (term gets multiplied by TKED)
204 return production_epsilon * _current_elem_volume;
205 }
206}
const double mu
const double rho
registerMooseObject("NavierStokesApp", LinearFVTKEDSourceSink)
virtual const std::set< SubdomainID > & blockIDs() const
const Elem * elem() 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 dissipation...
const Moose::Functor< Real > & _u_var
x-velocity
const Moose::Functor< Real > * _w_var
z-velocity
const Moose::Functor< Real > & _C1_eps
Value of the first epsilon closure coefficient.
NS::WallTreatmentEnum _wall_treatment
Method used for wall treatment.
std::map< const Elem *, std::vector< Real > > _dist
static InputParameters validParams()
const unsigned int _dim
The dimension of the simulation.
const Moose::Functor< Real > & _C2_eps
Value of the second epsilon closure coefficient.
std::map< const Elem *, std::vector< const FaceInfo * > > _face_infos
virtual void initialSetup() override
const Moose::Functor< Real > & _mu_t
Turbulent dynamic viscosity.
const Moose::Functor< Real > & _k
Turbulent kinetic energy.
virtual Real computeMatrixContribution() override
const std::vector< BoundaryName > & _wall_boundary_names
Wall boundaries.
const Real _C_pl
Production Limiter Constant.
std::unordered_set< const Elem * > _wall_bounded
Maps for wall treatment.
virtual Real computeRightHandSideContribution() override
const Moose::Functor< Real > * _v_var
y-velocity
const Moose::Functor< Real > & _rho
Density.
LinearFVTKEDSourceSink(const InputParameters &params)
Class constructor.
const Moose::Functor< Real > & _mu
Dynamic viscosity.
const Real _C_mu
C_mu constant.
FEProblemBase & _fe_problem
void paramError(const std::string &param, Args... args) const
Real getElemValue(const ElemInfo &elem_info, const StateArg &state) const
virtual void initialSetup()
unsigned int getAxisymmetricRadialCoord() const
Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) const
SubProblem & _subproblem
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:205
static const std::string mu_t
Definition NS.h:129
static const std::string mu
Definition NS.h:127
static const std::string TKE
Definition NS.h:180
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)