Insert essential boundary values in the rotated solve's field copy-back - #500
Open
lmoresi wants to merge 1 commit into
Open
Insert essential boundary values in the rotated solve's field copy-back#500lmoresi wants to merge 1 commit into
lmoresi wants to merge 1 commit into
Conversation
Essential-BC DOFs are absent from the global vector, so the rotated path's per-field globalToLocal scatter left them at ZERO in the output fields wherever the Dirichlet datum was non-zero. The solve itself was always right -- the residual path inserts the values internally -- but every field-based diagnostic (projection, Integral, evaluate, renders) read a garbage boundary strip. Measured: far-field sigma_xy of 0.79 for a true 1.00, and a projected stress row off by 3x one fault length out. Invisible to every earlier rotated test because their Dirichlet walls were homogeneous: zero was accidentally the datum. Fix: petsc_dm_insert_boundary_values in cython/petsc_discretisation.pyx -- wrapping DMPlexInsertBoundaryValues, which petsc4py does not expose; the same insertion the consistent-boundary-flux paths already use (issues #407/#411) -- called per field after the scatter in _finalize_rotated_solution. The regression test drives an inhomogeneous lid with rotated free-slip sides and asserts the FIELD carries the wall values. The tell that found it: the divergence theorem, Integral(2 e_xy) against its own boundary term. The rotated boundary's prescribed datum and the sigma_nn reaction recovery were never affected (both live in the global vector). Fixes #497. Underworld development team with AI support from Claude Code Claude-Session: https://claude.ai/code/session_01WDKP73LD3dCFQSNgEXbbw9
Member
Author
|
Adversarial self-review, scope and hazards:
Underworld development team with AI support from Claude Code |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a rotated free-slip solve copy-back defect where inhomogeneous essential (Dirichlet) boundary values were missing from the per-field local vectors after scattering from the composite global solution, leading to incorrect field-based diagnostics near Dirichlet boundaries.
Changes:
- Adds a Cython shim
petsc_dm_insert_boundary_values()wrappingDMPlexInsertBoundaryValues()(not exposed by petsc4py) to insert essential BC values into local vectors. - Updates the rotated solve finalization to call this insertion after the global-to-local scatter for each field.
- Adds a regression test ensuring inhomogeneous Dirichlet wall values are preserved in the output field after a rotated solve.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/test_1018_rotated_freeslip.py | Adds a regression test that fails if rotated copy-back drops inhomogeneous Dirichlet values. |
| src/underworld3/utilities/rotated_bc.py | Inserts essential BC values into each field local vector after scatter in _finalize_rotated_solution. |
| src/underworld3/cython/petsc_discretisation.pyx | Introduces petsc_dm_insert_boundary_values() as a Python-level wrapper around DMPlexInsertBoundaryValues. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+395
to
+396
| from underworld3.cython.petsc_discretisation import \ | ||
| petsc_dm_insert_boundary_values |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #497.
Essential-BC DOFs are absent from the global vector, so the rotated path's per-field
globalToLocalscatter left them at zero in the output fields wherever the Dirichlet datum was non-zero. The solve itself was always correct — the residual path inserts the values internally — but every field-based diagnostic (projection,uw.maths.Integral,uw.function.evaluate, renders) read a garbage boundary strip. Measured on the split-node fault study: far-field sigma_xy of 0.79 for a true 1.00, and a projected stress row off by 3x one fault length out. Every existing rotated test used homogeneous Dirichlet on the other walls, so zero was accidentally the right value — which is how this survived.Fix:
petsc_dm_insert_boundary_valuesincython/petsc_discretisation.pyx— wrappingDMPlexInsertBoundaryValues, which petsc4py does not expose; the same insertion the consistent-boundary-flux paths already use internally (cf. #407/#411) — called per field after the scatter in_finalize_rotated_solution.Not affected (both live in the global vector): the rotated boundary's own prescribed datum (
add_rotated_freeslip_bc(conds != 0, ...), the free-surface path), and the sigma_nn / dynamic-topography reaction recovery.Regression test:
test_rotated_solve_fields_carry_inhomogeneous_dirichlet_wallsintests/test_1018_rotated_freeslip.py— an inhomogeneous lid with rotated free-slip sides, asserting the FIELD carries the wall values; it fails without the fix. The change is a verbatim cherry-pick of 08f8603 fromfeature/fault-split-node, where the full rotated suite (19 tests) and the fault-contact suites run green with it.The tell that found it, for the record: the divergence theorem —
Integral(2 e_xy) dAagainst its own boundary term.Underworld development team with AI support from Claude Code