Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix hard coding bug in partial vertical LGR setup; #98

Merged
merged 8 commits into from
Nov 14, 2024
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"
120 changes: 80 additions & 40 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,47 @@
name: Publish release

on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
branches:
- master
# branchname trigger if we had the ability to auto-prep release PRs
# (turned off for doi-usgs org)
#- v[0-9]+.[0-9]+.[0-9]+*
release:
types:
- published

jobs:

release:
name: Create Release
# runs only when changes are merged to master
if: ${{ github.event_name == 'push' && github.ref_name == 'master' }}
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout source
uses: actions/checkout@v3
- name: Checkout master branch
uses: actions/checkout@v4
with:
ref: master
- name: Bump version and push tag
id: tag_version
uses: mathieudutour/[email protected]
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
tag_name: ${{ steps.tag_version.outputs.new_tag }}
release_name: Modflow-setup ${{ steps.tag_version.outputs.new_tag }}
body: |
Changes in this Release:
draft: false
${{ steps.tag_version.outputs.changelog }}
draft: true
prerelease: false

docs:
Expand All @@ -33,9 +51,11 @@ jobs:

steps:
- name: Checkout source
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
persist-credentials: false
ref: master
fetch-tags: true

- name: Get latest release version number
id: get_version
Expand All @@ -49,16 +69,9 @@ jobs:
- name: Setup Micromamba
uses: mamba-org/setup-micromamba@v1
with:
environment-file: ci/test_environment.yaml
cache-environment: false
cache-downloads: false
# persist on the same day.
# cache-environment-key: environment-${{ steps.date.outputs.date }}
# cache-downloads-key: downloads-${{ steps.date.outputs.date }}
create-args: >-
python=${{ matrix.python-version }}
init-shell: >-
bash
environment-file: ci/test_environment.yml
cache-environment: true
cache-downloads: true

- name: Conda info
shell: bash -l {0}
Expand Down Expand Up @@ -91,7 +104,7 @@ jobs:
- name: Run tests
shell: bash -l {0}
run: |
pytest mfsetup/test/test_notebooks.py
pytest mfsetup/tests/test_notebooks.py

- name: Build docs
shell: bash -l {0}
Expand All @@ -108,23 +121,50 @@ jobs:
CLEAN: false
TARGET_FOLDER: ${{ steps.get_version.outputs.version }}

deploy:
needs: release
runs-on: ubuntu-latest
publish:
name: Publish package
# runs only after release is published (manually promoted from draft)
# (allows editing of release notes, etc.)
if: ${{ github.event_name == 'release' }}
runs-on: ubuntu-latest #ubuntu-22.04
permissions:
contents: write
pull-requests: write
id-token: write # mandatory for trusted publishing
environment: # requires a 'release' environment in repo settings
name: release
url: https://pypi.org/p/modflow-setup
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.ALL_PROJECTS }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*

- name: Checkout master branch
uses: actions/checkout@v4
with:
ref: master
fetch-tags: true

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
cache: 'pip'
cache-dependency-path: pyproject.toml

- name: Install Python dependencies
run: |
pip install --upgrade pip
pip install build twine

- name: Build package
run: python -m build

