Repository navigation
Fix issues #240-#249 - #266
Merged
asalmgren merged 8 commits intoSep 21, 2026
Merged
Conversation
- AMReX-Fluids#240 ApplyCCProjection leaked cc_phi/cc_gphi on every call (raw new with no delete). Hold them in Vector<MultiFab> and pass GetVecOfPtrs to Hydro. - AMReX-Fluids#241 The single EB scalar op was shared by the tracer and temperature passes, and MLEBABecLap cannot revert an EB Dirichlet BC to Neumann, so an EB value set by one field was silently applied to the other. Give the temperature its own solve/apply ops, selected by an is_temperature flag. - AMReX-Fluids#242 init_burggraf evaluated the exact solution at x-0.5, y-0.5 while the probtype-16 forcing, lid profile and DiffFromExact all use [0,1]^2 (regression from PR AMReX-Fluids#160). Drop the shift. - AMReX-Fluids#243 The 2D cylinder cull in incflo_PCInit rejected direction = 2 (the only value its disk formula fit) and culled a disk for directions 0/1, where AdvectWithFlow and EB2::CylinderIF use slabs. Use the same convention as AdvectWithFlow. - AMReX-Fluids#244 A fresh start seeded tracer particles on level 0 and never redistributed, so initial particle tagging counted zero on level >= 1 and the first advection used level-0 MAC velocities. Redistribute after each level is created from scratch. - AMReX-Fluids#245 steady_state = 1 was accepted but SteadyStateReached() is an Abort stub, so the run took one step and then died. Refuse it at read time, as PR AMReX-Fluids#212 did for amr.KE_int. - AMReX-Fluids#246 InitData never recorded m_last_chk (and restart set m_last_plt = 0), so Evolve's final-output block rewrote the step's checkpoint/plotfile, renaming the restart checkpoint to *.old.*. - AMReX-Fluids#247 ReadCheckpointFile took finest_level from the header without checking amr.max_level, writing grids[]/m_leveldata[] out of bounds when restarting with a smaller max_level. Abort with a diagnostic instead. - AMReX-Fluids#248 The update_temperature corrector passed the tracer laps (get_laps_new) to compute_laps_T instead of get_laps_tem_new. Latent today because MOL + temperature is refused at read time. - AMReX-Fluids#249 The update_density corrector refreshed no ghost cells of density/density_nph, but ApplyCCProjection averages density_nph to faces through them, mixing predictor and corrector values on inter-grid faces. Use one ghost cell in both passes. Built clean (no warnings) for 2D/3D with and without EB. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
WeiqunZhang
approved these changes
Sep 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #240, Fixes #241, Fixes #242, Fixes #243, Fixes #244, Fixes #245, Fixes #246, Fixes #247, Fixes #248, Fixes #249.
Medium severity
ApplyCCProjection still allocates cc_phi/cc_gphi with
newand never deletes them: the per-call leak reported as #191 was marked closed by PR #213 but the code was not changed #240ApplyCCProjectionallocatedcc_phi/cc_gphiwithnewand never deleted them, leaking1 + AMREX_SPACEDIMcell-centred fields per call (device memory on GPU). This was reported as ApplyCCProjection leaks cc_phi/cc_gphi MultiFabs (raw new, never deleted) every call #191 and closed by PR fix issues 171 176 181 188 189 191 #213 without the fix landing. They are now held inVector<MultiFab>and handed to Hydro withGetVecOfPtrs, matching howinv_rho/m_fluxesare already done in the same function.DiffusionScalarOp: the single EB scalar op is shared by the tracer and temperature passes, so an EB Dirichlet BC set by one pass (tracer_eb or temperature_eb) is silently applied to the other, with the other field's values and coefficient #241
DiffusionScalarOpowned one EB solve op and one EB apply op, shared by the tracer and temperature passes.MLEBABecLaphas no way to revert an EB Dirichlet BC back to homogeneous Neumann, so with only one ofeb_flow.tracer/eb_flow.temperaturegiven, the other field silently solved with a Dirichlet EB pinned to the first field's value and coefficient. The temperature now gets its ownm_eb_tem_solve_op/m_eb_tem_apply_op, selected by anis_temperatureflag passed fromdiffuse_temperature/compute_laps_T. Pure plumbing — the per-component logic is untouched.init_burggraf evaluates the exact solution at x-0.5, y-0.5 (regression from PR #160) while the probtype-16 forcing, lid profile and DiffFromExact use [0,1]: benchmark.burggraf starts half a cavity out of place #242
init_burggrafevaluated the exact solution atx-0.5, y-0.5while the probtype-16 forcing, the lid profile andDiffFromExactall use[0,1]^2, so the IC was the exact solution translated by (-1/2,-1/2) — an O(1) slip velocity on no-slip walls. A regression from PR wrap constants with Real() #160 (a cosmeticReal()-wrapping pass); the shift is removed.incflo_PCInit 2D cylinder cull: ALWAYS_ASSERT rejects cylinder.direction=2 (the only value its disk formula fits) and culls a disk for directions 0/1 where AdvectWithFlow and EB2::CylinderIF use slabs (regression from PR #213) #243 The 2D cylinder cull in
incflo_PCInitwas self-contradictory: the assert admitted onlydirection0 or 1, but the formula was the out-of-plane (direction 2) disk distance and ignored the direction it had just validated. MeanwhileAdvectWithFlowandEB2::CylinderIFtreat 2 as a disk and 0/1 as slabs. Sodirection = 2aborted outright, and 0/1 seeded a disk while every later step confined particles to a slab. Init now uses the same convention asAdvectWithFlow.Fresh start seeds tracer particles on level 0 and never redistributes: initial ErrorEst counts zero particles on level >= 1 (no level 2 from particle tagging at t=0) and the first advection uses level-0 MAC velocities for every particle #244 A fresh start seeds tracer particles on level 0 only and nothing on that path ever calls
Redistribute()(the restart path gets it fromParticleContainer::Restart). So initialErrorEstcounted zero particles on level >= 1 — withrefine_particlesas the criterion the initial hierarchy stopped at level 1 regardless ofamr.max_level— and the first advection moved every particle under a fine patch with level-0 MAC velocities. Now redistributes after each level is created from scratch.Low severity
ReadParameters accepts steady_state=1 but SteadyStateReached() is an Abort stub: run takes one step, then dies #245
steady_state = 1was read and accepted, butSteadyStateReached()is anamrex::Abortstub with the real body#if 0'd.Evolve()masks its entry test with&& !m_steady_state, so the run paid for full initialization plus one complete time step and then died on what reads as an internal TODO (with thestop_timecap disabled for that step, andsteady_state_tolsilently ignored). Now refused at read time, exactly as PR fix issue 177 178 179 #212 did foramr.KE_int.InitData never records m_last_chk (and restart sets m_last_plt=0): Evolve's final-output block rewrites the step's checkpoint/plotfile, renaming the restart checkpoint to *.old.* #246
InitDatawrotechk00000without settingm_last_chk, and the restart branch leftm_last_chk = -1while recordingm_last_plt = 0instead ofm_nstep. When the loop then takes no steps, Evolve's final-output block rewrote the step's checkpoint and plotfile —UtilCreateCleanDirectoryrenames the existing directory to*.old.*first, so the very checkpoint the run restarted from was renamed and replaced by an identical copy. Both counters now record the step of each write.ReadCheckpointFile takes finest_level from the header without checking amr.max_level: restarting with a smaller max_level writes grids[]/m_leveldata[] out of bounds #247
ReadCheckpointFiletookfinest_levelfrom the header and loopedMakeNewLevelFromScratchover it, butgrids/dmap/m_leveldata/m_t_neware all sizedmax_level + 1from the current inputs. Restarting with a smalleramr.max_levelwrote past the end of those vectors — silent heap corruption in a release build. Now aborts with a diagnostic naming both values.update_temperature corrector passes the tracer laps (get_laps_new) to compute_laps_T instead of get_laps_tem_new (latent: MOL+temperature is refused at read time) #248 The
StepType::Correctorbranch ofupdate_temperaturepassedget_laps_new()(the tracer Laplacian,m_ntraccomponents) tocompute_laps_Tinstead ofget_laps_tem_new(). Unreachable today —ReadParametersrefusesuse_temperaturewithadvection_type = MOL— but it would clobber the tracer'slapsand alias out-of-bounds components forntrac > 1the moment that guard is lifted. One-token fix.update_density corrector refreshes no ghost cells of density/density_nph, but ApplyCCProjection averages density_nph to faces through its ghost cells: stale predictor values on inter-grid faces (MOL + use_cc_proj + variable density) #249
update_densityusedng = 0in the corrector, so the ghost cells ofdensity/density_nphstill held predictor values.ApplyCCProjectionaveragesdensity_nphto faces viaamrex_avg_cc_to_fc, which reads the ghost cell on the low face of every grid, so thedt/rhoface coefficient was assembled from two different time levels on faces coinciding with grid boundaries — making MOL +use_cc_proj+ variable-density runs depend onamr.max_grid_size. Now one ghost cell in both passes, so the corrector'sfillpatch_densityrefreshes them.Testing
Built clean with no warnings in four configurations:
test_2d(2D EB),test_no_eb_2d(2D no-EB),test_3d(3D EB),test_no_eb_3d(3D no-EB).Note that #242 (burggraf IC) and #249 (corrector density ghost cells) change numerical output, so the affected benchmarks will need regolding.
benchmark.burggrafin particular: the deck runs tostop_time = 5at Re = 100, so theNorm0printed bytest_convergence_burggrafwas previously measuring the decay of the spurious transient rather than the discretisation error of the steady solution.🤖 Generated with Claude Code