Skip to content

fix(mass): convergence_func on PowerLawBroken, PowerLawMultipole, cNFW family#467

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/convergence-func-audit
May 29, 2026
Merged

fix(mass): convergence_func on PowerLawBroken, PowerLawMultipole, cNFW family#467
Jammy2211 merged 1 commit into
mainfrom
feature/convergence-func-audit

Conversation

@Jammy2211
Copy link
Copy Markdown
Collaborator

Summary

Follow-up to #466, which added convergence_func to the dPIE family. A planning-time audit flagged ~12 more profiles; on inspection most already inherit a working convergence_func (DevVaucouleurs, Exponential, GaussianGradient, SersicGradient, the NFW MCR variants). Three families genuinely lacked it and are reachable via radial mass integration (mass_integralmass_angular_within_circle_from → Einstein radius) and/or MGE three_D=False potential decomposition, where the abstract convergence_func raised NotImplementedError:

  • PowerLawBroken(+Sph) — extracted a _convergence radial helper shared by convergence_2d_from and a new convergence_func.
  • PowerLawMultipoleconvergence_func returns the zero monopole (a pure multipole encloses zero net azimuthally-averaged mass).
  • cNFW family (cNFW, cNFWSph, cNFWMCRScatterLudlow(Sph), cNFWMCRLudlow(Sph)) — convergence_func reuses the MGE-of-3D-density decomposition radially; q-independent like NFW.convergence_func.

Separately, PowerLawBroken.potential_2d_from now raises a clear NotImplementedError. Its MGE potential decomposition integrates the convergence along a complex contour, which requires an analytic convergence; the broken power law's convergence is piecewise (kink at break_radius) so the result was numerically invalid (~1e7). It already raised NotImplementedError before this PR (via the missing convergence_func); this makes the failure explicit and documented. Convergence, deflections, convergence_func, and the Einstein-radius / enclosed-mass integrals remain correct.

API Changes

Added convergence_func overrides on PowerLawBroken, PowerLawBrokenSph (inherited), PowerLawMultipole, and the cNFW family (cNFWSph + MCR variants inherit). PowerLawBroken._convergence is a new private radial helper. PowerLawBroken.potential_2d_from now raises NotImplementedError explicitly (it was already non-functional). No signatures of existing public methods changed. See full details below.

Test Plan

  • python -m pytest test_autogalaxy/profiles/mass/ — 413 passed
  • New regression tests in test_power_law_broken.py, test_power_law_multipole.py, test_cnfw.py (convergence_func matches radial helper / zero monopole / q-independence; mass integral runs; potential raises)
  • End-to-end via autolens_workspace_test/scripts/mass/{total,dark}.py: convergence_func enclosed-mass cross-check (mass_angular = πR·α) PASS for PowerLawBrokenSph (rel 1.7e-11), cNFWSph (rel 1.5e-4), PowerLawMultipole (0); cNFW/cNFWSph self-consistency all PASS
Full API Changes (for automation & release notes)

Added

  • PowerLawBroken.convergence_func(grid_radius, xp=np) — radial κ(r); inherited by PowerLawBrokenSph
  • PowerLawBroken._convergence(radii, xp=np) — private radial helper shared with convergence_2d_from
  • PowerLawMultipole.convergence_func(grid_radius, xp=np) — returns zero (zero monopole of a pure multipole)
  • cNFW.convergence_func(grid_radius, xp=np) — MGE-of-3D-density radial convergence; inherited by cNFWSph, cNFWMCRScatterLudlow(Sph), cNFWMCRLudlow(Sph)

Changed Behaviour

  • PowerLawBroken.potential_2d_from / PowerLawBrokenSph now raise NotImplementedError with an explanatory message (the MGE potential is numerically invalid for the profile's piecewise convergence). Convergence, deflections, and Einstein-radius integrals are unaffected.

🤖 Generated with Claude Code

…W family

Follow-up to #466 (dPIE convergence_func). Adds the abstract convergence_func
hook to the three mass-profile families that define convergence_2d_from but
never overrode convergence_func, so radial mass integration (mass_integral ->
mass_angular_within_circle_from -> Einstein radius) and MGE three_D=False
potential decomposition no longer raise NotImplementedError. PowerLawBroken's
MGE potential is incompatible with its piecewise convergence, so
potential_2d_from now raises an explanatory NotImplementedError.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Jammy2211
Copy link
Copy Markdown
Collaborator Author

Workspace PR: PyAutoLabs/autolens_workspace_test#136

@Jammy2211 Jammy2211 merged commit 6d55bd0 into main May 29, 2026
6 checks passed
@Jammy2211 Jammy2211 deleted the feature/convergence-func-audit branch May 29, 2026 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pending-release PR queued for the next release build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant