Merged
Conversation
Instead of aborting when user-specified refinement box indices are not divisible by ref_ratio, automatically snap lo indices down and hi indices up to the nearest aligned value, with a diagnostic print.
ERF_InitCustomPertVels_ParticleTests.H accessed z_nd at the full domain khi+1, which is out of bounds for partial-z L1 boxes. Use geomdata.ProbHi()[2] for the domain top height instead. ERF_InitCustomPert_ParticleTests.H had an assertion requiring the box to span the full z-domain, which fails with partial-z AMR. Removed the assertion and unused khi variable.
Add terrain-aware k-index fixing (FixKIndexAMR) and per-level Redistribute for particles on refined levels. Add ExtractAndRouteOORParticles to handle particles escaping the fine level z-extent in partial-z refinement by recomputing k-indices for the target level. Add compute_k_from_z for uniform and stretched vertical grids. Add k-clamping in ERFParticlesAssignor and bounds checks in AdvectWithFlow and ComputeTemperature. Use terrain-aware Redistribute(z_phys_nd) in post_timestep and after regrid. Remove premature Redistribute calls from MakeNewLevel functions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…l-by-level Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…o be reverted)" This reverts commit 8b2a3ac.
…recision fixes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…test for HIP since it freezes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e m_zlevels_d Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
Refactors the warm SDM implementation to reduce per-tile boilerplate, consolidate GPU memory management, improve numerical precision in templated code, and add GPU-direct distribution sampling. No physics changes; all 8 SDM ctests pass with identical results.
New files
Source/Particles/ERF_SuperDropletPCProcess.H: DefinesSDProcess::ProcessContextandSDProcess::ParticlePointersstructs that bundle geometry/species metadata and SoA attribute pointers, respectively. These replace the repeated manual extraction ofplo,dxi,num_species,num_aerosols, species/aerosol mass pointer arrays, etc. at the top of every particle kernel.Source/Utils/ERF_InterpolationUtils.H: Generic multi-field cloud-in-cell (CIC) interpolation helperERF::Interpolation::interpolateFields()templated on an enum of field indices. Replaces duplicated per-field interpolation code in advection, mass change, and boundary routines.Core infrastructure (
ERF_SuperDropletPC.H,ERF_SuperDropletPCDefinitions.H)forEachParticleTile(): Three overloads (withProcessContext, lightweight, serial) that replace manual#pragma omp parallel+ParIterloops throughout the codebase. The serial variant (forEachParticleTileSerial) is used where thread safety is required (e.g.,DenseBinsin coalescence).buildProcessContext(lev): Consolidates extraction of geometry arrays, species/aerosol counts and indices, water density, and device property pointers into a singleProcessContextstruct.setupParticlePointers(): Consolidates extraction of SoA attribute pointers (velocity, mass, radius, multiplicity, terminal velocity, species masses, aerosol masses) into aParticlePointersstruct.updateParticleAttributes(): StaticAMREX_GPU_DEVICEmethod that recomputes effective radius and total mass from species/aerosol mass arrays. Replaces inlineSD_effective_radius+SD_total_masscalls scattered across boundary, recycle, and add-particle routines.m_sp_density,m_sp_solubility,m_sp_ionization,m_sp_mol_weight, and correspondingm_ae_*arrays): allocated once viainitializeDeviceProperties()and invalidated onsetSpeciesMaterial/setAerosolMaterial. Replaces per-tileGpu::DeviceVectorallocations + host-to-device copies that previously occurred inside every particle loop.particleToMeshHelper(): Template for particle-to-mesh deposition with support for non-uniform vertical grids (m_zlevels_d). RefactorsSDNumberDensity,numberDensity,massDensity,massFlux,speciesMassDensity, and the newcloudRainDensityto delegate to this helper.ridx_a/ridx_srefactoring: These runtime-offset index functions are now the base implementations (withoutSuperDropletsRealIdxSoA::ncompsoffset);idx_a/idx_sare redefined to call them with the compile-time offset added.SDTerminalVelocityTypeconverted fromenum structtoAMREX_ENUM, enabling directParmParseparsing andgetEnumNameString()for terminal velocity model selection.SuperDropletsIntIdxSoAtypedef added for integer SoA component access.m_term_vel_typerenamed tom_term_vel_type_w;m_idx_winitialized to-1.Distribution sampling (
ERF_SDInitialization.H/.cpp,ERF_SuperDropletPCAddParticles.cpp)SDDistributionTypeAMREX_ENUMreplaces theSupDropInit::attrib_init_*string constants. All distribution type comparisons,ParmParsequeries, and printing now use the enum directly instead of string matching.SDDistributionParamsstruct: GPU-compatible POD holding distribution type, mass/radius bounds, pre-computed CDF bounds for truncated log-normal, and multiplicity parameters.SD_erfinv_gpu():AMREX_GPU_HOST_DEVICEinverse error function approximation for GPU-side log-normal inverse CDF sampling.SD_sample_mass_gpu():AMREX_GPU_HOST_DEVICEfunction that generates a mass sample fromSDDistributionParams+ aRandomEngine, supporting constant, exponential, and log-normal (including autorange) distributions with both sampled and constant multiplicity modes.getSpeciesDistParams(),getAerosolDistParams(),makeDistributionParams(): BuildSDDistributionParamsfrom the existing member vectors, pre-computing log-space ranges and CDF bounds on the host.addParticles(): Replaced host-sidegetSpeciesDistribution/getAerosolDistributioncalls (which allocatedO(num_species * np)host vectors, sampled on CPU, then copied to device) with a singleParallelForRNGkernel that callsSD_sample_mass_gpudirectly into the particle SoA. Per-tile device vectors for material properties replaced with persistent device arrays.setDefaults()now checksm_is_waterto set species-specific defaults (water gets tiny initial mass; non-water species get zero).Per-file refactoring
ERF_SuperDropletPCAdvection.cpp: Rewritten withforEachParticleTile+buildProcessContext+interpolateFields.InterpFieldsAdvenum for density/pressure/temperature interpolation. Post-Redistributek-index update loop added.ERF_SuperDropletPCBoundaries.cpp: Rewritten withforEachParticleTile+buildProcessContext. UsesupdateParticleAttributesinstead of inline radius/mass recalculation.ERF_SuperDropletPCMassChange.cpp: Rewritten withforEachParticleTile.InterpFieldsLVenum for saturation/pressure/temperature interpolation. Solver objects (drsqdt,newton_solver) moved outside the tile loop.ERF_SuperDropletPCRecycle.cpp: Rewritten withforEachParticleTilefor all three iteration blocks (recycle, post-redistribute location update, remove inactive). Division-by-zero guard added fordeac_fraccomputation.ERF_SuperDropletPCDiagnostics.cpp: IndividualReduceMin/ReduceMax/ReduceSumcalls replaced with a single fusedReduceData<>/ReduceOpspass. Individual MPI reductions replaced with batched arrayReduceRealMin/ReduceRealMax/ReduceRealSumcalls.ERF_SuperDropletPCInitializations.cpp: Terminal velocity parsing usesAMREX_ENUMdirectly instead of string comparison.AMREX_ASSERTchanged toAMREX_ALWAYS_ASSERTfor species/aerosol count checks.initializeDeviceProperties()called indefine(). Z-levels reading added for non-uniform grids.SetAttributesandDensityScalingrewritten withforEachParticleTile.ERF_SuperDropletPCUtils.cpp:computeMeshVarrefactored with early returns and cleaner dispatch.SDNumberDensity,numberDensity,massDensity,massFluxdelegate toparticleToMeshHelper.cloudRainDensityadded (previously was a 4-argument overload ofspeciesMassDensity).Precision and constant fixes
ERF_SuperDropletPCMassChange.H: Include guard fixed (COALESCENCE->MASSCHANGE). Namespace renamedSDMassChangeUtils->SDMassChangeUtils_LV. Named constants (one,zero,myhalf,two,three) replaced withRT()casts throughout ODE functions.std::exp(-myhalf*std::log(R_sq))replaced withRT(1.0)/std::sqrt(R_sq). Helper methods added toTimeIntegrator:computeTimestep,computeTau,limitTimestep,isTimestepTooSmall,evalRHS,printStepInfo,printStepInfoNewton.ERF_SuperDropletPCCoalescence.H:amrex::Real(...)replaced withRT(...)throughout all data tables and kernel functions. Named constants replaced withRT()casts.ERF_TerminalVelocity.H:m_rhorenamed tom_rho_w. Viscosity calculation consolidated intoviscCoeff(a_T)method (was inline inCloudRainShima). Allamrex::Real(...)replaced withRT(...).ERF_Constants.H:four_thirds_piconstant added. Used throughout in place ofReal(4.0)/three*PIor(amrex::Real(4.0)/three)*PI.Misc
ERF_SuperDropletsMoist.H:GetPlotVarrefactored withtry_copyhelper lambda.ERF_SuperDropletsMoistUtils.cpp:speciesMassDensity4-argument calls updated tocloudRainDensity.SDInitProperties::readInputs(the per-species keyed queries supersede the oldcondensate_*keys).