Skip to content

Solver.poisson support pre-integrated vfuncs#115

Open
magnesium2400 wants to merge 1 commit intoDeep-MI:mainfrom
magnesium2400:integrate
Open

Solver.poisson support pre-integrated vfuncs#115
magnesium2400 wants to merge 1 commit intoDeep-MI:mainfrom
magnesium2400:integrate

Conversation

@magnesium2400
Copy link
Copy Markdown

  • Solver.poisson always multiplies the input vfunc h by self.mass to generate an integrated map
  • This creates difficulties when solving for different maps, where some are integrated, and some are not: a new Solver object has to be created and its mass set to the identity
  • It is easier to create a flag where the user can specify if the map is already integrated or not. This is what I have done here.
  • This also simplifies the code in diffgeo.compute_geodesic_f etc.
  • The default behaviour is preserved
  • The figures in Test_TriaMesh_Geodesics.ipynb still look good when vf = fem.poisson(Bi * divx) is replaced by vf = fem.poisson(divx, integrate=False)

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 8, 2026

Codecov Report

❌ Patch coverage is 88.88889% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 50.01%. Comparing base (dcacc4a) to head (0cd9031).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
lapy/diffgeo.py 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #115      +/-   ##
==========================================
- Coverage   50.04%   50.01%   -0.04%     
==========================================
  Files          15       15              
  Lines        3153     3151       -2     
  Branches      414      415       +1     
==========================================
- Hits         1578     1576       -2     
  Misses       1426     1426              
  Partials      149      149              
Flag Coverage Δ
unittests 50.01% <88.88%> (-0.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
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 adds an option to Solver.poisson to skip mass-matrix integration when the RHS is already pre-integrated, and updates differential-geometry helpers to use that option instead of mutating Solver.mass.

Changes:

  • Add integrate: bool = True to Solver.poisson to optionally bypass B*h integration.
  • Update diffgeo.compute_geodesic_f, tria_compute_geodesic_f, and tria_compute_rotated_f to call poisson(..., integrate=False) instead of replacing fem.mass with the identity.
  • Document the new flag in the poisson docstring.

Reviewed changes

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

File Description
lapy/solver.py Introduces integrate flag and conditional mass-matrix application when building the RHS.
lapy/diffgeo.py Switches geodesic/rotated-function routines to use integrate=False rather than altering solver state.

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

Comment on lines +812 to +816
integrate: bool, default=True
Whether to integrate the right hand side over the surface using
the mass matrix. If True, the right hand side is effectively
replaced by ``B h``. If False, the right hand side is used as is,
which corresponds to ``A x = h``.
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

The new parameter doc header uses integrate: bool but the rest of the docstring follows NumPy style (name : type). Also, integrate=False changes the equation being solved and skips mass-matrix scaling for the Neumann term as well (since b = h - nvec is no longer multiplied by B). Please adjust the docstring (including the earlier text that implies A x = B h) and clarify the expected ntup convention when integrate=False.

Copilot uses AI. Check for mistakes.
Comment on lines 912 to +915
# compute right hand side
mass = self.mass.astype(dtype, copy=False)
b = mass * (h - nvec)
b = h - nvec
if integrate:
b = self.mass.astype(dtype, copy=False) * b
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

The new integrate flag introduces a second execution path for RHS construction. Please add unit tests covering integrate=False (including at least one case with Dirichlet/Neumann terms if supported) and asserting it matches the previous workaround (e.g., setting mass to identity or pre-multiplying h appropriately), so behavior stays stable across refactors.

Copilot uses AI. Check for mistakes.
gradf = compute_gradient(geom, vfunc)
fem = Solver(geom, lump=True, use_cholmod=use_cholmod)
fem.mass = sparse.eye(fem.stiffness.shape[0], dtype=fem.stiffness.dtype)
# fem.mass = sparse.eye(fem.stiffness.shape[0], dtype=fem.stiffness.dtype)
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

There’s now commented-out dead code (# fem.mass = sparse.eye(...)). Since integrate=False is the intended mechanism, consider removing the commented assignment and leaving a short explanatory comment (e.g., that compute_divergence already returns an integrated divergence so Poisson should not re-apply B).

Suggested change
# fem.mass = sparse.eye(fem.stiffness.shape[0], dtype=fem.stiffness.dtype)
# compute_divergence already returns an integrated divergence, so Poisson
# should solve with integrate=False and must not re-apply the mass matrix.

Copilot uses AI. Check for mistakes.
Comment on lines 201 to +203
# div is the integrated divergence (so it is already B*div);
# pass identity instead of B here
fem.mass = sparse.eye(fem.stiffness.shape[0])
# fem.mass = sparse.eye(fem.stiffness.shape[0])
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

The comment here still describes the old workaround (“pass identity instead of B here”) and keeps the identity assignment commented out. Please update the comment to reflect the new approach (integrate=False) and remove the commented-out fem.mass = sparse.eye(...) line to avoid confusing future readers.

Copilot uses AI. Check for mistakes.
tn = tria.tria_normals()
fem = Solver(tria, lump=True, use_cholmod=use_cholmod)
fem.mass = sparse.eye(fem.stiffness.shape[0], dtype=vfunc.dtype)
# fem.mass = sparse.eye(fem.stiffness.shape[0], dtype=vfunc.dtype)
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

There’s leftover commented-out code (# fem.mass = sparse.eye(...)) from the pre-integrate workaround. Since this function now calls poisson(..., integrate=False), please remove the commented assignment and (if needed) replace it with a brief note explaining why integration is disabled here.

Suggested change
# fem.mass = sparse.eye(fem.stiffness.shape[0], dtype=vfunc.dtype)
# The divergence has already been assembled, so disable integration in the
# Poisson solve instead of using the old mass-matrix workaround.

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants