Documentation 6b54b78464
Loading...
Searching...
No Matches
viscous_fluxes.hpp
Go to the documentation of this file.
1/*!
2 * \file viscous_fluxes.hpp
3 * \brief Decorator classes for computation of viscous fluxes.
4 * \author P. Gomes, C. Pederson, A. Bueno, F. Palacios, T. Economon
5 * \version 8.5.0 "Harrier"
6 *
7 * SU2 Project Website: https://su2code.github.io
8 *
9 * The SU2 Project is maintained by the SU2 Foundation
10 * (http://su2foundation.org)
11 *
12 * Copyright 2012-2026, SU2 Contributors (cf. AUTHORS.md)
13 *
14 * SU2 is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * SU2 is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
26 */
27
28#pragma once
29
30#include "../../CNumericsSIMD.hpp"
31#include "../../util.hpp"
32#include "../variables.hpp"
33#include "common.hpp"
34
35/*!
36 * \class CNoViscousFlux
37 * \ingroup ViscDiscr
38 * \brief Numerics classes that accept a compile-time decorator should use this
39 * class template as a "do-nothing" decorator and as a link to the interface when
40 * they are not being decorated.
41 * Compile-time decoration works by specifying the base class as a template parameter.
42 * Then the class being decorated should call a method of its base class to add some
43 * contribution to the flux/source and Jacobians just before writting the results to
44 * CSysVector and CSysMatrix. The mechanism can be used to chain any number of classes
45 * at compile-time, but its main purpose is to combine convective and viscous fluxes
46 * in the most (nearly) efficient way.
47 */
48template<size_t NDIM>
50protected:
51 static constexpr size_t nDim = NDIM;
52 static constexpr size_t nPrimVar = 0;
53
54 template<class... Ts>
55 CNoViscousFlux(Ts&...) {}
56
57 /*!
58 * \brief Empty method, real decorators should take as arguments whatever
59 * the decorated class can pass them to avoid expensive data accesses.
60 */
61 template<class... Ts>
62 void viscousTerms(Ts&...) const {}
63};
64
65/*!
66 * \class CCompressibleViscousFluxBase
67 * \ingroup ViscDiscr
68 * \brief Decorator class to add viscous fluxes (compressible flow).
69 */
70template<size_t NDIM, class Derived>
72protected:
73 static constexpr size_t nDim = NDIM;
74 static constexpr size_t nPrimVarGrad = nDim+1;
75
79 const bool correct;
80 const bool useSA_QCR;
81 const bool wallFun;
82 const bool uq;
83 const bool uq_permute;
84 const size_t uq_eigval_comp;
87
89
90 /*!
91 * \brief Constructor, initialize constants and booleans.
92 */
93 template<class... Ts>
94 CCompressibleViscousFluxBase(const CConfig& config, int iMesh,
95 const CVariable* turbVars_, Ts&...) :
96 gamma(config.GetGamma()),
97 gasConst(config.GetGas_ConstantND()),
98 prandtlTurb(config.GetPrandtl_Turb()),
99 correct(iMesh == MESH_0),
100 useSA_QCR(config.GetSAParsedOptions().qcr2000),
101 wallFun(config.GetWall_Functions()),
102 uq(config.GetSSTParsedOptions().uq),
103 uq_permute(config.GetUQ_Permute()),
104 uq_eigval_comp(config.GetEig_Val_Comp()),
105 uq_delta_b(config.GetUQ_Delta_B()),
106 uq_urlx(config.GetUQ_URLX()),
107 turbVars(turbVars_) {
108 }
109
110 /*!
111 * \brief Add viscous contributions to flux and jacobians.
112 */
113 template<class PrimVarType, size_t nVar>
114 FORCEINLINE void viscousTerms(const Int& iEdge,
115 const Int& iPoint,
116 const Int& jPoint,
117 const PrimVarType& avgV,
118 const CPair<PrimVarType>& V,
119 const CVariable& solution_,
120 const VectorDbl<nDim>& vector_ij,
121 const CGeometry& geometry,
122 const CConfig& config,
123 const Double& area,
124 const VectorDbl<nDim>& unitNormal,
125 bool implicit,
126 VectorDbl<nVar>& flux,
127 MatrixDbl<nVar>& jac_i,
128 MatrixDbl<nVar>& jac_j) const {
129
130 static_assert(PrimVarType::nVar <= Derived::nPrimVar);
131
132 /*--- Pointer on which to call the "compile-time virtual" methods. ---*/
133
134 const auto derived = static_cast<const Derived*>(this);
135
136 const auto& solution = static_cast<const CNSVariable&>(solution_);
137 const auto& gradient = solution.GetGradient_Primitive();
138
139 /*--- Compute distance and handle zero without "ifs" by making it large. ---*/
140
141 auto dist2_ij = squaredNorm(vector_ij);
142 Double mask = dist2_ij < EPS*EPS;
143 dist2_ij += mask / (EPS*EPS);
144
145 /*--- Compute the corrected mean gradient. ---*/
146
147 auto avgGrad = averageGradient<nPrimVarGrad,nDim>(iPoint, jPoint, gradient);
148 if(correct) correctGradient(V, vector_ij, dist2_ij, avgGrad);
149
150 /*--- Stress and heat flux tensors. ---*/
151
152 const Double eddyVisc = uq? Double(0.0) : avgV.eddyVisc();
153 auto tau = stressTensor(avgV.laminarVisc() + eddyVisc, avgGrad);
154 if(useSA_QCR) addQCR(avgGrad, tau, eddyVisc / (avgV.laminarVisc() + eddyVisc));
155 if(uq) {
156 Double turb_ke = 0.5*(gatherVariables(iPoint, turbVars->GetSolution()) +
158 addPerturbedRSM(avgV, avgGrad, turb_ke, tau,
160 }
161
162 if(wallFun) addTauWall(iPoint, jPoint, solution.GetTau_Wall(), unitNormal, tau);
163
164 Double cond = derived->thermalConductivity(avgV);
165 VectorDbl<nDim> heatFlux;
166 for (size_t iDim = 0; iDim < nDim; ++iDim) {
167 heatFlux(iDim) = cond * avgGrad(0,iDim);
168 }
169
170 /*--- Projected flux. ---*/
171
172 auto viscFlux = viscousFlux<nVar>(avgV, tau, heatFlux, unitNormal);
173 for (size_t iVar = 0; iVar < nVar; ++iVar) {
174 viscFlux(iVar) *= area;
175 flux(iVar) -= viscFlux(iVar);
176 }
177
178 if (!implicit) return;
179
180 /*--- Flux Jacobians. ---*/
181
182 Double dist_ij = sqrt(dist2_ij);
183 auto dtau = stressTensorJacobian<nVar>(avgV, unitNormal, dist_ij);
184
185 /*--- Energy flux Jacobian. ---*/
186 auto dEdU = derived->energyJacobian(avgV, dtau, cond, area, dist_ij, iPoint, jPoint, solution);
187
188 /*--- Update momentum and energy terms ("symmetric" part). ---*/
189 for (size_t iDim = 0; iDim < nDim; ++iDim) {
190 for (size_t iVar = 0; iVar < nVar; ++iVar) {
191 jac_i(iDim+1,iVar) -= area * dtau(iDim,iVar);
192 jac_j(iDim+1,iVar) += area * dtau(iDim,iVar);
193 }
194 }
195 for (size_t iVar = 0; iVar < nVar; ++iVar) {
196 jac_i(nDim+1,iVar) += dEdU(iVar);
197 jac_j(nDim+1,iVar) -= dEdU(iVar);
198 }
199 /*--- "Non-symmetric" energy terms. ---*/
200 Double proj = dot<nDim>(&viscFlux(1), avgV.velocity());
201 Double halfOnRho = 0.5/avgV.density();
202 jac_i(nDim+1,0) += halfOnRho * proj;
203 jac_j(nDim+1,0) += halfOnRho * proj;
204 for (size_t iDim = 0; iDim < nDim; ++iDim) {
205 jac_i(nDim+1,iDim+1) -= halfOnRho * viscFlux(iDim+1);
206 jac_j(nDim+1,iDim+1) -= halfOnRho * viscFlux(iDim+1);
207 }
208 }
209
210 /*!
211 * \overload Average primitives if not provided yet.
212 */
213 template<class PrimVarType, class... Ts>
214 FORCEINLINE void viscousTerms(const Int& iEdge,
215 const Int& iPoint,
216 const Int& jPoint,
217 const CPair<PrimVarType>& V,
218 Ts&... args) const {
219 PrimVarType avgV;
220 for (size_t iVar = 0; iVar < PrimVarType::nVar; ++iVar) {
221 avgV.all(iVar) = 0.5 * (V.i.all(iVar) + V.j.all(iVar));
222 }
223
224 /*--- Continue calculation. ---*/
225 viscousTerms(iEdge, iPoint, jPoint, avgV, V, args...);
226 }
227
228 /*!
229 * \overload Compute the i-j vector if not provided yet.
230 */
231 template<class PrimVarType, class... Ts>
232 FORCEINLINE void viscousTerms(const Int& iEdge,
233 const Int& iPoint,
234 const Int& jPoint,
235 const PrimVarType& avgV,
236 const CPair<PrimVarType>& V,
237 const CVariable& solution_,
238 const CGeometry& geometry,
239 Ts&... args) const {
240
241 const auto vector_ij = distanceVector<nDim>(iPoint, jPoint, geometry.nodes->GetCoord());
242
243 /*--- Continue calculation. ---*/
244 viscousTerms(iEdge, iPoint, jPoint, avgV, V, solution_, vector_ij, geometry, args...);
245 }
246};
247
248/*!
249 * \class CCompressibleViscousFlux
250 * \ingroup ViscDiscr
251 * \brief Decorator class to add viscous fluxes (compressible flow, ideal gas).
252 */
253template<size_t NDIM>
254class CCompressibleViscousFlux : public CCompressibleViscousFluxBase<NDIM, CCompressibleViscousFlux<NDIM> > {
255public:
256 static constexpr size_t nPrimVar = NDIM+9;
258 using Base::gamma;
259 using Base::gasConst;
260 using Base::prandtlTurb;
261
262 /*!
263 * \brief Constructor, initialize constants and booleans.
264 */
265 template<class... Ts>
266 CCompressibleViscousFlux(Ts&... args) : Base(args...) {}
267
268 /*!
269 * \brief Compute the thermal conductivity.
270 */
271 template<class PrimitiveType>
272 FORCEINLINE Double thermalConductivity(const PrimitiveType& V) const {
273 return V.thermalCond() + V.cp() * V.eddyVisc() / prandtlTurb;
274 }
275
276 /*!
277 * \brief Compute Jacobian of the energy flux, except the part due to the work of viscous forces.
278 */
279 template<size_t nVar, size_t nDim, class PrimitiveType, class... Ts>
281 const MatrixDbl<nDim,nVar>& dtau,
282 const Double& thermalCond,
283 const Double& area,
284 const Double& dist_ij,
285 Ts&... args) const {
286 Double vel2 = 0.5 * squaredNorm<nDim>(V.velocity());
287 Double phi = (gamma-1) / V.density();
288 Double RdTdrho = phi*vel2 - V.pressure() / pow(V.density(),2);
289 Double condOnRd = thermalCond / (gasConst * dist_ij);
290 Double contraction = 0.0;
291 for (size_t iDim = 0; iDim < nDim; ++iDim) {
292 contraction += dtau(iDim,0) * V.velocity(iDim);
293 }
294 VectorDbl<nVar> dEdU;
295 dEdU(0) = area * (condOnRd * RdTdrho - contraction);
296 for (size_t iDim = 0; iDim < nDim; ++iDim) {
297 dEdU(iDim+1) = area * (dtau(iDim,0) - condOnRd*phi*V.velocity(iDim));
298 }
299 dEdU(nDim+1) = area * condOnRd * phi;
300
301 return dEdU;
302 }
303};
304
305/*!
306 * \class CGeneralCompressibleViscousFlux
307 * \ingroup ViscDiscr
308 * \brief Decorator class to add viscous fluxes (compressible flow, real gas).
309 */
310template<size_t NDIM>
311class CGeneralCompressibleViscousFlux : public CCompressibleViscousFluxBase<NDIM, CGeneralCompressibleViscousFlux<NDIM> > {
312public:
313 static constexpr size_t nPrimVar = NDIM+9;
314 static constexpr size_t nSecVar = 4;
316 using Base::prandtlTurb;
317
318 /*!
319 * \brief Constructor, initialize constants and booleans.
320 */
321 template<class... Ts>
322 CGeneralCompressibleViscousFlux(Ts&... args) : Base(args...) {}
323
324 /*!
325 * \brief Compute the thermal conductivity.
326 */
327 template<class PrimitiveType>
328 FORCEINLINE Double thermalConductivity(const PrimitiveType& V) const {
329 return V.thermalCond() + V.cp()*V.eddyVisc()/prandtlTurb;
330 }
331
332 /*!
333 * \brief Compute Jacobian of the energy flux, except the part due to the work of viscous forces.
334 */
335 template<size_t nVar, size_t nDim, class PrimitiveType, class VariableType>
337 const MatrixDbl<nDim,nVar>& dtau,
338 const Double& thermalCond,
339 const Double& area,
340 const Double& dist_ij,
341 const Int& iPoint,
342 const Int& jPoint,
343 const VariableType& solution) const {
344 Double vel2 = squaredNorm<nDim>(V.velocity());
345 Double contraction = 0.0;
346 for (size_t iDim = 0; iDim < nDim; ++iDim) {
347 contraction += dtau(iDim,0) * V.velocity(iDim);
348 }
349
350 auto secVar_i = gatherVariables<nSecVar>(iPoint, solution.GetSecondary());
351 auto secVar_j = gatherVariables<nSecVar>(jPoint, solution.GetSecondary());
352
353 Double dTdrho_e = 0.5 * (secVar_i(2) + secVar_j(2));
354 Double dTde_rho = 0.5 * (secVar_i(3) + secVar_j(3)) / V.density();
355
356 Double condOnDist = thermalCond / dist_ij;
357 Double dTdrho = dTdrho_e + dTde_rho*(vel2-V.enthalpy()+V.pressure()/V.density());
358
359 VectorDbl<nVar> dEdU;
360 dEdU(0) = area * (condOnDist * dTdrho - contraction);
361 for (size_t iDim = 0; iDim < nDim; ++iDim) {
362 dEdU(iDim+1) = area * (dtau(iDim,0) - condOnDist*dTde_rho*V.velocity(iDim));
363 }
364 dEdU(nDim+1) = area * condOnDist * dTde_rho;
365
366 return dEdU;
367 }
368};
simd::Array< su2double > Double
Define Double and Int SIMD types.
Definition CNumericsSIMD.hpp:36
A templated matrix/vector-like object.
Definition C2DContainer.hpp:374
Decorator class to add viscous fluxes (compressible flow).
Definition viscous_fluxes.hpp:71
const bool uq
Definition viscous_fluxes.hpp:82
const bool useSA_QCR
Definition viscous_fluxes.hpp:80
const bool uq_permute
Definition viscous_fluxes.hpp:83
const bool wallFun
Definition viscous_fluxes.hpp:81
void viscousTerms(const Int &iEdge, const Int &iPoint, const Int &jPoint, const CPair< PrimVarType > &V, Ts &... args) const
Definition viscous_fluxes.hpp:214
const su2double prandtlTurb
Definition viscous_fluxes.hpp:78
const su2double uq_delta_b
Definition viscous_fluxes.hpp:85
const CVariable * turbVars
Definition viscous_fluxes.hpp:88
const su2double gasConst
Definition viscous_fluxes.hpp:77
const size_t uq_eigval_comp
Definition viscous_fluxes.hpp:84
static constexpr size_t nPrimVarGrad
Definition viscous_fluxes.hpp:74
const su2double gamma
Definition viscous_fluxes.hpp:76
void viscousTerms(const Int &iEdge, const Int &iPoint, const Int &jPoint, const PrimVarType &avgV, const CPair< PrimVarType > &V, const CVariable &solution_, const VectorDbl< nDim > &vector_ij, const CGeometry &geometry, const CConfig &config, const Double &area, const VectorDbl< nDim > &unitNormal, bool implicit, VectorDbl< nVar > &flux, MatrixDbl< nVar > &jac_i, MatrixDbl< nVar > &jac_j) const
Add viscous contributions to flux and jacobians.
Definition viscous_fluxes.hpp:114
CCompressibleViscousFluxBase(const CConfig &config, int iMesh, const CVariable *turbVars_, Ts &...)
Constructor, initialize constants and booleans.
Definition viscous_fluxes.hpp:94
static constexpr size_t nDim
Definition viscous_fluxes.hpp:73
void viscousTerms(const Int &iEdge, const Int &iPoint, const Int &jPoint, const PrimVarType &avgV, const CPair< PrimVarType > &V, const CVariable &solution_, const CGeometry &geometry, Ts &... args) const
Definition viscous_fluxes.hpp:232
const bool correct
Definition viscous_fluxes.hpp:79
const su2double uq_urlx
Definition viscous_fluxes.hpp:86
Decorator class to add viscous fluxes (compressible flow, ideal gas).
Definition viscous_fluxes.hpp:254
Double thermalConductivity(const PrimitiveType &V) const
Compute the thermal conductivity.
Definition viscous_fluxes.hpp:272
CCompressibleViscousFlux(Ts &... args)
Constructor, initialize constants and booleans.
Definition viscous_fluxes.hpp:266
static constexpr size_t nPrimVar
Definition viscous_fluxes.hpp:256
VectorDbl< nVar > energyJacobian(const PrimitiveType &V, const MatrixDbl< nDim, nVar > &dtau, const Double &thermalCond, const Double &area, const Double &dist_ij, Ts &... args) const
Compute Jacobian of the energy flux, except the part due to the work of viscous forces.
Definition viscous_fluxes.hpp:280
Main class for defining the problem; basically this class reads the configuration file,...
Definition CConfig.hpp:64
su2double GetGradient_Primitive(unsigned long iPoint, unsigned long iVar, unsigned long iDim) const final
Get the value of the primitive variables gradient.
Definition CFlowVariable.hpp:147
Decorator class to add viscous fluxes (compressible flow, real gas).
Definition viscous_fluxes.hpp:311
VectorDbl< nVar > energyJacobian(const PrimitiveType &V, const MatrixDbl< nDim, nVar > &dtau, const Double &thermalCond, const Double &area, const Double &dist_ij, const Int &iPoint, const Int &jPoint, const VariableType &solution) const
Compute Jacobian of the energy flux, except the part due to the work of viscous forces.
Definition viscous_fluxes.hpp:336
static constexpr size_t nPrimVar
Definition viscous_fluxes.hpp:313
Double thermalConductivity(const PrimitiveType &V) const
Compute the thermal conductivity.
Definition viscous_fluxes.hpp:328
static constexpr size_t nSecVar
Definition viscous_fluxes.hpp:314
CGeneralCompressibleViscousFlux(Ts &... args)
Constructor, initialize constants and booleans.
Definition viscous_fluxes.hpp:322
Parent class for defining the geometry of the problem (complete geometry, multigrid agglomerated geom...
Definition CGeometry.hpp:75
CPoint * nodes
Node vector (dual grid information).
Definition CGeometry.hpp:253
Class for defining the variables of the compressible Navier-Stokes solver.
Definition CNSVariable.hpp:38
Numerics classes that accept a compile-time decorator should use this class template as a "do-nothing...
Definition viscous_fluxes.hpp:49
static constexpr size_t nDim
Definition viscous_fluxes.hpp:51
void viscousTerms(Ts &...) const
Empty method, real decorators should take as arguments whatever the decorated class can pass them to ...
Definition viscous_fluxes.hpp:62
static constexpr size_t nPrimVar
Definition viscous_fluxes.hpp:52
CNoViscousFlux(Ts &...)
Definition viscous_fluxes.hpp:55
Base class to define the interface.
Definition CNumericsSIMD.hpp:50
su2double GetCoord(unsigned long iPoint, unsigned long iDim) const
Get the coordinates dor the control volume.
Definition CPoint.hpp:158
Main class for defining the variables.
Definition CVariable.hpp:50
su2double GetSolution(unsigned long iPoint, unsigned long iVar) const
Get the solution.
Definition CVariable.hpp:248
A simple SIMD type relying on implicit vectorization, i.e. done by the compiler, explicitly vectorize...
Definition vectorization.hpp:89
#define FORCEINLINE
Definition code_config.hpp:44
passivedouble su2double
Definition code_config.hpp:181
Helper functions for viscous methods.
void addPerturbedRSM(const PrimitiveType &V, const MatrixType &grad, const Double &turb_ke, MatrixDbl< nDim, nDim > &tau, Ts... uq_args)
Add perturbed stress tensor.
Definition common.hpp:98
void addQCR(const MatrixType &grad, MatrixDbl< nDim > &tau, Double turb_fraction)
SA-QCR2000 modification of the stress tensor.
Definition common.hpp:124
void correctGradient(const PrimitiveType &V, const VectorDbl< nDim > &vector_ij, const Double &dist2_ij, MatrixDbl< nVar, nDim > &avgGrad)
Correct average gradient with the directional derivative to avoid decoupling.
Definition common.hpp:56
MatrixDbl< nDim > stressTensor(const Double &viscosity, const MatrixDbl< nVar, nDim > &grad)
Compute the stress tensor.
Definition common.hpp:73
void addTauWall(const Int &iPoint, const Int &jPoint, const Container &tauWall, const VectorDbl< nDim > &unitNormal, MatrixDbl< nDim > &tau)
Scale the stress tensor according to the target (from a wall function) magnitude in the tangential di...
Definition common.hpp:157
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
auto squaredNorm(ForwardIterator iterator) -> typename std::decay< decltype(*iterator)>::type
Squared norm.
Definition util.hpp:231
Double gatherVariables(Int iPoint, const Container &vars, size_t iVar=0)
Gather a single variable, from column iVar (0 by default) of row iPoint of a 2D container,...
Definition util.hpp:277
const unsigned int MESH_0
Definition of the finest grid level.
Definition option_structure.hpp:88
@ V
Menter k-w SST model with vorticity production terms.
constexpr passivedouble EPS
Error scale.
Definition option_structure.hpp:100
Simple pair type for i/j variables.
Definition util.hpp:130