38 template <MInt scheme = AUSM>
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);
45 else IF_CONSTEXPR(scheme ==
SLAU) {
46 Slau_(orientation, upwindCoefficient, A, leftVars, rightVars, srfcCoeff, flux);
51 const MFloat*
const leftVars,
const MFloat*
const rightVars,
const MFloat*
const NotUsed(srfcCoeff),
54 const MFloat*
const leftVars,
const MFloat*
const rightVars,
55 const MFloat*
const NotUsed(srfcCoeff),
MFloat*
const flux);
57 const MFloat*
const leftVars,
const MFloat*
const rightVars,
const MFloat*
const NotUsed(srfcCoeff),
64 const MFloat*
const bndrySurfVars);
66 template <MInt centralizeScheme>
68 [[maybe_unused]]
const MInt orientation,
69 [[maybe_unused]]
const MFloat levelFac);
72 template <MInt stencil>
80 TERMM(1,
"Viscous Flux Scheme not implemented.");
85 template <MInt stencil>
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,
92 viscousFluxThreePoint(orientation, A, isBndry, surfaceCoords, coord0, coord1, cellVars0, cellVars1, vars0, vars1,
93 slope0, slope1, f0, f1, flux);
96 viscousFluxStabilized(orientation, A, isBndry, surfaceCoords, coord0, coord1, cellVars0, cellVars1, vars0, vars1,
97 slope0, slope1, f0, f1, flux);
100 TERMM(1,
"Viscous Flux Scheme not implemented.");
110 const MFloat*
const surfaceCoords,
const MFloat*
const coord0,
111 const MFloat*
const coord1,
const MFloat*
const cellVars0,
117 const MFloat*
const surfaceCoords,
const MFloat*
const coord0,
118 const MFloat*
const coord1,
const MFloat*
const cellVars0,
124 template <MInt stencil>
132 TERMM(1,
"Viscous Flux Scheme not implemented.");
143 const MFloat*
const NotUsed(avarsCell));
146 const MFloat*
const NotUsed(avarsCell));
151 const MFloat*
const slopesCell);
175 return density * temperture /
m_gamma;
208 const MFloat energyDensity) {
209 return m_gammaMinusOne * (energyDensity - 0.5 / density * momentumDensitySquared);
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);
281 return C *
POW2(dx) / diffusion_coefficient;
317 IF_CONSTEXPR(nDim == 2) {
318 std::array<MInt, 2>
a = {0, 1};
322 std::array<MInt, 3>
a = {0, 1, 2};
333 struct ConservativeVariables;
334 struct FluxVariables;
336 struct PrimitiveVariables;
337 struct AdditionalVariables;
339 struct SurfaceCoefficients;
361 static const MInt Segfault = std::numeric_limits<MInt>::min();
363 static constexpr MInt RHO_U = 0;
364 static constexpr MInt RHO_V = 1;
365 static constexpr MInt RHO_W = nDim == 3 ? 2 : Segfault;
367 static constexpr MInt RHO_E = nDim;
368 static constexpr MInt RHO = nDim + 1;
370 static constexpr MInt RHO_C = nDim + 2;
392 static const MInt Segfault = std::numeric_limits<MInt>::min();
396 static constexpr MInt W = nDim == 3 ? 2 : Segfault;
398 static constexpr MInt RHO = nDim;
399 static constexpr MInt P = nDim + 1;
401 static constexpr MInt C = nDim + 2;
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"};
412 std::array<MString, nDim + 3>
a = {
"u",
"v",
"w",
"rho",
"p",
"c"};
420 void getPrimitiveVariableNames(
MString* names);
427 static constexpr MInt noVariables = 0;
432 const MInt m_noSurfaceCoefficients = 0;
437 const MFloat*
const leftVars,
const MFloat*
const rightVars,
438 const MFloat*
const NotUsed(srfcCoeff),
MFloat*
const flux) {
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;
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;
452 const MFloat MLR = 0.5 * (ML + MR);
453 const MFloat PLR = PL * (0.5 + upwindCoefficient * ML) + PR * (0.5 - upwindCoefficient * MR);
456 const MFloat RHO_AL = RHOL * AL;
457 const MFloat RHO_AR = RHOR * AR;
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);
464 const MFloat PLfRHOL = PL / RHOL;
465 const MFloat PRfRHOR = PR / RHOR;
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);
471 const MFloat e0 = PLfRHOL * m_F1BGammaMinusOne + 0.5 * U2L + PLfRHOL;
472 const MFloat e1 = PRfRHOR * m_F1BGammaMinusOne + 0.5 * U2R + PRfRHOR;
474 std::array<MFloat, nDim> pFactor{};
475 pFactor[orientation] = 1.0;
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])
483 flux[FV->RHO_E] = (RHO_U2 * (e0 + e1) + AbsRHO_U2 * (e0 - e1)) * A;
484 flux[FV->RHO] = 2.0 * RHO_U2 * A;
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;
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!");
504 std::array<MFloat, nDim> pFactor = {};
505 pFactor[orientation] = F1;
507 MFloat UL = leftVars[PV->U];
508 MFloat VL = leftVars[PV->V];
510 IF_CONSTEXPR(nDim == 3) { WL = leftVars[PV->W]; }
511 MFloat RL = leftVars[PV->RHO];
512 MFloat PL = leftVars[PV->P];
514 MFloat UR = rightVars[PV->U];
515 MFloat VR = rightVars[PV->V];
517 IF_CONSTEXPR(nDim == 3) { WR = rightVars[PV->W]; }
518 MFloat RR = rightVars[PV->RHO];
519 MFloat PR = rightVars[PV->P];
521 MFloat ql = leftVars[orientation];
522 MFloat AL = sqrt(m_gamma * PL / RL);
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;
528 MFloat qr = rightVars[orientation];
529 MFloat AR = sqrt(m_gamma * PR / RR);
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;
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);
541 MFloat P = F1B2 * (PL + PR) + upwindCoefficient * (ML * PL - MR * PR);
543 flux[FV->RHO] = F1B2 * (M * (RL * AL + RR * AR) + fabs(M) * (RL * AL - RR * AR)) * A;
545 (F1B2 * (M * (RL * AL * UL + RR * AR * UR) + fabs(M) * (RL * AL * UL - RR * AR * UR)) + P * pFactor[0]) * A;
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) {
550 (F1B2 * (M * (RL * AL * WL + RR * AR * WR) + fabs(M) * (RL * AL * WL - RR * AR * WR)) + P * pFactor[2]) * A;
552 flux[FV->RHO_E] = F1B2 * (M * (RL * AL * HL + RR * AR * HR) + fabs(M) * (RL * AL * HL - RR * AR * HR)) * 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!");
564 std::array<MFloat, nDim> pFactor = {};
565 pFactor[orientation] = F1;
567 const MFloat UL = leftVars[PV->U];
568 const MFloat VL = leftVars[PV->V];
570 IF_CONSTEXPR(nDim == 3) { WL = leftVars[PV->W]; }
571 const MFloat RL = leftVars[PV->RHO];
572 const MFloat PL = leftVars[PV->P];
574 const MFloat UR = rightVars[PV->U];
575 const MFloat VR = rightVars[PV->V];
577 IF_CONSTEXPR(nDim == 3) { WR = rightVars[PV->W]; }
578 const MFloat RR = rightVars[PV->RHO];
579 const MFloat PR = rightVars[PV->P];
581 const MFloat ql = leftVars[orientation];
582 const MFloat AL = sqrt(m_gamma * PL / RL);
584 IF_CONSTEXPR(nDim == 2) { KL = F1B2 * (UL * UL + VL * VL); }
585 IF_CONSTEXPR(nDim == 3) { KL = F1B2 * (UL * UL + VL * VL + WL * WL); }
587 const MFloat HL = (m_gamma * PL) / (m_gammaMinusOne * RL) + KL;
589 const MFloat qr = rightVars[orientation];
590 const MFloat AR = sqrt(m_gamma * PR / RR);
592 IF_CONSTEXPR(nDim == 2) { KR = F1B2 * (UR * UR + VR * VR); }
593 IF_CONSTEXPR(nDim == 3) { KR = F1B2 * (UR * UR + VR * VR + WR * WR); }
595 const MFloat HR = (m_gamma * PR) / (m_gammaMinusOne * RR) + KR;
597 const MFloat ALR = F1B2 * (AL + AR);
598 const MFloat ML = ql / ALR;
599 const MFloat MR = qr / ALR;
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);
604 const MFloat MH =
mMin(F1, sqrt(KL + KR) / ALR);
607 const MFloat P = F1B2 * (PL + PR + (BL - BR) * (PL - PR) + (BL + BR - F1) * sqrt(KL + KR) * (RL + RR) * ALR);
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);
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;
625 const MFloat PL = leftVars[PV->P];
626 const MFloat PR = rightVars[PV->P];
627 const MFloat PLR = 0.5 * (PR + PL);
629 std::array<MFloat, nDim> pFactor{};
630 pFactor[orientation] = 1.0;
632 for(
MUint n = 0; n < nDim; n++) {
633 flux[FV->RHO_VV[n]] = PLR * pFactor[n] * A;
636 flux[FV->RHO_E] = 0.0;
641 for(
MUint s = 0; s < PV->m_noSpecies; ++s) {
642 flux[FV->RHO_Y[s]] = 0.0;
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]];
655 for(
MInt v = 0; v < FV->noVariables; ++v) {
659 flux[CV->RHO_VV[orientation]] = bndrySurfVars[PV->P] * A;
660 flux[CV->RHO_E] = bndrySurfVars[PV->P] * bndrySurfVars[PV->VV[orientation]] * A;
664template <MInt centralizeScheme>
667 [[maybe_unused]]
const MInt orientation,
668 [[maybe_unused]]
const MFloat levelFac) {
669 static_assert(centralizeScheme > 0 && centralizeScheme < 6,
"Unintended/unimplemented function-call!");
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);
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);
693 else IF_CONSTEXPR(centralizeScheme == 3) {
694 for(
MInt v = 0; v < PV->noVariables; v++) {
695 const MFloat Vmean = F1B2 * (varL[v] + varR[v]);
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]))),
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);
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);
731 static const MFloat rhoUDth = m_muInfinity * m_F1BPr;
732 static const MFloat F1BRe0 = F1 / m_Re0;
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]]);
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]);
748 const MFloat T = m_gamma * p * Frho;
751 const MUint id0 = orientation;
752 const MUint id1 = index0[orientation];
753 const MUint id2 = index1[orientation];
756 const MFloat dAOverRe = A * F1BRe0;
759 const MFloat mue = (T * sqrt(T) * m_sutherlandPlusOne) / (T + m_sutherlandConstant);
763 const MFloat lambda = (T * sqrt(T) * m_sutherlandPlusOneThermal) / (T + m_sutherlandConstantThermal);
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]));
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;
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]));
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;
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]));
793 for(
MUint n = 0; n < nDim; n++) {
794 flux[FV->RHO_VV[n]] -= dAOverRe * tau[n];
796 flux[FV->RHO_E] -= dAOverRe * (std::inner_product(velocity.begin(), velocity.end(), tau.begin(), 0.0) + q);
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]);
812 static const MFloat F1BRe0 = F1 / m_Re0;
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]]);
825 const MUint id0 = orientation;
826 const MUint id1 = index0[orientation];
827 const MUint id2 = index1[orientation];
830 const MFloat dAOverRe = A * F1BRe0;
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;
838 std::array<MFloat, nDim> tau{};
839 IF_CONSTEXPR(nDim == 2) {
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]));
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;
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]));
856 for(
MUint n = 0; n < nDim; n++) {
857 flux[CV->RHO_VV[n]] -= dAOverRe * tau[n];
859 flux[CV->RHO_E] -= dAOverRe * (std::inner_product(velocity.begin(), velocity.end(), tau.begin(), 0.0));
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,
870 static const MFloat rhoUDth = m_muInfinity * m_F1BPr;
871 static const MFloat F1BRe0 = F1 / m_Re0;
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]]);
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]);
887 const MFloat T = m_gamma * p * Frho;
890 const MUint id0 = orientation;
891 const MUint id1 = index0[orientation];
892 const MUint id2 = index1[orientation];
895 const MFloat dAOverRe = A * F1BRe0;
898 const MFloat mue = (T * sqrt(T) * m_sutherlandPlusOne) / (T + m_sutherlandConstant);
900 const MFloat lambda = (T * sqrt(T) * m_sutherlandPlusOneThermal) / (T + m_sutherlandConstantThermal);
903 std::vector<MFloat> slopes(PV->noVariables * nDim);
908 for(
MInt var = 0; var < PV->noVariables; var++) {
909 slopes[nDim * var + id0] =
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];
927 slopes[nDim * var + id0] /= (coord1[id0] - coord0[id0]);
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];
936 slopes[nDim * var + id0] = f0 * slope0[var * nDim + id0] + f1 * slope1[var * nDim + id0];
940 const MUint sq0 = PV->P * nDim + id0;
941 const MUint sq1 = PV->RHO * nDim + id0;
943 const MFloat q = lambda * m_gFGMOrPr * Frho * (slopes[sq0] - p * Frho * slopes[sq1]);
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;
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]);
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]);
966 for(
MUint n = 0; n < nDim; n++) {
967 flux[FV->RHO_VV[n]] -= dAOverRe * tau[n];
969 flux[FV->RHO_E] -= dAOverRe * (std::inner_product(velocity.begin(), velocity.end(), tau.begin(), 0.0) + q);
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]);
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,
995 static const MFloat rhoUDth = m_muInfinity * m_F1BPr;
996 static const MFloat F1BRe0 = F1 / m_Re0;
997 const MFloat fac = m_enhanceThreePointViscFluxFactor;
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]]);
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]);
1013 const MFloat T = m_gamma * p * Frho;
1016 const MUint id0 = orientation;
1017 const MUint id1 = index0[orientation];
1018 const MUint id2 = index1[orientation];
1021 const MFloat dAOverRe = A * F1BRe0;
1024 const MFloat mue = (T * sqrt(T) * m_sutherlandPlusOne) / (T + m_sutherlandConstant);
1026 const MFloat lambda = (T * sqrt(T) * m_sutherlandPlusOneThermal) / (T + m_sutherlandConstantThermal);
1029 std::vector<MFloat> slopes(PV->noVariables * nDim);
1034 for(
MInt var = 0; var < PV->noVariables; var++) {
1035 slopes[nDim * var + id0] =
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];
1053 slopes[nDim * var + id0] /= (coord1[id0] - coord0[id0]);
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];
1062 slopes[nDim * var + id0] =
1063 fac * slopes[nDim * var + id0] + (1.0 - fac) * (f0 * slope0[var * nDim + id0] + f1 * slope1[var * nDim + id0]);
1066 slopes[nDim * var + id0] = f0 * slope0[var * nDim + id0] + f1 * slope1[var * nDim + id0];
1070 const MUint sq0 = PV->P * nDim + id0;
1071 const MUint sq1 = PV->RHO * nDim + id0;
1073 const MFloat q = lambda * m_gFGMOrPr * Frho * (slopes[sq0] - p * Frho * slopes[sq1]);
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;
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]);
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]);
1096 for(
MUint n = 0; n < nDim; n++) {
1097 flux[FV->RHO_VV[n]] -= dAOverRe * tau[n];
1099 flux[FV->RHO_E] -= dAOverRe * (std::inner_product(velocity.begin(), velocity.end(), tau.begin(), 0.0) + q);
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]);
1111 const MFloat*
const NotUsed(avarsCell)) {
1112 const MFloat fRho = F1 / cvarsCell[CV->RHO];
1114 for(
MInt n = 0; n < nDim; ++n) {
1115 pvarsCell[PV->VV[n]] = cvarsCell[CV->RHO_VV[n]] * fRho;
1116 velPOW2 +=
POW2(pvarsCell[PV->VV[n]]);
1120 pvarsCell[PV->RHO] = cvarsCell[CV->RHO];
1121 pvarsCell[PV->P] = m_gammaMinusOne * (cvarsCell[CV->RHO_E] - F1B2 * pvarsCell[PV->RHO] * velPOW2);
1124 for(
MUint s = 0; s < PV->m_noSpecies; ++s) {
1125 pvarsCell[PV->Y[s]] = cvarsCell[CV->RHO_Y[s]] * fRho;
1131 const MFloat*
const NotUsed(avarsCell)) {
1134 for(
MInt vel = 0; vel < nDim; ++vel) {
1135 cvarsCell[vel] = pvarsCell[vel] * pvarsCell[PV->RHO];
1136 velPOW2 +=
POW2(pvarsCell[vel]);
1140 cvarsCell[CV->RHO_E] = pvarsCell[PV->P] * m_F1BGammaMinusOne + F1B2 * pvarsCell[PV->RHO] * velPOW2;
1143 cvarsCell[CV->RHO] = pvarsCell[PV->RHO];
1146 for(
MUint s = 0; s < PV->m_noSpecies; ++s) {
1147 cvarsCell[CV->RHO_Y[s]] = pvarsCell[PV->Y[s]] * pvarsCell[PV->RHO];
1152inline std::vector<std::vector<MFloat>>
1154 const MFloat*
const NotUsed(avarsCell),
const MFloat*
const slopesCell) {
1156 for(
MInt i = 0; i < nDim; i++) {
1157 U2 +=
POW2(pvarsCell[PV->VV[i]]);
1160 std::vector<std::vector<MFloat>> dQ(CV->noVariables, std::vector<MFloat>(nDim));
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];
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];
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)
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)
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)
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)
constexpr MFloat speedOfSound(const MFloat density, const MFloat pressure)
Speed of sound: a = sqrt(gamma * pressure / density)
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]
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
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr Real POW2(const Real x)
constexpr T mMin(const T &x, const T &y)
constexpr T mMax(const T &x, const T &y)
std::basic_string< char > MString
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.