Documentation 6b54b78464
Loading...
Searching...
No Matches
common.hpp
Go to the documentation of this file.
1/*!
2 * \file common.hpp
3 * \brief Helper functions for viscous methods.
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 "../../../numerics/CNumerics.hpp"
34
35/*!
36 * \brief Average gradients at i/j points.
37 */
38template<size_t nVar, size_t nDim, class GradientType>
40 const GradientType& gradient) {
41 auto avgGrad = gatherVariables<nVar,nDim>(iPoint, gradient);
42 auto grad_j = gatherVariables<nVar,nDim>(jPoint, gradient);
43 for (size_t iVar = 0; iVar < nVar; ++iVar) {
44 for (size_t iDim = 0; iDim < nDim; ++iDim) {
45 avgGrad(iVar,iDim) *= 0.5;
46 avgGrad(iVar,iDim) += 0.5 * grad_j(iVar,iDim);
47 }
48 }
49 return avgGrad;
50}
51
52/*!
53 * \brief Correct average gradient with the directional derivative to avoid decoupling.
54 */
55template<size_t nVar, size_t nDim, class PrimitiveType>
56FORCEINLINE void correctGradient(const PrimitiveType& V,
57 const VectorDbl<nDim>& vector_ij,
58 const Double& dist2_ij,
59 MatrixDbl<nVar,nDim>& avgGrad) {
60 for (size_t iVar = 0; iVar < nVar; ++iVar) {
61 Double corr = (dot(avgGrad[iVar],vector_ij) - V.j.all(iVar) + V.i.all(iVar)) / dist2_ij;
62 for (size_t iDim = 0; iDim < nDim; ++iDim) {
63 avgGrad(iVar,iDim) -= corr * vector_ij(iDim);
64 }
65 }
66}
67
68/*!
69 * \brief Compute the stress tensor.
70 * \note Second viscosity term ignored.
71 */
72template<size_t nVar, size_t nDim>
74 const MatrixDbl<nVar,nDim>& grad) {
75 /*--- Hydrostatic term. ---*/
76 Double velDiv = 0.0;
77 for (size_t iDim = 0; iDim < nDim; ++iDim) {
78 velDiv += grad(iDim+1,iDim);
79 }
80 Double pTerm = 2.0/3.0 * viscosity * velDiv;
81
83 for (size_t iDim = 0; iDim < nDim; ++iDim) {
84 /*--- Deviatoric term. ---*/
85 for (size_t jDim = 0; jDim < nDim; ++jDim) {
86 tau(iDim,jDim) = viscosity * (grad(jDim+1,iDim) + grad(iDim+1,jDim));
87 }
88 tau(iDim,iDim) -= pTerm;
89 }
90 return tau;
91}
92
93/*!
94 * \brief Add perturbed stress tensor.
95 * \note Not inlined because it is not easy to vectorize properly, due to tred2 and tql2.
96 */
97template<class PrimitiveType, class MatrixType, size_t nDim, class... Ts>
98NEVERINLINE void addPerturbedRSM(const PrimitiveType& V,
99 const MatrixType& grad,
100 const Double& turb_ke,
102 Ts... uq_args) {
103 /*--- Handle SIMD dimensions 1 by 1. ---*/
104 for (size_t k = 0; k < Double::Size; ++k) {
105 su2double velgrad[nDim][nDim];
106 for (size_t iVar = 0; iVar < nDim; ++iVar)
107 for (size_t iDim = 0; iDim < nDim; ++iDim)
108 velgrad[iVar][iDim] = grad(iVar+1,iDim)[k];
109
110 su2double rsm[3][3];
111 CNumerics::ComputePerturbedRSM(nDim, uq_args..., velgrad, V.density()[k],
112 V.eddyVisc()[k], turb_ke[k], rsm);
113
114 for (size_t iDim = 0; iDim < nDim; ++iDim)
115 for (size_t jDim = 0; jDim < nDim; ++jDim)
116 tau(iDim,jDim)[k] -= V.density()[k] * rsm[iDim][jDim];
117 }
118}
119
120/*!
121 * \brief SA-QCR2000 modification of the stress tensor.
122 */
123template<class MatrixType, size_t nDim>
124FORCEINLINE void addQCR(const MatrixType& grad, MatrixDbl<nDim>& tau, Double turb_fraction) {
125 constexpr passivedouble c_cr1 = 0.3;
126
127 /*--- Denominator, antisymmetric normalized rotation tensor. ---*/
128 Double denom = 0.0;
129 for (size_t iDim = 0; iDim < nDim; ++iDim)
130 for (size_t jDim = 0; jDim < nDim; ++jDim)
131 denom += grad(iDim+1,jDim) * grad(iDim+1,jDim);
132
133 const Double factor = 1 / sqrt(fmax(denom,1e-10));
134
135 /*--- Compute the QCR term, and update the stress tensor. ---*/
136 MatrixDbl<nDim> qcr;
137 for (size_t iDim = 0; iDim < nDim; ++iDim) {
138 for (size_t jDim = 0; jDim < nDim; ++jDim) {
139 qcr(iDim,jDim) = 0.0;
140 for (size_t kDim = 0; kDim < nDim; ++kDim) {
141 Double O_ik = (grad(iDim+1,kDim) - grad(kDim+1,iDim)) * factor;
142 Double O_jk = (grad(jDim+1,kDim) - grad(kDim+1,jDim)) * factor;
143 qcr(iDim,jDim) += O_ik*tau(jDim,kDim) + O_jk*tau(iDim,kDim);
144 }
145 }
146 }
147 for (size_t iDim = 0; iDim < nDim; ++iDim)
148 for (size_t jDim = 0; jDim < nDim; ++jDim)
149 tau(iDim,jDim) -= turb_fraction * c_cr1 * qcr(iDim,jDim);
150}
151
152/*!
153 * \brief Scale the stress tensor according to the target (from a
154 * wall function) magnitude in the tangential direction.
155 */
156template<class Container, size_t nDim>
157FORCEINLINE void addTauWall(const Int& iPoint, const Int& jPoint,
158 const Container& tauWall,
159 const VectorDbl<nDim>& unitNormal,
160 MatrixDbl<nDim>& tau) {
161
162 Double tauWall_i = fmax(gatherVariables(iPoint, tauWall), 0.0);
163 Double tauWall_j = fmax(gatherVariables(jPoint, tauWall), 0.0);
164
165 Double isWall_i = tauWall_i > 0.0;
166 Double isWall_j = tauWall_j > 0.0;
167 /*--- Arithmetic xor. ---*/
168 Double isNormalEdge = isWall_i+isWall_j - 2*isWall_i*isWall_j;
169
170 /*--- Tau wall is 0 for edges that are not normal to walls. ---*/
171 Double tauWall_ij = (tauWall_i+tauWall_j) * isNormalEdge;
172
173 /*--- Scale is 1 for those edges, i.e. tau is not changed. ---*/
174 Double scale =
175 tauWall_ij / fmax(norm(tangentProjection(tau,unitNormal)), EPS) + (1.0-isNormalEdge);
176
177 for (size_t iDim = 0; iDim < nDim; ++iDim)
178 for (size_t jDim = 0; jDim < nDim; ++jDim)
179 tau(iDim,jDim) *= scale;
180}
181
182/*!
183 * \brief Jacobian of the stress tensor (compressible flow).
184 */
185template<size_t nVar, size_t nDim, class PrimitiveType>
187 const VectorDbl<nDim>& normal,
188 const Double& dist_ij) {
189 Double viscosity = V.laminarVisc() + V.eddyVisc();
190 Double xi = viscosity / (V.density() * dist_ij);
192 for (size_t iDim = 0; iDim < nDim; ++iDim) {
193 /*--- Momentum. ---*/
194 for (size_t jDim = 0; jDim < nDim; ++jDim) {
195 jac(iDim,jDim+1) = (-1/3.0) * xi * normal(iDim) * normal(jDim);
196 }
197 jac(iDim,iDim+1) -= xi;
198 /*--- Density. ---*/
199 jac(iDim,0) = -dot<nDim>(&jac(iDim,1), V.velocity());
200 /*--- Energy. ---*/
201 jac(iDim,nDim+1) = 0.0;
202 }
203 return jac;
204}
205
206/*!
207 * \brief Viscous flux for compressible flows.
208 */
209template<size_t nVar, size_t nDim, class PrimitiveType>
211 const MatrixDbl<nDim>& tau,
212 const VectorDbl<nDim>& heatFlux,
213 const VectorDbl<nDim>& normal) {
214 VectorDbl<nVar> flux;
215 flux(0) = 0.0;
216 for (size_t iDim = 0; iDim < nDim; ++iDim) {
217 /*--- Using the symmetry of the tensor. ---*/
218 flux(iDim+1) = dot(tau[iDim], normal);
219 }
220 flux(nDim+1) = 0.0;
221 for (size_t iDim = 0; iDim < nDim; ++iDim) {
222 auto viscWork = dot<nDim>(tau[iDim], V.velocity());
223 flux(nDim+1) += normal(iDim) * (heatFlux(iDim) + viscWork);
224 }
225 return flux;
226}
A templated matrix/vector-like object.
Definition C2DContainer.hpp:374
static void ComputePerturbedRSM(size_t nDim, size_t uq_eigval_comp, bool uq_permute, su2double uq_delta_b, su2double uq_urlx, const Mat1 &velgrad, Scalar density, Scalar viscosity, Scalar turb_ke, Mat2 &MeanPerturbedRSM)
Perturb the Reynolds stress tensor based on parameters.
Definition CNumerics.hpp:581
A simple SIMD type relying on implicit vectorization, i.e. done by the compiler, explicitly vectorize...
Definition vectorization.hpp:89
@ Size
Definition vectorization.hpp:95
double passivedouble
Definition code_config.hpp:129
#define NEVERINLINE
Definition code_config.hpp:50
#define FORCEINLINE
Definition code_config.hpp:44
passivedouble su2double
Definition code_config.hpp:181
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
VectorDbl< nVar > viscousFlux(const PrimitiveType &V, const MatrixDbl< nDim > &tau, const VectorDbl< nDim > &heatFlux, const VectorDbl< nDim > &normal)
Viscous flux for compressible flows.
Definition common.hpp:210
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
MatrixDbl< nDim, nVar > stressTensorJacobian(const PrimitiveType &V, const VectorDbl< nDim > &normal, const Double &dist_ij)
Jacobian of the stress tensor (compressible flow).
Definition common.hpp:186
MatrixDbl< nVar, nDim > averageGradient(const Int &iPoint, const Int &jPoint, const GradientType &gradient)
Average gradients at i/j points.
Definition common.hpp:39
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
Double norm(const Vector< Double, nDim > &vector)
Vector norm.
Definition util.hpp:267
Vector< Double, nDim > tangentProjection(const Matrix< Double, nDim, nDim > &tensor, const Vector< Double, nDim > &unitVector)
Tangential projection.
Definition util.hpp:251
auto dot(ForwardIterator iterator, const T *ptr) -> typename std::decay< decltype(*ptr)>::type
Dot product.
Definition util.hpp:203
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
@ V
Menter k-w SST model with vorticity production terms.
constexpr passivedouble EPS
Error scale.
Definition option_structure.hpp:100