Skip to content

Unify mesh integration and add grouped moment quadrature#1770

Open
peterdsharpe wants to merge 4 commits into
NVIDIA:mainfrom
peterdsharpe:psharpe/mesh-integration-reductions
Open

Unify mesh integration and add grouped moment quadrature#1770
peterdsharpe wants to merge 4 commits into
NVIDIA:mainfrom
peterdsharpe:psharpe/mesh-integration-reductions

Conversation

@peterdsharpe

@peterdsharpe peterdsharpe commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

This makes integrate() the main entry point for both cell-centered (P0) and point-centered (P1) field integration. The existing integrate_cell_data() and integrate_point_data() functions remain available as deprecated compatibility wrappers, so current imports keep working while users migrate.

It adds an explicit nan_policy to integrate(), integrate_flux(), and the new integrate_moment(); the existing Mesh methods forward the policy where applicable. The default, "omit", preserves the current masked-data behavior, while "propagate" keeps NaNs visible in the result.

integrate_moment() computes measure-weighted outer-product moments with support for named cell fields, aligned group dimensions, configurable accumulation precision, and gradients without materializing an outer product for every cell.

Testing

Tests cover compatibility warnings, both NaN policies, grouped moment shapes, dtype handling, validation, gradients, and Mesh method forwarding.

physicsnemo/mesh/calculus/integration.py makes integrate() the single public entry point for ordinary P0 cell and P1 point field integration, keeping the location-specific implementations private. A shared nan_policy now gives integrate() and integrate_flux() explicit omit or propagate behavior instead of hard-coded NaN reduction.

The same module adds integrate_moment() for measure-weighted outer-product moments. It supports aligned group axes, named cell fields, configurable accumulation precision, validation, and a batched matrix-product implementation that avoids materializing one outer product per cell.

physicsnemo/mesh/calculus/__init__.py removes the redundant point and cell integration exports and exposes integrate_moment alongside integrate and integrate_flux. physicsnemo/mesh/mesh.py forwards nan_policy through the existing integrate and integrate_flux convenience methods while leaving the more specialized moment operation functional-only.

test/mesh/calculus/test_integration.py routes ordinary quadrature coverage through integrate() and adds tests for NaN policies, grouped moment shapes, named fields, reduced-precision accumulation, FP64 preservation, gradients, validation, and flux forwarding.

The result is a smaller and more consistent public API plus a reusable numerical reduction for mesh statistics, weak forms, and learned or classical integral operators.
@copy-pr-bot

copy-pr-bot Bot commented Jul 1, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@peterdsharpe peterdsharpe requested a review from ktangsali July 1, 2026 02:18
@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR unifies the mesh integration API by making integrate() the single public entry point for P0/P1 quadrature (renaming the old per-location helpers to private), adds a configurable nan_policy to all integration functions, and introduces integrate_moment() for batched, measure-weighted outer-product moments via a grouped BMM kernel that avoids materialising per-cell outer products.

  • integrate_cell_data and integrate_point_data are removed from the public exports in __init__.py; any downstream code importing them directly will break with no deprecation notice or migration path.
  • integrate_moment is added to the public API and its _integrate_weighted_moment core function is carefully guarded for torch compiler compatibility, but nan_policy validation sits outside the is_compiling guard unlike all other checks in the same function.
  • The new Mesh.integrate_moment instance method is absent, breaking the ergonomic pattern established by the other integration methods.

Important Files Changed

Filename Overview
physicsnemo/mesh/calculus/init.py Removes previously-exported integrate_cell_data and integrate_point_data from the public API and adds integrate_moment; this is a breaking change for downstream code importing those names directly.
physicsnemo/mesh/calculus/integration.py Renames cell/point integrators to private, adds nan_policy parameter to all public functions, and introduces integrate_moment / _integrate_weighted_moment; logic is sound but nan_policy validation sits outside the compiler guard in _integrate_weighted_moment and validation is duplicated between the public and private functions.
physicsnemo/mesh/mesh.py Adds nan_policy keyword-only parameter to Mesh.integrate and Mesh.integrate_flux and forwards it correctly; no Mesh.integrate_moment method is added, which breaks the ergonomic pattern of the other methods.
test/mesh/calculus/test_integration.py Updates existing tests to use unified integrate() API, adds thorough TestIntegrateMoment suite and NaN-policy tests; missing an invalid nan_policy test case for integrate_moment.

Comments Outside Diff (2)

  1. physicsnemo/mesh/calculus/__init__.py, line 8-13 (link)

    P1 Breaking public API removal

    integrate_cell_data and integrate_point_data were previously exported from physicsnemo.mesh.calculus (they appear in the removed lines of this __init__.py). Any downstream code doing from physicsnemo.mesh.calculus import integrate_cell_data will now get an ImportError. The CHANGELOG checklist item is unchecked and the PR description does not mention a deprecation cycle or version bump, so users upgrading will encounter silent breakage with no migration path.

  2. test/mesh/calculus/test_integration.py, line 672 (link)

    P2 Missing test_invalid_nan_policy for integrate_moment

    TestIntegrateCellFields and TestIntegrateFlux both have a test_invalid_nan_policy test that checks a ValueError is raised for an unrecognised nan_policy string. TestIntegrateMoment has no such test. The validation in _integrate_weighted_moment is deliberately outside the is_compiling guard, so a missing test leaves that path uncovered and makes it harder to catch regressions if the validation is ever moved.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (1): Last reviewed commit: "Unify mesh integration and add grouped m..." | Re-trigger Greptile

Comment thread physicsnemo/mesh/calculus/integration.py
Comment thread physicsnemo/mesh/calculus/integration.py
Comment thread physicsnemo/mesh/mesh.py
Keep integrate_cell_data and integrate_point_data available as warning-emitting wrappers around the unified integrate API, preserving the released import paths during a deprecation cycle. Re-export the aliases, document the migration in CHANGELOG.md, and cover compatibility warnings plus invalid integrate_moment nan policies.
@peterdsharpe

Copy link
Copy Markdown
Collaborator Author

/ok to test 844c030

@peterdsharpe

Copy link
Copy Markdown
Collaborator Author

/ok to test 0b9621d

accumulation_dtype: torch.dtype | None,
nan_policy: NanPolicy,
) -> torch.Tensor:
"""Core weighted grouped moment used by Mesh and streamed operators."""

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can we add docstrings for parameters?



class TestIntegrateCellData:
class TestIntegrateCellFields:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could you have parameterized cell vs. point using pytest parameterize?

return result_flat.reshape(result_shape)


def integrate_moment(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Does it make sense to expose it as Mesh.integrate_moment() as well? I believe currently Mesh.integrate() and Mesh.integrate_flux() exist, but not the moment one.

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.

2 participants