16 static const auto model =
NS_SA;
25#define IF_NOT_NOREC (1)
28 template <EulerModel model>
56 ArrayDOFV<nVarsFixed> &rhs,
57 JacobianDiagBlock<nVarsFixed> &JSource,
58 ArrayDOFV<nVarsFixed> &u,
59 ArrayRECV<nVarsFixed> &uRecUnlim,
60 ArrayRECV<nVarsFixed> &uRec,
61 ArrayDOFV<1> &uRecBeta,
62 ArrayDOFV<1> &cellRHSAlpha,
73 if (settings.useSourceGradFixGG)
74 for (
auto &
v : gradUFix)
76 nFaceReducedOrder = 0;
78 const bool ignoreVis = flags & RHS_Ignore_Viscosity;
79 const bool dontUpdateIntegration = flags & RHS_Dont_Update_Integration;
80 const bool dontUpdateBndFlux = flags & RHS_Dont_Record_Bud_Flux;
81 const bool direct2ndRec = flags & RHS_Direct_2nd_Rec;
82 const bool direct2ndRec1stConv = flags & RHS_Direct_2nd_Rec_1st_Conv;
83 const bool direct2ndUseLimiter = flags & RHS_Direct_2nd_Rec_use_limiter;
84 const bool direct2ndRec_already_have_uGradBufNoLim = flags & RHS_Direct_2nd_Rec_already_have_uGradBufNoLim;
85 const bool recoverIncFScale = flags & RHS_Recover_IncFScale;
87 DNDS_assert(direct2ndRec1stConv ? direct2ndRec :
true);
88 auto rsType = settings.rsType;
91 std::unique_ptr<ScopedValueAlternator<real>> p_rsIncFScaleAlternator;
93 p_rsIncFScaleAlternator = std::make_unique<ScopedValueAlternator<real>>(settings.rsIncFScale, 1.0);
95#ifdef USE_MG_O1_LLF_FLUX
101 fluxWallSumLocal.setZero(cnvars);
102 if (!dontUpdateIntegration)
104 fluxWallSum.setZero(cnvars);
105 for (
Geom::t_index i = Geom::BC_ID_DEFAULT_MAX; i < pBCHandler->size(); i++)
107 if (pBCHandler->GetFlagFromIDSoft(i,
"integrationOpt") == 0)
109 if (!bndIntegrations.count(i))
111 auto intOpt = pBCHandler->GetFlagFromIDSoft(i,
"integrationOpt");
112 bndIntegrations.emplace(i, IntegrationRecorder(mesh->getMPI(), intOpt == 1 ? nVars : nVars + 2));
115 for (
auto &
v : bndIntegrations)
122 typename TVFV::template TFBoundary<nVarsFixed>
123 FBoundary = [&](
const TU &UL,
const TU &UMean,
index iCell,
index iFace,
int ig,
126 TVec normOutV = normOut(Seq012);
127 Eigen::Matrix<real, dim, dim> normBase = Geom::NormBuildLocalBaseV<dim>(normOutV);
128 bool compressed =
false;
129 TU ULfixed = this->CompressRecPart(
133 return this->generateBoundaryValue(ULfixed, UMean, iCell, iFace, ig, normOutV, normBase, pPhy, t, bType,
true, 1);
135 if (!direct2ndRec_already_have_uGradBufNoLim)
137 vfv->DoReconstruction2ndGrad(uGradBufNoLim, u, FBoundary, settings.direct2ndRecMethod);
138 uGradBufNoLim.trans.startPersistentPull();
141 if (!direct2ndRec1stConv)
142 this->LimiterUGrad(u, uGradBufNoLim, uGradBuf, direct2ndUseLimiter ? LIMITER_UGRAD_No_Flags : LIMITER_UGRAD_Disable_Shock_Limiter);
143 if (!direct2ndRec1stConv)
144 uGradBuf.trans.startPersistentPull();
145 if (!direct2ndRec_already_have_uGradBufNoLim)
146 uGradBufNoLim.trans.waitPersistentPull();
147 if (!direct2ndRec1stConv)
148 uGradBuf.trans.waitPersistentPull();
150 uGradBuf = uGradBufNoLim;
153#if defined(DNDS_DIST_MT_USE_OMP)
154 static std::vector<TU> faceFluxBuf;
155 if (faceFluxBuf.size() < mesh->NumFaceProc())
157 faceFluxBuf.resize(mesh->NumFaceProc(), TU::Zero(nVars));
161 auto faceOp = [&](
index iFace) {
165 double t0 = MPI_Wtime();
167#if defined(DNDS_DIST_MT_USE_OMP)
168# pragma omp declare reduction(TUAdd:TU : omp_out += omp_in) initializer(omp_priv = omp_orig)
169# pragma omp parallel for schedule(runtime) reduction(TUAdd : fluxWallSumLocal)
171 for (
index iFace = 0; iFace < mesh->NumFaceProc(); iFace++)
174 auto f2c = mesh->face2cell[iFace];
175 Elem::Quadrature gFace = direct2ndRec ? vfv->GetFaceQuadO1(iFace) : vfv->GetFaceQuad(iFace);
176 Eigen::Matrix<real, nVarsFixed, 1, Eigen::ColMajor> fluxEs(cnvars, 1);
184 Geom::Elem::SummationNoOp noOp;
185 auto faceBndID = mesh->GetFaceZone(iFace);
186 auto faceBCType = pBCHandler->GetTypeFromID(faceBndID);
187 TU_Batch ULxyV, URxyV;
188 ULxyV.resize(u.father->MatRowSize(), gFace.GetNumPoints());
189 URxyV.resizeLike(ULxyV);
190 TDiffU_Batch DiffUxyV, DiffUxyPrimV;
191 DiffUxyV.resize(dim * gFace.GetNumPoints(), u.father->MatRowSize());
192 DiffUxyPrimV.resizeLike(DiffUxyV);
193 TVec_Batch unitNormV, vgXYV;
194 unitNormV.resize(dim, gFace.GetNumPoints()), vgXYV.resizeLike(unitNormV);
196 TVec unitNormCent = vfv->GetFaceNorm(iFace, -1)(Seq012);
197 TMat normBaseCent = Geom::NormBuildLocalBaseV<dim>(unitNormCent);
198 TU ULMeanXy = u[f2c[0]];
199 this->UFromCell2Face(ULMeanXy, iFace, f2c[0], 0);
203 URMeanXy = u[f2c[1]];
204 this->UFromCell2Face(URMeanXy, iFace, f2c[1], 1);
208 URMeanXy = generateBoundaryValue(
209 ULMeanXy, ULMeanXy, f2c[0], iFace, -1,
212 vfv->GetFaceQuadraturePPhys(iFace, -1),
214 mesh->GetFaceZone(iFace),
false, 0);
216 TU_Batch FLFix, FRFix;
217#ifdef USE_FLUX_BALANCE_TERM
218 FLFix.setZero(cnvars, gFace.GetNumPoints()), FRFix.setZero(cnvars, gFace.GetNumPoints());
221 if (settings.useSourceGradFixGG)
222 faceGradFix.setZero(Eigen::NoChange, u.father->MatRowSize());
224 gFace.IntegrationSimple(
226 [&](
decltype(noOp) &finc,
int iG,
real w)
228 int iGQ = direct2ndRec ? -1 : iG;
230 int nDiff = vfv->GetFaceAtr(iFace).NDIFF;
231 TVec unitNorm = vfv->GetFaceNorm(iFace, iGQ)(Seq012);
232 TMat normBase = Geom::NormBuildLocalBaseV<dim>(unitNorm);
236 if (direct2ndRec && !direct2ndRec1stConv)
237 ULxy += uGradBuf[f2c[0]].transpose() * (vfv->GetFaceQuadraturePPhysFromCell(iFace, f2c[0], 0, -1) - vfv->GetCellQuadraturePPhys(f2c[0], -1))(SeqG012);
238 else if (!direct2ndRec1stConv)
239 ULxy += (vfv->GetIntPointDiffBaseValue(f2c[0], iFace, 0, iGQ, std::array<int, 1>{0}, 1) *
243 this->UFromCell2Face(ULxy, iFace, f2c[0], 0);
245 if (&uRecUnlim != &uRec && !direct2ndRec)
247 ULxyUnlim = u[f2c[0]];
248 ULxyUnlim += (vfv->GetIntPointDiffBaseValue(f2c[0], iFace, 0, iGQ, std::array<int, 1>{0}, 1) *
252 this->UFromCell2Face(ULxyUnlim, iFace, f2c[0], 0);
258#ifndef DNDS_FV_EULEREVALUATOR_IGNORE_VISCOUS_TERM
259 TDiffU GradULxy, GradURxy;
260 GradULxy.resize(Eigen::NoChange, cnvars);
261 GradURxy.resize(Eigen::NoChange, cnvars);
262 GradULxy.setZero(), GradURxy.setZero();
264 if (direct2ndRec && !direct2ndRec1stConv)
265 GradULxy(SeqG012, EigenAll) = uGradBuf[f2c[0]];
266 else if (!direct2ndRec1stConv)
268 if constexpr (gDim == 2)
269 GradULxy({0, 1}, EigenAll) =
270 vfv->GetIntPointDiffBaseValue(f2c[0], iFace, 0, iGQ, std::array<int, 2>{1, 2}, 3) *
273 GradULxy({0, 1, 2}, EigenAll) =
274 vfv->GetIntPointDiffBaseValue(f2c[0], iFace, 0, iGQ, std::array<int, 3>{1, 2, 3}, 4) *
277 this->DiffUFromCell2Face(GradULxy, iFace, f2c[0], 0);
282 real minVol = vfv->GetCellVol(f2c[0]);
290 if (direct2ndRec && !direct2ndRec1stConv)
291 URxy += uGradBuf[f2c[1]].transpose() * (vfv->GetFaceQuadraturePPhysFromCell(iFace, f2c[1], 1, -1) - vfv->GetCellQuadraturePPhys(f2c[1], -1))(SeqG012);
292 else if (!direct2ndRec1stConv)
293 URxy += (vfv->GetIntPointDiffBaseValue(f2c[1], iFace, 1, iGQ, std::array<int, 1>{0}, 1) *
297 this->UFromCell2Face(URxy, iFace, f2c[1], 1);
298 if (&uRecUnlim != &uRec && !direct2ndRec)
300 URxyUnlim = u[f2c[1]];
301 URxyUnlim += (vfv->GetIntPointDiffBaseValue(f2c[1], iFace, 1, iGQ, std::array<int, 1>{0}, 1) *
305 this->UFromCell2Face(URxyUnlim, iFace, f2c[1], 1);
310#ifndef DNDS_FV_EULEREVALUATOR_IGNORE_VISCOUS_TERM
312 if (direct2ndRec && !direct2ndRec1stConv)
313 GradURxy(SeqG012, EigenAll) = uGradBuf[f2c[1]];
314 else if (!direct2ndRec1stConv)
316 if constexpr (gDim == 2)
317 GradURxy({0, 1}, EigenAll) =
318 vfv->GetIntPointDiffBaseValue(f2c[1], iFace, 1, iGQ, std::array<int, 2>{1, 2}, 3) *
321 GradURxy({0, 1, 2}, EigenAll) =
322 vfv->GetIntPointDiffBaseValue(f2c[1], iFace, 1, iGQ, std::array<int, 3>{1, 2, 3}, 4) *
325 this->DiffUFromCell2Face(GradURxy, iFace, f2c[1], 1);
329 minVol = std::min(minVol, vfv->GetCellVol(f2c[1]));
330 distBary = (vfv->GetOtherCellBaryFromCell(f2c[0], f2c[1], iFace) - vfv->GetCellBary(f2c[0])).norm();
333 (vfv->GetOtherCellBaryFromCell(f2c[0], f2c[1], iFace) -
334 vfv->GetCellBary(f2c[0]))
339 URxy = generateBoundaryValue(
340 ULxy, ULMeanXy, f2c[0], iFace, iGQ,
343 vfv->GetFaceQuadraturePPhys(iFace, iGQ),
345 mesh->GetFaceZone(iFace),
true, 0);
346 if (&uRecUnlim != &uRec &&
false)
347 URxyUnlim = generateBoundaryValue(
348 ULxyUnlim, ULMeanXy, f2c[0], iFace, iGQ,
351 vfv->GetFaceQuadraturePPhys(iFace, iGQ),
353 mesh->GetFaceZone(iFace),
true, 0);
356#ifndef DNDS_FV_EULEREVALUATOR_IGNORE_VISCOUS_TERM
359 distBary = (vfv->GetFaceQuadraturePPhysFromCell(iFace, f2c[0], 0, -1) - vfv->GetCellBary(f2c[0])).norm() * 2.;
362 (vfv->GetFaceQuadraturePPhysFromCell(iFace, f2c[0], 0, -1) -
363 vfv->GetCellBary(f2c[0]))
369 real distGRP = minVol / vfv->GetFaceArea(iFace) * 2;
370 distGRP = std::max(std::min(distBaryPerp, distGRP * 2), distGRP * 0.25);
371 if (direct2ndRec1stConv)
373 if (settings.noGRPOnWall && !direct2ndRec1stConv)
381 TU UMeanXy = 0.5 * (ULxy + URxy);
383#ifndef DNDS_FV_EULEREVALUATOR_IGNORE_VISCOUS_TERM
384 TDiffU GradUMeanXy = (GradURxy + GradULxy) * 0.5 +
386 (unitNorm * (URxyUnlim - ULxyUnlim).transpose());
387 if (!GradUMeanXy.allFinite())
389 std::cout <<
"GradUMeanXy\n"
390 << GradUMeanXy <<
"\n";
391 std::cout <<
"GradULxy\n"
393 std::cout <<
"GradURxy\n"
395 std::cout << std::endl;
403 TDiffU GradUMeanXyPrim;
404 real gamma = settings.idealGasProperty.gamma;
405 if (settings.usePrimGradInVisFlux)
407 TDiffU GradULxyPrim, GradURxyPrim;
408 GradULxyPrim.resizeLike(GradURxy), GradURxyPrim.resizeLike(GradURxy);
409 Gas::GradientCons2Prim_IdealGas<dim>(ULxy, GradULxy, GradULxyPrim, gamma);
410 Gas::GradientCons2Prim_IdealGas<dim>(URxy, GradURxy, GradURxyPrim, gamma);
411 TU URxyPrim(cnvars), ULxyPrim(cnvars);
412 Gas::IdealGasThermalConservative2Primitive<dim>(ULxy, ULxyPrim, gamma);
413 Gas::IdealGasThermalConservative2Primitive<dim>(URxy, URxyPrim, gamma);
415 GradUMeanXyPrim = (GradURxyPrim + GradULxyPrim) * 0.5 +
417 (unitNorm * (URxyPrim - ULxyPrim).transpose());
425 if (settings.useSourceGradFixGG)
427 faceGradFix += 0.5 * unitNorm * (URxy - ULxy).transpose() * ((direct2ndRec ? vfv->GetFaceArea(iFace) / vfv->GetFaceParamArea(iFace) : vfv->GetFaceJacobiDet(iFace, iG)) * w);
435 GradUMeanXy *= 0, GradUMeanXyPrim *= 0;
437 if (!GradUMeanXy.allFinite())
439 std::cout << GradURxy << std::endl;
440 std::cout << GradULxy << std::endl;
441 std::cout << distGRP << std::endl;
442 std::cout << f2c[0] <<
" " << f2c[1] <<
" " << mesh->NumCell() <<
" " << mesh->NumCellProc() << std::endl;
443 std::cout << uRec[f2c[0]] << std::endl;
444 std::cout <<
"-----------------------------------\n";
446 std::cout << uRec[f2c[1]] << std::endl;
447 std::cout <<
"-----------------------------------\n";
448 std::cout << u[f2c[0]].transpose() << std::endl;
450 std::cout << u[f2c[1]].transpose() << std::endl;
460 Gas::IdealGasThermalConservative2Primitive<dim>(ULc, ULcPrim, settings.idealGasProperty.gamma);
461 ULcPrim(Seq123).setZero();
462 Gas::IdealGasThermalPrimitive2Conservative<dim>(ULcPrim, ULc, settings.idealGasProperty.gamma);
465 real temp = pBCHandler->GetValueFromID(mesh->GetFaceZone(iFace))(0);
467 ULcPrim.resizeLike(ULc);
468 Gas::IdealGasThermalConservative2Primitive<dim>(ULc, ULcPrim, settings.idealGasProperty.gamma);
470 DNDS_assert_info(ULcPrim(0) > 0 && ULcPrim(I4) > 0 && temp > 0, fmt::format(
"{}, {}, {}", ULcPrim(0), ULcPrim(I4), temp));
473 real newDensity = ULcPrim(I4) / temp / settings.idealGasProperty.Rgas;
474 ULcPrim(0) = newDensity;
475 Gas::IdealGasThermalPrimitive2Conservative<dim>(ULcPrim, URxy, settings.idealGasProperty.gamma);
481 auto seqC = Eigen::seq(iG * dim, iG * dim + dim - 1);
482 ULxyV(EigenAll, iG) = ULxy;
483 URxyV(EigenAll, iG) = URxy;
486 DiffUxyV(seqC, EigenAll) = GradUMeanXy;
487 DiffUxyPrimV(seqC, EigenAll) = GradUMeanXyPrim;
489 unitNormV(EigenAll, iG) = unitNorm;
490 vgXYV(EigenAll, iG) = GetFaceVGrid(iFace, iGQ);
492 TReal_Batch lam0V, lam123V, lam4V;
498 DiffUxyV, DiffUxyPrimV,
502 GetFaceVGrid(iFace, -1),
506 lam0V, lam123V, lam4V,
507 mesh->GetFaceZone(iFace),
510 if (mesh->getMPI().rank == 0)
518 gFace.IntegrationSimple(
520 [&](
decltype(fluxEs) &finc,
int iG)
522 finc.resizeLike(fluxEs);
523 finc(EigenAll, 0) = fincC(EigenAll, iG);
524 finc *= (direct2ndRec ? vfv->GetFaceArea(iFace) / vfv->GetFaceParamArea(iFace) : vfv->GetFaceJacobiDet(iFace, iG));
527 if (settings.useRoeJacobian)
529 Eigen::Vector<real, 3> lamEs;
531 gFace.IntegrationSimple(
533 [&](
decltype(lamEs) &finc,
int iG)
536 finc(1) = lam123V(iG);
538 finc *= (direct2ndRec ? vfv->GetFaceArea(iFace) / vfv->GetFaceParamArea(iFace) : vfv->GetFaceJacobiDet(iFace, iG));
540 lamEs /= vfv->GetFaceArea(iFace);
541 lambdaFace0[iFace] = lamEs(0);
542 lambdaFace123[iFace] = lamEs(1);
543 lambdaFace4[iFace] = lamEs(2);
546#if defined(DNDS_DIST_MT_USE_OMP)
547 faceFluxBuf.at(iFace) = fluxEs(EigenAll, 0);
550 TU fluxIncL = fluxEs(EigenAll, 0);
551 TU fluxIncR = -fluxEs(EigenAll, 0);
553 this->UFromFace2Cell(fluxIncL, iFace, f2c[0], 0);
555 this->UFromFace2Cell(fluxIncR, iFace, f2c[1], 1);
560 rhs[f2c[0]] += fluxIncL / vfv->GetCellVol(f2c[0]);
562 rhs[f2c[1]] += fluxIncR / vfv->GetCellVol(f2c[1]);
565 if (settings.useSourceGradFixGG)
566#if defined(DNDS_DIST_MT_USE_OMP)
571 TDiffU faceGradFixL{faceGradFix}, faceGradFixR{faceGradFix};
572 if (f2c[0] < mesh->NumCell())
573 this->DiffUFromCell2Face(faceGradFixL, iFace, f2c[0], 0,
true), gradUFix[f2c[0]] += faceGradFixL;
574 if (f2c[1] < mesh->NumCell() && f2c[1] !=
UnInitIndex)
575 this->DiffUFromCell2Face(faceGradFixR, iFace, f2c[1], 1,
true), gradUFix[f2c[1]] += faceGradFixR;
579 if (!dontUpdateBndFlux)
582 DNDS_assert(mesh->face2bndM.find(iFace) != mesh->face2bndM.end());
583 fluxBnd.at(mesh->face2bndM[iFace]) = fluxEs(EigenAll, 0) / vfv->GetFaceArea(iFace);
584 TVec fluxBndForceTInt;
585 fluxBndForceTInt.setZero();
586 gFace.IntegrationSimple(
588 [&](
decltype(fluxBndForceTInt) &finc,
int iG)
590 TU fcur = fincC(EigenAll, iG);
591 TVec ncur = unitNormV(EigenAll, iG);
593 finc -= ncur * (ncur.dot(finc));
594 finc *= (direct2ndRec ? vfv->GetFaceArea(iFace) / vfv->GetFaceParamArea(iFace) : vfv->GetFaceJacobiDet(iFace, iG));
596 fluxBndForceT.at(mesh->face2bndM[iFace]) = fluxBndForceTInt / vfv->GetFaceArea(iFace);
600 if (!dontUpdateIntegration)
605 fluxWallSumLocal -= fluxEs(EigenAll, 0);
606 if (iFace >= mesh->NumFace())
611 if (!dontUpdateIntegration)
612#if defined(DNDS_DIST_MT_USE_OMP)
616 if (pBCHandler->GetFlagFromIDSoft(mesh->GetFaceZone(iFace),
"integrationOpt") == 1)
618 bndIntegrations.at(mesh->GetFaceZone(iFace)).Add(-fluxEs(EigenAll, 0), vfv->GetFaceArea(iFace));
620 if (pBCHandler->GetFlagFromIDSoft(mesh->GetFaceZone(iFace),
"integrationOpt") == 2)
623 if (settings.frameConstRotation.enabled)
624 this->TransformURotatingFrame(uL, vfv->GetFaceQuadraturePPhys(iFace, -1), 1);
626 auto gamma = settings.idealGasProperty.gamma;
627 Gas::IdealGasThermalConservative2Primitive<dim>(uL, uLPrim, gamma);
628 Eigen::Vector<real, Eigen::Dynamic> vInt;
629 vInt.resize(nVars + 2);
630 vInt(Eigen::seq(0, nVars - 1)) = uL;
632 auto [p0, T0] = Gas::IdealGasThermalPrimitiveGetP0T0<dim>(uLPrim, gamma, settings.idealGasProperty.Rgas);
633 vInt(nVars) = p0, vInt(nVars + 1) = T0;
635 bndIntegrations.at(mesh->GetFaceZone(iFace)).Add(vInt * fluxEs(0, 0), fluxEs(0, 0));
640#if defined(DNDS_DIST_MT_USE_OMP)
641# pragma omp parallel for schedule(static)
642 for (
int iPart = 0; iPart < mesh->NLocalParts(); iPart++)
643 for (index iCell = mesh->LocalPartStart(iPart); iCell < mesh->LocalPartEnd(iPart); iCell++)
645 auto c2f = mesh->cell2face[iCell];
646 for (
int ic2f = 0; ic2f < c2f.size(); ic2f++)
648 index iFace = c2f[ic2f];
649 int if2c = mesh->CellIsFaceBack(iCell, iFace) ? 0 : 1;
650 TU fluxFaceC = faceFluxBuf[iFace] * (if2c ? -1 : 1);
651 this->UFromFace2Cell(fluxFaceC, iFace, iCell, if2c);
653 rhs[iCell] += fluxFaceC / vfv->GetCellVol(iCell);
654 if (mesh->face2cell(iFace, 1 - if2c) == iCell)
656 TU fluxFaceC = faceFluxBuf[iFace] * (if2c ? -1 : 1) * (-1);
657 this->UFromFace2Cell(fluxFaceC, iFace, iCell, 1 - if2c);
658 rhs[iCell] += fluxFaceC / vfv->GetCellVol(iCell);
663 double t1 = MPI_Wtime();
667 auto cellOp = [&](
index iCell) {
671 if (!settings.ignoreSourceTerm)
673 JSource.clearValues();
674#if defined(DNDS_DIST_MT_USE_OMP)
675# pragma omp parallel for schedule(guided)
677 for (index iCell = 0; iCell < mesh->NumCell(); iCell++)
680 auto gCell = direct2ndRec ? vfv->GetCellQuadO1(iCell) : vfv->GetCellQuad(iCell);
683 if (settings.ransSource2nd || settings.source2nd)
685 cellGrad2nd.setZero(Eigen::NoChange, u[iCell].size());
687 for (index iFace : mesh->cell2face[iCell])
689 index iCellOther = mesh->CellFaceOther(iCell, iFace);
690 TVec uNorm = vfv->GetFaceNormFromCell(iFace, iCell, -1, -1)(Seq012) *
691 (mesh->CellIsFaceBack(iCell, iFace) ? 1 : -1);
693 if (iCellOther != UnInitIndex)
694 uR = u[iCellOther], this->UFromOtherCell(uR, iFace, iCell, iCellOther, -1);
696 uR = generateBoundaryValue(
697 uC, uC, iCell, iFace, -1,
698 uNorm, Geom::NormBuildLocalBaseV<dim>(uNorm),
699 vfv->GetFaceQuadraturePPhys(iFace, -1),
700 t, mesh->GetFaceZone(iFace),
true, 0);
701 cellGrad2nd += vfv->GetFaceArea(iFace) * uNorm * (uR - uC).transpose() * 0.5;
703 cellGrad2nd /= vfv->GetCellVol(iCell);
706 Eigen::Matrix<real, nVarsFixed, Eigen::Dynamic> sourceV;
707 sourceV.setZero(cnvars, JSource.isBlock() ? cnvars + 1 : 2);
709 Geom::Elem::SummationNoOp noOp;
712 if (settings.useSourceGradFixGG)
713 cellGradFix = gradUFix[iCell] / vfv->GetCellVol(iCell);
715 gCell.IntegrationSimple(
717 [&](
decltype(sourceV) &finc,
int iG)
719 int iGQ = direct2ndRec ? -1 : iG;
721 GradU.resize(Eigen::NoChange, cnvars);
723 PerformanceTimer::Instance().StartTimer(PerformanceTimer::LimiterB);
725 GradU(SeqG012, EigenAll) = uGradBufNoLim[iCell];
726 else if (settings.source2nd)
730 if constexpr (gDim == 2)
731 GradU({0, 1}, EigenAll) =
732 vfv->GetIntPointDiffBaseValue(iCell, -1, -1, iGQ, std::array<int, 2>{1, 2}, 3) *
735 GradU({0, 1, 2}, EigenAll) =
736 vfv->GetIntPointDiffBaseValue(iCell, -1, -1, iGQ, std::array<int, 3>{1, 2, 3}, 4) *
738 if (settings.useSourceGradFixGG)
739 GradU += cellGradFix;
740 if (settings.ransSource2nd)
742 if constexpr (Traits::hasSA)
743 GradU(EigenAll, I4 + 1) = cellGrad2nd(EigenAll, I4 + 1);
744 if constexpr (Traits::has2EQ)
745 GradU(EigenAll, {I4 + 1, I4 + 2}) = cellGrad2nd(EigenAll, {I4 + 1, I4 + 2});
752 (vfv->GetIntPointDiffBaseValue(iCell, -1, -1, iGQ, std::array<int, 1>{0}, 1) *
757 PerformanceTimer::Instance().StopTimer(PerformanceTimer::LimiterB);
762 finc.resizeLike(sourceV);
768 vfv->GetCellQuadraturePPhys(iCell, iGQ), jac,
774 vfv->GetCellQuadraturePPhys(iCell, iGQ), jac,
775 iCell, iGQ, JSource.isBlock() ? 2 : 1);
776 if (JSource.isBlock())
777 finc(EigenAll, Eigen::seq(Eigen::fix<1>, EigenLast)) = jac;
779 finc(EigenAll, 1) = sourceJDiag;
781 finc *= direct2ndRec ? vfv->GetCellVol(iCell) / vfv->GetCellParamVol(iCell) : vfv->GetCellJacobiDet(iCell, iG);
782 if (finc.hasNaN() || (!finc.allFinite()))
784 std::cout << finc.transpose() << std::endl;
785 std::cout << ULxy.transpose() << std::endl;
786 std::cout << GradU << std::endl;
790 sourceV *= cellRHSAlpha[iCell](0) / vfv->GetCellVol(iCell);
791 rhs[iCell] += sourceV(EigenAll, 0);
792 if (JSource.isBlock())
793 JSource.getBlock(iCell) = sourceV(EigenAll, Eigen::seq(Eigen::fix<1>, EigenLast));
795 JSource.getDiag(iCell) = sourceV(EigenAll, 1);
805 if (!dontUpdateIntegration)
806 MPI::Allreduce(fluxWallSumLocal.data(), fluxWallSum.data(), fluxWallSum.size(), DNDS_MPI_REAL, MPI_SUM, u.father->getMPI().comm);
807 if (!dontUpdateIntegration)
808 for (
auto &i : bndIntegrations)
812 double t2 = MPI_Wtime();
#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 + ...
Core finite-volume evaluator for compressible Navier-Stokes / Euler equations.
#define DNDS_FV_EULEREVALUATOR_GET_FIXED_EIGEN_SEQS
Declares compile-time Eigen index sequences for sub-vector access into conservative state vectors.
#define DNDS_MPI_InsertCheck(mpi, info)
Debug helper: barrier + print "CHECK <info> RANK r @ fn @ file:line".
#define DNDS_SWITCH_INTELLISENSE(real, intellisense)
RAII helper that temporarily overrides a variable and restores its original value when the scope exit...
void EvaluateRHS(ArrayDOFV< nVarsFixed > &rhs, JacobianDiagBlock< nVarsFixed > &JSource, ArrayDOFV< nVarsFixed > &u, ArrayRECV< nVarsFixed > &uRecUnlim, ArrayRECV< nVarsFixed > &uRec, ArrayDOFV< 1 > &uRecBeta, ArrayDOFV< 1 > &cellRHSAlpha, bool onlyOnHalfAlpha, real t, uint64_t flags=RHS_No_Flags)
Evaluate the spatial right-hand side of the semi-discrete system.
Eigen::Vector< real, nVarsFlow > TU
Fixed-size 5-component conservative state vector (rho, rhoU, rhoV, rhoW, E).
Eigen::Matrix< real, 3, nVarsFlow > TDiffU
Fixed-size 3x5 spatial gradient of the conservative state (one row per spatial dimension).
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...
@ NS_SA
NS + Spalart-Allmaras, 2D geometry (6 vars).
@ BCWallIsothermal
Isothermal wall; requires wall temperature in the BC value vector.
@ BCWall
No-slip viscous wall boundary.
@ BCWallInvis
Inviscid slip wall boundary.
@ BCSpecial
Test-case-specific boundary (Riemann, DMR, isentropic vortex, RT).
@ BCOut
Supersonic outflow (extrapolation) boundary.
@ BCSym
Symmetry plane boundary.
@ BCFar
Far-field (characteristic-based) boundary.
DNDS_CONSTANT const index UnInitIndex
Sentinel "not initialised" index value (= INT64_MIN).
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
DNDS_CONSTANT const real veryLargeReal
Catch-all upper bound ("practically infinity") for physical scalars.
Eigen::Matrix< real, 5, 1 > v