pyfracval.overlap ================= .. py:module:: pyfracval.overlap .. autoapi-nested-parse:: Overlap calculation dispatch for PyFracVAL. Functions for computing maximum overlap between particle clusters, with variants for PCA, CCA, fast, parallel, and auto-dispatch modes. The overlap tolerance and sticking feasibility checks are used in the PCA/CCA workflow of :cite:p:`Moran2019FracVAL`. Constants --------- PARALLEL_OVERLAP_THRESHOLD Minimum cluster size to trigger parallel overlap calculation. Functions --------- calculate_max_overlap_cca Full pairwise overlap calculation for CCA cluster pair. calculate_max_overlap_pca Full pairwise overlap calculation for PCA cluster pair. calculate_max_overlap_pca_fast Optimised overlapping-spheres overlap for PCA. calculate_max_overlap_cca_fast Optimised overlapping-spheres overlap for CCA. calculate_max_overlap_pca_parallel Parallel overlap calculation for PCA cluster pair. calculate_max_overlap_cca_parallel Parallel overlap calculation for CCA cluster pair. calculate_max_overlap_pca_auto Auto-dispatch overlap for PCA (chooses fast vs parallel). calculate_max_overlap_cca_auto Auto-dispatch overlap for CCA (chooses fast vs parallel). Module Contents --------------- .. py:function:: calculate_max_overlap_cca(coords1, radii1, coords2, radii2) Calculate max overlap between two particle clusters (Numba optimized). Overlap is defined as `1 - distance / (radius1 + radius2)` for overlapping pairs, max(0). :param coords1: Nx3 coordinates of cluster 1. :type coords1: np.ndarray :param radii1: N radii of cluster 1. :type radii1: np.ndarray :param coords2: Mx3 coordinates of cluster 2. :type coords2: np.ndarray :param radii2: M radii of cluster 2. :type radii2: np.ndarray :returns: Maximum overlap fraction found between any particle in cluster 1 and any particle in cluster 2. Returns 0.0 if no overlap. :rtype: float .. py:function:: calculate_max_overlap_pca(coords_agg, radii_agg, coord_new, radius_new) Calculate max overlap between a new particle and an aggregate (Numba). Overlap is defined as `1 - distance / (radius_new + radius_agg)` for overlapping pairs, max(0). :param coords_agg: Nx3 coordinates of the existing aggregate. :type coords_agg: np.ndarray :param radii_agg: N radii of the aggregate particles. :type radii_agg: np.ndarray :param coord_new: 3D coordinates of the new particle. :type coord_new: np.ndarray :param radius_new: Radius of the new particle. :type radius_new: float :returns: Maximum overlap fraction found between the new particle and any particle in the aggregate. Returns 0.0 if no overlap. :rtype: float .. py:function:: calculate_max_overlap_pca_fast(coords_agg, radii_agg, coord_new, radius_new, tolerance = 1e-06) Calculate max overlap with early termination (optimized for speed). This optimized version includes: 1. Early termination: Returns immediately when overlap exceeds tolerance 2. Bounding sphere pre-check: Avoids sqrt for particles far apart 3. Sequential execution: Trades parallelization for early exit Overlap is defined as `1 - distance / (radius_new + radius_agg)`. Performance: ~2-3x faster than parallel version when overlap is found early. :param coords_agg: Nx3 coordinates of the existing aggregate. :type coords_agg: np.ndarray :param radii_agg: N radii of the aggregate particles. :type radii_agg: np.ndarray :param coord_new: 3D coordinates of the new particle. :type coord_new: np.ndarray :param radius_new: Radius of the new particle. :type radius_new: float :param tolerance: Overlap tolerance threshold for early termination (default: 1e-6). :type tolerance: float, optional :returns: Maximum overlap fraction found. Returns immediately if overlap > tolerance. :rtype: float .. py:function:: calculate_max_overlap_cca_fast(coords1, radii1, coords2, radii2, tolerance = 1e-06) Calculate max overlap between clusters with early termination (optimized). This optimized version includes: 1. Early termination: Returns immediately when overlap exceeds tolerance 2. Bounding sphere pre-check: Avoids sqrt for particles far apart 3. Sequential execution: Trades parallelization for early exit Overlap is defined as `1 - distance / (radius1 + radius2)`. Performance: ~2-3x faster than parallel version when overlap is found early. :param coords1: Nx3 coordinates of cluster 1. :type coords1: np.ndarray :param radii1: N radii of cluster 1. :type radii1: np.ndarray :param coords2: Mx3 coordinates of cluster 2. :type coords2: np.ndarray :param radii2: M radii of cluster 2. :type radii2: np.ndarray :param tolerance: Overlap tolerance threshold for early termination (default: 1e-6). :type tolerance: float, optional :returns: Maximum overlap fraction found. Returns immediately if overlap > tolerance. :rtype: float .. py:function:: calculate_max_overlap_pca_parallel(coords_agg, radii_agg, coord_new, radius_new) Calculate max overlap for PCA with parallel execution (no early termination). This version uses Numba prange to parallelize overlap checks across all aggregate particles. Trade-off: No early termination, but faster for large N. Use for n_agg > PARALLEL_OVERLAP_THRESHOLD (~200 particles). :param coords_agg: Current aggregate coordinates (n_agg, 3) :type coords_agg: np.ndarray :param radii_agg: Current aggregate radii (n_agg,) :type radii_agg: np.ndarray :param coord_new: New particle coordinates (3,) :type coord_new: np.ndarray :param radius_new: New particle radius :type radius_new: float :returns: Maximum overlap fraction found across all particles :rtype: float .. py:function:: calculate_max_overlap_cca_parallel(coords1, radii1, coords2, radii2) Calculate max overlap for CCA with parallel execution (no early termination). This version uses Numba prange to parallelize overlap checks. Computes all pair overlaps in parallel. Use for n1 * n2 > PARALLEL_OVERLAP_THRESHOLD (~200 pairs). :param coords1: Cluster 1 coordinates (n1, 3) :type coords1: np.ndarray :param radii1: Cluster 1 radii (n1,) :type radii1: np.ndarray :param coords2: Cluster 2 coordinates (n2, 3) :type coords2: np.ndarray :param radii2: Cluster 2 radii (n2,) :type radii2: np.ndarray :returns: Maximum overlap fraction found across all particle pairs :rtype: float .. py:function:: calculate_max_overlap_pca_auto(coords_agg, radii_agg, coord_new, radius_new, tolerance = 1e-06) Auto-dispatch to parallel or sequential overlap check based on size. For large aggregates (n > PARALLEL_OVERLAP_THRESHOLD), uses parallel version without early termination. For small aggregates, uses sequential with early exit. :param coords_agg: Current aggregate coordinates (n_agg, 3) :type coords_agg: np.ndarray :param radii_agg: Current aggregate radii (n_agg,) :type radii_agg: np.ndarray :param coord_new: New particle coordinates (3,) :type coord_new: np.ndarray :param radius_new: New particle radius :type radius_new: float :param tolerance: Overlap tolerance for early termination (default: 1e-6) :type tolerance: float, optional :returns: Maximum overlap fraction :rtype: float .. py:function:: calculate_max_overlap_cca_auto(coords1, radii1, coords2, radii2, tolerance = 1e-06) Check max overlap between two clusters during CCA sticking. FIX (PyFracVAL-xwx): Always use the sequential early-termination path. The previous parallel dispatch was counterproductive for CCA: in sticking, clusters are placed touching (high overlap probability), so early termination fires almost immediately. The parallel path computes ALL n1*n2 pairs even when the first pair already overlaps, making it 78x slower for large clusters. Benchmark (n1=n2=256, 65536 pairs): parallel=109µs, fast=1.4µs. :param coords1: Cluster 1 coordinates (n1, 3) :type coords1: np.ndarray :param radii1: Cluster 1 radii (n1,) :type radii1: np.ndarray :param coords2: Cluster 2 coordinates (n2, 3) :type coords2: np.ndarray :param radii2: Cluster 2 radii (n2,) :type radii2: np.ndarray :param tolerance: Overlap tolerance for early termination (default: 1e-6) :type tolerance: float, optional :returns: Maximum overlap fraction :rtype: float