https://mooseframework.inl.gov
LinearFVTKESourceSink.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 
10 #include "LinearFVTKESourceSink.h"
11 #include "Assembly.h"
12 #include "SubProblem.h"
13 #include "NavierStokesMethods.h"
14 
15 registerMooseObject("NavierStokesApp", LinearFVTKESourceSink);
16 
19 {
21  params.addClassDescription("Elemental kernel to compute the production and destruction "
22  " terms of turbulent kinetic energy (TKE).");
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::TKED,
27  "Coupled turbulent kinetic energy dissipation rate.");
28  params.addRequiredParam<MooseFunctorName>(NS::density, "Fluid density");
29  params.addRequiredParam<MooseFunctorName>(NS::mu, "Dynamic viscosity.");
30  params.addRequiredParam<MooseFunctorName>(NS::mu_t, "Turbulent viscosity.");
31 
32  params.addParam<std::vector<BoundaryName>>(
33  "walls", {}, "Boundaries that correspond to solid walls.");
34  MooseEnum wall_treatment("eq_newton eq_incremental eq_linearized neq", "neq");
35 
36  params.addParam<MooseEnum>("wall_treatment",
37  wall_treatment,
38  "The method used for computing the wall functions "
39  "'eq_newton', 'eq_incremental', 'eq_linearized', 'neq'");
40  params.addParam<Real>("C_mu", 0.09, "Coupled turbulent kinetic energy closure.");
41  params.addParam<Real>("C_pl", 10.0, "Production Limiter Constant Multiplier.");
42 
43  return params;
44 }
45 
47  : LinearFVElementalKernel(params),
48  _dim(_subproblem.mesh().dimension()),
49  _u_var(getFunctor<Real>("u")),
50  _v_var(params.isParamValid("v") ? &(getFunctor<Real>("v")) : nullptr),
51  _w_var(params.isParamValid("w") ? &(getFunctor<Real>("w")) : nullptr),
52  _epsilon(getFunctor<Real>(NS::TKED)),
53  _rho(getFunctor<Real>(NS::density)),
54  _mu(getFunctor<Real>(NS::mu)),
55  _mu_t(getFunctor<Real>(NS::mu_t)),
56  _wall_boundary_names(getParam<std::vector<BoundaryName>>("walls")),
57  _wall_treatment(getParam<MooseEnum>("wall_treatment").getEnum<NS::WallTreatmentEnum>()),
58  _C_mu(getParam<Real>("C_mu")),
59  _C_pl(getParam<Real>("C_pl"))
60 {
61  if (_dim >= 2 && !_v_var)
62  paramError("v", "In two or more dimensions, the v velocity must be supplied!");
63 
64  if (_dim >= 3 && !_w_var)
65  paramError("w", "In three or more dimensions, the w velocity must be supplied!");
66 
67  // // Strain tensor term requires velocity gradients;
68  if (dynamic_cast<const MooseLinearVariableFV<Real> *>(&_u_var))
69  requestVariableCellGradient(getParam<MooseFunctorName>("u"));
70  if (dynamic_cast<const MooseLinearVariableFV<Real> *>(_v_var))
71  requestVariableCellGradient(getParam<MooseFunctorName>("v"));
72  if (dynamic_cast<const MooseLinearVariableFV<Real> *>(_w_var))
73  requestVariableCellGradient(getParam<MooseFunctorName>("w"));
74 }
75 
76 void
78 {
84 }
85 
86 Real
88 {
89  /*
90  Matrix contribution:
91  - Computes near-wall TKE destruction
92  - Computes bulk TKE destruction
93  */
94 
95  // Useful variables
96  const auto state = determineState();
97  const auto elem_arg = makeElemArg(_current_elem_info->elem());
98  const Real rho = _rho(elem_arg, state);
99 
100  if (_wall_bounded.find(_current_elem_info->elem()) != _wall_bounded.end())
101  {
102 
103  // Useful variables
104  const Real mu = _mu(elem_arg, state);
105  const Real TKE = _var.getElemValue(*_current_elem_info, state);
106 
107  // Assembly variables
108  Real production = 0.0;
109  Real destruction = 0.0;
110  Real tot_weight = 0.0;
111  std::vector<Real> y_plus_vec, velocity_grad_norm_vec;
112 
113  // Get near-wall element velocity vector
114  RealVectorValue velocity(_u_var(elem_arg, state));
115  if (_v_var)
116  velocity(1) = (*_v_var)(elem_arg, state);
117  if (_w_var)
118  velocity(2) = (*_w_var)(elem_arg, state);
119 
120  // Get faceInfo and distance vector for between all walls and elements
121  const auto & face_info_vec = libmesh_map_find(_face_infos, _current_elem_info->elem());
122  const auto & distance_vec = libmesh_map_find(_dist, _current_elem_info->elem());
123  mooseAssert(distance_vec.size(), "Should have found a distance vector");
124  mooseAssert(distance_vec.size() == face_info_vec.size(),
125  "Should be as many distance vectors as face info vectors");
126 
127  // Populate y+, near wall velocity gradient, and update weights
128  for (unsigned int i = 0; i < distance_vec.size(); i++)
129  {
130  const auto parallel_speed = NS::computeSpeed<Real>(
131  velocity - velocity * face_info_vec[i]->normal() * face_info_vec[i]->normal());
132  const auto distance = distance_vec[i];
133 
134  Real y_plus;
135  if (_wall_treatment == NS::WallTreatmentEnum::NEQ) // Non-equilibrium --> Non-iterative
136  y_plus = distance * std::sqrt(std::sqrt(_C_mu) * TKE) * rho / mu;
137  else // Equilibrium --> Iterative
138  y_plus = NS::findyPlus<Real>(mu, rho, std::max(parallel_speed, 1e-10), distance);
139 
140  y_plus_vec.push_back(y_plus);
141  const Real velocity_grad_norm = parallel_speed / distance;
142  velocity_grad_norm_vec.push_back(velocity_grad_norm);
143  tot_weight += 1.0;
144  }
145 
146  // Compute near-wall production and destruction
147  for (unsigned int i = 0; i < y_plus_vec.size(); i++)
148  {
149  const auto y_plus = y_plus_vec[i];
150 
151  const auto fi = face_info_vec[i];
152  const bool defined_on_elem_side = _var.hasFaceSide(*fi, true);
153  const Elem * const loc_elem = defined_on_elem_side ? &fi->elem() : fi->neighborPtr();
154  const Moose::FaceArg facearg = {
155  fi, Moose::FV::LimiterType::CentralDifference, false, false, loc_elem, nullptr};
156 
157  const Real wall_mut = _mu_t(facearg, state);
158  const Real wall_mu = _mu(facearg, state);
159  const auto tau_w = (wall_mut + wall_mu) * velocity_grad_norm_vec[i];
160  const auto destruction_visc = 2.0 * wall_mu / Utility::pow<2>(distance_vec[i]) / tot_weight;
161  const auto destruction_log = std::pow(_C_mu, 0.75) * rho * std::pow(TKE, 0.5) /
162  (NS::von_karman_constant * distance_vec[i]) / tot_weight;
163 
164  if (y_plus < 11.25)
165  destruction += destruction_visc;
166  else
167  {
168  destruction += destruction_log;
169  production += tau_w * std::pow(_C_mu, 0.25) / std::sqrt(TKE) /
170  (NS::von_karman_constant * distance_vec[i]) / tot_weight;
171  }
172  }
173 
174  // Assign terms to matrix to solve implicitly (they get multiplied by TKE)
175  return (destruction - production) * _current_elem_volume;
176  }
177  else
178  {
179  // Compute destruction
180  const auto destruction =
181  rho * _epsilon(elem_arg, state) / _var.getElemValue(*_current_elem_info, state);
182 
183  // Assign to matrix to solve implicitly
184  return destruction * _current_elem_volume;
185  }
186 }
187 
188 Real
190 {
191 
192  // Useful variables
193  const auto state = determineState();
194  const auto elem_arg = makeElemArg(_current_elem_info->elem());
195 
196  if (_wall_bounded.find(_current_elem_info->elem()) != _wall_bounded.end()) // Wall bounded
197  return 0.0; // Do nothing
198  else // Not wall bounded
199  {
200  // Compute TKE production
201  const auto subdomain_id = _current_elem_info->elem()->subdomain_id();
202  const auto coord_sys = _subproblem.getCoordSystem(subdomain_id);
203  const unsigned int rz_radial_coord =
205  const auto symmetric_strain_tensor_sq_norm = NS::computeShearStrainRateNormSquared<Real>(
206  _u_var, _v_var, _w_var, elem_arg, state, coord_sys, rz_radial_coord);
207 
208  auto production = _mu_t(elem_arg, state) * symmetric_strain_tensor_sq_norm;
209 
210  // k-Production limiter (needed for flows with stagnation zones)
211  const Real production_limit = _C_pl * _rho(elem_arg, state) * _epsilon(elem_arg, state);
212 
213  // Apply production limiter
214  production = std::min(production, production_limit);
215 
216  // Assign production to RHS
217  return production * _current_elem_volume;
218  }
219 }
const ElemInfo * _current_elem_info
unsigned int getAxisymmetricRadialCoord() const
const Moose::Functor< Real > * _w_var
z-velocity
std::map< const Elem *, std::vector< Real > > _dist
static constexpr Real von_karman_constant
Definition: NS.h:205
static const std::string mu_t
Definition: NS.h:129
SubProblem & _subproblem
void paramError(const std::string &param, Args... args) const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void requestVariableCellGradient(const std::string &variable_name)
const Real _C_pl
Production Limiter Constant.
Moose::StateArg determineState() const
const Elem * elem() const
const Moose::Functor< Real > & _u_var
x-velocity
static InputParameters validParams()
MooseLinearVariableFV< Real > & _var
MeshBase & mesh
static const std::string density
Definition: NS.h:34
static const std::string TKE
Definition: NS.h:180
WallTreatmentEnum
Wall treatment options.
Definition: NS.h:186
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...
virtual const std::set< SubdomainID > & blockIDs() const
const NS::WallTreatmentEnum _wall_treatment
Method used for wall treatment.
const Moose::Functor< Real > & _rho
Density.
Real distance(const Point &p)
void addRequiredParam(const std::string &name, const std::string &doc_string)
const std::vector< BoundaryName > & _wall_boundary_names
Wall boundaries.
registerMooseObject("NavierStokesApp", LinearFVTKESourceSink)
Moose::ElemArg makeElemArg(const Elem *elem, bool correct_skewnewss=false) const
template Real findyPlus< Real >(const Real &mu, const Real &rho, const Real &u, Real dist)
Kernel that adds contributions to the source and the sink of the turbulent kinetic energy discretized...
const Real _C_mu
C_mu constant.
const Moose::Functor< Real > & _epsilon
epsilon - dissipation rate of TKE
std::unordered_set< const Elem * > _wall_bounded
const unsigned int _dim
The dimension of the domain.
static const std::string mu
Definition: NS.h:127
const Moose::Functor< Real > & _mu
Dynamic viscosity.
const double rho
static InputParameters validParams()
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...
virtual Real computeMatrixContribution() override
LinearFVTKESourceSink(const InputParameters &params)
Class constructor.
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)
virtual Real computeRightHandSideContribution() override
virtual void initialSetup() override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real getElemValue(const ElemInfo &elem_info, const StateArg &state) const
static const std::string TKED
Definition: NS.h:181
void addClassDescription(const std::string &doc_string)
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-...
Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) const
static const std::string velocity
Definition: NS.h:46
FEProblemBase & _fe_problem
template Real computeSpeed< Real >(const libMesh::VectorValue< Real > &velocity)
virtual void initialSetup()
const double mu
std::map< const Elem *, std::vector< const FaceInfo * > > _face_infos
MooseUnits pow(const MooseUnits &, int)
const Moose::Functor< Real > & _mu_t
Turbulent dynamic viscosity.
virtual bool hasFaceSide(const FaceInfo &fi, const bool fi_elem_side) const override
const Moose::Functor< Real > * _v_var
y-velocity