Skip to main content

PyVista and CoDimensional

pyvista-modflow

Read MODFLOW-USG unstructured grids into PyVista as exact, flat-layered volumes.

PyPI CI MIT license

Built and maintained by CoDimensional PBC.

The three layers of the Freyberg MODFLOW-USG model pulled apart, colored by elevation, showing quadtree refinement along the river and the stepped tops of the cells

FloPy's Freyberg MODFLOW-USG model, layers pulled apart, 60× vertical exaggeration (scripts/render_readme.py).

Install

pip install pyvista-modflow

It depends only on NumPy and PyVista (0.49 or later, with VTK 9.4 or later), and it registers itself as the PyVista reader for .dis and .disu files.

Quickstart

import pyvista as pv

grid = pv.read('model.disu')  # finds model.gsf or model.shp beside it
grid = pv.read('model.disu', footprints='cells.shp')  # or name the outlines
grid.plot(show_edges=True)  # colored by layer

pyvista_modflow.read(...) takes the same arguments. The grid carries two cell arrays: layer, and node, the 1-based MODFLOW node number. Use node to attach heads or any other per-node result:

import numpy as np

heads = np.loadtxt('heads.txt')  # one value per MODFLOW node, from any post-processor
grid.cell_data['head'] = heads[grid.cell_data['node'] - 1]

Command line

Installing the package also lets the pyvista command read DISU files. The footprint file must sit beside the DISU with the same name (model.gsf or model.shp).

pyvista convert model.disu model.vtu  # one model
pyvista convert "*.disu" .vtu         # every model in the folder
pyvista plot model.disu

Recipes

Aquifers are thin, so exaggerate z before looking at them:

grid.scale([1, 1, 20]).plot(scalars='head', show_edges=True)

One layer, a cross-section, or a cutaway of whole cells:

layer2 = grid.threshold([2, 2], scalars='layer')
section = grid.slice(normal='y')
cutaway = grid.clip(normal='x', crinkle=True)

Save it for ParaView or any other VTK reader:

grid.save('model.vtu')

Background

A MODFLOW-USG DISU file holds each cell's top, bottom and area, but no x or y coordinates. The cell outlines come from a sidecar file, and the usual conversions build the cells from that sidecar's vertices. Those vertices are shared between neighboring cells and carry a single z, so every cell is bent to follow an interpolated surface instead of its own flat top and bottom.

This reader takes each cell's outline from the sidecar and its elevations from the DISU, so every cell is a flat-topped prism. Neighboring columns break at different elevations, so the reader splits every side wall wherever a neighbor's top or bottom meets it, and inserts the extra corner a refined (quadtree or nested) neighbor puts part way along a coarse cell's edge. A wall shared by two cells is the same face in both, so the surface PyVista extracts has no interior walls. Tops and bottoms are not split the same way: where a layer is refined differently from the one above it, the coarse cell's top and the fine cells' bottoms touch without sharing faces.

Inputs

File Holds
DISU (.dis, .disu) Nodes per layer and every node's TOP, BOT and AREA. INTERNAL, CONSTANT, OPEN/CLOSE, free and fixed-width Fortran formats are read.
GSF (.gsf) One outline per node. Vertex z is ignored.
Polygon shapefile (.shp with .shx, .dbf, optional .prj) One layer's outlines, numbered 1 .. n by a whole-number ID field (id_field=), reused by every layer of a layered (IVSD = -1) DISU. The .prj is kept as crs_wkt field data.

Each outline's area is checked against the DISU AREA, which catches outlines matched to the wrong nodes; area_rtol=None skips it. A node whose TOP is not above its BOT has no volume and is skipped with a warning, and the node cell array maps every cell back to its MODFLOW node.

MODFLOW 6 (DISV, DISU, binary grid files) and structured DIS files are not read yet.

Development

just sync   # uv sync with the dev group
just test   # pytest
just lint   # pre-commit on every file
just figure # re-render the figure above

The test models in tests/data/ come from FloPy (public domain, CC0); see tests/data/README.md.

Metadata

Release files for pyvista-modflow 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyvista-modflow 0.1.0
File Size Uploaded Provenance Actions
pyvista_modflow-0.1.0.tar.gz 1.0 MB With provenance Details for pyvista_modflow-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pyvista-modflow 0.1.0
File Interpreter ABI Platform Actions
pyvista_modflow-0.1.0-py3-none-any.whl Python 3 none any Details for pyvista_modflow-0.1.0-py3-none-any.whl

Total release size: 1.1 MB

Release files / pyvista_modflow-0.1.0.tar.gz

Download URL pyvista_modflow-0.1.0.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
fc4cbf30442853884ace7379790f8f9563091d2544bbca5d33b1f496f10b40ab
BLAKE2b-256 checksum
How to use checksums
95be22297cfc0ce914a4d96e658e0432047d12d3322e5548a1efed47c6489eaf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Release files / pyvista_modflow-0.1.0-py3-none-any.whl

Download URL pyvista_modflow-0.1.0-py3-none-any.whl
Size 20.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9bea28ad7d19c91220e80fa7fc669a74adbcfd2b4c775677e1923afc9674cf9a
BLAKE2b-256 checksum
How to use checksums
b04b603f63d807ec5c3d802203a7edcd3496970bd6ead5fdb3af6ead93d3630b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Security for pyvista-modflow 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pyvista_modflow-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page