Fix issues #186, #191-#193, #195-#200 - #205
Merged
Merged
Conversation
…-Fluids#195-AMReX-Fluids#200 Source/Diffusion.{H,cpp}, Source/NavierStokes.cpp (AMReX-Fluids#200): - diffuse_tensor_Vsync solved with shear viscosity hard-coded to 1.0, ignoring the beta it was passed. Restore its use; thread a betaCC parameter through diffuse_Vsync so MLEBTensorOp::setEBShearViscosity gets the old-time cell-centered viscosity in EB builds. - diffuse_tensor_Vsync scaled only component 0 of the RHS by rhsscale while setScalars scaled the operator for all components. - diffuse_tensor_Vsync multiplied the rho_flag==3 RHS by old-time density while acoef and the caller both use new-time density. - diffuse_tensor_velocity never multiplied its RHS by rhsscale. - diffuse_scalar never called setCoarseFineBC on a level>0 solve with no coarse data, so MLMG assumed a refinement ratio of 2. Source/Projection.cpp (AMReX-Fluids#199): - The RZ branch of scaleVar zeroed velocity ghosts outside the domain in the axial direction, destroying inflow values the nodal divu stencil reads. Scale them by radius instead, as the pre-port Fortran radmpyvel did, and mirror the change in rescaleVar. - computeRhoG's 3D y-hi face mixed density rows in rho_ii, both in the main loop and in the x-lo ext_dir edge branch; the latter also read one cell outside the rho FAB. Source/NavierStokesBase.cpp (AMReX-Fluids#198): - Restart with ns.gradp_in_checkpoint=0 called computeGradP on a Gradp_Type StateData that AmrLevel::restart had left undefined. Define it first, using the midpoint of Press's own interval so that Gradp's curTime()/prevTime() match Press's exactly. Source/NavierStokesBase.cpp (AMReX-Fluids#197): - post_timestep_particle passed an undefined MultiFab to Timestamp whenever particles.timestamp_indices was not set. - post_timestep_particle and ParticleDerive built MultiFabs on level lev's BoxArray with the *current* level's FabFactory. - ParticleDerive("total_particle_count") accumulated fine into coarse with a host BoxIterator loop over device data; it is now a ParallelFor with Gpu::Atomic::AddNoRet, which also removes an OpenMP race between tiles. Source/NavierStokesBase.cpp (AMReX-Fluids#196): - The cut-cell CrseAdd/FineAdd overloads multiply by the EB area fraction, but AMReX-Hydro already area-weighted the fluxes, so cut c/f faces were refluxed with ap^2. Hand those overloads un-weighted copies. - The StateRedist "state" for the mac_sync was copied from Vsync/Ssync without filling ghost cells, making the sync correction near box boundaries grid-decomposition dependent. - use_wts_in_divnc was sitting in ApplyMLRedistribution's fac_for_deltaR slot, so dm_as_fine was scaled by +dt even in the mac_sync, where the fluxes go to FineAdd with -dt. Source/NavierStokesBase.{H,cpp}, Source/NS_average.cpp (AMReX-Fluids#195, AMReX-Fluids#186): - time_avg/time_avg_fluct/dt_avg were sized only in post_init and post_restart, so a level created by a later regrid indexed them out of bounds. Add grow_avg_vectors() and call it from post_regrid and from both init() overloads. - The brand-new-level init() never initialized Average_Type. FillCoarsePatch it, as the init(AmrLevel&) twin does, and seed the level's accumulators from the coarser level so that the interpolated integral is normalized consistently. - checkPoint wrote the single shared TimeAverage file once per level with trunc, so only the finest level's data survived, and dt_avg was never checkpointed. Level 0 now writes one (time_avg, time_avg_fluct, dt_avg) triple per level, and post_restart reads forward to its own level's triple. - time_average dereferenced Average_Type old data that is never allocated on a fresh start with ns.init_iter=0. Source/SyncRegister.cpp (AMReX-Fluids#193): - The bndry_mask threshold was SPACEDIM^SPACEDIM-0.5 (26.5 in 3D) but the accumulated count maxes out at 2^SPACEDIM, so in 3D no node was ever masked out of the sync-projection RHS. 2D is unchanged; 3D multilevel answers move. - outflow_dirs was one element short of the number of directions the loop below can record. Source/NS_LES.cpp (AMReX-Fluids#192): - The Smagorinsky branch added each velocity-gradient component to itself rather than to its transpose, so mu_t was built from |grad u| instead of |S| and was overpredicted in every rotational flow. Pair each component with its transpose. Util/ConvertCheckpoint/ConvertCheckpointGrids.cpp (AMReX-Fluids#191): - nsets_save was a 1-element Vector written at indices 0..ndesc-1 and resized only at lev==1. Drop the global and derive nsets from the data pointers, the way StateData::checkPoint does. - ConvertData unconditionally dereferenced old_data, which is null when a state was checkpointed with nsets==1. - The trailing state types were given zero ghost cells, but cell_cons_interp's slope stencil reads one cell outside the coarse fab; and the source ghosts were never filled, so periodic-boundary ghosts fed the setVal(10.) sentinel into the slopes. Util/ConvertCheckpoint/Make.package: - Drop the reference to AMReX_FABUTIL_$(DIM)D.F, which no longer exists in AMReX; without this the utility does not build at all. Note that regression baselines move for 3D multilevel runs (AMReX-Fluids#193), any viscous multilevel run (AMReX-Fluids#200), EB cut-cell reflux (AMReX-Fluids#196), RZ with axial inflow (AMReX-Fluids#199) and Smagorinsky LES (AMReX-Fluids#192). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 28, 2026
Closed
Closed
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 #186, #191, #192, #193, #195, #196, #197, #198, #199, #200.
Changes
Source/Diffusion.{H,cpp},Source/NavierStokes.cpp(#200)diffuse_tensor_Vsyncsolved with shear viscosity hard-coded to1.0, ignoring thebetait was passed. Restored; abetaCCparameter is threaded throughdiffuse_VsyncsoMLEBTensorOp::setEBShearViscositygets the old-time cell-centered viscosity in EB builds.diffuse_tensor_Vsyncscaled only component 0 of the RHS byrhsscalewhilesetScalarsscaled the operator for all components.diffuse_tensor_Vsyncmultiplied therho_flag==3RHS by old-time density whileacoefand the caller both use new-time density.diffuse_tensor_velocitynever multiplied its RHS byrhsscale.diffuse_scalarnever calledsetCoarseFineBCon alevel>0solve with no coarse data, so MLMG assumed a refinement ratio of 2.Source/Projection.cpp(#199)scaleVarzeroed velocity ghosts outside the domain in the axial direction, destroying inflow values the nodaldivustencil reads. They are now scaled by radius, as the pre-port Fortranradmpyveldid, with the inverse inrescaleVar.computeRhoG's 3D y-hi face mixed density rows inrho_ii, both in the main loop and in the x-loext_diredge branch; the latter also read one cell outside therhoFAB.Source/NavierStokesBase.cpp(#198)ns.gradp_in_checkpoint=0calledcomputeGradPon aGradp_TypeStateDatathatAmrLevel::restarthad left undefined. It is now defined first, using the midpoint of Press's own interval soGradp'scurTime()/prevTime()match Press's exactly.Source/NavierStokesBase.cpp(#197)post_timestep_particlepassed an undefinedMultiFabtoTimestampwheneverparticles.timestamp_indiceswas not set.post_timestep_particleandParticleDerivebuiltMultiFabs on levellev'sBoxArraywith the current level'sFabFactory.ParticleDerive("total_particle_count")accumulated fine into coarse with a hostBoxIteratorloop over device data; it is now aParallelForwithGpu::Atomic::AddNoRet, which also removes an OpenMP race between tiles.Source/NavierStokesBase.cpp(#196)CrseAdd/FineAddoverloads multiply by the EB area fraction, but AMReX-Hydro already area-weighted the fluxes, so cut coarse/fine faces were refluxed withap^2. Those overloads now get un-weighted copies.StateRedist"state" for themac_syncwas copied fromVsync/Ssyncwithout filling ghost cells, making the sync correction near box boundaries grid-decomposition dependent.use_wts_in_divncwas sitting inApplyMLRedistribution'sfac_for_deltaRslot, sodm_as_finewas scaled by+dteven in themac_sync, where the fluxes go toFineAddwith-dt.Source/NavierStokesBase.{H,cpp},Source/NS_average.cpp(#195, #186)time_avg/time_avg_fluct/dt_avgwere sized only inpost_initandpost_restart, so a level created by a later regrid indexed them out of bounds. Addedgrow_avg_vectors(), called frompost_regridand bothinit()overloads.init()never initializedAverage_Type. It nowFillCoarsePatches it, as theinit(AmrLevel&)twin does, and seeds the level's accumulators from the coarser level so the interpolated integral is normalized consistently.checkPointwrote the single sharedTimeAveragefile once per level withtrunc, so only the finest level's data survived, anddt_avgwas never checkpointed. Level 0 now writes one(time_avg, time_avg_fluct, dt_avg)triple per level, andpost_restartreads forward to its own level's triple.time_averagedereferencedAverage_Typeold data that is never allocated on a fresh start withns.init_iter=0.Source/SyncRegister.cpp(#193)bndry_maskthreshold wasSPACEDIM^SPACEDIM-0.5(26.5 in 3D) but the accumulated count maxes out at2^SPACEDIM, so in 3D no node was ever masked out of the sync-projection RHS. 2D is unchanged.outflow_dirswas one element short of the number of directions the loop below can record.Source/NS_LES.cpp(#192)mu_twas built from|grad u|instead of|S|and was overpredicted in every rotational flow.Util/ConvertCheckpoint/ConvertCheckpointGrids.cpp(#191)nsets_savewas a 1-elementVectorwritten at indices0..ndesc-1and resized only atlev==1. The global is gone;nsetsis derived from the data pointers, the wayStateData::checkPointdoes.ConvertDataunconditionally dereferencedold_data, which is null when a state was checkpointed withnsets==1.cell_cons_interp's slope stencil reads one cell outside the coarse fab; and the source ghosts were never filled, so periodic-boundary ghosts fed thesetVal(10.)sentinel into the slopes.Util/ConvertCheckpoint/Make.packageAMReX_FABUTIL_$(DIM)D.F, which no longer exists in AMReX. Without this the utility does not build at all, so this was needed to test the ConvertCheckpointGrids: nsets_save OOB write, null old_data deref, 0-ghost interp stencil #191 fix.Testing
Builds clean (no new warnings):
Exec/run2d,Exec/run3d,Exec/eb_run2d,Exec/eb_run3d,Exec/run_2d_particles,Tutorials/HotSpot(2D and 3D),Util/ConvertCheckpoint.Baseline-vs-fixed runs confirm each fix:
developmentand now run to completion (ns.init_iter=0averaging; particles withouttimestamp_indices; restart from a Gradp-less checkpoint synthesized by editing a real checkpoint header).TimeAverage; the fix writes per-level triples, and a restart withmax_levelraised to 2 creates level 2 mid-run and seeds it from level 1 without going out of bounds.nsets==1one (written withinit_iter=0), preserving the nsets pattern; IAMR restarts from both.regtest.3d.rayleightaylorto 7 steps, 3 levels, 13mac_synccalls — 3D masking is now live and the run is stable.hotspotand non-EBhotspotdiffer from baseline by ~1e-5 relative (expected: real viscosity in the Vsync solve plus the cut-cell reflux correction).eb flow_past_cylinder-x,eb bubble,eb double_shear_layer,poiseuille,traceradvect_bdsandhotspot_rzare bit-identical.hotspot_rz(no inflow, inviscid) is unchanged.Baselines that move
3D multilevel sync-projection (#193), any viscous multilevel run (#200), EB cut-cell reflux (#196), RZ with axial inflow (#199), and Smagorinsky LES (#192). Affected tests include
regtest.3d.rayleightaylorand the other 3D multilevel decks,regtest.2d.hotspot,Tutorials/Bubble,eb_run2d/regtest.2d.hotspot, and theeb_run3dmultilevel decks.Separately,
Exec/eb_run2d/regtest.2d.shock_past_cylinderaborts with "MLMG failed" on both baseline and patched code in my environment — a pre-existing failure, unrelated to these changes.🤖 Generated with Claude Code