Mallard 0.8.0
Unstructured, GPU accelerated, high-order finite volume CFD solver
Mallard website
Loading...
Searching...
No Matches
les.h
Go to the documentation of this file.
1
12#ifndef LES_H
13#define LES_H
14
15#include <string>
16#include <unordered_map>
17
18#include <Kokkos_Core.hpp>
19#include <toml.hpp>
20
21#include "common.h"
22#include "log.h"
23
25
26static const std::unordered_map<std::string, SGSModel> SGS_MODELS = {
27 {"smagorinsky", SGSModel::SMAGORINSKY},
28 {"wale", SGSModel::WALE},
29 {"vreman", SGSModel::VREMAN},
30 {"sigma", SGSModel::SIGMA},
31};
32
40struct LES {
42 rtype C = 1.35_r;
45 bool scotti = false;
46 bool dynamic = false; // C from the Germano identity over the whole domain, once per step (see Solver) // the eddy viscosity's width V^(1/3) f(a_1, a_2) (Scotti, Meneveau & Lilly 1993)
47
49 static LES from_input(const toml::value & input);
50
51 static bool in_input(const toml::value & input) { return input.contains("les"); }
52
57 static double scotti_factor(double h1, double h2, double h3);
58
61
62 logging::Items summary() const;
63
66 static double operator_of(const SGSModel model, const double g[3][3]) {
67 switch (model) {
69 return smagorinsky(g);
70 case SGSModel::WALE:
71 return wale(g);
73 return vreman(g);
74 default:
75 return sigma(g);
76 }
77 }
78
81 rtype nu_t(const double g[3][3], const rtype delta) const {
82 const double c = static_cast<double>(C);
83 const double coefficient = model == SGSModel::VREMAN ? c : c * c;
84 const double d = static_cast<double>(delta);
85 return static_cast<rtype>(coefficient * d * d * operator_of(model, g));
86 }
87
89 static double strain_squared(const double g[3][3]) {
90 double s = 0.0;
91 for (int i = 0; i < 3; i++) {
92 for (int j = 0; j < 3; j++) {
93 const double s_ij = 0.5 * (g[i][j] + g[j][i]);
94 s += s_ij * s_ij;
95 }
96 }
97 return s;
98 }
99
102 static double smagorinsky(const double g[3][3]) { return Kokkos::sqrt(2.0 * strain_squared(g)); }
103
106 static double wale(const double g[3][3]) {
107 double g2[3][3];
108 for (int i = 0; i < 3; i++) {
109 for (int j = 0; j < 3; j++) {
110 g2[i][j] = 0.0;
111 for (int k = 0; k < 3; k++) g2[i][j] += g[i][k] * g[k][j];
112 }
113 }
114 const double trace = (g2[0][0] + g2[1][1] + g2[2][2]) / 3.0;
115 double sd = 0.0;
116 for (int i = 0; i < 3; i++) {
117 for (int j = 0; j < 3; j++) {
118 const double s = 0.5 * (g2[i][j] + g2[j][i]) - (i == j ? trace : 0.0);
119 sd += s * s;
120 }
121 }
122 const double ss = strain_squared(g);
123 const double denominator = Kokkos::pow(ss, 2.5) + Kokkos::pow(sd, 1.25);
124 return denominator > 0.0 ? Kokkos::pow(sd, 1.5) / denominator : 0.0;
125 }
126
129 static double vreman(const double g[3][3]) {
130 double b[3][3], aa = 0.0;
131 for (int i = 0; i < 3; i++) {
132 for (int j = 0; j < 3; j++) {
133 // b_ij = sum_m a_mi a_mj = sum_m g_im g_jm
134 b[i][j] = 0.0;
135 for (int m = 0; m < 3; m++) b[i][j] += g[i][m] * g[j][m];
136 aa += g[i][j] * g[i][j];
137 }
138 }
139 const double B = b[0][0] * b[1][1] - b[0][1] * b[0][1] + b[0][0] * b[2][2] - b[0][2] * b[0][2] +
140 b[1][1] * b[2][2] - b[1][2] * b[1][2];
141 return aa > 0.0 ? Kokkos::sqrt(Kokkos::fmax(B, 0.0) / aa) : 0.0;
142 }
143
154 static void singular_values(const double g[3][3], double s[3]) {
155 double G[3][3];
156 for (int i = 0; i < 3; i++) {
157 for (int j = 0; j < 3; j++) {
158 G[i][j] = 0.0;
159 for (int k = 0; k < 3; k++) G[i][j] += g[k][i] * g[k][j];
160 }
161 }
162 const double I1 = G[0][0] + G[1][1] + G[2][2];
163 const double I2 = G[0][0] * G[1][1] - G[0][1] * G[0][1] + G[0][0] * G[2][2] - G[0][2] * G[0][2] +
164 G[1][1] * G[2][2] - G[1][2] * G[1][2];
165 const double det = g[0][0] * (g[1][1] * g[2][2] - g[1][2] * g[2][1]) -
166 g[0][1] * (g[1][0] * g[2][2] - g[1][2] * g[2][0]) +
167 g[0][2] * (g[1][0] * g[2][1] - g[1][1] * g[2][0]);
168 const double I3 = det * det;
169 double l1 = I1 / 3.0;
170 const double a1 = I1 * I1 / 9.0 - I2 / 3.0;
171 if (a1 > 0.0) {
172 const double a2 = I1 * I1 * I1 / 27.0 - I1 * I2 / 6.0 + I3 / 2.0;
173 const double a3 = Kokkos::acos(Kokkos::fmin(1.0, Kokkos::fmax(-1.0, a2 / Kokkos::pow(a1, 1.5)))) / 3.0;
174 l1 += 2.0 * Kokkos::sqrt(a1) * Kokkos::cos(a3);
175 }
176 s[0] = s[1] = s[2] = 0.0;
177 if (!(l1 > 0.0)) return;
178 const double product = I3 / l1;
179 const double sum = Kokkos::fmax((I2 - product) / l1, 0.0);
180 const double l2 = 0.5 * (sum + Kokkos::sqrt(Kokkos::fmax(sum * sum - 4.0 * product, 0.0)));
181 const double l3 = l2 > 0.0 ? product / l2 : 0.0;
182 s[0] = Kokkos::sqrt(l1);
183 s[1] = Kokkos::sqrt(Kokkos::fmin(l2, l1));
184 s[2] = Kokkos::sqrt(Kokkos::fmin(l3, l2));
185 }
186
189 static double sigma(const double g[3][3]) {
190 double s[3];
192 if (!(s[0] > 0.0)) return 0.0;
193 return Kokkos::fmax(s[2] * (s[0] - s[1]) * (s[1] - s[2]) / (s[0] * s[0]), 0.0);
194 }
195};
196
197#endif // LES_H
Common header file.
KOKKOS_INLINE_FUNCTION rtype dot(const rtype *a, const rtype *b)
Compute the dot product of two arrays.
Definition common_math.h:32
float rtype
Definition common_typedef.h:39
SGSModel
Definition les.h:24
Console output: rank-0 info lines, aligned sections and tables, warnings and errors on stderr,...
std::vector< std::pair< std::string, std::string > > Items
Key-value lines of a setup section, in display order.
Definition log.h:27
Eddy viscosity nu_t = C^2 Delta^2 D(g) (Vreman: c Delta^2 D(g)) of the resolved velocity gradient g[i...
Definition les.h:40
static double scotti_factor(double h1, double h2, double h3)
Scotti, Meneveau & Lilly's (1993) factor cosh(sqrt(4/27 ((ln a_1)^2 - ln a_1 ln a_2 + (ln a_2)^2))) f...
Definition les.cpp:74
static KOKKOS_INLINE_FUNCTION double wale(const double g[3][3])
(S^d:S^d)^(3/2) / ((S:S)^(5/2) + (S^d:S^d)^(5/4)), S^d the traceless symmetric part of g^2.
Definition les.h:106
static KOKKOS_INLINE_FUNCTION void singular_values(const double g[3][3], double s[3])
Singular values s1 >= s2 >= s3 >= 0 of g, the square roots of the eigenvalues l1 >= l2 >= l3 of G = g...
Definition les.h:154
static KOKKOS_INLINE_FUNCTION double vreman(const double g[3][3])
sqrt(B / (a:a)) with a_ij = d u_j / d x_i, b = a^T a and B its second invariant.
Definition les.h:129
static KOKKOS_INLINE_FUNCTION double strain_squared(const double g[3][3])
Definition les.h:89
logging::Items summary() const
Definition les.cpp:79
static KOKKOS_INLINE_FUNCTION double sigma(const double g[3][3])
s3 (s1 - s2)(s2 - s3) / s1^2 of the singular values s of g.
Definition les.h:189
static KOKKOS_INLINE_FUNCTION double operator_of(const SGSModel model, const double g[3][3])
D(g) of the model, the eddy viscosity for unit constant and filter width.
Definition les.h:66
static bool in_input(const toml::value &input)
Definition les.h:51
bool dynamic
Definition les.h:46
static KOKKOS_INLINE_FUNCTION double smagorinsky(const double g[3][3])
sqrt(2 S:S).
Definition les.h:102
static LES from_input(const toml::value &input)
The [les] table of an input (see in_input).
Definition les.cpp:42
rtype Pr_t
Definition les.h:43
rtype C
Definition les.h:42
static rtype default_constant(SGSModel model)
Model constant by default: Lilly's C_s, Nicoud & Ducros's C_w, Vreman's c, Nicoud et al....
Definition les.cpp:29
rtype Sc_t
Definition les.h:44
SGSModel model
Definition les.h:41
KOKKOS_INLINE_FUNCTION rtype nu_t(const double g[3][3], const rtype delta) const
Kinematic eddy viscosity for the gradient g[i][j] = d u_i / d x_j and filter width delta.
Definition les.h:81
bool scotti
Definition les.h:45
CellSetup< ExecSpace > c
Definition teno_setup.cpp:1810
Geometry< Space > g
Definition teno_setup.cpp:678
std::vector< double > delta
Definition transport.cpp:285