Repository navigation
Fix Exodus encode treating every face as full width - #1752
Merged
Merged
Conversation
`_encode_exodus` looked for padding with `row == -1`, but connectivity is padded with `INT_FILL_VALUE`. The match never fired, so every face was counted at the maximum width: a mixed mesh collapsed into a single block with the wrong element type, and the padding itself was written out as `INT_FILL_VALUE + 1` where a node index belongs. Match `INT_FILL_VALUE` instead. Blocks now split by face size, which is what Exodus requires -- element blocks are homogeneous -- so a mixed mesh is genuinely regrouped on write and reloads permuted. Two existing round-trip tests, `test_mixed_exodus` and `test_grid_ugrid_exodus_roundtrip`, compare the Exodus faces as a set for now; recording and restoring the original order is a separate fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jayeshkrishna
left a comment
There was a problem hiding this comment.
The change looks good. There are some suggestions on more test cases and modifying the comments/PR commit message,
The PR commit message could be changed to something like,
Exodus element blocks are homogeneous, so a mixed mesh has to be split by
face size (e.g. Mixed mesh containing TRI and SHELL elements are split
into two homogeneous blocks, the first block containing TRI elements and
the second block containing SHELL elements). In the face node connectivity
array the user specifies padding for shorter elements using a fillvalue.
This fillvalue is frequently specified by users as -1. However note that
this fillvalue/padding is internally stored as INT_FILL_VALUE in uxarray.
See PR #241 for details.
The _encode_exodus function was incorrectly finding the end of each face with
np.where(row == -1). The comparison never matches if the fillvalue is different
(or not specified by the user), so every face (including faces with padding) is counted at the maximum width of the connectivity array. Two things follow:
(1) a mixed mesh collapses into a single element block carrying the wrong
element type (e.g. triangles and quads all written as SHELL4)
(2) the padding itself is written out as INT_FILL_VALUE + 1 in a slot where
a node index belongs.
The fix matches node values to INT_FILL_VALUE to detect each face. Element
blocks are then split by face size, which is what Exodus requires (blocks are
homogeneous).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
@jayeshkrishna I'll use your commit message when I squash-merge it; otherwise it should be ready for another look. |
cmdupuis3
marked this pull request as ready for review
October 27, 2026 16:32
jayeshkrishna
approved these changes
Oct 27, 2026
dylannelson
approved these changes
Oct 28, 2026
dylannelson
left a comment
Member
There was a problem hiding this comment.
Confirmed the fix works as intended and that the followup work of reordering will be needed but since it's expected after this, we can proceed.
Was interesting seeing a node index return "-9223372036854775807", which is now fixed.
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.
Closes #1753
Overview
_encode_exodusfinds the end of each face withnp.where(row == -1), but connectivity padding is stored asINT_FILL_VALUE. The comparison never matches, so every face is counted at the maximum width. Two things follow: a mixed mesh collapses into a single element block carrying the wrong element type (triangles and quads all written asSHELL4), and the padding itself is written out asINT_FILL_VALUE + 1in a slot where a node index belongs.The fix matches
INT_FILL_VALUE. Element blocks then split by face size, which is what Exodus requires — blocks are homogeneous.One note for reviewers: because blocks now genuinely split, a mixed mesh is regrouped by face size on write, and nothing yet records that permutation, so the mesh reloads reordered. Two existing round-trip tests therefore compare the Exodus faces as a set in this PR instead of element-wise —
test_mixed_exodus(on themixed.exofixture) andtest_grid_ugrid_exodus_roundtrip(onoutRLL1deg, which has polar triangles among its quads). The follow-up (cmd/exodus_block_reorder) records the ordering and restores both strict comparisons. This PR is green on its own, but it does temporarily loosen those two assertions.PR Checklist
General
Testing & Benchmarking
Documentation and Examples
docs/api.rst; internal (private) function names start with an underscore (_)AI Disclosure
AI Usage: Claude Opus 5