30 using tVec = Eigen::Vector3d;
34 static const int MaxBatch = 16;
38 static constexpr real kScaleHartenYee = IdealGas::kScaleHartenYee;
39 static constexpr real kScaleLD = IdealGas::kScaleLD;
40 static constexpr real kScaleHFix = IdealGas::kScaleHFix;
119 template <int dim = 3, class TVec, class TeV>
124 ReV(Eigen::seq(Eigen::fix<2>, Eigen::fix<dim>), Eigen::seq(Eigen::fix<2>, Eigen::fix<dim>))
128 ReV(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>), {0, 1, dim + 1}).colwise() =
velo;
130 ReV(1, dim + 1) += a;
133 ReV(dim + 1, 0) = H -
velo(0) * a;
134 ReV(dim + 1, dim + 1) = H +
velo(0) * a;
135 ReV(dim + 1, 1) = 0.5 * Vsqr;
137 ReV(dim + 1, Eigen::seq(Eigen::fix<2>, Eigen::fix<dim>)) =
138 velo(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim - 1>));
159 template <
int dim = 3,
class TVec,
class TeV>
163 real gammaBar = gamma - 1;
164 LeV(0, 0) = H + a / gammaBar * (
velo(0) - a);
165 LeV(0, 1) = -
velo(0) - a / gammaBar;
166 LeV(0, Eigen::seq(Eigen::fix<2>, Eigen::fix<dim>)) =
167 -
velo(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim - 1>));
170 LeV(1, 0) = -2 * H + 4 / gammaBar * (a * a);
171 LeV(1, Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) =
velo.transpose() * 2;
172 LeV(1, dim + 1) = -2;
174 LeV(Eigen::seq(Eigen::fix<2>, Eigen::fix<dim>), 0) =
175 velo(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim - 1>)) * (-2 * (a * a) / gammaBar);
176 LeV(Eigen::seq(Eigen::fix<2>, Eigen::fix<dim>), Eigen::seq(Eigen::fix<2>, Eigen::fix<dim>))
178 .setConstant(2 * (a * a) / gammaBar);
180 LeV(dim + 1, 0) = H - a / gammaBar * (
velo(0) + a);
181 LeV(dim + 1, 1) = -
velo(0) + a / gammaBar;
182 LeV(dim + 1, Eigen::seq(Eigen::fix<2>, Eigen::fix<dim>)) =
183 -
velo(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim - 1>));
184 LeV(dim + 1, dim + 1) = 1;
186 LeV *= gammaBar / (2 * a * a);
206 using TVec = Eigen::Vector<real, dim>;
229 template <
int dim = 3,
typename TULm,
typename TURm,
typename TFdumpInfo>
231 real gamma,
const TFdumpInfo &dumpInfo)
235 rp.
veloLm = (ULm(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / ULm(0)).matrix();
236 rp.
veloRm = (URm(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / URm(0)).matrix();
278 template <
int dim = 3,
class TCons,
class TPrim>
280 const TCons &U, TPrim &prim,
real gamma)
283 real vSqr = (U(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) / U(0)).squaredNorm();
286 real p = (gamma - 1) * (E - rho * 0.5 * vSqr);
305 template <
int dim = 3,
class TCons,
class TPrim>
307 const TPrim &prim, TCons &U,
real gamma)
310 real vSqr = prim(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).squaredNorm();
312 real p = prim(dim + 1);
313 real E = p / (gamma - 1) + (rho * 0.5 * vSqr);
332 template <
int dim = 3,
class TPrim>
334 const TPrim &prim,
real gamma,
real rg)
336 static const auto Seq123 = Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>);
337 static const auto I4 = dim + 1;
339 real vsqr = prim(Seq123).squaredNorm();
340 real asqr = gamma * prim(I4) / prim(0);
342 real p0 = std::pow(1 + (gamma - 1) * 0.5 * Msqr, gamma / (gamma - 1)) * prim(I4);
343 real T0 = (1 + (gamma - 1) * 0.5 * Msqr) * T;
344 return std::make_tuple(p0, T0);
364 template <
int dim = 3,
typename TU,
typename TF,
class TVec,
class TVecVG>
367 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) = U(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) * (
velo(0) -
vg(0));
369 F(dim + 1) +=
velo(0) * p;
390 template <
int dim = 3,
typename TU,
typename TF,
class TVec,
class TVecN,
class TVecVG>
393 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) = U(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) * (
velo -
vg).dot(
n);
394 F(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) += p *
n;
395 F(dim + 1) +=
velo.dot(
n) * p;
413 template <
int dim = 3,
typename TU,
typename TF,
class TVec,
class TVecVG,
class TP>
416 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>), EigenAll) = U(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>), EigenAll).array().rowwise() * (
velo(0, EigenAll) -
vg(0, EigenAll)).array();
417 F(1, EigenAll).array() += p.array();
418 F(dim + 1, EigenAll).array() +=
velo(0, EigenAll).array() * p.array();
436 template <
int dim = 3,
typename TU,
typename TF,
class TVec,
class TVecVG,
class TVecN,
class TP>
439 auto vn = (
velo.array() *
n.array()).colwise().sum();
440 auto vgn = (
vg.array() *
n.array()).colwise().sum();
441 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>), EigenAll) = U(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>), EigenAll).array().rowwise() * (vn - vgn).array();
442 F(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>), EigenAll).array() +=
n.array().rowwise() * p.array();
443 F(dim + 1, EigenAll).array() += vn * p.array();
462 template <
int dim = 3,
typename TU,
class TVec>
465 dVelo = (
dU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) -
466 U(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) / U(0) *
dU(0)) /
468 dp = (gamma - 1) * (
dU(dim + 1) -
469 0.5 * (
dU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).dot(
velo) +
470 U(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).dot(dVelo)));
495 template <
int dim = 3,
typename TU,
typename TF,
class TVec,
class TVecVG>
497 const TVec &unitNorm,
498 const TVecVG &
velo,
const TVec &dVelo,
const TVec &
vg,
503 real dvn = dVelo.dot(unitNorm);
504 F(0) =
dU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).dot(unitNorm);
505 F(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) =
506 dU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) * vn +
507 U(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) * dvn + unitNorm * dp;
508 F(dim + 1) = (
dU(dim + 1) + dp) * vn + (U(dim + 1) + p) * dvn;
509 static const auto SeqI52Last = Eigen::seq(Eigen::fix<dim + 2>, EigenLast);
510 if constexpr (TU::RowsAtCompileTime == Eigen::Dynamic || TU::RowsAtCompileTime > dim + 2)
511 F(SeqI52Last) =
dU(SeqI52Last) * vn + U(SeqI52Last) * dvn;
512 F -=
dU *
vg.dot(unitNorm);
527 template <
int dim = 3,
typename TU>
531 Eigen::Matrix<real, dim + 2, dim + 2> ReV;
532 Eigen::Vector<real, dim>
velo =
533 (U(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / U(0)).matrix();
538 EulerGasRightEigenVector<dim>(
velo, vsqr, H, std::sqrt(asqr), ReV);
554 template <
int dim = 3,
typename TU>
558 Eigen::Matrix<real, dim + 2, dim + 2> LeV;
559 Eigen::Vector<real, dim>
velo =
560 (U(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / U(0)).matrix();
565 EulerGasLeftEigenVector<dim>(
velo, vsqr, H, std::sqrt(asqr), gamma, LeV);
601 template <
int dim = 3,
int type = 0,
602 typename TUL,
typename TUR,
603 typename TULm,
typename TURm,
typename TVecVG,
typename TVecN,
604 typename TF,
typename TFdumpInfo>
606 const TVecVG &
vg,
const TVecN &
n,
608 const TFdumpInfo &dumpInfo,
real &lam0,
real &lam123,
real &lam4)
610 using TVec = Eigen::Vector<real, dim>;
612 if (!(UL(0) > 0 && UR(0) > 0))
617 TVec veloL = (UL(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / UL(0)).matrix();
618 TVec veloR = (UR(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / UR(0)).matrix();
620 real asqrL, asqrR, pL, pR, HL, HR;
621 real vsqrL = veloL.squaredNorm();
622 real vsqrR = veloR.squaredNorm();
626 auto rp = ComputeRoePreamble<dim>(ULm, URm, gamma, dumpInfo);
628 Eigen::Vector<real, dim + 2> FL, FR;
629 GasInviscidFlux_XY<dim>(UL, veloL,
vg,
n, pL, FL);
630 GasInviscidFlux_XY<dim>(UR, veloR,
vg,
n, pR, FR);
632 real veloRoeN = rp.veloRoe.dot(
n);
634 real veloRoe0 = veloRoeN - vgN;
635 lam0 = std::abs(veloRoe0 - rp.aRoe);
636 lam123 = std::abs(veloRoe0);
637 lam4 = std::abs(veloRoe0 + rp.aRoe);
638 real veloLm0 = (rp.veloLm -
vg).dot(
n);
639 real veloRm0 = (rp.veloRm -
vg).dot(
n);
641 Eigen::Vector<real, dim + 2> incU =
642 UR(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) -
643 UL(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>));
644 real incU123N = incU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).dot(
n);
646 TVec alpha23V = incU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) - incU(0) * rp.veloRoe;
647 TVec alpha23VT = alpha23V -
n * alpha23V.dot(
n);
648 real incU4b = incU(dim + 1) - alpha23VT.dot(rp.veloRoe);
649 real alpha1 = (gamma - 1) / rp.asqrRoe *
650 (incU(0) * (rp.HRoe - veloRoeN * veloRoeN) +
651 veloRoeN * incU123N - incU4b);
652 real alpha0 = (incU(0) * (veloRoeN + rp.aRoe) - incU123N - rp.aRoe * alpha1) / (2 * rp.aRoe);
653 real alpha4 = incU(0) - (alpha0 + alpha1);
658 real SL = std::min(veloRoe0 - rp.aRoe, veloLm0 - std::sqrt(asqrL));
659 real SR = std::max(veloRoe0 + rp.aRoe, veloRm0 + std::sqrt(asqrR));
660 real UU = std::abs(veloRoe0);
661 real dfix = rp.aRoe / (rp.aRoe + std::max(UU, dLambda * fixScale));
662 real SP = std::max(SR, 0.0);
663 real SM = std::min(SL, 0.0);
665 if constexpr (type != 1)
667 Eigen::Vector<real, dim + 2> ReV1;
670 ReV1(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) = rp.veloRoe;
671 ReV1(dim + 1) = rp.vsqrRoe * 0.5;
676 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) =
677 (SP * FL - SM * FR) / div +
679 (UR(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) -
680 UL(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) -
681 dfix * ReV1 * alpha1);
692 lam123 = ((SP + SM) * (veloRoe0)-2.0 * (1.0 - delta1) * (SP * SM)) / (SP - SM);
693 lam4 = ((SP + SM) * (veloRoe0 + rp.aRoe) - 2.0 * (1.0 - delta2) * (SP * SM)) / (SP - SM);
694 lam0 = ((SP + SM) * (veloRoe0 - rp.aRoe) - 2.0 * (1.0 - delta3) * (SP * SM)) / (SP - SM);
695 lam123 = std::abs(lam123);
696 lam0 = std::abs(lam0);
697 lam4 = std::abs(lam4);
704 Eigen::Vector<real, dim + 2> incF;
705 incF(0) = alpha0 + alpha1 + alpha4;
706 incF(dim + 1) = (rp.HRoe - veloRoeN * rp.aRoe) * alpha0 + 0.5 * rp.vsqrRoe * alpha1 +
707 (rp.HRoe + veloRoeN * rp.aRoe) * alpha4 + alpha23VT.dot(rp.veloRoe);
708 incF(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) =
709 (rp.veloRoe - rp.aRoe *
n) * alpha0 + (rp.veloRoe + rp.aRoe *
n) * alpha4 +
710 rp.veloRoe * alpha1 + alpha23VT;
712 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) = (FL + FR) * 0.5 - 0.5 * incF;
737 template <
int dim = 3,
typename TUL,
typename TUR,
typename TULm,
typename TURm,
738 typename TVecVG,
typename TVecN,
739 typename TF,
typename TFdumpInfo>
741 const TVecVG &
vg,
const TVecN &
n,
743 const TFdumpInfo &dumpInfo,
real &lam0,
real &lam123,
real &lam4)
746 using TVec = Eigen::Vector<real, dim>;
748 if (!(UL(0) > 0 && UR(0) > 0))
753 TVec veloL = (UL(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / UL(0)).matrix();
754 TVec veloR = (UR(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / UR(0)).matrix();
756 real asqrL, asqrR, pL, pR, HL, HR;
757 real vsqrL = veloL.squaredNorm();
758 real vsqrR = veloR.squaredNorm();
762 auto rp = ComputeRoePreamble<dim>(ULm, URm, gamma, dumpInfo);
764 Eigen::Vector<real, dim + 2> FL, FR;
765 GasInviscidFlux_XY<dim>(UL, veloL,
vg,
n, pL, FL);
766 GasInviscidFlux_XY<dim>(UR, veloR,
vg,
n, pR, FR);
768 real veloRoeN = rp.veloRoe.dot(
n);
770 real veloRoe0 = veloRoeN - vgN;
771 lam0 = std::abs(veloRoe0 - rp.aRoe);
772 lam123 = std::abs(veloRoe0);
773 lam4 = std::abs(veloRoe0 + rp.aRoe);
774 real veloLm0 = (rp.veloLm -
vg).dot(
n);
775 real veloRm0 = (rp.veloRm -
vg).dot(
n);
779 real q = std::sqrt(1 + (gamma + 1) / 2 / gamma * (pS / p - 1));
784 real pS = 0.5 * (rp.pLm + rp.pRm) - 0.5 * (veloLm0 - veloRm0) * rp.rhoRoe * rp.aRoe;
785 pS = std::max(0.0, pS);
786 real SL = veloLm0 - std::sqrt(rp.asqrLm) * HLLCq(rp.pLm, pS);
787 real SR = veloRm0 + std::sqrt(rp.asqrRm) * HLLCq(rp.pRm, pS);
798 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) = FL;
803 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) = FR;
807 real div = (UL(0) * (SL - veloLm0) - UR(0) * (SR - veloRm0));
810 (UL(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).dot(
n) - vgN * UL(0)) * (SL - veloLm0) -
811 (UR(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).dot(
n) - vgN * UR(0)) * (SR - veloRm0)) /
814 Eigen::Vector<real, dim + 2> DS;
816 DS(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) =
n;
823 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) = FL;
825 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) =
826 ((UL(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) * SL - FL) * SS +
827 DS * ((pL + UL(0) * (SL - veloLm0) * (SS - veloLm0)) * SL)) /
834 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) = FR;
836 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) =
837 ((UR(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) * SR - FR) * SS +
838 DS * ((pR + UR(0) * (SR - veloRm0) * (SS - veloRm0)) * SR)) /
878 template <
int eigScheme>
885 const real scaleHartenYee = kScaleHartenYee * fixScale;
886 const real scaleLD = kScaleLD * fixScale;
887 const real scaleHFix = kScaleHFix * fixScale;
888 static const real incFScaleA = 1.0;
889 if constexpr (eigScheme == 0)
894 const real thresH = std::max<real>({0., lam - lamL, lamR - lam}) * scaleHartenYee;
896 return (
sqr(
v) / thresH + thresH) * 0.5;
901 lam0 = Flim(lam0 * incFScaleA, uAve - aAve, uL - aL, uR - aR);
902 lam123 = Flim(lam123 * incFScale, uAve, uL, uR);
903 lam4 = Flim(lam4 * incFScaleA, uAve + aAve, uL + aL, uR + aR);
910 else if constexpr (eigScheme == 1)
913 const real aLm = aL * incFScaleA;
914 const real aRm = aR * incFScaleA;
915 const real veloLm0 = uL;
916 const real veloRm0 = uR;
917 const real uLm =
signTol(veloLm0, aLm *
smallReal) * std::max(std::abs(veloLm0) * incFScale, aLm * scaleLD);
918 const real uRm =
signTol(veloRm0, aRm *
smallReal) * std::max(std::abs(veloRm0) * incFScale, aRm * scaleLD);
919 lam0 = std::max(std::abs(uLm - aLm), std::abs(uRm - aRm));
920 lam123 = std::max(std::abs(uLm), std::abs(uRm));
921 lam4 = std::max(std::abs(uLm + aLm), std::abs(uRm + aRm));
923 else if constexpr (eigScheme == 3)
929 const real LDthreshold = std::abs(uAve) / scaleLD;
930 const real aRoeStar = std::min(LDthreshold, aAve * incFScaleA);
931 lam0 = std::abs(uAve * incFScale - aRoeStar);
932 lam4 = std::abs(uAve * incFScale + aRoeStar);
934 else if constexpr (eigScheme == 4)
940#ifdef USE_SIGN_MINUS_AT_ROE_M4_FLUX
941 const real uStar =
signM(uAve) * std::max(aAve * scaleLD, std::abs(uAve));
943 const real uStar =
signTol(uAve, aAve *
smallReal) * std::max(aAve * scaleLD, std::abs(uAve) * incFScale);
945 lam0 = std::abs(uStar - aAve * incFScaleA);
946 lam123 = std::abs(uStar);
947 lam4 = std::abs(uStar + aAve * incFScaleA);
949 else if constexpr (eigScheme == 5)
955 const real veloLm0 = uL * incFScale;
956 const real veloRm0 = uR * incFScale;
957 const real aLm = std::min(aL * incFScaleA, std::abs(veloLm0) / scaleLD);
958 const real aRm = std::min(aR * incFScaleA, std::abs(veloRm0) / scaleLD);
959 lam0 = std::max(std::abs(veloLm0 - aLm), std::abs(veloRm0 - aRm));
960 lam123 = std::max(std::abs(veloLm0), std::abs(veloRm0));
961 lam4 = std::max(std::abs(veloLm0 + aLm), std::abs(veloRm0 + aRm));
964 else if constexpr (eigScheme == 6)
966 lam0 = std::max(std::abs(uAve * incFScale - aAve * incFScaleA), dLambda * scaleHFix);
967 lam4 = std::max(std::abs(uAve * incFScale + aAve * incFScaleA), dLambda * scaleHFix);
968 lam123 = std::max(std::abs(uAve * incFScale), dLambda * scaleHFix);
970 else if constexpr (eigScheme == 7)
972 lam0 *= std::abs(uAve * incFScale - aAve * incFScaleA);
973 lam4 *= std::abs(uAve * incFScale + aAve * incFScaleA);
974 lam123 *= std::abs(uAve * incFScale);
976 const real thresholdHartenYee = scaleHartenYee * (VAve + aAve);
977 const real thresholdHartenYeeS =
sqr(thresholdHartenYee);
978 if (lam0 < thresholdHartenYee)
979 lam0 = (
sqr(lam0) + thresholdHartenYeeS) / (2 * thresholdHartenYee);
980 if (lam4 < thresholdHartenYee)
981 lam4 = (
sqr(lam4) + thresholdHartenYeeS) / (2 * thresholdHartenYee);
982 if (lam123 < thresholdHartenYee)
983 lam123 = (
sqr(lam123) + thresholdHartenYeeS) / (2 * thresholdHartenYee);
986 else if constexpr (eigScheme == 8)
988 lam0 = std::max(std::abs(uAve * incFScale - aAve * incFScaleA), dLambda * scaleHFix);
989 lam4 = std::max(std::abs(uAve * incFScale + aAve * incFScaleA), dLambda * scaleHFix);
990 lam123 = std::max(std::abs(uAve * incFScale), dLambda * scaleHFix);
993 const real thresholdHartenYee = scaleHartenYee * (VAve + aAve);
994 const real thresholdHartenYeeS =
sqr(thresholdHartenYee);
995 if (lam0 < thresholdHartenYee)
996 lam0 = (
sqr(lam0) + thresholdHartenYeeS) / (2 * thresholdHartenYee);
997 if (lam4 < thresholdHartenYee)
998 lam4 = (
sqr(lam4) + thresholdHartenYeeS) / (2 * thresholdHartenYee);
999 if (lam123 < thresholdHartenYee)
1000 lam123 = (
sqr(lam123) + thresholdHartenYeeS) / (2 * thresholdHartenYee);
1038 template <
int dim = 3,
int eigScheme = 0,
1039 typename TUL,
typename TUR,
1040 typename TULm,
typename TURm,
1041 typename TVecVG,
typename TVecN,
1042 typename TF,
typename TFdumpInfo>
1044 const TULm &ULm,
const TURm &URm,
1045 const TVecVG &
vg,
const TVecN &
n,
1048 const TFdumpInfo &dumpInfo,
real &lam0,
real &lam123,
real &lam4)
1050 using TVec = Eigen::Vector<real, dim>;
1052 if (!(UL(0) > 0 && UR(0) > 0))
1057 TVec veloL = (UL(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / UL(0)).matrix();
1058 TVec veloR = (UR(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / UR(0)).matrix();
1060 real asqrL, asqrR, pL, pR, HL, HR;
1061 real vsqrL = veloL.squaredNorm();
1062 real vsqrR = veloR.squaredNorm();
1066 auto rp = ComputeRoePreamble<dim>(ULm, URm, gamma, dumpInfo);
1068 Eigen::Vector<real, dim + 2> FL, FR;
1069 GasInviscidFlux_XY<dim>(UL, veloL,
vg,
n, pL, FL);
1070 GasInviscidFlux_XY<dim>(UR, veloR,
vg,
n, pR, FR);
1072 real veloRoeN = rp.veloRoe.dot(
n);
1074 real veloRoe0 = veloRoeN - vgN;
1075 lam0 = std::abs(veloRoe0 - rp.aRoe);
1076 lam123 = std::abs(veloRoe0);
1077 lam4 = std::abs(veloRoe0 + rp.aRoe);
1078 real veloLm0 = (rp.veloLm -
vg).dot(
n);
1079 real veloRm0 = (rp.veloRm -
vg).dot(
n);
1081 if constexpr (eigScheme == 2)
1085 lam0 = lam123 = lam4 = std::max(std::abs(veloLm0) + std::sqrt(rp.asqrLm), std::abs(veloRm0) + std::sqrt(rp.asqrRm));
1086 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) =
1088 0.5 * lam0 * (UR(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) - UL(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)));
1092 Roe_EntropyFixer<eigScheme>(std::sqrt(rp.asqrLm), std::sqrt(rp.asqrRm), rp.aRoe,
1093 veloLm0, veloRm0, veloRoe0,
1094 (rp.veloLm -
vg).norm(), (rp.veloRm -
vg).norm(), (rp.veloRoe -
vg).norm(),
1095 dLambda, fixScale, incFScale,
1096 lam0, lam123, lam4);
1098 Eigen::Vector<real, dim + 2> incU =
1099 UR(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) -
1100 UL(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>));
1101 real incU123N = incU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).dot(
n);
1103 TVec alpha23V = incU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) - incU(0) * rp.veloRoe;
1104 TVec alpha23VT = alpha23V -
n * alpha23V.dot(
n);
1105 real incU4b = incU(dim + 1) - alpha23VT.dot(rp.veloRoe);
1106 real alpha1 = (gamma - 1) / rp.asqrRoe *
1107 (incU(0) * (rp.HRoe - veloRoeN * veloRoeN) +
1108 veloRoeN * incU123N - incU4b);
1109 real alpha0 = (incU(0) * (veloRoeN + rp.aRoe) - incU123N - rp.aRoe * alpha1) / (2 * rp.aRoe);
1110 real alpha4 = incU(0) - (alpha0 + alpha1);
1114 alpha23VT *= lam123;
1117 Eigen::Vector<real, dim + 2> incF;
1118 incF(0) = alpha0 + alpha1 + alpha4;
1119 incF(dim + 1) = (rp.HRoe - veloRoeN * rp.aRoe) * alpha0 + 0.5 * rp.vsqrRoe * alpha1 +
1120 (rp.HRoe + veloRoeN * rp.aRoe) * alpha4 + alpha23VT.dot(rp.veloRoe);
1121 incF(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) =
1122 (rp.veloRoe - rp.aRoe *
n) * alpha0 + (rp.veloRoe + rp.aRoe *
n) * alpha4 +
1123 rp.veloRoe * alpha1 + alpha23VT;
1125 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>)) = (FL + FR) * 0.5 - 0.5 * incF;
1148 template <
int dim = 3,
typename TUL,
typename TUR,
typename TVecV,
typename TUOut>
1150 TVecV &veloRoe,
real &vsqrRoe,
real &aRoe,
real &asqrRoe,
real &HRoe, TUOut &UOut)
1152 using TVec = Eigen::Vector<real, dim>;
1153 static const auto Seq123 = Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>);
1154 static const auto I4 = dim + 1;
1155 TVec veloLm = (UL(Seq123).array() / UL(0)).matrix();
1156 TVec veloRm = (UR(Seq123).array() / UR(0)).matrix();
1157 real asqrLm, asqrRm, pLm, pRm, HLm, HRm;
1158 real vsqrLm = veloLm.squaredNorm();
1159 real vsqrRm = veloRm.squaredNorm();
1163 real sqrtRhoLm = std::sqrt(UL(0));
1164 real sqrtRhoRm = std::sqrt(UR(0));
1166 veloRoe = (sqrtRhoLm * veloLm + sqrtRhoRm * veloRm) / (sqrtRhoLm + sqrtRhoRm);
1167 vsqrRoe = veloRoe.squaredNorm();
1168 HRoe = (sqrtRhoLm * HLm + sqrtRhoRm * HRm) / (sqrtRhoLm + sqrtRhoRm);
1169 asqrRoe = (gamma - 1) * (HRoe - 0.5 * vsqrRoe);
1171 aRoe = std::sqrt(asqrRoe);
1173 UOut(0) = sqrtRhoLm * sqrtRhoRm;
1174 UOut(Seq123) = veloRoe * UOut(0);
1175 real pRoe = asqrRoe * UOut(0) / gamma;
1176 UOut(I4) = pRoe / (gamma - 1) + 0.5 * vsqrRoe * UOut(0);
1177 UOut(Eigen::seq(I4 + 1, EigenLast)) =
1178 UOut(0) / (sqrtRhoLm + sqrtRhoRm) *
1179 (UL(Eigen::seq(I4 + 1, EigenLast)) / sqrtRhoLm +
1180 UR(Eigen::seq(I4 + 1, EigenLast)) / sqrtRhoRm);
1209 template <
int dim = 3,
typename TDU,
typename TDF,
typename TVecV,
typename TVecN>
1215 static const auto SeqI52Last = Eigen::seq(Eigen::fix<dim + 2>, EigenLast);
1216 using TVec = Eigen::Vector<real, dim>;
1217 real veloRoeN = veloRoe.dot(
n);
1219 real incU123N = incU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).dot(
n);
1221 TVec alpha23V = incU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) - incU(0) * veloRoe;
1222 TVec alpha23VT = alpha23V -
n * alpha23V.dot(
n);
1223 real incU4b = incU(dim + 1) - alpha23VT.dot(veloRoe);
1224 real alpha1 = (gamma - 1) / asqrRoe *
1225 (incU(0) * (HRoe - veloRoeN * veloRoeN) +
1226 veloRoeN * incU123N - incU4b);
1227 real alpha0 = (incU(0) * (veloRoeN + aRoe) - incU123N - aRoe * alpha1) / (2 * aRoe);
1228 real alpha4 = incU(0) - (alpha0 + alpha1);
1232 alpha23VT *= lam123;
1235 incF(0) += alpha0 + alpha1 + alpha4;
1236 incF(dim + 1) += (HRoe - veloRoeN * aRoe) * alpha0 + 0.5 * vsqrRoe * alpha1 +
1237 (HRoe + veloRoeN * aRoe) * alpha4 + alpha23VT.dot(veloRoe);
1238 incF(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)) +=
1239 (veloRoe - aRoe *
n) * alpha0 + (veloRoe + aRoe *
n) * alpha4 +
1240 veloRoe * alpha1 + alpha23VT;
1242 incF(SeqI52Last) += incU(SeqI52Last) * lam123;
1272 template <
int dim = 3,
int eigScheme = 0,
1273 typename TUL,
typename TUR,
1274 typename TULm,
typename TURm,
1275 typename TVecVG,
typename TVecVGm,
1276 typename TVecN,
typename TVecNm,
1277 typename TF,
typename TFdumpInfo>
1279 const TULm &ULm,
const TURm &URm,
1280 const TVecVG &
vg,
const TVecVGm &vgm,
1281 const TVecN &
n,
const TVecNm &nm,
1285 const TFdumpInfo &dumpInfo,
real &lam0,
real &lam123,
real &lam4)
1287 using TVec = Eigen::Vector<real, dim>;
1288 using TVec_Batch = Eigen::Matrix<
real, dim, -1, Eigen::ColMajor, dim, MaxBatch>;
1289 using TReal_Batch = Eigen::Matrix<
real, 1, -1, Eigen::RowMajor, 1, MaxBatch>;
1290 using TU5_Batch = Eigen::Matrix<
real, dim + 2, -1, Eigen::ColMajor, dim + 2, MaxBatch>;
1293 for (
int iB = 0; iB < nB; iB++)
1294 if (!(UL(0, iB) > 0 && UR(0, iB) > 0))
1299 TVec_Batch veloL = (UL(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>), EigenAll).array().rowwise() / UL(0, EigenAll).array()).matrix();
1300 TVec_Batch veloR = (UR(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>), EigenAll).array().rowwise() / UR(0, EigenAll).array()).matrix();
1301 TVec veloLm = (ULm(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / ULm(0)).matrix();
1302 TVec veloRm = (URm(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>)).array() / URm(0)).matrix();
1305 pL.resize(nB), pR.resize(nB);
1306 for (
int iB = 0; iB < nB; iB++)
1308 real asqrL, asqrR, HL, HR;
1309 real vsqrL = veloL(EigenAll, iB).squaredNorm();
1310 real vsqrR = veloR(EigenAll, iB).squaredNorm();
1311 IdealGasThermal(UL(dim + 1, iB), UL(0, iB), vsqrL, gamma, pL(iB), asqrL, HL);
1312 IdealGasThermal(UR(dim + 1, iB), UR(0, iB), vsqrR, gamma, pR(iB), asqrR, HR);
1315 real asqrLm, asqrRm, pLm, pRm, HLm, HRm;
1316 real vsqrLm = veloLm.squaredNorm();
1317 real vsqrRm = veloRm.squaredNorm();
1318 IdealGasThermal(ULm(dim + 1), ULm(0), vsqrLm, gamma, pLm, asqrLm, HLm);
1319 IdealGasThermal(URm(dim + 1), URm(0), vsqrRm, gamma, pRm, asqrRm, HRm);
1321 real sqrtRhoLm = std::sqrt(ULm(0));
1322 real sqrtRhoRm = std::sqrt(URm(0));
1324 TVec veloRoe = (sqrtRhoLm * veloLm + sqrtRhoRm * veloRm) / (sqrtRhoLm + sqrtRhoRm);
1325 real vsqrRoe = veloRoe.squaredNorm();
1326 real HRoe = (sqrtRhoLm * HLm + sqrtRhoRm * HRm) / (sqrtRhoLm + sqrtRhoRm);
1327 real asqrRoe = (gamma - 1) * (HRoe - 0.5 * vsqrRoe);
1328 real rhoRoe = sqrtRhoLm * sqrtRhoRm;
1329 real veloRoeN = veloRoe.dot(nm);
1330 real vgmN = vgm.dot(nm);
1331 real veloRoeRN = veloRoeN - vgmN;
1332 real veloLm0 = (veloLm - vgm).dot(nm);
1333 real veloRm0 = (veloRm - vgm).dot(nm);
1336 FL.resize(Eigen::NoChange, UL.cols());
1337 FR.resize(Eigen::NoChange, UL.cols());
1338 GasInviscidFlux_XY_Batch<dim>(UL, veloL,
vg,
n, pL, FL);
1339 GasInviscidFlux_XY_Batch<dim>(UR, veloR,
vg,
n, pR, FR);
1346 real aRoe = std::sqrt(asqrRoe);
1348 lam0 = std::abs(veloRoeRN - aRoe);
1349 lam123 = std::abs(veloRoeRN);
1350 lam4 = std::abs(veloRoeRN + aRoe);
1352 if constexpr (eigScheme == 2)
1356 lam0 = lam123 = lam4 = std::max(std::abs(veloLm0) + std::sqrt(asqrLm), std::abs(veloRm0) + std::sqrt(asqrRm));
1357 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>), EigenAll) =
1359 0.5 * lam0 * (UR(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>), EigenAll) - UL(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>), EigenAll));
1363 Roe_EntropyFixer<eigScheme>(std::sqrt(asqrLm), std::sqrt(asqrRm), aRoe,
1364 veloLm0, veloRm0, veloRoeRN,
1365 (veloLm - vgm).norm(), (veloRm - vgm).norm(), (veloRoe - vgm).norm(),
1366 dLambda, fixScale, incFScale,
1367 lam0, lam123, lam4);
1370 UR(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>), EigenAll) -
1371 UL(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>), EigenAll);
1372 TReal_Batch incU123N =
1373 (incU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>), EigenAll).array() *
n.array()).colwise().sum();
1374 TVec_Batch alpha23V = incU(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>), EigenAll) - veloRoe * incU(0, EigenAll);
1375 TVec_Batch alpha23VT = alpha23V.array() -
n.array().rowwise() * (alpha23V.array() *
n.array()).colwise().sum();
1376 TReal_Batch incU4b =
1377 incU(dim + 1, EigenAll) -
1378 veloRoe.transpose() * alpha23VT;
1379 TReal_Batch alpha1 =
1380 (gamma - 1) / asqrRoe *
1381 (incU(0, EigenAll) * (HRoe - veloRoeN * veloRoeN) +
1382 veloRoeN * incU123N - incU4b);
1383 TReal_Batch alpha0 =
1384 (incU(0, EigenAll) * (veloRoeN + aRoe) - incU123N - aRoe * alpha1) / (2 * aRoe);
1385 TReal_Batch alpha4 =
1386 incU(0, EigenAll) - (alpha0 + alpha1);
1390 alpha23VT *= lam123;
1394 incF.resize(Eigen::NoChange, UL.cols());
1395 incF(0, EigenAll) = alpha0 + alpha1 + alpha4;
1396 incF(dim + 1, EigenAll) = (HRoe - veloRoeN * aRoe) * alpha0 + 0.5 * vsqrRoe * alpha1 +
1397 (HRoe + veloRoeN * aRoe) * alpha4 + veloRoe.transpose() * alpha23VT;
1398 incF(Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>), EigenAll) =
1399 ((-aRoe *
n).array().colwise() + veloRoe.array()).rowwise() * alpha0.array() +
1400 ((aRoe *
n).array().colwise() + veloRoe.array()).rowwise() * alpha4.array() +
1402 (veloRoe * alpha1).array();
1406 F(Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>), EigenAll) = (FL + FR) * 0.5 - 0.5 * incF;
1434 template <
int dim = 3,
1435 typename TUL,
typename TUR,
1436 typename TULm,
typename TURm,
1437 typename TVecVG,
typename TVecN,
1438 typename TF,
typename TFdumpInfo>
1441 TUL &&UL, TUR &&UR, TULm &&ULm, TURm &&URm,
1442 TVecVG &&
vg, TVecN &&
n,
real gamma, TF &&F,
1445 TFdumpInfo &&dumpInfo,
real &lam0,
real &lam123,
real &lam4)
1447#define DNDS_GAS_CALL_ROE(type) \
1448 RoeFlux_IdealGas_HartenYee<dim, type>( \
1449 UL, UR, ULm, URm, vg, n, gamma, F, dLambda, fixScale, incFScale, \
1450 dumpInfo, lam0, lam123, lam4)
1453 RoeFlux_IdealGas_HartenYee<dim>(
1454 UL, UR, ULm, URm,
vg,
n, gamma, F, dLambda, fixScale, incFScale,
1455 dumpInfo, lam0, lam123, lam4);
1474 else if (type ==
HLLEP)
1475 HLLEPFlux_IdealGas<dim, 0>(
1476 UL, UR, ULm, URm,
vg,
n, gamma, F, dLambda, fixScale,
1477 dumpInfo, lam0, lam123, lam4);
1479 HLLEPFlux_IdealGas<dim, 1>(
1480 UL, UR, ULm, URm,
vg,
n, gamma, F, dLambda, fixScale,
1481 dumpInfo, lam0, lam123, lam4);
1482 else if (type ==
HLLC)
1483 HLLCFlux_IdealGas_HartenYee<dim>(
1484 UL, UR, ULm, URm,
vg,
n, gamma, F, dLambda, fixScale,
1485 dumpInfo, lam0, lam123, lam4);
1488#undef DNDS_GAS_CALL_ROE
1514 template <
int dim = 3,
1515 typename TUL,
typename TUR,
1516 typename TULm,
typename TURm,
1517 typename TVecVG,
typename TVecVGm,
1518 typename TVecN,
typename TVecNm,
1519 typename TF,
typename TFdumpInfo>
1523 TULm &&ULm, TURm &&URm,
1524 TVecVG &&
vg, TVecVGm &&vgm,
1525 TVecN &&
n, TVecNm &&nm,
1528 TFdumpInfo &dumpInfo,
real &lam0,
real &lam123,
real &lam4)
1530#define DNDS_GAS_CALL_ROE(type) \
1531 RoeFlux_IdealGas_HartenYee_Batch<dim, type>( \
1532 UL, UR, ULm, URm, vg, vgm, n, nm, gamma, F, dLambda, fixScale, incFScale, \
1533 dumpInfo, lam0, lam123, lam4)
1536 RoeFlux_IdealGas_HartenYee_Batch<dim>(
1537 UL, UR, ULm, URm,
vg, vgm,
n, nm, gamma, F, dLambda, fixScale, incFScale,
1538 dumpInfo, lam0, lam123, lam4);
1559#undef DNDS_GAS_CALL_ROE
1594 template <
int dim = 3,
typename TU,
typename TGradU,
typename TFlux,
typename TNorm>
1598 static const auto Seq01234 = Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>);
1599 static const auto Seq012 = Eigen::seq(Eigen::fix<0>, Eigen::fix<dim - 1>);
1600 static const auto Seq123 = Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>);
1602 Eigen::Vector<real, dim>
velo = U(Seq123) / U(0);
1603 static const real lambda = -2. / 3.;
1604 Eigen::Matrix<real, dim, dim> diffVelo = GradUPrim(Seq012, Seq123);
1605 Eigen::Vector<real, dim> GradP = GradUPrim(Seq012, dim + 1);
1607 real p = (gamma - 1) * (U(dim + 1) - U(0) * 0.5 * vSqr);
1608 Eigen::Vector<real, dim> GradT = (gamma / ((gamma - 1) * Cp * U(0) * U(0))) *
1609 (U(0) * GradP - p * GradUPrim(Seq012, 0));
1612 GradT -= GradT.dot(norm) * norm;
1614 Eigen::Matrix<real, dim, dim> vStress = (diffVelo + diffVelo.transpose()) * mu +
1615 Eigen::Matrix<real, dim, dim>::Identity() * (lambda * mu * diffVelo.trace());
1618 real b = std::sqrt((diffVelo.array() * diffVelo.array()).sum());
1619 Eigen::Matrix<real, dim, dim> O = (diffVelo.transpose() - diffVelo) / (
b +
verySmallReal);
1621 Eigen::Matrix<real, dim, dim> vStressQCRFix;
1622 vStressQCRFix.setZero();
1623 vStressQCRFix.diagonal() = (vStress.array() * O.array()).rowwise().sum();
1624 vStressQCRFix(0, 1) = O(0, 1) * (vStress(1, 1) - vStress(0, 0));
1627 vStressQCRFix(0, 1) += O(1, 2) * vStress(0, 2) + O(0, 2) * vStress(1, 2);
1628 vStressQCRFix(0, 2) = O(0, 2) * (vStress(2, 2) - vStress(0, 0)) + O(0, 1) * vStress(2, 1) + O(2, 1) * vStress(0, 1);
1629 vStressQCRFix(1, 2) = O(1, 2) * (vStress(2, 2) - vStress(1, 1)) + O(1, 0) * vStress(2, 0) + O(2, 0) * vStress(1, 0);
1631 Eigen::Matrix<real, dim, dim> vStressQCRFixFull = vStressQCRFix + vStressQCRFix.transpose();
1632 vStress -= ccr1 * mutRatio * vStressQCRFixFull;
1635 Flux(Seq123) = vStress * norm;
1636 Flux(dim + 1) = (vStress *
velo + k * GradT).dot(norm);
1637 if (!Flux.allFinite())
1640 << U.transpose() <<
"\n";
1641 std::cout <<
"GradUPrim\n"
1642 << GradUPrim <<
"\n";
1643 std::cout <<
"norm\n"
1645 std::cout <<
"gamma\n"
1677 template <
int dim = 3,
typename TU,
typename TGradU,
typename TGradUPrim>
1680 static const auto Seq01234 = Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>);
1681 static const auto Seq012 = Eigen::seq(Eigen::fix<0>, Eigen::fix<dim - 1>);
1682 static const auto Seq123 = Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>);
1683 static const auto I4 = dim + 1;
1685 Eigen::Vector<real, dim>
velo = U(Seq123) / U(0);
1688 GradUPrim(Seq012, Seq123) = (1.0 /
sqr(U(0))) *
1689 (U(0) * GradU(Seq012, Seq123) -
1690 GradU(Seq012, 0) * Eigen::RowVector<real, dim>(U(Seq123)));
1691 GradUPrim(Seq012, I4) = (gamma - 1) *
1692 (GradU(Seq012, dim + 1) -
1694 (GradU(Seq012, Seq123) *
velo +
1695 GradUPrim(Seq012, Seq123) * Eigen::Vector<real, dim>(U(Seq123))));
1696 GradUPrim(Seq012, Eigen::seq(Eigen::fix<I4 + 1>, EigenLast)) -= GradU(Seq012, 0) * U(Eigen::seq(Eigen::fix<I4 + 1>, EigenLast)).transpose() / U(0);
1697 GradUPrim(Seq012, Eigen::seq(Eigen::fix<I4 + 1>, EigenLast)) /= U(0);
1712 template <
int dim,
typename TU,
typename TGradU>
1715 static const auto Seq01234 = Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>);
1716 static const auto Seq012 = Eigen::seq(Eigen::fix<0>, Eigen::fix<dim - 1>);
1717 static const auto Seq123 = Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>);
1718 Eigen::Matrix<real, dim, dim> diffVelo = (1.0 /
sqr(U(0))) *
1719 (U(0) * GradU(Seq012, Seq123) -
1720 GradU(Seq012, 0) * Eigen::RowVector<real, dim>(U(Seq123)));
1749 template <
int dim = 3,
int scheme = 0,
int nVarsFixed,
typename TU,
typename TUInc>
1752 static const real safetyRatio = 1 - 1e-5;
1753 static const auto Seq01234 = Eigen::seq(Eigen::fix<0>, Eigen::fix<dim + 1>);
1754 static const auto Seq012 = Eigen::seq(Eigen::fix<0>, Eigen::fix<dim - 1>);
1755 static const auto Seq123 = Eigen::seq(Eigen::fix<1>, Eigen::fix<dim>);
1756 static const auto I4 = dim + 1;
1758 Eigen::Vector<real, nVarsFixed> ret = uInc;
1759 Eigen::Vector<real, nVarsFixed> uNew = u + uInc;
1761 newrhoEinteralNew = std::max(
smallReal * rhoEOld, newrhoEinteralNew);
1762 real rhoENew = uNew(I4) - uNew(Seq123).squaredNorm() / (uNew(0) +
verySmallReal) * 0.5;
1763 real alphaEst1 = (rhoEOld - newrhoEinteralNew) / std::max(-rhoENew + rhoEOld,
verySmallReal);
1764 if (rhoENew > rhoEOld)
1766 alphaEst1 = std::min(alphaEst1, 1.);
1767 alphaEst1 = std::max(alphaEst1, 0.);
1770 real alphaL, alphaR, c0, c1, c2;
1771 alphaL = alphaR = c0 = c1 = c2 = 0;
1772 if constexpr (scheme == 0)
1774 c0 = 2 * u(I4) * u(0) - u(Seq123).squaredNorm() - 2 * u(0) * newrhoEinteralNew;
1775 c1 = 2 * u(I4) * ret(0) + 2 * u(0) * ret(I4) - 2 * u(Seq123).dot(ret(Seq123)) - 2 * ret(0) * newrhoEinteralNew;
1776 c2 = 2 * ret(I4) * ret(0) - ret(Seq123).squaredNorm();
1778 real deltaC =
sqr(c1) - 4 * c0 * c2;
1781 std::cout << std::scientific << std::setprecision(5);
1782 std::cout << u.transpose() << std::endl;
1783 std::cout << uInc.transpose() << std::endl;
1784 std::cout << newrhoEinteralNew << std::endl;
1785 std::cout << fmt::format(
"{} {} {}", c0, c1, c2) << std::endl;
1789 deltaC = std::max(0., deltaC);
1790 real alphaL = (-std::sqrt(deltaC) - c1) / (2 * c2);
1791 real alphaR = (std::sqrt(deltaC) - c1) / (2 * c2);
1799 if (std::abs(c2) < 1e-10 * c0)
1801 if (std::abs(c1) < 1e-10 * c0)
1807 alpha = std::min(-c0 / c1, 1.);
1812 alpha = std::min((c2 > 0 ? alphaL : alphaL), 1.);
1815 alpha *= safetyRatio;
1819 else if constexpr (scheme == 1)
1822 alpha *= safetyRatio;
1832 real decay = 1 - 1e-2;
1834 for (iter = 0; iter < 1000; iter++)
1836 real ek = 0.5 * (u(Seq123) + ret(Seq123)).squaredNorm() / (u(0) + ret(0) +
verySmallReal);
1837 if (ret(I4) + u(I4) - ek < newrhoEinteralNew)
1840 ret *= decay,
alpha *= decay;
1847 real ek = 0.5 * (u(Seq123) + ret(Seq123)).squaredNorm() / (u(0) + ret(0) +
verySmallReal);
1849 std::cout << std::scientific << std::setprecision(5);
1850 std::cout << fmt::format(
"alphas: {}, {}, {}\n",
alpha, alphaL, alphaR);
1851 std::cout << fmt::format(
"ABC: {}, {}, {}\n", c2, c1, c0);
1852 std::cout << u.transpose() << std::endl;
1853 std::cout << uInc.transpose() << std::endl;
1854 std::cout << fmt::format(
"eks: {} {}\n", ret(I4) + u(I4) - ek, newrhoEinteralNew);
Extended enum-to-JSON serialization macro that also exposes allowed string values for JSON Schema gen...
#define DNDS_DEFINE_ENUM_JSON(EnumType_,...)
Define JSON serialization for an enum AND expose its allowed string values.
Core type aliases, constants, and metaprogramming utilities for the DNDS framework.
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
#define DNDS_GAS_CALL_ROE(type)
Shared ideal-gas thermodynamics and Roe-flux primitives.
JSON-to-Eigen conversion utilities and nlohmann_json helper macros.
void HLLEPFlux_IdealGas(const TUL &UL, const TUR &UR, const TULm &ULm, const TURm &URm, const TVecVG &vg, const TVecN &n, real gamma, TF &F, real dLambda, real fixScale, const TFdumpInfo &dumpInfo, real &lam0, real &lam123, real &lam4)
HLLEP (HLL with Enhanced Pressure) approximate Riemann solver for an ideal gas on a moving grid.
void GradientCons2Prim_IdealGas(const TU &U, const TGradU &GradU, TGradUPrim &GradUPrim, real gamma)
Converts the gradient of conservative variables to the gradient of primitive variables for an ideal g...
void RoeFluxIncFDiff(const TDU &incU, const TVecN &n, const TVecV &veloRoe, real vsqrRoe, real aRoe, real asqrRoe, real HRoe, real lam0, real lam123, real lam4, real gamma, TDF &incF)
Computes the dissipation part of the Roe flux |A|·dU, given pre-computed Roe averages and entropy-fix...
RoePreamble< dim > ComputeRoePreamble(const TULm &ULm, const TURm &URm, real gamma, const TFdumpInfo &dumpInfo)
Compute Roe-averaged quantities from mean-state L/R vectors.
RiemannSolverType
Selects the approximate Riemann solver and its entropy-fix variant.
void GasInviscidFlux_XY_Batch(const TU &U, const TVec &velo, const TVecVG &vg, const TVecN &n, TP &&p, TF &F)
Batched face-normal inviscid flux for column-major state matrices.
Eigen::Vector2d tVec2
Convenience alias for 2-D real vector.
void RoeFlux_IdealGas_HartenYee_Batch(const TUL &UL, const TUR &UR, const TULm &ULm, const TURm &URm, const TVecVG &vg, const TVecVGm &vgm, const TVecN &n, const TVecNm &nm, real gamma, TF &F, real dLambda, real fixScale, real incFScale, const TFdumpInfo &dumpInfo, real &lam0, real &lam123, real &lam4)
Batched Roe flux with selectable entropy fix for column-major state matrices.
void GasInviscidFlux(const TU &U, const TVec &velo, const TVecVG &vg, real p, TF &F)
Computes the inviscid (Euler) flux in the x-direction for a moving grid.
void ViscousFlux_IdealGas(const TU &U, const TGradU &GradUPrim, TNorm norm, bool adiabatic, real gamma, real mu, real mutRatio, bool mutQCRFix, real k, real Cp, TFlux &Flux)
Computes the viscous (Navier-Stokes) flux projected onto a face normal for an ideal gas.
void HLLCFlux_IdealGas_HartenYee(const TUL &UL, const TUR &UR, const TULm &ULm, const TURm &URm, const TVecVG &vg, const TVecN &n, real gamma, TF &F, real dLambda, real fixScale, const TFdumpInfo &dumpInfo, real &lam0, real &lam123, real &lam4)
HLLC (Harten-Lax-van Leer-Contact) approximate Riemann solver for an ideal gas on a moving grid.
void IdealGasThermal(real E, real rho, real vSqr, real gamma, real &p, real &asqr, real &H)
Thin wrapper delegating to IdealGas::IdealGasThermal.
void GasInviscidFluxFacialIncrement(const TU &U, const TU &dU, const TVec &unitNorm, const TVecVG &velo, const TVec &dVelo, const TVec &vg, real dp, real p, TF &F)
Computes the increment of the facial inviscid flux from state, velocity, and pressure increments.
void RoeFlux_IdealGas_HartenYee(const TUL &UL, const TUR &UR, const TULm &ULm, const TURm &URm, const TVecVG &vg, const TVecN &n, real gamma, TF &F, real dLambda, real fixScale, real incFScale, const TFdumpInfo &dumpInfo, real &lam0, real &lam123, real &lam4)
Core Roe approximate Riemann solver with a selectable entropy-fix scheme for an ideal gas on a moving...
void InviscidFlux_IdealGas_Dispatcher(RiemannSolverType type, TUL &&UL, TUR &&UR, TULm &&ULm, TURm &&URm, TVecVG &&vg, TVecN &&n, real gamma, TF &&F, real dLambda, real fixScale, real incFScale, TFdumpInfo &&dumpInfo, real &lam0, real &lam123, real &lam4)
Runtime dispatcher from RiemannSolverType to the correct Roe / HLLC / HLLEP template instantiation.
void GasInviscidFlux_XY(const TU &U, const TVec &velo, const TVecVG &vg, const TVecN &n, real p, TF &F)
Computes the inviscid flux projected onto an arbitrary face normal n, accounting for grid motion vg.
void InviscidFlux_IdealGas_Batch_Dispatcher(RiemannSolverType type, TUL &&UL, TUR &&UR, TULm &&ULm, TURm &&URm, TVecVG &&vg, TVecVGm &&vgm, TVecN &&n, TVecNm &&nm, real gamma, TF &&F, real dLambda, real fixScale, real incFScale, TFdumpInfo &dumpInfo, real &lam0, real &lam123, real &lam4)
Runtime dispatcher for batched Roe flux from RiemannSolverType to the correct RoeFlux_IdealGas_Harten...
void EulerGasLeftEigenVector(const TVec &velo, real Vsqr, real H, real a, real gamma, TeV &LeV)
Fills the left eigenvector matrix (inverse of the right eigenvector matrix) for the 1-D Euler system ...
void IdealGasThermalPrimitive2Conservative(const TPrim &prim, TCons &U, real gamma)
Converts primitive variables to conservative variables for an ideal gas.
real IdealGasGetCompressionRatioPressure(const TU &u, const TUInc &uInc, real newrhoEinteralNew)
Computes the maximum safe compression ratio (scaling factor α ∈ [0,1]) for a conservative-variable in...
auto IdealGas_EulerGasRightEigenVector(const TU &U, real gamma)
Convenience wrapper that computes the right eigenvector matrix directly from a conservative state vec...
void GasInviscidFlux_Batch(const TU &U, const TVec &velo, const TVecVG &vg, TP &&p, TF &F)
Batched x-direction inviscid flux for column-major state matrices.
std::tuple< real, real > IdealGasThermalPrimitiveGetP0T0(const TPrim &prim, real gamma, real rg)
Computes total (stagnation) pressure p0 and temperature T0 from a primitive state using isentropic re...
Eigen::Vector3d tVec
Convenience alias for 3-D real vector.
void IdealGasThermalConservative2Primitive(const TCons &U, TPrim &prim, real gamma)
Converts conservative variables to primitive variables for an ideal gas.
class TeV inline void EulerGasRightEigenVector(const TVec &velo, real Vsqr, real H, real a, TeV &ReV)
void IdealGasUIncrement(const TU &U, const TU &dU, const TVec &velo, real gamma, TVec &dVelo, real &dp)
Computes velocity and pressure increments from a conservative-state increment, used for the Lax-flux ...
auto IdealGas_EulerGasLeftEigenVector(const TU &U, real gamma)
Convenience wrapper that computes the left eigenvector matrix directly from a conservative state vect...
auto GetGradVelo(const TU &U, const TGradU &GradU)
Extracts the velocity gradient tensor from the conservative-variable gradient using the quotient rule...
void Roe_EntropyFixer(const real aL, const real aR, const real aAve, const real uL, const real uR, const real uAve, const real VL, const real VR, const real VAve, real dLambda, real fixScale, real incFScale, real &lam0, real &lam123, real &lam4)
Template-dispatched entropy-fix for Roe-type Riemann solvers.
void GetRoeAverage(const TUL &UL, const TUR &UR, real gamma, TVecV &veloRoe, real &vsqrRoe, real &aRoe, real &asqrRoe, real &HRoe, TUOut &UOut)
Computes the Roe-averaged state vector including passive scalars (e.g. RANS turbulence variables).
DNDS_DEVICE_CALLABLE void IdealGasThermal(real E, real rho, real vSqr, real gamma, real &p, real &asqr, real &H)
Compute pressure, speed-of-sound squared, and specific enthalpy from total energy,...
constexpr real signM(real a)
"Signum, biased toward -1": treats 0 as negative.
DNDS_CONSTANT const real verySmallReal
Catch-all lower bound ("effectively zero").
constexpr real signTol(real a, real tol)
Tolerant signum: returns 0 inside [-tol, tol].
constexpr T sqr(const T &a)
a * a, constexpr. Works for all arithmetic types.
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
constexpr real signP(real a)
"Signum, biased toward +1": treats 0 as positive.
DNDS_CONSTANT const real smallReal
Loose lower bound (for iterative-solver tolerances etc.).
Pre-computed Roe-averaged quantities shared by all Riemann solvers.
TVec veloRoe
Roe-averaged velocity vector.
Eigen::Vector< real, dim > TVec
real sqrtRhoRm
√ρ for L/R states (used in Roe weighting).
TVec veloRm
Left/right mean-state velocity vectors.
real aRoe
Roe-averaged |v|², H, a², ρ, and speed of sound.
real HRm
Speed-of-sound², pressure, and enthalpy for L/R mean states.
real vsqrRm
Squared velocity magnitudes for L/R mean states.
Eigen::Matrix< real, 5, 1 > v
Eigen::Vector3d vg(0, 0, 0)
Eigen::Vector< real, 5 > dU
Eigen::Vector3d n(1.0, 0.0, 0.0)