pyfracval.cca.rescue#
Detect-and-drop rescue for CCA sticking failures.
docs/source/overlap_failure_census.md’s real data is a caution, not a green light: at N=128 hard regime, every failure happens at CCA round 1 between ~12-particle subclusters, with a median of 9/24 (~37.5%) particles implicated - not the “a handful out of hundreds” scale the idea was originally framed around. This module implements the mechanism regardless (it may behave differently at larger N or later rounds, which the census data didn’t sample), gated by an explicit drop budget so it only fires when a failure genuinely is localized - most of the failures this project has actually measured will not qualify, and that is by design, not a bug.
Design: rather than re-running the full candidate/rotation search on a reduced cluster pair (expensive, and would need to plumb a raw-coords entry point through the whole _perform_cca_sticking machinery), this takes the exact geometric placement that was already censused as failing, removes the specific particles the census identified as offending, and checks whether that placement is now overlap-free. This directly answers the question the user’s own framing asked (“would dropping the monomers make the cluster fusable”) without a second search. If removing those particles doesn’t resolve the overlap (some other pair is still too close), the rescue simply fails and the caller falls through to the existing round-abort behavior - no retry-with-a-different- placement is attempted here.
No backfill: a rescued merge produces fewer than the requested N particles. The final aggregate’s shortfall is reported via AggregateProperties.n_particles_dropped rather than silently absorbed.
Module Contents#
- pyfracval.cca.rescue.select_drop_candidates(census, max_drop_particles, max_drop_fraction)[source]#
Decide which particles to drop from each side of a failed pair, given its overlap census.
Budget: min(max_drop_particles, ceil(max_drop_fraction * cluster_size)) per side - an absolute safety cap (never drop more than max_drop_particles outright) and a relative cap (never drop more than max_drop_fraction of a small cluster, so a 20-particle cluster doesn’t lose a quarter of itself just because the fixed budget allows it). Both bounds are configurable (OrchestratorAlgorithmConfig.cca_drop_rescue_max_particles / cca_drop_rescue_max_fraction) since the right values are an empirical question, not something to fix a priori - see docs/source/overlap_failure_census.md’s severity-histogram data for what’s actually observed.
Because the two caps combine with
min, the absolute one dominates once clusters get large: at N=512’s observed cluster-pair size of 100,min(5, ceil(0.25*100))is still 5, so the relative budget never actually engages no matter how it is set (docs/source/drop_rescue.md). Settingmax_drop_particlesto 0 (or negative) therefore means “no absolute cap - scale purely with cluster size”, which is the only way to get a genuinely N-aware budget.Returns (drop_idx1, drop_idx2) if within budget on both sides, else None (rescue not attempted - caller falls through to the existing round-abort behavior).
- pyfracval.cca.rescue.retry_sticking_with_drops(coords1_failed, radii1, coords2_failed, radii2, drop_idx1, drop_idx2, tol_ov)[source]#
Remove the given particle indices from the already-placed failing geometry and check whether the result is overlap-free.
Parameters mirror the last-censused placement (coords1_failed/coords2_failed - the same arrays pyfracval/overlap_statistics.py::compute_overlap_census was run against, not a fresh re-placement).
Returns (combined_coords, combined_radii) on success, None if the reduced pair still overlaps (dropping those particles wasn’t enough) or would empty a cluster entirely.