MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
fvcartesiansyseqnns.h
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#ifndef FVSYSEQNNS_H_
8#define FVSYSEQNNS_H_
9
10#include <algorithm>
11#include <array>
12#include <iomanip>
13#include <iterator>
14#include <limits>
15#include <numeric>
16
18//#include "fvsyseqn.h"
19#include "INCLUDE/maiatypes.h"
20#include "MEMORY/alloc.h"
21#include "enums.h"
22#include "filter.h"
23
24// Only needed (really: possible to use) in single-threaded applications
25#ifndef _OPENMP
26#include "MEMORY/scratch.h"
27#endif
28
29
30template <MInt nDim>
32 // Declare parent a friend so that CRTP can access private methods/members
33 // friend class FvSysEqn<nDim>;
34
35 public:
36 FvSysEqnNS(const MInt solverId, const MInt noSpecies);
37
38 template <MInt scheme = AUSM>
39 inline void Ausm(const MInt orientation, const MFloat upwindCoefficient, const MFloat A, const MFloat* const leftVars,
40 const MFloat* const rightVars, const MFloat* const srfcCoeff, MFloat* const flux) {
41 IF_CONSTEXPR(scheme == AUSM) { Ausm_(orientation, upwindCoefficient, A, leftVars, rightVars, srfcCoeff, flux); }
42 else IF_CONSTEXPR(scheme == AUSMPLUS) {
43 AusmPlus_(orientation, upwindCoefficient, A, leftVars, rightVars, srfcCoeff, flux);
44 }
45 else IF_CONSTEXPR(scheme == SLAU) {
46 Slau_(orientation, upwindCoefficient, A, leftVars, rightVars, srfcCoeff, flux);
47 }
48 }
49
50 inline void Ausm_(const MInt orientation, const MFloat upwindCoefficient, const MFloat A,
51 const MFloat* const leftVars, const MFloat* const rightVars, const MFloat* const NotUsed(srfcCoeff),
52 MFloat* const flux);
53 inline void AusmPlus_(const MInt orientation, const MFloat upwindCoefficient, const MFloat A,
54 const MFloat* const leftVars, const MFloat* const rightVars,
55 const MFloat* const NotUsed(srfcCoeff), MFloat* const flux);
56 inline void Slau_(const MInt orientation, const MFloat NotUsed(upwindCoefficient), const MFloat A,
57 const MFloat* const leftVars, const MFloat* const rightVars, const MFloat* const NotUsed(srfcCoeff),
58 MFloat* const flux);
59
60 inline void AusmBndryCorrection(const MInt orientation, const MFloat A, const MFloat* const leftVars,
61 const MFloat* const rightVars, MFloat* const flux);
62
63 inline void AusmALECorrection(const MInt orientation, const MFloat A, MFloat* const flux, MFloat* const surfVars,
64 const MFloat* const bndrySurfVars);
65
66 template <MInt centralizeScheme>
67 inline void centralizeSurfaceVariables(MFloat* const varL, MFloat* const varR,
68 [[maybe_unused]] const MInt orientation,
69 [[maybe_unused]] const MFloat levelFac);
70
71 // Dispatch function for classic five-point-style viscous flux schemes
72 template <MInt stencil>
73 inline void viscousFlux(const MInt orientation, const MFloat A, const MFloat* const vars0, const MFloat* const vars1,
74 const MFloat* const slope0, const MFloat* const slope1, const MFloat* const srfcCoeff,
75 const MFloat f0, const MFloat f1, MFloat* const flux) {
76 IF_CONSTEXPR(stencil == FIVE_POINT) {
77 viscousFluxFivePoint(orientation, A, vars0, vars1, slope0, slope1, srfcCoeff, f0, f1, flux);
78 }
79 else {
80 TERMM(1, "Viscous Flux Scheme not implemented.");
81 }
82 }
83
84 // Dispatch function for compact viscous flux schemes
85 template <MInt stencil>
86 inline void viscousFlux(const MInt orientation, const MFloat A, const MBool isBndry,
87 const MFloat* const surfaceCoords, const MFloat* const coord0, const MFloat* const coord1,
88 const MFloat* const cellVars0, const MFloat* const cellVars1, const MFloat* const vars0,
89 const MFloat* const vars1, const MFloat* const slope0, const MFloat* const slope1,
90 const MFloat f0, const MFloat f1, MFloat* const flux) {
91 IF_CONSTEXPR(stencil == THREE_POINT) {
92 viscousFluxThreePoint(orientation, A, isBndry, surfaceCoords, coord0, coord1, cellVars0, cellVars1, vars0, vars1,
93 slope0, slope1, f0, f1, flux);
94 }
95 else IF_CONSTEXPR(stencil == FIVE_POINT_STABILIZED) {
96 viscousFluxStabilized(orientation, A, isBndry, surfaceCoords, coord0, coord1, cellVars0, cellVars1, vars0, vars1,
97 slope0, slope1, f0, f1, flux);
98 }
99 else {
100 TERMM(1, "Viscous Flux Scheme not implemented.");
101 }
102 }
103
104 inline void viscousFluxFivePoint(const MInt orientation, const MFloat A, const MFloat* const vars0,
105 const MFloat* const vars1, const MFloat* const slope0, const MFloat* const slope1,
106 const MFloat* const NotUsed(srfcCoeff), const MFloat f0, const MFloat f1,
107 MFloat* const flux);
108
109 inline void viscousFluxThreePoint(const MInt orientation, const MFloat A, const MBool isBndry,
110 const MFloat* const surfaceCoords, const MFloat* const coord0,
111 const MFloat* const coord1, const MFloat* const cellVars0,
112 const MFloat* const cellVars1, const MFloat* const vars0, const MFloat* const vars1,
113 const MFloat* const slope0, const MFloat* const slope1, const MFloat f0,
114 const MFloat f1, MFloat* const flux);
115
116 inline void viscousFluxStabilized(const MInt orientation, const MFloat A, const MBool isBndry,
117 const MFloat* const surfaceCoords, const MFloat* const coord0,
118 const MFloat* const coord1, const MFloat* const cellVars0,
119 const MFloat* const cellVars1, const MFloat* const vars0, const MFloat* const vars1,
120 const MFloat* const slope0, const MFloat* const slope1, const MFloat f0,
121 const MFloat f1, MFloat* const flux);
122
123 // Dispatch function for wall-model viscous flux correction with five-point stencil
124 template <MInt stencil>
125 inline void wmViscousFluxCorrection(const MInt orientation, const MFloat A, const MFloat* const vars0,
126 const MFloat* const vars1, const MFloat* const slope0, const MFloat* const slope1,
127 const MFloat f0, const MFloat f1, MFloat* const flux, MFloat const mue_wm) {
128 IF_CONSTEXPR(stencil == FIVE_POINT) {
129 wmViscousFluxCorrectionFivePoint(orientation, A, vars0, vars1, slope0, slope1, f0, f1, flux, mue_wm);
131 else {
132 TERMM(1, "Viscous Flux Scheme not implemented.");
136 inline void wmViscousFluxCorrectionFivePoint(const MInt orientation, const MFloat A, const MFloat* const vars0,
137 const MFloat* const vars1, const MFloat* const slope0,
138 const MFloat* const slope1, const MFloat f0, const MFloat f1,
139 MFloat* const flux, MFloat const mue_wm);
141
142 inline void computePrimitiveVariables(const MFloat* const cvarsCell, MFloat* const pvarsCell,
143 const MFloat* const NotUsed(avarsCell));
144
145 inline void computeConservativeVariables(const MFloat* const pvarsCell, MFloat* const cvarsCell,
146 const MFloat* const NotUsed(avarsCell));
147
148 inline std::vector<std::vector<MFloat>> conservativeSlopes(const MFloat* const pvarsCell,
149 const MFloat* const cvarsCell,
150 const MFloat* const avarsCell,
151 const MFloat* const slopesCell);
152
153 void computeVolumeForces(const MInt, MFloat*, MFloat*, const MFloat, const MFloat* const, const MInt,
154 const MInt* const, const MFloat* const, const MInt, MFloat){};
155
157 inline constexpr MFloat speedOfSound(const MFloat density, const MFloat pressure) {
158 return std::sqrt(m_gamma * pressure / density);
159 };
160
162 inline constexpr MFloat speedOfSoundSquared(const MFloat density, const MFloat pressure) {
163 return m_gamma * pressure / density;
164 };
165
167 inline constexpr MFloat speedOfSound(const MFloat temperature) { return std::sqrt(temperature); };
168
170 inline constexpr MFloat temperature_ES(const MFloat density, const MFloat pressure) {
171 return m_gamma * pressure / density;
172 };
174 inline constexpr MFloat pressure_ES(const MFloat temperture, const MFloat density) {
175 return density * temperture / m_gamma;
176 }
177
179 inline constexpr MFloat density_ES(const MFloat pressure, const MFloat temperature) {
180 return m_gamma * pressure / temperature;
181 }
182
184 inline constexpr MFloat temperature_IR(const MFloat Ma) { return 1 / (1.0 + 0.5 * m_gammaMinusOne * POW2(Ma)); }
185
188 inline constexpr MFloat pressure_IR(const MFloat temperature) {
189 return pow(temperature, m_FGammaBGammaMinusOne) / m_gamma;
190 }
191
194 inline constexpr MFloat pressure_IRit(const MFloat pressure, const MFloat massFlux) {
195 return pow(1.0 - m_gammaMinusOne * F1B2 * pow(pressure, -2.0 * m_F1BGamma) * POW2(massFlux),
197 }
198
200 inline constexpr MFloat density_IR(const MFloat temperature) { return pow(temperature, m_F1BGammaMinusOne); }
201
203 inline constexpr MFloat density_IR_P(const MFloat pressure) { return pow(pressure * m_gamma, m_F1BGamma); }
204
207 inline constexpr MFloat pressure(const MFloat density, const MFloat momentumDensitySquared,
208 const MFloat energyDensity) {
209 return m_gammaMinusOne * (energyDensity - 0.5 / density * momentumDensitySquared);
210 };
211
214 inline constexpr MFloat internalEnergy(const MFloat pressure, const MFloat density, const MFloat velocitySquared) {
215 return pressure * m_F1BGammaMinusOne + 0.5 * density * velocitySquared;
216 }
217
220 inline constexpr MFloat pressureEnergy(const MFloat pressure) { return pressure * m_F1BGammaMinusOne; }
221
223 inline constexpr MFloat enthalpy(const MFloat pressure, const MFloat density) {
224 return pressure / density * m_FGammaBGammaMinusOne;
225 }
226
228 inline constexpr MFloat entropy(const MFloat pressure, const MFloat density) {
229 return pressure / pow(density, m_gamma);
230 }
231
233 inline constexpr MFloat CroccoBusemann(const MFloat Ma, const MFloat x) {
234 return (1 + 0.5 * m_gammaMinusOne * POW2(Ma) * x * (1.0 - x));
235 }
236
238 inline constexpr MFloat vanDriest(const MFloat Ma) {
239 return (sqrt((m_gammaMinusOne / 2.0 * POW2(Ma) * pow(m_Pr, F1B3))
240 / (1.0 + m_gammaMinusOne / 2.0 * POW2(Ma) * pow(m_Pr, F1B3))));
241 }
242
246 inline constexpr MFloat sutherlandLaw(const MFloat T) {
247 return (T * sqrt(T) * m_sutherlandPlusOne) / (T + m_sutherlandConstant);
248 }
249
253 inline MFloat computeTimeStepEulerMagnitude(const MFloat rho, const std::array<MFloat, nDim> u, const MFloat p,
254 const MFloat C, const MFloat dx) {
255 const MFloat a = speedOfSound(rho, p);
256 const MFloat u_mag = std::sqrt(std::inner_product(&u[0], &u[nDim], &u[0], 0.0));
257 return C * dx / (u_mag + a);
258 };
259
262 inline constexpr MFloat gamma_Ref() { return m_gamma; }
263
266 inline constexpr MFloat cp_Ref() { return m_F1BGammaMinusOne; }
267
270 inline constexpr MFloat cv_Ref() { return m_F1BGamma * m_F1BGammaMinusOne; }
271
274 inline constexpr MFloat p_Ref() { return m_F1BGamma; }
275
279 inline constexpr MFloat computeTimeStepDiffusion(const MFloat diffusion_coefficient, const MFloat C,
280 const MFloat dx) {
281 return C * POW2(dx) / diffusion_coefficient;
282 };
283
284 public:
285 static constexpr MInt m_noRansEquations = 0;
286 static constexpr MInt m_ransModel = NORANS;
287
288 protected:
290
292
293 // Equation specific values
299 MFloat m_Pr = 0.72;
307
308 // Stencil specific properties
310
312
314 static inline MFloat sgn(MFloat val) { return (val < F0) ? -F1 : F1; }
315
316 static constexpr std::array<MInt, nDim> getArray012() {
317 IF_CONSTEXPR(nDim == 2) {
318 std::array<MInt, 2> a = {0, 1};
319 return a;
320 }
321 else {
322 std::array<MInt, 3> a = {0, 1, 2};
323 return a;
324 }
325 }
326
327 public:
328 // Equation specific values
331
332 // Hold indices for primitive and conservative variables
333 struct ConservativeVariables;
334 struct FluxVariables; // these are the variables for which the fluxes are calculated
335 // usually the same as conservative variables
336 struct PrimitiveVariables;
337 struct AdditionalVariables; // these are additional variables that are saved in the cell collector
338 // they might be used in SysEqn functions etc.
339 struct SurfaceCoefficients;
340 static constexpr MBool hasAV = false;
341 static constexpr MBool hasSC = false;
343 FluxVariables* FV = nullptr;
347
348 // Index helper constants for viscousFlux
349 // template <MInt nDim>
350 static const MUint index0[nDim];
351
352 // template <MInt nDim>
353 static const MUint index1[nDim];
354};
355
356
359template <MInt nDim>
361 static const MInt Segfault = std::numeric_limits<MInt>::min();
362
363 static constexpr MInt RHO_U = 0;
364 static constexpr MInt RHO_V = 1;
365 static constexpr MInt RHO_W = nDim == 3 ? 2 : Segfault;
366 static constexpr std::array<MInt, nDim> RHO_VV = getArray012();
367 static constexpr MInt RHO_E = nDim;
368 static constexpr MInt RHO = nDim + 1;
369
370 static constexpr MInt RHO_C = nDim + 2;
371
374
375 MInt* RHO_Y = nullptr;
376
377 ConservativeVariables(const MInt noSpecies);
379};
380
383template <MInt nDim>
385 FluxVariables(const MInt noSpecies);
386};
387
390template <MInt nDim>
392 static const MInt Segfault = std::numeric_limits<MInt>::min();
393
394 static constexpr MInt U = 0;
395 static constexpr MInt V = 1;
396 static constexpr MInt W = nDim == 3 ? 2 : Segfault;
397 static constexpr std::array<MInt, nDim> VV = getArray012();
398 static constexpr MInt RHO = nDim;
399 static constexpr MInt P = nDim + 1;
400
401 static constexpr MInt C = nDim + 2;
402
405
406 const std::array<MString, nDim + 3> varNames = [] {
407 IF_CONSTEXPR(nDim == 2) {
408 std::array<MString, nDim + 3> a = {"u", "v", "rho", "p", "c"};
409 return a;
410 }
411 else {
412 std::array<MString, nDim + 3> a = {"u", "v", "w", "rho", "p", "c"};
413 return a;
414 }
415 }();
416
417 MInt* Y = nullptr;
418
419 PrimitiveVariables(const MInt noSpecies);
420 void getPrimitiveVariableNames(MString* names);
422};
423
425template <MInt nDim>
427 static constexpr MInt noVariables = 0;
428};
429
430template <MInt nDim>
432 const MInt m_noSurfaceCoefficients = 0;
433};
434
435template <MInt nDim>
436inline void FvSysEqnNS<nDim>::Ausm_(const MInt orientation, const MFloat upwindCoefficient, const MFloat A,
437 const MFloat* const leftVars, const MFloat* const rightVars,
438 const MFloat* const NotUsed(srfcCoeff), MFloat* const flux) {
439 // catch the primitive variables rho and p,
440 // compute speed of sound, and interface mach number
441 const MFloat RHOL = leftVars[PV->RHO];
442 const MFloat PL = leftVars[PV->P];
443 const MFloat AL = sqrt(m_gamma * mMax(MFloatEps, PL / mMax(MFloatEps, RHOL)));
444 const MFloat ML = leftVars[orientation] / AL;
445
446 const MFloat RHOR = rightVars[PV->RHO];
447 const MFloat PR = rightVars[PV->P];
448 const MFloat AR = sqrt(m_gamma * mMax(MFloatEps, PR / mMax(MFloatEps, RHOR)));
449 const MFloat MR = rightVars[orientation] / AR;
450
451 // calculation of the resulting pressure and mach number on the surface
452 const MFloat MLR = 0.5 * (ML + MR);
453 const MFloat PLR = PL * (0.5 + upwindCoefficient * ML) + PR * (0.5 - upwindCoefficient * MR);
454
455 // calculation of the left and right rho*a
456 const MFloat RHO_AL = RHOL * AL;
457 const MFloat RHO_AR = RHOR * AR;
458
459 // calculation of the resulting mass flux through the surface
460 const MFloat RHO_U2 = 0.25 * (MLR * (RHO_AL + RHO_AR) + fabs(MLR) * (RHO_AL - RHO_AR));
461 const MFloat AbsRHO_U2 = fabs(RHO_U2);
462
463 // calculation of the energy:
464 const MFloat PLfRHOL = PL / RHOL;
465 const MFloat PRfRHOR = PR / RHOR;
466
467 // velocity magnitudes
468 const MFloat U2L = std::inner_product(&leftVars[PV->U], &leftVars[PV->U] + nDim, &leftVars[PV->U], 0.0);
469 const MFloat U2R = std::inner_product(&rightVars[PV->U], &rightVars[PV->U] + nDim, &rightVars[PV->U], 0.0);
470
471 const MFloat e0 = PLfRHOL * m_F1BGammaMinusOne + 0.5 * U2L + PLfRHOL;
472 const MFloat e1 = PRfRHOR * m_F1BGammaMinusOne + 0.5 * U2R + PRfRHOR;
473
474 std::array<MFloat, nDim> pFactor{};
475 pFactor[orientation] = 1.0;
476
477 for(MUint n = 0; n < nDim; n++) {
478 flux[FV->RHO_VV[n]] = (RHO_U2 * (leftVars[PV->VV[n]] + rightVars[PV->VV[n]])
479 + AbsRHO_U2 * (leftVars[PV->VV[n]] - rightVars[PV->VV[n]]) + PLR * pFactor[n])
480 * A;
481 }
482
483 flux[FV->RHO_E] = (RHO_U2 * (e0 + e1) + AbsRHO_U2 * (e0 - e1)) * A;
484 flux[FV->RHO] = 2.0 * RHO_U2 * A;
485
486 // Flux calculation for species transport
487 // TODO labels:FV @Julian, Make noSpecies constexpr
488 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
489 const MFloat YsL = leftVars[PV->Y[s]];
490 const MFloat YsR = rightVars[PV->Y[s]];
491 flux[FV->RHO_Y[s]] = (RHO_U2 * (YsL + YsR) + AbsRHO_U2 * (YsL - YsR)) * A;
492 }
493}
494
495
496template <MInt nDim>
497inline void FvSysEqnNS<nDim>::AusmPlus_(const MInt orientation, const MFloat upwindCoefficient, const MFloat A,
498 const MFloat* const leftVars, const MFloat* const rightVars,
499 const MFloat* const NotUsed(srfcCoeff), MFloat* const flux) {
500 if(PV->m_noSpecies > 0) {
501 mTerm(1, "Not yet implemented for multiple-species!");
502 }
503
504 std::array<MFloat, nDim> pFactor = {};
505 pFactor[orientation] = F1;
506
507 MFloat UL = leftVars[PV->U];
508 MFloat VL = leftVars[PV->V];
509 MFloat WL = 0.0;
510 IF_CONSTEXPR(nDim == 3) { WL = leftVars[PV->W]; }
511 MFloat RL = leftVars[PV->RHO];
512 MFloat PL = leftVars[PV->P];
513
514 MFloat UR = rightVars[PV->U];
515 MFloat VR = rightVars[PV->V];
516 MFloat WR = 0.0;
517 IF_CONSTEXPR(nDim == 3) { WR = rightVars[PV->W]; }
518 MFloat RR = rightVars[PV->RHO];
519 MFloat PR = rightVars[PV->P];
520
521 MFloat ql = leftVars[orientation];
522 MFloat AL = sqrt(m_gamma * PL / RL);
523 MFloat KL = 0.0;
524 KL = F1B2 * (UL * UL + VL * VL);
525 IF_CONSTEXPR(nDim == 3) { KL = F1B2 * (UL * UL + VL * VL + WL * WL); }
526 MFloat HL = (m_gamma * PL) / (m_gammaMinusOne * RL) + KL;
527
528 MFloat qr = rightVars[orientation];
529 MFloat AR = sqrt(m_gamma * PR / RR);
530 MFloat KR = 0.0;
531 KR = F1B2 * (UR * UR + VR * VR);
532 IF_CONSTEXPR(nDim == 3) { KR = F1B2 * (UR * UR + VR * VR + WR * WR); }
533 MFloat HR = (m_gamma * PR) / (m_gammaMinusOne * RR) + KR;
534
535 MFloat ML = ql / AL;
536 MFloat MR = qr / AR;
537
538 MFloat MLP = (fabs(ML) > F1) ? F1B2 * (ML + fabs(ML)) : F1B4 * POW2(ML + F1);
539 MFloat MRM = (fabs(MR) > F1) ? F1B2 * (MR - fabs(MR)) : -F1B4 * POW2(MR - F1);
540 MFloat M = MLP + MRM;
541 MFloat P = F1B2 * (PL + PR) + upwindCoefficient * (ML * PL - MR * PR);
542
543 flux[FV->RHO] = F1B2 * (M * (RL * AL + RR * AR) + fabs(M) * (RL * AL - RR * AR)) * A;
544 flux[FV->RHO_U] =
545 (F1B2 * (M * (RL * AL * UL + RR * AR * UR) + fabs(M) * (RL * AL * UL - RR * AR * UR)) + P * pFactor[0]) * A;
546 flux[FV->RHO_V] =
547 (F1B2 * (M * (RL * AL * VL + RR * AR * VR) + fabs(M) * (RL * AL * VL - RR * AR * VR)) + P * pFactor[1]) * A;
548 IF_CONSTEXPR(nDim == 3) {
549 flux[FV->RHO_W] =
550 (F1B2 * (M * (RL * AL * WL + RR * AR * WR) + fabs(M) * (RL * AL * WL - RR * AR * WR)) + P * pFactor[2]) * A;
551 }
552 flux[FV->RHO_E] = F1B2 * (M * (RL * AL * HL + RR * AR * HR) + fabs(M) * (RL * AL * HL - RR * AR * HR)) * A;
553}
554
555
556template <MInt nDim>
557inline void FvSysEqnNS<nDim>::Slau_(const MInt orientation, const MFloat NotUsed(upwindCoefficient), const MFloat A,
558 const MFloat* const leftVars, const MFloat* const rightVars,
559 const MFloat* const NotUsed(srfcCoeff), MFloat* const flux) {
560 if(PV->m_noSpecies > 0) {
561 mTerm(1, "Not yet implemented for multiple-species!");
562 }
563
564 std::array<MFloat, nDim> pFactor = {};
565 pFactor[orientation] = F1;
566
567 const MFloat UL = leftVars[PV->U];
568 const MFloat VL = leftVars[PV->V];
569 MFloat WL = 0.0;
570 IF_CONSTEXPR(nDim == 3) { WL = leftVars[PV->W]; }
571 const MFloat RL = leftVars[PV->RHO];
572 const MFloat PL = leftVars[PV->P];
573
574 const MFloat UR = rightVars[PV->U];
575 const MFloat VR = rightVars[PV->V];
576 MFloat WR = 0.0;
577 IF_CONSTEXPR(nDim == 3) { WR = rightVars[PV->W]; }
578 const MFloat RR = rightVars[PV->RHO];
579 const MFloat PR = rightVars[PV->P];
580
581 const MFloat ql = leftVars[orientation];
582 const MFloat AL = sqrt(m_gamma * PL / RL);
583 MFloat KL = 0.0;
584 IF_CONSTEXPR(nDim == 2) { KL = F1B2 * (UL * UL + VL * VL); }
585 IF_CONSTEXPR(nDim == 3) { KL = F1B2 * (UL * UL + VL * VL + WL * WL); }
586
587 const MFloat HL = (m_gamma * PL) / (m_gammaMinusOne * RL) + KL;
588
589 const MFloat qr = rightVars[orientation];
590 const MFloat AR = sqrt(m_gamma * PR / RR);
591 MFloat KR = 0.0;
592 IF_CONSTEXPR(nDim == 2) { KR = F1B2 * (UR * UR + VR * VR); }
593 IF_CONSTEXPR(nDim == 3) { KR = F1B2 * (UR * UR + VR * VR + WR * WR); }
594
595 const MFloat HR = (m_gamma * PR) / (m_gammaMinusOne * RR) + KR;
596
597 const MFloat ALR = F1B2 * (AL + AR);
598 const MFloat ML = ql / ALR;
599 const MFloat MR = qr / ALR;
600
601 const MFloat BL = (fabs(ML) > F1) ? F1B2 * (F1 + sgn(ML)) : F1B4 * POW2(ML + F1) * (F2 - ML);
602 const MFloat BR = (fabs(MR) > F1) ? F1B2 * (F1 - sgn(MR)) : F1B4 * POW2(MR - F1) * (F2 + MR);
603
604 const MFloat MH = mMin(F1, sqrt(KL + KR) / ALR);
605 const MFloat XI = POW2(F1 - MH);
606 // const MFloat P = F1B2*( PL+PR + (BL-BR)*(PL-PR) + (F1-XI)*(BL+BR-F1)*(PL+PR) ); //SLAU
607 const MFloat P = F1B2 * (PL + PR + (BL - BR) * (PL - PR) + (BL + BR - F1) * sqrt(KL + KR) * (RL + RR) * ALR); // SLAU2
608 const MFloat g = -mMax(mMin(ML, F0), -F1) * mMin(mMax(MR, F0), F1);
609 const MFloat Q = (RL * fabs(ql) + RR * fabs(qr)) / (RL + RR);
610 const MFloat QL = (F1 - g) * Q + g * fabs(ql);
611 const MFloat QR = (F1 - g) * Q + g * fabs(qr);
612 const MFloat M = F1B2 * (RL * (ql + fabs(QL)) + RR * (qr - fabs(QR)) - XI * (PR - PL) / ALR);
613
614 flux[FV->RHO] = M * A;
615 flux[FV->RHO_U] = (F1B2 * ((M + fabs(M)) * UL + (M - fabs(M)) * UR) + P * pFactor[0]) * A;
616 flux[FV->RHO_V] = (F1B2 * ((M + fabs(M)) * VL + (M - fabs(M)) * VR) + P * pFactor[1]) * A;
617 IF_CONSTEXPR(nDim == 3) { flux[FV->RHO_W] = (F1B2 * ((M + fabs(M)) * WL + (M - fabs(M)) * WR) + P * pFactor[2]) * A; }
618 flux[FV->RHO_E] = F1B2 * ((M + fabs(M)) * HL + (M - fabs(M)) * HR) * A;
619}
620
621
622template <MInt nDim>
623inline void FvSysEqnNS<nDim>::AusmBndryCorrection(const MInt orientation, const MFloat A, const MFloat* const leftVars,
624 const MFloat* const rightVars, MFloat* const flux) {
625 const MFloat PL = leftVars[PV->P];
626 const MFloat PR = rightVars[PV->P];
627 const MFloat PLR = 0.5 * (PR + PL);
628
629 std::array<MFloat, nDim> pFactor{};
630 pFactor[orientation] = 1.0;
631
632 for(MUint n = 0; n < nDim; n++) {
633 flux[FV->RHO_VV[n]] = PLR * pFactor[n] * A;
634 }
635
636 flux[FV->RHO_E] = 0.0;
637 flux[FV->RHO] = 0.0;
638
639 // Flux calculation for species transport
640 // TODO labels:FV @Julian, Make noSpecies constexpr
641 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
642 flux[FV->RHO_Y[s]] = 0.0;
643 }
644}
645
646template <MInt nDim>
647inline void FvSysEqnNS<nDim>::AusmALECorrection(const MInt orientation,
648 const MFloat A,
649 MFloat* const flux,
650 MFloat* const surfVars,
651 const MFloat* const bndrySurfVars) {
652 surfVars[PV->VV[orientation]] = bndrySurfVars[PV->VV[orientation]];
653 surfVars[PV->noVariables + PV->VV[orientation]] = bndrySurfVars[PV->VV[orientation]];
654
655 for(MInt v = 0; v < FV->noVariables; ++v) {
656 flux[v] = 0.0;
657 }
658
659 flux[CV->RHO_VV[orientation]] = bndrySurfVars[PV->P] * A;
660 flux[CV->RHO_E] = bndrySurfVars[PV->P] * bndrySurfVars[PV->VV[orientation]] * A;
661}
662
663template <MInt nDim>
664template <MInt centralizeScheme>
666 MFloat* const varR,
667 [[maybe_unused]] const MInt orientation,
668 [[maybe_unused]] const MFloat levelFac) {
669 static_assert(centralizeScheme > 0 && centralizeScheme < 6, "Unintended/unimplemented function-call!");
670
671 IF_CONSTEXPR(centralizeScheme == 1) {
672 const MFloat z = mMin(F1, mMax(fabs(varL[orientation]) / sqrt(m_gamma * varL[PV->P] / varL[PV->RHO]),
673 fabs(varR[orientation]) / sqrt(m_gamma * varR[PV->P] / varR[PV->RHO])));
674 for(MInt k = 0; k < nDim; k++) {
675 const MInt velId = PV->VV[k];
676 const MFloat ML = varL[velId];
677 const MFloat MR = varR[velId];
678 varL[velId] = F1B2 * ((F1 + z) * ML + (F1 - z) * MR);
679 varR[velId] = F1B2 * ((F1 + z) * MR + (F1 - z) * ML);
680 }
681 }
682 else IF_CONSTEXPR(centralizeScheme == 2) {
683 const MFloat z = mMin(F1, (fabs(varL[orientation]) / sqrt(m_gamma * varL[PV->P] / varL[PV->RHO]))
684 * (fabs(varR[orientation]) / sqrt(m_gamma * varR[PV->P] / varR[PV->RHO])));
685 for(MInt k = 0; k < nDim; k++) {
686 const MInt velId = PV->VV[k];
687 const MFloat ML = varL[velId];
688 const MFloat MR = varR[velId];
689 varL[velId] = F1B2 * ((F1 + z) * ML + (F1 - z) * MR);
690 varR[velId] = F1B2 * ((F1 + z) * MR + (F1 - z) * ML);
691 }
692 }
693 else IF_CONSTEXPR(centralizeScheme == 3) {
694 for(MInt v = 0; v < PV->noVariables; v++) {
695 const MFloat Vmean = F1B2 * (varL[v] + varR[v]);
696 varL[v] = Vmean;
697 varR[v] = Vmean;
698 }
699 }
700 else IF_CONSTEXPR(centralizeScheme == 4) {
701 const MFloat z = pow(mMin(F1, (fabs(varL[orientation]) / sqrt(m_gamma * varL[PV->P] / varL[PV->RHO]))
702 * (fabs(varR[orientation]) / sqrt(m_gamma * varR[PV->P] / varR[PV->RHO]))),
703 levelFac);
704 for(MInt k = 0; k < nDim; k++) {
705 const MInt velId = PV->VV[k];
706 const MFloat ML = varL[velId];
707 const MFloat MR = varR[velId];
708 varL[velId] = F1B2 * ((F1 + z) * ML + (F1 - z) * MR);
709 varR[velId] = F1B2 * ((F1 + z) * MR + (F1 - z) * ML);
710 }
711 }
712 else {
713 const MFloat z = mMin(F1, m_centralizeSurfaceVariablesFactor
714 * mMax((fabs(varL[orientation]) / sqrt(m_gamma * varL[PV->P] / varL[PV->RHO])),
715 (fabs(varR[orientation]) / sqrt(m_gamma * varR[PV->P] / varR[PV->RHO]))));
716 for(MInt k = 0; k < nDim; k++) {
717 const MInt velId = PV->VV[k];
718 const MFloat ML = varL[velId];
719 const MFloat MR = varR[velId];
720 varL[velId] = F1B2 * ((F1 + z) * ML + (F1 - z) * MR);
721 varR[velId] = F1B2 * ((F1 + z) * MR + (F1 - z) * ML);
722 }
723 }
724}
725
726template <MInt nDim>
727inline void FvSysEqnNS<nDim>::viscousFluxFivePoint(const MInt orientation, const MFloat A, const MFloat* const vars0,
728 const MFloat* const vars1, const MFloat* const slope0,
729 const MFloat* const slope1, const MFloat* const, const MFloat f0,
730 const MFloat f1, MFloat* const flux) {
731 static const MFloat rhoUDth = m_muInfinity * m_F1BPr;
732 static const MFloat F1BRe0 = F1 / m_Re0;
733
734 // calculate the primitve variables on the surface u,v,rho,p
735 const std::array<MFloat, nDim> velocity = [&] {
736 std::array<MFloat, nDim> tmp{};
737 for(MUint n = 0; n < nDim; n++) {
738 tmp[n] = F1B2 * (vars0[PV->VV[n]] + vars1[PV->VV[n]]);
739 }
740 return tmp;
741 }();
742
743 const MFloat rho = F1B2 * (vars0[PV->RHO] + vars1[PV->RHO]);
744 const MFloat Frho = F1 / rho;
745 const MFloat p = F1B2 * (vars0[PV->P] + vars1[PV->P]);
746
747 // Temperature on the surface T = gamma * p / rho
748 const MFloat T = m_gamma * p * Frho;
749
750 // Indices for the orientations
751 const MUint id0 = orientation;
752 const MUint id1 = index0[orientation];
753 const MUint id2 = index1[orientation];
754
755 // Compute A / Re
756 const MFloat dAOverRe = A * F1BRe0;
757
758 // calculate the viscosity with the sutherland law mue = T^3/2 * (1+S/T_0)(T + S/T_0)
759 const MFloat mue = (T * sqrt(T) * m_sutherlandPlusOne) / (T + m_sutherlandConstant);
760
761 // calculate the heat flux (T_x = gamma*(p_x/rho - p/rho^2 * rho_x))
762
763 const MFloat lambda = (T * sqrt(T) * m_sutherlandPlusOneThermal) / (T + m_sutherlandConstantThermal);
764
765 const MUint sq0 = PV->P * nDim + id0;
766 const MUint sq1 = PV->RHO * nDim + id0;
767 const MFloat q = (lambda)*m_gFGMOrPr * Frho
768 * ((f0 * slope0[sq0] + f1 * slope1[sq0]) - p * Frho * (f0 * slope0[sq1] + f1 * slope1[sq1]));
769
770 // Compute the stress terms
771 const MUint s00 = id0 * nDim + id0;
772 const MUint s01 = id0 * nDim + id1;
773 const MUint s10 = id1 * nDim + id0;
774 const MUint s11 = id1 * nDim + id1;
775
776 std::array<MFloat, nDim> tau{};
777 IF_CONSTEXPR(nDim == 2) {
778 tau[id0] = mue * (f0 * (F4B3 * slope0[s00] - F2B3 * slope0[s11]) + f1 * (F4B3 * slope1[s00] - F2B3 * slope1[s11]));
779 tau[id1] = mue * (f0 * (slope0[s01] + slope0[s10]) + f1 * (slope1[s01] + slope1[s10]));
780 }
781 else IF_CONSTEXPR(nDim == 3) {
782 const MUint s22 = id2 * nDim + id2;
783 const MUint s02 = id0 * nDim + id2;
784 const MUint s20 = id2 * nDim + id0;
785 tau[id0] = mue
786 * (f0 * (F4B3 * slope0[s00] - F2B3 * (slope0[s11] + slope0[s22]))
787 + f1 * (F4B3 * slope1[s00] - F2B3 * (slope1[s11] + slope1[s22])));
788 tau[id1] = mue * (f0 * (slope0[s01] + slope0[s10]) + f1 * (slope1[s01] + slope1[s10]));
789 tau[id2] = mue * (f0 * (slope0[s02] + slope0[s20]) + f1 * (slope1[s02] + slope1[s20]));
790 }
791
792 // Compute the flux
793 for(MUint n = 0; n < nDim; n++) {
794 flux[FV->RHO_VV[n]] -= dAOverRe * tau[n];
795 }
796 flux[FV->RHO_E] -= dAOverRe * (std::inner_product(velocity.begin(), velocity.end(), tau.begin(), 0.0) + q);
797
798 // progress variable
799 const MFloat c = dAOverRe * rhoUDth;
800 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
801 const MUint i = PV->Y[s] * nDim + id0;
802 flux[FV->RHO_Y[s]] -= c * (f0 * slope0[i] + f1 * slope1[i]);
803 }
804}
805
806template <MInt nDim>
808 const MFloat* const vars0, const MFloat* const vars1,
809 const MFloat* const slope0, const MFloat* const slope1,
810 const MFloat f0, const MFloat f1, MFloat* const flux,
811 const MFloat mue_wm) {
812 static const MFloat F1BRe0 = F1 / m_Re0;
813
814
815 // calculate the primitve variables on the surface u,v,rho,p
816 const std::array<MFloat, nDim> velocity = [&] {
817 std::array<MFloat, nDim> tmp{};
818 for(MUint n = 0; n < nDim; n++) {
819 tmp[n] = F1B2 * (vars0[PV->VV[n]] + vars1[PV->VV[n]]);
820 }
821 return tmp;
822 }();
823
824 // Indices for the orientations
825 const MUint id0 = orientation;
826 const MUint id1 = index0[orientation];
827 const MUint id2 = index1[orientation];
828
829 // Compute A / Re
830 const MFloat dAOverRe = A * F1BRe0;
831
832 // Compute the stress terms
833 const MUint s00 = id0 * nDim + id0;
834 const MUint s01 = id0 * nDim + id1;
835 const MUint s10 = id1 * nDim + id0;
836 const MUint s11 = id1 * nDim + id1;
837
838 std::array<MFloat, nDim> tau{};
839 IF_CONSTEXPR(nDim == 2) {
840 tau[id0] =
841 mue_wm * (f0 * (F4B3 * slope0[s00] - F2B3 * slope0[s11]) + f1 * (F4B3 * slope1[s00] - F2B3 * slope1[s11]));
842 tau[id1] = mue_wm * (f0 * (slope0[s01] + slope0[s10]) + f1 * (slope1[s01] + slope1[s10]));
843 }
844 else IF_CONSTEXPR(nDim == 3) {
845 const MUint s22 = id2 * nDim + id2;
846 const MUint s02 = id0 * nDim + id2;
847 const MUint s20 = id2 * nDim + id0;
848 tau[id0] = mue_wm
849 * (f0 * (F4B3 * slope0[s00] - F2B3 * (slope0[s11] + slope0[s22]))
850 + f1 * (F4B3 * slope1[s00] - F2B3 * (slope1[s11] + slope1[s22])));
851 tau[id1] = mue_wm * (f0 * (slope0[s01] + slope0[s10]) + f1 * (slope1[s01] + slope1[s10]));
852 tau[id2] = mue_wm * (f0 * (slope0[s02] + slope0[s20]) + f1 * (slope1[s02] + slope1[s20]));
853 }
854
855 // Correct the fluxes
856 for(MUint n = 0; n < nDim; n++) {
857 flux[CV->RHO_VV[n]] -= dAOverRe * tau[n];
858 }
859 flux[CV->RHO_E] -= dAOverRe * (std::inner_product(velocity.begin(), velocity.end(), tau.begin(), 0.0));
860}
861
862template <MInt nDim>
863inline void FvSysEqnNS<nDim>::viscousFluxThreePoint(const MInt orientation, const MFloat A, const MBool isBndry,
864 const MFloat* const surfaceCoords, const MFloat* const coord0,
865 const MFloat* const coord1, const MFloat* const cellVars0,
866 const MFloat* const cellVars1, const MFloat* const vars0,
867 const MFloat* const vars1, const MFloat* const slope0,
868 const MFloat* const slope1, const MFloat f0, const MFloat f1,
869 MFloat* const flux) {
870 static const MFloat rhoUDth = m_muInfinity * m_F1BPr;
871 static const MFloat F1BRe0 = F1 / m_Re0;
872
873 // calculate the primitve variables on the surface u,v,rho,p
874 const std::array<MFloat, nDim> velocity = [&] {
875 std::array<MFloat, nDim> tmp{};
876 for(MUint n = 0; n < nDim; n++) {
877 tmp[n] = F1B2 * (vars0[PV->VV[n]] + vars1[PV->VV[n]]);
878 }
879 return tmp;
880 }();
881
882 const MFloat rho = F1B2 * (vars0[PV->RHO] + vars1[PV->RHO]);
883 const MFloat Frho = F1 / rho;
884 const MFloat p = F1B2 * (vars0[PV->P] + vars1[PV->P]);
885
886 // Temperature on the surface T = gamma * p / rho
887 const MFloat T = m_gamma * p * Frho;
888
889 // Indices for the orientations
890 const MUint id0 = orientation;
891 const MUint id1 = index0[orientation];
892 const MUint id2 = index1[orientation];
893
894 // Compute A / Re
895 const MFloat dAOverRe = A * F1BRe0;
896
897 // calculate the viscosity with the sutherland law mue = T^3/2 * (1+S/T_0)(T + S/T_0)
898 const MFloat mue = (T * sqrt(T) * m_sutherlandPlusOne) / (T + m_sutherlandConstant);
899
900 const MFloat lambda = (T * sqrt(T) * m_sutherlandPlusOneThermal) / (T + m_sutherlandConstantThermal);
901
902 // TODO labels:FV @Julian, change to stack alloc
903 std::vector<MFloat> slopes(PV->noVariables * nDim);
904
905 /*#ifdef _VISCOUS_SLOPES_COMPACT_VARIANT_
906 const MFloat dx = F1B2 * (coord1[id0] - coord0[id0]);
907 #endif*/
908 for(MInt var = 0; var < PV->noVariables; var++) {
909 slopes[nDim * var + id0] =
910 cellVars1[var]
911 - cellVars0[var]
912 /*#ifdef _VISCOUS_SLOPES_COMPACT_VARIANT_
913 + (surfaceCoords[id0] - coord1[id0] + dx) * slope1[var * nDim + id0]
914 - (surfaceCoords[id0] - coord0[id0] - dx) * slope0[var * nDim + id0]
915 #endif*/
916 + (surfaceCoords[id1] - coord1[id1]) * slope1[var * nDim + id1]
917 - (surfaceCoords[id1] - coord0[id1]) * slope0[var * nDim + id1];
918 IF_CONSTEXPR(nDim == 3) {
919 slopes[nDim * var + id0] += (surfaceCoords[id2] - coord1[id2]) * slope1[var * nDim + id2]
920 - (surfaceCoords[id2] - coord0[id2]) * slope0[var * nDim + id2];
921 }
922 /*#ifdef _VISCOUS_SLOPES_COMPACT_VARIANT_
923 )
924 / (F2 * dx);
925 #else*/
926 // )
927 slopes[nDim * var + id0] /= (coord1[id0] - coord0[id0]);
928
929
930 //#endif
931 slopes[nDim * var + id1] = f0 * slope0[var * nDim + id1] + f1 * slope1[var * nDim + id1];
932 IF_CONSTEXPR(nDim == 3) {
933 slopes[nDim * var + id2] = f0 * slope0[var * nDim + id2] + f1 * slope1[var * nDim + id2];
934 }
935 if(isBndry) {
936 slopes[nDim * var + id0] = f0 * slope0[var * nDim + id0] + f1 * slope1[var * nDim + id0];
937 }
938 }
939
940 const MUint sq0 = PV->P * nDim + id0;
941 const MUint sq1 = PV->RHO * nDim + id0;
942
943 const MFloat q = lambda * m_gFGMOrPr * Frho * (slopes[sq0] - p * Frho * slopes[sq1]);
944
945 // Compute the stress terms
946 const MUint s00 = id0 * nDim + id0;
947 const MUint s01 = id0 * nDim + id1;
948 const MUint s10 = id1 * nDim + id0;
949 const MUint s11 = id1 * nDim + id1;
950
951 std::array<MFloat, nDim> tau{};
952 IF_CONSTEXPR(nDim == 2) {
953 tau[id0] = mue * (F4B3 * slopes[s00] - F2B3 * slopes[s11]);
954 tau[id1] = mue * (slopes[s01] + slopes[s10]);
955 }
956 else IF_CONSTEXPR(nDim == 3) {
957 const MUint s22 = id2 * nDim + id2;
958 const MUint s02 = id0 * nDim + id2;
959 const MUint s20 = id2 * nDim + id0;
960 tau[id0] = mue * (F4B3 * slopes[s00] - F2B3 * (slopes[s11] + slopes[s22]));
961 tau[id1] = mue * (slopes[s01] + slopes[s10]);
962 tau[id2] = mue * (slopes[s02] + slopes[s20]);
963 }
964
965 // Compute the flux
966 for(MUint n = 0; n < nDim; n++) {
967 flux[FV->RHO_VV[n]] -= dAOverRe * tau[n];
968 }
969 flux[FV->RHO_E] -= dAOverRe * (std::inner_product(velocity.begin(), velocity.end(), tau.begin(), 0.0) + q);
970
971 // progress variable
972 const MFloat c = dAOverRe * rhoUDth;
973 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
974 const MUint i = PV->Y[s] * nDim + id0;
975 flux[FV->RHO_Y[s]] -= c * (f0 * slope0[i] + f1 * slope1[i]);
976 }
977}
978
987template <MInt nDim>
988inline void FvSysEqnNS<nDim>::viscousFluxStabilized(const MInt orientation, const MFloat A, const MBool isBndry,
989 const MFloat* const surfaceCoords, const MFloat* const coord0,
990 const MFloat* const coord1, const MFloat* const cellVars0,
991 const MFloat* const cellVars1, const MFloat* const vars0,
992 const MFloat* const vars1, const MFloat* const slope0,
993 const MFloat* const slope1, const MFloat f0, const MFloat f1,
994 MFloat* const flux) {
995 static const MFloat rhoUDth = m_muInfinity * m_F1BPr;
996 static const MFloat F1BRe0 = F1 / m_Re0;
997 const MFloat fac = m_enhanceThreePointViscFluxFactor; // increased stability
998
999 // calculate the primitve variables on the surface u,v,rho,p
1000 const std::array<MFloat, nDim> velocity = [&] {
1001 std::array<MFloat, nDim> tmp{};
1002 for(MUint n = 0; n < nDim; n++) {
1003 tmp[n] = F1B2 * (vars0[PV->VV[n]] + vars1[PV->VV[n]]);
1004 }
1005 return tmp;
1006 }();
1007
1008 const MFloat rho = F1B2 * (vars0[PV->RHO] + vars1[PV->RHO]);
1009 const MFloat Frho = F1 / rho;
1010 const MFloat p = F1B2 * (vars0[PV->P] + vars1[PV->P]);
1011
1012 // Temperature on the surface T = gamma * p / rho
1013 const MFloat T = m_gamma * p * Frho;
1014
1015 // Indices for the orientations
1016 const MUint id0 = orientation;
1017 const MUint id1 = index0[orientation];
1018 const MUint id2 = index1[orientation];
1019
1020 // Compute A / Re
1021 const MFloat dAOverRe = A * F1BRe0;
1022
1023 // calculate the viscosity with the sutherland law mue = T^3/2 * (1+S/T_0)(T + S/T_0)
1024 const MFloat mue = (T * sqrt(T) * m_sutherlandPlusOne) / (T + m_sutherlandConstant);
1025
1026 const MFloat lambda = (T * sqrt(T) * m_sutherlandPlusOneThermal) / (T + m_sutherlandConstantThermal);
1027
1028 // TODO labels:FV @Julian, change to stack alloc
1029 std::vector<MFloat> slopes(PV->noVariables * nDim);
1030
1031 /*#ifdef _VISCOUS_SLOPES_COMPACT_VARIANT_
1032 const MFloat dx = F1B2 * (coord1[id0] - coord0[id0]);
1033 #endif*/
1034 for(MInt var = 0; var < PV->noVariables; var++) {
1035 slopes[nDim * var + id0] =
1036 cellVars1[var]
1037 - cellVars0[var]
1038 /*#ifdef _VISCOUS_SLOPES_COMPACT_VARIANT_
1039 + (surfaceCoords[id0] - coord1[id0] + dx) * slope1[var * nDim + id0]
1040 - (surfaceCoords[id0] - coord0[id0] - dx) * slope0[var * nDim + id0]
1041 #endif*/
1042 + (surfaceCoords[id1] - coord1[id1]) * slope1[var * nDim + id1]
1043 - (surfaceCoords[id1] - coord0[id1]) * slope0[var * nDim + id1];
1044 IF_CONSTEXPR(nDim == 3) {
1045 slopes[nDim * var + id0] += (surfaceCoords[id2] - coord1[id2]) * slope1[var * nDim + id2]
1046 - (surfaceCoords[id2] - coord0[id2]) * slope0[var * nDim + id2];
1047 }
1048 /*#ifdef _VISCOUS_SLOPES_COMPACT_VARIANT_
1049 )
1050 / (F2 * dx);
1051 #else*/
1052 // )
1053 slopes[nDim * var + id0] /= (coord1[id0] - coord0[id0]);
1054
1055
1056 //#endif
1057 slopes[nDim * var + id1] = f0 * slope0[var * nDim + id1] + f1 * slope1[var * nDim + id1];
1058 IF_CONSTEXPR(nDim == 3) {
1059 slopes[nDim * var + id2] = f0 * slope0[var * nDim + id2] + f1 * slope1[var * nDim + id2];
1060 }
1061
1062 slopes[nDim * var + id0] =
1063 fac * slopes[nDim * var + id0] + (1.0 - fac) * (f0 * slope0[var * nDim + id0] + f1 * slope1[var * nDim + id0]);
1064
1065 if(isBndry) {
1066 slopes[nDim * var + id0] = f0 * slope0[var * nDim + id0] + f1 * slope1[var * nDim + id0];
1067 }
1068 }
1069
1070 const MUint sq0 = PV->P * nDim + id0;
1071 const MUint sq1 = PV->RHO * nDim + id0;
1072
1073 const MFloat q = lambda * m_gFGMOrPr * Frho * (slopes[sq0] - p * Frho * slopes[sq1]);
1074
1075 // Compute the stress terms
1076 const MUint s00 = id0 * nDim + id0;
1077 const MUint s01 = id0 * nDim + id1;
1078 const MUint s10 = id1 * nDim + id0;
1079 const MUint s11 = id1 * nDim + id1;
1080
1081 std::array<MFloat, nDim> tau{};
1082 IF_CONSTEXPR(nDim == 2) {
1083 tau[id0] = mue * (F4B3 * slopes[s00] - F2B3 * slopes[s11]);
1084 tau[id1] = mue * (slopes[s01] + slopes[s10]);
1085 }
1086 else IF_CONSTEXPR(nDim == 3) {
1087 const MUint s22 = id2 * nDim + id2;
1088 const MUint s02 = id0 * nDim + id2;
1089 const MUint s20 = id2 * nDim + id0;
1090 tau[id0] = mue * (F4B3 * slopes[s00] - F2B3 * (slopes[s11] + slopes[s22]));
1091 tau[id1] = mue * (slopes[s01] + slopes[s10]);
1092 tau[id2] = mue * (slopes[s02] + slopes[s20]);
1093 }
1094
1095 // Compute the flux
1096 for(MUint n = 0; n < nDim; n++) {
1097 flux[FV->RHO_VV[n]] -= dAOverRe * tau[n];
1098 }
1099 flux[FV->RHO_E] -= dAOverRe * (std::inner_product(velocity.begin(), velocity.end(), tau.begin(), 0.0) + q);
1100
1101 // progress variable
1102 const MFloat c = dAOverRe * rhoUDth;
1103 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
1104 const MUint i = PV->Y[s] * nDim + id0;
1105 flux[FV->RHO_Y[s]] -= c * (f0 * slope0[i] + f1 * slope1[i]);
1106 }
1107}
1108
1109template <MInt nDim>
1110inline void FvSysEqnNS<nDim>::computePrimitiveVariables(const MFloat* const cvarsCell, MFloat* const pvarsCell,
1111 const MFloat* const NotUsed(avarsCell)) {
1112 const MFloat fRho = F1 / cvarsCell[CV->RHO];
1113 MFloat velPOW2 = F0;
1114 for(MInt n = 0; n < nDim; ++n) { // compute velocity
1115 pvarsCell[PV->VV[n]] = cvarsCell[CV->RHO_VV[n]] * fRho;
1116 velPOW2 += POW2(pvarsCell[PV->VV[n]]);
1117 }
1118
1119 // density and pressure:
1120 pvarsCell[PV->RHO] = cvarsCell[CV->RHO]; // density
1121 pvarsCell[PV->P] = m_gammaMinusOne * (cvarsCell[CV->RHO_E] - F1B2 * pvarsCell[PV->RHO] * velPOW2);
1122
1123 // compute the species
1124 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
1125 pvarsCell[PV->Y[s]] = cvarsCell[CV->RHO_Y[s]] * fRho;
1126 }
1127}
1128
1129template <MInt nDim>
1130inline void FvSysEqnNS<nDim>::computeConservativeVariables(const MFloat* const pvarsCell, MFloat* const cvarsCell,
1131 const MFloat* const NotUsed(avarsCell)) {
1132 // compute rho v
1133 MFloat velPOW2 = F0;
1134 for(MInt vel = 0; vel < nDim; ++vel) {
1135 cvarsCell[vel] = pvarsCell[vel] * pvarsCell[PV->RHO];
1136 velPOW2 += POW2(pvarsCell[vel]);
1137 }
1138
1139 // compute rho e
1140 cvarsCell[CV->RHO_E] = pvarsCell[PV->P] * m_F1BGammaMinusOne + F1B2 * pvarsCell[PV->RHO] * velPOW2;
1141
1142 // copy the density
1143 cvarsCell[CV->RHO] = pvarsCell[PV->RHO];
1144
1145 // compute rho Yi
1146 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
1147 cvarsCell[CV->RHO_Y[s]] = pvarsCell[PV->Y[s]] * pvarsCell[PV->RHO];
1148 }
1149}
1150
1151template <MInt nDim>
1152inline std::vector<std::vector<MFloat>>
1153FvSysEqnNS<nDim>::conservativeSlopes(const MFloat* const pvarsCell, const MFloat* const NotUsed(cvarsCell),
1154 const MFloat* const NotUsed(avarsCell), const MFloat* const slopesCell) {
1155 MFloat U2 = F0;
1156 for(MInt i = 0; i < nDim; i++) {
1157 U2 += POW2(pvarsCell[PV->VV[i]]);
1158 }
1159
1160 std::vector<std::vector<MFloat>> dQ(CV->noVariables, std::vector<MFloat>(nDim));
1161
1162 for(MInt d = 0; d < nDim; d++) {
1163 dQ[CV->RHO][d] = slopesCell[PV->RHO * nDim + d];
1164 dQ[CV->RHO_E][d] = slopesCell[PV->P * nDim + d] / (m_gamma - F1) + F1B2 * U2 * slopesCell[PV->RHO * nDim + d];
1165 for(MInt j = 0; j < nDim; j++) {
1166 dQ[CV->RHO_VV[j]][d] =
1167 pvarsCell[PV->VV[j]] * slopesCell[PV->RHO * nDim + d] + pvarsCell[PV->RHO] * slopesCell[PV->VV[j] * nDim + d];
1168 dQ[CV->RHO_E][d] += pvarsCell[PV->RHO] * pvarsCell[PV->VV[j]] * slopesCell[PV->VV[j] * nDim + d];
1169 }
1170 for(MUint s = 0; s < CV->m_noSpecies; ++s) {
1171 dQ[CV->RHO_Y[s]][d] =
1172 pvarsCell[PV->Y[s]] * slopesCell[PV->RHO * nDim + d] + pvarsCell[PV->RHO] * slopesCell[PV->Y[s] * nDim + d];
1173 }
1174 }
1175
1176 return dQ;
1177}
1178
1179
1180#endif // FVSYSEQNNS_H_
static constexpr MInt m_noRansEquations
void computePrimitiveVariables(const MFloat *const cvarsCell, MFloat *const pvarsCell, const MFloat *const NotUsed(avarsCell))
void computeVolumeForces(const MInt, MFloat *, MFloat *, const MFloat, const MFloat *const, const MInt, const MInt *const, const MFloat *const, const MInt, MFloat)
constexpr MFloat cp_Ref()
constexpr MFloat speedOfSoundSquared(const MFloat density, const MFloat pressure)
speed of sound squared a^2 = gamma * pressure / density
constexpr MFloat pressure(const MFloat density, const MFloat momentumDensitySquared, const MFloat energyDensity)
MFloat m_sutherlandConstant
constexpr MFloat vanDriest(const MFloat Ma)
van-Driest Transformation (correspods to R*H)
static constexpr std::array< MInt, nDim > getArray012()
void Ausm_(const MInt orientation, const MFloat upwindCoefficient, const MFloat A, const MFloat *const leftVars, const MFloat *const rightVars, const MFloat *const NotUsed(srfcCoeff), MFloat *const flux)
ConservativeVariables * CV
static constexpr MBool hasAV
constexpr MFloat cv_Ref()
void wmViscousFluxCorrection(const MInt orientation, const MFloat A, const MFloat *const vars0, const MFloat *const vars1, const MFloat *const slope0, const MFloat *const slope1, const MFloat f0, const MFloat f1, MFloat *const flux, MFloat const mue_wm)
void centralizeSurfaceVariables(MFloat *const varL, MFloat *const varR, const MInt orientation, const MFloat levelFac)
MFloat m_sutherlandPlusOneThermal
constexpr MFloat pressureEnergy(const MFloat pressure)
constexpr MFloat internalEnergy(const MFloat pressure, const MFloat density, const MFloat velocitySquared)
PrimitiveVariables * PV
constexpr MFloat computeTimeStepDiffusion(const MFloat diffusion_coefficient, const MFloat C, const MFloat dx)
void viscousFluxStabilized(const MInt orientation, const MFloat A, const MBool isBndry, const MFloat *const surfaceCoords, const MFloat *const coord0, const MFloat *const coord1, const MFloat *const cellVars0, const MFloat *const cellVars1, const MFloat *const vars0, const MFloat *const vars1, const MFloat *const slope0, const MFloat *const slope1, const MFloat f0, const MFloat f1, MFloat *const flux)
Computes the viscous fluxes using a five-point stencil (less dissipative) blended with a compact sten...
MFloat m_sutherlandPlusOne
void Ausm(const MInt orientation, const MFloat upwindCoefficient, const MFloat A, const MFloat *const leftVars, const MFloat *const rightVars, const MFloat *const srfcCoeff, MFloat *const flux)
constexpr MFloat pressure_ES(const MFloat temperture, const MFloat density)
pressure: p = rho * T / gamma (equation of state - ideal gas law)
MFloat m_centralizeSurfaceVariablesFactor
void viscousFlux(const MInt orientation, const MFloat A, const MBool isBndry, const MFloat *const surfaceCoords, const MFloat *const coord0, const MFloat *const coord1, const MFloat *const cellVars0, const MFloat *const cellVars1, const MFloat *const vars0, const MFloat *const vars1, const MFloat *const slope0, const MFloat *const slope1, const MFloat f0, const MFloat f1, MFloat *const flux)
void AusmALECorrection(const MInt orientation, const MFloat A, MFloat *const flux, MFloat *const surfVars, const MFloat *const bndrySurfVars)
AdditionalVariables * AV
MFloat computeTimeStepEulerMagnitude(const MFloat rho, const std::array< MFloat, nDim > u, const MFloat p, const MFloat C, const MFloat dx)
MFloat m_enhanceThreePointViscFluxFactor
constexpr MFloat density_ES(const MFloat pressure, const MFloat temperature)
density: rho = gamma * p / T (equation of state - ideal gas law)
void viscousFluxThreePoint(const MInt orientation, const MFloat A, const MBool isBndry, const MFloat *const surfaceCoords, const MFloat *const coord0, const MFloat *const coord1, const MFloat *const cellVars0, const MFloat *const cellVars1, const MFloat *const vars0, const MFloat *const vars1, const MFloat *const slope0, const MFloat *const slope1, const MFloat f0, const MFloat f1, MFloat *const flux)
SurfaceCoefficients * SC
MFloat m_FGammaBGammaMinusOne
MFloat m_referenceTemperature
constexpr MFloat enthalpy(const MFloat pressure, const MFloat density)
enthalpy from primitive variables
void viscousFluxFivePoint(const MInt orientation, const MFloat A, const MFloat *const vars0, const MFloat *const vars1, const MFloat *const slope0, const MFloat *const slope1, const MFloat *const NotUsed(srfcCoeff), const MFloat f0, const MFloat f1, MFloat *const flux)
void AusmBndryCorrection(const MInt orientation, const MFloat A, const MFloat *const leftVars, const MFloat *const rightVars, MFloat *const flux)
void viscousFlux(const MInt orientation, const MFloat A, const MFloat *const vars0, const MFloat *const vars1, const MFloat *const slope0, const MFloat *const slope1, const MFloat *const srfcCoeff, const MFloat f0, const MFloat f1, MFloat *const flux)
void readProperties()
constexpr MFloat speedOfSound(const MFloat density, const MFloat pressure)
Speed of sound: a = sqrt(gamma * pressure / density)
constexpr MFloat p_Ref()
void AusmPlus_(const MInt orientation, const MFloat upwindCoefficient, const MFloat A, const MFloat *const leftVars, const MFloat *const rightVars, const MFloat *const NotUsed(srfcCoeff), MFloat *const flux)
constexpr MFloat density_IR(const MFloat temperature)
density: rho = T^(1/(gamma -1 )) (isentropic relationship)
constexpr MFloat temperature_ES(const MFloat density, const MFloat pressure)
Temperature: T = gamma * pressure / density (equation of state - ideal gas law)
constexpr MFloat pressure_IR(const MFloat temperature)
void wmViscousFluxCorrectionFivePoint(const MInt orientation, const MFloat A, const MFloat *const vars0, const MFloat *const vars1, const MFloat *const slope0, const MFloat *const slope1, const MFloat f0, const MFloat f1, MFloat *const flux, MFloat const mue_wm)
void Slau_(const MInt orientation, const MFloat NotUsed(upwindCoefficient), const MFloat A, const MFloat *const leftVars, const MFloat *const rightVars, const MFloat *const NotUsed(srfcCoeff), MFloat *const flux)
MFloat m_F1BGammaMinusOne
static constexpr MInt m_ransModel
constexpr MFloat pressure_IRit(const MFloat pressure, const MFloat massFlux)
static MFloat sgn(MFloat val)
static const MUint index1[nDim]
FluxVariables * FV
std::vector< std::vector< MFloat > > conservativeSlopes(const MFloat *const pvarsCell, const MFloat *const cvarsCell, const MFloat *const avarsCell, const MFloat *const slopesCell)
static const MUint index0[nDim]
constexpr MFloat sutherlandLaw(const MFloat T)
constexpr MFloat entropy(const MFloat pressure, const MFloat density)
entropy from primitive variables
constexpr MFloat temperature_IR(const MFloat Ma)
Temperature: T = 1 / (1 + (gamma - 1)/2 * Ma^2) (isentropic relationship)
constexpr MFloat gamma_Ref()
constexpr MFloat speedOfSound(const MFloat temperature)
Speed of sound: a = sqrt(T)
constexpr MFloat density_IR_P(const MFloat pressure)
density: rho = (p * gamma)^(1/gamma) (isentropic relationship)
void computeConservativeVariables(const MFloat *const pvarsCell, MFloat *const cvarsCell, const MFloat *const NotUsed(avarsCell))
MFloat m_sutherlandConstantThermal
constexpr MFloat CroccoBusemann(const MFloat Ma, const MFloat x)
Crocco-Busemann relation.
static constexpr MBool hasSC
@ FIVE_POINT_STABILIZED
Definition: enums.h:184
@ FIVE_POINT
Definition: enums.h:184
@ THREE_POINT
Definition: enums.h:184
@ SLAU
Definition: enums.h:182
@ AUSM
Definition: enums.h:182
@ AUSMPLUS
Definition: enums.h:182
@ NORANS
Definition: enums.h:52
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
constexpr Real POW2(const Real x)
Definition: functions.h:119
constexpr T mMin(const T &x, const T &y)
Definition: functions.h:90
constexpr T mMax(const T &x, const T &y)
Definition: functions.h:94
int32_t MInt
Definition: maiatypes.h:62
uint32_t MUint
Definition: maiatypes.h:63
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
No additional variables are used in this SysEqn.
Static indices for accessing conservative variables in nDim spatial dimensions.
Static indices for accessing flux variables in this SysEqn identical to the conservative variables.
Static indices for accessing primitive variables in nDim spatial dimensions.
Definition: contexttypes.h:19