Skip to content

1602-lattice-particle-cloud-packing#1603

Merged
sbryngelson merged 2 commits into
MFlowCode:masterfrom
danieljvickers:1602-lattice-particle-cloud-packing
Jun 16, 2026
Merged

1602-lattice-particle-cloud-packing#1603
sbryngelson merged 2 commits into
MFlowCode:masterfrom
danieljvickers:1602-lattice-particle-cloud-packing

Conversation

@danieljvickers

Copy link
Copy Markdown
Member

Description

Adds a new particle cloud packing algorithm in the form of lattice-based packing. This tries to take a computationally-optimal approach to placing particles by using a basic geometric lattice. This code is only CPU facing.

Closes #1602 .

Type of change (delete unused ones)

  • New feature
  • Documentation

Testing

I swapped out the packing method in our current example case and observed output.

Checklist

Check these like this [x] to indicate which of the below applies.

  • I added or updated tests for new behavior
  • I updated documentation if user-facing behavior changed

@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown

Claude Code Review

Head SHA: 1756742

Files changed:

  • 5
  • docs/documentation/case.md
  • src/common/m_derived_types.fpp
  • src/simulation/m_checker.fpp
  • src/simulation/m_particle_cloud.fpp
  • toolchain/mfc/case_validator.py

Findings

1. Lattice particles placed outside cloud bounds (2D) — s_particle_cloud_lattice

In the 2D triangular lattice path the outer loop has no y-bound guard:

do while (n_placed < n_target)
    py = ymin + real(row, wp)*row_dy
    ! ← no check that py <= ymax
    ...
    do while (px <= xmax .and. n_placed < n_target)
        call s_add_cloud_particle(...)   ! places particle at py, which may be > ymax

The spacing formula sets area_per_particle = (sqrt(3)/2)*spacing**2 equal to the total area divided by n_target, but row_dy = spacing*sqrt(3)/2 generally does not divide (ymax - ymin) evenly. When the in-bounds row count is one short of what the theory predicts, the outer loop increments row past ymax and the inner do while (px <= xmax) still fires, placing a full row of particles outside the cloud y-extent. These out-of-bounds IB particles corrupt the bed geometry silently.

Fix: add a py <= ymax guard to the outer loop (or skip the inner loop when py > ymax), and abort after the loop if n_placed < n_target (mirroring the check in s_particle_cloud_random_box).


2. FCC x/y/z positions unchecked against cloud bounds (3D) — s_particle_cloud_lattice

In the 3D FCC path no coordinate is validated before placement:

ncx = max(1, ceiling((xmax - xmin)/cell))
ncy = max(1, ceiling((ymax - ymin)/cell))
kz = 0
do while (n_placed < n_target)
    do jy = 0, ncy - 1
        do ix = 0, ncx - 1
            do b = 1, 4
                if (n_placed >= n_target) exit
                call s_add_cloud_particle(cloud_idx, ib_idx, geom,
                    xmin + real(ix,wp)*cell + bx_off(b),   ! can exceed xmax
                    ymin + real(jy,wp)*cell + by_off(b),   ! can exceed ymax
                    zmin + real(kz,wp)*cell + bz_off(b),   ! no zmax bound at all
                    particle_cloud_ibs)
  • x/y: for ix = ncx-1 (or jy = ncy-1) combined with a face-centre basis offset of 0.5_wp*cell, the position can exceed xmax (or ymax) by up to 0.5*cell. ncx = ceiling((xmax-xmin)/cell) does not guarantee that all grid points land inside the box.
  • z: there is no ncz; kz increments freely until n_placed >= n_target. If boundary rounding causes the in-bounds FCC sites to total fewer than n_target, all excess particles land at z > zmax and ib_idx overruns the particle_cloud_ibs array (allocated to exactly n_total_particles), producing an out-of-bounds write.

Fix: add explicit x <= xmax, y <= ymax, z <= zmax guards inside the innermost loop before calling s_add_cloud_particle, compute ncz = max(1, ceiling((zmax-zmin)/cell)) to bound the outer loop, and abort if n_placed < n_target after all layers are exhausted.

@danieljvickers
danieljvickers marked this pull request as ready for review June 15, 2026 18:34
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 40.78947% with 45 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.81%. Comparing base (825adb2) to head (ea125ab).

Files with missing lines Patch % Lines
src/simulation/m_particle_cloud.fpp 41.33% 44 Missing ⚠️
src/simulation/m_checker.fpp 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1603      +/-   ##
==========================================
- Coverage   60.95%   60.81%   -0.14%     
==========================================
  Files          82       82              
  Lines       19926    19975      +49     
  Branches     2924     2929       +5     
==========================================
+ Hits        12145    12148       +3     
- Misses       5805     5851      +46     
  Partials     1976     1976              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sbryngelson
sbryngelson merged commit 7722a81 into MFlowCode:master Jun 16, 2026
82 checks passed
@danieljvickers
danieljvickers deleted the 1602-lattice-particle-cloud-packing branch June 16, 2026 14:22
sbryngelson added a commit to wilfonba/MFC-Wilfong that referenced this pull request Jun 16, 2026
…tate; adopt master's IB-patch parallelism refactor (MFlowCode#1603/MFlowCode#1549)

post_process m_global_parameters: kept MFlowCode#1290 nidx/neighbor_ranks + master's ib_airfoil decls. m_ib_patches: took master's two-mode s_apply_ib_patches dispatcher and re-applied MFlowCode#1290's x_domain->glb_bounds substitution (10 sites, both parallelism modes) so IB periodic wrapping uses the global extent under MPI decomposition. Verified: 3-target CPU build, precheck clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Lattice Particle Cloud Packing

2 participants