rtx-cfd: solver_metric_force carries the scheme's limited face correction with the predictor's far-upwind choice, so the flux form is the solver's under TVD too (CFD2 ny = 41: three boxes spread 1.8 N/m → 5e-13; the upwind-only form read 120.2 for a solver box of 126.0)
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
CI / WASM Build + Size Check (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_0116sg1Qz1gMv9hdcKP1XUam
This commit is contained in:
Omar Sobh
2026-09-06 17:42:47 -07:00
co-authored by Claude Fable 5.1
parent ce3cbcce57
commit 11d001fe48
@@ -385,7 +385,8 @@ impl OversetPisoSolver {
impl OversetPisoSolver {
/// The force on everything inside the box `(i0, i1, j0, j1)` (cell
/// index bounds, as `EmbeddedMask::control_volume_force`) in the
/// SOLVER'S OWN flux form: the predictor's upwind convective flux,
/// SOLVER'S OWN flux form: the predictor's convective flux (upwind
/// plus the scheme's limited correction),
/// its diffusive flux and the cell pressure, on the momentum control
/// volumes' faces that make up the box boundary (u volumes `i0 + 1
/// ..= i1` × `j0 .. j1`, v volumes `i0 .. i1` × `j0 + 1 ..= j1`),
@@ -409,29 +410,65 @@ impl OversetPisoSolver {
let mu = self.background.config().viscosity;
let bg = &field.background;
let (u, v, p) = (&bg.u_old, &bg.v_old, &bg.p);
let upwind = |f: f64, up: f64, down: f64| if f >= 0.0 { up } else { down };
// The predictor's face value: upwind plus the scheme's limited
// correction with the same far-upwind choice (`u_rhs`), so the
// flux form is the solver's under upwind AND under TVD.
let scheme = self.background.parameters().convection_scheme;
let face = |f: f64, far_up: Option<f64>, up: f64, down: f64, far_dn: Option<f64>| {
if f >= 0.0 {
up + scheme.face_correction(far_up, up, down)
} else {
down + scheme.face_correction(far_dn, down, up)
}
};
// Outward x-momentum flux through the u-volume face at cell i's
// centre (n = +x), per unit length.
let phi_u_x = |j: usize, i: usize| {
let ue = 0.5 * (u[(j, i)] + u[(j, i + 1)]);
rho * ue * upwind(ue, u[(j, i)], u[(j, i + 1)]) - mu * (u[(j, i + 1)] - u[(j, i)]) / dx
+ p[(j, i)]
let uf = face(
ue,
(i >= 1).then(|| u[(j, i - 1)]),
u[(j, i)],
u[(j, i + 1)],
(i + 2 <= nx).then(|| u[(j, i + 2)]),
);
rho * ue * uf - mu * (u[(j, i + 1)] - u[(j, i)]) / dx + p[(j, i)]
};
// Through the u-volume face at v-face row j (n = +y), for u face i.
let phi_u_y = |j: usize, i: usize| {
let vn = 0.5 * (v[(j, i - 1)] + v[(j, i)]);
rho * vn * upwind(vn, u[(j - 1, i)], u[(j, i)]) - mu * (u[(j, i)] - u[(j - 1, i)]) / dy
let uf = face(
vn,
(j >= 2).then(|| u[(j - 2, i)]),
u[(j - 1, i)],
u[(j, i)],
(j + 1 < ny).then(|| u[(j + 1, i)]),
);
rho * vn * uf - mu * (u[(j, i)] - u[(j - 1, i)]) / dy
};
// y-momentum: through the v-volume face at cell j's centre (n = +y).
let phi_v_y = |j: usize, i: usize| {
let vn = 0.5 * (v[(j, i)] + v[(j + 1, i)]);
rho * vn * upwind(vn, v[(j, i)], v[(j + 1, i)]) - mu * (v[(j + 1, i)] - v[(j, i)]) / dy
+ p[(j, i)]
let vf = face(
vn,
(j >= 1).then(|| v[(j - 1, i)]),
v[(j, i)],
v[(j + 1, i)],
(j + 2 <= ny).then(|| v[(j + 2, i)]),
);
rho * vn * vf - mu * (v[(j + 1, i)] - v[(j, i)]) / dy + p[(j, i)]
};
// Through the v-volume face at u-face column i (n = +x), for v face j.
let phi_v_x = |j: usize, i: usize| {
let ue = 0.5 * (u[(j - 1, i)] + u[(j, i)]);
rho * ue * upwind(ue, v[(j, i - 1)], v[(j, i)]) - mu * (v[(j, i)] - v[(j, i - 1)]) / dx
let vf = face(
ue,
(i >= 2).then(|| v[(j, i - 2)]),
v[(j, i - 1)],
v[(j, i)],
(i + 1 < nx).then(|| v[(j, i + 1)]),
);
rho * ue * vf - mu * (v[(j, i)] - v[(j, i - 1)]) / dx
};
let vol = dx * dy;
let (mut out_x, mut out_y) = (0.0, 0.0);