feat(Mf6Splitter): split structured models into DISV models - #2820
feat(Mf6Splitter): split structured models into DISV models#2820jdhughes-dev wants to merge 3 commits into
Conversation
split_model() and split_multi_model() take to_disv, which writes DISV models from a structured model instead of the structured bounding box of each part. A DISV model carries only the cells assigned to it, and stacks of cells that are inactive in every layer are excluded, so a model no longer pads out to a bounding box full of inactive cells. to_disv is ignored with a warning for a DISV model and is an error for a DISU model. The grid of a model is built one model at a time from the new StructuredGrid.get_cell_iverts(), so peak memory scales with the largest part rather than with the parent grid. save_node_mapping() records the grid type of the split models so a structured to DISV mapping round trips. Closes modflowpy#2816
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #2820 +/- ##
===========================================
+ Coverage 55.5% 73.4% +17.9%
===========================================
Files 644 659 +15
Lines 124135 132344 +8209
===========================================
+ Hits 68947 97239 +28292
+ Misses 55188 35105 -20083
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR enhances Mf6Splitter to optionally convert structured (DIS) models into DISV (vertex) models during splitting, so each split model contains only its assigned active cells (excluding cell stacks inactive in every layer) while preserving the ability to reconstruct outputs and round-trip saved node mappings.
Changes:
- Add
to_disvoption tosplit_model()andsplit_multi_model()to write DISV models when splitting a structured model, with validation/warnings for incompatible grid types. - Add
StructuredGrid.get_cell_iverts()and use it to build DISVvertices/cell2dper split model with reduced peak memory usage. - Extend node-mapping save/load to record
new_grid_type, and add new automated tests for structured→DISV splitting, idomain handling, geometry, and reconstruction.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| flopy/mf6/utils/model_splitter.py | Implements to_disv workflow, DIS→DISV remapping, grid-type persistence in node maps, and related reconstruction adjustments. |
| flopy/discretization/structuredgrid.py | Adds StructuredGrid.get_cell_iverts() and reuses it for structured iverts generation. |
| autotest/test_model_splitter.py | Adds coverage for structured→DISV splitting behavior, idomain exclusion rules, reconstruction, geometry, and save/load mapping. |
| autotest/test_grid.py | Adds unit test coverage for StructuredGrid.get_cell_iverts(). |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if nodes is None: | ||
| nodes = np.arange(self.ncpl, dtype=int) | ||
| else: | ||
| nodes = np.atleast_1d(nodes) | ||
|
|
There was a problem hiding this comment.
Fixed in e98301e. nodes is now np.ravel(np.asarray(nodes, dtype=int)), which handles an array of any shape and coerces floats. The ravel returns a view and asarray() is a no-op for an int array, so the node array is not copied on the path that matters, where get_cell_iverts() is called once per split model. The (n, 1) and ndarray cases were added to test_get_cell_iverts.
np.atleast_1d() left a node array with a trailing dimension, for example shape (n, 1), two dimensional, and the vertex arithmetic then failed to broadcast into the one dimensional result rows. Ravel the node numbers and coerce them to int so an array of any shape works as documented. The ravel is a view and asarray() is a no-op for an int array, so the array is not copied.
switch_models() already updates the modelgrid, so caching a second copy of its grid type is redundant and goes stale when the model is switched. Read self._modelgrid.grid_type where the grid type of the parent model is needed, and leave switch_models() alone. Also cover reconstruct_recarray() for a vertex model, which had no test.
split_model()andsplit_multi_model()taketo_disv, which writes DISV models from astructured model instead of the structured bounding box of each part
every layer are excluded
to_disvis ignored with a warning for a DISV model and is an error for a DISU modelStructuredGrid.get_cell_iverts(); each model grid is built from it one model at a time,so peak memory scales with the largest part rather than with the parent grid
save_node_mapping()records the grid type of the split models so a structured to DISV mappinground trips
Closes #2816