1 #ifndef VERTEXCFD_CLOSURE_INCOMPRESSIBLESPALARTALLMARASSOURCE_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_INCOMPRESSIBLESPALARTALLMARASSOURCE_IMPL_HPP
4 #include "utils/VertexCFD_Utils_SmoothMath.hpp"
5 #include "utils/VertexCFD_Utils_VectorField.hpp"
7 #include <Panzer_HierarchicParallelism.hpp>
13 namespace ClosureModel
16 template<
class EvalType,
class Traits,
int NumSpaceDim>
17 IncompressibleSpalartAllmarasSource<EvalType, Traits, NumSpaceDim>::
18 IncompressibleSpalartAllmarasSource(
const panzer::IntegrationRule& ir)
19 : _sa_var(
"spalart_allmaras_variable", ir.dl_scalar)
20 , _distance(
"distance", ir.dl_scalar)
21 , _grad_sa_var(
"GRAD_spalart_allmaras_variable", ir.dl_vector)
22 , _nu(
"kinematic_viscosity", ir.dl_scalar)
32 , _c_w1(_c_b1 / (_kappa * _kappa) + (1.0 + _c_b2) / _sigma)
36 , _sa_source(
"SOURCE_spalart_allmaras_equation", ir.dl_scalar)
37 , _sa_prod(
"PRODUCTION_spalart_allmaras_equation", ir.dl_scalar)
38 , _sa_dest(
"DESTRUCTION_spalart_allmaras_equation", ir.dl_scalar)
41 this->addDependentField(_sa_var);
42 this->addDependentField(_distance);
43 this->addDependentField(_grad_sa_var);
44 this->addDependentField(_nu);
46 Utils::addDependentVectorField(
47 *
this, ir.dl_vector, _grad_velocity,
"GRAD_velocity_");
50 this->addEvaluatedField(_sa_source);
51 this->addEvaluatedField(_sa_prod);
52 this->addEvaluatedField(_sa_dest);
55 this->setName(
"Spalart-Allmaras Incompressible Source "
56 + std::to_string(num_space_dim) +
"D");
60 template<
class EvalType,
class Traits,
int NumSpaceDim>
61 void IncompressibleSpalartAllmarasSource<EvalType, Traits, NumSpaceDim>::
62 evaluateFields(
typename Traits::EvalData workset)
64 auto policy = panzer::HP::inst().teamPolicy<scalar_type, PHX::Device>(
66 Kokkos::parallel_for(this->getName(), policy, *
this);
70 template<
class EvalType,
class Traits,
int NumSpaceDim>
71 KOKKOS_INLINE_FUNCTION
void
72 IncompressibleSpalartAllmarasSource<EvalType, Traits, NumSpaceDim>::operator()(
73 const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team)
const
75 const int cell = team.league_rank();
76 const int num_point = _sa_var.extent(1);
77 const double smooth_tol = 1.0e-8;
84 Kokkos::TeamThreadRange(team, 0, num_point), [&](
const int point) {
86 const auto sa_var = _sa_var(cell, point);
87 const auto d = _distance(cell, point);
88 const scalar_type sa_ramp
89 = SmoothMath::ramp(sa_var, -smooth_tol, smooth_tol);
92 scalar_type S2 = pow(_grad_velocity[0](cell, point, 1)
93 - _grad_velocity[1](cell, point, 0),
96 if (num_space_dim == 3)
98 S2 += pow(_grad_velocity[1](cell, point, 2)
99 - _grad_velocity[2](cell, point, 1),
101 + pow(_grad_velocity[2](cell, point, 0)
102 - _grad_velocity[0](cell, point, 2),
106 const scalar_type S = SmoothMath::max(sqrt(S2), smooth_tol, 0.0);
109 const scalar_type chi = sa_var / _nu(cell, point);
110 const scalar_type f_v1 = pow(chi, 3.0)
111 / (pow(chi, 3.0) + pow(_c_v1, 3.0));
112 const scalar_type f_v2 = 1.0 - chi / (1.0 + chi * f_v1);
113 const scalar_type f_t2 = _c_t3 * exp(-_c_t4 * chi * chi);
116 const scalar_type Sbar = sa_var * f_v2 / (_kappa * _kappa * d * d);
119 scalar_type Stilda = S;
121 if (Sbar > -_c_v2 * S)
127 Stilda += S * (_c_v2 * _c_v2 * S + _c_v3 * Sbar)
128 / ((_c_v3 - 2 * _c_v2) * S - Sbar);
132 if (sqrt(pow(Stilda, 2.0)) < smooth_tol)
136 Stilda = -smooth_tol;
145 const scalar_type sa_prod_pos = _c_b1 * (1.0 - f_t2) * Stilda
147 const scalar_type sa_prod_neg = _c_b1 * (1.0 - _c_t3) * S * sa_var;
149 _sa_prod(cell, point) = sa_ramp * sa_prod_pos
150 + (1.0 - sa_ramp) * sa_prod_neg;
153 const scalar_type r_sa = sa_var
154 / (Stilda * _kappa * _kappa * d * d);
155 const scalar_type r = SmoothMath::min(r_sa, _rlim, smooth_tol);
156 const scalar_type g = r + _c_w2 * (pow(r, 6.0) - r);
157 const scalar_type f_w = g
158 * pow((1.0 + pow(_c_w3, 6.0))
159 / (pow(g, 6.0) + pow(_c_w3, 6.0)),
163 const scalar_type sa_dest_pos
164 = -(_c_w1 * f_w - _c_b1 * f_t2 / (_kappa * _kappa))
165 * pow(sa_var / d, 2.0);
166 const scalar_type sa_dest_neg = _c_w1 * pow(sa_var / d, 2.0);
168 _sa_dest(cell, point) = sa_ramp * sa_dest_pos
169 + (1.0 - sa_ramp) * sa_dest_neg;
172 _sa_source(cell, point) = _sa_prod(cell, point)
173 + _sa_dest(cell, point);
176 for (
int i = 0; i < num_space_dim; ++i)
178 _sa_source(cell, point)
179 += _c_b2 / _sigma * pow(_grad_sa_var(cell, point, i), 2.0);