├── .flake8 ├── .git-blame-ignore-revs ├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .pylintrc ├── .readthedocs.yml ├── CITATION.cff ├── HISTORY.md ├── LICENSE ├── README.md ├── autotest ├── __init__.py ├── conftest.py ├── pytest.ini ├── test_interface.py └── test_mf6_examples.py ├── cliff.toml ├── docs ├── Makefile ├── conf.py ├── examples │ ├── data │ │ ├── ats0 │ │ │ ├── gwf_ats01a.ats │ │ │ ├── gwf_ats01a.dis │ │ │ ├── gwf_ats01a.ghb │ │ │ ├── gwf_ats01a.ic │ │ │ ├── gwf_ats01a.ims │ │ │ ├── gwf_ats01a.nam │ │ │ ├── gwf_ats01a.npf │ │ │ ├── gwf_ats01a.obs │ │ │ ├── gwf_ats01a.oc │ │ │ ├── gwf_ats01a.sto │ │ │ ├── gwf_ats01a.tdis │ │ │ ├── gwf_ats01a.wel │ │ │ └── mfsim.nam │ │ ├── dis_model │ │ │ ├── mfsim.nam │ │ │ ├── test_model.chd │ │ │ ├── test_model.dis │ │ │ ├── test_model.drn │ │ │ ├── test_model.evt │ │ │ ├── test_model.ic │ │ │ ├── test_model.ims │ │ │ ├── test_model.nam │ │ │ ├── test_model.npf │ │ │ ├── test_model.oc │ │ │ ├── test_model.rch │ │ │ ├── test_model.rcha │ │ │ ├── test_model.sto │ │ │ ├── test_model.tdis │ │ │ └── test_model.wel │ │ ├── disu_model │ │ │ ├── flow.chd │ │ │ ├── flow.disu │ │ │ ├── flow.disu.area.dat │ │ │ ├── flow.disu.cl12.dat │ │ │ ├── flow.disu.hwva.dat │ │ │ ├── flow.disu.iac.dat │ │ │ ├── flow.disu.ja.dat │ │ │ ├── flow.ic │ │ │ ├── flow.ims │ │ │ ├── flow.nam │ │ │ ├── flow.npf │ │ │ ├── flow.oc │ │ │ ├── flow.rch │ │ │ ├── flow.tdis │ │ │ └── mfsim.nam │ │ ├── disv_model │ │ │ ├── mfsim.nam │ │ │ ├── model.ims │ │ │ ├── simulation.tdis │ │ │ ├── tri_model.ic │ │ │ ├── tri_model.nam │ │ │ ├── tri_model.npf │ │ │ ├── tri_model.oc │ │ │ ├── tri_model_cnst.disv │ │ │ ├── tri_model_gaus.disv │ │ │ ├── tri_model_left.chd │ │ │ └── tri_model_right.chd │ │ └── two_models │ │ │ ├── mfsim.nam │ │ │ ├── model1.chd │ │ │ ├── model1.dis │ │ │ ├── model1.ic │ │ │ ├── model1.mawq │ │ │ ├── model1.nam │ │ │ ├── model1.npf │ │ │ ├── model1.oc │ │ │ ├── model2.dis │ │ │ ├── model2.ic │ │ │ ├── model2.mawq │ │ │ ├── model2.nam │ │ │ ├── model2.npf │ │ │ ├── model2.oc │ │ │ ├── simulation.exg │ │ │ ├── simulation.gnc │ │ │ ├── simulation.ims │ │ │ ├── simulation.mvr │ │ │ └── simulation.tdis │ └── notebooks │ │ ├── Extensions.py │ │ ├── Head_Monitor_Example.py │ │ └── Quickstart.py ├── index.rst └── make.bat ├── guide-to-publish.md ├── manualtest └── collect_states.py ├── modflowapi ├── __init__.py ├── extensions │ ├── __init__.py │ ├── advpaks.py │ ├── apiexchange.py │ ├── apimodel.py │ ├── apisimulation.py │ ├── data.py │ ├── datamodel.py │ ├── pakbase.py │ └── runner.py ├── modflowapi.py ├── util.py └── version.py ├── pyproject.toml ├── scripts └── update_version.py └── version.txt /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | exclude = 3 | .git, 4 | __pycache__, 5 | build, 6 | dist, 7 | examples, 8 | autotest 9 | ignore = 10 | # https://flake8.pycqa.org/en/latest/user/error-codes.html 11 | # 'module' imported but unused 12 | F401, 13 | # https://pycodestyle.readthedocs.io/en/latest/intro.html#error-codes 14 | # E1: Indentation 15 | E121, E122, E126, E127, E128, 16 | # E2: Whitespace 17 | E203, E221, E222, E226, E231, E241, 18 | # E4: Import 19 | E402, 20 | # E5: Line length 21 | E501, E502, 22 | # E7: Statement 23 | E722, E741, 24 | # W2: Whitespace warning 25 | W291, W292, W293, 26 | # W3: Blank line warning 27 | W391, 28 | # W5: Line break warning 29 | W503, W504 30 | 31 | statistics = True 32 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # change CRLF to LF line endings for source files (#12) 2 | e0ca9e80a60ae6c85933a69ec322a5bc861a32ab 3 | 4 | # apply isort rule, split long comment lines (#47) 5 | 0c632e511fb54068d14dcdff44c572ccb6e8831f 6 | 7 | # reformat Python code with line length = 88 (#57) 8 | 4cee570791f7b9631179f7c42286a07d9b232fb0 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set the merge driver for windows files 8 | # 9 | *.bat text eol=crlf 10 | 11 | # Denote all files that are truly binary and should not be modified. 12 | *.png binary 13 | *.jpg binary 14 | *.pdf binary 15 | 16 | # Do not modify the model data in various directories 17 | examples/data/** binary 18 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: modflowapi continuous integration 2 | 3 | on: 4 | schedule: 5 | - cron: '0 8 * * *' # run at 8 AM UTC (12 am PST) 6 | push: 7 | pull_request: 8 | branches: [main, develop] 9 | concurrency: 10 | group: ${{ github.workflow }}-${{ github.ref }} 11 | cancel-in-progress: true 12 | jobs: 13 | 14 | std_setup: 15 | name: standard installation 16 | runs-on: ubuntu-latest 17 | strategy: 18 | fail-fast: false 19 | defaults: 20 | run: 21 | shell: bash 22 | steps: 23 | 24 | - name: Checkout repo 25 | uses: actions/checkout@v4 26 | 27 | - name: Setup uv 28 | uses: astral-sh/setup-uv@v5 29 | with: 30 | cache-dependency-glob: "**/pyproject.toml" 31 | 32 | - name: Print version 33 | run: uv run python -c "import modflowapi; print(modflowapi.__version__)" 34 | 35 | lint: 36 | name: lint 37 | runs-on: ubuntu-latest 38 | if: github.event_name != 'schedule' 39 | strategy: 40 | fail-fast: false 41 | defaults: 42 | run: 43 | shell: bash 44 | steps: 45 | - name: Checkout repo 46 | uses: actions/checkout@v4 47 | 48 | - name: Setup uv 49 | uses: astral-sh/setup-uv@v5 50 | with: 51 | enable-cache: false 52 | 53 | - name: Lint 54 | run: uvx ruff check . 55 | 56 | - name: Format 57 | run: uvx ruff format . --check 58 | 59 | - name: Spelling 60 | run: uvx codespell 61 | 62 | autotest_extensions: 63 | name: modflowapi extensions autotests 64 | needs: lint 65 | runs-on: ${{ matrix.os }} 66 | strategy: 67 | fail-fast: false 68 | matrix: 69 | os: [ ubuntu-latest, macos-latest, windows-latest ] 70 | python-version: [ "3.10", "3.11", "3.12", "3.13" ] 71 | defaults: 72 | run: 73 | shell: bash 74 | steps: 75 | - name: Checkout repo 76 | uses: actions/checkout@v4 77 | 78 | - name: Setup uv 79 | uses: astral-sh/setup-uv@v5 80 | with: 81 | cache-dependency-glob: "**/pyproject.toml" 82 | python-version: ${{ matrix.python-version }} 83 | 84 | - name: Install 85 | run: uv sync --all-extras 86 | 87 | - name: Install Python dependencies 88 | run: | 89 | uv pip install git+https://git@github.com/Deltares/xmipy@develop 90 | uv pip install git+https://git@github.com/MODFLOW-ORG/modflow-devtools@develop 91 | 92 | - name: Install modflow executables 93 | uses: modflowpy/install-modflow-action@v1 94 | with: 95 | path: ${{ github.workspace }}/autotest 96 | repo: modflow6-nightly-build 97 | 98 | - name: Run autotests 99 | working-directory: ./autotest 100 | shell: bash -l {0} 101 | run: uv run pytest -v -n auto -m "not mf6" 102 | 103 | autotest_preidm_extensions: 104 | name: modflowapi pre-idm extensions autotests 105 | needs: lint 106 | runs-on: ${{ matrix.os }} 107 | strategy: 108 | fail-fast: false 109 | matrix: 110 | os: [ ubuntu-latest, macos-13, windows-latest ] 111 | python-version: [ "3.10", "3.11", "3.12", "3.13" ] 112 | defaults: 113 | run: 114 | shell: bash 115 | steps: 116 | - name: Checkout repo 117 | uses: actions/checkout@v4 118 | 119 | - name: Setup uv 120 | uses: astral-sh/setup-uv@v5 121 | with: 122 | cache-dependency-glob: "**/pyproject.toml" 123 | python-version: ${{ matrix.python-version }} 124 | 125 | - name: Install 126 | run: uv sync --all-extras 127 | 128 | - name: Install Python dependencies 129 | run: | 130 | uv pip install git+https://git@github.com/Deltares/xmipy@develop 131 | uv pip install git+https://git@github.com/MODFLOW-ORG/modflow-devtools@develop 132 | 133 | - name: Install modflow executables 134 | uses: modflowpy/install-modflow-action@v1 135 | with: 136 | path: ${{ github.workspace }}/autotest 137 | repo: executables 138 | tag: "14.0" 139 | 140 | - name: Run autotests 141 | working-directory: ./autotest 142 | shell: bash -l {0} 143 | run: pytest -v -n auto -m "not mf6" 144 | 145 | autotest_mf6_examples: 146 | name: modflowapi mf6 examples autotests 147 | needs: lint 148 | runs-on: ${{ matrix.os }} 149 | strategy: 150 | fail-fast: false 151 | matrix: 152 | os: [ ubuntu-latest, macos-latest, windows-latest ] 153 | python-version: [ "3.10", "3.11", "3.12", "3.13" ] 154 | defaults: 155 | run: 156 | shell: bash 157 | steps: 158 | - name: Checkout repo 159 | uses: actions/checkout@v4 160 | 161 | - name: Setup uv 162 | uses: astral-sh/setup-uv@v5 163 | with: 164 | cache-dependency-glob: "**/pyproject.toml" 165 | python-version: ${{ matrix.python-version }} 166 | 167 | - name: Install 168 | run: uv sync --all-extras 169 | 170 | - name: Install modflow6 nightly build 171 | uses: modflowpy/install-modflow-action@v1 172 | with: 173 | path: ${{ github.workspace }}/autotest 174 | repo: modflow6-nightly-build 175 | 176 | - name: Run autotests 177 | working-directory: ./autotest 178 | shell: bash -l {0} 179 | run: uv run pytest -v -n auto test_mf6_examples.py 180 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | branches: 5 | - main 6 | - v[0-9]+.[0-9]+.[0-9]+* 7 | release: 8 | types: 9 | - published 10 | jobs: 11 | prep: 12 | name: Prepare release 13 | runs-on: ubuntu-latest 14 | if: ${{ github.event_name == 'push' && github.ref_name != 'main' }} 15 | permissions: 16 | contents: write 17 | pull-requests: write 18 | defaults: 19 | run: 20 | shell: bash 21 | steps: 22 | 23 | - name: Checkout release branch 24 | uses: actions/checkout@v4 25 | with: 26 | fetch-depth: 0 27 | 28 | - name: Setup Python 29 | uses: actions/setup-python@v4 30 | with: 31 | python-version: '3.10' 32 | cache: 'pip' 33 | cache-dependency-path: pyproject.toml 34 | 35 | - name: Install Python dependencies 36 | run: | 37 | pip install --upgrade pip 38 | pip install build twine 39 | pip install . 40 | pip install ".[lint, test]" 41 | 42 | - name: Update version 43 | id: version 44 | run: | 45 | ref="${{ github.ref_name }}" 46 | version="${ref#"v"}" 47 | python scripts/update_version.py -v "$version" 48 | python -c "import modflowapi; print('Version: ', modflowapi.__version__)" 49 | echo "version=$version" >> $GITHUB_OUTPUT 50 | 51 | - name: Touch changelog 52 | run: touch HISTORY.md 53 | 54 | - name: Generate changelog 55 | id: cliff 56 | uses: orhun/git-cliff-action@v1 57 | with: 58 | config: cliff.toml 59 | args: --verbose --unreleased --tag ${{ steps.version.outputs.version }} 60 | env: 61 | OUTPUT: CHANGELOG.md 62 | 63 | - name: Update changelog 64 | run: | 65 | # substitute full group names 66 | sed -i 's/#### Ci/#### Continuous integration/' CHANGELOG.md 67 | sed -i 's/#### Feat/#### New features/' CHANGELOG.md 68 | sed -i 's/#### Fix/#### Bug fixes/' CHANGELOG.md 69 | sed -i 's/#### Refactor/#### Refactoring/' CHANGELOG.md 70 | sed -i 's/#### Test/#### Testing/' CHANGELOG.md 71 | 72 | # prepend release changelog to cumulative changelog 73 | clog="HISTORY.md" 74 | temp="temp.md" 75 | echo "$(tail -n +2 $clog)" > $clog 76 | cat CHANGELOG.md $clog > $temp 77 | sudo mv $temp $clog 78 | sed -i '1i # Changelog' $clog 79 | 80 | - name: Upload changelog 81 | uses: actions/upload-artifact@v3 82 | with: 83 | name: changelog 84 | path: CHANGELOG.md 85 | 86 | - name: Lint Python files 87 | run: ruff check . 88 | 89 | - name: Format Python files 90 | run: ruff format . 91 | 92 | - name: Push release branch 93 | env: 94 | GITHUB_TOKEN: ${{ github.token }} 95 | run: | 96 | ver="${{ steps.version.outputs.version }}" 97 | changelog=$(cat CHANGELOG.md | grep -v "### Version $ver") 98 | 99 | # remove this release's changelog so we don't commit it 100 | # the changes have already been prepended to HISTORY.md 101 | rm -f CHANGELOG.md 102 | 103 | # commit and push changes 104 | git config core.sharedRepository true 105 | git config user.name "github-actions[bot]" 106 | git config user.email "41898282+github-actions[bot]@users.noreply.github.com" 107 | git add -A 108 | git commit -m "ci(release): set version to ${{ steps.version.outputs.version }}, update changelog" 109 | git push origin "${{ github.ref_name }}" 110 | 111 | title="Release $ver" 112 | body=' 113 | # Release '$ver' 114 | 115 | The release can be approved by merging this pull request into `main`. This will trigger jobs to publish the release to PyPI and reset `develop` from `main`, incrementing the minor version number. 116 | 117 | ## Changelog 118 | 119 | '$changelog' 120 | ' 121 | gh pr create -B "main" -H "${{ github.ref_name }}" --title "$title" --draft --body "$body" 122 | 123 | release: 124 | name: Draft release 125 | # runs only when changes are merged to main 126 | if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} 127 | runs-on: ubuntu-latest 128 | permissions: 129 | contents: write 130 | pull-requests: write 131 | steps: 132 | 133 | - name: Checkout repo 134 | uses: actions/checkout@v4 135 | with: 136 | ref: main 137 | 138 | - name: Setup Python 139 | uses: actions/setup-python@v4 140 | with: 141 | python-version: '3.10' 142 | 143 | - name: Install Python dependencies 144 | run: | 145 | pip install --upgrade pip 146 | pip install . 147 | pip install ".[test]" 148 | 149 | # actions/download-artifact won't look at previous workflow runs but we need to in order to get changelog 150 | - name: Download artifacts 151 | uses: dawidd6/action-download-artifact@v2 152 | 153 | - name: Draft release 154 | env: 155 | GITHUB_TOKEN: ${{ github.token }} 156 | run: | 157 | version=$(python scripts/update_version.py -g) 158 | title="modflowapi $version" 159 | notes=$(cat "changelog/CHANGELOG.md" | grep -v "### Version $version") 160 | gh release create "$version" \ 161 | --target main \ 162 | --title "$title" \ 163 | --notes "$notes" \ 164 | --draft \ 165 | --latest 166 | 167 | publish: 168 | name: Publish package 169 | # runs only after release is published (manually promoted from draft) 170 | if: github.event_name == 'release' && github.repository_owner == 'MODFLOW-ORG' 171 | runs-on: ubuntu-22.04 172 | permissions: 173 | contents: write 174 | pull-requests: write 175 | id-token: write 176 | environment: # requires a 'release' environment in repo settings 177 | name: release 178 | url: https://pypi.org/p/modflowapi 179 | steps: 180 | 181 | - name: Checkout main branch 182 | uses: actions/checkout@v4 183 | with: 184 | ref: main 185 | 186 | - name: Setup Python 187 | uses: actions/setup-python@v4 188 | with: 189 | python-version: '3.10' 190 | 191 | - name: Install Python dependencies 192 | run: | 193 | pip install --upgrade pip 194 | pip install build twine 195 | pip install . 196 | 197 | - name: Build package 198 | run: python -m build 199 | 200 | - name: Check package 201 | run: twine check --strict dist/* 202 | 203 | - name: Upload package 204 | uses: actions/upload-artifact@v4 205 | with: 206 | name: dist 207 | path: dist 208 | 209 | - name: Publish to PyPI 210 | uses: pypa/gh-action-pypi-publish@release/v1 211 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | 131 | # pycharm 132 | .idea/ 133 | 134 | # library files 135 | **.dll 136 | **.so 137 | **.dylib 138 | 139 | # uv lockfile 140 | uv.lock 141 | 142 | # temporary test folders 143 | autotest/temp/** 144 | 145 | # notebooks 146 | docs/examples/notebooks/*.ipynb 147 | 148 | # autosummary 149 | docs/_autosummary/ 150 | 151 | # mf6 output files 152 | **/*.lst 153 | **/*.stdout 154 | **/*.cbc 155 | **/*.cbb 156 | **/*.hds 157 | **/*.hed 158 | **/*.grb 159 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | build: 3 | os: "ubuntu-24.04" 4 | tools: 5 | python: "3.13" 6 | sphinx: 7 | configuration: docs/conf.py 8 | formats: 9 | - pdf 10 | python: 11 | install: 12 | - method: pip 13 | path: . 14 | extra_requirements: 15 | - docs -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: If you use this software, please cite both the article from preferred-citation 3 | and the software itself. 4 | type: software 5 | title: MODFLOW API 6 | version: 0.3.0.dev0 7 | date-released: '2023-04-19' 8 | abstract: An extension to xmipy for the MODFLOW API. 9 | repository-artifact: https://pypi.org/project/modflowapi 10 | repository-code: https://github.com/MODFLOW-ORG/modflowapi 11 | license: CC0-1.0 12 | authors: 13 | - family-names: Hughes 14 | given-names: Joseph D. 15 | alias: jdhughes-usgs 16 | affiliation: U.S. Geological Survey 17 | orcid: https://orcid.org/0000-0003-1311-2354 18 | - family-names: Russcher 19 | given-names: Martijn 20 | alias: mjr-deltares 21 | affiliation: Deltares 22 | orcid: https://orcid.org/0000-0001-8799-6514 23 | - family-names: Langevin 24 | given-names: Christian D. 25 | alias: langevin-usgs 26 | affiliation: U.S. Geological Survey 27 | orcid: https://orcid.org/0000-0001-5610-9759 28 | - family-names: Hofer 29 | given-names: Julian 30 | alias: Hofer-Julian 31 | affiliation: Deltares 32 | - family-names: Larsen 33 | given-names: Joshua D. 34 | alias: jlarsen-usgs 35 | affiliation: U.S. Geological Survey 36 | orcid: https://orcid.org/0000-0002-1218-800X 37 | preferred-citation: 38 | type: article 39 | authors: 40 | - family-names: Hughes 41 | given-names: Joseph D. 42 | orcid: https://orcid.org/0000-0003-1311-2354 43 | - family-names: Russcher 44 | given-names: Martijn J. 45 | orcid: https://orcid.org/0000-0001-8799-6514 46 | - family-names: Langevin 47 | given-names: Christian D. 48 | orcid: https://orcid.org/0000-0001-5610-9759 49 | - family-names: Morway 50 | given-names: Eric D. 51 | orcid: https://orcid.org/0000-0002-8553-6140 52 | - family-names: McDonald 53 | given-names: Richard R. 54 | orcid: https://orcid.org/0000-0002-0703-0638 55 | title: The MODFLOW Application Programming Interface for simulation control and software interoperability 56 | doi: 10.1016/j.envsoft.2021.105257 57 | journal: Environmental Modelling & Software 58 | volume: 138 59 | start: 105257 60 | year: 2022 61 | month: 2 62 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | ### Version 0.2.0 3 | 4 | #### Refactoring 5 | 6 | * [refactor(rhs, hcof)](https://github.com/MODFLOW-ORG/modflowapi/commit/c0f681c5b7525388ead4df8c6363c1b4514d6de6): Updates to allow setting values when rhs and hcof have not yet had pointers set.. Committed by Joshua Larsen on 2023-04-28. 7 | * [refactor(Quickstart.ipynb)](https://github.com/MODFLOW-ORG/modflowapi/commit/3b6675aa687f5af01813abfdb143c7ddd4343646): Fix error in callback_function. Committed by Joshua Larsen on 2023-07-17. 8 | * [refactor(rhs, hcof)](https://github.com/MODFLOW-ORG/modflowapi/commit/ce4e50286d66da51c6b05f0de29c7c646344f6ce): Allow setting rhs and hcof when pointers have not been previously set. Committed by Joshua Larsen on 2023-07-17. 9 | * [refactor](https://github.com/MODFLOW-ORG/modflowapi/commit/e693282611d5863bafeece362230a4aadd02311f): Update libmf6 path handling (#27). Committed by w-bonelli on 2023-08-03. 10 | * [refactor(_ptr_to_recarray)](https://github.com/MODFLOW-ORG/modflowapi/commit/5a631592f2da57bf1564c263e9602c46e5a5a50c): Slice pointers prior to setting data to recarray. Committed by Joshua Larsen on 2023-08-08. 11 | * [refactor(_ptr_to_recarray)](https://github.com/MODFLOW-ORG/modflowapi/commit/959fe31abda263a52d01262af7dc4c2a878eadb5): Slice pointers prior to setting data to recarray. Committed by Joshua Larsen on 2023-08-08. 12 | * [refactor(extensions)](https://github.com/MODFLOW-ORG/modflowapi/commit/c97339d06e7386055e486f6354825ec15cea4638): Add support for IDM changes. Committed by Joshua Larsen on 2023-12-21. 13 | * [refactor(extensions)](https://github.com/MODFLOW-ORG/modflowapi/commit/de0aff9c21d5d925235f306fd2b3d148c3281efa): Add support for IDM changes. Committed by Joshua Larsen on 2023-12-21. 14 | 15 | ### Version 0.1.0 16 | 17 | * Fix typo in README (https://github.com/MODFLOW-ORG/modflowapi/pull/4) 18 | * modflowapi interface (https://github.com/MODFLOW-ORG/modflowapi/pull/8) 19 | * update package: manual variable address assembly updated to use xmipy get_variable_addr() 20 | * update additional manual variable address assembly statements 21 | * Refactor code and added functionality: 22 | * add stress_period_start, stress_period_end Callbacks 23 | * fix ApiModel __repr__ 24 | * added Exchanges, TDIS, ATS, and SLN support 25 | * added ScalarInput and ScalarPackage support 26 | * update autotests 27 | * added parallel testing support through pytest-xdist 28 | * updated markers and split the extensions tests from the mf6 examples tests 29 | * added a test for ATS 30 | * update setup.cfg 31 | * update ci.yml 32 | * update(ListInput): add auxvar to stress_period_data when auxiliary variables are used 33 | * Allow None to be passed to stress_period_data.values to disable stresses for a package 34 | * updates: ApiModel, ApiSimulation, run_simulation 35 | * added a `totim` property on `ApiSimulation` and `ApiModel` 36 | * added docstrings to ApiModel property methods 37 | * updated termination message in run_simulation 38 | * added a finalize callback to Callbacks and run_simulation 39 | * add support for AUXNAME_CST 40 | * add(Head Monitor Example): Add a head monitor example application 41 | * ApiModel: adjust X based on nodetouser 42 | * ApiPackage: enforce lower cased variable names in get_advanced_var 43 | * ArrayPointer: trap for arrays that are not adjusted by reduced node numbers (ex. idomain) 44 | * update setup.cfg 45 | * try reformatting the xmipy installation instructions 46 | * fix(get value): fixed error handling when modflowapi fails to get a pointer to a value from the API (https://github.com/MODFLOW-ORG/modflowapi/pull/9) 47 | Co-authored-by: scottrp <45947939+scottrp@users.noreply.github.com> 48 | * update(rhs, hcof, AdvancedInput): bug fixes for setting variable values for advanced inputs 49 | * update rhs and hcof to copy values to pointer instead of overwriting the pointer 50 | * add a check for AdvancedInput variables that do not have pointer support in xmipy 51 | * update setting routine for AdvancedInput 52 | * refactor(EOL): change CRLF to LF line endings for source files (https://github.com/MODFLOW-ORG/modflowapi/pull/12) 53 | * Use pyproject.toml for project metadata, add citation info (https://github.com/MODFLOW-ORG/modflowapi/pull/11) 54 | * add(test_rhs_hcof_advanced): add additional test (https://github.com/MODFLOW-ORG/modflowapi/pull/13) 55 | * added test for getting and setting rhs, hcof, and advanced variable values 56 | * update project to use unix line separators 57 | * use np.testing.assert_allclose() instead of AssertionError 58 | * Add missing RIV support to modflowapi (https://github.com/MODFLOW-ORG/modflowapi/pull/16) 59 | * add(test_rhs_hcof_advanced): add additional test 60 | * added test for getting and setting rhs, hcof, and advanced variable values 61 | * update project to use unix line separators 62 | * use np.testing.assert_allclose() instead of AssertionError 63 | * Add missing riv package to modflowapi 64 | 65 | ### Version 0.0.1 66 | 67 | Initial release. 68 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # modflowapi 2 | 3 | [![CI](https://github.com/MODFLOW-ORG/modflowapi/actions/workflows/ci.yml/badge.svg)](https://github.com/MODFLOW-ORG/modflowapi/actions/workflows/ci.yml) 4 | [![GitHub contributors](https://img.shields.io/github/contributors/MODFLOW-ORG/modflowapi)](https://img.shields.io/github/contributors/MODFLOW-ORG/modflowapi) 5 | [![GitHub tag](https://img.shields.io/github/tag/MODFLOW-ORG/modflowapi.svg)](https://github.com/MODFLOW-ORG/modflowapi/tags/latest) 6 | 7 | [![PyPI License](https://img.shields.io/pypi/l/modflowapi)](https://pypi.python.org/pypi/modflowapi) 8 | [![PyPI Status](https://img.shields.io/pypi/status/modflowapi.png)](https://pypi.python.org/pypi/modflowapi) 9 | [![PyPI Format](https://img.shields.io/pypi/format/modflowapi)](https://pypi.python.org/pypi/modflowapi) 10 | [![PyPI Version](https://img.shields.io/pypi/v/modflowapi.png)](https://pypi.python.org/pypi/modflowapi) 11 | [![PyPI Versions](https://img.shields.io/pypi/pyversions/modflowapi.png)](https://pypi.python.org/pypi/modflowapi) 12 | 13 | [![Anaconda License](https://anaconda.org/conda-forge/modflowapi/badges/license.svg)](https://anaconda.org/conda-forge/modflowapi/badges/license.svg) 14 | [![Anaconda Version](https://anaconda.org/conda-forge/modflowapi/badges/version.svg)](https://anaconda.org/conda-forge/modflowapi) 15 | [![Anaconda Updated](https://anaconda.org/conda-forge/modflowapi/badges/latest_release_date.svg)](https://anaconda.org/conda-forge/modflowapi) 16 | 17 | An extension to [xmipy](https://pypi.org/project/xmipy/) for the [MODFLOW API](https://www.usgs.gov/publications/modflow-application-programming-interface-simulationcontrol-and-software). 18 | 19 | 20 | 21 | 22 | - [Introduction](#introduction) 23 | - [Installation](#installation) 24 | - [Documentation](#documentation) 25 | - [Citation](#citation) 26 | 27 | 28 | 29 | ## Introduction 30 | 31 | The `modflowapi` Python package can be used to access functionality in the eXtended Model Interface (XMI) wrapper (XmiWrapper) 32 | and additional functionality specific to the MODFLOW API. Currently it is a joint development of the USGS and Deltares. 33 | 34 | ## Installation 35 | 36 | `modflowapi` requires Python 3.10+, with: 37 | 38 | ```shell 39 | numpy 40 | pandas 41 | xmipy 42 | ``` 43 | 44 | To install `modflowapi` with pip: 45 | 46 | ``` 47 | pip install modflowapi 48 | ``` 49 | 50 | Or with conda: 51 | 52 | ``` 53 | conda install -c conda-forge modflowapi 54 | ``` 55 | 56 | ## Documentation 57 | 58 | Documentation is available [on ReadTheDocs](modflowapi.readthedocs.io). 59 | 60 | Examples using `modflowapi` and its extensions can be found in the [Quickstart](docs/examples/notebooks/Quickstart.ipynb) and the [Extensions](docs/examples/notebooks/MODFLOW-API_extensions_objects.ipynb) notebooks. An example of using the MODFLOW API to monitor heads during a simulation can be found in the [Head Monitor Example](docs/examples/notebooks/Head_Monitor_Example.ipynb) Notebook. 61 | 62 | For more info on MODFLOW 6 see [the USGS overview](https://water.usgs.gov/ogw/modflow/). 63 | 64 | ## Citation 65 | 66 | Hughes, Joseph D., Russcher, M. J., Langevin, C. D., Morway, E. D. and McDonald, R. R., 2022, The MODFLOW Application Programming Interface for simulationcontrol and software interoperability: Environmental Modelling & Software, v. 148, p. 105257, [doi:10.1016/j.envsoft.2021.105257](https://doi.org/10.1016/j.envsoft.2021.105257). 67 | -------------------------------------------------------------------------------- /autotest/__init__.py: -------------------------------------------------------------------------------- 1 | # init file for pytest 2 | -------------------------------------------------------------------------------- /autotest/conftest.py: -------------------------------------------------------------------------------- 1 | pytest_plugins = ["modflow_devtools.fixtures"] 2 | -------------------------------------------------------------------------------- /autotest/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | addopts = -ra --color=yes 3 | python_files = 4 | test_*.py 5 | markers = 6 | mf6: tests for modflow 6 examples 7 | extensions: tests for modflowapi extensions 8 | -------------------------------------------------------------------------------- /autotest/test_mf6_examples.py: -------------------------------------------------------------------------------- 1 | import modflow_devtools.models as models 2 | import pandas as pd 3 | import pytest 4 | 5 | from modflowapi import run_simulation 6 | 7 | examples = models.get_examples() 8 | pytestmark = pytest.mark.mf6 9 | dll = "libmf6" 10 | skip = [ 11 | # https://github.com/MODFLOW-ORG/modflowapi/issues/53 12 | "ex-prt-mp7-p02", 13 | "ex-prt-mp7-p04", 14 | "ex-gwe-barends", 15 | ] 16 | 17 | temporary_skip_state_count = set( 18 | [ 19 | # Skip state count tests for these model for now. 20 | # There seems to be a different problem. 21 | "ex-gwf-fhb", 22 | "ex-gwf-nwt-p02a", 23 | "ex-gwf-nwt-p02b", 24 | "ex-gwe-geotherm", 25 | "ex-gwe-radial-slow", 26 | ] 27 | ) 28 | 29 | 30 | class StateCollector: 31 | """ 32 | Callback that collects the model state sequence. 33 | 34 | THe attribute `states` is a list of tuples `(model_name, state_name)`, 35 | where `state_name` is `callback_step.name`. 36 | """ 37 | 38 | def __init__(self): 39 | self.states = [] 40 | 41 | def __call__(self, sim, callback_step): 42 | self.states.append((sim.model_names[0], callback_step.name)) 43 | 44 | 45 | def count_states(states): 46 | """ 47 | Count states per model. 48 | 49 | The numbers of `start_state` and `end_state` should match. 50 | """ 51 | states = pd.DataFrame(states, columns=["model", "state"]) 52 | counts = states.groupby(["model", "state"])[["state"]].agg("count") 53 | counts.columns = ["counts"] 54 | return counts 55 | 56 | 57 | def compare_counts(counts): 58 | matches = [ 59 | ("iteration_start", "iteration_end"), 60 | ("stress_period_start", "stress_period_end"), 61 | ("timestep_start", "timestep_end"), 62 | ] 63 | for model_name in counts.index.levels[0]: 64 | model = counts.loc[model_name] 65 | for state1, state2 in matches: 66 | count1, count2 = model.loc[state1].iloc[0], model.loc[state2].iloc[0] 67 | assert count1 == count2, ( 68 | f"{state1}: {int(count1)}", 69 | f"{state2}: {int(count2)}", 70 | ) 71 | 72 | 73 | @pytest.mark.parametrize("example_name", examples.keys()) 74 | def test_example(function_tmpdir, example_name): 75 | if example_name in skip: 76 | pytest.skip(f"Skipping example {example_name}") 77 | for model_name in examples[example_name]: 78 | model_relpath = model_name.rpartition(example_name + "/")[-1] 79 | model_workspace = function_tmpdir / model_relpath 80 | models.copy_to(model_workspace, model_name, verbose=True) 81 | callback = StateCollector() 82 | run_simulation(dll, model_workspace, callback=callback, verbose=True) 83 | if model_name in temporary_skip_state_count: 84 | counts = count_states(callback.states) 85 | compare_counts(counts) 86 | -------------------------------------------------------------------------------- /cliff.toml: -------------------------------------------------------------------------------- 1 | # configuration file for git-cliff (0.1.0) 2 | 3 | [changelog] 4 | body = """ 5 | {% if version %}\ 6 | ### Version {{ version | trim_start_matches(pat="v") }} 7 | {% else %}\ 8 | ### [unreleased] 9 | {% endif %}\ 10 | {% for group, commits in commits | group_by(attribute="group") %} 11 | #### {{ group | upper_first }} 12 | {% for commit in commits %} 13 | * [{{ commit.group }}{% if commit.scope %}({{ commit.scope }}){% endif %}](https://github.com/MODFLOW-ORG/modflowapi/commit/{{ commit.id }}): {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}. Committed by {{ commit.author.name }} on {{ commit.author.timestamp | date(format="%Y-%m-%d") }}.\ 14 | {% endfor %} 15 | {% endfor %}\n 16 | """ 17 | trim = true 18 | 19 | [git] 20 | conventional_commits = true 21 | filter_unconventional = true 22 | split_commits = false 23 | commit_parsers = [ 24 | { message = "^[fF]eat", group = "feat"}, 25 | { message = "^[fF]ix", group = "fix"}, 26 | { message = "^[bB]ug", group = "fix"}, 27 | { message = "^[pP]erf", group = "perf"}, 28 | { message = "^[rR]efactor", group = "refactor"}, 29 | { message = "^[uU]pdate", group = "refactor"}, 30 | { message = "^[aA]dd", group = "refactor"}, 31 | { message = "^[dD]oc.*", group = "docs", skip = true}, 32 | { message = "^[bB]inder", group = "docs", skip = true}, 33 | { message = "^[nN]otebook.*", group = "docs", skip = true}, 34 | { message = "^[rR][eE][aA][dD].*", group = "docs", skip = true}, 35 | { message = "^[sS]tyl.*", group = "style", skip = true}, 36 | { message = "^[tT]est.*", group = "test", skip = true}, 37 | { message = "^[cC][iI]", skip = true}, 38 | { message = "^[cC][iI]\\(release\\):", skip = true}, 39 | { message = "^[rR]elease", skip = true}, 40 | { message = "^[cC]hore", group = "chore", skip = true}, 41 | ] 42 | protect_breaking_commits = false 43 | filter_commits = false 44 | tag_pattern = "[0-9].[0-9].[0-9]" 45 | ignore_tags = "" 46 | sort_commits = "oldest" 47 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # For the full list of built-in configuration values, see the documentation: 4 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 5 | 6 | import os 7 | import sys 8 | from pathlib import Path 9 | 10 | from flopy.utils.get_modflow import run_main as get_modflow 11 | 12 | sys.path.insert(0, os.path.abspath("../")) 13 | from modflowapi import __version__ 14 | 15 | # -- Determine if this is a development or release version ------------------ 16 | branch_or_version = __version__ if "dev" not in __version__ else "develop" 17 | 18 | # -- Project information ----------------------------------------------------- 19 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information 20 | project = "modflowapi" 21 | copyright = "2025, modflowapi developers" 22 | author = "modflowapi developers" 23 | release = "0.3.0.dev0" 24 | 25 | # -- General configuration --------------------------------------------------- 26 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration 27 | extensions = ["sphinx.ext.autodoc", "sphinx.ext.autosummary", "myst_parser", "nbsphinx"] 28 | templates_path = ["_templates"] 29 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "**/Extensions.py"] 30 | 31 | # -- Options for HTML output ------------------------------------------------- 32 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output 33 | html_theme = "sphinx_rtd_theme" 34 | html_static_path = ["_static"] 35 | 36 | # -- nbsphinx configuration ------------------------------------------------- 37 | nbsphinx_custom_formats = { 38 | ".py": ["jupytext.reads", {"fmt": "py:light"}], 39 | } 40 | 41 | # -- Install MODFLOW -------------------------------------------------------- 42 | bindir = Path.cwd() / "examples" / "notebooks" 43 | repo = "modflow6-nightly-build" if branch_or_version == "develop" else "modflow6" 44 | get_modflow(str(bindir), repo=repo) 45 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.ats: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN dimensions 3 | MAXATS 2 4 | END dimensions 5 | 6 | BEGIN perioddata 7 | 1 5.00000000 1.00100000E-05 10.00000000 2.00000000 5.00000000 8 | 8 5.00000000 1.00100000E-05 10.00000000 2.00000000 5.00000000 9 | END perioddata 10 | 11 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.dis: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN options 3 | END options 4 | 5 | BEGIN dimensions 6 | NLAY 1 7 | NROW 1 8 | NCOL 2 9 | END dimensions 10 | 11 | BEGIN griddata 12 | delr 13 | CONSTANT 100.00000000 14 | delc 15 | CONSTANT 1.00000000 16 | top 17 | CONSTANT 100.00000000 18 | botm 19 | CONSTANT 0.00000000 20 | idomain 21 | INTERNAL FACTOR 1 22 | 1 1 23 | END griddata 24 | 25 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.ghb: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN options 3 | PRINT_INPUT 4 | PRINT_FLOWS 5 | END options 6 | 7 | BEGIN dimensions 8 | MAXBOUND 1 9 | END dimensions 10 | 11 | BEGIN period 1 12 | 1 1 1 50.00000000 1.00000000 13 | END period 1 14 | 15 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.ic: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN griddata 3 | strt 4 | CONSTANT 50.00000000 5 | END griddata 6 | 7 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.ims: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN options 3 | PRINT_OPTION summary 4 | END options 5 | 6 | BEGIN nonlinear 7 | OUTER_DVCLOSE 1.00000000E-06 8 | OUTER_MAXIMUM 10 9 | UNDER_RELAXATION dbd 10 | UNDER_RELAXATION_THETA 0.70000000 11 | END nonlinear 12 | 13 | BEGIN linear 14 | INNER_MAXIMUM 2 15 | INNER_DVCLOSE 1.00000000E-06 16 | inner_rclose 1.00000000E-06 17 | LINEAR_ACCELERATION cg 18 | RELAXATION_FACTOR 0.97000000 19 | SCALING_METHOD none 20 | REORDERING_METHOD none 21 | END linear 22 | 23 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.nam: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN options 3 | END options 4 | 5 | BEGIN packages 6 | DIS6 gwf_ats01a.dis dis 7 | IC6 gwf_ats01a.ic ic 8 | NPF6 gwf_ats01a.npf npf 9 | STO6 gwf_ats01a.sto sto 10 | WEL6 gwf_ats01a.wel wel_0 11 | GHB6 gwf_ats01a.ghb ghb_0 12 | OC6 gwf_ats01a.oc oc 13 | OBS6 gwf_ats01a.obs head_obs 14 | END packages 15 | 16 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.npf: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN options 3 | END options 4 | 5 | BEGIN griddata 6 | icelltype 7 | CONSTANT 1 8 | k 9 | CONSTANT 1.00000000 10 | END griddata 11 | 12 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.obs: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN options 3 | DIGITS 20 4 | END options 5 | 6 | BEGIN continuous FILEOUT gwf_ats01a.obs.csv 7 | obs1 head 1 1 1 8 | obs2 head 1 1 2 9 | END continuous FILEOUT gwf_ats01a.obs.csv 10 | 11 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.oc: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN options 3 | BUDGET FILEOUT gwf_ats01a.cbc 4 | BUDGETCSV FILEOUT gwf_ats01a.csv 5 | HEAD FILEOUT gwf_ats01a.hds 6 | HEAD PRINT_FORMAT COLUMNS 10 WIDTH 15 DIGITS 6 GENERAL 7 | END options 8 | 9 | BEGIN period 1 10 | SAVE HEAD ALL 11 | PRINT HEAD ALL 12 | PRINT BUDGET ALL 13 | END period 1 14 | 15 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.sto: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN options 3 | END options 4 | 5 | BEGIN griddata 6 | iconvert 7 | CONSTANT 1 8 | ss 9 | CONSTANT 0.00000000 10 | sy 11 | CONSTANT 0.10000000 12 | END griddata 13 | 14 | BEGIN period 1 15 | TRANSIENT 16 | END period 1 17 | 18 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.tdis: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN options 3 | TIME_UNITS days 4 | ATS6 FILEIN gwf_ats01a.ats 5 | END options 6 | 7 | BEGIN dimensions 8 | NPER 1 9 | END dimensions 10 | 11 | BEGIN perioddata 12 | 10.00000000 1 1.00000000 13 | END perioddata 14 | 15 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/gwf_ats01a.wel: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN options 3 | PRINT_INPUT 4 | PRINT_FLOWS 5 | END options 6 | 7 | BEGIN dimensions 8 | MAXBOUND 1 9 | END dimensions 10 | 11 | BEGIN period 1 12 | 1 1 2 -10.00000000 13 | END period 1 14 | 15 | -------------------------------------------------------------------------------- /docs/examples/data/ats0/mfsim.nam: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 12/21/2022 at 10:15:53. 2 | BEGIN options 3 | END options 4 | 5 | BEGIN timing 6 | TDIS6 gwf_ats01a.tdis 7 | END timing 8 | 9 | BEGIN models 10 | gwf6 gwf_ats01a.nam gwf_ats01a 11 | END models 12 | 13 | BEGIN exchanges 14 | END exchanges 15 | 16 | BEGIN solutiongroup 1 17 | ims6 gwf_ats01a.ims gwf_ats01a 18 | END solutiongroup 1 19 | 20 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/mfsim.nam: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | END options 4 | 5 | BEGIN timing 6 | TDIS6 test_model.tdis 7 | END timing 8 | 9 | BEGIN models 10 | gwf6 test_model.nam test_model 11 | END models 12 | 13 | BEGIN exchanges 14 | END exchanges 15 | 16 | BEGIN solutiongroup 1 17 | ims6 test_model.ims test_model 18 | END solutiongroup 1 19 | 20 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.chd: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | END options 4 | 5 | BEGIN dimensions 6 | MAXBOUND 12 7 | END dimensions 8 | 9 | BEGIN period 1 10 | 1 1 3 95.00000000 11 | 1 1 4 95.00000000 12 | 1 1 5 95.00000000 13 | 1 1 6 95.00000000 14 | 1 1 7 95.00000000 15 | 1 1 8 95.00000000 16 | 1 10 3 75.00000000 17 | 1 10 4 75.00000000 18 | 1 10 5 75.00000000 19 | 1 10 6 75.00000000 20 | 1 10 7 75.00000000 21 | 1 10 8 75.00000000 22 | END period 1 23 | 24 | BEGIN period 2 25 | 1 1 3 95.00000000 26 | 1 1 4 95.00000000 27 | 1 1 5 95.00000000 28 | 1 1 6 95.00000000 29 | 1 1 7 95.00000000 30 | 1 1 8 95.00000000 31 | 1 10 3 75.00000000 32 | 1 10 4 75.00000000 33 | 1 10 5 75.00000000 34 | 1 10 6 75.00000000 35 | 1 10 7 75.00000000 36 | 1 10 8 75.00000000 37 | END period 2 38 | 39 | BEGIN period 3 40 | 1 1 3 95.00000000 41 | 1 1 4 95.00000000 42 | 1 1 5 95.00000000 43 | 1 1 6 95.00000000 44 | 1 1 7 95.00000000 45 | 1 1 8 95.00000000 46 | 1 10 3 75.00000000 47 | 1 10 4 75.00000000 48 | 1 10 5 75.00000000 49 | 1 10 6 75.00000000 50 | 1 10 7 75.00000000 51 | 1 10 8 75.00000000 52 | END period 3 53 | 54 | BEGIN period 4 55 | 1 1 3 95.00000000 56 | 1 1 4 95.00000000 57 | 1 1 5 95.00000000 58 | 1 1 6 95.00000000 59 | 1 1 7 95.00000000 60 | 1 1 8 95.00000000 61 | 1 10 3 75.00000000 62 | 1 10 4 75.00000000 63 | 1 10 5 75.00000000 64 | 1 10 6 75.00000000 65 | 1 10 7 75.00000000 66 | 1 10 8 75.00000000 67 | END period 4 68 | 69 | BEGIN period 5 70 | 1 1 3 95.00000000 71 | 1 1 4 95.00000000 72 | 1 1 5 95.00000000 73 | 1 1 6 95.00000000 74 | 1 1 7 95.00000000 75 | 1 1 8 95.00000000 76 | 1 10 3 75.00000000 77 | 1 10 4 75.00000000 78 | 1 10 5 75.00000000 79 | 1 10 6 75.00000000 80 | 1 10 7 75.00000000 81 | 1 10 8 75.00000000 82 | END period 5 83 | 84 | BEGIN period 6 85 | 1 1 3 95.00000000 86 | 1 1 4 95.00000000 87 | 1 1 5 95.00000000 88 | 1 1 6 95.00000000 89 | 1 1 7 95.00000000 90 | 1 1 8 95.00000000 91 | 1 10 3 75.00000000 92 | 1 10 4 75.00000000 93 | 1 10 5 75.00000000 94 | 1 10 6 75.00000000 95 | 1 10 7 75.00000000 96 | 1 10 8 75.00000000 97 | END period 6 98 | 99 | BEGIN period 7 100 | 1 1 3 95.00000000 101 | 1 1 4 95.00000000 102 | 1 1 5 95.00000000 103 | 1 1 6 95.00000000 104 | 1 1 7 95.00000000 105 | 1 1 8 95.00000000 106 | 1 10 3 75.00000000 107 | 1 10 4 75.00000000 108 | 1 10 5 75.00000000 109 | 1 10 6 75.00000000 110 | 1 10 7 75.00000000 111 | 1 10 8 75.00000000 112 | END period 7 113 | 114 | BEGIN period 8 115 | 1 1 3 95.00000000 116 | 1 1 4 95.00000000 117 | 1 1 5 95.00000000 118 | 1 1 6 95.00000000 119 | 1 1 7 95.00000000 120 | 1 1 8 95.00000000 121 | 1 10 3 75.00000000 122 | 1 10 4 75.00000000 123 | 1 10 5 75.00000000 124 | 1 10 6 75.00000000 125 | 1 10 7 75.00000000 126 | 1 10 8 75.00000000 127 | END period 8 128 | 129 | BEGIN period 9 130 | 1 1 3 95.00000000 131 | 1 1 4 95.00000000 132 | 1 1 5 95.00000000 133 | 1 1 6 95.00000000 134 | 1 1 7 95.00000000 135 | 1 1 8 95.00000000 136 | 1 10 3 75.00000000 137 | 1 10 4 75.00000000 138 | 1 10 5 75.00000000 139 | 1 10 6 75.00000000 140 | 1 10 7 75.00000000 141 | 1 10 8 75.00000000 142 | END period 9 143 | 144 | BEGIN period 10 145 | 1 1 3 95.00000000 146 | 1 1 4 95.00000000 147 | 1 1 5 95.00000000 148 | 1 1 6 95.00000000 149 | 1 1 7 95.00000000 150 | 1 1 8 95.00000000 151 | 1 10 3 75.00000000 152 | 1 10 4 75.00000000 153 | 1 10 5 75.00000000 154 | 1 10 6 75.00000000 155 | 1 10 7 75.00000000 156 | 1 10 8 75.00000000 157 | END period 10 158 | 159 | BEGIN period 11 160 | 1 1 3 95.00000000 161 | 1 1 4 95.00000000 162 | 1 1 5 95.00000000 163 | 1 1 6 95.00000000 164 | 1 1 7 95.00000000 165 | 1 1 8 95.00000000 166 | 1 10 3 75.00000000 167 | 1 10 4 75.00000000 168 | 1 10 5 75.00000000 169 | 1 10 6 75.00000000 170 | 1 10 7 75.00000000 171 | 1 10 8 75.00000000 172 | END period 11 173 | 174 | BEGIN period 12 175 | 1 1 3 95.00000000 176 | 1 1 4 95.00000000 177 | 1 1 5 95.00000000 178 | 1 1 6 95.00000000 179 | 1 1 7 95.00000000 180 | 1 1 8 95.00000000 181 | 1 10 3 75.00000000 182 | 1 10 4 75.00000000 183 | 1 10 5 75.00000000 184 | 1 10 6 75.00000000 185 | 1 10 7 75.00000000 186 | 1 10 8 75.00000000 187 | END period 12 188 | 189 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.dis: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | LENGTH_UNITS meters 4 | END options 5 | 6 | BEGIN dimensions 7 | NLAY 1 8 | NROW 10 9 | NCOL 10 10 | END dimensions 11 | 12 | BEGIN griddata 13 | delr 14 | CONSTANT 63.60000000 15 | delc 16 | CONSTANT 63.60000000 17 | top 18 | CONSTANT 100.00000000 19 | botm 20 | CONSTANT 0.00000000 21 | IDOMAIN 22 | INTERNAL FACTOR 1 23 | 0 0 1 1 1 1 1 1 0 0 24 | 0 1 1 1 1 1 1 1 1 0 25 | 1 1 1 1 1 1 1 1 1 1 26 | 1 1 1 1 1 1 1 1 1 1 27 | 1 1 1 1 1 1 1 1 1 1 28 | 1 1 1 1 1 1 1 1 1 1 29 | 1 1 1 1 1 1 1 1 1 1 30 | 1 1 1 1 1 1 1 1 1 1 31 | 0 1 1 1 1 1 1 1 1 0 32 | 0 0 1 1 1 1 1 1 0 0 33 | END griddata 34 | 35 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.drn: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | END options 4 | 5 | BEGIN dimensions 6 | MAXBOUND 2 7 | END dimensions 8 | 9 | BEGIN period 1 10 | 1 2 3 94.00000000 10.00000000 11 | 1 2 4 95.00000000 10.00000000 12 | END period 1 13 | 14 | BEGIN period 2 15 | 1 2 3 94.00000000 10.00000000 16 | 1 2 4 95.00000000 10.00000000 17 | END period 2 18 | 19 | BEGIN period 3 20 | 1 2 3 94.00000000 10.00000000 21 | 1 2 4 95.00000000 10.00000000 22 | END period 3 23 | 24 | BEGIN period 4 25 | 1 2 3 94.00000000 10.00000000 26 | 1 2 4 95.00000000 10.00000000 27 | END period 4 28 | 29 | BEGIN period 5 30 | 1 2 3 94.00000000 10.00000000 31 | 1 2 4 95.00000000 10.00000000 32 | END period 5 33 | 34 | BEGIN period 6 35 | 1 2 3 94.00000000 10.00000000 36 | 1 2 4 95.00000000 10.00000000 37 | END period 6 38 | 39 | BEGIN period 7 40 | 1 2 3 94.00000000 10.00000000 41 | 1 2 4 95.00000000 10.00000000 42 | END period 7 43 | 44 | BEGIN period 8 45 | 1 2 3 94.00000000 10.00000000 46 | 1 2 4 95.00000000 10.00000000 47 | END period 8 48 | 49 | BEGIN period 9 50 | 1 2 3 94.00000000 10.00000000 51 | 1 2 4 95.00000000 10.00000000 52 | END period 9 53 | 54 | BEGIN period 10 55 | 1 2 3 94.00000000 10.00000000 56 | 1 2 4 95.00000000 10.00000000 57 | END period 10 58 | 59 | BEGIN period 11 60 | 1 2 3 94.00000000 10.00000000 61 | 1 2 4 95.00000000 10.00000000 62 | END period 11 63 | 64 | BEGIN period 12 65 | 1 2 3 94.00000000 10.00000000 66 | 1 2 4 95.00000000 10.00000000 67 | END period 12 68 | 69 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.evt: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | END options 4 | 5 | BEGIN dimensions 6 | MAXBOUND 2 7 | END dimensions 8 | 9 | BEGIN period 1 10 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 11 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 12 | END period 1 13 | 14 | BEGIN period 2 15 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 16 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 17 | END period 2 18 | 19 | BEGIN period 3 20 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 21 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 22 | END period 3 23 | 24 | BEGIN period 4 25 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 26 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 27 | END period 4 28 | 29 | BEGIN period 5 30 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 31 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 32 | END period 5 33 | 34 | BEGIN period 6 35 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 36 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 37 | END period 6 38 | 39 | BEGIN period 7 40 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 41 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 42 | END period 7 43 | 44 | BEGIN period 8 45 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 46 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 47 | END period 8 48 | 49 | BEGIN period 9 50 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 51 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 52 | END period 9 53 | 54 | BEGIN period 10 55 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 56 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 57 | END period 10 58 | 59 | BEGIN period 11 60 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 61 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 62 | END period 11 63 | 64 | BEGIN period 12 65 | 1 5 4 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 66 | 1 5 5 100.00000000 0.02000000 10.00000000 0.20000000 0.10000000 67 | END period 12 68 | 69 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.ic: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN griddata 3 | strt 4 | CONSTANT 95.00000000 5 | END griddata 6 | 7 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.ims: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | PRINT_OPTION all 4 | COMPLEXITY complex 5 | NO_PTC ALL 6 | END options 7 | 8 | BEGIN nonlinear 9 | UNDER_RELAXATION dbd 10 | UNDER_RELAXATION_GAMMA 0.00000000 11 | UNDER_RELAXATION_THETA 0.97000000 12 | UNDER_RELAXATION_KAPPA 1.00000000E-04 13 | END nonlinear 14 | 15 | BEGIN linear 16 | inner_rclose 1.00000000E-10 L2NORM_RCLOSE 17 | LINEAR_ACCELERATION bicgstab 18 | SCALING_METHOD l2norm 19 | END linear 20 | 21 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.nam: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | PRINT_INPUT 4 | PRINT_FLOWS 5 | SAVE_FLOWS 6 | NEWTON UNDER_RELAXATION 7 | END options 8 | 9 | BEGIN packages 10 | DIS6 test_model.dis dis 11 | IC6 test_model.ic ic 12 | NPF6 test_model.npf npf 13 | STO6 test_model.sto sto 14 | WEL6 test_model.wel wel_0 15 | DRN6 test_model.drn drn_0 16 | RCH6 test_model.rch rch_0 17 | RCH6 test_model.rcha rcha_0 18 | CHD6 test_model.chd chd_0 19 | EVT6 test_model.evt evt_0 20 | OC6 test_model.oc oc 21 | END packages 22 | 23 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.npf: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | SAVE_SPECIFIC_DISCHARGE 4 | END options 5 | 6 | BEGIN griddata 7 | icelltype 8 | CONSTANT 1 9 | k 10 | CONSTANT 1.00000000 11 | END griddata 12 | 13 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.oc: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | BUDGET FILEOUT test_model.cbc 4 | HEAD FILEOUT test_model.hds 5 | END options 6 | 7 | BEGIN period 1 8 | SAVE HEAD ALL 9 | SAVE BUDGET ALL 10 | PRINT HEAD ALL 11 | PRINT BUDGET ALL 12 | END period 1 13 | 14 | BEGIN period 2 15 | SAVE HEAD ALL 16 | SAVE BUDGET ALL 17 | PRINT HEAD ALL 18 | PRINT BUDGET ALL 19 | END period 2 20 | 21 | BEGIN period 3 22 | SAVE HEAD ALL 23 | SAVE BUDGET ALL 24 | PRINT HEAD ALL 25 | PRINT BUDGET ALL 26 | END period 3 27 | 28 | BEGIN period 4 29 | SAVE HEAD ALL 30 | SAVE BUDGET ALL 31 | PRINT HEAD ALL 32 | PRINT BUDGET ALL 33 | END period 4 34 | 35 | BEGIN period 5 36 | SAVE HEAD ALL 37 | SAVE BUDGET ALL 38 | PRINT HEAD ALL 39 | PRINT BUDGET ALL 40 | END period 5 41 | 42 | BEGIN period 6 43 | SAVE HEAD ALL 44 | SAVE BUDGET ALL 45 | PRINT HEAD ALL 46 | PRINT BUDGET ALL 47 | END period 6 48 | 49 | BEGIN period 7 50 | SAVE HEAD ALL 51 | SAVE BUDGET ALL 52 | PRINT HEAD ALL 53 | PRINT BUDGET ALL 54 | END period 7 55 | 56 | BEGIN period 8 57 | SAVE HEAD ALL 58 | SAVE BUDGET ALL 59 | PRINT HEAD ALL 60 | PRINT BUDGET ALL 61 | END period 8 62 | 63 | BEGIN period 9 64 | SAVE HEAD ALL 65 | SAVE BUDGET ALL 66 | PRINT HEAD ALL 67 | PRINT BUDGET ALL 68 | END period 9 69 | 70 | BEGIN period 10 71 | SAVE HEAD ALL 72 | SAVE BUDGET ALL 73 | PRINT HEAD ALL 74 | PRINT BUDGET ALL 75 | END period 10 76 | 77 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.rch: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | END options 4 | 5 | BEGIN dimensions 6 | MAXBOUND 2 7 | END dimensions 8 | 9 | BEGIN period 1 10 | 1 10 3 0.25000000 11 | 1 10 4 0.25000000 12 | END period 1 13 | 14 | BEGIN period 2 15 | 1 10 3 0.25000000 16 | 1 10 4 0.25000000 17 | END period 2 18 | 19 | BEGIN period 3 20 | 1 10 3 0.25000000 21 | 1 10 4 0.25000000 22 | END period 3 23 | 24 | BEGIN period 4 25 | 1 10 3 0.25000000 26 | 1 10 4 0.25000000 27 | END period 4 28 | 29 | BEGIN period 5 30 | 1 10 3 0.25000000 31 | 1 10 4 0.25000000 32 | END period 5 33 | 34 | BEGIN period 6 35 | 1 10 3 0.25000000 36 | 1 10 4 0.25000000 37 | END period 6 38 | 39 | BEGIN period 7 40 | 1 10 3 0.25000000 41 | 1 10 4 0.25000000 42 | END period 7 43 | 44 | BEGIN period 8 45 | 1 10 3 0.25000000 46 | 1 10 4 0.25000000 47 | END period 8 48 | 49 | BEGIN period 9 50 | 1 10 3 0.25000000 51 | 1 10 4 0.25000000 52 | END period 9 53 | 54 | BEGIN period 10 55 | 1 10 3 0.25000000 56 | 1 10 4 0.25000000 57 | END period 10 58 | 59 | BEGIN period 11 60 | 1 10 3 0.25000000 61 | 1 10 4 0.25000000 62 | END period 11 63 | 64 | BEGIN period 12 65 | 1 10 3 0.25000000 66 | 1 10 4 0.25000000 67 | END period 12 68 | 69 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.rcha: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | READASARRAYS 4 | END options 5 | 6 | BEGIN period 1 7 | recharge 8 | CONSTANT 0.00100000 9 | END period 1 10 | 11 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.sto: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | END options 4 | 5 | BEGIN griddata 6 | iconvert 7 | CONSTANT 1 8 | ss 9 | CONSTANT 1.00000000E-05 10 | sy 11 | CONSTANT 0.15000000 12 | END griddata 13 | 14 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.tdis: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | TIME_UNITS days 4 | END options 5 | 6 | BEGIN dimensions 7 | NPER 12 8 | END dimensions 9 | 10 | BEGIN perioddata 11 | 31.00000000 31 1.00000000 12 | 28.00000000 28 1.00000000 13 | 31.00000000 31 1.00000000 14 | 30.00000000 30 1.00000000 15 | 31.00000000 31 1.00000000 16 | 30.00000000 30 1.00000000 17 | 31.00000000 31 1.00000000 18 | 31.00000000 31 1.00000000 19 | 30.00000000 30 1.00000000 20 | 31.00000000 31 1.00000000 21 | 30.00000000 30 1.00000000 22 | 31.00000000 31 1.00000000 23 | END perioddata 24 | 25 | -------------------------------------------------------------------------------- /docs/examples/data/dis_model/test_model.wel: -------------------------------------------------------------------------------- 1 | # File generated by Flopy version 3.3.6 on 10/07/2022 at 11:12:19. 2 | BEGIN options 3 | AUXILIARY TEST1 TEST2 4 | END options 5 | 6 | BEGIN dimensions 7 | MAXBOUND 10 8 | END dimensions 9 | 10 | BEGIN period 1 11 | 1 6 5 -150.00000000 1.0 2.0 12 | 1 2 3 -100.00000000 1.0 2.0 13 | 1 4 6 -50.0000000000 1.0 2.0 14 | END period 1 15 | 16 | BEGIN period 2 17 | 1 6 5 -100.00000000 1.0 2.0 18 | 1 2 3 -50.00000000 1.0 2.0 19 | 1 4 6 -50.0000000000 1.0 2.0 20 | END period 2 21 | 22 | BEGIN period 3 23 | 1 6 5 -0.00000000 1.0 2.0 24 | 1 2 3 -0.00000000 1.0 2.0 25 | 1 4 6 -50.0000000000 1.0 2.0 26 | END period 3 27 | 28 | BEGIN period 4 29 | 1 6 5 -10.00000000 1.0 2.0 30 | 1 2 3 -0.00000000 1.0 2.0 31 | 1 4 6 -5.0000000000 1.0 2.0 32 | END period 4 33 | 34 | BEGIN period 5 35 | 1 6 5 -150.00000000 1.0 2.0 36 | 1 2 3 -200.00000000 1.0 2.0 37 | 1 4 6 -350.0000000000 1.0 2.0 38 | END period 5 39 | 40 | BEGIN period 6 41 | 1 6 5 -100.00000000 1.0 2.0 42 | 1 2 3 -10.00000000 1.0 2.0 43 | 1 4 6 -80.0000000000 1.0 2.0 44 | END period 6 45 | 46 | BEGIN period 7 47 | 1 6 5 -10.00000000 1.0 2.0 48 | 1 2 3 -50.00000000 1.0 2.0 49 | 1 4 6 -50.0000000000 1.0 2.0 50 | END period 7 51 | 52 | BEGIN period 8 53 | 1 6 5 -100.00000000 1.0 2.0 54 | 1 2 3 -50.00000000 1.0 2.0 55 | 1 4 6 -50.0000000000 1.0 2.0 56 | END period 8 57 | 58 | BEGIN period 9 59 | 1 6 5 -100.00000000 1.0 2.0 60 | 1 2 3 -50.00000000 1.0 2.0 61 | 1 4 6 -50.0000000000 1.0 2.0 62 | END period 9 63 | 64 | BEGIN period 10 65 | 1 6 5 -100.00000000 1.0 2.0 66 | 1 2 3 -50.00000000 1.0 2.0 67 | 1 4 6 -50.0000000000 1.0 2.0 68 | END period 10 69 | 70 | BEGIN period 11 71 | 1 6 5 -100.00000000 1.0 2.0 72 | 1 2 3 -50.00000000 1.0 2.0 73 | 1 4 6 -50.0000000000 1.0 2.0 74 | END period 11 75 | 76 | BEGIN period 12 77 | 1 6 5 -100.00000000 1.0 2.0 78 | 1 2 3 -50.00000000 1.0 2.0 79 | 1 4 6 -50.0000000000 1.0 2.0 80 | END period 12 81 | 82 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.chd: -------------------------------------------------------------------------------- 1 | begin options 2 | PRINT_INPUT 3 | PRINT_FLOWS 4 | SAVE_FLOWS 5 | end options 6 | 7 | begin dimensions 8 | MAXBOUND 14 9 | end dimensions 10 | 11 | begin period 1 12 | 1 1. 13 | 8 1. 14 | 15 1. 15 | 19 1. 16 | 23 1. 17 | 27 1. 18 | 34 1. 19 | 20 | 7 0. 21 | 14 0. 22 | 18 0. 23 | 22 0. 24 | 26 0. 25 | 33 0. 26 | 40 0. 27 | end period 28 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.disu: -------------------------------------------------------------------------------- 1 | # Unstructured discretization file for MODFLOW-USG 2 | begin options 3 | LENGTH_UNITS meters 4 | end options 5 | 6 | begin dimensions 7 | nodes 121 8 | nja 601 9 | end dimensions 10 | 11 | BEGIN GRIDDATA 12 | top 13 | constant 0. 14 | bot 15 | constant -100. 16 | area 17 | open/close 'flow.disu.area.dat' FACTOR 1.0 IPRN 0 18 | END GRIDDATA 19 | 20 | begin connectiondata 21 | ihc 22 | constant 1 23 | iac 24 | open/close 'flow.disu.iac.dat' FACTOR 1 IPRN 0 25 | ja 26 | open/close 'flow.disu.ja.dat' FACTOR 1 IPRN 0 27 | cl12 28 | open/close 'flow.disu.cl12.dat' FACTOR 1.0 IPRN 0 29 | hwva 30 | open/close 'flow.disu.hwva.dat' FACTOR 1.0 IPRN 0 31 | end connectiondata 32 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.disu.area.dat: -------------------------------------------------------------------------------- 1 | 10000 10000 10000 10000 10000 2 | 10000 10000 10000 10000 10000 3 | 10000 10000 10000 10000 10000 4 | 10000 10000 10000 10000 10000 5 | 10000 10000 10000 10000 10000 6 | 10000 10000 10000 10000 10000 7 | 10000 10000 10000 10000 10000 8 | 10000 10000 10000 10000 10000 9 | 1111.11 1111.11 1111.11 1111.11 1111.11 10 | 1111.11 1111.11 1111.11 1111.11 1111.11 11 | 1111.11 1111.11 1111.11 1111.11 1111.11 12 | 1111.11 1111.11 1111.11 1111.11 1111.11 13 | 1111.11 1111.11 1111.11 1111.11 1111.11 14 | 1111.11 1111.11 1111.11 1111.11 1111.11 15 | 1111.11 1111.11 1111.11 1111.11 1111.11 16 | 1111.11 1111.11 1111.11 1111.11 1111.11 17 | 1111.11 1111.11 1111.11 1111.11 1111.11 18 | 1111.11 1111.11 1111.11 1111.11 1111.11 19 | 1111.11 1111.11 1111.11 1111.11 1111.11 20 | 1111.11 1111.11 1111.11 1111.11 1111.11 21 | 1111.11 1111.11 1111.11 1111.11 1111.11 22 | 1111.11 1111.11 1111.11 1111.11 1111.11 23 | 1111.11 1111.11 1111.11 1111.11 1111.11 24 | 1111.11 1111.11 1111.11 1111.11 1111.11 25 | 1111.11 26 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.disu.cl12.dat: -------------------------------------------------------------------------------- 1 | 0 50 50 0 50 2 | 50 50 0 50 50 3 | 50 0 50 50 50 4 | 0 50 50 50 0 5 | 50 50 50 0 50 6 | 50 0 50 50 50 7 | 0 50 50 50 50 8 | 0 50 50 50 50 9 | 50 50 0 50 50 10 | 50 50 50 50 0 11 | 50 50 50 50 50 12 | 50 0 50 50 50 13 | 50 0 50 50 50 14 | 0 50 50 50 0 15 | 50 50 50 50 50 16 | 50 0 50 50 50 17 | 50 50 50 0 50 18 | 50 50 0 50 50 19 | 50 0 50 50 50 20 | 50 50 50 0 50 21 | 50 50 50 50 50 22 | 0 50 50 50 0 23 | 50 50 50 0 50 24 | 50 50 50 50 50 25 | 0 50 50 50 50 26 | 50 50 0 50 50 27 | 50 0 50 50 50 28 | 0 50 50 50 50 29 | 0 50 50 50 50 30 | 50 50 0 50 50 31 | 50 50 50 50 0 32 | 50 50 50 50 50 33 | 50 0 50 50 50 34 | 50 0 50 50 50 35 | 0 50 50 0 50 36 | 50 50 0 50 50 37 | 50 0 50 50 50 38 | 0 50 50 50 0 39 | 50 50 50 0 50 40 | 50 0 16.6667 16.6667 16.6667 41 | 16.6667 0 16.6667 16.6667 16.6667 42 | 16.6667 0 16.6667 16.6667 16.6667 43 | 16.6667 0 16.6667 16.6667 16.6667 44 | 16.6667 0 16.6667 16.6667 16.6667 45 | 16.6667 0 16.6667 16.6667 16.6667 46 | 16.6667 0 16.6667 16.6667 16.6667 47 | 16.6667 0 16.6667 16.6667 16.6667 48 | 16.6667 0 16.6667 16.6667 16.6667 49 | 16.6667 0 16.6667 16.6667 16.6667 50 | 16.6667 0 16.6667 16.6667 16.6667 51 | 16.6667 0 16.6667 16.6667 16.6667 52 | 16.6667 0 16.6667 16.6667 16.6667 53 | 16.6667 0 16.6667 16.6667 16.6667 54 | 16.6667 0 16.6667 16.6667 16.6667 55 | 16.6667 0 16.6667 16.6667 16.6667 56 | 16.6667 0 16.6667 16.6667 16.6667 57 | 16.6667 0 16.6667 16.6667 16.6667 58 | 16.6667 0 16.6667 16.6667 16.6667 59 | 16.6667 0 16.6667 16.6667 16.6667 60 | 16.6667 0 16.6667 16.6667 16.6667 61 | 16.6667 0 16.6667 16.6667 16.6667 62 | 16.6667 0 16.6667 16.6667 16.6667 63 | 16.6667 0 16.6667 16.6667 16.6667 64 | 16.6667 0 16.6667 16.6667 16.6667 65 | 16.6667 0 16.6667 16.6667 16.6667 66 | 16.6667 0 16.6667 16.6667 16.6667 67 | 16.6667 0 16.6667 16.6667 16.6667 68 | 16.6667 0 16.6667 16.6667 16.6667 69 | 16.6667 0 16.6667 16.6667 16.6667 70 | 16.6667 0 16.6667 16.6667 16.6667 71 | 16.6667 0 16.6667 16.6667 16.6667 72 | 16.6667 0 16.6667 16.6667 16.6667 73 | 16.6667 0 16.6667 16.6667 16.6667 74 | 16.6667 0 16.6667 16.6667 16.6667 75 | 16.6667 0 16.6667 16.6667 16.6667 76 | 16.6667 0 16.6667 16.6667 16.6667 77 | 16.6667 0 16.6667 16.6667 16.6667 78 | 16.6667 0 16.6667 16.6667 16.6667 79 | 16.6667 0 16.6667 16.6667 16.6667 80 | 16.6667 0 16.6667 16.6667 16.6667 81 | 16.6667 0 16.6667 16.6667 16.6667 82 | 16.6667 0 16.6667 16.6667 16.6667 83 | 16.6667 0 16.6667 16.6667 16.6667 84 | 16.6667 0 16.6667 16.6667 16.6667 85 | 16.6667 0 16.6667 16.6667 16.6667 86 | 16.6667 0 16.6667 16.6667 16.6667 87 | 16.6667 0 16.6667 16.6667 16.6667 88 | 16.6667 0 16.6667 16.6667 16.6667 89 | 16.6667 0 16.6667 16.6667 16.6667 90 | 16.6667 0 16.6667 16.6667 16.6667 91 | 16.6667 0 16.6667 16.6667 16.6667 92 | 16.6667 0 16.6667 16.6667 16.6667 93 | 16.6667 0 16.6667 16.6667 16.6667 94 | 16.6667 0 16.6667 16.6667 16.6667 95 | 16.6667 0 16.6667 16.6667 16.6667 96 | 16.6667 0 16.6667 16.6667 16.6667 97 | 16.6667 0 16.6667 16.6667 16.6667 98 | 16.6667 0 16.6667 16.6667 16.6667 99 | 16.6667 0 16.6667 16.6667 16.6667 100 | 16.6667 0 16.6667 16.6667 16.6667 101 | 16.6667 0 16.6667 16.6667 16.6667 102 | 16.6667 0 16.6667 16.6667 16.6667 103 | 16.6667 0 16.6667 16.6667 16.6667 104 | 16.6667 0 16.6667 16.6667 16.6667 105 | 16.6667 0 16.6667 16.6667 16.6667 106 | 16.6667 0 16.6667 16.6667 16.6667 107 | 16.6667 0 16.6667 16.6667 16.6667 108 | 16.6667 0 16.6667 16.6667 16.6667 109 | 16.6667 0 16.6667 16.6667 16.6667 110 | 16.6667 0 16.6667 16.6667 16.6667 111 | 16.6667 0 16.6667 16.6667 16.6667 112 | 16.6667 0 16.6667 16.6667 16.6667 113 | 16.6667 0 16.6667 16.6667 16.6667 114 | 16.6667 0 16.6667 16.6667 16.6667 115 | 16.6667 0 16.6667 16.6667 16.6667 116 | 16.6667 0 16.6667 16.6667 16.6667 117 | 16.6667 0 16.6667 16.6667 16.6667 118 | 16.6667 0 16.6667 16.6667 16.6667 119 | 16.6667 0 16.6667 16.6667 16.6667 120 | 16.6667 0 16.6667 16.6667 16.6667 121 | 16.6667 122 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.disu.hwva.dat: -------------------------------------------------------------------------------- 1 | 0 100. 100. 2 | 0 100. 100. 100. 3 | 0 100. 100. 100. 4 | 0 100. 100. 100. 5 | 0 100. 100. 100. 6 | 0 100. 100. 100. 7 | 0 100. 100. 8 | 0 100. 100. 100. 9 | 0 100. 100. 100. 100. 10 | 0 100. 100. 100. 33.33 33.33 33.33 11 | 0 100. 100. 100. 33.33 33.33 33.33 12 | 0 100. 100. 100. 33.33 33.33 33.33 13 | 0 100. 100. 100. 100. 14 | 0 100. 100. 100. 15 | 0 100. 100. 100. 16 | 0 100. 100. 100. 33.33 33.33 33.33 17 | 0 100. 100. 100. 33.33 33.33 33.33 18 | 0 100. 100. 100. 19 | 0 100. 100. 100. 20 | 0 100. 100. 100. 33.33 33.33 33.33 21 | 0 100. 100. 100. 33.33 33.33 33.33 22 | 0 100. 100. 100. 23 | 0 100. 100. 100. 24 | 0 100. 100. 100. 33.33 33.33 33.33 25 | 0 100. 100. 100. 33.33 33.33 33.33 26 | 0 100. 100. 100. 27 | 0 100. 100. 100. 28 | 0 100. 100. 100. 100. 29 | 0 100. 100. 100. 33.33 33.33 33.33 30 | 0 100. 100. 100. 33.33 33.33 33.33 31 | 0 100. 100. 100. 33.33 33.33 33.33 32 | 0 100. 100. 100. 100. 33 | 0 100. 100. 100. 34 | 0 100. 100. 35 | 0 100. 100. 100. 36 | 0 100. 100. 100. 37 | 0 100. 100. 100. 38 | 0 100. 100. 100. 39 | 0 100. 100. 100. 40 | 0 100. 100. 41 | 0 33.33 33.33 33.33 33.33 42 | 0 33.33 33.33 33.33 33.33 43 | 0 33.33 33.33 33.33 33.33 44 | 0 33.33 33.33 33.33 33.33 45 | 0 33.33 33.33 33.33 33.33 46 | 0 33.33 33.33 33.33 33.33 47 | 0 33.33 33.33 33.33 33.33 48 | 0 33.33 33.33 33.33 33.33 49 | 0 33.33 33.33 33.33 33.33 50 | 0 33.33 33.33 33.33 33.33 51 | 0 33.33 33.33 33.33 33.33 52 | 0 33.33 33.33 33.33 33.33 53 | 0 33.33 33.33 33.33 33.33 54 | 0 33.33 33.33 33.33 33.33 55 | 0 33.33 33.33 33.33 33.33 56 | 0 33.33 33.33 33.33 33.33 57 | 0 33.33 33.33 33.33 33.33 58 | 0 33.33 33.33 33.33 33.33 59 | 0 33.33 33.33 33.33 33.33 60 | 0 33.33 33.33 33.33 33.33 61 | 0 33.33 33.33 33.33 33.33 62 | 0 33.33 33.33 33.33 33.33 63 | 0 33.33 33.33 33.33 33.33 64 | 0 33.33 33.33 33.33 33.33 65 | 0 33.33 33.33 33.33 33.33 66 | 0 33.33 33.33 33.33 33.33 67 | 0 33.33 33.33 33.33 33.33 68 | 0 33.33 33.33 33.33 33.33 69 | 0 33.33 33.33 33.33 33.33 70 | 0 33.33 33.33 33.33 33.33 71 | 0 33.33 33.33 33.33 33.33 72 | 0 33.33 33.33 33.33 33.33 73 | 0 33.33 33.33 33.33 33.33 74 | 0 33.33 33.33 33.33 33.33 75 | 0 33.33 33.33 33.33 33.33 76 | 0 33.33 33.33 33.33 33.33 77 | 0 33.33 33.33 33.33 33.33 78 | 0 33.33 33.33 33.33 33.33 79 | 0 33.33 33.33 33.33 33.33 80 | 0 33.33 33.33 33.33 33.33 81 | 0 33.33 33.33 33.33 33.33 82 | 0 33.33 33.33 33.33 33.33 83 | 0 33.33 33.33 33.33 33.33 84 | 0 33.33 33.33 33.33 33.33 85 | 0 33.33 33.33 33.33 33.33 86 | 0 33.33 33.33 33.33 33.33 87 | 0 33.33 33.33 33.33 33.33 88 | 0 33.33 33.33 33.33 33.33 89 | 0 33.33 33.33 33.33 33.33 90 | 0 33.33 33.33 33.33 33.33 91 | 0 33.33 33.33 33.33 33.33 92 | 0 33.33 33.33 33.33 33.33 93 | 0 33.33 33.33 33.33 33.33 94 | 0 33.33 33.33 33.33 33.33 95 | 0 33.33 33.33 33.33 33.33 96 | 0 33.33 33.33 33.33 33.33 97 | 0 33.33 33.33 33.33 33.33 98 | 0 33.33 33.33 33.33 33.33 99 | 0 33.33 33.33 33.33 33.33 100 | 0 33.33 33.33 33.33 33.33 101 | 0 33.33 33.33 33.33 33.33 102 | 0 33.33 33.33 33.33 33.33 103 | 0 33.33 33.33 33.33 33.33 104 | 0 33.33 33.33 33.33 33.33 105 | 0 33.33 33.33 33.33 33.33 106 | 0 33.33 33.33 33.33 33.33 107 | 0 33.33 33.33 33.33 33.33 108 | 0 33.33 33.33 33.33 33.33 109 | 0 33.33 33.33 33.33 33.33 110 | 0 33.33 33.33 33.33 33.33 111 | 0 33.33 33.33 33.33 33.33 112 | 0 33.33 33.33 33.33 33.33 113 | 0 33.33 33.33 33.33 33.33 114 | 0 33.33 33.33 33.33 33.33 115 | 0 33.33 33.33 33.33 33.33 116 | 0 33.33 33.33 33.33 33.33 117 | 0 33.33 33.33 33.33 33.33 118 | 0 33.33 33.33 33.33 33.33 119 | 0 33.33 33.33 33.33 33.33 120 | 0 33.33 33.33 33.33 33.33 121 | 0 33.33 33.33 33.33 33.33 122 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.disu.iac.dat: -------------------------------------------------------------------------------- 1 | 3 4 4 4 4 2 | 4 3 4 5 7 3 | 7 7 5 4 4 4 | 7 7 4 4 7 5 | 7 4 4 7 7 6 | 4 4 5 7 7 7 | 7 5 4 3 4 8 | 4 4 4 4 3 9 | 5 5 5 5 5 10 | 5 5 5 5 5 11 | 5 5 5 5 5 12 | 5 5 5 5 5 13 | 5 5 5 5 5 14 | 5 5 5 5 5 15 | 5 5 5 5 5 16 | 5 5 5 5 5 17 | 5 5 5 5 5 18 | 5 5 5 5 5 19 | 5 5 5 5 5 20 | 5 5 5 5 5 21 | 5 5 5 5 5 22 | 5 5 5 5 5 23 | 5 5 5 5 5 24 | 5 5 5 5 5 25 | 5 26 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.disu.ja.dat: -------------------------------------------------------------------------------- 1 | 1 2 8 2 1 2 | 3 9 3 2 4 3 | 10 4 3 5 11 4 | 5 4 6 12 6 5 | 5 7 13 7 6 6 | 14 8 1 9 15 7 | 9 2 8 10 16 8 | 10 3 9 11 41 9 | 42 43 11 4 10 10 | 12 44 45 46 12 11 | 5 11 13 47 48 12 | 49 13 6 12 14 13 | 17 14 7 13 18 14 | 15 8 16 19 16 15 | 9 15 20 41 50 16 | 59 17 13 18 21 17 | 49 58 67 18 14 18 | 17 22 19 15 20 19 | 23 20 16 19 24 20 | 68 77 86 21 17 21 | 22 25 76 85 94 22 | 22 18 21 26 23 23 | 19 24 27 24 20 24 | 23 28 95 104 113 25 | 25 21 26 32 103 26 | 112 121 26 22 25 27 | 33 27 23 28 34 28 | 28 24 27 29 35 29 | 29 28 30 36 113 30 | 114 115 30 29 31 31 | 37 116 117 118 31 32 | 30 32 38 119 120 33 | 121 32 25 31 33 34 | 39 33 26 32 40 35 | 34 27 35 35 28 36 | 34 36 36 29 35 37 | 37 37 30 36 38 38 | 38 31 37 39 39 39 | 32 38 40 40 33 40 | 39 41 10 16 42 41 | 50 42 10 41 43 42 | 51 43 10 42 44 43 | 52 44 11 43 45 44 | 53 45 11 44 46 45 | 54 46 11 45 47 46 | 55 47 12 46 48 47 | 56 48 12 47 49 48 | 57 49 12 17 48 49 | 58 50 16 41 51 50 | 59 51 42 50 52 51 | 60 52 43 51 53 52 | 61 53 44 52 54 53 | 62 54 45 53 55 54 | 63 55 46 54 56 55 | 64 56 47 55 57 56 | 65 57 48 56 58 57 | 66 58 17 49 57 58 | 67 59 16 50 60 59 | 68 60 51 59 61 60 | 69 61 52 60 62 61 | 70 62 53 61 63 62 | 71 63 54 62 64 63 | 72 64 55 63 65 64 | 73 65 56 64 66 65 | 74 66 57 65 67 66 | 75 67 17 58 66 67 | 76 68 20 59 69 68 | 77 69 60 68 70 69 | 78 70 61 69 71 70 | 79 71 62 70 72 71 | 80 72 63 71 73 72 | 81 73 64 72 74 73 | 82 74 65 73 75 74 | 83 75 66 74 76 75 | 84 76 21 67 75 76 | 85 77 20 68 78 77 | 86 78 69 77 79 78 | 87 79 70 78 80 79 | 88 80 71 79 81 80 | 89 81 72 80 82 81 | 90 82 73 81 83 82 | 91 83 74 82 84 83 | 92 84 75 83 85 84 | 93 85 21 76 84 85 | 94 86 20 77 87 86 | 95 87 78 86 88 87 | 96 88 79 87 89 88 | 97 89 80 88 90 89 | 98 90 81 89 91 90 | 99 91 82 90 92 91 | 100 92 83 91 93 92 | 101 93 84 92 94 93 | 102 94 21 85 93 94 | 103 95 24 86 96 95 | 104 96 87 95 97 96 | 105 97 88 96 98 97 | 106 98 89 97 99 98 | 107 99 90 98 100 99 | 108 100 91 99 101 100 | 109 101 92 100 102 101 | 110 102 93 101 103 102 | 111 103 25 94 102 103 | 112 104 24 95 105 104 | 113 105 96 104 106 105 | 114 106 97 105 107 106 | 115 107 98 106 108 107 | 116 108 99 107 109 108 | 117 109 100 108 110 109 | 118 110 101 109 111 110 | 119 111 102 110 112 111 | 120 112 25 103 111 112 | 121 113 24 29 104 113 | 114 114 29 105 113 114 | 115 115 29 106 114 115 | 116 116 30 107 115 116 | 117 117 30 108 116 117 | 118 118 30 109 117 118 | 119 119 31 110 118 119 | 120 120 31 111 119 120 | 121 121 25 31 112 121 | 120 122 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.ic: -------------------------------------------------------------------------------- 1 | # Basic package file for MODFLOW-USG, generated by Flopy. 2 | begin options 3 | end options 4 | 5 | BEGIN GRIDDATA 6 | strt 7 | INTERNAL FACTOR 1 IPRN 3 8 | 1 0 0 0 0 9 | 0 0 1 0 0 10 | 0 0 0 0 1 11 | 0 0 0 1 0 12 | 0 0 1 0 0 13 | 0 1 0 0 0 14 | 0 0 0 1 0 15 | 0 0 0 0 0 16 | 0 0 0 0 0 17 | 0 0 0 0 0 18 | 0 0 0 0 0 19 | 0 0 0 0 0 20 | 0 0 0 0 0 21 | 0 0 0 0 0 22 | 0 0 0 0 0 23 | 0 0 0 0 0 24 | 0 0 0 0 0 25 | 0 0 0 0 0 26 | 0 0 0 0 0 27 | 0 0 0 0 0 28 | 0 0 0 0 0 29 | 0 0 0 0 0 30 | 0 0 0 0 0 31 | 0 0 0 0 0 32 | 0 33 | END GRIDDATA -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.ims: -------------------------------------------------------------------------------- 1 | begin options 2 | PRINT_OPTION SUMMARY 3 | end options 4 | 5 | begin nonlinear 6 | OUTER_DVCLOSE 1.e-8 7 | outer_maximum 1000 8 | under_relaxation none 9 | end nonlinear 10 | 11 | begin linear 12 | INNER_DVCLOSE 1.0e-8 13 | inner_rclose 0.01 14 | inner_maximum 1000 15 | linear_acceleration cg 16 | scaling_method none 17 | REORDERING_METHOD none 18 | relaxation_factor 0.97 19 | end linear 20 | 21 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.nam: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | END OPTIONS 3 | 4 | BEGIN PACKAGES 5 | DISU6 flow.disu 6 | IC6 flow.ic 7 | CHD6 flow.chd 8 | NPF6 flow.npf 9 | RCH6 flow.rch 10 | OC6 flow.oc 11 | END PACKAGES 12 | 13 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.npf: -------------------------------------------------------------------------------- 1 | begin options 2 | SAVE_FLOWS 3 | end options 4 | # 5 | BEGIN GRIDDATA 6 | # 7 | #apply these arrays for the entire simulation 8 | # 9 | #icelltype(nodes) is 0:confined, 1:convertible, 4:upstream? 10 | icelltype 11 | constant 0 12 | # 13 | #K(nodes) horizontal hydraulic conductivity 14 | K 15 | constant 1. 16 | # 17 | #K33(nodes) vertical hydraulic conductivity 18 | K33 19 | constant 1. 20 | # 21 | #this will crash it funkyarray 22 | # constant 23 | END GRIDDATA 24 | 25 | 26 | 50 -1.0e+30 0 0 27 | 0 28 | 0 29 | 1 30 | 1 31 | 0 32 | 0 1.000e+00 (10G13.0) -1 HK() = Horizontal hydraulic conductivity of layer 1 33 | 0 1.000e+00 (10G13.0) -1 VKA() = Vertical hydraulic conductivity of layer 1 34 | 0 0.000e+00 (10G13.0) -1 WETDRY() = Wetting threshold of layer 1 35 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.oc: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | HEAD FILEOUT flow.hds 3 | BUDGET FILEOUT flow.cbc 4 | END OPTIONS 5 | 6 | BEGIN PERIOD 1 7 | PRINT BUDGET ALL 8 | SAVE BUDGET ALL 9 | PRINT HEAD ALL 10 | SAVE HEAD ALL 11 | END PERIOD 12 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.rch: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | FIXED_CELL 3 | END OPTIONS 4 | 5 | BEGIN DIMENSIONS 6 | MAXBOUND 10 7 | END DIMENSIONS 8 | 9 | BEGIN PERIOD 1 10 | 1 0.000 11 | 2 0.000 12 | 3 0.000 13 | 4 0.000 14 | 5 0.000 15 | 6 0.000 16 | 7 0.000 17 | 8 0.000 18 | 9 0.000 19 | 10 0.000 20 | END PERIOD 1 21 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/flow.tdis: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | TIME_UNITS DAYS 3 | END OPTIONS 4 | 5 | BEGIN DIMENSIONS 6 | NPER 1 7 | END DIMENSIONS 8 | 9 | BEGIN PERIODDATA 10 | #perlen nstp tsmult 11 | 1.0 1 1.0 12 | END PERIODDATA 13 | -------------------------------------------------------------------------------- /docs/examples/data/disu_model/mfsim.nam: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | END OPTIONS 3 | 4 | BEGIN TIMING 5 | TDIS6 flow.tdis 6 | END TIMING 7 | 8 | BEGIN MODELS 9 | #modeltype namefile modelname 10 | GWF6 flow.nam GWF_1 11 | END MODELS 12 | 13 | BEGIN EXCHANGES 14 | END EXCHANGES 15 | 16 | BEGIN SOLUTIONGROUP 1 17 | MXITER 1 18 | IMS6 flow.ims GWF_1 19 | END SOLUTIONGROUP 20 | -------------------------------------------------------------------------------- /docs/examples/data/disv_model/mfsim.nam: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | END OPTIONS 3 | 4 | BEGIN TIMING 5 | TDIS6 simulation.tdis 6 | END TIMING 7 | 8 | BEGIN MODELS 9 | #modeltype namefile modelname 10 | GWF6 tri_model.nam GWF_1 11 | END MODELS 12 | 13 | BEGIN EXCHANGES 14 | END EXCHANGES 15 | 16 | BEGIN SOLUTIONGROUP 1 17 | MXITER 1 18 | IMS6 model.ims GWF_1 19 | END SOLUTIONGROUP 20 | -------------------------------------------------------------------------------- /docs/examples/data/disv_model/model.ims: -------------------------------------------------------------------------------- 1 | begin options 2 | PRINT_OPTION SUMMARY 3 | end options 4 | 5 | begin nonlinear 6 | OUTER_DVCLOSE 1.e-4 7 | outer_maximum 500 8 | under_relaxation none 9 | end nonlinear 10 | 11 | begin linear 12 | INNER_DVCLOSE 1.0e-4 13 | inner_rclose 0.001 14 | #L2NORM_RCLOSE 15 | inner_maximum 100 16 | linear_acceleration cg 17 | scaling_method none 18 | REORDERING_METHOD none 19 | relaxation_factor 0.97 20 | end linear 21 | 22 | 23 | 24 | 1.0E-4 1.0E-4 500 100 1 0 002 #hclose, hiclose,mxiter,iter1,iprsms,nonmeth,linmeth 25 | #PCGU [option: "bcgs", "cg"] ipc iscl iord rclosepcgu relax 26 | cg 3 0 0 0.001 0.97 27 | # bcgs 3 0 0 0.001 0.97 28 | 29 | 1.0E-4 1.0E-4 500 100 1 0 001 #hclose, hiclose,mxiter,iter1,iprsms,nonmeth,linmeth 30 | 2 0 0 2 0 0 0 1e-3 31 | IACL NORDER LEVEL NORTH IREDSYS RRCTOL IDROPTOL EPSRN 32 | 33 | 34 | 35 | 0.0001 0.0001 500 100 1 0 1 36 | 2 0 0 2 0 0 0 1e-3 37 | IACL NORDER LEVEL NORTH IREDSYS RRCTOL IDROPTOL EPSRN 38 | 39 | 0.0001 0.0001 500 100 1 0 5 40 | 3 0 0 100000 41 | -------------------------------------------------------------------------------- /docs/examples/data/disv_model/simulation.tdis: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | TIME_UNITS MINUTES 3 | END OPTIONS 4 | 5 | BEGIN DIMENSIONS 6 | NPER 1 7 | END DIMENSIONS 8 | 9 | BEGIN PERIODDATA 10 | #perlen nstp tsmult 11 | 1.0 1 1.0 12 | END PERIODDATA 13 | -------------------------------------------------------------------------------- /docs/examples/data/disv_model/tri_model.ic: -------------------------------------------------------------------------------- 1 | # Basic package file for MODFLOW, generated by Flopy. 2 | begin options 3 | end options 4 | 5 | BEGIN GRIDDATA 6 | strt 7 | constant 1. 8 | END GRIDDATA 9 | -------------------------------------------------------------------------------- /docs/examples/data/disv_model/tri_model.nam: -------------------------------------------------------------------------------- 1 | # Name file for mf2005, generated by Flopy. 2 | BEGIN PACKAGES 3 | DISV6 tri_model_cnst.disv 4 | IC6 tri_model.ic 5 | NPF6 tri_model.npf 6 | CHD6 tri_model_left.chd CHD_LEFT 7 | CHD6 tri_model_right.chd CHD_RIGHT 8 | OC6 tri_model.oc 9 | END PACKAGES 10 | 11 | -------------------------------------------------------------------------------- /docs/examples/data/disv_model/tri_model.npf: -------------------------------------------------------------------------------- 1 | begin options 2 | PRINT_FLOWS 3 | SAVE_FLOWS 4 | SAVE_SPECIFIC_DISCHARGE 5 | end options 6 | # 7 | BEGIN GRIDDATA 8 | #icelltype(nodes) is 0:confined, 1:convertible, 4:upstream? 9 | icelltype 10 | constant 0 11 | # 12 | K 13 | constant 1.0 k Layer 1 14 | K33 15 | constant 1.0 K33 Layer 1 16 | k22 17 | constant 1.0 18 | END GRIDDATA -------------------------------------------------------------------------------- /docs/examples/data/disv_model/tri_model.oc: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | HEAD FILEOUT tri_model.hds 3 | BUDGET FILEOUT tri_model.cbc 4 | END OPTIONS 5 | 6 | BEGIN PERIOD 1 7 | PRINT BUDGET ALL 8 | SAVE BUDGET ALL 9 | PRINT HEAD ALL 10 | SAVE HEAD ALL 11 | END PERIOD 12 | 13 | -------------------------------------------------------------------------------- /docs/examples/data/disv_model/tri_model_cnst.disv: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | END OPTIONS 3 | 4 | BEGIN DIMENSIONS 5 | NCPL 200 6 | NLAY 4 7 | NVERT 121 8 | END DIMENSIONS 9 | 10 | BEGIN GRIDDATA 11 | TOP 12 | CONSTANT 2.0 13 | BOTM LAYERED 14 | CONSTANT 1.5 15 | CONSTANT 1.0 16 | CONSTANT 0.5 17 | CONSTANT 0.0 18 | IDOMAIN LAYERED 19 | INTERNAL FACTOR 1 IPRN -1 20 | 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 21 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 22 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 24 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 25 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 26 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 27 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 28 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 29 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 30 | CONSTANT 1 31 | CONSTANT 1 32 | CONSTANT 1 33 | END GRIDDATA 34 | 35 | BEGIN VERTICES 36 | 1 0.0 10.0 37 | 2 1.0 10.0 38 | 3 2.0 10.0 39 | 4 3.0 10.0 40 | 5 4.0 10.0 41 | 6 5.0 10.0 42 | 7 6.0 10.0 43 | 8 7.0 10.0 44 | 9 8.0 10.0 45 | 10 9.0 10.0 46 | 11 10.0 10.0 47 | 12 0.0 9.0 48 | 13 1.0 9.0 49 | 14 2.0 9.0 50 | 15 3.0 9.0 51 | 16 4.0 9.0 52 | 17 5.0 9.0 53 | 18 6.0 9.0 54 | 19 7.0 9.0 55 | 20 8.0 9.0 56 | 21 9.0 9.0 57 | 22 10.0 9.0 58 | 23 0.0 8.0 59 | 24 1.0 8.0 60 | 25 2.0 8.0 61 | 26 3.0 8.0 62 | 27 4.0 8.0 63 | 28 5.0 8.0 64 | 29 6.0 8.0 65 | 30 7.0 8.0 66 | 31 8.0 8.0 67 | 32 9.0 8.0 68 | 33 10.0 8.0 69 | 34 0.0 7.0 70 | 35 1.0 7.0 71 | 36 2.0 7.0 72 | 37 3.0 7.0 73 | 38 4.0 7.0 74 | 39 5.0 7.0 75 | 40 6.0 7.0 76 | 41 7.0 7.0 77 | 42 8.0 7.0 78 | 43 9.0 7.0 79 | 44 10.0 7.0 80 | 45 0.0 6.0 81 | 46 1.0 6.0 82 | 47 2.0 6.0 83 | 48 3.0 6.0 84 | 49 4.0 6.0 85 | 50 5.0 6.0 86 | 51 6.0 6.0 87 | 52 7.0 6.0 88 | 53 8.0 6.0 89 | 54 9.0 6.0 90 | 55 10.0 6.0 91 | 56 0.0 5.0 92 | 57 1.0 5.0 93 | 58 2.0 5.0 94 | 59 3.0 5.0 95 | 60 4.0 5.0 96 | 61 5.0 5.0 97 | 62 6.0 5.0 98 | 63 7.0 5.0 99 | 64 8.0 5.0 100 | 65 9.0 5.0 101 | 66 10.0 5.0 102 | 67 0.0 4.0 103 | 68 1.0 4.0 104 | 69 2.0 4.0 105 | 70 3.0 4.0 106 | 71 4.0 4.0 107 | 72 5.0 4.0 108 | 73 6.0 4.0 109 | 74 7.0 4.0 110 | 75 8.0 4.0 111 | 76 9.0 4.0 112 | 77 10.0 4.0 113 | 78 0.0 3.0 114 | 79 1.0 3.0 115 | 80 2.0 3.0 116 | 81 3.0 3.0 117 | 82 4.0 3.0 118 | 83 5.0 3.0 119 | 84 6.0 3.0 120 | 85 7.0 3.0 121 | 86 8.0 3.0 122 | 87 9.0 3.0 123 | 88 10.0 3.0 124 | 89 0.0 2.0 125 | 90 1.0 2.0 126 | 91 2.0 2.0 127 | 92 3.0 2.0 128 | 93 4.0 2.0 129 | 94 5.0 2.0 130 | 95 6.0 2.0 131 | 96 7.0 2.0 132 | 97 8.0 2.0 133 | 98 9.0 2.0 134 | 99 10.0 2.0 135 | 100 0.0 1.0 136 | 101 1.0 1.0 137 | 102 2.0 1.0 138 | 103 3.0 1.0 139 | 104 4.0 1.0 140 | 105 5.0 1.0 141 | 106 6.0 1.0 142 | 107 7.0 1.0 143 | 108 8.0 1.0 144 | 109 9.0 1.0 145 | 110 10.0 1.0 146 | 111 0.0 0.0 147 | 112 1.0 0.0 148 | 113 2.0 0.0 149 | 114 3.0 0.0 150 | 115 4.0 0.0 151 | 116 5.0 0.0 152 | 117 6.0 0.0 153 | 118 7.0 0.0 154 | 119 8.0 0.0 155 | 120 9.0 0.0 156 | 121 10.0 0.0 157 | END VERTICES 158 | 159 | BEGIN CELL2D 160 | 1 0.33 9.67 3 1 2 12 161 | 2 0.67 9.33 3 2 13 12 162 | 3 1.33 9.67 3 2 3 13 163 | 4 1.67 9.33 3 3 14 13 164 | 5 2.33 9.67 3 3 4 14 165 | 6 2.67 9.33 3 4 15 14 166 | 7 3.33 9.67 3 4 5 15 167 | 8 3.67 9.33 3 5 16 15 168 | 9 4.33 9.67 3 5 6 16 169 | 10 4.67 9.33 3 6 17 16 170 | 11 5.33 9.67 3 6 7 17 171 | 12 5.67 9.33 3 7 18 17 172 | 13 6.33 9.67 3 7 8 18 173 | 14 6.67 9.33 3 8 19 18 174 | 15 7.33 9.67 3 8 9 19 175 | 16 7.67 9.33 3 9 20 19 176 | 17 8.33 9.67 3 9 10 20 177 | 18 8.67 9.33 3 10 21 20 178 | 19 9.33 9.67 3 10 11 21 179 | 20 9.67 9.33 3 11 22 21 180 | 21 0.33 8.67 3 12 13 23 181 | 22 0.67 8.33 3 13 24 23 182 | 23 1.33 8.67 3 13 14 24 183 | 24 1.67 8.33 3 14 25 24 184 | 25 2.33 8.67 3 14 15 25 185 | 26 2.67 8.33 3 15 26 25 186 | 27 3.33 8.67 3 15 16 26 187 | 28 3.67 8.33 3 16 27 26 188 | 29 4.33 8.67 3 16 17 27 189 | 30 4.67 8.33 3 17 28 27 190 | 31 5.33 8.67 3 17 18 28 191 | 32 5.67 8.33 3 18 29 28 192 | 33 6.33 8.67 3 18 19 29 193 | 34 6.67 8.33 3 19 30 29 194 | 35 7.33 8.67 3 19 20 30 195 | 36 7.67 8.33 3 20 31 30 196 | 37 8.33 8.67 3 20 21 31 197 | 38 8.67 8.33 3 21 32 31 198 | 39 9.33 8.67 3 21 22 32 199 | 40 9.67 8.33 3 22 33 32 200 | 41 0.33 7.67 3 23 24 34 201 | 42 0.67 7.33 3 24 35 34 202 | 43 1.33 7.67 3 24 25 35 203 | 44 1.67 7.33 3 25 36 35 204 | 45 2.33 7.67 3 25 26 36 205 | 46 2.67 7.33 3 26 37 36 206 | 47 3.33 7.67 3 26 27 37 207 | 48 3.67 7.33 3 27 38 37 208 | 49 4.33 7.67 3 27 28 38 209 | 50 4.67 7.33 3 28 39 38 210 | 51 5.33 7.67 3 28 29 39 211 | 52 5.67 7.33 3 29 40 39 212 | 53 6.33 7.67 3 29 30 40 213 | 54 6.67 7.33 3 30 41 40 214 | 55 7.33 7.67 3 30 31 41 215 | 56 7.67 7.33 3 31 42 41 216 | 57 8.33 7.67 3 31 32 42 217 | 58 8.67 7.33 3 32 43 42 218 | 59 9.33 7.67 3 32 33 43 219 | 60 9.67 7.33 3 33 44 43 220 | 61 0.33 6.67 3 34 35 45 221 | 62 0.67 6.33 3 35 46 45 222 | 63 1.33 6.67 3 35 36 46 223 | 64 1.67 6.33 3 36 47 46 224 | 65 2.33 6.67 3 36 37 47 225 | 66 2.67 6.33 3 37 48 47 226 | 67 3.33 6.67 3 37 38 48 227 | 68 3.67 6.33 3 38 49 48 228 | 69 4.33 6.67 3 38 39 49 229 | 70 4.67 6.33 3 39 50 49 230 | 71 5.33 6.67 3 39 40 50 231 | 72 5.67 6.33 3 40 51 50 232 | 73 6.33 6.67 3 40 41 51 233 | 74 6.67 6.33 3 41 52 51 234 | 75 7.33 6.67 3 41 42 52 235 | 76 7.67 6.33 3 42 53 52 236 | 77 8.33 6.67 3 42 43 53 237 | 78 8.67 6.33 3 43 54 53 238 | 79 9.33 6.67 3 43 44 54 239 | 80 9.67 6.33 3 44 55 54 240 | 81 0.33 5.67 3 45 46 56 241 | 82 0.67 5.33 3 46 57 56 242 | 83 1.33 5.67 3 46 47 57 243 | 84 1.67 5.33 3 47 58 57 244 | 85 2.33 5.67 3 47 48 58 245 | 86 2.67 5.33 3 48 59 58 246 | 87 3.33 5.67 3 48 49 59 247 | 88 3.67 5.33 3 49 60 59 248 | 89 4.33 5.67 3 49 50 60 249 | 90 4.67 5.33 3 50 61 60 250 | 91 5.33 5.67 3 50 51 61 251 | 92 5.67 5.33 3 51 62 61 252 | 93 6.33 5.67 3 51 52 62 253 | 94 6.67 5.33 3 52 63 62 254 | 95 7.33 5.67 3 52 53 63 255 | 96 7.67 5.33 3 53 64 63 256 | 97 8.33 5.67 3 53 54 64 257 | 98 8.67 5.33 3 54 65 64 258 | 99 9.33 5.67 3 54 55 65 259 | 100 9.67 5.33 3 55 66 65 260 | 101 0.33 4.67 3 56 57 67 261 | 102 0.67 4.33 3 57 68 67 262 | 103 1.33 4.67 3 57 58 68 263 | 104 1.67 4.33 3 58 69 68 264 | 105 2.33 4.67 3 58 59 69 265 | 106 2.67 4.33 3 59 70 69 266 | 107 3.33 4.67 3 59 60 70 267 | 108 3.67 4.33 3 60 71 70 268 | 109 4.33 4.67 3 60 61 71 269 | 110 4.67 4.33 3 61 72 71 270 | 111 5.33 4.67 3 61 62 72 271 | 112 5.67 4.33 3 62 73 72 272 | 113 6.33 4.67 3 62 63 73 273 | 114 6.67 4.33 3 63 74 73 274 | 115 7.33 4.67 3 63 64 74 275 | 116 7.67 4.33 3 64 75 74 276 | 117 8.33 4.67 3 64 65 75 277 | 118 8.67 4.33 3 65 76 75 278 | 119 9.33 4.67 3 65 66 76 279 | 120 9.67 4.33 3 66 77 76 280 | 121 0.33 3.67 3 67 68 78 281 | 122 0.67 3.33 3 68 79 78 282 | 123 1.33 3.67 3 68 69 79 283 | 124 1.67 3.33 3 69 80 79 284 | 125 2.33 3.67 3 69 70 80 285 | 126 2.67 3.33 3 70 81 80 286 | 127 3.33 3.67 3 70 71 81 287 | 128 3.67 3.33 3 71 82 81 288 | 129 4.33 3.67 3 71 72 82 289 | 130 4.67 3.33 3 72 83 82 290 | 131 5.33 3.67 3 72 73 83 291 | 132 5.67 3.33 3 73 84 83 292 | 133 6.33 3.67 3 73 74 84 293 | 134 6.67 3.33 3 74 85 84 294 | 135 7.33 3.67 3 74 75 85 295 | 136 7.67 3.33 3 75 86 85 296 | 137 8.33 3.67 3 75 76 86 297 | 138 8.67 3.33 3 76 87 86 298 | 139 9.33 3.67 3 76 77 87 299 | 140 9.67 3.33 3 77 88 87 300 | 141 0.33 2.67 3 78 79 89 301 | 142 0.67 2.33 3 79 90 89 302 | 143 1.33 2.67 3 79 80 90 303 | 144 1.67 2.33 3 80 91 90 304 | 145 2.33 2.67 3 80 81 91 305 | 146 2.67 2.33 3 81 92 91 306 | 147 3.33 2.67 3 81 82 92 307 | 148 3.67 2.33 3 82 93 92 308 | 149 4.33 2.67 3 82 83 93 309 | 150 4.67 2.33 3 83 94 93 310 | 151 5.33 2.67 3 83 84 94 311 | 152 5.67 2.33 3 84 95 94 312 | 153 6.33 2.67 3 84 85 95 313 | 154 6.67 2.33 3 85 96 95 314 | 155 7.33 2.67 3 85 86 96 315 | 156 7.67 2.33 3 86 97 96 316 | 157 8.33 2.67 3 86 87 97 317 | 158 8.67 2.33 3 87 98 97 318 | 159 9.33 2.67 3 87 88 98 319 | 160 9.67 2.33 3 88 99 98 320 | 161 0.33 1.67 3 89 90 100 321 | 162 0.67 1.33 3 90 101 100 322 | 163 1.33 1.67 3 90 91 101 323 | 164 1.67 1.33 3 91 102 101 324 | 165 2.33 1.67 3 91 92 102 325 | 166 2.67 1.33 3 92 103 102 326 | 167 3.33 1.67 3 92 93 103 327 | 168 3.67 1.33 3 93 104 103 328 | 169 4.33 1.67 3 93 94 104 329 | 170 4.67 1.33 3 94 105 104 330 | 171 5.33 1.67 3 94 95 105 331 | 172 5.67 1.33 3 95 106 105 332 | 173 6.33 1.67 3 95 96 106 333 | 174 6.67 1.33 3 96 107 106 334 | 175 7.33 1.67 3 96 97 107 335 | 176 7.67 1.33 3 97 108 107 336 | 177 8.33 1.67 3 97 98 108 337 | 178 8.67 1.33 3 98 109 108 338 | 179 9.33 1.67 3 98 99 109 339 | 180 9.67 1.33 3 99 110 109 340 | 181 0.33 0.67 3 100 101 111 341 | 182 0.67 0.33 3 101 112 111 342 | 183 1.33 0.67 3 101 102 112 343 | 184 1.67 0.33 3 102 113 112 344 | 185 2.33 0.67 3 102 103 113 345 | 186 2.67 0.33 3 103 114 113 346 | 187 3.33 0.67 3 103 104 114 347 | 188 3.67 0.33 3 104 115 114 348 | 189 4.33 0.67 3 104 105 115 349 | 190 4.67 0.33 3 105 116 115 350 | 191 5.33 0.67 3 105 106 116 351 | 192 5.67 0.33 3 106 117 116 352 | 193 6.33 0.67 3 106 107 117 353 | 194 6.67 0.33 3 107 118 117 354 | 195 7.33 0.67 3 107 108 118 355 | 196 7.67 0.33 3 108 119 118 356 | 197 8.33 0.67 3 108 109 119 357 | 198 8.67 0.33 3 109 120 119 358 | 199 9.33 0.67 3 109 110 120 359 | 200 9.67 0.33 3 110 121 120 360 | END CELL2D 361 | 362 | -------------------------------------------------------------------------------- /docs/examples/data/disv_model/tri_model_left.chd: -------------------------------------------------------------------------------- 1 | begin options 2 | PRINT_INPUT 3 | PRINT_FLOWS 4 | SAVE_FLOWS 5 | end options 6 | 7 | begin dimensions 8 | MAXBOUND 10 9 | end dimensions 10 | 11 | begin period 1 12 | #layer 1 13 | 1 1 10. 14 | 1 21 10. 15 | 1 41 10. 16 | 1 61 10. 17 | 1 81 10. 18 | 1 101 10. 19 | 1 121 10. 20 | 1 141 10. 21 | 1 161 10. 22 | 1 181 10. 23 | end period 24 | 25 | -------------------------------------------------------------------------------- /docs/examples/data/disv_model/tri_model_right.chd: -------------------------------------------------------------------------------- 1 | begin options 2 | PRINT_INPUT 3 | PRINT_FLOWS 4 | SAVE_FLOWS 5 | end options 6 | 7 | begin dimensions 8 | MAXBOUND 10 9 | end dimensions 10 | 11 | begin period 1 12 | #layer 1 13 | 1 20 5. 14 | 1 40 5. 15 | 1 60 5. 16 | 1 80 5. 17 | 1 100 5. 18 | 1 120 5. 19 | 1 140 5. 20 | 1 160 5. 21 | 1 180 5. 22 | 1 200 5. 23 | end period 24 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/mfsim.nam: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | #none 3 | END OPTIONS 4 | 5 | BEGIN TIMING 6 | TDIS6 simulation.tdis 7 | END TIMING 8 | 9 | BEGIN MODELS 10 | #modeltype namefile modelname 11 | GWF6 model1.nam PARENT 12 | GWF6 model2.nam CHILD 13 | END MODELS 14 | 15 | BEGIN EXCHANGES 16 | GWF6-GWF6 simulation.exg PARENT CHILD 17 | END EXCHANGES 18 | 19 | BEGIN SOLUTIONGROUP 1 20 | MXITER 1 21 | IMS6 simulation.ims PARENT CHILD 22 | END SOLUTIONGROUP 23 | 24 | 25 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model1.chd: -------------------------------------------------------------------------------- 1 | begin options 2 | PRINT_INPUT 3 | PRINT_FLOWS 4 | SAVE_FLOWS 5 | end options 6 | 7 | begin dimensions 8 | MAXBOUND 30 9 | end dimensions 10 | 11 | begin period 1 12 | 13 | #left 14 | 1 1 1 1. 15 | 1 2 1 1. 16 | 1 3 1 1. 17 | 1 4 1 1. 18 | 1 5 1 1. 19 | 1 6 1 1. 20 | 1 7 1 1. 21 | 22 | #right 23 | 1 1 7 0. 24 | 1 2 7 0. 25 | 1 3 7 0. 26 | 1 4 7 0. 27 | 1 5 7 0. 28 | 1 6 7 0. 29 | 1 7 7 0. 30 | end period 31 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model1.dis: -------------------------------------------------------------------------------- 1 | # Structured discretization file for MODFLOW-USG 2 | begin options 3 | LENGTH_UNITS meters 4 | end options 5 | 6 | begin dimensions 7 | nlay 1 8 | nrow 7 9 | ncol 7 10 | end dimensions 11 | 12 | BEGIN GRIDDATA 13 | IDOMAIN 14 | INTERNAL FACTOR 1 15 | 1 1 1 1 1 1 1 16 | 1 1 1 1 1 1 1 17 | 1 1 0 0 0 1 1 18 | 1 1 0 0 0 1 1 19 | 1 1 0 0 0 1 1 20 | 1 1 1 1 1 1 1 21 | 1 1 1 1 1 1 1 22 | delr 23 | constant 100. 24 | delc 25 | constant 100. 26 | top 27 | constant 0. 28 | botm 29 | constant -100 30 | END GRIDDATA 31 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model1.ic: -------------------------------------------------------------------------------- 1 | # Basic package file for MODFLOW-USG, generated by Flopy. 2 | begin options 3 | end options 4 | 5 | BEGIN GRIDDATA 6 | strt 7 | INTERNAL FACTOR 1.0 IPRN 3 8 | 1.0 1.0 1.0 1.0 1.0 1.0 0.0 9 | 1.0 1.0 1.0 1.0 1.0 1.0 0.0 10 | 1.0 1.0 1.0 1.0 1.0 1.0 0.0 11 | 1.0 1.0 1.0 1.0 1.0 1.0 0.0 12 | 1.0 1.0 1.0 1.0 1.0 1.0 0.0 13 | 1.0 1.0 1.0 1.0 1.0 1.0 0.0 14 | 1.0 1.0 1.0 1.0 1.0 1.0 0.0 15 | END GRIDDATA 16 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model1.mawq: -------------------------------------------------------------------------------- 1 | #option block. Note -- no comments allowed on auxiliary line 2 | begin options 3 | PRINT_INPUT (echo input to listing file) 4 | PRINT_FLOWS (print the flows to the listing file) 5 | BOUNDNAMES 6 | #OBS6 FILEIN flow15.maw_1.obs 7 | MOVER 8 | end options 9 | 10 | begin dimensions 11 | NMAWWELLS 1 12 | end dimensions 13 | 14 | BEGIN PACKAGEDATA 15 | # no radius bottom strt condeqn ngwnodes name 16 | 1 0.15 -10.0 10.0 SPECIFIED 1 'well 1' 17 | END PACKAGEDATA 18 | 19 | begin CONNECTIONDATA 20 | # conn l r c stop sbot K rskin 21 | 1 1 1 4 2 10. -10. 1. 0 22 | end CONNECTIONDATA 23 | 24 | begin period 1 steady-state 25 | 1 rate 0. 26 | end period 27 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model1.nam: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | NEWTON 3 | END OPTIONS 4 | 5 | BEGIN PACKAGES 6 | DIS6 model1.dis 7 | IC6 model1.ic 8 | NPF6 model1.npf npf_p1 9 | CHD6 model1.chd 10 | MAW6 model1.mawq 11 | OC6 model1.oc oc_p1 12 | END PACKAGES 13 | 14 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model1.npf: -------------------------------------------------------------------------------- 1 | begin options 2 | save_FLOWS 3 | end options 4 | # 5 | BEGIN GRIDDATA 6 | icelltype 7 | constant 0 8 | K 9 | constant 1. 10 | K33 11 | constant 1. 12 | END GRIDDATA 13 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model1.oc: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | HEAD FILEOUT model1.hds 3 | BUDGET FILEOUT model1.cbc 4 | END OPTIONS 5 | 6 | BEGIN PERIOD 1 7 | PRINT BUDGET ALL 8 | SAVE BUDGET ALL 9 | PRINT HEAD ALL 10 | SAVE HEAD ALL 11 | END PERIOD 12 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model2.dis: -------------------------------------------------------------------------------- 1 | # Unstructured discretization file for MODFLOW-USG 2 | begin options 3 | LENGTH_UNITS meters 4 | end options 5 | 6 | begin dimensions 7 | nlay 1 8 | nrow 9 9 | ncol 9 10 | end dimensions 11 | 12 | BEGIN GRIDDATA 13 | delr 14 | constant 33.33 15 | delc 16 | constant 33.33 17 | top 18 | constant 0. 19 | botm 20 | constant -100. 21 | END GRIDDATA 22 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model2.ic: -------------------------------------------------------------------------------- 1 | # Basic package file for MODFLOW-USG, generated by Flopy. 2 | begin options 3 | end options 4 | 5 | BEGIN GRIDDATA 6 | strt 7 | constant 1.0 8 | END GRIDDATA 9 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model2.mawq: -------------------------------------------------------------------------------- 1 | #option block. Note -- no comments allowed on auxiliary line 2 | begin options 3 | PRINT_INPUT (echo input to listing file) 4 | PRINT_FLOWS (print the flows to the listing file) 5 | BOUNDNAMES 6 | #OBS6 FILEIN flow15.maw_2.obs 7 | MOVER 8 | end options 9 | 10 | begin dimensions 11 | NMAWWELLS 1 12 | end dimensions 13 | 14 | BEGIN PACKAGEDATA 15 | # no radius bottom strt condeqn ngwnodes name 16 | 1 0.15 -10.0 10.0 SPECIFIED 1 'well 1' 17 | END PACKAGEDATA 18 | 19 | begin CONNECTIONDATA 20 | # conn l r c stop sbot K rskin 21 | 1 1 1 5 5 10. -10. 1. 0 22 | end CONNECTIONDATA 23 | 24 | begin period 1 steady-state 25 | 1 rate -10. 26 | end period 27 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model2.nam: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | NEWTON 3 | END OPTIONS 4 | 5 | BEGIN PACKAGES 6 | DIS6 model2.dis 7 | IC6 model2.ic 8 | NPF6 model2.npf 9 | MAW6 model2.mawq 10 | OC6 model2.oc oc_p2 11 | END PACKAGES 12 | 13 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model2.npf: -------------------------------------------------------------------------------- 1 | begin options 2 | SAVE_FLOWS 3 | end options 4 | # 5 | BEGIN GRIDDATA 6 | # 7 | #apply these arrays for the entire simulation 8 | # 9 | #icelltype(nodes) is 0:confined, 1:convertible, 4:upstream? 10 | icelltype 11 | constant 0 12 | # 13 | #K(nodes) horizontal hydraulic conductivity 14 | K 15 | constant 1. 16 | # 17 | #K33(nodes) vertical hydraulic conductivity 18 | K33 19 | constant 1. 20 | # 21 | #this will crash it funkyarray 22 | # constant 23 | END GRIDDATA 24 | 25 | 26 | 50 -1.0e+30 0 0 27 | 0 28 | 0 29 | 1 30 | 1 31 | 0 32 | 0 1.000e+00 (10G13.0) -1 HK() = Horizontal hydraulic conductivity of layer 1 33 | 0 1.000e+00 (10G13.0) -1 VKA() = Vertical hydraulic conductivity of layer 1 34 | 0 0.000e+00 (10G13.0) -1 WETDRY() = Wetting threshold of layer 1 35 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/model2.oc: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | HEAD FILEOUT model2.hds 3 | BUDGET FILEOUT model2.cbc 4 | END OPTIONS 5 | 6 | BEGIN PERIOD 1 7 | PRINT BUDGET ALL 8 | SAVE BUDGET ALL 9 | PRINT HEAD ALL 10 | SAVE HEAD ALL 11 | END PERIOD 12 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/simulation.exg: -------------------------------------------------------------------------------- 1 | 2 | begin options 3 | PRINT_INPUT 4 | PRINT_FLOWS 5 | SAVE_FLOWS 6 | AUXILIARY testaux 7 | GNC6 FILEIN simulation.gnc 8 | MVR6 FILEIN simulation.mvr 9 | end options 10 | 11 | begin dimensions 12 | NEXG 36 13 | end dimensions 14 | 15 | # nodem1 nodem2 ihc cl1 cl2 hwva testaux 16 | begin exchangedata 17 | # 18 | # left side 19 | 1 3 2 1 1 1 1 50. 16.67 33.33 100.99 20 | 1 3 2 1 2 1 1 50. 16.67 33.33 100.99 21 | 1 3 2 1 3 1 1 50. 16.67 33.33 100.99 22 | 1 4 2 1 4 1 1 50. 16.67 33.33 100.99 23 | 1 4 2 1 5 1 1 50. 16.67 33.33 100.99 24 | 1 4 2 1 6 1 1 50. 16.67 33.33 100.99 25 | 1 5 2 1 7 1 1 50. 16.67 33.33 100.99 26 | 1 5 2 1 8 1 1 50. 16.67 33.33 100.99 27 | 1 5 2 1 9 1 1 50. 16.67 33.33 100.99 28 | # 29 | # right side 30 | 1 3 6 1 1 9 1 50. 16.67 33.33 100.99 31 | 1 3 6 1 2 9 1 50. 16.67 33.33 100.99 32 | 1 3 6 1 3 9 1 50. 16.67 33.33 100.99 33 | 1 4 6 1 4 9 1 50. 16.67 33.33 100.99 34 | 1 4 6 1 5 9 1 50. 16.67 33.33 100.99 35 | 1 4 6 1 6 9 1 50. 16.67 33.33 100.99 36 | 1 5 6 1 7 9 1 50. 16.67 33.33 100.99 37 | 1 5 6 1 8 9 1 50. 16.67 33.33 100.99 38 | 1 5 6 1 9 9 1 50. 16.67 33.33 100.99 39 | # 40 | # back 41 | 1 2 3 1 1 1 1 50. 16.67 33.33 100.99 42 | 1 2 3 1 1 2 1 50. 16.67 33.33 100.99 43 | 1 2 3 1 1 3 1 50. 16.67 33.33 100.99 44 | 1 2 4 1 1 4 1 50. 16.67 33.33 100.99 45 | 1 2 4 1 1 5 1 50. 16.67 33.33 100.99 46 | 1 2 4 1 1 6 1 50. 16.67 33.33 100.99 47 | 1 2 5 1 1 7 1 50. 16.67 33.33 100.99 48 | 1 2 5 1 1 8 1 50. 16.67 33.33 100.99 49 | 1 2 5 1 1 9 1 50. 16.67 33.33 100.99 50 | # 51 | # front 52 | 1 6 3 1 9 1 1 50. 16.67 33.33 100.99 53 | 1 6 3 1 9 2 1 50. 16.67 33.33 100.99 54 | 1 6 3 1 9 3 1 50. 16.67 33.33 100.99 55 | 1 6 4 1 9 4 1 50. 16.67 33.33 100.99 56 | 1 6 4 1 9 5 1 50. 16.67 33.33 100.99 57 | 1 6 4 1 9 6 1 50. 16.67 33.33 100.99 58 | 1 6 5 1 9 7 1 50. 16.67 33.33 100.99 59 | 1 6 5 1 9 8 1 50. 16.67 33.33 100.99 60 | 1 6 5 1 9 9 1 50. 16.67 33.33 100.99 61 | end exchangedata 62 | 63 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/simulation.gnc: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | #I2KN 3 | #IMPLICIT 4 | PRINT_INPUT 5 | PRINT_FLOWS 6 | END OPTIONS 7 | 8 | BEGIN DIMENSIONS 9 | NUMGNC 36 10 | NUMALPHAJ 1 11 | END DIMENSIONS 12 | 13 | BEGIN GNCDATA 14 | # noden nodem nodesj alphasj 15 | # left side 16 | 1 3 2 1 1 1 1 2 2 0.333333333333 17 | 1 3 2 1 2 1 0 0 0 0.333333333333 18 | 1 3 2 1 3 1 1 4 2 0.333333333333 19 | 1 4 2 1 4 1 1 3 2 0.333333333333 20 | 1 4 2 1 5 1 0 0 0 0.333333333333 21 | 1 4 2 1 6 1 1 5 2 0.333333333333 22 | 1 5 2 1 7 1 1 4 2 0.333333333333 23 | 1 5 2 1 8 1 0 0 0 0.333333333333 24 | 1 5 2 1 9 1 1 6 2 0.333333333333 25 | # 26 | # right side 27 | 1 3 6 1 1 9 1 2 6 0.333333333333 28 | 1 3 6 1 2 9 0 0 0 0.333333333333 29 | 1 3 6 1 3 9 1 4 6 0.333333333333 30 | 1 4 6 1 4 9 1 3 6 0.333333333333 31 | 1 4 6 1 5 9 0 0 0 0.333333333333 32 | 1 4 6 1 6 9 1 5 6 0.333333333333 33 | 1 5 6 1 7 9 1 4 6 0.333333333333 34 | 1 5 6 1 8 9 0 0 0 0.333333333333 35 | 1 5 6 1 9 9 1 6 6 0.333333333333 36 | # 37 | # back 38 | 1 2 3 1 1 1 1 2 2 0.333333333333 39 | 1 2 3 1 1 2 0 0 0 0.333333333333 40 | 1 2 3 1 1 3 1 2 4 0.333333333333 41 | 1 2 4 1 1 4 1 2 3 0.333333333333 42 | 1 2 4 1 1 5 0 0 0 0.333333333333 43 | 1 2 4 1 1 6 1 2 5 0.333333333333 44 | 1 2 5 1 1 7 1 2 4 0.333333333333 45 | 1 2 5 1 1 8 0 0 0 0.333333333333 46 | 1 2 5 1 1 9 1 2 6 0.333333333333 47 | # 48 | # front 49 | 1 6 3 1 9 1 1 6 2 0.333333333333 50 | 1 6 3 1 9 2 0 0 0 0.333333333333 51 | 1 6 3 1 9 3 1 6 4 0.333333333333 52 | 1 6 4 1 9 4 1 6 3 0.333333333333 53 | 1 6 4 1 9 5 0 0 0 0.333333333333 54 | 1 6 4 1 9 6 1 6 5 0.333333333333 55 | 1 6 5 1 9 7 1 6 4 0.333333333333 56 | 1 6 5 1 9 8 0 0 0 0.333333333333 57 | 1 6 5 1 9 9 1 6 6 0.333333333333 58 | END GNCDATA 59 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/simulation.ims: -------------------------------------------------------------------------------- 1 | begin options 2 | PRINT_OPTION SUMMARY 3 | end options 4 | 5 | begin nonlinear 6 | OUTER_DVCLOSE 1.e-8 7 | outer_maximum 1000 8 | under_relaxation none 9 | end nonlinear 10 | 11 | begin linear 12 | INNER_DVCLOSE 1.0e-8 13 | inner_rclose 0.01 14 | inner_maximum 1000 15 | linear_acceleration bicgstab 16 | scaling_method none 17 | REORDERING_METHOD none 18 | relaxation_factor 0.97 19 | end linear 20 | 21 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/simulation.mvr: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | PRINT_INPUT 3 | PRINT_FLOWS 4 | MODELNAMES 5 | END OPTIONS 6 | 7 | BEGIN DIMENSIONS 8 | MAXMVR 10 9 | MAXPACKAGES 2 10 | END DIMENSIONS 11 | 12 | BEGIN PACKAGES 13 | 'PARENT' 'MAW-1' 14 | 'CHILD' 'MAW-1' 15 | END PACKAGES 16 | 17 | BEGIN PERIOD 1 18 | # mnamep packnamep idp mnamer packnamer idr type val 19 | # ------------------------------------------------------- 20 | 'CHILD' 'MAW-1' 1 'PARENT' 'MAW-1' 1 FACTOR 0.5 21 | END PERIOD 1 22 | -------------------------------------------------------------------------------- /docs/examples/data/two_models/simulation.tdis: -------------------------------------------------------------------------------- 1 | BEGIN OPTIONS 2 | TIME_UNITS DAYS 3 | END OPTIONS 4 | 5 | BEGIN DIMENSIONS 6 | NPER 1 7 | END DIMENSIONS 8 | 9 | BEGIN PERIODDATA 10 | #perlen nstp tsmult 11 | 1.0 1 1.0 12 | END PERIODDATA 13 | -------------------------------------------------------------------------------- /docs/examples/notebooks/Extensions.py: -------------------------------------------------------------------------------- 1 | # --- 2 | # jupyter: 3 | # jupytext: 4 | # text_representation: 5 | # extension: .py 6 | # format_name: light 7 | # format_version: '1.5' 8 | # jupytext_version: 1.14.4 9 | # kernelspec: 10 | # display_name: Python 3 (ipykernel) 11 | # language: python 12 | # name: python3 13 | # --- 14 | 15 | # # Interacting with MODFLOW-API Interface objects 16 | # 17 | # The purpose of this notebook is to show the MODFLOW-API interface objects and introduce the user to 18 | # the data types and how to interact with the objects. 19 | # 20 | # **Note**: This notebook shows how to run a model using the modflow-api at the end of the notebook. 21 | # However, the majority of the notebook is an illustration of how to access and work with the data 22 | # types that are returned to a user defined callback function. 23 | 24 | # + 25 | import platform 26 | from pathlib import Path 27 | 28 | import modflowapi 29 | from modflowapi import Callbacks 30 | from modflowapi.extensions import ApiSimulation 31 | 32 | # - 33 | 34 | # Define the paths to the model and the Modflow shared library 35 | 36 | # + 37 | sim_ws = Path("../data/dis_model") 38 | dll = "./libmf6" 39 | if platform.system().lower() == "windows": 40 | ext = ".dll" 41 | elif platform.system().lower() == "linux": 42 | ext = ".so" 43 | else: 44 | ext = ".dylib" 45 | 46 | dll = Path(dll + ext) 47 | # - 48 | 49 | # #### Initializing the API model object 50 | # 51 | # The modflow api allows users to initialize an object that can be used to interact with the model. 52 | # This processes is done automatically with the `modflowapi.run_model` function call. We're going 53 | # to initialize an object outside of that call as a demonstration of the interface data objects 54 | 55 | # + 56 | mf6 = modflowapi.ModflowApi(dll, working_directory=sim_ws) 57 | mf6.initialize() 58 | 59 | # let's advance the model to the first timestep 60 | dt = mf6.get_time_step() 61 | mf6.prepare_time_step(dt) 62 | # - 63 | 64 | # ## The `ApiSimulation` object 65 | # 66 | # The `ApiSimulation` object is the top level container for the modflowapi interface classes. 67 | # This container holds methods and other objects that allow the user to access boundary condition 68 | # pointer data without assembling the specific memory addresses of the modflow data. 69 | # 70 | # Let's take a look at the `ApiSimulation` object 71 | 72 | sim = ApiSimulation.load(mf6) 73 | sim 74 | 75 | # The simulation object allows the user to access models by name and has a number of handy properties 76 | # and contains simulation level packages such as `sln`, `tdis`, `ats`, and `exchanges` 77 | 78 | mnames = sim.model_names 79 | mnames 80 | 81 | kstp, kper = sim.kstp, sim.kper 82 | kstp, kper 83 | 84 | nstp = sim.nstp 85 | nstp 86 | 87 | ims = sim.sln 88 | ims 89 | 90 | ims.dvclose 91 | 92 | # ## The `ApiModel` object 93 | # 94 | # `ApiModel` objects are accessed from the `ApiSimulation` object and are a container for packages. 95 | # These objects allow the user to view which packages are available and access those packages. 96 | # 97 | # The following cells show the main attributes and functions available on the `ApiModel` object 98 | 99 | # Model objects are accessible through the `get_model` function and as attributes on the sim object 100 | 101 | model = sim.get_model("test_model") 102 | model 103 | 104 | # approach 2 105 | model = sim.test_model 106 | model 107 | 108 | # There are also a number of other functions available including the following: 109 | 110 | model.shape 111 | 112 | model.size 113 | 114 | model.solution_id 115 | 116 | # A list of all package names that are accessible is also available 117 | 118 | model.package_names 119 | 120 | # ## The `ApiPackage` object(s) 121 | # 122 | # Each package is contained in `ApiPackage` container. There are three types depending on the input data. 123 | # We'll access and take a look at each of the types of `ApiPackage` containers. 124 | 125 | # Packages can be accessed from the `Model` object using `get_package()` or by attribute 126 | 127 | # example 1: get a package using get_package 128 | rch = model.get_package("rcha_0") 129 | rch 130 | 131 | # example 2: get a package by package name attribute 132 | wel = model.wel_0 133 | wel 134 | 135 | # example 3: get all packages based on a package type 136 | rch_pkgs = model.rch 137 | rch_pkgs 138 | 139 | # ### `ListPackage` objects 140 | # 141 | # `ListPackage` objects are the primary object type of stress period data. The exception to this rule 142 | # is the advanced packages which will be discussed later. 143 | # 144 | # `ListPackage` objects allow users to access stress period data as a numpy recarray or as a pandas dataframe. 145 | 146 | recarray = rch.stress_period_data.values 147 | recarray[0:10] 148 | 149 | df = rch.stress_period_data.dataframe 150 | df.head() 151 | 152 | # ### Updating values for `ListPackage` based data 153 | # 154 | # There are multiple ways to update values for `ListPackage` based data. The `.values` and `.dataframe` 155 | # attributes can be used, or the object can be directly indexed if the user knows the underlying data. 156 | # Here are some examples: 157 | 158 | # + 159 | recarray["recharge"][0] *= 100 160 | rch.stress_period_data.values = recarray 161 | 162 | # show that values have been updated 163 | recarray = rch.stress_period_data.values 164 | recarray[0:5] 165 | 166 | # + 167 | df = rch.stress_period_data.dataframe 168 | df.loc[1, "recharge"] = 10000 169 | rch.stress_period_data.dataframe = df 170 | 171 | # show that values have been updated 172 | df = rch.stress_period_data.dataframe 173 | df.head() 174 | # - 175 | 176 | # #### Interfacing directly with the `.stress_period_data` attribute 177 | # 178 | # The `.stress_period_data` attribute returns a container class that interacts with the internal modflow 179 | # pointers. The data can be adjusted by interacting with `.stress_period_data` in the same fashion as 180 | # changing data in a numpy recarray. 181 | 182 | rch.stress_period_data["recharge"] *= 100 183 | 184 | df = rch.stress_period_data.dataframe 185 | df.head() 186 | 187 | # #### Adding or removing a boundary condition 188 | # In list packages the user can add and remove specific boundary conditions. Note: if a user adds a 189 | # boundary condition, such as another well during a stress period, the total number of wells cannot 190 | # be greater than the wel package's `maxbound` variable. Here's an example 191 | 192 | wel = model.wel 193 | maxbound = wel.maxbound 194 | nbound = wel.nbound 195 | print(f"{nbound=}", f"{maxbound=}") 196 | 197 | # For the current stress period there are two active wells `nbound=2`, but there can be up to ten 198 | # `maxbound=10`. 199 | 200 | recarray = wel.stress_period_data.values 201 | recarray 202 | 203 | recarray.resize((nbound + 1,), refcheck=False) 204 | recarray[-1] = ((0, 1, 5), -20.0, 0, 1) 205 | recarray 206 | 207 | wel.stress_period_data.values = recarray 208 | nbound = wel.nbound 209 | f"{nbound=}" 210 | 211 | wel.stress_period_data.dataframe 212 | 213 | # ### `ArrayPackage` objects 214 | # 215 | # The `ArrayPackage` class is used as a container for packages such as `DIS`, `NPF`, and `IC` that 216 | # do not contain any sort of stress period data. These packages are used primarily to define model 217 | # connectivity, initial conditions, and hydraulic parameters of the basin. 218 | 219 | npf = model.npf 220 | npf 221 | 222 | # For an `ArrayPackage` type object, variable names can be viewed by calling the `.variable_names` property 223 | 224 | npf.variable_names 225 | 226 | # ### Updating values for `ArrayPackage` objects 227 | # 228 | # Two methods are available for accessing and updating data in `ArrayPackage` objects. `get_array()` 229 | # and `set_array()` methods can be used to get and set data. Arrays can also be accessed as attributes 230 | # on the object. 231 | 232 | # Using `get_array()` and `set_array()` 233 | 234 | hk = npf.get_array("k11") 235 | hk 236 | 237 | hk[0, 0:5, 0:5] = 50 238 | npf.set_array("k11", hk) 239 | 240 | # confirm that the data has been updated 241 | hk = npf.get_array("k11") 242 | hk 243 | 244 | # Getting and setting data by attribute 245 | 246 | # needs an update for inplace operations.... 247 | npf.k33[0, 0:5, 0:5] = 5 248 | 249 | # confirm that the data has been updated 250 | npf.k33.values 251 | 252 | # ## Accessing "advanced variables" 253 | # 254 | # Advanced variables in this context are variables that would not normally need to be accessed by the user, 255 | # and in many cases changes to these variables would cause the Modflow simulation to do unexpected things. 256 | 257 | # For each package object a list of advanced variables can be returned by calling the `advanced_vars` attribute 258 | 259 | wel = model.wel_0 260 | wel.advanced_vars 261 | 262 | # The user can access and change these values, _at their own risk_, using the `.get_advanced_var()` and 263 | # `.set_advanced_var()` methods. Data is returned to the user in the internal modflowapi structure. 264 | 265 | wel.get_advanced_var("ibcnum") 266 | 267 | # ### Advanced Packages 268 | # 269 | # Certain packages only support accessing data through the `.get_advanced_var()` and `.set_advanced_var()` 270 | # methods. These packages, are sometimes referred to as "advanced packages" and include: BUY, CSUB, GNC, 271 | # HFB, MAW, MVR, SFR, and UZF. 272 | 273 | # ------- 274 | 275 | # Let's close the existing modflowapi shared library object and look at an example of how this is all 276 | # used in practice. 277 | 278 | # Note: the full prepare/solve/finalize sequence below is temporarily required to work around a bug 279 | # in MODFLOW 6. The bug has been patched, but the patch has not been released yet. The sequence can 280 | # be reduced to just `mf6.finalize()` when the patch is released. 281 | 282 | mf6.prepare_solve(model.solution_id) 283 | mf6.solve(model.solution_id) 284 | mf6.finalize_solve(model.solution_id) 285 | mf6.finalize_time_step() 286 | mf6.finalize() 287 | 288 | # # Putting it all together and running a modflowapi simulation 289 | # 290 | # To run a simulation using the built in modflowapi runner the user needs to create a function that 291 | # will receive callbacks at different steps in the simulation run. For the remainder of this notebook, 292 | # we'll show how to create a callback function and use it with the `modflowapi.run_simulation()` method. 293 | 294 | # ## Create a callback function for adjusting model data 295 | # 296 | # The callback function allows users to wrap function that updates the modflow model at different steps. 297 | # The `modflowapi.Callbacks` object allows users to find the particular solution step that they are 298 | # currently in. `modflowapi.Callbacks` includes: 299 | # 300 | # - `Callbacks.initialize`: the initialize callback sends loaded simulation data back to the user to 301 | # make adjustments before the model begins solving. This callback only occurs once at the beginning of 302 | # the MODFLOW6 simulation 303 | # - `Callbacks.stress_period_start`: the stress_period_start callback sends simulation data for each 304 | # solution group to the user to make adjustments to stress packages at the beginning of each stress period. 305 | # - `Callbacks.stress_period_end`: the stress_period_end callback sends simulation data for each solution 306 | # group to the user at the end of each stress period. This can be useful for writing custom output and 307 | # coupling models. 308 | # - `Callbacks.timestep_start`: the timestep_start callback sends simulation data for each solution group to 309 | # the user to make adjustments to stress packages at the beginning of each timestep. 310 | # - `Callbacks.timestep_end`: the timestep_end callback sends simulation data for each solution group to the 311 | # user at the end of each timestep. This can be useful for writing custom output and coupling models. 312 | # - `Callbacks.iteration_start`: the iteration_start callback sends simulation data for each solution group 313 | # to the user to make adjustments to stress packages at the beginning of each outer solution iteration. 314 | # - `Callbacks.iteration_end`: the iteration_end callback sends simulation data for each solution group to 315 | # the user to make adjustments to stress packages and check values of stress packages at the end of each 316 | # outer solution iteration. 317 | # - `Callbacks.finalize`: the finalize callback is useful for finalizing models coupled with the modflowapi. 318 | # 319 | # The user can use any or all of these callbacks within their callback function 320 | 321 | 322 | def callback_function(sim, callback_step): 323 | """ 324 | A demonstration function that dynamically adjusts recharge 325 | and pumping in a modflow-6 model through the MODFLOW-API 326 | 327 | Parameters 328 | ---------- 329 | sim : modflowapi.Simulation 330 | A simulation object for the solution group that is 331 | currently being solved 332 | callback_step : enumeration 333 | modflowapi.Callbacks enumeration object that indicates 334 | the part of the solution modflow is currently in. 335 | """ 336 | ml = sim.test_model 337 | if callback_step == Callbacks.initialize: 338 | print(sim.models) 339 | 340 | if callback_step == Callbacks.stress_period_start: 341 | # adjust recharge for stress periods 1 through 7 342 | if sim.kper <= 6: 343 | rcha = ml.rcha_0 344 | spd = rcha.stress_period_data 345 | print(f"updating recharge: stress_period={ml.kper}") 346 | spd["recharge"] += 0.40 * sim.kper 347 | 348 | if callback_step == Callbacks.timestep_start: 349 | print(f"updating wel flux: stress_period={ml.kper}, timestep={ml.kstp}") 350 | ml.wel.stress_period_data["q"] -= ml.kstp * 1.5 351 | 352 | if callback_step == Callbacks.iteration_start: 353 | # we can implement complex solutions to boundary conditions here! 354 | pass 355 | 356 | 357 | # The callback function is then passed to `modflowapi.run_simulation` 358 | 359 | modflowapi.run_simulation(dll, sim_ws, callback_function, verbose=False) 360 | -------------------------------------------------------------------------------- /docs/examples/notebooks/Head_Monitor_Example.py: -------------------------------------------------------------------------------- 1 | # --- 2 | # jupyter: 3 | # jupytext: 4 | # text_representation: 5 | # extension: .py 6 | # format_name: light 7 | # format_version: '1.5' 8 | # jupytext_version: 1.16.7 9 | # kernelspec: 10 | # display_name: Python 3 (ipykernel) 11 | # language: python 12 | # name: python3 13 | # --- 14 | 15 | # # MODFLOW-API Head monitor example 16 | # 17 | # In this example the modflow-api is used in a more complex callback function to create a Head Monitor 18 | # that updates at the timestep level. This example reverses `CHD` boundary conditions each stress period 19 | # on a simple 10 x 10 model and displays the head results for each timestep. 20 | # 21 | 22 | # + 23 | from pathlib import Path 24 | 25 | import matplotlib.pyplot as plt 26 | import numpy as np 27 | from flopy.discretization import StructuredGrid 28 | from flopy.plot import PlotMapView 29 | from IPython.display import clear_output, display 30 | 31 | # remove this import if adapted to python script 32 | from modflowapi import Callbacks, run_simulation 33 | 34 | # - 35 | 36 | # First we create a class to hold a callback function. 37 | # 38 | # This class handles changing the `CHD` boundary condition as well as updating the matplotlib plot. 39 | 40 | 41 | class StructuredHeadMonitor: 42 | """ 43 | An example class that reverses the model gradient by 44 | swapping CHD boundary conditions each stress period, 45 | and monitors the head at each timestep by updating 46 | a matplotlib plot. This class could be adapted to 47 | be used as a head monitor to observe other changes 48 | in the model by modifying the callback class. 49 | 50 | Parameters 51 | ---------- 52 | layer: int 53 | zero based model layer to plot 54 | vmin : float 55 | minimum head value for color scaling on the plot 56 | vmax : float 57 | maximum head value for color scaling on the plot 58 | """ 59 | 60 | def __init__(self, layer, vmin, vmax): 61 | self.modelgrid = None 62 | self.ax = None 63 | self.pmv = None 64 | self.pc = None 65 | self.ax = None 66 | self.layer = layer 67 | self.vmin = vmin 68 | self.vmax = vmax 69 | self.kperold = None 70 | 71 | def build_modelgrid(self, ml): 72 | """ 73 | Method to update the matplotlib plot 74 | 75 | Parameters 76 | ---------- 77 | ml : ApiModel 78 | modflow-api ApiModel object 79 | """ 80 | delc = ml.dis.get_advanced_var("delc") 81 | delr = ml.dis.get_advanced_var("delr") 82 | top = ml.dis.top.values[0] 83 | botm = ml.dis.bot.values 84 | idomain = ml.dis.idomain.values 85 | self.modelgrid = StructuredGrid(delc=delc, delr=delr, top=top, botm=botm, idomain=idomain) 86 | 87 | def initialize_plot(self): 88 | """ 89 | Method to initialize a matplotlib plot using flopy 90 | """ 91 | fig, ax = plt.subplots(figsize=(8, 8)) 92 | self.fig = fig 93 | self.ax = ax 94 | self.pmv = PlotMapView(modelgrid=self.modelgrid, ax=ax, layer=self.layer) 95 | grid = self.pmv.plot_grid() 96 | idm = self.pmv.plot_inactive() 97 | initial = np.full(self.modelgrid.shape, np.nan) 98 | self.pc = self.pmv.plot_array(initial, vmin=self.vmin, vmax=self.vmax) 99 | plt.colorbar(self.pc) 100 | 101 | def update_plot(self, ml): 102 | """ 103 | Method to update the matplotlib plot 104 | 105 | Parameters 106 | ---------- 107 | ml : ApiModel 108 | modflow-api ApiModel object 109 | """ 110 | heads = ml.X 111 | self.ax.cla() 112 | grid = self.pmv.plot_grid() 113 | idm = self.pmv.plot_inactive() 114 | self.pc = self.pmv.plot_array(heads, vmin=self.vmin, vmax=self.vmax) 115 | 116 | # only applicable to jupyter notebooks, remove these 117 | # two lines in python script 118 | display(self.fig) 119 | if ml.kper == (ml.nper - 1) and ml.kstp == (ml.nstp - 1): 120 | pass 121 | else: 122 | clear_output(wait=True) 123 | 124 | # the pause time can be reduced if adapted in python script 125 | plt.pause(0.1) 126 | 127 | def callback(self, sim, callback_step): 128 | """ 129 | A demonstration function that dynamically adjusts the CHD 130 | boundary conditions each stress period in a modflow-6 model 131 | through the MODFLOW-API and then updates heads on a matplotlib 132 | plot for each timestep. 133 | 134 | Parameters 135 | ---------- 136 | sim : modflowapi.Simulation 137 | A simulation object for the solution group that is 138 | currently being solved 139 | callback_step : enumeration 140 | modflowapi.Callbacks enumeration object that indicates 141 | the part of the solution modflow is currently in. 142 | """ 143 | if callback_step == Callbacks.initialize: 144 | ml = sim.get_model() 145 | self.build_modelgrid(ml) 146 | self.initialize_plot() 147 | 148 | if callback_step == Callbacks.timestep_start: 149 | ml = sim.get_model() 150 | if ml.kper == 0: 151 | self.kperold = ml.kper 152 | head = ml.chd.stress_period_data.dataframe["head"].values 153 | self.head = head 154 | else: 155 | df = ml.chd.stress_period_data.dataframe 156 | if self.kperold != ml.kper: 157 | self.kperold = ml.kper 158 | self.head = self.head[::-1] 159 | 160 | df["head"] = self.head 161 | ml.chd.stress_period_data.dataframe = df 162 | 163 | if callback_step == Callbacks.timestep_end: 164 | ml = sim.get_model() 165 | self.update_plot(ml) 166 | 167 | 168 | # Run the model using the and supply the `StructuredHeadMonitor`'s `callback` function 169 | 170 | hdmon = StructuredHeadMonitor(layer=0, vmin=70, vmax=95) 171 | dll = "libmf6" 172 | sim_ws = Path("../data/dis_model") 173 | run_simulation(dll, sim_ws, hdmon.callback, verbose=True) 174 | -------------------------------------------------------------------------------- /docs/examples/notebooks/Quickstart.py: -------------------------------------------------------------------------------- 1 | # --- 2 | # jupyter: 3 | # jupytext: 4 | # text_representation: 5 | # extension: .py 6 | # format_name: light 7 | # format_version: '1.5' 8 | # jupytext_version: 1.16.7 9 | # kernelspec: 10 | # display_name: Python 3 (ipykernel) 11 | # language: python 12 | # name: python3 13 | # --- 14 | 15 | # # MODFLOW API Quickstart 16 | # 17 | # This notebook presents a quickstart guide to working with the modflowapi package through the extension modules. 18 | # This quickstart guide serves as a roadmap for user development of custom callback functions. For a detailed 19 | # explanation of the `modflowapi.extensions` objects that are accessible through a callback function, see the 20 | # notebook `MODFLOW-API extensions objects.ipynb`. 21 | 22 | # + 23 | from pathlib import Path 24 | 25 | import modflowapi 26 | from modflowapi import Callbacks 27 | 28 | # - 29 | 30 | # Define paths to the modflow6 api shared library 31 | 32 | # + 33 | sim_ws = Path("../data/dis_model") 34 | 35 | dll = Path("./libmf6") 36 | 37 | 38 | # - 39 | 40 | # First we create a callback function for adjusting model data. 41 | # 42 | # The callback function allows users to wrap function that updates the modflow model at different steps. 43 | # The `modflowapi.Callbacks` object allows users to find the particular solution step that they are 44 | # currently in. `modflowapi.Callbacks` includes: 45 | # 46 | # - `Callbacks.initialize`: the initialize callback sends loaded simulation data back to the user to 47 | # make adjustments before the model begins solving. This callback only occurs once at the beginning 48 | # of the MODFLOW6 simulation. 49 | # - `Callbacks.stress_period_start`: the stress_period_start callback sends simulation data for each 50 | # solution group to the user to make adjustments to stress packages at the beginning of each stress 51 | # period. 52 | # - `Callbacks.stress_period_end`: the stress_period_end callback sends simulation data for each solution 53 | # group to the user at the end of each stress period. This can be useful for writing custom output 54 | # and coupling models. 55 | # - `Callbacks.timestep_start`: the timestep_start callback sends simulation data for each solution group 56 | # to the user to make adjustments to stress packages at the beginning of each timestep. 57 | # - `Callbacks.timestep_end`: the timestep_end callback sends simulation data for each solution group to 58 | # the user at the end of each timestep. This can be useful for writing custom output and coupling models. 59 | # - `Callbacks.iteration_start`: the iteration_start callback sends simulation data for each solution group 60 | # to the user to make adjustments to stress packages at the beginning of each outer solution iteration. 61 | # - `Callbacks.iteration_end`: the iteration_end callback sends simulation data for each solution group to 62 | # the user to make adjustments to stress packages and check values of stress packages at the end of each 63 | # outer solution iteration. 64 | # 65 | # The user can use any of these callbacks within their callback function. 66 | 67 | 68 | def callback_function(sim, callback_step): 69 | """ 70 | A demonstration function that dynamically adjusts recharge 71 | and pumping in a modflow-6 model through the MODFLOW-API 72 | 73 | Parameters 74 | ---------- 75 | sim : modflowapi.ApiSimulation 76 | A simulation object for the solution group that is 77 | currently being solved 78 | step : enumeration 79 | modflowapi.Callbacks enumeration object that indicates 80 | the part of the solution modflow is currently in. 81 | """ 82 | ml = sim.test_model 83 | if callback_step == Callbacks.initialize: 84 | print(sim.models) 85 | 86 | if callback_step == Callbacks.stress_period_start: 87 | # adjust recharge for stress periods 7 through 12 88 | if sim.kper <= 6: 89 | rcha = ml.rcha_0 90 | spd = rcha.stress_period_data 91 | print(f"updating recharge: stress_period={ml.kper}") 92 | spd["recharge"] += 0.40 * sim.kper 93 | 94 | if callback_step == Callbacks.timestep_start: 95 | print(f"updating wel flux: stress_period={ml.kper}, timestep={ml.kstp}") 96 | ml.wel.stress_period_data["q"] -= ml.kstp * 1.5 97 | 98 | if callback_step == Callbacks.iteration_start: 99 | # we can implement complex solutions to boundary conditions here! 100 | pass 101 | 102 | 103 | # The callback function is then passed to `modflowapi.run_simulation` 104 | 105 | modflowapi.run_simulation(dll, sim_ws, callback_function, verbose=False) 106 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. modflowapi documentation master file, created by 2 | sphinx-quickstart on Thu Apr 3 11:41:16 2025. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | modflowapi documentation 7 | ======================== 8 | 9 | An extension to `xmipy` for the MODFLOW API. 10 | 11 | 12 | .. toctree:: 13 | :maxdepth: 2 14 | :caption: User Guide 15 | 16 | examples/notebooks/Quickstart 17 | examples/notebooks/Extensions 18 | examples/notebooks/Head_Monitor_Example 19 | 20 | .. autosummary:: 21 | :caption: API Reference 22 | :toctree: _autosummary 23 | :recursive: 24 | 25 | modflowapi -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | %SPHINXBUILD% >NUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /guide-to-publish.md: -------------------------------------------------------------------------------- 1 | # How to publish to PyPi 2 | 3 | 1) If present delete dist folder 4 | 5 | 2) If not done yet, install build and twine via 6 | ``` 7 | pip install build twine 8 | ``` 9 | 3) Update the version in ``modflowapi/version.py`` 10 | 11 | 4) Re-create the wheels: 12 | ``` 13 | python -m build 14 | ``` 15 | 5) Re-upload the new files: 16 | ``` 17 | twine upload dist/* 18 | ``` 19 | -------------------------------------------------------------------------------- /manualtest/collect_states.py: -------------------------------------------------------------------------------- 1 | """Test helper for sequence of model states.""" 2 | 3 | from collections import defaultdict 4 | 5 | import pandas as pd 6 | 7 | import modflowapi 8 | 9 | 10 | class StateCollector: 11 | """ 12 | Callback that collects the model state sequence. 13 | 14 | THe attribute `states` is a list of tuples `(model_name, state_name)`, 15 | where `state_name` is `callback_step.name`. 16 | """ 17 | 18 | def __init__(self): 19 | self.states = [] 20 | 21 | def __call__(self, sim, callback_step): 22 | self.states.append((sim.model_names[0], callback_step.name)) 23 | 24 | 25 | def run(dll, sim_path): 26 | """Run a model and collect its sat sequence.""" 27 | callback = StateCollector() 28 | modflowapi.run_simulation(dll=dll, sim_path=sim_path, callback=callback) 29 | return callback.states 30 | 31 | 32 | def visualize_states(states, limit=None): 33 | """ 34 | Visualize the state sequence by model. 35 | 36 | This prints one tree-like sequence of state names per model. 37 | Different state groups have different indentations to visualize the 38 | flow. 39 | """ 40 | indents = { 41 | "initialize": 0, 42 | "finalize": 0, 43 | "stress_period_start": 4, 44 | "stress_period_end": 4, 45 | "timestep_start": 8, 46 | "timestep_end": 8, 47 | "iteration_start": 12, 48 | "iteration_end": 12, 49 | } 50 | models = defaultdict(list) 51 | for model_name, state in states: 52 | models[model_name].append(state) 53 | for model_name, model_states in models.items(): 54 | print(model_name) 55 | for count, state in enumerate(model_states): 56 | if limit and limit == count: 57 | break 58 | print(" " * indents[state], state) 59 | 60 | 61 | def count_states(states): 62 | """ 63 | Count states per model. 64 | 65 | The numbers of `start_state` and `end_state` should match. 66 | """ 67 | states = pd.DataFrame(states, columns=["model", "state"]) 68 | counts = states.groupby(["model", "state"])[["state"]].agg("count") 69 | counts.columns = ["counts"] 70 | return counts 71 | -------------------------------------------------------------------------------- /modflowapi/__init__.py: -------------------------------------------------------------------------------- 1 | # ruff: noqa: F401, allow imports directly from modflowapi 2 | from modflowapi.modflowapi import ModflowApi 3 | 4 | from . import extensions 5 | from .extensions.runner import Callbacks, run_simulation 6 | from .version import __version__ 7 | -------------------------------------------------------------------------------- /modflowapi/extensions/__init__.py: -------------------------------------------------------------------------------- 1 | # ruff: noqa: F401, allow imports directly from modflowapi.extensions 2 | from .apiexchange import ApiExchange 3 | from .apimodel import ApiModel 4 | from .apisimulation import ApiSimulation 5 | -------------------------------------------------------------------------------- /modflowapi/extensions/advpaks.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from .data import ListInput 4 | from .pakbase import AdvancedPackage 5 | 6 | 7 | class SfrPakage(AdvancedPackage): 8 | """ 9 | Container for SFR and SFR like packages 10 | 11 | Parameters 12 | ---------- 13 | model : ApiModel 14 | modflowapi model object 15 | pkg_type : str 16 | package type. Ex. "SFR" 17 | pkg_name : str 18 | package name (in the mf6 variables) 19 | sim_package : bool 20 | boolean flag for simulation level packages. Ex. TDIS, IMS 21 | """ 22 | 23 | def __init__(self, model, pkg_type, pkg_name, sim_package=False): 24 | super().__init__(model, pkg_type, pkg_name, sim_package) 25 | 26 | self._diversion_var_arrs = [] 27 | self._set_advanced_variable_addrs("diversions", "_diversion_var_addrs") 28 | self._diversion_vars = ListInput(self, self._diversion_var_arrs, spd=False) 29 | 30 | @property 31 | def diversions(self): 32 | return self._diversion_vars 33 | 34 | @diversions.setter 35 | def diversions(self, recarray): 36 | """ 37 | Setter object to update the diversions data 38 | 39 | """ 40 | if isinstance(recarray, np.recarray): 41 | self._diversion_vars.values = recarray 42 | elif isinstance(recarray, ListInput): 43 | self._diversion_vars.values = recarray.values 44 | elif recarray is None: 45 | self._diversion_vars.values = recarray 46 | else: 47 | raise TypeError(f"{type(recarray)} is not a supported diversions type") 48 | 49 | 50 | class LakPackage(AdvancedPackage): 51 | """ 52 | Container for LAK and LAK like packages 53 | 54 | Parameters 55 | ---------- 56 | model : ApiModel 57 | modflowapi model object 58 | pkg_type : str 59 | package type. Ex. "LAK" 60 | pkg_name : str 61 | package name (in the mf6 variables) 62 | sim_package : bool 63 | boolean flag for simulation level packages. Ex. TDIS, IMS 64 | """ 65 | 66 | def __init__(self, model, pkg_type, pkg_name, sim_package=False): 67 | super().__init__(model, pkg_type, pkg_name, sim_package) 68 | 69 | 70 | class MawPackage(AdvancedPackage): 71 | """ 72 | Container for MAW and MAW like packages 73 | 74 | Parameters 75 | ---------- 76 | model : ApiModel 77 | modflowapi model object 78 | pkg_type : str 79 | package type. Ex. "MAW" 80 | pkg_name : str 81 | package name (in the mf6 variables) 82 | sim_package : bool 83 | boolean flag for simulation level packages. Ex. TDIS, IMS 84 | """ 85 | 86 | def __init__(self, model, pkg_type, pkg_name, sim_package=False): 87 | super().__init__(model, pkg_type, pkg_name, sim_package) 88 | 89 | 90 | class UzfPackage(AdvancedPackage): 91 | """ 92 | Container for UZF and UZF like packages 93 | 94 | Parameters 95 | ---------- 96 | model : ApiModel 97 | modflowapi model object 98 | pkg_type : str 99 | package type. Ex. "UZF" 100 | pkg_name : str 101 | package name (in the mf6 variables) 102 | sim_package : bool 103 | boolean flag for simulation level packages. Ex. TDIS, IMS 104 | """ 105 | 106 | def __init__(self, model, pkg_type, pkg_name, sim_package=False): 107 | super().__init__(model, pkg_type, pkg_name, sim_package) 108 | -------------------------------------------------------------------------------- /modflowapi/extensions/apiexchange.py: -------------------------------------------------------------------------------- 1 | from .apimodel import ApiMbase 2 | from .pakbase import ListPackage 3 | 4 | 5 | class ApiExchange(ApiMbase): 6 | """ 7 | ApiExchange class for GWF-GWF packages and container to access the 8 | simulation level GWF-GWF, MVR, and GNC packages 9 | 10 | Parameters 11 | ---------- 12 | mf6 : ModflowApi 13 | initialized ModflowApi object 14 | name : str 15 | modflow exchange name. ex. "GWF-GWF_1" 16 | """ 17 | 18 | def __init__(self, mf6, name): 19 | pkg_types = { 20 | "gwf-gwf": ListPackage, 21 | "gwt-gwt": ListPackage, 22 | "gwe-gwe": ListPackage, 23 | } 24 | super().__init__(mf6, name, pkg_types) 25 | -------------------------------------------------------------------------------- /modflowapi/extensions/apimodel.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from .datamodel import get_package_type, gridshape 4 | from .pakbase import AdvancedPackage, ArrayPackage, ListPackage, package_factory 5 | 6 | 7 | class ApiMbase: 8 | """ 9 | Base object for the Models and Exchanges 10 | 11 | Parameters 12 | ---------- 13 | mf6 : ModflowApi 14 | initialized ModflowApi object 15 | name : str 16 | modflow model name. ex. "GWF_1", "GWF-GWF_1" 17 | pkg_types : None, dict 18 | optional dictionary of package types and ApiPackage class types 19 | """ 20 | 21 | def __init__(self, mf6, name, pkg_types=None): 22 | self.mf6 = mf6 23 | self.name = name 24 | self._pkg_names = None 25 | self._pak_type = None 26 | self._pkg_types = pkg_types 27 | self.package_dict = {} 28 | self._set_package_names() 29 | self._create_package_list() 30 | 31 | @property 32 | def package_list(self): 33 | """ 34 | Returns a list of package objects for the model 35 | """ 36 | return [package for _, package in self.package_dict.items()] 37 | 38 | @property 39 | def package_names(self): 40 | """ 41 | Returns a list of package names for the model 42 | """ 43 | return list(self.package_dict.keys()) 44 | 45 | @property 46 | def package_types(self): 47 | return list(set([package.pkg_type for package in self.package_list])) 48 | 49 | def _set_package_names(self): 50 | """ 51 | Method to get/set all package names within the model 52 | """ 53 | pak_types = {"dis": "DIS"} 54 | for addr in self.mf6.get_input_var_names(): 55 | tmp = addr.split("/") 56 | if addr.endswith("PACKAGE_TYPE") and tmp[0] == self.name: 57 | pak_types[tmp[1]] = self.mf6.get_value(addr)[0] 58 | elif tmp[0] == self.name and len(tmp) == 2: 59 | if tmp[0].startswith("GWF-GWF"): 60 | pak_types[tmp[0]] = "GWF-GWF" 61 | pak_types.pop("dis", None) 62 | elif tmp[0].startswith("GWT-GWT"): 63 | pak_types[tmp[0]] = "GWT-GWT" 64 | pak_types.pop("dis", None) 65 | 66 | self._pak_type = list(pak_types.values()) 67 | self._pkg_names = list(pak_types.keys()) 68 | 69 | def _create_package_list(self): 70 | """ 71 | Method to load packages and set up the package dict/list variable 72 | """ 73 | for ix, pkg_name in enumerate(self._pkg_names): 74 | pkg_type = self._pak_type[ix].lower() 75 | if self._pkg_types is None: 76 | basepackage = get_package_type(pkg_type) 77 | else: 78 | if pkg_type in self._pkg_types: 79 | basepackage = self._pkg_types[pkg_type] 80 | else: 81 | basepackage = AdvancedPackage 82 | 83 | package = package_factory(pkg_type, basepackage) 84 | adj_pkg_name = "".join(pkg_type.split("-")) 85 | 86 | if adj_pkg_name.lower() in ("gwfgwf", "gwtgwt"): 87 | adj_pkg_name = "" 88 | else: 89 | adj_pkg_name = pkg_name 90 | 91 | package = package(basepackage, self, pkg_type, adj_pkg_name) 92 | self.package_dict[pkg_name.lower()] = package 93 | 94 | def get_package(self, pkg_name) -> ListPackage or ArrayPackage or AdvancedPackage: 95 | """ 96 | Method to get a package 97 | 98 | Parameters 99 | ---------- 100 | pkg_name : str 101 | package name str. Ex. "wel_0" 102 | """ 103 | pkg_name = pkg_name.lower() 104 | if pkg_name in self.package_dict: 105 | return self.package_dict[pkg_name] 106 | 107 | raise KeyError(f"{pkg_name} is not a valid package name for this model") 108 | 109 | 110 | class ApiModel(ApiMbase): 111 | """ 112 | Container to hold MODFLOW model information and load supported packages 113 | 114 | Parameters 115 | ---------- 116 | mf6 : ModflowApi 117 | initialized ModflowApi object 118 | name : str 119 | modflow model name. ex. "GWF_1" 120 | 121 | """ 122 | 123 | def __init__(self, mf6, name): 124 | _id_addr = mf6.get_var_address("ID", name) 125 | self._id = mf6.get_value(_id_addr)[0] 126 | if self._id < 1: 127 | self._id = 1 128 | _solnid = mf6.get_var_address("IDSOLN", name) 129 | self._solnid = mf6.get_value(_solnid)[0] 130 | grid_type = mf6.get_grid_type(self._id) 131 | if grid_type == "rectilinear": 132 | self.dis_type = "dis" 133 | self.dis_name = "DIS" 134 | elif grid_type == "unstructured": 135 | self.dis_type = "disu" 136 | self.dis_name = "DIS" 137 | else: 138 | raise AssertionError(f"Unrecognized discretization type {grid_type}") 139 | 140 | self.allow_convergence = True 141 | self._shape = None 142 | self._size = None 143 | self._nodetouser = None 144 | self._usertonode = None 145 | self._iteration = 0 146 | 147 | super().__init__(mf6, name) 148 | 149 | def __repr__(self): 150 | s = f"{self.name}, " 151 | shape = self.shape 152 | if self.dis_type == "dis": 153 | s += f"{shape[0]} Layer, {shape[1]} Row, {shape[2]} Column model\n" 154 | 155 | elif self.dis_type == "disu": 156 | if len(shape) == 2: 157 | s += f"{shape[0]} Layer, {shape[1]} Nodes per layer model\n" 158 | else: 159 | s += f"{shape[0]} Node model\n" 160 | else: 161 | pass 162 | 163 | s += "Packages accessible include: \n" 164 | for typ, baseobj in [ 165 | ("ArrayPackage", ArrayPackage), 166 | ("ListPackage", ListPackage), 167 | ("AdvancedPackage", AdvancedPackage), 168 | ]: 169 | s += f" {typ} objects:\n" 170 | for name, obj in self.package_dict.items(): 171 | if isinstance(obj, baseobj): 172 | s += f" {name}: {type(obj)}\n" 173 | 174 | return s 175 | 176 | def __getattr__(self, item): 177 | """ 178 | Method for getting packages either by package name or by 179 | package type name 180 | 181 | """ 182 | if item in self.package_dict: 183 | return self.package_dict[item] 184 | else: 185 | pkg_list = [] 186 | for pkg_name, package in self.package_dict.items(): 187 | if item == package.pkg_type: 188 | pkg_list.append(package) 189 | 190 | if len(pkg_list) == 0: 191 | return super().__getattribute__(item) 192 | elif len(pkg_list) == 1: 193 | return pkg_list[0] 194 | else: 195 | return pkg_list 196 | 197 | def __setattr__(self, key, value): 198 | """ 199 | Method for type checking variables 200 | """ 201 | if key == "allow_convergence": 202 | if not isinstance(value, bool): 203 | raise TypeError("allow convergenge must be a boolean value") 204 | 205 | super().__setattr__(key, value) 206 | 207 | @property 208 | def kper(self): 209 | """ 210 | Returns the current stress period 211 | """ 212 | var_addr = self.mf6.get_var_address("KPER", "TDIS") 213 | return self.mf6.get_value(var_addr)[0] - 1 214 | 215 | @property 216 | def kstp(self): 217 | """ 218 | Returns the current timestep 219 | """ 220 | var_addr = self.mf6.get_var_address("KSTP", "TDIS") 221 | return self.mf6.get_value(var_addr)[0] - 1 222 | 223 | @property 224 | def nstp(self): 225 | """ 226 | Returns the number of timesteps in the current stress period 227 | """ 228 | var_addr = self.mf6.get_var_address("NSTP", "TDIS") 229 | return self.mf6.get_value(var_addr)[0] 230 | 231 | @property 232 | def nper(self): 233 | """ 234 | Returns the number of stress periods 235 | """ 236 | var_addr = self.mf6.get_var_address("NPER", "TDIS") 237 | return self.mf6.get_value(var_addr)[0] 238 | 239 | @property 240 | def totim(self): 241 | """ 242 | Returns the current model time 243 | """ 244 | var_addr = self.mf6.get_var_address("TOTIM", "TDIS") 245 | return self.mf6.get_value(var_addr)[0] 246 | 247 | @property 248 | def subcomponent_id(self): 249 | """ 250 | Returns the model subcomponent id 251 | """ 252 | return self._id 253 | 254 | @property 255 | def solution_id(self): 256 | """ 257 | Returns the model solution id 258 | """ 259 | return self._solnid 260 | 261 | @property 262 | def shape(self): 263 | """ 264 | Returns a tuple of the model shape 265 | """ 266 | ivn = self.mf6.get_input_var_names() 267 | if self._shape is None: 268 | shape_vars = gridshape[self.dis_type] 269 | shape = [] 270 | for var in shape_vars: 271 | var_addr = self.mf6.get_var_address(var.upper(), self.name, self.dis_name) 272 | if var_addr in ivn: 273 | shape.append(self.mf6.get_value(var_addr)[0]) 274 | if not shape: 275 | var_addr = self.mf6.get_var_address("NODES", self.name, self.dis_name) 276 | shape.append(self.mf6.get_value(var_addr)[0]) 277 | self._shape = tuple(shape) 278 | return self._shape 279 | 280 | @property 281 | def size(self): 282 | """ 283 | Returns the number of nodes in the model 284 | """ 285 | if self._size is None: 286 | size = 1 287 | for dim in self.shape: 288 | size *= dim 289 | self._size = size 290 | return self._size 291 | 292 | @property 293 | def nodetouser(self): 294 | """ 295 | Returns the "nodeuser" array 296 | """ 297 | if self._nodetouser is None: 298 | self._set_node_mapping() 299 | return self._nodetouser 300 | 301 | @property 302 | def usertonode(self): 303 | """ 304 | Returns an array that maps user arrays to modflow's internal nodes 305 | """ 306 | if self._usertonode is None: 307 | self._set_node_mapping() 308 | return self._usertonode 309 | 310 | @property 311 | def X(self): 312 | """ 313 | Returns the solution array. Ex. GFW models return heads, GWT 314 | returns a concentration array, etc... 315 | """ 316 | x = self.mf6.get_value(self.mf6.get_var_address("X", self.name)) 317 | array = np.full(self.size, np.nan) 318 | array[self.nodetouser] = x[: self.nodetouser.size] 319 | return array.reshape(self.shape) 320 | 321 | def _set_node_mapping(self): 322 | """ 323 | Sets the node mapping arrays NODEUSER and NODEREDUCED for mapping 324 | user arrays to modflow's internal arrays 325 | """ 326 | node_addr = self.mf6.get_var_address("NODES", self.name, self.dis_name) 327 | nodes = self.mf6.get_value(node_addr).item() 328 | if nodes == self.size: 329 | nodeuser = np.arange(nodes).astype(int) 330 | nodereduced = np.copy(nodeuser) 331 | else: 332 | nodeuser_addr = self.mf6.get_var_address("NODEUSER", self.name, self.dis_name) 333 | nodeuser = self.mf6.get_value(nodeuser_addr) - 1 334 | nodereduced_addr = self.mf6.get_var_address("NODEREDUCED", self.name, self.dis_name) 335 | nodereduced = self.mf6.get_value(nodereduced_addr) - 1 336 | 337 | self._nodetouser = nodeuser 338 | self._usertonode = nodereduced 339 | -------------------------------------------------------------------------------- /modflowapi/extensions/apisimulation.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from .apiexchange import ApiExchange 4 | from .apimodel import ApiMbase, ApiModel 5 | from .pakbase import ApiSlnPackage, ListPackage, ScalarPackage, package_factory 6 | 7 | 8 | class ApiSimulation: 9 | """ 10 | ApiSimulation object that holds a modflow simulation info and loads 11 | supported models. 12 | 13 | Parameters 14 | ---------- 15 | mf6 : ModflowApi 16 | initialized ModflowApi object 17 | models : dict 18 | dictionary of model_name: modflowapi.extensions.ApiModel objects 19 | solutions : dict 20 | dictionary of solution_id: solution_name 21 | exchanges : dict 22 | dictionary of exchange_name: modflowapi.extensions.ApiExchange objects 23 | tdis : ApiTdisPackage 24 | time discretization (TDIS) ScalarPackage 25 | ats : None or ApiAtsPackage 26 | adaptive time step ScalarPackage object 27 | """ 28 | 29 | def __init__(self, mf6, models, solutions, exchanges, tdis, ats): 30 | self.mf6 = mf6 31 | self._models = models 32 | self._exchanges = exchanges 33 | self._solutions = solutions 34 | self._iteration = -1 35 | 36 | self.tdis = tdis 37 | self.ats = ats 38 | self._ats_active = True 39 | if ats is None: 40 | self._ats_active = False 41 | 42 | def __getattr__(self, item): 43 | """ 44 | Dynamic method to get models by model name 45 | """ 46 | if item.lower() in self._models: 47 | return self.get_model(item) 48 | else: 49 | return super().__getattribute__(item) 50 | 51 | def __repr__(self): 52 | s = self.__doc__ 53 | s += f"Number of models: {len(self._models)}:\n" 54 | for name, obj in self._models.items(): 55 | s += f"\t{name} : {type(obj)}\n" 56 | s += "Simulation level packages include:\n" 57 | s += f"\tSLN: {self.sln}\n" 58 | s += f"\tTDIS: {self.tdis}\n" 59 | if self.ats_active: 60 | s += f"\tATS: {self.ats}\n" 61 | if self._exchanges: 62 | s += "\tExchanges include:\n" 63 | for name, exchange in self._exchanges.items(): 64 | f"\t\t{name}: {type(exchange)}\n" 65 | 66 | return s 67 | 68 | @property 69 | def ats_active(self): 70 | """ 71 | Returns a boolean to indicate if the ATS package is used in this 72 | simulation. 73 | """ 74 | return self._ats_active 75 | 76 | @property 77 | def ats_period(self): 78 | """ 79 | Returns a boolean to indicate if this is an ATS stress period 80 | """ 81 | # maybe return tuple (bool, dtmin) 82 | if self.ats_active: 83 | recarray = self.ats.stress_period_data.values 84 | idx = np.where(recarray["iperats"] == self.kper + 1)[0] 85 | if len(idx) > 0: 86 | return True, recarray["dtmin"][idx[0]] 87 | 88 | return False, None 89 | 90 | @property 91 | def allow_convergence(self): 92 | """ 93 | Returns a boolean value that specifies if the user will allow the 94 | model to converge. Default is True 95 | """ 96 | for model in self.models: 97 | if not model.allow_convergence: 98 | return False 99 | return True 100 | 101 | @allow_convergence.setter 102 | def allow_convergence(self, value): 103 | """ 104 | Method to set the allow_convergence flag 105 | 106 | Parameters 107 | ---------- 108 | value : bool 109 | if True (default) model converges if solution converges, if False 110 | model will continue solving after solution converges. 111 | """ 112 | for model in self.models: 113 | model.allow_convergence = value 114 | 115 | @property 116 | def subcomponent_count(self): 117 | """ 118 | Returns the number of subcomponents in the simulation 119 | """ 120 | return self.mf6.get_subcomponent_count() 121 | 122 | @property 123 | def solutions(self): 124 | """ 125 | Returns a dictionary of solution_id : (name, ApiSlnPackage) 126 | """ 127 | return self._solutions 128 | 129 | @property 130 | def sln(self): 131 | """ 132 | Returns an ApiSolution object 133 | """ 134 | if len(self._solutions) > 1: 135 | return list(self._solutions.values()) 136 | else: 137 | for sln in self._solutions.values(): 138 | return sln 139 | 140 | @property 141 | def model_names(self): 142 | """ 143 | Returns a list of model names 144 | """ 145 | return list(self._models.keys()) 146 | 147 | @property 148 | def exchange_names(self): 149 | """ 150 | Returns a list of exchange GWF-GWF names 151 | """ 152 | if self._exchanges.keys(): 153 | return list(self._exchanges.keys()) 154 | 155 | @property 156 | def models(self): 157 | """ 158 | Returns a list of ApiModel objects associated with the simulation 159 | """ 160 | return [v for _, v in self._models.items()] 161 | 162 | @property 163 | def iteration(self): 164 | return self._iteration 165 | 166 | @iteration.setter 167 | def iteration(self, value): 168 | if isinstance(value, int): 169 | self._iteration = value 170 | 171 | @property 172 | def kper(self): 173 | """ 174 | Returns the current stress period 175 | """ 176 | return self.tdis.kper - 1 177 | 178 | @property 179 | def kstp(self): 180 | """ 181 | Returns the current time step 182 | """ 183 | return self.tdis.kstp - 1 184 | 185 | @property 186 | def nstp(self): 187 | """ 188 | Returns the total number of time steps 189 | """ 190 | return self.tdis.nstp 191 | 192 | @property 193 | def nper(self): 194 | """ 195 | Returns the total number of stress periods 196 | """ 197 | return self.tdis.nper 198 | 199 | @property 200 | def totim(self): 201 | """ 202 | Returns the current model time 203 | """ 204 | return self.tdis.totim 205 | 206 | @property 207 | def delt(self): 208 | """ 209 | Returns the timestep length for the current time step 210 | """ 211 | return self.tdis.delt 212 | 213 | def get_model(self, model_id=None): 214 | """ 215 | Method to get a model from the simulation object by model name or 216 | subcomponent id 217 | 218 | Parameters 219 | ---------- 220 | model_id : str, int 221 | model name (ex. "GWF_1") or subcomponent id (ex. 1) 222 | """ 223 | if model_id is None: 224 | model_id = int(min([model.subcomponent_id for model in self.models])) 225 | 226 | if isinstance(model_id, int): 227 | for model in self.models: 228 | if model_id == model.subcomponent_id: 229 | return model 230 | raise KeyError(f"No model found with subcomponent id {model_id}") 231 | 232 | elif isinstance(model_id, str): 233 | model_id = model_id.lower() 234 | if model_id in self._models: 235 | return self._models[model_id] 236 | raise KeyError(f"Model name {model_id} is invalid") 237 | 238 | else: 239 | raise TypeError("A string or int must be supplied to get model") 240 | 241 | def get_exchange(self, exchange_name=None): 242 | """ 243 | Get a GWF-GWF "model" and all associated simulation level package 244 | data (ex. GNC, MVR) 245 | 246 | Parameters 247 | ---------- 248 | exchange_name : str 249 | name of the GWF-GWF exchange package 250 | 251 | Returns 252 | ------- 253 | modflowapi.extensions.ApiExchange object 254 | """ 255 | if self.exchange_names is None: 256 | raise AssertionError("No exchanges are present in this simulation") 257 | 258 | if exchange_name is None: 259 | for _, exg in self._exchanges: 260 | return exg 261 | 262 | else: 263 | if exchange_name in self._exchanges: 264 | return self._exchanges[exchange_name] 265 | raise KeyError(f"Exchange name {exchange_name} is invalid") 266 | 267 | @staticmethod 268 | def load(mf6): 269 | """ 270 | Method to load a modflowapi instance into the ApiSimulation extensions 271 | 272 | Parameters 273 | ---------- 274 | mf6 : ModflowApi 275 | initialized ModflowApi object 276 | """ 277 | variables = mf6.get_input_var_names() 278 | model_names = [] 279 | for variable in variables: 280 | t = variable.split("/") 281 | if len(t) == 3: 282 | name = t[0] 283 | id_var_addr = mf6.get_var_address("ID", name) 284 | if name.startswith("SLN"): 285 | continue 286 | elif name.startswith("GWTIM") or name.startswith("GWFIM") or name.startswith("GWEIM"): 287 | continue 288 | elif name.startswith("GWFCON") or name.startswith("GWTCON") or name.startswith("GWECON"): 289 | continue 290 | if id_var_addr not in variables: 291 | continue 292 | 293 | if name not in model_names: 294 | model_names.append(name) 295 | 296 | models = {} 297 | for name in model_names: 298 | models[name.lower()] = ApiModel(mf6, name) 299 | 300 | solution_names = [] 301 | for variable in variables: 302 | t = variable.split("/") 303 | if len(t) == 2: 304 | name = t[0] 305 | id_var_addr = mf6.get_var_address("ID", name) 306 | if name.lower() in models or name == "TDIS": 307 | continue 308 | if name.startswith("GWTIM") or name.startswith("GWFIM") or name.startswith("GWEIM"): 309 | continue 310 | if id_var_addr not in variables: 311 | continue 312 | 313 | solution_names.append(t[0]) 314 | 315 | idp_names = [i for i in mf6.get_value("__INPUT__/SIM/NAM/SLNMNAMES")] 316 | solution_types = [ 317 | i[:-1].lower() for ix, i in enumerate(mf6.get_value("__INPUT__/SIM/NAM/SLNTYPE")) if idp_names[ix] 318 | ] 319 | 320 | tmpmdl = ApiMbase(mf6, "") 321 | solution_names = list(set(solution_names)) 322 | solution_dict = {} 323 | for name in solution_names: 324 | sid_var_addr = mf6.get_var_address("ID", name) 325 | sid = mf6.get_value(sid_var_addr)[0] 326 | slntype = solution_types[sid - 1] 327 | sln = ApiSlnPackage(tmpmdl, name, pkg_type=slntype) 328 | solution_dict[sid] = sln 329 | 330 | solutions = solution_dict 331 | 332 | # TDIS package construction 333 | tdis_constructor = package_factory("tdis", ScalarPackage) 334 | tdis = tdis_constructor(ScalarPackage, tmpmdl, "tdis", "tdis", sim_package=True) 335 | 336 | ats = None 337 | # ATS package construction 338 | for variable in variables: 339 | if variable.startswith("ATS"): 340 | ats_constructor = package_factory("ats", ListPackage) 341 | ats = ats_constructor(ListPackage, tmpmdl, "ats", "ats", sim_package=True) 342 | break 343 | 344 | # get the exchanges 345 | exchange_names = [] 346 | for variable in variables: 347 | if variable.startswith("GWF-GWF") or variable.startswith("GWT-GWT"): 348 | exchange_name = variable.split("/")[0] 349 | if exchange_name not in exchange_names: 350 | exchange_names.append(exchange_name) 351 | 352 | # sim_packages: tdis, gwf-gwf, sln 353 | exchanges = {} 354 | for exchange_name in exchanges: 355 | exchange = ApiExchange(mf6, exchange_name) 356 | exchanges[exchange_name.lower()] = exchange 357 | 358 | return ApiSimulation(mf6, models, solutions, exchanges, tdis, ats) 359 | -------------------------------------------------------------------------------- /modflowapi/extensions/datamodel.py: -------------------------------------------------------------------------------- 1 | """ 2 | Centralized location to store the "data model"/relationship trees for packages 3 | blocks, and input variables that are used by the modflowapi.extensions code 4 | """ 5 | 6 | gridshape = { 7 | "dis": ["nlay", "nrow", "ncol"], 8 | "disu": [ 9 | "nlay", 10 | "ncpl", 11 | ], 12 | } 13 | 14 | 15 | # Note: HFB variables are not accessible in the memory manager 10/7/2022 16 | pkgvars = { 17 | "dis": ["top", "bot", "area", "idomain"], 18 | "chd": [ 19 | "nbound", 20 | "maxbound", 21 | "nodelist", 22 | ("bound", ("head",)), 23 | "naux", 24 | "auxname_cst", 25 | "auxvar", 26 | ], 27 | "drn": [ 28 | "nbound", 29 | "maxbound", 30 | "nodelist", 31 | ( 32 | "bound", 33 | ( 34 | "elev", 35 | "cond", 36 | ), 37 | ), 38 | "naux", 39 | "auxname_cst", 40 | "auxvar", 41 | ], 42 | "evt": [ 43 | "nbound", 44 | "maxbound", 45 | "nodelist", 46 | ( 47 | "bound", 48 | ( 49 | "surface", 50 | "rate", 51 | "depth", 52 | ), 53 | ), 54 | # "pxdp:NSEG", "petm:NSEG" 55 | "naux", 56 | "auxname_cst", 57 | "auxvar", 58 | ], 59 | "ghb": [ 60 | "nbound", 61 | "maxbound", 62 | "nodelist", 63 | ( 64 | "bound", 65 | ( 66 | "bhead", 67 | "cond", 68 | ), 69 | ), 70 | "naux", 71 | "auxname_cst", 72 | "auxvar", 73 | ], 74 | "ic": ["strt"], 75 | "npf": ["k11", "k22", "k33", "angle1", "angle2", "angle3", "icelltype"], 76 | "rch": [ 77 | "maxbound", 78 | "nbound", 79 | "nodelist", 80 | ("bound", ("recharge",)), 81 | "naux", 82 | "auxname_cst", 83 | "auxvar", 84 | ], 85 | "riv": [ 86 | "maxbound", 87 | "nbound", 88 | "nodelist", 89 | ("bound", ("stage", "cond", "rbot")), 90 | "naux", 91 | "auxname_cst", 92 | "auxvar", 93 | ], 94 | "sto": ["iconvert", "ss", "sy"], 95 | "wel": [ 96 | "maxbound", 97 | "nbound", 98 | "nodelist", 99 | ("bound", ("q",)), 100 | "naux", 101 | "auxname_cst", 102 | "auxvar", 103 | ], 104 | # gwe model 105 | "cnd": ["alh", "alv", "ath1", "ath2", "atv", "kts"], 106 | "est": ["porosity", "decay", "cps", "rhos"], 107 | "cpt": [ 108 | "maxbound", 109 | "nbound", 110 | "nodelist", 111 | ("bound", ("temp",)), 112 | "naux", 113 | "auxname_cst", 114 | "auxvar", 115 | ], 116 | "esl": [ 117 | "maxbound", 118 | "nbound", 119 | "nodelist", 120 | ("bound", ("senerrate",)), 121 | "naux", 122 | "auxname_cst", 123 | "auxvar", 124 | ], 125 | # gwt model 126 | "dsp": ["diffc", "alh", "alv", "ath1", "ath2", "atv"], 127 | "cnc": [ 128 | "maxbound", 129 | "nbound", 130 | "nodelist", 131 | ("bound", ("conc",)), 132 | "naux", 133 | "auxname_cst", 134 | "auxvar", 135 | ], 136 | "ist": [ 137 | "cim", 138 | "thtaim", 139 | "zetaim", 140 | "decay", 141 | "decay_sorbed", 142 | "bulk_density", 143 | "distcoef", 144 | ], 145 | "mst": ["porosity", "decay", "decay_sorbed", "bulk_density", "distcoef"], 146 | "src": [ 147 | "maxbound", 148 | "nbound", 149 | "nodelist", 150 | ("bound", ("smassrate",)), 151 | "naux", 152 | "auxname_cst", 153 | "auxvar", 154 | ], 155 | # prt model 156 | "mip": ["porosity", "retfactor", "izone"], 157 | # exchange model 158 | "gwf-gwf": ["nexg", "nodem1", "nodem2", "cl1", "cl2", "ihc", "hwva"], 159 | "gwt-gwt": ["nexg", "nodem1", "nodem2", "cl1", "cl2", "ihc", "hwva"], 160 | "gwe-gwe": ["nexg", "nodem1", "nodem2", "cl1", "cl2", "ihc", "hwva"], 161 | # simulation 162 | "ats": [ 163 | "maxats", 164 | "iperats", 165 | "dt0", 166 | "dtmin", 167 | "dtmax", 168 | "dtadj", 169 | "dtfailadj", 170 | ], 171 | "tdis": [ 172 | "nper", 173 | "itmuni", 174 | "kper", 175 | "kstp", 176 | "delt", 177 | "pertim", 178 | "totim,", 179 | "perlen", 180 | "nstp", 181 | "tsmult", 182 | ], 183 | # solution package 184 | "sln-ims": [ 185 | "mxiter", 186 | "dvclose", 187 | "gamma", 188 | "theta", 189 | "akappa", 190 | "amomentum", 191 | "numtrack", 192 | "btol", 193 | "breduc", 194 | "res_lim", 195 | ], 196 | "ims": [ 197 | "niterc", 198 | "dvclose", 199 | "rclose", 200 | "relax", 201 | "ipc", 202 | "droptol", 203 | "north", 204 | "iscl", 205 | "iord", 206 | ], 207 | "sln-ems": [ 208 | "icnvg", 209 | "ttsoln", 210 | ], 211 | } 212 | 213 | 214 | adv_pkgvars = { 215 | "sfr": { 216 | "packagedata": [ 217 | "maxbound", 218 | ( 219 | "ifno:range:maxbound", 220 | "nodelist", 221 | "length", 222 | "width", 223 | "slope", 224 | "strtop", 225 | "bthick", 226 | "hk", 227 | "rough", 228 | "nconnreach", 229 | "ustrf", 230 | "ndiv", 231 | ), 232 | ], 233 | "diversions": [ 234 | "ndiv:count_nonzero:ndiv", 235 | ( 236 | "ifno:where_idx:ndiv", 237 | "idv:where_val:ndiv", 238 | "divreach", # iconr 239 | ), 240 | ], 241 | "perioddata": [ 242 | "maxbound", 243 | "nbound", 244 | ( 245 | "bound", 246 | ("ifno", "sfrsetting", "setting_0", "setting_1"), 247 | ), 248 | ], 249 | }, 250 | "uzf": { 251 | "packagedata": [ 252 | "maxbound", 253 | ( 254 | "ifno:range:maxbound", 255 | "nodelist", 256 | "landflag", 257 | "ivertcon", 258 | "surfdep", 259 | "vks", 260 | "thtr", 261 | "thts", 262 | "thti", 263 | "eps", 264 | ), 265 | ], 266 | "perioddata": [ 267 | "maxbound", 268 | "nbound", 269 | ("bound", ("ifno:range:maxbound", "finf", "pet", "extdp", "extwc", "ha", "hroot", "rootact")), 270 | ], 271 | }, 272 | "lak": { 273 | "packagedata": ["nlakes", ("ifno:range:nlakes", "strt", "nlakeconn")], 274 | }, 275 | "maw": {"packagedata": ["nmawwells", ("ifno:range:nmawwells", "radius", "bot", "strt", "ngwfnodes")]}, 276 | } 277 | 278 | 279 | def get_package_type(pkg_type): 280 | from .advpaks import LakPackage, MawPackage, SfrPakage, UzfPackage 281 | from .pakbase import AdvancedPackage, ArrayPackage, ListPackage, ScalarPackage 282 | 283 | pkg_types = { 284 | "dis": ArrayPackage, 285 | "chd": ListPackage, 286 | "drn": ListPackage, 287 | "evt": ListPackage, 288 | "ghb": ListPackage, 289 | "ic": ArrayPackage, 290 | "npf": ArrayPackage, 291 | "rch": ListPackage, 292 | "riv": ListPackage, 293 | "sto": ArrayPackage, 294 | "wel": ListPackage, 295 | # advanced 296 | "sfr": SfrPakage, 297 | "uzf": UzfPackage, 298 | "lak": LakPackage, 299 | "maw": MawPackage, 300 | # "csub": None, 301 | # gwt 302 | "dsp": ArrayPackage, 303 | "cnc": ListPackage, 304 | "ist": ArrayPackage, 305 | "mst": ArrayPackage, 306 | "src": ListPackage, 307 | # gwe 308 | "cnd": ArrayPackage, 309 | "est": ArrayPackage, 310 | "cpt": ListPackage, 311 | "esl": ListPackage, 312 | # prt 313 | "mip": ArrayPackage, 314 | # sim_level pkgs 315 | "tdis": ScalarPackage, 316 | "ats": ListPackage, 317 | } 318 | if pkg_type in pkg_types: 319 | return pkg_types[pkg_type] 320 | else: 321 | return AdvancedPackage 322 | -------------------------------------------------------------------------------- /modflowapi/extensions/runner.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | from .. import ModflowApi 4 | from .apisimulation import ApiSimulation 5 | 6 | 7 | class Callbacks(Enum): 8 | initialize = 0 9 | stress_period_start = 1 10 | stress_period_end = 2 11 | timestep_start = 3 12 | timestep_end = 4 13 | iteration_start = 5 14 | iteration_end = 6 15 | finalize = 7 16 | 17 | 18 | def run_simulation(dll, sim_path, callback, verbose=False, _develop=False): 19 | """ 20 | Method to run a Modflow simulation using the MODFLOW-API 21 | with a callback function 22 | 23 | Parameters 24 | ---------- 25 | dll : str 26 | path to the Modflow6 shared object 27 | sim_path : str 28 | path to the Modflow6 simulation 29 | callback : method 30 | user defined method that intercepts the simulation 31 | progress and allows for input variable adjustments on the fly 32 | verbose : bool 33 | flag for verbose output from the simulation runner 34 | _develop : bool 35 | flag that dumps a list of all mf6 api variable addresses to text 36 | file named "var_list.txt". This is primarily used for extensions 37 | development purposes and bug fixes within the modflowapi python 38 | package. 39 | """ 40 | mf6 = ModflowApi(dll, working_directory=sim_path) 41 | 42 | if verbose: 43 | version = mf6.get_version() 44 | print(f"MODFLOW-6 API Version {version}") 45 | print("Initializing MODFLOW-6 simulation") 46 | 47 | mf6.initialize() 48 | sim = ApiSimulation.load(mf6) 49 | 50 | if _develop: 51 | with open("var_list.txt", "w") as foo: 52 | for name in mf6.get_input_var_names(): 53 | foo.write(f"{name}\n") 54 | 55 | callback(sim, Callbacks.initialize) 56 | 57 | has_converged = False 58 | current_time = mf6.get_current_time() 59 | end_time = mf6.get_end_time() 60 | kperold = [0 for _ in range(sim.subcomponent_count)] 61 | 62 | while current_time < end_time: 63 | dt = mf6.get_time_step() 64 | mf6.prepare_time_step(dt) 65 | 66 | if verbose: 67 | print(f"Solving: Stress Period {sim.kper + 1}; Timestep {sim.kstp + 1}") 68 | 69 | for sol_id, slnobj in sorted(sim.solutions.items()): 70 | models = {} 71 | maxiter = slnobj.mxiter 72 | solution = {sol_id: slnobj} 73 | for model in sim.models: 74 | if sol_id == model.solution_id: 75 | models[model.name.lower()] = model 76 | 77 | sim_grp = ApiSimulation(mf6, models, solution, sim._exchanges, sim.tdis, sim.ats) 78 | mf6.prepare_solve(sol_id) 79 | if sim.kper != kperold[sol_id - 1]: 80 | callback(sim_grp, Callbacks.stress_period_start) 81 | kperold[sol_id - 1] += 1 82 | elif current_time == 0: 83 | callback(sim_grp, Callbacks.stress_period_start) 84 | 85 | kiter = 0 86 | callback(sim_grp, Callbacks.timestep_start) 87 | 88 | if sim_grp.ats_period[0]: 89 | mindt = sim_grp.ats_period[-1] 90 | while sim_grp.delt > mindt: 91 | sim_grp.iteration = kiter 92 | callback(sim_grp, Callbacks.iteration_start) 93 | has_converged = mf6.solve(sol_id) 94 | callback(sim_grp, Callbacks.iteration_end) 95 | kiter += 1 96 | if has_converged and sim_grp.allow_convergence: 97 | break 98 | 99 | else: 100 | while kiter < maxiter: 101 | sim_grp.iteration = kiter 102 | callback(sim_grp, Callbacks.iteration_start) 103 | has_converged = mf6.solve(sol_id) 104 | callback(sim_grp, Callbacks.iteration_end) 105 | kiter += 1 106 | if has_converged and sim_grp.allow_convergence: 107 | break 108 | 109 | callback(sim_grp, Callbacks.timestep_end) 110 | mf6.finalize_solve(sol_id) 111 | if sim_grp.nstp == sim_grp.kstp + 1: 112 | callback(sim_grp, Callbacks.stress_period_end) 113 | 114 | mf6.finalize_time_step() 115 | current_time = mf6.get_current_time() 116 | 117 | if not has_converged: 118 | print(f"Simulation group: {sim_grp} DID NOT CONVERGE") 119 | 120 | try: 121 | callback(sim, Callbacks.finalize) 122 | mf6.finalize() 123 | except Exception: 124 | raise RuntimeError("MF6 simulation failed, check listing file") 125 | 126 | print("NORMAL TERMINATION OF SIMULATION") 127 | -------------------------------------------------------------------------------- /modflowapi/modflowapi.py: -------------------------------------------------------------------------------- 1 | from xmipy import XmiWrapper 2 | 3 | from .util import amend_libmf6_path 4 | 5 | 6 | class ModflowApi(XmiWrapper): 7 | """ 8 | This class extends eXtended Model Interface (XMI) Wrapper (XmiWrapper) 9 | for the MODFLOW API. XMI extends the CSDMS Basic Model Interface 10 | 11 | The extension to the XMI does not change anything in the XMI or BMI 12 | interfaces, so models implementing the ModflowApi interface is compatible 13 | with the XmiWrapper which provides XMI and BMI functionality. 14 | 15 | """ 16 | 17 | def __init__( 18 | self, 19 | lib_path: str, 20 | lib_dependency: str = None, 21 | working_directory: str = ".", 22 | timing: bool = False, 23 | ): 24 | super().__init__( 25 | amend_libmf6_path(lib_path), 26 | lib_dependency=lib_dependency, 27 | working_directory=working_directory, 28 | timing=timing, 29 | ) 30 | -------------------------------------------------------------------------------- /modflowapi/util.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from platform import system 3 | 4 | 5 | def amend_libmf6_path(path) -> str: 6 | ext = Path(path).suffix 7 | path = str(path) 8 | os = system().lower() 9 | if os == "windows": 10 | if not ext: 11 | path += ".dll" 12 | path = str(Path(path).absolute()) 13 | elif os == "linux": 14 | if not ext: 15 | path += ".so" 16 | if not path.startswith("./"): 17 | if not path.startswith("/"): 18 | path = "./" + path 19 | elif os == "darwin" and not ext: 20 | path += ".dylib" 21 | return path 22 | -------------------------------------------------------------------------------- /modflowapi/version.py: -------------------------------------------------------------------------------- 1 | # modflowapi version file automatically created using...update_version.py 2 | # created on...February 08, 2024 09:04:23 3 | __version__ = "0.3.0.dev0" 4 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["hatchling"] 3 | build-backend = "hatchling.build" 4 | 5 | [project] 6 | name = "modflowapi" 7 | dynamic = ["version"] 8 | authors = [ 9 | {name = "Joseph D. Hughes", email = "jdhughes@usgs.gov"}, 10 | {name = "Martijn Russcher", email = "Martijn.Russcher@deltares.nl"}, 11 | {name = "Christian D. Langevin", email = "langevin@usgs.gov"}, 12 | {name = "Julian Hofer", email = "Julian.Hofer@deltares.nl"}, 13 | {name = "Joshua D. Larsen", email = "jlarsen@usgs.gov"}, 14 | ] 15 | maintainers = [ 16 | {name = "Joseph D. Hughes", email = "jdhughes@usgs.gov"}, 17 | ] 18 | description = "modflowapi is an extension to the xmipy Python package" 19 | readme = "README.md" 20 | keywords = ["MODFLOW", "groundwater", "hydrogeology", "bmi", "xmi"] 21 | license = {text = "CC0"} 22 | classifiers = [ 23 | "Development Status :: 4 - Beta", 24 | "Intended Audience :: Science/Research", 25 | "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", 26 | "Programming Language :: Python :: 3", 27 | "Programming Language :: Python :: 3 :: Only", 28 | "Programming Language :: Python :: 3.10", 29 | "Programming Language :: Python :: 3.11", 30 | "Programming Language :: Python :: 3.12", 31 | "Programming Language :: Python :: 3.13", 32 | "Topic :: Scientific/Engineering :: Hydrology", 33 | ] 34 | requires-python = ">=3.10" 35 | dependencies = [ 36 | "numpy", 37 | "pandas", 38 | "xmipy", 39 | ] 40 | 41 | [project.optional-dependencies] 42 | dev = ["modflowapi[test,lint]"] 43 | test = [ 44 | "filelock", 45 | "modflow-devtools[dfn] @ git+https://github.com/MODFLOW-ORG/modflow-devtools.git", 46 | "pytest!=8.1.0", 47 | "pytest-order", 48 | "pytest-xdist", 49 | "GitPython", 50 | "pooch", 51 | "scipy", 52 | "pyshp", 53 | "shapely", 54 | "rasterio", 55 | "rasterstats" 56 | ] 57 | lint = [ 58 | "codespell[toml] >=2.2.2", 59 | "ruff", 60 | ] 61 | docs = [ 62 | "modflowapi[test]", 63 | "sphinx", 64 | "sphinx-rtd-theme", 65 | "myst-parser", 66 | "jupyter", 67 | "jupytext", 68 | "nbsphinx", 69 | "ipython", 70 | "flopy", 71 | ] 72 | 73 | [project.urls] 74 | Repository = "https://github.com/MODFLOW-ORG/modflowapi" 75 | Publication = "https://doi.org/10.1016/j.envsoft.2021.105257" 76 | 77 | [tool.hatch.build.targets.sdist] 78 | only-include = ["modflowapi"] 79 | 80 | [tool.hatch.build.targets.wheel] 81 | packages = ["modflowapi"] 82 | 83 | [tool.hatch.version] 84 | path = "modflowapi/version.py" 85 | 86 | [tool.hatch.metadata] 87 | # temporary, until new devtools release 88 | allow-direct-references = true 89 | 90 | [tool.ruff] 91 | line-length = 120 92 | 93 | [tool.ruff.lint] 94 | select = ["F", "E", "I001"] 95 | ignore = [ 96 | "F841" # local variable assigned but never used 97 | ] 98 | 99 | [tool.codespell] 100 | skip = "cliff.toml,*.grb" 101 | ignore-words-list = [ 102 | "delt", 103 | "wel", 104 | "nam", 105 | "ist", 106 | ] 107 | -------------------------------------------------------------------------------- /scripts/update_version.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import textwrap 3 | from datetime import datetime 4 | from os.path import basename 5 | from pathlib import Path 6 | 7 | from filelock import FileLock 8 | from packaging.version import Version 9 | 10 | _project_name = "modflowapi" 11 | _project_root_path = Path(__file__).parent.parent 12 | _version_txt_path = _project_root_path / "version.txt" 13 | _version_py_path = _project_root_path / "modflowapi" / "version.py" 14 | _citation_cff_path = _project_root_path / "CITATION.cff" 15 | 16 | _initial_version = Version("0.0.1") 17 | _current_version = Version(_version_txt_path.read_text().strip()) 18 | 19 | 20 | def log_update(path, version: Version): 21 | print(f"Updated {path} with version {version}") 22 | 23 | 24 | def update_version_txt(version: Version): 25 | with open(_version_txt_path, "w") as f: 26 | f.write(str(version)) 27 | log_update(_version_txt_path, version) 28 | 29 | 30 | def update_version_py(timestamp: datetime, version: Version): 31 | with open(_version_py_path, "w") as f: 32 | f.write(f"# {_project_name} version file automatically created using...{basename(__file__)}\n") 33 | f.write(f"# created on...{timestamp.strftime('%B %d, %Y %H:%M:%S')}\n") 34 | f.write(f'__version__ = "{version}"\n') 35 | log_update(_version_py_path, version) 36 | 37 | 38 | def update_citation_cff(version: Version): 39 | lines = open(_citation_cff_path, "r").readlines() 40 | with open(_citation_cff_path, "w") as f: 41 | for line in lines: 42 | if line.startswith("version:"): 43 | line = f"version: {version}\n" 44 | f.write(line) 45 | log_update(_citation_cff_path, version) 46 | 47 | 48 | def update_version(timestamp: datetime = datetime.now(), version: Version = None): 49 | lock_path = Path(_version_py_path.name + ".lock") 50 | try: 51 | lock = FileLock(lock_path) 52 | previous = Version(_version_txt_path.read_text().strip()) 53 | version = version if version else Version(previous.major, previous.minor, previous.patch) 54 | 55 | with lock: 56 | update_version_txt(version) 57 | update_version_py(timestamp, version) 58 | update_citation_cff(version) 59 | finally: 60 | try: 61 | lock_path.unlink() 62 | except FileNotFoundError: 63 | pass 64 | 65 | 66 | if __name__ == "__main__": 67 | parser = argparse.ArgumentParser( 68 | prog=f"Update {_project_name} version", 69 | formatter_class=argparse.RawDescriptionHelpFormatter, 70 | epilog=textwrap.dedent( 71 | """\ 72 | Update version information in version.txt in the project root, 73 | as well as several other files in the repository. If --version 74 | is not provided, the version number will not be changed. A file 75 | lock is held to synchronize file access. The version tag must be 76 | standard '..' format for semantic versioning. 77 | """ 78 | ), 79 | ) 80 | parser.add_argument("-v", "--version", required=False, help="Specify the release version") 81 | parser.add_argument( 82 | "-g", 83 | "--get", 84 | required=False, 85 | action="store_true", 86 | help="Get the current version number, no updates (defaults false)", 87 | ) 88 | args = parser.parse_args() 89 | 90 | if args.get: 91 | print(_current_version) 92 | else: 93 | update_version( 94 | timestamp=datetime.now(), 95 | version=(Version(args.version) if args.version else _current_version), 96 | ) 97 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 0.3.0.dev0 --------------------------------------------------------------------------------