https://mooseframework.inl.gov
WallDistanceMixingLengthAux.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 
13 
16 {
18  params.addClassDescription(
19  "Computes the turbulent mixing length by assuming that it is "
20  "proportional to the distance from the nearest wall. The mixing"
21  "length is capped at a distance proportional to inputted parameter delta.");
22  params.addParam<std::vector<BoundaryName>>(
23  "walls", {}, "Boundaries that correspond to solid walls.");
24  params.addParam<MooseFunctorName>("von_karman_const", 0.41, ""); // Von Karman constant
25  params.addParam<MooseFunctorName>("von_karman_const_0", 0.09, ""); // Escudier' model parameter
26  params.addParam<MooseFunctorName>(
27  "delta",
28  1e9,
29  ""); // Tunable parameter related to the thickness of the boundary layer.
30  // When it is not specified, Prandtl's original mixing length model is retrieved.
31  return params;
32 }
33 
35  : AuxKernel(parameters),
36  _wall_boundary_names(getParam<std::vector<BoundaryName>>("walls")),
37  _von_karman_const(getFunctor<Real>("von_karman_const")),
38  _von_karman_const_0(getFunctor<Real>("von_karman_const_0")),
39  _delta(getFunctor<Real>("delta"))
40 {
41  const MeshBase & mesh = _subproblem.mesh().getMesh();
42  if (!mesh.is_replicated())
43  mooseError("WallDistanceMixingLengthAux only supports replicated meshes");
44  if (!dynamic_cast<MooseVariableFV<Real> *>(&_var))
45  paramError("variable",
46  "'",
47  name(),
48  "' is currently programmed to use finite volume machinery, so make sure that '",
49  _var.name(),
50  "' is a finite volume variable.");
51 }
52 
53 Real
55 {
56  // Get reference to the libMesh mesh object
57  const MeshBase & l_mesh = _mesh.getMesh();
58 
59  // Get the ids of the wall boundaries
60  std::vector<BoundaryID> vec_ids = _mesh.getBoundaryIDs(_wall_boundary_names, true);
61 
62  // Loop over all boundaries
63  Real min_dist2 = 1e9;
64  const auto & bnd_to_elem_map = _mesh.getBoundariesToActiveSemiLocalElemIds();
65  for (BoundaryID bid : vec_ids)
66  {
67  // Get the set of elements on this boundary
68  auto search = bnd_to_elem_map.find(bid);
69  if (search == bnd_to_elem_map.end())
70  mooseError("Error computing wall distance; the boundary id ", bid, " is invalid");
71  const auto & bnd_elems = search->second;
72 
73  // Loop over all boundary elements and find the distance to the closest one
74  for (dof_id_type elem_id : bnd_elems)
75  {
76  const Elem & elem{l_mesh.elem_ref(elem_id)};
77  const auto side = _mesh.sideWithBoundaryID(&elem, bid);
78  const FaceInfo * fi = _mesh.faceInfo(&elem, side);
79  // It's possible that we are on an internal boundary
80  if (!fi)
81  {
82  const Elem * const neigh = elem.neighbor_ptr(side);
83  mooseAssert(
84  neigh,
85  "In WallDistanceMixingLengthAux, we could not find a face information object with elem "
86  "and side, and we are on an external boundary. This shouldn't happen.");
87  const auto neigh_side = neigh->which_neighbor_am_i(&elem);
88  fi = _mesh.faceInfo(neigh, neigh_side);
89  mooseAssert(fi, "We should have a face info for either the elem or neigh side");
90  }
91  Point bnd_pos = fi->faceCentroid();
92  const auto distance = bnd_pos - _q_point[_qp];
93  const auto dist2 = distance * distance;
94  mooseAssert(dist2 != 0, "This distance should never be 0");
95  min_dist2 = std::min(min_dist2, dist2);
96  }
97  }
98 
99  const Moose::ElemArg elem_arg = {_current_elem, false};
100  const Moose::StateArg state_arg = Moose::currentState();
101 
102  const auto delta = _delta(elem_arg, state_arg);
103  const auto von_karman_const = _von_karman_const(elem_arg, state_arg);
104  const auto von_karman_const_0 = _von_karman_const_0(elem_arg, state_arg);
105 
106  if (std::sqrt(min_dist2) / delta <= von_karman_const_0 / von_karman_const)
107  return von_karman_const * std::sqrt(min_dist2);
108  else
109  return von_karman_const_0 * delta;
110 }
virtual MooseMesh & mesh()=0
const std::vector< BoundaryName > & _wall_boundary_names
const Moose::Functor< Real > & _von_karman_const_0
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const Point & faceCentroid() const
MeshBase & mesh
static InputParameters validParams()
int delta(unsigned int i, unsigned int j)
Delta function, which returns zero if $i j$ and unity if $i=j$.
const std::string & name() const override
Real distance(const Point &p)
virtual const std::string & name() const
const Moose::Functor< Real > & _von_karman_const
const std::vector< const FaceInfo *> & faceInfo() const
MeshBase & getMesh()
WallDistanceMixingLengthAux(const InputParameters &parameters)
boundary_id_type BoundaryID
unsigned int sideWithBoundaryID(const Elem *const elem, const BoundaryID boundary_id) const
void paramError(const std::string &param, Args... args) const
MooseVariableField< Real > & _var
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
registerMooseObject("NavierStokesApp", WallDistanceMixingLengthAux)
SubProblem & _subproblem
void mooseError(Args &&... args) const
const Elem *const & _current_elem
void addClassDescription(const std::string &doc_string)
static InputParameters validParams()
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
const Moose::Functor< Real > & _delta
const MooseArray< Point > & _q_point
const std::unordered_map< boundary_id_type, std::unordered_set< dof_id_type > > & getBoundariesToActiveSemiLocalElemIds() const
StateArg currentState()
uint8_t dof_id_type