void MyEvaluator::EvaluateRHS(tUDof<nV> &rhs, const tUDof<nV> &u,
const tURec<nV> &uRec, real t)
{
// Clear owned RHS.
for (index iCell = 0; iCell < mesh->NumCell(); iCell++)
rhs[iCell].setZero();
// Loop over all faces (owned + ghost).
for (index iFace = 0; iFace < mesh->NumFaceProc(); iFace++)
{
auto f2c = mesh->face2cell[iFace];
auto fQuad = vfv->GetFaceQuad(iFace);
Eigen::Matrix<real, nV, 1> flux_accum = Eigen::Matrix<real, nV, 1>::Zero();
fQuad.IntegrationSimple(flux_accum,
[&](auto &finc, int iG, real w)
{
// 1. Normal at this quadrature point.
tVec n = vfv->GetFaceNorm(iFace, iG)(Seq012);
// 2. Reconstruct left state at quad pt.
// GetIntPointDiffBaseValue returns a (1 x NDOF-1) row of
// basis values; multiplied by uRec gives the polynomial value.
TU UL = u[f2c[0]] +
(vfv->GetIntPointDiffBaseValue(
f2c[0], iFace, /*if2c=*/0, iG,
std::array<int,1>{0}, /*maxDiff=*/0) * uRec[f2c[0]]
).transpose();
// 3. Reconstruct right state (or apply BC).
TU UR;
if (f2c[1] != UnInitIndex)
{
UR = u[f2c[1]] +
(vfv->GetIntPointDiffBaseValue(
f2c[1], iFace, /*if2c=*/1, iG,
std::array<int,1>{0}, 0) * uRec[f2c[1]]
).transpose();
}
else
{
// Boundary face: apply FBoundary.
tPoint pPhy = vfv->GetFaceQuadraturePPhys(iFace, iG);
UR = FBoundary(UL, u[f2c[0]], f2c[0], iFace, iG,
vfv->GetFaceNorm(iFace, iG), pPhy,
mesh->GetFaceZone(iFace));
}
// 4. Your numerical flux (Roe, HLLC, LF, ...)
finc = myRiemannSolver(UL, UR, n);
// 5. Multiply by face Jacobian determinant.
finc *= vfv->GetFaceJacobiDet(iFace, iG);
});
// Accumulate into cell RHS with appropriate signs and volumes.
rhs[f2c[0]] += flux_accum / vfv->GetCellVol(f2c[0]);
if (f2c[1] != UnInitIndex)
rhs[f2c[1]] -= flux_accum / vfv->GetCellVol(f2c[1]);
}
// (Optional) volume source integral: another loop using GetCellQuad.
}