Skip to content

Comments

fix: #1087 - [M5-P1] Fix NaN kernel for monodisperse particles#1090

Open
Gorkowski wants to merge 1 commit intouncscode:mainfrom
Gorkowski:issue-1087-adw-7ef9668e
Open

fix: #1087 - [M5-P1] Fix NaN kernel for monodisperse particles#1090
Gorkowski wants to merge 1 commit intouncscode:mainfrom
Gorkowski:issue-1087-adw-7ef9668e

Conversation

@Gorkowski
Copy link
Collaborator

Target Branch: main

Fixes #1087 | Workflow: 7ef9668e

Summary

Prevents NaNs in the charged coagulation kernel when kinetic enhancement collapses for same-sign monodisperse particles. Adds regression coverage to ensure repulsive pairs drive the kernel to zero while mixed/attractive cases stay finite and the particle-resolved step completes.

What Changed

New Components

  • particula/dynamics/coagulation/tests/charged_kernel_bugs_test.py - Regression tests covering monodisperse same/opposite-sign kernels, mixed-charge matrix finiteness, kinetic limit extreme case, and particle-resolved step behavior.

Modified Components

  • particula/particles/properties/diffusive_knudsen_module.py - Added KINETIC_ENHANCE_MIN guard and safe divide to avoid near-zero kinetic enhancement producing NaN/Inf; documented root cause inline.
  • particula/particles/properties/tests/diffusive_knudsen_test.py - Added regression asserting extreme negative potentials stay finite and near zero.
  • particula/dynamics/condensation/tests/staggered_stability_test.py - Minor cleanup (remove stray blank line).

Tests Added/Updated

  • charged_kernel_bugs_test.py - Monodisperse opposite/same-sign, mixed-charge kernel finiteness, kinetic limit extreme negative, particle-resolved step crash/zero-merger checks.
  • diffusive_knudsen_test.py - Near-zero kinetic enhancement guard regression.

How It Works

  • Introduces KINETIC_ENHANCE_MIN = 1e-80 and uses np.divide(..., where=kinetic_enhance >= threshold, out=inf) so repulsive same-sign interactions yield an infinite denominator, driving the diffusive Knudsen number (and kernel) toward zero instead of NaN.
  • Inline comment links the guard to the Coulomb enhancement call chain for traceability (issue [M5-P1] Fix NaN kernel for monodisperse particles #1087).
  • Regression tests cover kernel generation across models and the particle-resolved step to ensure no ValueError/NaN paths remain.

Implementation Notes

  • Threshold chosen to be far below physical values while preventing divide-by-zero warnings under -Werror.
  • Safety net stays localized; attractive/mixed interactions are untouched because their kinetic enhancement remains above the threshold.

Testing

  • Workflow tests (patch pipeline): pytest (includes new/updated cases).

Add a safe divide in get_diffusive_knudsen_number to avoid
near-zero kinetic enhancement causing inf/NaN, using an explicit
threshold and documenting the same-sign repulsion path.

Add regression coverage for monodisperse same-sign kernels, opposite-
sign finiteness, full kernel matrix finiteness across implementations,
particle-resolved step behavior, and extreme negative kinetic limits.

Closes uncscode#1087

ADW-ID: 7ef9668e
Copilot AI review requested due to automatic review settings February 23, 2026 15:59
@Gorkowski Gorkowski added agent Created or managed by ADW automation blocked Blocked - review required before ADW can process labels Feb 23, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a critical bug in the charged coagulation kernel where monodisperse same-sign particles produced NaN values, causing crashes in the particle-resolved coagulation step. The fix introduces a numerical guard that prevents division by near-zero kinetic enhancement values, correctly driving the kernel to zero for strongly repulsive same-sign interactions.

Changes:

  • Added KINETIC_ENHANCE_MIN guard constant and safe division logic in diffusive_knudsen_module.py to prevent NaN propagation when kinetic enhancement approaches zero for extreme repulsive potentials
  • Created comprehensive regression test suite in charged_kernel_bugs_test.py covering monodisperse cases, mixed charges, multiple kernel models, and particle-resolved step behavior
  • Added unit test for the guard in diffusive_knudsen_test.py to verify extreme negative potentials yield finite near-zero values

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
particula/particles/properties/diffusive_knudsen_module.py Added KINETIC_ENHANCE_MIN = 1e-80 constant and guard using np.divide with where= to set denominator to infinity when kinetic enhancement is below threshold, preventing NaN from division by near-zero
particula/particles/properties/tests/diffusive_knudsen_test.py Added test_near_zero_kinetic_enhancement_guard to verify extreme negative potentials (phi=-200) produce finite near-zero results instead of NaN
particula/dynamics/coagulation/tests/charged_kernel_bugs_test.py New file with 6 regression tests covering monodisperse opposite/same-sign cases, parametrized kernel function tests across 5 models, kinetic limit extremes, and particle-resolved step crash/zero-merger scenarios
particula/dynamics/condensation/tests/staggered_stability_test.py Removed extraneous blank line between imports (style cleanup)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

)
denominator = sum_of_radii * continuum_enhance / kinetic_enhance
# Guard for same-sign repulsion; see coulomb_enhancement.py:83-97 and
# diffusive_knudsen_module.py:119-126 (issue #1087).
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The line reference "diffusive_knudsen_module.py:119-126" in the comment appears to point to lines that include the numerator calculation and comment start. Consider updating to reference lines 113-119 (where kinetic_enhance is computed from coulomb_potential_ratio) for better accuracy and traceability.

Suggested change
# diffusive_knudsen_module.py:119-126 (issue #1087).
# diffusive_knudsen_module.py:113-119 (issue #1087).

Copilot uses AI. Check for mistakes.
from particula.util.reduced_quantity import get_reduced_self_broadcast
from particula.util.validate_inputs import validate_inputs

KINETIC_ENHANCE_MIN = 1e-80
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a brief inline comment explaining the threshold choice, e.g., "Threshold prevents NaN/Inf from exp(phi) ≈ 0 when phi < -184 (extreme same-sign repulsion)". This would improve code maintainability by documenting the physical reasoning behind the constant value.

Suggested change
KINETIC_ENHANCE_MIN = 1e-80
KINETIC_ENHANCE_MIN = 1e-80 # Minimum kinetic enhancement to avoid underflow/NaN when exp(phi) → 0 for extreme same-sign repulsion

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Created or managed by ADW automation blocked Blocked - review required before ADW can process

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[M5-P1] Fix NaN kernel for monodisperse particles

1 participant