feat(gridgen): build GNC package input from gridgen output - #2789
feat(gridgen): build GNC package input from gridgen output#2789jdhughes-dev wants to merge 4 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #2789 +/- ##
==========================================
+ Coverage 55.5% 70.0% +14.5%
==========================================
Files 644 315 -329
Lines 124135 65915 -58220
==========================================
- Hits 68947 46205 -22742
+ Misses 55188 19710 -35478
🚀 New features to boost your workflow:
|
1a36867 to
4eeab30
Compare
Gridgen computes the ghost node data whenever it exports a grid and writes it to qtg.gnc.dat, but the file was not read, so the data it already had was not reaching the GNC Package. Gridgen now reads the file with get_gnc and converts it to MODFLOW 6 and MODFLOW-USG GNC Package input with get_gridprops_gnc6 and get_gridprops_gnc5. Two notebooks show the workflow, and the MODFLOW 6 notebook compares the corrected and uncorrected solutions against the exact solution for a confined homogeneous problem with a linear head field. Also corrects MfUsgGnc.write_file, which formatted the contributing factors with %10.2e and truncated them to three significant digits, wrote the options list with its Python repr, and wrote the record fields with no separator so that a value filling its width ran into the next value.
4eeab30 to
bfb655e
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds support for building Ghost Node Correction (GNC) package inputs directly from GRIDGEN output (qtg.gnc.dat) and improves MODFLOW-USG GNC/CLN-style list writing so free-format records remain tokenizable (URWORD-safe).
Changes:
- Added
Gridgen.get_gncand helpers to readqtg.gnc.datand convert it to MODFLOW 6 / MODFLOW-USG GNC package constructor inputs. - Added
get_gridprops_gnc5conversion utilities and exposed them viaflopy.utils. - Fixed MODFLOW-USG GNC writer output (options formatting + avoid truncating contributing factors) and fixed
fmt_stringto separate free-format fields with spaces.
Reviewed changes
Copilot reviewed 9 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| flopy/utils/gridgen.py | Adds GRIDGEN qtg.gnc.dat reader and Gridgen helpers to build MODFLOW 6/USG GNC gridprops. |
| flopy/utils/gnc.py | Extends utilities with MODFLOW-USG (get_gridprops_gnc5) conversion support. |
| flopy/utils/init.py | Re-exports get_gridprops_gnc5 from flopy.utils. |
| flopy/mfusg/mfusggnc.py | Fixes GNC package file writing (options keywords + higher-precision/free-format list output). |
| flopy/mfusg/mfusg.py | Fixes fmt_string so free-format lists are space-separated to keep fields readable by URWORD. |
| autotest/test_gridgen.py | Adds end-to-end and unit tests for reading GRIDGEN GNC output and building gridprops. |
| autotest/test_gnc.py | Adds tests to validate agreement between computed vs GRIDGEN GNC and validates output formatting behavior. |
| .docs/Notebooks/mfusg_gnc_example.py | New notebook example demonstrating MODFLOW-USG GNC workflow with GRIDGEN output. |
| .docs/Notebooks/gnc_example.py | New/updated notebook example demonstrating MODFLOW 6 GNC workflows including GRIDGEN route. |
| examples/data/mfusg_transport/Ex3_CLN_Conduit/Dispersion/Conduit_Dispersion_CLN.CBB | Adds/updates example dataset artifact used by documentation/examples. |
Suppressed comments (1)
autotest/test_gnc.py:485
- This assertion is duplicated (the exact same np.allclose(run(2), run(4), ...) check is performed twice). Remove the duplicate to avoid redundant solver runs and keep the test intent clear.
assert np.allclose(run(2), run(4), atol=1e-8)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @requires_exe("gridgen") | ||
| @requires_pkg("shapely", "geopandas") | ||
| @requires_exe("gridgen") | ||
| @requires_pkg("shapely", "geopandas") |
There was a problem hiding this comment.
Both removed. They are leftovers from splitting these tests across branches.
The second one is not a decorator. Line 485 repeated the assertion at the end of test_mfusg_gnc_padding:
assert np.allclose(run(2), run(4), atol=1e-8)
assert np.allclose(run(2), run(4), atol=1e-8)Each run() builds and runs a MODFLOW-USG model, so the test was doing four model runs where two are needed.
Swept the rest of the split files for the same kind of damage and found nothing else.
fmt_string joined the field formats with no separator regardless of the format of the list, so the fields of a free format list were held apart only by the padding in each format. A value that filled its width ran into the next value and the record could no longer be read with URWORD. Ten digit node numbers were enough to merge four fields of a gnc record into one token, and a free format CLN model was already writing output that only held together because of the field widths. The separator now follows the format of the list, the way MfList.fmt_string already does it: a space for free format, which URWORD reads, and nothing for fixed format, which is read by position. This replaces the sep argument added earlier in this branch, which put the choice on the caller instead of taking it from the format. Closes modflowpy#2788
959d731 to
e970cfc
Compare
Running the MODFLOW-USG transport tests writes model output into the example data directory, which left an untracked cbb file that was easy to commit by accident. Both cases of the extension are ignored because the tests write it in upper case. The cbb files already tracked as expected output are unaffected, since an ignore rule does not apply to a tracked file.
Splitting the tests across branches left a repeated requires_exe and requires_pkg pair on one test, and a repeated assertion on another. The repeated assertion ran the two MODFLOW-USG models a second time, so the test did four model runs where two were needed.
Added
Gridgen.get_gncto read the ghost node data gridgen writes toqtg.gnc.datAdded
Gridgen.get_gridprops_gnc6,Gridgen.get_gridprops_gnc5, andget_gridprops_gnc5to convert it to MODFLOW 6 and MODFLOW-USG GNC Package inputFixed
MfUsgGnc.write_file, which truncated the contributing factors to three significant digits and wrote the options list with its Python reprFixed
fmt_string, which joined the field formats with no separator regardless of the format of the list, so a value that filled its width ran into the next valueCloses bug: CLN package list output has no separator between fields #2788