Skip to content

Feature/plume strike vectorization parallel - #121

Merged
andytorrestb merged 7 commits into
plume-kit:masterfrom
andytorrestb:feature/plume-strike-vectorization-parallel
Jul 19, 2026
Merged

Feature/plume strike vectorization parallel#121
andytorrestb merged 7 commits into
plume-kit:masterfrom
andytorrestb:feature/plume-strike-vectorization-parallel

Conversation

@andytorrestb

Copy link
Copy Markdown
Member

No description provided.

andytorrestb and others added 7 commits July 18, 2026 16:33
Replace the per-face Python loop in compute_plume_strikes() with NumPy
operations over all faces per active thruster. The original loop is
preserved verbatim as _compute_plume_strikes_scalar() for regression
comparison, debugging, and benchmarking.

The vectorized core operates on plain serializable inputs (centroids,
normals, thruster dicts, config values) so it can later run in process
workers. Gas kinetics stays scalar, evaluated only for struck faces.
Zero-distance faces and the legacy 3.14 theta constant are preserved so
strike counts and struck-face IDs match the scalar path bit-for-bit
(verified on all case/rpod/* cases, kinetics arrays exactly equal).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The target mesh is stationary during a JFH run, so jfh_plume_strikes()
now computes face centroids once and passes them to
compute_plume_strikes() via the optional face_centroids parameter
instead of recomputing them for every firing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jfh_plume_strikes() gains optional parallel/workers arguments layered
over new optional config keys ([exec] parallel, [exec] workers); default
behavior remains serial and byte-identical to before. When enabled,
independent per-firing strike arrays are computed in a
ProcessPoolExecutor (one firing per task). Workers receive only plain
serializable inputs -- precomputed centroids, unit normals, thruster
dicts, JFH step dicts, and the few needed config scalars -- shipped once
per worker via a pool initializer, so memory scales with workers x faces
rather than firings x faces.

Cumulative arrays (cum_strikes, max_pressures, max_shears,
cum_heat_flux_load) are still accumulated serially in firing order and
VTK files are written serially by the parent, preserving the
firing_data return structure exactly. Invalid parallel/workers values
raise clear ValueErrors; runtime parallel failures log a warning and
fall back to serial execution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
plume_unit_test_04 asserts the vectorized compute_plume_strikes() path
(with and without precomputed centroids) reproduces the scalar
reference exactly -- strike arrays and struck-face IDs bit-for-bit --
for every firing of the 1d_approach (geometry-only) and
multi_thrusters_square (Simplified kinetics) cases, plus explicit
zero-distance face skipping.

plume_integration_test_02 asserts jfh_plume_strikes() default behavior
stays serial and return-compatible, that the parallel path (workers=2)
matches serial per-firing and cumulative outputs, that workers=1
resolves to serial, and that invalid worker counts raise ValueError.

Kinetics arrays use np.allclose(rtol=1e-12, atol=1e-12): observed
bit-identical on this platform, tolerance only guards platform BLAS
reduction-order differences (rationale documented in each file).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
python scripts/benchmark_plume_strikes.py times the scalar reference vs
the vectorized geometry path, and serial vs process-parallel execution,
on existing repo cases (default case/rpod/1d_approach; --case, --workers,
--repeat, --skip-scalar options). It reports elapsed times and verifies
strike equivalence but asserts no speedup thresholds, keeping it stable
on shared machines.

Measured on this machine: vectorized geometry is ~245x faster than the
scalar reference on 1d_approach (10 firings x 3584 faces) and ~24x on
multi_thrusters_square with Simplified kinetics. Process-parallel is
slower than serial on these small cases because Windows process spawn
dominates; it is intended for large meshes/many firings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Relocate scripts/benchmark_plume_strikes.py to
tests/rpod/rpod_integration_test_06.py, following the established rpod
test format (unittest.TestCase, header description block, ../case/rpod
paths, conftest-derived rpod/integration markers). The benchmark prints
elapsed times (visible with pytest -s) for scalar-vs-vectorized geometry
on 1d_approach and multi_thrusters_square, and serial-vs-parallel
execution with 2 workers; it asserts only exact strike equality, never
timing thresholds. No existing test files are modified.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The full-file rewrite in 5f44163 wrote the file with LF endings, while
the rest of the repository (including this file on master) uses CRLF.
Because core.autocrlf is true with no .gitattributes, the EOL flip made
git treat all 137 original lines as deleted-and-re-added, inflating the
diff to +417/-137 when the real change is +281/-1.

Restoring CRLF (content byte-identical to the previous commit) collapses
the diff to the actual change. No functional change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@andytorrestb
andytorrestb merged commit 78a73e7 into plume-kit:master Jul 19, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant