12 #include "libmesh/vector_value.h" 18 delta(
unsigned int i,
unsigned int j)
29 return a > 0 ? 1 : (
a < 0 ? -1 : 0);
33 getIndex(
const Real &
p,
const std::vector<Real> & bounds)
35 if (
p < bounds.front() ||
p > bounds.back())
38 for (
unsigned int i = 1; i < bounds.size(); ++i)
42 return bounds.size() - 2;
47 const Real &
Re,
const Real &
rho,
const Real &
mu,
const Real & drho,
const Real & dmu)
49 return Re * (drho / std::max(
rho, 1e-6) - dmu / std::max(
mu, 1e-8));
60 return (
k * (
mu * dcp +
cp * dmu) -
mu *
cp * dk) / std::max(
k *
k, 1e-8);
67 using std::log, std::sqrt,
std::pow, std::max, std::abs;
70 constexpr
int MAX_ITERS{50};
71 constexpr
Real REL_TOLERANCE{1e-6};
74 mooseAssert(
mu > 0,
"Need a strictly positive viscosity");
75 mooseAssert(
rho > 0,
"Need a strictly positive density");
76 mooseAssert(u > 0,
"Need a strictly positive velocity");
77 mooseAssert(dist > 0,
"Need a strictly positive wall distance");
87 T u_star =
max(1e-20, (-b_c +
sqrt(
pow(b_c, 2) + 4.0 * a_c * c_c)) / (2.0 * a_c));
90 for (
int i = 0; i < MAX_ITERS; ++i)
95 T new_u_star =
max(1e-20, u_star - residual /
deriv);
101 if (rel_err < REL_TOLERANCE)
105 mooseException(
"Could not find the wall friction velocity (mu: ",
119 template <
typename T>
123 using std::max, std::log, std::abs;
127 constexpr
int MAX_ITERS{10};
128 constexpr
Real REL_TOLERANCE{1e-2};
131 mooseAssert(
mu > 0,
"Need a strictly positive viscosity");
132 mooseAssert(u > 0,
"Need a strictly positive velocity");
133 mooseAssert(
rho > 0,
"Need a strictly positive density");
134 mooseAssert(dist > 0,
"Need a strictly positive wall distance");
136 Real yPlusLast = 0.0;
137 T yPlus = dist * u *
rho /
mu;
140 unsigned int iters = 0;
149 ++iters < MAX_ITERS);
158 template <
typename T>
171 template <
typename T>
179 const unsigned int rz_radial_coord)
181 const auto & grad_u = u.
gradient(elem_arg, state);
182 const T Sij_xx = 2.0 * grad_u(0);
189 const T grad_xx = grad_u(0);
203 const auto & grad_v = (*v).gradient(elem_arg, state);
204 Sij_xy = grad_u(1) + grad_v(0);
205 Sij_yy = 2.0 * grad_v(1);
211 trace += Sij_yy / 3.0;
215 const auto & grad_w = (*w).gradient(elem_arg, state);
217 Sij_xz = grad_u(2) + grad_w(0);
218 Sij_yz = grad_v(2) + grad_w(1);
219 Sij_zz = 2.0 * grad_w(2);
227 trace += Sij_zz / 3.0;
233 mooseAssert(elem_arg.
elem,
"ElemArg must reference an element for cylindrical calculations.");
235 mooseAssert(
radius > 0.0,
"Axisymmetric radial coordinate should be positive.");
238 switch (rz_radial_coord)
247 mooseError(
"Unsupported axisymmetric radial coordinate index: ", rz_radial_coord);
250 mooseAssert(radial_functor,
251 "The functor corresponding to the axisymmetric radial velocity must be provided.");
252 const T radial_velocity = (*radial_functor)(elem_arg, state);
253 Sij_zz = 2.0 * radial_velocity /
radius;
254 grad_zz = radial_velocity /
radius;
255 trace += Sij_zz / 3.0;
260 return (Sij_xx -
trace) * grad_xx + Sij_xy * grad_xy + Sij_xz * grad_xz + Sij_xy * grad_yx +
261 (Sij_yy -
trace) * grad_yy + Sij_yz * grad_yz + Sij_xz * grad_zx + Sij_yz * grad_zy +
262 (Sij_zz -
trace) * grad_zz;
270 const unsigned int rz_radial_coord);
278 const unsigned int rz_radial_coord);
285 const std::set<SubdomainID> & block_ids,
286 std::unordered_set<const Elem *> & wall_bounded)
289 wall_bounded.clear();
294 auto gather_functor = [&subproblem, &wall_bounded](
const processor_id_type libmesh_dbg_var(pid),
295 const std::vector<dof_id_type> & elem_ids,
296 std::vector<unsigned char> & data_to_fill)
298 mooseAssert(pid != subproblem.
processor_id(),
"We shouldn't be gathering from ourselves.");
299 data_to_fill.resize(elem_ids.size());
305 const auto elem =
mesh.elem_ptr(elem_ids[i]);
306 data_to_fill[i] = wall_bounded.count(elem) != 0;
310 auto action_functor = [&subproblem, &wall_bounded](
const processor_id_type libmesh_dbg_var(pid),
311 const std::vector<dof_id_type> & elem_ids,
312 const std::vector<unsigned char> & filled_data)
315 "The request filler shouldn't have been ourselves");
316 mooseAssert(elem_ids.size() == filled_data.size(),
"I think these should be the same size");
322 const auto elem =
mesh.elem_ptr(elem_ids[i]);
324 wall_bounded.insert(elem);
329 std::unordered_map<processor_id_type, std::vector<dof_id_type>> elem_ids_requested;
331 for (
const auto & elem : fe_problem.
mesh().
getMesh().active_local_element_ptr_range())
332 if (block_ids.find(elem->subdomain_id()) != block_ids.end())
333 for (
const auto i_side : elem->side_index_range())
337 std::set<BoundaryID> combined_side_bds;
339 combined_side_bds.insert(side_bnds.begin(), side_bnds.end());
340 if (
const auto neighbor = elem->neighbor_ptr(i_side))
342 const auto neighbor_side = neighbor->which_neighbor_am_i(elem);
343 const auto & neighbor_bnds = subproblem.
mesh().
getBoundaryIDs(neighbor, neighbor_side);
344 combined_side_bds.insert(neighbor_bnds.begin(), neighbor_bnds.end());
348 if (neighbor->processor_id() != subproblem.
processor_id() &&
349 block_ids.find(neighbor->subdomain_id()) != block_ids.end())
350 elem_ids_requested[neighbor->processor_id()].push_back(neighbor->id());
353 for (
const auto wall_id : wall_boundary_ids)
354 if (combined_side_bds.count(wall_id))
356 wall_bounded.insert(elem);
361 unsigned char * bool_ex =
nullptr;
363 subproblem.
comm(), elem_ids_requested, gather_functor, action_functor, bool_ex);
371 const std::set<SubdomainID> & block_ids,
372 std::map<
const Elem *, std::vector<Real>> & dist_map)
377 for (
const auto & elem : fe_problem.
mesh().
getMesh().active_local_element_ptr_range())
378 if (block_ids.find(elem->subdomain_id()) != block_ids.end())
379 for (
const auto i_side : elem->side_index_range())
383 std::set<BoundaryID> combined_side_bds;
385 combined_side_bds.insert(side_bnds.begin(), side_bnds.end());
386 if (
const auto neighbor = elem->neighbor_ptr(i_side))
388 const auto neighbor_side = neighbor->which_neighbor_am_i(elem);
389 const std::vector<BoundaryID> & neighbor_bnds =
391 combined_side_bds.insert(neighbor_bnds.begin(), neighbor_bnds.end());
394 for (
const auto wall_id : wall_boundary_ids)
395 if (combined_side_bds.count(wall_id))
400 const auto & neighbor = elem->neighbor_ptr(i_side);
402 const auto & elem_for_fi = elem_has_fi ? elem : neighbor;
403 const auto side = elem_has_fi ? i_side : neighbor->which_neighbor_am_i(elem);
408 dist_map[elem].push_back(dist);
418 const std::set<SubdomainID> & block_ids,
419 std::map<
const Elem *, std::vector<const FaceInfo *>> & face_info_map)
421 face_info_map.clear();
424 for (
const auto & elem : fe_problem.
mesh().
getMesh().active_local_element_ptr_range())
425 if (block_ids.find(elem->subdomain_id()) != block_ids.end())
426 for (
const auto i_side : elem->side_index_range())
430 std::set<BoundaryID> combined_side_bds;
432 combined_side_bds.insert(side_bnds.begin(), side_bnds.end());
433 if (elem->neighbor_ptr(i_side) && !elem->neighbor_ptr(i_side)->is_remote())
435 const auto neighbor = elem->neighbor_ptr(i_side);
436 const auto neighbor_side = neighbor->which_neighbor_am_i(elem);
437 const std::vector<BoundaryID> & neighbor_bnds =
439 combined_side_bds.insert(neighbor_bnds.begin(), neighbor_bnds.end());
442 for (
const auto wall_id : wall_boundary_ids)
443 if (combined_side_bds.count(wall_id))
448 const auto & neighbor = elem->neighbor_ptr(i_side);
450 const auto & elem_for_fi = elem_has_fi ? elem : neighbor;
451 const auto side = elem_has_fi ? i_side : neighbor->which_neighbor_am_i(elem);
454 face_info_map[elem].push_back(fi);
virtual MooseMesh & mesh()=0
int computeSign(const Real &a)
Sign function, returns $+1$ if $a$ is positive and $-1$ if $a$ is negative.
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
void pull_parallel_vector_data(const Communicator &comm, const MapToVectors &queries, GatherFunctor &gather_data, const ActionFunctor &act_on_data, const datum *example)
static constexpr Real von_karman_constant
bool elemHasFaceInfo(const Elem &elem, const Elem *const neighbor)
static constexpr Real min_y_plus
void mooseError(Args &&... args)
T computeSpeed(const libMesh::VectorValue< T > &velocity)
Compute the speed (velocity norm) given the supplied velocity.
Real prandtlPropertyDerivative(const Real &mu, const Real &cp, const Real &k, const Real &dmu, const Real &dcp, const Real &dk)
Computes the derivative of the Prandtl number, $Pr{ C_p}{k}$, with respect to an arbitrary variale $$...
const Point & faceCentroid() const
Real trace(const RealTensor &A, const unsigned int &dim)
int delta(unsigned int i, unsigned int j)
Delta function, which returns zero if $i j$ and unity if $i=j$.
const Parallel::Communicator & comm() const
template Real findUStar< Real >(const Real &mu, const Real &rho, const Real &u, const Real dist)
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...
const Point & neighborCentroid() const
DualNumber< Real, DNDerivativeType, false > ADReal
auto max(const L &left, const R &right)
template Real findyPlus< Real >(const Real &mu, const Real &rho, const Real &u, Real dist)
uint8_t processor_id_type
static const std::string cp
const std::vector< const FaceInfo *> & faceInfo() const
const Point & elemCentroid() const
Real deriv(unsigned n, unsigned alpha, unsigned beta, Real x)
static const std::string mu
const libMesh::Elem * elem
template ADReal findUStar< ADReal >(const ADReal &mu, const ADReal &rho, const ADReal &u, const Real dist)
Real reynoldsPropertyDerivative(const Real &Re, const Real &rho, const Real &mu, const Real &drho, const Real &dmu)
Computes the derivative of the Reynolds number, $Re { Vd}{}$, with respect to an arbitrary variable $...
const Point & normal() const
unsigned int getIndex(const Real &p, const std::vector< Real > &bounds)
Determines the index $i$ in a sorted array such that the input point is within the $i$-th and $i+1$-t...
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...
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
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)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string v
template ADReal computeSpeed< ADReal >(const libMesh::VectorValue< ADReal > &velocity)
static constexpr Real E_turb_constant
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
template ADReal computeShearStrainRateNormSquared< ADReal >(const Moose::Functor< ADReal > &u, const Moose::Functor< ADReal > *v, const Moose::Functor< ADReal > *w, const Moose::ElemArg &elem_arg, const Moose::StateArg &state, const Moose::CoordinateSystemType coord_sys, const unsigned int rz_radial_coord)
GradientType gradient(const ElemArg &elem, const StateArg &state) const
template ADReal findyPlus< ADReal >(const ADReal &mu, const ADReal &rho, const ADReal &u, Real dist)
virtual MooseMesh & mesh() override
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-...
static const std::string velocity
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
T findyPlus(const T &mu, const T &rho, const T &u, Real dist)
Finds the non-dimensional wall distance normalized with the friction velocity Implements a fixed-poin...
template Real computeSpeed< Real >(const libMesh::VectorValue< Real > &velocity)
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
T findUStar(const T &mu, const T &rho, const T &u, Real dist)
Finds the friction velocity using standard velocity wall functions formulation.
processor_id_type processor_id() const
T computeShearStrainRateNormSquared(const Moose::Functor< T > &u, const Moose::Functor< T > *v, const Moose::Functor< T > *w, const Moose::ElemArg &elem_arg, const Moose::StateArg &state, const Moose::CoordinateSystemType coord_sys=Moose::COORD_XYZ, const unsigned int rz_radial_coord=0)
Utility function to compute the shear strain rate.
MooseUnits pow(const MooseUnits &, int)
static const std::string k
auto index_range(const T &sizable)
Point vertex_average() const