- name: Check package
run: twine check --strict dist/*

- name: Upload package
uses: actions/upload-artifact@v4
with:
name: dist
path: dist

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
88 changes: 85 additions & 3 deletions docs/source/input/ic.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,88 @@
=======================================================================================
Specifying Initial Conditions
Initial Conditions
=======================================================================================

.. note::
This page is a work in progress and needs some more work.
Similar to other packages, input of initial conditions follows the structure of MODFLOW and Flopy. Setting the starting heads from the model top is often a good way to go initially. After the model has been run, starting heads can then be :ref:`updated from the initial model head output <Example script for updating starting heads from a previous run>` to improve convergence on subsequent runs.

.. Note::

With any transient model, an :ref:`initial steady-state stress period <Time Discretization>` is recommended, regardless of initial conditions. Specification of initial conditions is mostly a consideration for improving model convergence.

Starting heads defaults
--------------------------
Omitting or leaving the ``ic:`` block blank triggers one of two default actions:

* If there is no parent model, or a parent model with the ``default_source_data`` option turned off, starting heads are set to the model top.
* If there is a parent model with the ``default_source_data`` option turned on, starting heads are set from the parent model starting heads.

Specifying starting heads directly
-----------------------------------
For MODFLOW 6 models, the "Options" and "Griddata" input blocks are represented as sub-blocks within the ``ic:`` block. Within the ``griddata:`` block, model inputs can be specified directly, as long as they are consistent with the definition of the model grid. For example, if ``strt: [100., 100.]`` is specified, the model must be either two layers (for "LAYERED" input; see MODFLOW input instructions) or two cells. An example of specifying a uniform starting head condition for a model of any size:

.. code-block:: yaml

ic:
griddata:
strt: 100.

Or specifying uniform starting heads by layer:

.. code-block:: yaml

ic:
griddata:
strt: [100., 99.]

External files can also be supplied, following the Flopy format:

.. code-block:: yaml

ic:
griddata:
strt:
- {'filename': 'strt_000.dat'}
- {'filename': 'strt_001.dat'}

Specifying starting heads from grid-independent sources
--------------------------------------------------------
Similar to other packages, input specified via a ``source_data:`` sub-block can be mapped to the model grid from a variety of sources.

Explicitly setting starting heads to the model top (for example, to override the default behavior with ``default_source_data`` from a parent model):

.. code-block:: yaml

ic:
source_data:
strt: 'from_model_top'

Setting starting heads from a binary head save file (pathed relative to the configuration file):

.. code-block:: yaml

ic:
source_data:
strt:
from_parent:
binaryfile: '/path/to/pleasant.hds'
stress_period: 0

Explicitly setting starting heads to the parent model starting heads (for example, to override the default behavior if ``default_source_data`` is ``False``)

.. code-block:: yaml

ic:
source_data:
strt: from_parent

Example script for updating starting heads from a previous run
---------------------------------------------------------------
The following example script opens MODFLOW binary head results using Flopy, and writes them to external files that can then be input to the IC or BAS6 Packages (for MODFLOW 6 or MODFLOW-NWT models, respectively). If you followed the Modflow-setup defaults to write external files to an ``external/`` folder, with starting head files named as shown in the script, this will overwrite your previous starting head files, requiring no additional action after running the script.

.. literalinclude:: ../../../examples/update_starting_heads_from_previous.py
:language: python
:linenos:

Download the file:
:download:`update_starting_heads_from_previous.py <../../../examples/update_starting_heads_from_previous.py>`

**Note:** This script can be run as soon as the initial steady-state stress period is done solving. The current MODFLOW run can then be canceled and MODFLOW restarted, hopefully with improved convergence in the initial period.
2 changes: 1 addition & 1 deletion docs/source/input/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Input instructions by package
Specifying Aquifer Properties (UPW, NPF, STO) <props.rst>
Basic stress packages (CHD, DRN, GHB, RCH, RIV, WEL) <basic-stress.rst>
The Discretization Package (DIS, TDIS, BAS6) <dis.rst>
Specifying Initial Conditions (IC, BAS6) <ic.rst>
Initial Conditions (IC, BAS6) <ic.rst>
The Lake Package (LAK) <lak.rst>
The Streamflow Routing Package (SFR, GAGE) <sfr.rst>
Head observations (OBS, HYD) <obs.rst>
Expand Down
9 changes: 4 additions & 5 deletions examples/pleasant_lgr_parent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,11 @@ tdis:

# Initial Conditions Package
ic:
# starting heads sampled from parent model
# override default_source_data: True setting
# (to set starting heads from the parent model starting heads)
# set starting heads to the model top
source_data:
strt:
from_parent:
binaryfile: 'data/pleasant/pleasant.hds'
stress_period: 0
strt: from_model_top

# Node Property Flow Package
npf:
Expand Down
20 changes: 20 additions & 0 deletions examples/update_starting_heads_from_previous.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Update model starting heads from previous (initial steady-state) solution
"""
from pathlib import Path

import numpy as np
from flopy.utils import binaryfile as bf

model_ws = Path('.')
headfile = model_ws / 'model.hds'
starting_heads_file_fmt = str(model_ws / 'external/strt_{:03d}.dat')


hdsobj = bf.HeadFile(headfile)
print(f'reading {headfile}...')

initial_ss_heads = hdsobj.get_data(kstpkper=(0, 0))
for per, layer_heads in enumerate(initial_ss_heads):
outfile = starting_heads_file_fmt.format(per)
np.savetxt(starting_heads_file_fmt.format(per), layer_heads, fmt='%.2f')
print(f"updated {outfile}")
10 changes: 10 additions & 0 deletions mfsetup/discretization.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,16 @@ def make_lgr_idomain(parent_modelgrid, inset_modelgrid,
y1 = inset_modelgrid.ycellcenters[-1, -1]
pi1, pj1 = parent_modelgrid.intersect(x1, y1, forgive=True)
idomain = np.ones(parent_modelgrid.shape, dtype=int)
if any(np.isnan([pi0, pj0])):
raise ValueError(f"LGR model upper left corner {pi0}, {pj0} "
"is outside of the parent model domain! "
"Check the grid offset and dimensions."
)
if any(np.isnan([pi1, pj1])):
raise ValueError(f"LGR model lower right corner {pi0}, {pj0} "
"is outside of the parent model domain! "
"Check the grid offset and dimensions."
)
idomain[0:(np.array(ncppl) > 0).sum(),
pi0:pi1+1, pj0:pj1+1] = 0
return idomain
Expand Down
Loading