Mallard 0.8.0
Unstructured, GPU accelerated, high-order finite volume CFD solver
Mallard website
Loading...
Searching...
No Matches
viscous_flux.h
Go to the documentation of this file.
1
12#ifndef VISCOUS_FLUX_H
13#define VISCOUS_FLUX_H
14
15#include <Kokkos_Core.hpp>
16
17#include "common.h"
18#include "boundary.h"
19#include "physics.h"
20
27void viscous_traction(const rtype mu, const rtype g[][N_DIM], const rtype * n, rtype * tau_n,
28 const rtype hoop_divergence = 0.0_r) {
29 rtype div = 0.0;
30 if constexpr (N_DIM == 2) {
31 div = g[0][0] + g[1][1];
32 } else {
33 div = g[0][0] + g[1][1] + g[2][2];
34 }
37 FOR_I_DIM {
38 for (uint8_t j = 0; j < N_DIM; j++) tau[i][j] = mu * (g[i][j] + g[j][i]);
39 tau[i][i] = mu * (2.0_r * g[i][i] - 2.0_r / 3.0_r * div);
40 }
42}
43
49rtype hoop_divergence(const rtype r, const rtype * u, const rtype g[][N_DIM]) {
50 return r > 0.0_r ? u[1] / r : g[1][1];
51}
52
58rtype variance_jump(const Kokkos::View<rtype *[3]> & covariance, const int32_t c0, const int32_t c1,
59 const rtype * d) {
60 if constexpr (N_DIM == 2) {
61 auto var = [&](const int32_t c) {
62 return covariance(c, 0) * d[0] * d[0] + 2.0_r * covariance(c, 1) * d[0] * d[1] +
63 covariance(c, 2) * d[1] * d[1];
64 };
65 return (var(c1) - var(c0)) / dot<N_DIM>(d, d);
66 } else {
67 (void)covariance;
68 (void)c0;
69 (void)c1;
70 (void)d;
71 return 0.0_r;
72 }
73}
74
82rtype mean_offset(const rtype * g0, const rtype * g1, const rtype * d, const rtype dvar) {
83 rtype dg[N_DIM];
84 FOR_I_DIM dg[i] = g1[i] - g0[i];
85 return 0.5_r * dot<N_DIM>(dg, d) / dot<N_DIM>(d, d) * dvar;
86}
87
93rtype face_fraction(const Kokkos::View<rtype *[N_DIM]> & face_coords, const Kokkos::View<rtype *[N_DIM]> & cell_coords,
94 const uint32_t f, const int32_t c0, const rtype * d) {
96 FOR_I_DIM x_f[i] = face_coords(f, i) - cell_coords(c0, i);
97 return dot<N_DIM>(x_f, d) / dot<N_DIM>(d, d);
98}
99
121 Kokkos::View<rtype *[N_DIM]> normals;
122 Kokkos::View<rtype *> face_area;
123 Kokkos::View<rtype *[N_DIM]> face_coords;
124 Kokkos::View<rtype *[N_DIM]> cell_coords;
125 Kokkos::View<int32_t *[2]> cells_of_face;
126 Kokkos::View<rtype *[N_DIM]> shifts;
127 Kokkos::View<uint8_t *> face_shift;
128 Kokkos::View<rtype *[N_CONSERVATIVE]> W;
129 Kokkos::View<rtype *[N_CONSERVATIVE][N_DIM]> gradients;
131 Kokkos::View<rtype *[N_CONSERVATIVE]> face_flux;
133 bool axisymmetric = false; // face_area is then the revolved area
134 Kokkos::View<rtype *[3]> covariance; // axisymmetric: Mesh::cell_covariance
135 Kokkos::View<rtype *[3]> sgs; // LES: (cell, [mu_t, lambda_t, -]), else empty
136 bool sgs_only = false; // LES budget: the SGS stress and heat flux alone
137
138 static constexpr uint8_t NQ = N_DIM + 1; // [u, T]
139
146 void cell_state(const int32_t c, rtype * q, rtype g[NQ][N_DIM]) const {
147 const rtype rho = W(c, 0), p = W(c, N_DIM + 1);
148 for (uint8_t k = 0; k < N_DIM; k++) q[k] = W(c, 1 + k);
149 q[N_DIM] = p / (rho * physics.R);
150 FOR_I_DIM {
151 for (uint8_t k = 0; k < N_DIM; k++) g[k][i] = gradients(c, 1 + k, i);
152 g[N_DIM][i] = (gradients(c, N_DIM + 1, i) - physics.R * q[N_DIM] * gradients(c, 0, i)) / (rho * physics.R);
153 }
154 }
155
161 const int32_t c0 = cells_of_face(i_face, 0);
162 const int32_t c1 = cells_of_face(i_face, 1);
163 rtype n[N_DIM];
166 unit<N_DIM>(n_vec, n);
167 rtype q0[NQ], g0[NQ][N_DIM], q1[NQ], g1[NQ][N_DIM];
168 cell_state(c0, q0, g0);
169 cell_state(c1, q1, g1);
170 rtype d[N_DIM];
171 const uint8_t s = face_shift(i_face);
172 FOR_I_DIM d[i] = (cell_coords(c1, i) + shifts(s, i)) - cell_coords(c0, i);
173 const rtype d_n = dot<N_DIM>(d, n);
174 // Axisymmetric cell centers are not symmetric about the faces: interpolate
175 // to the face, at fraction t along the line between them
177 const rtype dvar = axisymmetric ? variance_jump(covariance, c0, c1, d) : 0.0_r;
178 for (uint8_t k = 0; k < NQ; k++) {
179 q_f[k] = 0.5_r * (q0[k] + q1[k]);
180 FOR_I_DIM g_f[k][i] = 0.5_r * (g0[k][i] + g1[k][i]);
181 rtype dq = q1[k] - q0[k];
182 if (axisymmetric) dq -= mean_offset(g0[k], g1[k], d, dvar);
183 const rtype correction = (dq - dot<N_DIM>(g_f[k], d)) / d_n;
184 if (axisymmetric) {
185 q_f[k] = q0[k] + t * (q1[k] - q0[k]);
186 FOR_I_DIM g_f[k][i] = g0[k][i] + t * (g1[k][i] - g0[k][i]);
187 }
188 FOR_I_DIM g_f[k][i] += correction * n[i];
189 }
190 }
191
192
194 void operator()(const uint32_t i_face) const {
195 const int32_t c0 = cells_of_face(i_face, 0);
196 const int32_t c1 = cells_of_face(i_face, 1);
197 rtype n[N_DIM];
200 unit<N_DIM>(n_vec, n);
201
202 rtype q0[NQ], g0[NQ][N_DIM];
203 cell_state(c0, q0, g0);
204 rtype q_f[NQ], g_f[NQ][N_DIM];
205 bool heat_flux_given = false;
206 rtype heat_flux = 0.0; // Into the domain
207 bool symmetry = false;
208 bool wall = false;
209
210 if (c1 >= 0) {
212 } else {
214 for (uint8_t k = 0; k < NQ; k++) {
215 q_f[k] = q0[k];
216 FOR_I_DIM g_f[k][i] = g0[k][i];
217 }
218 if (bc.is_wall()) {
219 wall = true;
220 rtype dn = 0.0;
221 FOR_I_DIM dn += (face_coords(i_face, i) - cell_coords(c0, i)) * n[i];
222 for (uint8_t k = 0; k < N_DIM; k++) q_f[k] = bc.data[1 + k];
224 if (bc.type == BoundaryType::WALL_ISOTHERMAL) q_f[N_DIM] = bc.data[0];
225 for (uint8_t k = 0; k < n_set; k++) {
226 const rtype correction = (q_f[k] - q0[k]) / dn - dot<N_DIM>(g_f[k], n);
227 FOR_I_DIM g_f[k][i] += correction * n[i];
228 }
229 if (bc.type != BoundaryType::WALL_ISOTHERMAL) {
230 heat_flux_given = true;
231 heat_flux = (bc.type == BoundaryType::WALL_HEAT_FLUX) ? bc.data[N_DIM + 1] : 0.0_r;
232 }
233 } else if (bc.type == BoundaryType::SYMMETRY) {
234 symmetry = true;
235 } else if (boundaries.face_image_face(i_face) >= 0) {
237 } else if (bc.type == BoundaryType::EXTRAPOLATION || bc.type == BoundaryType::P_OUT ||
239 bc.type == BoundaryType::PARTITION || bc.is_characteristic()) {
240 // Zero normal derivatives across transmissive and outflow boundaries
241 for (uint8_t k = 0; k < NQ; k++) {
242 const rtype g_n = dot<N_DIM>(g_f[k], n);
243 FOR_I_DIM g_f[k][i] -= g_n * n[i];
244 }
245 }
246 }
247
250 if (sgs.extent(0) > 0) {
251 // The wall shear stress and heat flux are molecular
252 rtype mu_t = 0.0_r, kappa_t = 0.0_r;
253 if (c1 >= 0) {
254 mu_t = 0.5_r * (sgs(c0, 0) + sgs(c1, 0));
255 kappa_t = 0.5_r * (sgs(c0, 1) + sgs(c1, 1));
256 } else if (!wall) {
257 mu_t = sgs(c0, 0);
258 kappa_t = sgs(c0, 1);
259 }
260 if (sgs_only) mu = kappa = 0.0_r;
261 mu += mu_t;
262 kappa += kappa_t;
263 }
267 if (symmetry) {
268 // Keep only the normal stress; the normal velocity vanishes on the plane,
269 // so the normal stress does no work
270 const rtype tau_nn = dot<N_DIM>(tau_n, n);
271 FOR_I_DIM tau_n[i] = tau_nn * n[i];
272 const rtype u_n = dot<N_DIM>(q_f, n);
273 FOR_I_DIM q_f[i] -= u_n * n[i];
274 q_n = 0.0;
275 }
276 if (heat_flux_given) {
277 q_n = heat_flux;
278 }
279
281 flux[0] = 0.0;
282 FOR_I_DIM flux[1 + i] = tau_n[i];
283 flux[N_DIM + 1] = dot<N_DIM>(q_f, tau_n) + q_n;
284
285 const rtype A = face_area(i_face);
287 }
288};
289
290#endif // VISCOUS_FLUX_H
Boundary conditions.
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
#define N_DIM
Definition common_typedef.h:28
#define FOR_I_CONSERVATIVE
Definition common_typedef.h:33
#define N_CONSERVATIVE
Definition common_typedef.h:29
#define FOR_I_DIM
Definition common_typedef.h:32
Physics model declaration.
Device-copyable boundary condition.
Definition boundary.h:97
Device-side lookup from faces to boundary conditions.
Definition boundary.h:229
Kokkos::View< int32_t * > face_bc
Definition boundary.h:230
Kokkos::View< BoundaryCondition * > bcs
Definition boundary.h:249
Kokkos::View< int32_t * > face_image_face
Definition boundary.h:232
Calorically perfect gas, inviscid (Euler) or viscous and heat conducting (Navier-Stokes,...
Definition physics.h:54
KOKKOS_INLINE_FUNCTION rtype conductivity(const rtype mu) const
Thermal conductivity for dynamic viscosity mu.
Definition physics.h:108
rtype R
Definition physics.h:56
KOKKOS_INLINE_FUNCTION rtype viscosity(const rtype T) const
Dynamic viscosity at temperature T.
Definition physics.h:91
Integrates the viscous stress and heat flux over every face (one-point rule) and adds them to face_fl...
Definition viscous_flux.h:120
Kokkos::View< rtype *[N_CONSERVATIVE]> W
Definition viscous_flux.h:128
bool sgs_only
Definition viscous_flux.h:136
Kokkos::View< rtype *[N_CONSERVATIVE][N_DIM]> gradients
Definition viscous_flux.h:129
Kokkos::View< rtype *[3]> covariance
Definition viscous_flux.h:134
Kokkos::View< rtype *[3]> sgs
Definition viscous_flux.h:135
KOKKOS_INLINE_FUNCTION void cell_state(const int32_t c, rtype *q, rtype g[NQ][N_DIM]) const
Velocity and temperature q = [u, T] of cell c, and their gradients g[k][i] = d q_k / d x_i,...
Definition viscous_flux.h:146
Kokkos::View< rtype *[N_DIM]> face_coords
Definition viscous_flux.h:123
Kokkos::View< rtype *[N_DIM]> cell_coords
Definition viscous_flux.h:124
Kokkos::View< rtype *[N_DIM]> shifts
Definition viscous_flux.h:126
Kokkos::View< rtype *[N_CONSERVATIVE]> face_flux
Definition viscous_flux.h:131
KOKKOS_INLINE_FUNCTION void operator()(const uint32_t i_face) const
Definition viscous_flux.h:194
bool axisymmetric
Definition viscous_flux.h:133
Kokkos::View< rtype *[N_DIM]> normals
Definition viscous_flux.h:121
Kokkos::View< int32_t *[2]> cells_of_face
Definition viscous_flux.h:125
Kokkos::View< rtype * > face_area
Definition viscous_flux.h:122
Euler physics
Definition viscous_flux.h:132
Kokkos::View< uint8_t * > face_shift
Definition viscous_flux.h:127
BoundaryData boundaries
Definition viscous_flux.h:130
KOKKOS_INLINE_FUNCTION void interior_face(const uint32_t i_face, rtype *q_f, rtype g_f[NQ][N_DIM]) const
Values and gradients q_f, g_f on interior face i_face.
Definition viscous_flux.h:160
static constexpr uint8_t NQ
Definition viscous_flux.h:138
CellSetup< ExecSpace > c
Definition teno_setup.cpp:1810
uint8_t r
Definition teno_setup.cpp:687
Geometry< Space > g
Definition teno_setup.cpp:678
SlotArray< double, Space > A
Definition teno_setup.cpp:478
V< rtype *[N_DIM]> cell_coords
Definition teno_setup.cpp:388
V< rtype *[N_DIM]> face_coords
Definition teno_setup.cpp:399
KOKKOS_INLINE_FUNCTION rtype mean_offset(const rtype *g0, const rtype *g1, const rtype *d, const rtype dvar)
Part of the jump of two cell averages that comes from the cells' different spreads (variance jump dva...
Definition viscous_flux.h:82
KOKKOS_INLINE_FUNCTION rtype variance_jump(const Kokkos::View< rtype *[3]> &covariance, const int32_t c0, const int32_t c1, const rtype *d)
Axisymmetric meshes: jump from cell c0 to c1 of the cells' r-weighted variance along d (Mesh::cell_co...
Definition viscous_flux.h:58
KOKKOS_INLINE_FUNCTION void viscous_traction(const rtype mu, const rtype g[][N_DIM], const rtype *n, rtype *tau_n, const rtype hoop_divergence=0.0_r)
Viscous traction tau . n of a Newtonian fluid under Stokes' hypothesis, tau = mu (grad u + grad u^T -...
Definition viscous_flux.h:27
KOKKOS_INLINE_FUNCTION rtype hoop_divergence(const rtype r, const rtype *u, const rtype g[][N_DIM])
u_r / r at radius r for velocity u and gradient g (g[k][i] = d u_k / d x_i), with r = y: its limit d ...
Definition viscous_flux.h:49
KOKKOS_INLINE_FUNCTION rtype face_fraction(const Kokkos::View< rtype *[N_DIM]> &face_coords, const Kokkos::View< rtype *[N_DIM]> &cell_coords, const uint32_t f, const int32_t c0, const rtype *d)
Fraction along d (from the center of cell c0 to that of its neighbor) of the projection of face f's c...
Definition viscous_flux.h:93