Repository navigation
Bound chemistry face states with a scaling limiter (NaN at finite-cylinder rims) - #1975
sbryngelson wants to merge 4 commits into
Conversation
…finite-cylinder rims) At the cap/side rim of a finite IB cylinder (and any sharp IB corner) the ghost layers seen by one fluid cell mirror different faces: the first layer mirrors the side, deeper layers mirror the cap's stagnation region. With a hot isothermal wall the ghost column is then non-monotone, WENO overshoots the fluid/ghost face to ~7600 K, past the NASA fit where cp < 0, and HLLC returns a NaN sound speed. With chemistry, a reconstructed face state whose density or temperature is not positive, or whose temperature exceeds T_surface_max, now falls back to its cell's state. Adds a 2D hot-wall IB rectangle regression test that NaNs on master by step 30.
|
I checked this PR independently against the final commit 7b2c337 (CPU, CCE,
Developed with Claude Code. |
|
Note on interaction with #1969: in the GREEN run here, near-wall gas still reaches ~2850 K next to the 1800 K isothermal wall. That over-heating comes from the existing hot-wall ghost extrapolation (image-point sample distance), which #1969 fixes; with #1969 the rim ghost states are less extreme, so this face-state guard should trigger less often. The two are complementary: #1969 corrects the ghost values, this PR guards the reconstruction against out-of-range face states that remain at sharp corners. (Developed with Claude Code.) |
…of a first-order revert Replaces s_revert_unphysical_face_states with s_bound_face_states: each cell's reconstructed face states are scaled toward its cell state by one theta shared by both faces, the largest keeping face rho, p and R_mix positive and face T = p/(rho R_mix) <= T_surface_max. All three are linear in theta, so the positivity bound is closed form and the temperature bound the first root of a quadratic: continuous, no iteration. Range and loop style follow the species-bounds limiter. Regenerates 4646053A (tolerance 1e-5: corner faces amplify roundoff) and the burning-grain goldens B317404C and E5B66084, whose blowing ghost cells reconstruct a negative face density (-0.059 vs cell 0.020) that the limiter now scales.
96dec4f to
f23fb7d
Compare
Lines of Code
|
|
Closing this for now to bring the number of open PRs from me down to four, so the ones that stay open get real review attention rather than being lost in a queue of 35. No work is lost and nothing needs re-doing. The branch I intend to reopen these in small batches as the open slots free up. Apologies for the notification noise. Opened and closed with Claude Code. |
|
Root-cause context for the NaN this PR limits, from a separate investigation. This PR bounds chemistry face states with a scaling limiter because of NaNs at finite-cylinder rims. Chasing an apparently different near-IB NaN — a sphere in Mach 0.9 flow at Measured failure map. Same case, same code, varying only Mach and cells-per-diameter (1 rank, minimal 0.44M-cell domain, reproduces identically on CPU and GPU):
Failure gets worse with refinement, which is the signature of something other than ordinary under-resolution. What the state does. Instrumenting the ghost publish to report extremes over all ghost points, every RK stage: the minimum ghost pressure falls to 6.9 kPa and the minimum ghost density to 0.072, against ambient 101325 Pa and 1.168 kg/m3 — roughly 1/15 and 1/16 of ambient. The adjacent fluid follows it down smoothly, and pressure and velocity go NaN while density is still positive and finite (0.94), i.e. the temperature solve fails at near-vacuum rather than any field being corrupted. The criterion. ( Consistent with this, an ablation at the failing point: Why this may matter here. If the cylinder-rim NaN is also in a regime where The parameter does not separate our cases perfectly (M0.6/40 fails at 0.40 while M0.9/20 is clean at 0.45), so it is an indicator, not a sharp threshold. Written with Claude Code. |
Contribution Policy
All contributions are expected to demonstrate:
If these expectations are not met, we would prefer to implement the changes ourselves rather than spend time reviewing low-effort submissions.
Fixes #1964
Root cause
This is not a levelset or image-point bug. I checked every ghost point of the repro cylinder offline (same marker, levelset, image-point and stencil logic as master). Every image point lands in fluid, and every interpolation stencil has at least 4 fluid points (
cm3c_cases/debug_E/cyl_rim/tools/geom.py).The failure happens like this:
thermal_bc = 1, Twall = 1800 K), the ghost densities in that column are 0.14, 0.24, 0.27 and 0.28 kg/m^3, next to fluid at 1.05. The column is non-monotone.Instrumented trace from a restart at step 21 of the repro: at stage 3 of step 22, face (12, 17.5, 24) has ρ_R = 0.059 and p_R = 1.31e5, and the y-flux there is NaN. Non-reacting finite rods (no chemistry, adiabatic wall) run cleanly. With chemistry, an adiabatic IB (
thermal_bc = 0) or an ambient-temperature wall (Twall = 350 K) also runs cleanly. The hot isothermal wall is the ingredient that drives this to NaN.A convex corner has no single ghost value that suits both faces. A real fix at the IB level needs a new corner treatment (e.g., per-direction ghost states). This PR bounds the reconstructed face states where the NaN is produced.
#1969 alone does not fix this. #1969 extrapolates the hot-wall ghost from where the image point is actually sampled. On the repro it cools the shallowest rim ghost layer (step 21: 3176 K → 2063 K, ρ 0.137 → 0.193) but leaves layers 2–4 at ~3120 K, so the column is still non-monotone. The NaN is delayed, not removed: the 3D repro NaNs at step 26 instead of 22 (cell (12, 18, 21), the same rim position), and the 2D rectangle case at step 70 instead of 24.
Change
m_rhs.fpp: news_bound_face_states(id), run after reconstruction whenchemistryis on. It is a Zhang–Shu scaling limiter. Each cell's two face states (all primitive variables) are scaled toward the cell state by one θ ∈ [0, 1]. θ is the largest value that keeps face ρ, p and R_mix above 1e-12 of the cell value and face T = p/(ρ R_mix) ≤T_surface_max.T_surface_maxis 5000 K, the thermo windowm_ibmalready uses. ρ, p and R_mix are all linear in θ. So the positivity bound is closed form, and the T bound is the first root of a quadratic. That makes θ continuous in the data, with no iteration. θ = 1 (no change) wherever the faces are already in bounds. There is no lower T bound: an earlier 200 K bound moved1D -> Chemistry -> MultiComponent Diffusion. The range and the GPU loop style follow the species-bounds limiter (Keep species mass fractions in [0, 1] by construction instead of clipping #1963), so it runs over the range the reconstruction filled, with θ shared by both faces of a cell.2D -> Chemistry -> IBM -> Hot Wall Rectangle Corners(4646053A). It uses h2o2.yaml, 72x48 cells, 30 steps, ~3 s on CPU. It is the 2D analog: Mach 1.5 air onto an 1800 K isothermal IB rectangle. On master it aborts at step 30 (ICFL is NaN).Evidence (CPU, CCE, serial
--no-mpi)./mfc.sh test --no-mpi --no-gpu:-o IBM: 62 passed.A69D2D28failed once with a transientNo such file or directory: '0'and passed on rerun.-o Cylinder: 8 passed.-o Chemistry: 23 passed.2D -> IBM -> Vieille Burn Rate) and E5B66084 (2D -> Example -> ibm_burning_grain): the same case. On master, a blowing ghost cell inside the grain reconstructs a negative face density (ρ_face = −0.059 next to a cell ρ = 0.020, so face T < 0). HLLC is fed that state on master. The revert only touched that face, and the change stayed under the 1e-3 test tolerance. The limiter scales both faces of that cell (θ = 0.20). Fluid momentum moves by up to 3.7% relative where |value| > 1e-6, and the IB force (small in magnitude) changes a lot. With a per-face θ instead, I checked that B317404C stays within its tolerance. I kept the shared per-cell θ for consistency with Keep species mass fractions in [0, 1] by construction instead of clipping #1963. Reviewers may prefer per-face θ../mfc.sh precheckpasses.Not verified