1 #ifndef VERTEXCFD_CLOSURE_INCOMPRESSIBLESSTEDDYVISCOSITY_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_INCOMPRESSIBLESSTEDDYVISCOSITY_IMPL_HPP
4 #include "utils/VertexCFD_Utils_SmoothMath.hpp"
5 #include "utils/VertexCFD_Utils_VectorField.hpp"
7 #include <Panzer_HierarchicParallelism.hpp>
11 namespace ClosureModel
14 template<
class EvalType,
class Traits,
int NumSpaceDim>
15 IncompressibleSSTEddyViscosity<EvalType, Traits, NumSpaceDim>::
16 IncompressibleSSTEddyViscosity(
const panzer::IntegrationRule& ir,
17 const Teuchos::ParameterList& user_params,
18 bool on_wall_boundary)
19 : _turb_kinetic_energy(
"turb_kinetic_energy", ir.dl_scalar)
20 , _turb_specific_dissipation_rate(
"turb_specific_dissipation_rate",
22 , _grad_turb_kinetic_energy(
"GRAD_turb_kinetic_energy", ir.dl_vector)
23 , _grad_turb_specific_dissipation_rate(
24 "GRAD_turb_specific_dissipation_rate", ir.dl_vector)
25 , _distance(
"distance", ir.dl_scalar)
26 , _rho(
"density", ir.dl_scalar)
27 , _nu(
"kinematic_viscosity", ir.dl_scalar)
31 , _on_wall_boundary(on_wall_boundary)
32 , _nu_t(
"turbulent_eddy_viscosity", ir.dl_scalar)
33 , _sst_blending_function(
"sst_blending_function", ir.dl_scalar)
36 if (user_params.isSublist(
"Turbulence Parameters"))
38 const Teuchos::ParameterList turb_list
39 = user_params.sublist(
"Turbulence Parameters");
41 if (turb_list.isSublist(
"SST K-Omega Parameters"))
43 const Teuchos::ParameterList sst_list
44 = turb_list.sublist(
"SST K-Omega Parameters");
46 if (sst_list.isType<
double>(
"beta_star"))
48 _beta_star = sst_list.get<
double>(
"beta_star");
51 if (sst_list.isType<
double>(
"a_1"))
53 _a_1 = sst_list.get<
double>(
"a_1");
56 if (turb_list.isType<
double>(
"sigma_w2"))
58 _sigma_w2 = turb_list.get<
double>(
"sigma_w2");
63 this->addDependentField(_turb_kinetic_energy);
64 this->addDependentField(_turb_specific_dissipation_rate);
65 this->addDependentField(_grad_turb_kinetic_energy);
66 this->addDependentField(_grad_turb_specific_dissipation_rate);
67 if (!_on_wall_boundary)
69 this->addDependentField(_distance);
71 this->addDependentField(_rho);
72 this->addDependentField(_nu);
74 Utils::addDependentVectorField(
75 *
this, ir.dl_vector, _grad_velocity,
"GRAD_velocity_");
78 this->addEvaluatedField(_sst_blending_function);
79 this->addEvaluatedField(_nu_t);
82 this->setName(
"Incompressible SST Turbulent Eddy Viscosity "
83 + std::to_string(num_space_dim) +
"D");
87 template<
class EvalType,
class Traits,
int NumSpaceDim>
88 void IncompressibleSSTEddyViscosity<EvalType, Traits, NumSpaceDim>::evaluateFields(
89 typename Traits::EvalData workset)
93 if constexpr (Sacado::IsADType<scalar_type>::value)
95 const int fad_size = Kokkos::dimension_scalar(_nu_t.get_view());
96 bytes = scratch_view::shmem_size(_nu_t.extent(1), NUM_TMPS, fad_size);
100 bytes = scratch_view::shmem_size(_nu_t.extent(1), NUM_TMPS);
102 auto policy = panzer::HP::inst().teamPolicy<scalar_type, PHX::Device>(
104 policy.set_scratch_size(0, Kokkos::PerTeam(bytes));
105 Kokkos::parallel_for(this->getName(), policy, *
this);
109 template<
class EvalType,
class Traits,
int NumSpaceDim>
110 KOKKOS_INLINE_FUNCTION
void
111 IncompressibleSSTEddyViscosity<EvalType, Traits, NumSpaceDim>::operator()(
112 const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team)
const
118 const int cell = team.league_rank();
119 const int num_point = _nu_t.extent(1);
120 const double max_tol = 1.0e-10;
122 scratch_view tmp_field;
123 if constexpr (Sacado::IsADType<scalar_type>::value)
125 const int fad_size = Kokkos::dimension_scalar(_nu_t.get_view());
127 = scratch_view(team.team_shmem(), num_point, NUM_TMPS, fad_size);
131 tmp_field = scratch_view(team.team_shmem(), num_point, NUM_TMPS);
134 Kokkos::parallel_for(
135 Kokkos::TeamThreadRange(team, 0, num_point), [&](
const int point) {
136 auto&& vort_mag_x_F2 = _nu_t(cell, point);
138 for (
int i = 0; i < num_space_dim; ++i)
140 for (
int j = i + 1; j < num_space_dim; ++j)
143 += pow(_grad_velocity[i](cell, point, j)
144 - _grad_velocity[j](cell, point, i),
151 vort_mag_x_F2 = sqrt(SmoothMath::max(vort_mag_x_F2, max_tol, 0.0));
156 auto&& tke = tmp_field(point, TKE);
157 tke = SmoothMath::max(
158 _turb_kinetic_energy(cell, point), max_tol, 0.0);
159 auto&& omega = tmp_field(point, OMEGA);
160 omega = SmoothMath::max(
161 _turb_specific_dissipation_rate(cell, point), max_tol, 0.0);
163 _sst_blending_function(cell, point) = 1.0;
165 if (!_on_wall_boundary)
167 if (_distance(cell, point) > max_tol)
171 auto&& C = _sst_blending_function(cell, point);
173 for (
int j = 0; j < num_space_dim; ++j)
175 C += _grad_turb_kinetic_energy(cell, point, j)
176 * _grad_turb_specific_dissipation_rate(
183 2.0 * _rho(cell, point) * _sigma_w2 * C / omega,
199 auto&& A = tmp_field(point, LOG_REGION);
201 / (_beta_star * omega * _distance(cell, point));
207 auto&& B = tmp_field(point, NEAR_WALL);
208 B = 500.0 * _nu(cell, point)
209 / (omega * pow(_distance(cell, point), 2));
215 C = 4.0 * _rho(cell, point) * _sigma_w2 * tke
216 / (C * pow(_distance(cell, point), 2));
220 _sst_blending_function(cell, point) = tanh(pow(
221 SmoothMath::min(SmoothMath::max(A, B, 0.0), C, 0.0), 4));
226 *= tanh(pow(SmoothMath::max(2.0 * A, B, 0.0), 2));
234 / SmoothMath::max(_a_1 * omega, vort_mag_x_F2, max_tol);