Documentation 6b54b78464
Loading...
Searching...
No Matches
trans_sources.hpp
Go to the documentation of this file.
1/*!
2 * \file trans_sources.hpp
3 * \brief Numerics classes for integration of source terms in transition problems.
4 * \version 8.5.0 "Harrier"
5 *
6 * SU2 Project Website: https://su2code.github.io
7 *
8 * The SU2 Project is maintained by the SU2 Foundation
9 * (http://su2foundation.org)
10 *
11 * Copyright 2012-2026, SU2 Contributors (cf. AUTHORS.md)
12 *
13 * SU2 is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
17 *
18 * SU2 is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
25 */
26
27#pragma once
28#include "../../../../../Common/include/toolboxes/geometry_toolbox.hpp"
29#include "../../scalar/scalar_sources.hpp"
31
32/*!
33 * \class CSourcePieceWise_TranLM
34 * \brief Class for integrating the source terms of the LM transition model equations.
35 * \ingroup SourceDiscr
36 * \author S. Kang.
37 */
38template <class FlowIndices>
39class CSourcePieceWise_TransLM final : public CNumerics {
40 private:
41 const FlowIndices idx; /*!< \brief Object to manage the access to the flow primitives. */
42
43 const LM_ParsedOptions options;
44
45 /*--- LM Closure constants ---*/
46 const su2double c_e1 = 1.0;
47 const su2double c_a1 = 2.0;
48 const su2double c_e2 = 50.0;
49 const su2double c_a2 = 0.06;
50 const su2double sigmaf = 1.0;
51 const su2double s1 = 2.0;
52 const su2double c_theta = 0.03;
53 const su2double c_CF = 0.6;
54 const su2double sigmat = 2.0;
55
56 TURB_FAMILY TurbFamily;
57 su2double hRoughness;
58
59 su2double IntermittencySep = 1.0;
60 su2double IntermittencyEff = 1.0;
61
62 su2double Residual[2];
63 su2double* Jacobian_i[2];
64 su2double Jacobian_Buffer[4]; // Static storage for the Jacobian (which needs to be pointer for return type).
65
66 TransLMCorrelations TransCorrelations;
67
68 public:
69 /*!
70 * \brief Constructor of the class.
71 * \param[in] val_nDim - Number of dimensions of the problem.
72 * \param[in] val_nVar - Number of variables of the problem.
73 * \param[in] config - Definition of the particular problem.
74 */
75 CSourcePieceWise_TransLM(unsigned short val_nDim, unsigned short val_nVar, const CConfig* config)
76 : CNumerics(val_nDim, 2, config), idx(val_nDim, config->GetnSpecies()), options(config->GetLMParsedOptions()){
77 /*--- "Allocate" the Jacobian using the static buffer. ---*/
78 Jacobian_i[0] = Jacobian_Buffer;
79 Jacobian_i[1] = Jacobian_Buffer + 2;
80
81 TurbFamily = TurbModelFamily(config->GetKind_Turb_Model());
82
83 hRoughness = config->GethRoughness();
84
85 TransCorrelations.SetOptions(options);
86
87 }
88
89 /*!
90 * \brief Residual for source term integration.
91 * \param[in] config - Definition of the particular problem.
92 * \return A lightweight const-view (read-only) of the residual/flux and Jacobians.
93 */
94 ResidualType<> ComputeResidual(const CConfig* config) override {
95 /*--- ScalarVar[0] = k, ScalarVar[0] = w, TransVar[0] = gamma, and TransVar[0] = ReThetaT ---*/
96 /*--- dU/dx = PrimVar_Grad[1][0] ---*/
105 AD::SetPreaccIn(&V_i[idx.Velocity()], nDim);
106 AD::SetPreaccIn(PrimVar_Grad_i, nDim + idx.Velocity(), nDim);
108
109 su2double VorticityMag =
111
112 const su2double vel_u = V_i[idx.Velocity()];
113 const su2double vel_v = V_i[1 + idx.Velocity()];
114 const su2double vel_w = (nDim == 3) ? V_i[2 + idx.Velocity()] : 0.0;
115
116 const su2double Velocity_Mag = sqrt(vel_u * vel_u + vel_v * vel_v + vel_w * vel_w);
117
118 AD::SetPreaccIn(V_i[idx.Density()], V_i[idx.LaminarViscosity()], V_i[idx.EddyViscosity()]);
119
120 Density_i = V_i[idx.Density()];
121 Laminar_Viscosity_i = V_i[idx.LaminarViscosity()];
122 Eddy_Viscosity_i = V_i[idx.EddyViscosity()];
123
124 Residual[0] = 0.0;
125 Residual[1] = 0.0;
126 Jacobian_i[0][0] = 0.0;
127 Jacobian_i[0][1] = 0.0;
128 Jacobian_i[1][0] = 0.0;
129 Jacobian_i[1][1] = 0.0;
130
131 if (dist_i > 1e-10) {
132 su2double Tu = 1.0;
133 if (TurbFamily == TURB_FAMILY::KW) Tu = max(100.0 * sqrt(2.0 * ScalarVar_i[0] / 3.0) / Velocity_Mag, 0.027);
134 if (TurbFamily == TURB_FAMILY::SA) Tu = config->GetTurbulenceIntensity_FreeStream() * 100;
135
136 /*--- Corr_RetC correlation*/
137 const su2double Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu, TransVar_i[1]);
138
139 /*--- F_length correlation*/
140 const su2double Corr_F_length = TransCorrelations.FLength_Correlations(Tu, TransVar_i[1]);
141
142 /*--- F_length ---*/
143 su2double F_length = 0.0;
144 if (TurbFamily == TURB_FAMILY::KW) {
146 const su2double f_sub = exp(-pow(r_omega / 200.0, 2));
147 F_length = Corr_F_length * (1. - f_sub) + 40.0 * f_sub;
148 }
149 if (TurbFamily == TURB_FAMILY::SA) F_length = Corr_F_length;
150
151 /*--- F_onset ---*/
152 su2double R_t = 1.0;
153 if (TurbFamily == TURB_FAMILY::KW) R_t = Density_i * ScalarVar_i[0] / Laminar_Viscosity_i / ScalarVar_i[1];
154 if (TurbFamily == TURB_FAMILY::SA) R_t = Eddy_Viscosity_i / Laminar_Viscosity_i;
155
157 const su2double F_onset1 = Re_v / (2.193 * Corr_Rec);
158 su2double F_onset2 = 1.0;
159 su2double F_onset3 = 1.0;
160 if (TurbFamily == TURB_FAMILY::KW) {
161 F_onset2 = min(max(F_onset1, pow(F_onset1, 4.0)), 2.0);
162 F_onset3 = max(1.0 - pow(R_t / 2.5, 3.0), 0.0);
163 }
164 if (TurbFamily == TURB_FAMILY::SA) {
165 F_onset2 = min(max(F_onset1, pow(F_onset1, 4.0)), 4.0);
166 F_onset3 = max(2.0 - pow(R_t / 2.5, 3.0), 0.0);
167 }
168 const su2double F_onset = max(F_onset2 - F_onset3, 0.0);
169
170 /*-- Gradient of velocity magnitude ---*/
171
172 su2double dU_dx = 0.5 / Velocity_Mag * (2. * vel_u * PrimVar_Grad_i[1][0] + 2. * vel_v * PrimVar_Grad_i[2][0]);
173 if (nDim == 3) dU_dx += 0.5 / Velocity_Mag * (2. * vel_w * PrimVar_Grad_i[3][0]);
174
175 su2double dU_dy = 0.5 / Velocity_Mag * (2. * vel_u * PrimVar_Grad_i[1][1] + 2. * vel_v * PrimVar_Grad_i[2][1]);
176 if (nDim == 3) dU_dy += 0.5 / Velocity_Mag * (2. * vel_w * PrimVar_Grad_i[3][1]);
177
178 su2double dU_dz = 0.0;
179 if (nDim == 3)
180 dU_dz =
181 0.5 / Velocity_Mag *
182 (2. * vel_u * PrimVar_Grad_i[1][2] + 2. * vel_v * PrimVar_Grad_i[2][2] + 2. * vel_w * PrimVar_Grad_i[3][2]);
183
184 su2double du_ds = vel_u / Velocity_Mag * dU_dx + vel_v / Velocity_Mag * dU_dy;
185 if (nDim == 3) du_ds += vel_w / Velocity_Mag * dU_dz;
186
187 /*-- Calculate blending function f_theta --*/
188 su2double time_scale = 500.0 * Laminar_Viscosity_i / Density_i / Velocity_Mag / Velocity_Mag;
189 if (options.LM2015)
190 time_scale = min(time_scale,
192 const su2double theta_bl = TransVar_i[1] * Laminar_Viscosity_i / Density_i / Velocity_Mag;
193 const su2double delta_bl = 7.5 * theta_bl;
194 const su2double delta = 50.0 * VorticityMag * dist_i / Velocity_Mag * delta_bl + 1e-20;
195
196 su2double f_wake = 0.0;
197 if (TurbFamily == TURB_FAMILY::KW) {
199 f_wake = exp(-pow(re_omega / (1.0e+05), 2));
200 }
201 if (TurbFamily == TURB_FAMILY::SA) f_wake = 1.0;
202
203 const su2double var1 = (TransVar_i[0] - 1.0 / c_e2) / (1.0 - 1.0 / c_e2);
204 const su2double var2 = 1.0 - pow(var1, 2.0);
205 const su2double f_theta = min(max(f_wake * exp(-pow(dist_i / delta, 4)), var2), 1.0);
206 const su2double f_turb = exp(-pow(R_t / 4, 4));
207
208 su2double f_theta_2 = 0.0;
209 if (options.LM2015)
210 f_theta_2 = min(f_wake * exp(-pow(dist_i / delta, 4.0)), 1.0);
211
212 /*--- Corr_Ret correlation*/
213 const su2double Corr_Ret_lim = 20.0;
214 su2double f_lambda = 1.0;
215
216 su2double Retheta_Error = 200.0, Retheta_old = 0.0;
217 su2double lambda = 0.0;
218 su2double Corr_Ret = 20.0;
219
220 for (int iter = 0; iter < 100; iter++) {
221 su2double theta = Corr_Ret * Laminar_Viscosity_i / Density_i / Velocity_Mag;
222 lambda = Density_i * theta * theta / Laminar_Viscosity_i * du_ds;
223 lambda = min(max(-0.1, lambda), 0.1);
224
225 if (lambda <= 0.0) {
226 f_lambda = 1. - (-12.986 * lambda - 123.66 * lambda * lambda - 405.689 * lambda * lambda * lambda) *
227 exp(-pow(Tu / 1.5, 1.5));
228 } else {
229 f_lambda = 1. + 0.275 * (1. - exp(-35. * lambda)) * exp(-Tu / 0.5);
230 }
231
232 if (Tu <= 1.3) {
233 Corr_Ret = f_lambda * (1173.51 - 589.428 * Tu + 0.2196 / Tu / Tu);
234 } else {
235 Corr_Ret = 331.5 * f_lambda * pow(Tu - 0.5658, -0.671);
236 }
237 Corr_Ret = max(Corr_Ret, Corr_Ret_lim);
238
239 Retheta_Error = fabs(Retheta_old - Corr_Ret) / Retheta_old;
240
241 if (Retheta_Error < 0.0000001) {
242 break;
243 }
244
245 Retheta_old = Corr_Ret;
246 }
247
248 /*-- Corr_RetT_SCF Correlations--*/
249 su2double ReThetat_SCF = 0.0;
250 if (options.LM2015) {
251 su2double VelocityNormalized[3];
252 VelocityNormalized[0] = vel_u / Velocity_Mag;
253 VelocityNormalized[1] = vel_v / Velocity_Mag;
254 if (nDim == 3) VelocityNormalized[2] = vel_w / Velocity_Mag;
255
256 su2double StreamwiseVort = 0.0;
257 for (auto iDim = 0u; iDim < nDim; iDim++) {
258 StreamwiseVort += VelocityNormalized[iDim] * Vorticity_i[iDim];
259 }
260 StreamwiseVort = abs(StreamwiseVort);
261
262 const su2double H_CF = StreamwiseVort * dist_i / Velocity_Mag;
263 const su2double DeltaH_CF = H_CF * (1.0 + min(Eddy_Viscosity_i / Laminar_Viscosity_i, 0.4));
264 const su2double DeltaH_CF_Minus = max(-1.0 * (0.1066 - DeltaH_CF), 0.0);
265 const su2double DeltaH_CF_Plus = max(0.1066 - DeltaH_CF, 0.0);
266 const su2double fDeltaH_CF_Minus = 75.0 * tanh(DeltaH_CF_Minus / 0.0125);
267 const su2double fDeltaH_CF_Plus = 6200 * DeltaH_CF_Plus + 50000 * DeltaH_CF_Plus * DeltaH_CF_Plus;
268
269 const su2double toll = 1e-5;
270 su2double error = toll + 1.0;
271 su2double thetat_SCF = 0.0;
272 su2double rethetat_SCF_old = 20.0;
273 const int nMax = 100;
274
275 int iter;
276 for (iter = 0; iter < nMax && error > toll; iter++) {
277 thetat_SCF = rethetat_SCF_old * Laminar_Viscosity_i / (Density_i * (Velocity_Mag / 0.82));
278 thetat_SCF = max(1e-20, thetat_SCF);
279
280 ReThetat_SCF = -35.088 * log(hRoughness / thetat_SCF) + 319.51 + fDeltaH_CF_Plus - fDeltaH_CF_Minus;
281
282 error = abs(ReThetat_SCF - rethetat_SCF_old) / rethetat_SCF_old;
283
284 rethetat_SCF_old = ReThetat_SCF;
285 }
286 }
287
288 /*-- production term of Intermeittency(Gamma) --*/
289 const su2double Pg =
290 F_length * c_a1 * Density_i * StrainMag_i * sqrt(F_onset * TransVar_i[0]) * (1.0 - c_e1 * TransVar_i[0]);
291
292 /*-- destruction term of Intermeittency(Gamma) --*/
293 const su2double Dg = c_a2 * Density_i * VorticityMag * TransVar_i[0] * f_turb * (c_e2 * TransVar_i[0] - 1.0);
294
295 /*-- production term of ReThetaT --*/
296 const su2double PRethetat = c_theta * Density_i / time_scale * (Corr_Ret - TransVar_i[1]) * (1.0 - f_theta);
297
298 /*-- destruction term of ReThetaT --*/
299 // It should not be with the minus sign but I put for consistency
300 su2double DRethetat = 0.0;
301 if (options.LM2015)
302 DRethetat = -c_theta * (Density_i / time_scale) * c_CF * min(ReThetat_SCF - TransVar_i[1], 0.0) * f_theta_2;
303
304 /*--- Source ---*/
305 Residual[0] += (Pg - Dg) * Volume;
306 Residual[1] += (PRethetat - DRethetat) * Volume;
307
308 /*--- Implicit part ---*/
309 Jacobian_i[0][0] = (F_length * c_a1 * StrainMag_i * sqrt(F_onset) *
310 (0.5 * pow(TransVar_i[0], -0.5) - 1.5 * c_e1 * pow(TransVar_i[0], 0.5)) -
311 c_a2 * VorticityMag * f_turb * (2.0 * c_e2 * TransVar_i[0] - 1.0)) *
312 Volume;
313 Jacobian_i[0][1] = 0.0;
314 Jacobian_i[1][0] = 0.0;
315 Jacobian_i[1][1] = -c_theta / time_scale * (1.0 - f_theta) * Volume;
316 if (options.LM2015 && ReThetat_SCF - TransVar_i[1] < 0)
317 Jacobian_i[1][1] += (c_theta / time_scale) * c_CF * f_theta_2 * Volume;
318 }
319
320 AD::SetPreaccOut(Residual, nVar);
322
323 return ResidualType<>(Residual, Jacobian_i, nullptr);
324 }
325};
Main class for defining the problem; basically this class reads the configuration file,...
Definition CConfig.hpp:64
TURB_MODEL GetKind_Turb_Model(void) const
Get the kind of the turbulence model.
Definition CConfig.hpp:4693
su2double GetTurbulenceIntensity_FreeStream(void) const
Get the value of the non-dimensionalized freestream turbulence intensity.
Definition CConfig.hpp:2143
su2double GethRoughness(void) const
Get RMS roughness for Transtion model from config.
Definition CConfig.hpp:4711
Class for defining the numerical methods.
Definition CNumerics.hpp:48
su2double Eddy_Viscosity_i
Eddy viscosity at point i.
Definition CNumerics.hpp:77
unsigned short nVar
Number of dimensions and variables.
Definition CNumerics.hpp:52
CMatrixView< const su2double > ScalarVar_Grad_i
Gradient of scalar variables at point i.
Definition CNumerics.hpp:151
su2double StrainMag_i
Definition CNumerics.hpp:180
CMatrixView< const su2double > TransVar_Grad_i
Gradient of turbulent variables at point i.
Definition CNumerics.hpp:153
su2double Volume
Volume of the control volume around point i.
Definition CNumerics.hpp:173
su2double Density_i
Density at point i.
Definition CNumerics.hpp:89
const su2double * Vorticity_i
Definition CNumerics.hpp:179
const su2double * ScalarVar_i
Vector of scalar variables at point i.
Definition CNumerics.hpp:131
su2double Laminar_Viscosity_i
Laminar viscosity at point i.
Definition CNumerics.hpp:67
CMatrixView< const su2double > PrimVar_Grad_i
Gradient of primitive variables at point i.
Definition CNumerics.hpp:147
const su2double * V_i
Vector of primitive variables at point i.
Definition CNumerics.hpp:122
const su2double * TransVar_i
Vector of turbulent variables at point i.
Definition CNumerics.hpp:138
su2double dist_i
Distance of point i to the nearest wall.
Definition CNumerics.hpp:107
unsigned short nDim
Definition CNumerics.hpp:52
su2double LocalGridLength_i
Local grid length at point i.
Definition CNumerics.hpp:160
const su2double delta[3][3]
Identity matrix.
Definition CNumerics.hpp:62
Definition trans_sources.hpp:39
CSourcePieceWise_TransLM(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config)
Constructor of the class.
Definition trans_sources.hpp:75
ResidualType ComputeResidual(const CConfig *config) override
Residual for source term integration.
Definition trans_sources.hpp:94
Class for LM model's correlation functions.
Definition trans_correlations.hpp:35
void SetOptions(const LM_ParsedOptions val_options)
Set LM options.
Definition trans_correlations.hpp:46
su2double FLength_Correlations(const su2double Tu, const su2double Re_theta_t) const
Compute FLength from correlations.
Definition trans_correlations.hpp:126
su2double ReThetaC_Correlations(const su2double Tu, const su2double Re_theta_t) const
Compute Re_theta_c from correlations.
Definition trans_correlations.hpp:56
passivedouble su2double
Definition code_config.hpp:181
FORCEINLINE ARRAY_T exp(const ARRAY_T &x)
Definition special_vectorization.hpp:156
FORCEINLINE ARRAY_T sqrt(const ARRAY_T &x)
Definition special_vectorization.hpp:116
FORCEINLINE ARRAY_T pow(const ARRAY_T &a, const ARRAY_T &b)
Definition special_vectorization.hpp:179
FORCEINLINE ARRAY_T abs(const ARRAY_T &x)
Definition special_vectorization.hpp:117
void StartPreacc()
Starts a new preaccumulation section and sets the input variables.
Definition ad_structure.hpp:215
void EndPreacc()
Ends a preaccumulation section and computes the local Jacobi matrix of a code section using the varia...
Definition ad_structure.hpp:243
void SetPreaccOut(Ts &&... data)
Sets the scalar outputs of a preaccumulation section.
Definition ad_structure.hpp:222
void SetPreaccIn(Ts &&... data)
Sets the scalar inputs of a preaccumulation section.
Definition ad_structure.hpp:186
TURB_FAMILY
Families of turbulence models.
Definition option_structure.hpp:1080
@ SA
Spalart-Allmaras variants.
@ KW
k-w models.
TURB_FAMILY TurbModelFamily(TURB_MODEL model)
Associate turb models with their family.
Definition option_structure.hpp:1088
Return type used in some "ComputeResidual" overloads to give a const-view of the internally stored fl...
Definition CNumerics.hpp:218
Structure containing parsed LM options.
Definition option_structure.hpp:1417
bool LM2015
Use cross-flow corrections.
Definition option_structure.hpp:1419
Numerics class for the LM model's correlation functions.