Skip to content

feat(gnc): add ghost node correction data generation - #2787

Open
jdhughes-dev wants to merge 1 commit into
modflowpy:developfrom
jdhughes-dev:feat-gnc
Open

feat(gnc): add ghost node correction data generation#2787
jdhughes-dev wants to merge 1 commit into
modflowpy:developfrom
jdhughes-dev:feat-gnc

Conversation

@jdhughes-dev

@jdhughes-dev jdhughes-dev commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
  • Added flopy.utils.gnc to compute ghost node correction data from a model grid, a grid conforming array of refinement levels, and the grid connectivity
  • Added get_gridprops_gnc6 to convert the data to MODFLOW 6 GNC Package input
  • The computed data reproduces the ghost nodes gridgen writes to qtg.gnc.dat exactly, checked over five grid configurations

Base for #2789 and #2790, which build on this.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds first-class support in FloPy for generating Ghost Node Correction (GNC) package inputs for quadtree-like grids, either by reading GRIDGEN’s qtg.gnc.dat output or by computing equivalent GNC records directly from a model grid/connectivity. It also updates MODFLOW‑USG GNC file writing to avoid truncating contributing factors.

Changes:

  • Added flopy.utils.gnc to compute/check GNC records and convert them into MODFLOW 6 / MODFLOW‑USG package constructor dictionaries.
  • Extended Gridgen with get_gnc, get_gridprops_gnc6, and get_gridprops_gnc5 wrappers to consume GRIDGEN’s ghost node output.
  • Updated MfUsgGnc.write_file formatting behavior and added tests + notebooks demonstrating MF6 and MFUSG usage.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
flopy/utils/gridgen.py Adds GRIDGEN-side GNC readers and helpers to build MF6/MFUSG GNC package inputs.
flopy/utils/gnc.py New utility module to compute/check GNC records and build MF6/MFUSG constructor dictionaries.
flopy/utils/init.py Re-exports new GNC utilities at flopy.utils level.
flopy/mfusg/mfusggnc.py Adjusts USG GNC package writing (options serialization + higher precision formatting).
flopy/mfusg/init.py Removes duplicate MfUsgGnc export entry.
autotest/test_gridgen.py Adds integration tests validating GRIDGEN output reading and gridprops generation + round-trip.
autotest/test_gnc.py Adds unit/integration tests for computed GNC matching GRIDGEN and solver invariants (padding).
.docs/Notebooks/mfusg_gnc_example.py New MFUSG-focused notebook example for GRIDGEN-derived GNC.
.docs/Notebooks/gnc_example.py New MF6 notebook example for GRIDGEN-derived and computed GNC workflows.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread flopy/mfusg/mfusggnc.py Outdated
@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.90446% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.7%. Comparing base (556c088) to head (56416cb).
⚠️ Report is 182 commits behind head on develop.

Files with missing lines Patch % Lines
flopy/utils/gnc.py 94.8% 8 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #2787      +/-   ##
===========================================
+ Coverage     55.5%    72.7%   +17.1%     
===========================================
  Files          644      662      +18     
  Lines       124135   132609    +8474     
===========================================
+ Hits         68947    96422   +27475     
+ Misses       55188    36187   -19001     
Files with missing lines Coverage Δ
flopy/mfusg/__init__.py 100.0% <ø> (ø)
flopy/utils/__init__.py 100.0% <100.0%> (ø)
flopy/utils/gnc.py 94.8% <94.8%> (ø)

... and 579 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Ghost node correction data could not be built with FloPy, so the GNC Package
was difficult to use on a quadtree grid even though the correction is what
makes the control volume formulation accurate where a coarse cell meets a
finer one.

The new flopy.utils.gnc module computes the data from a model grid, a grid
conforming array of refinement levels, and the grid connectivity, and converts
it to MODFLOW 6 GNC Package input. Connectivity is taken from the grid when it
is not supplied, either from the iac and ja an unstructured grid carries or
from the cells that share an edge. Records with fewer contributing cells than
numalphaj repeat a cell and split its contributing factor rather than pad with
a cellid of zero, so that the same records are also valid MODFLOW-USG input.

The computed data reproduces the ghost nodes gridgen writes to qtg.gnc.dat
exactly, which is checked over five grid configurations.

Also removes a duplicate MfUsgGnc entry from the flopy.mfusg __all__ list,
which ruff check reports as RUF068 and which blocks the lint job.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (1)

flopy/utils/gnc.py:105

  • _check_gnc() can raise an IndexError instead of a ValueError when a record contains out-of-range node numbers (e.g., n >= nnodes). Since this function is used as a validation step (get_gridprops_gnc6(check=True)), it should detect invalid n/m indices explicitly and raise a clear ValueError message instead of crashing while slicing ia/ja.
    for irec, rec in enumerate(gnc):
        n = rec["n"]
        neighbors = ja[ia[n] : ia[n + 1]]
        # MODFLOW 6 rejects a ghost node whose n-m connection is absent
        if rec["m"] not in neighbors:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants