From 053c1a39f81dc8ce7b0b7a3b6af62e7dc377d49c Mon Sep 17 00:00:00 2001 From: wpbonelli Date: Wed, 13 Dec 2023 13:57:52 -0500 Subject: [PATCH] docs: remove ipynb files from version control (#128) * only version jupytext-managed scripts, not notebooks * add jupytext section to developer documentation * use flopy CLI to regenerate classes in CI --- .github/workflows/ex-rtd.yml | 5 +- .github/workflows/ex-workflow.yml | 28 +- .gitignore | 3 + DEVELOPER.md | 9 + notebooks/ex-gwf-advtidal.ipynb | 805 ---- notebooks/ex-gwf-bcf2ss.ipynb | 938 ----- notebooks/ex-gwf-bump.ipynb | 903 ---- notebooks/ex-gwf-capture.ipynb | 838 ---- notebooks/ex-gwf-csub-p01.ipynb | 793 ---- notebooks/ex-gwf-csub-p02.ipynb | 1322 ------ notebooks/ex-gwf-csub-p03.ipynb | 2333 ----------- notebooks/ex-gwf-csub-p04.ipynb | 1323 ------ notebooks/ex-gwf-curvilinear-90.ipynb | 945 ----- notebooks/ex-gwf-curvilinear.ipynb | 1150 ----- notebooks/ex-gwf-disvmesh.ipynb | 657 --- notebooks/ex-gwf-drn-p01.ipynb | 1854 -------- notebooks/ex-gwf-fhb.ipynb | 589 --- notebooks/ex-gwf-hani.ipynb | 557 --- notebooks/ex-gwf-lak-p01.ipynb | 1005 ----- notebooks/ex-gwf-lak-p02.ipynb | 1626 ------- notebooks/ex-gwf-lgr.ipynb | 1467 ------- notebooks/ex-gwf-lgrv.ipynb | 1035 ----- notebooks/ex-gwf-maw-p01.ipynb | 885 ---- notebooks/ex-gwf-maw-p02.ipynb | 830 ---- notebooks/ex-gwf-maw-p03.ipynb | 1360 ------ notebooks/ex-gwf-nwt-p02.ipynb | 809 ---- notebooks/ex-gwf-nwt-p03.ipynb | 1014 ----- notebooks/ex-gwf-radial.ipynb | 1539 ------- notebooks/ex-gwf-sagehen.ipynb | 1193 ------ notebooks/ex-gwf-sfr-p01.ipynb | 1769 -------- notebooks/ex-gwf-sfr-p01b.ipynb | 5120 ----------------------- notebooks/ex-gwf-spbc.ipynb | 537 --- notebooks/ex-gwf-twri.ipynb | 878 ---- notebooks/ex-gwf-u1disv.ipynb | 659 --- notebooks/ex-gwf-u1gwfgwf.ipynb | 942 ----- notebooks/ex-gwf-whirl.ipynb | 510 --- notebooks/ex-gwf-zaidel.ipynb | 586 --- notebooks/ex-gwt-gwtgwt-p10.ipynb | 1569 ------- notebooks/ex-gwt-hecht-mendez.ipynb | 1304 ------ notebooks/ex-gwt-henry.ipynb | 618 --- notebooks/ex-gwt-keating.ipynb | 895 ---- notebooks/ex-gwt-moc3d-p01.ipynb | 839 ---- notebooks/ex-gwt-moc3d-p02.ipynb | 601 --- notebooks/ex-gwt-moc3d-p02tg.ipynb | 741 ---- notebooks/ex-gwt-mt3dms-p01.ipynb | 988 ----- notebooks/ex-gwt-mt3dms-p02.ipynb | 964 ----- notebooks/ex-gwt-mt3dms-p03.ipynb | 884 ---- notebooks/ex-gwt-mt3dms-p04.ipynb | 1005 ----- notebooks/ex-gwt-mt3dms-p05.ipynb | 954 ----- notebooks/ex-gwt-mt3dms-p06.ipynb | 921 ---- notebooks/ex-gwt-mt3dms-p07.ipynb | 945 ----- notebooks/ex-gwt-mt3dms-p08.ipynb | 1069 ----- notebooks/ex-gwt-mt3dms-p09.ipynb | 895 ---- notebooks/ex-gwt-mt3dms-p10.ipynb | 1035 ----- notebooks/ex-gwt-mt3dsupp631.ipynb | 617 --- notebooks/ex-gwt-mt3dsupp632.ipynb | 891 ---- notebooks/ex-gwt-mt3dsupp82.ipynb | 715 ---- notebooks/ex-gwt-prudic2004t2.ipynb | 1030 ----- notebooks/ex-gwt-rotate.ipynb | 745 ---- notebooks/ex-gwt-saltlake.ipynb | 653 --- notebooks/ex-gwt-stallman.ipynb | 741 ---- notebooks/ex-gwt-synthetic-valley.ipynb | 1605 ------- notebooks/ex-gwt-uzt-2d.ipynb | 1304 ------ 63 files changed, 20 insertions(+), 63324 deletions(-) delete mode 100644 notebooks/ex-gwf-advtidal.ipynb delete mode 100644 notebooks/ex-gwf-bcf2ss.ipynb delete mode 100644 notebooks/ex-gwf-bump.ipynb delete mode 100644 notebooks/ex-gwf-capture.ipynb delete mode 100644 notebooks/ex-gwf-csub-p01.ipynb delete mode 100644 notebooks/ex-gwf-csub-p02.ipynb delete mode 100644 notebooks/ex-gwf-csub-p03.ipynb delete mode 100644 notebooks/ex-gwf-csub-p04.ipynb delete mode 100644 notebooks/ex-gwf-curvilinear-90.ipynb delete mode 100644 notebooks/ex-gwf-curvilinear.ipynb delete mode 100644 notebooks/ex-gwf-disvmesh.ipynb delete mode 100644 notebooks/ex-gwf-drn-p01.ipynb delete mode 100644 notebooks/ex-gwf-fhb.ipynb delete mode 100644 notebooks/ex-gwf-hani.ipynb delete mode 100644 notebooks/ex-gwf-lak-p01.ipynb delete mode 100644 notebooks/ex-gwf-lak-p02.ipynb delete mode 100644 notebooks/ex-gwf-lgr.ipynb delete mode 100644 notebooks/ex-gwf-lgrv.ipynb delete mode 100644 notebooks/ex-gwf-maw-p01.ipynb delete mode 100644 notebooks/ex-gwf-maw-p02.ipynb delete mode 100644 notebooks/ex-gwf-maw-p03.ipynb delete mode 100644 notebooks/ex-gwf-nwt-p02.ipynb delete mode 100644 notebooks/ex-gwf-nwt-p03.ipynb delete mode 100644 notebooks/ex-gwf-radial.ipynb delete mode 100644 notebooks/ex-gwf-sagehen.ipynb delete mode 100644 notebooks/ex-gwf-sfr-p01.ipynb delete mode 100644 notebooks/ex-gwf-sfr-p01b.ipynb delete mode 100644 notebooks/ex-gwf-spbc.ipynb delete mode 100644 notebooks/ex-gwf-twri.ipynb delete mode 100644 notebooks/ex-gwf-u1disv.ipynb delete mode 100644 notebooks/ex-gwf-u1gwfgwf.ipynb delete mode 100644 notebooks/ex-gwf-whirl.ipynb delete mode 100644 notebooks/ex-gwf-zaidel.ipynb delete mode 100644 notebooks/ex-gwt-gwtgwt-p10.ipynb delete mode 100644 notebooks/ex-gwt-hecht-mendez.ipynb delete mode 100644 notebooks/ex-gwt-henry.ipynb delete mode 100644 notebooks/ex-gwt-keating.ipynb delete mode 100644 notebooks/ex-gwt-moc3d-p01.ipynb delete mode 100644 notebooks/ex-gwt-moc3d-p02.ipynb delete mode 100644 notebooks/ex-gwt-moc3d-p02tg.ipynb delete mode 100644 notebooks/ex-gwt-mt3dms-p01.ipynb delete mode 100644 notebooks/ex-gwt-mt3dms-p02.ipynb delete mode 100644 notebooks/ex-gwt-mt3dms-p03.ipynb delete mode 100644 notebooks/ex-gwt-mt3dms-p04.ipynb delete mode 100644 notebooks/ex-gwt-mt3dms-p05.ipynb delete mode 100644 notebooks/ex-gwt-mt3dms-p06.ipynb delete mode 100644 notebooks/ex-gwt-mt3dms-p07.ipynb delete mode 100644 notebooks/ex-gwt-mt3dms-p08.ipynb delete mode 100644 notebooks/ex-gwt-mt3dms-p09.ipynb delete mode 100644 notebooks/ex-gwt-mt3dms-p10.ipynb delete mode 100644 notebooks/ex-gwt-mt3dsupp631.ipynb delete mode 100644 notebooks/ex-gwt-mt3dsupp632.ipynb delete mode 100644 notebooks/ex-gwt-mt3dsupp82.ipynb delete mode 100644 notebooks/ex-gwt-prudic2004t2.ipynb delete mode 100644 notebooks/ex-gwt-rotate.ipynb delete mode 100644 notebooks/ex-gwt-saltlake.ipynb delete mode 100644 notebooks/ex-gwt-stallman.ipynb delete mode 100644 notebooks/ex-gwt-synthetic-valley.ipynb delete mode 100644 notebooks/ex-gwt-uzt-2d.ipynb diff --git a/.github/workflows/ex-rtd.yml b/.github/workflows/ex-rtd.yml index b7268fd1..3bbe8c04 100644 --- a/.github/workflows/ex-rtd.yml +++ b/.github/workflows/ex-rtd.yml @@ -65,10 +65,7 @@ jobs: working-directory: ${{env.etc-directory}} - name: Update flopy MODFLOW 6 classes - run: | - import flopy - flopy.mf6.utils.generate_classes(branch="develop", backup=False) - shell: python + run: python -m flopy.mf6.utils.generate_classes --ref develop --no-backup - name: Install MODFLOW executables release uses: modflowpy/install-modflow-action@v1 diff --git a/.github/workflows/ex-workflow.yml b/.github/workflows/ex-workflow.yml index a8539ffe..879c3004 100644 --- a/.github/workflows/ex-workflow.yml +++ b/.github/workflows/ex-workflow.yml @@ -37,22 +37,16 @@ jobs: with: python-version: 3.8 - - name: Print python version - run: | - python --version - - name: Install Python packages run: | + python --version python -m pip install --upgrade pip setuptools wheel pip install -r requirements.pip.txt pip install -r requirements.usgs.txt working-directory: ${{env.etc-directory}} - name: Update flopy MODFLOW 6 classes - run: | - import flopy - flopy.mf6.utils.generate_classes(branch="develop", backup=False) - shell: python + run: python -m flopy.mf6.utils.generate_classes --ref develop --no-backup - name: Install MODFLOW executables release uses: modflowpy/install-modflow-action@v1 @@ -63,8 +57,7 @@ jobs: repo: modflow6-nightly-build - name: Run scripts without model runs - run: | - pytest -v -n=auto --durations=0 ci_build_files.py + run: pytest -v -n=auto --durations=0 ci_build_files.py working-directory: ${{env.etc-directory}} - name: zip input files @@ -77,8 +70,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: zip_files - path: | - ./modflow6-examples.zip + path: ./modflow6-examples.zip build: name: current-build @@ -126,10 +118,7 @@ jobs: working-directory: ${{env.etc-directory}} - name: Update flopy MODFLOW 6 classes - run: | - import flopy - flopy.mf6.utils.generate_classes(branch="develop", backup=False) - shell: python + run: python -m flopy.mf6.utils.generate_classes --ref develop --no-backup - name: Install MODFLOW executables release uses: modflowpy/install-modflow-action@v1 @@ -140,8 +129,7 @@ jobs: repo: modflow6-nightly-build - name: Run scripts - run: | - pytest -v -n=auto --durations=0 --run=True ci_build_files.py + run: pytest -v -n=auto --durations=0 --run=True ci_build_files.py working-directory: ${{env.etc-directory}} - name: Run processing script @@ -237,9 +225,7 @@ jobs: path: ./current/ - name: List files in the artifact directory - run: | - pwd - ls -R ./current/ + run: ls -R ./current/ - name: create bodyFile run: | diff --git a/.gitignore b/.gitignore index e1eadd50..a2c705f8 100644 --- a/.gitignore +++ b/.gitignore @@ -181,3 +181,6 @@ temp .doc/_images/ .notebooks/ .nb/ + +# only version control jupytext-managed python scripts/*.py +notebooks/ \ No newline at end of file diff --git a/DEVELOPER.md b/DEVELOPER.md index b931aa27..1ca16ca1 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -14,6 +14,7 @@ This document describes how to set up an environment to use or develop the MODFL - [Running the examples](#running-the-examples) - [Using `jupyter`](#using-jupyter) - [Using `pytest`](#using-pytest) + - [Using `jupytext`](#using-jupytext) - [Contributing examples](#contributing-examples) - [Releasing the examples](#releasing-the-examples) - [Generate notebooks and tables](#generate-notebooks-and-tables) @@ -83,6 +84,14 @@ To run models, use `--run True`. To run in serial instead of parallel, omit `-n auto`. +### Using `jupytext` + +The example scripts can be converted to notebooks with `jupytext`. For instance, from the project root, to generate and execute a notebook in `notebooks/`: + +```shell +jupytext --from py --to ipynb scripts/ex-gwf-twri.py -o notebooks/ex-gwf-twri.ipynb --execute +``` + ## Contributing examples Adding a new example requires adding a new example script in the `scripts/` folder and adding a new LaTeX problem description in the `doc/sections/` folder. Then open a pull request from your fork of the repository. diff --git a/notebooks/ex-gwf-advtidal.ipynb b/notebooks/ex-gwf-advtidal.ipynb deleted file mode 100644 index 3c93a282..00000000 --- a/notebooks/ex-gwf-advtidal.ipynb +++ /dev/null @@ -1,805 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "4411da57", - "metadata": {}, - "source": [ - "## Advgwtidal example\n", - "\n", - "This model represents highlands bordered by a tidal estuary. The model\n", - "has 3 layers representing an upper aquifer, confining bed, and lower aquifer.\n", - "The grid is 15 rows by 10 columns. The length unit is feet and the time unit\n", - "is days. Each cell is 500 ft × 500 ft. The estuary is represented by GHB\n", - "boundaries in column 10. Two rivers cross the area from left to right.\n", - "Recharge is zoned by the use of three Recharge-Package input files\n" - ] - }, - { - "cell_type": "markdown", - "id": "1a75e9d1", - "metadata": {}, - "source": [ - "### Advgwtidal Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e6881cac", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1c7ab014", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from flopy.utils.gridintersect import GridIntersect\n", - "from shapely.geometry import Polygon" - ] - }, - { - "cell_type": "markdown", - "id": "a443a794", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06c49239", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "5d847cd8", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "21c78f8e", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "4fbff411", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c89d5f1", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (4, 4)" - ] - }, - { - "cell_type": "markdown", - "id": "a32c3afa", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7af70771", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "d2061249", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "17c514d1", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-advtidal\"" - ] - }, - { - "cell_type": "markdown", - "id": "18ce5ace", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e034b9e3", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "8c8bf07b", - "metadata": {}, - "source": [ - "Table Advgwtidal Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d1372a50", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 4 # Number of periods\n", - "nlay = 3 # Number of layers\n", - "ncol = 10 # Number of columns\n", - "nrow = 15 # Number of rows\n", - "delr = 500.0 # Column width ($m$)\n", - "delc = 500.0 # Row width ($m$)\n", - "top = 50.0 # Top of the model ($m$)\n", - "botm_str = \"5.0, -10.0, -100.0\" # Layer bottom elevations ($m$)\n", - "strt = 50.0 # Starting head ($m$)\n", - "icelltype_str = \"1, 0, 0\" # Cell conversion type\n", - "k11_str = \"5.0, 0.1, 4.0\" # Horizontal hydraulic conductivity ($m/d$)\n", - "k33_str = \"0.5, 5.0e-3, 0.1\" # Vertical hydraulic conductivity ($m/d$)\n", - "ss = 1.0e-6 # Specific storage ($/m$)\n", - "sy = 0.2 # Specific yield (unitless)" - ] - }, - { - "cell_type": "markdown", - "id": "35f88aba", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation has 1 steady stress period (1 day)\n", - "and 3 transient stress periods (10 days each).\n", - "Each transient stress period has 120 2-hour time steps." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c404006b", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [1.0, 10.0, 10.0, 10.0]\n", - "nstp = [1, 120, 120, 120]\n", - "tsmult = [1.0, 1.0, 1.0, 1.0]\n", - "tdis_ds = list(zip(perlen, nstp, tsmult))" - ] - }, - { - "cell_type": "markdown", - "id": "094ead5b", - "metadata": {}, - "source": [ - "parse parameter strings into tuples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ad82358e", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]\n", - "k11 = [float(value) for value in k11_str.split(\",\")]\n", - "k33 = [float(value) for value in k33_str.split(\",\")]\n", - "icelltype = [int(value) for value in icelltype_str.split(\",\")]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a1e1a771", - "metadata": {}, - "outputs": [], - "source": [ - "# ### Create Advgwtidal Recharge Zones\n", - "#\n", - "# shapely is used to construct recharge zones\n", - "#\n", - "recharge_zone_1 = Polygon(\n", - " shell=[\n", - " (0, 0),\n", - " (3000, 0),\n", - " (3000, 5500),\n", - " (1000, 7500),\n", - " (0, 7500),\n", - " (0, 0),\n", - " ],\n", - ")\n", - "recharge_zone_2 = Polygon(\n", - " shell=[\n", - " (1000, 7500),\n", - " (3000, 5500),\n", - " (5000, 7500),\n", - " (1000, 7500),\n", - " ],\n", - ")\n", - "recharge_zone_3 = Polygon(\n", - " shell=[\n", - " (3000, 0),\n", - " (5000, 0),\n", - " (5000, 7500),\n", - " (3000, 5500),\n", - " (3000, 0),\n", - " ],\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "af624fc7", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "feed9675", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 50\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "59226c48", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 Advgwtidal model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1e02f151", - "metadata": {}, - "outputs": [], - "source": [ - "def get_timeseries(fname, names, interpolation, filename=None):\n", - " tsdata = []\n", - " for row in np.genfromtxt(fname, delimiter=\",\", comments=\"#\"):\n", - " tsdata.append(tuple(row))\n", - " tsdict = {\n", - " \"timeseries\": tsdata,\n", - " \"time_series_namerecord\": names,\n", - " \"interpolation_methodrecord\": interpolation,\n", - " }\n", - " if filename is not None:\n", - " tsdict[\"filename\"] = filename\n", - " return tsdict" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "78ca96c2", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name,\n", - " sim_ws=sim_ws,\n", - " exe_name=\"mf6\",\n", - " verbosity_level=0,\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " cvoptions=\"perched\",\n", - " perched=True,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=1,\n", - " ss=1.0e-6,\n", - " sy=sy,\n", - " steady_state={0: True},\n", - " transient={1: True},\n", - " )\n", - "\n", - " ghb_spd = []\n", - " ghb_spd += [[1, i, 9, \"tides\", 15.0, \"ESTUARY-L2\"] for i in range(nrow)]\n", - " ghb_spd += [[2, i, 9, \"tides\", 1500.0, \"ESTUARY-L3\"] for i in range(nrow)]\n", - " ghb_spd = {0: ghb_spd}\n", - " fname = os.path.join(config.data_ws, sim_name, \"tides.csv\")\n", - " tsdict = get_timeseries(fname, \"tides\", \"linear\")\n", - " ghbobs_dict = {}\n", - " ghbobs_dict[f\"{sim_name}.ghb.obs.csv\"] = [\n", - " (\"ghb_2_6_10\", \"ghb\", (1, 5, 9)),\n", - " (\"ghb_3_6_10\", \"ghb\", (2, 5, 9)),\n", - " (\"estuary2\", \"ghb\", \"ESTUARY-L2\"),\n", - " (\"estuary3\", \"ghb\", \"ESTUARY-L3\"),\n", - " ]\n", - "\n", - " flopy.mf6.ModflowGwfghb(\n", - " gwf,\n", - " stress_period_data=ghb_spd,\n", - " boundnames=True,\n", - " timeseries=tsdict,\n", - " observations=ghbobs_dict,\n", - " pname=\"GHB-TIDAL\",\n", - " )\n", - "\n", - " wel_spd = {}\n", - " wel_spd[1] = [\n", - " [0, 11, 2, -50, \"\"],\n", - " [2, 4, 7, \"well_1_rate\", \"well_1\"],\n", - " [2, 3, 2, \"well_2_rate\", \"well_2\"],\n", - " ]\n", - " wel_spd[2] = [\n", - " [2, 3, 2, \"well_2_rate\", \"well_2\"],\n", - " [2, 4, 7, \"well_1_rate\", \"well_1\"],\n", - " ]\n", - " wel_spd[3] = [\n", - " [2, 4, 7, \"well_1_rate\", \"well_1\"],\n", - " [2, 3, 2, \"well_2_rate\", \"well_2\"],\n", - " [0, 11, 2, -10, \"\"],\n", - " [0, 2, 4, -20, \"\"],\n", - " [0, 13, 5, -40, \"\"],\n", - " ]\n", - " fname = os.path.join(config.data_ws, sim_name, \"wellrates.csv\")\n", - " tsdict = get_timeseries(\n", - " fname,\n", - " [\"well_1_rate\", \"well_2_rate\", \"well_6_rate\"],\n", - " 3 * [\"stepwise\"],\n", - " )\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " stress_period_data=wel_spd,\n", - " boundnames=True,\n", - " timeseries=tsdict,\n", - " pname=\"WEL\",\n", - " )\n", - "\n", - " rivlay = 20 * [0]\n", - " rivrow = [2, 3, 4, 4, 5, 5, 5, 4, 4, 4, 9, 8, 7, 6, 6, 5, 5, 6, 6, 6]\n", - " rivcol = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n", - " rivstg = 10 * [\"river_stage_1\"] + 10 * [\"river_stage_2\"]\n", - " rivcnd = 2 * [1000 + f + 1 for f in range(10)]\n", - " rivrbt = list(np.linspace(35.9, 35.0, 10)) + list(np.linspace(36.9, 36.0, 10))\n", - " rivbnd = (\n", - " 5 * [\"\"]\n", - " + [\"riv1_c6\", \"riv1_c7\"]\n", - " + 3 * [\"\"]\n", - " + 3 * [\"riv2_upper\"]\n", - " + 2 * [\"\"]\n", - " + [\"riv2_c6\", \"riv2_c7\"]\n", - " + 3 * [\"\"]\n", - " )\n", - " riv_spd = list(zip(rivlay, rivrow, rivcol, rivstg, rivcnd, rivrbt, rivbnd))\n", - " fname = os.path.join(config.data_ws, sim_name, \"riverstage.csv\")\n", - " tsdict = get_timeseries(\n", - " fname,\n", - " [\"river_stage_1\", \"river_stage_2\"],\n", - " [\"linear\", \"stepwise\"],\n", - " )\n", - " flopy.mf6.ModflowGwfriv(\n", - " gwf,\n", - " stress_period_data=riv_spd,\n", - " boundnames=True,\n", - " timeseries=tsdict,\n", - " pname=\"RIV\",\n", - " )\n", - "\n", - " for ipak, p in enumerate([recharge_zone_1, recharge_zone_2, recharge_zone_3]):\n", - " ix = GridIntersect(gwf.modelgrid, method=\"vertex\", rtree=True)\n", - " result = ix.intersect(p)\n", - " rch_spd = []\n", - " for i in range(result.shape[0]):\n", - " rch_spd.append(\n", - " [\n", - " 0,\n", - " *result[\"cellids\"][i],\n", - " f\"rch_{ipak + 1}\",\n", - " result[\"areas\"][i] / delr / delc,\n", - " ]\n", - " )\n", - " fname = os.path.join(config.data_ws, sim_name, f\"recharge{ipak + 1}.csv\")\n", - " tsdict = get_timeseries(\n", - " fname,\n", - " [f\"rch_{ipak + 1}\"],\n", - " [\"stepwise\"],\n", - " filename=f\"{sim_name}.rch{ipak + 1}.ts\",\n", - " )\n", - " flopy.mf6.ModflowGwfrch(\n", - " gwf,\n", - " stress_period_data=rch_spd,\n", - " boundnames=True,\n", - " timeseries=tsdict,\n", - " fixed_cell=True,\n", - " print_input=True,\n", - " print_flows=True,\n", - " save_flows=True,\n", - " auxiliary=[\"MULTIPLIER\"],\n", - " auxmultname=\"MULTIPLIER\",\n", - " pname=f\"RCH-ZONE_{ipak + 1}\",\n", - " filename=f\"{sim_name}.rch{ipak + 1}\",\n", - " )\n", - "\n", - " nseg = 3\n", - " etsurf = 50\n", - " etrate = 0.0004\n", - " depth = 10.0\n", - " pxdp = [0.2, 0.5]\n", - " petm = [0.3, 0.1]\n", - " row, col = np.where(np.zeros((nrow, ncol)) == 0)\n", - " cellids = list(zip(nrow * ncol * [0], row, col))\n", - " evt_spd = [\n", - " [k, i, j, etsurf, etrate, depth, *pxdp, *petm] for k, i, j in cellids\n", - " ]\n", - " flopy.mf6.ModflowGwfevt(gwf, nseg=nseg, stress_period_data=evt_spd, pname=\"EVT\")\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - "\n", - " obsdict = {}\n", - " obslist = [[\"h1_13_8\", \"head\", (2, 12, 7)]]\n", - " obsdict[f\"{sim_name}.obs.head.csv\"] = obslist\n", - " obslist = [[\"icf1\", \"flow-ja-face\", (0, 4, 5), (0, 5, 5)]]\n", - " obsdict[f\"{sim_name}.obs.flow.csv\"] = obslist\n", - " obs = flopy.mf6.ModflowUtlobs(gwf, print_input=False, continuous=obsdict)\n", - "\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "e9c75206", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 Advgwtidal model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "59288d78", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "cc09941f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the Advgwtidal model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9d48385e", - "metadata": {}, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=False):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "afb9af4c", - "metadata": {}, - "outputs": [], - "source": [ - "# Function to plot the Advgwtidal model results.\n", - "#\n", - "def plot_grid(sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=(5.5, 8.0))\n", - "\n", - " ax = fig.add_subplot(2, 2, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " pmv.plot_grid()\n", - " pmv.plot_bc(name=\"WEL\", kper=3)\n", - " pmv.plot_bc(name=\"RIV\")\n", - " title = \"Layer 1\"\n", - " letter = chr(ord(\"@\") + 1)\n", - " fs.heading(letter=letter, heading=title, ax=ax)\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - "\n", - " ax = fig.add_subplot(2, 2, 2, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=1)\n", - " pmv.plot_grid()\n", - " pmv.plot_bc(name=\"GHB\")\n", - " title = \"Layer 2\"\n", - " letter = chr(ord(\"@\") + 2)\n", - " fs.heading(letter=letter, heading=title, ax=ax)\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - "\n", - " ax = fig.add_subplot(2, 2, 3, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=2)\n", - " pmv.plot_grid()\n", - " pmv.plot_bc(name=\"GHB\")\n", - " pmv.plot_bc(ftype=\"WEL\", kper=3)\n", - " title = \"Layer 3\"\n", - " letter = chr(ord(\"@\") + 3)\n", - " fs.heading(letter=letter, heading=title, ax=ax)\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - "\n", - " ax = fig.add_subplot(2, 2, 4, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax)\n", - " pmv.plot_grid(linewidth=0)\n", - " for ip, (p, fc) in enumerate(\n", - " [\n", - " (recharge_zone_1, \"r\"),\n", - " (recharge_zone_2, \"b\"),\n", - " (recharge_zone_3, \"g\"),\n", - " ]\n", - " ):\n", - " xs, ys = p.exterior.xy\n", - " ax.fill(\n", - " xs,\n", - " ys,\n", - " alpha=0.25,\n", - " fc=fc,\n", - " ec=\"none\",\n", - " label=f\"Recharge Zone {ip + 1}\",\n", - " )\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - " fs.graph_legend(ax)\n", - " title = \"Recharge zones\"\n", - " letter = chr(ord(\"@\") + 4)\n", - " fs.heading(letter=letter, heading=title, ax=ax)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d2b5a249", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_ts(sim):\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - " obsnames = gwf.obs[1].output.obs_names\n", - " obs_list = [\n", - " gwf.obs[1].output.obs(f=obsnames[0]),\n", - " gwf.obs[1].output.obs(f=obsnames[1]),\n", - " gwf.ghb.output.obs(),\n", - " ]\n", - " ylabel = (\"head (m)\", \"flow ($m^3/d$)\", \"flow ($m^3/d$)\")\n", - " obs_fig = (\"obs-head\", \"obs-flow\", \"ghb-obs\")\n", - " for iplot, obstype in enumerate(obs_list):\n", - " fig = plt.figure(figsize=(6, 3))\n", - " ax = fig.add_subplot()\n", - " tsdata = obstype.data\n", - " for name in tsdata.dtype.names[1:]:\n", - " ax.plot(tsdata[\"totim\"], tsdata[name], label=name)\n", - " ax.set_xlabel(\"time (d)\")\n", - " ax.set_ylabel(ylabel[iplot])\n", - " fs.graph_legend(ax)\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}-{}{}\".format(sim_name, obs_fig[iplot], config.figure_ext),\n", - " )\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4b9b8eda", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " plot_grid(sim)\n", - " plot_ts(sim)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "0c180319", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the Advgwtidal model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a93b3d79", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " sim = build_model()\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b16910d4", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "b4d6a23a", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a9ad4a31", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Advgwtidal Simulation\n", - " #\n", - " # Model grid and simulation results\n", - "\n", - " simulation()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-bcf2ss.ipynb b/notebooks/ex-gwf-bcf2ss.ipynb deleted file mode 100644 index d372def6..00000000 --- a/notebooks/ex-gwf-bcf2ss.ipynb +++ /dev/null @@ -1,938 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "16fb7e43", - "metadata": {}, - "source": [ - "## Original BCF2SS MODFLOW example\n", - "\n", - "This problem is described in McDonald and Harbaugh (1988) and duplicated in\n", - "Harbaugh and McDonald (1996). This problem is also is distributed with\n", - "MODFLOW-2005 (Harbaugh, 2005) and MODFLOW 6 (Langevin and others, 2017).\n" - ] - }, - { - "cell_type": "markdown", - "id": "13f5171f", - "metadata": {}, - "source": [ - "### BCF2SS Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eca817d7", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "59e9cd82", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "08c451a4", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c5f2b91c", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "5bada09d", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a4884517", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "7dd34921", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "296dbbe6", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 6)" - ] - }, - { - "cell_type": "markdown", - "id": "78ed30d4", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c01ab99", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "9a228b59", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "130e3fe2", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-bcf2ss\"" - ] - }, - { - "cell_type": "markdown", - "id": "dd17d973", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b9087412", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "d3d1b07a", - "metadata": {}, - "source": [ - "Load the wetdry array for layer 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "124bc0b4", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "pth = os.path.join(\"..\", \"data\", sim_name, \"wetdry01.txt\")\n", - "wetdry_layer0 = np.loadtxt(\n", - " pth,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "ffce6367", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8190b0d6", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-bcf2ss-p01a\": {\n", - " \"rewet\": True,\n", - " \"wetfct\": 1.0,\n", - " \"iwetit\": 1,\n", - " \"ihdwet\": 0,\n", - " \"linear_acceleration\": \"cg\",\n", - " \"newton\": None,\n", - " },\n", - " \"ex-gwf-bcf2ss-p02a\": {\n", - " \"rewet\": False,\n", - " \"wetfct\": None,\n", - " \"iwetit\": None,\n", - " \"ihdwet\": None,\n", - " \"linear_acceleration\": \"bicgstab\",\n", - " \"newton\": \"NEWTON\",\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "e7ab2455", - "metadata": {}, - "source": [ - "Table BCF2SS Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d6535a33", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 2 # Number of periods\n", - "nlay = 2 # Number of layers\n", - "nrow = 10 # Number of rows\n", - "ncol = 15 # Number of columns\n", - "delr = 500.0 # Column width ($ft$)\n", - "delc = 500.0 # Row width ($ft$)\n", - "top = 150.0 # Top of the model ($ft$)\n", - "botm_str = \"50.0, -50.\" # Layer bottom elevations ($ft$)\n", - "icelltype_str = \"1, 0\" # Cell conversion type\n", - "k11_str = \"10.0, 5.0\" # Horizontal hydraulic conductivity ($ft/d$)\n", - "k33 = 0.1 # Vertical hydraulic conductivity ($ft/d$)\n", - "strt = 0.0 # Starting head ($ft$)\n", - "recharge = 0.004 # Recharge rate ($ft/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "de16a04f", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "92b69dfe", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = (\n", - " (1.0, 1.0, 1),\n", - " (1.0, 1.0, 1),\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "6c5bafa8", - "metadata": {}, - "source": [ - "parse parameter strings into tuples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9f8dc33e", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]\n", - "icelltype = [int(value) for value in icelltype_str.split(\",\")]\n", - "k11 = [float(value) for value in k11_str.split(\",\")]" - ] - }, - { - "cell_type": "markdown", - "id": "87110471", - "metadata": {}, - "source": [ - "### Create BCF2SS Model Boundary Conditions" - ] - }, - { - "cell_type": "markdown", - "id": "407d28cd", - "metadata": {}, - "source": [ - "Well boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bafc19a3", - "metadata": {}, - "outputs": [], - "source": [ - "wel_spd = {\n", - " 1: [\n", - " [1, 2, 3, -35000.0],\n", - " [1, 7, 3, -35000.0],\n", - " ]\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "13efa4f8", - "metadata": {}, - "source": [ - "River boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4806255c", - "metadata": {}, - "outputs": [], - "source": [ - "riv_spd = {0: [[1, i, 14, 0.0, 10000.0, -5] for i in range(nrow)]}" - ] - }, - { - "cell_type": "markdown", - "id": "25900d04", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "181fd2d5", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 100\n", - "hclose = 1e-6\n", - "rclose = 1e-3\n", - "relax = 0.97" - ] - }, - { - "cell_type": "markdown", - "id": "45bc77dd", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 TWRI model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0cf0f84a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(name, rewet, wetfct, iwetit, ihdwet, linear_acceleration, newton):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " linear_acceleration=linear_acceleration,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " relaxation_factor=relax,\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim, modelname=sim_name, save_flows=True, newtonoptions=newton\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " if rewet:\n", - " rewet_record = [\n", - " \"wetfct\",\n", - " wetfct,\n", - " \"iwetit\",\n", - " iwetit,\n", - " \"ihdwet\",\n", - " ihdwet,\n", - " ]\n", - " wetdry = [wetdry_layer0, 0]\n", - " else:\n", - " rewet_record = None\n", - " wetdry = None\n", - "\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " rewet_record=rewet_record,\n", - " wetdry=wetdry,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfriv(gwf, stress_period_data=riv_spd)\n", - " flopy.mf6.ModflowGwfwel(gwf, stress_period_data=wel_spd)\n", - " flopy.mf6.ModflowGwfrcha(gwf, recharge=recharge)\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "f40bc69e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 TWRI model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7a2410cc", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "e655d823", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the TWRI model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "211d0411", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "6d777a84", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the BCF2SS model results with heads in each layer.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f8aae8e7", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_simulated_results(num, gwf, ho, co, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - "\n", - " botm_arr = gwf.dis.botm.array\n", - "\n", - " fig = plt.figure(figsize=(6.8, 6), constrained_layout=False)\n", - " gs = mpl.gridspec.GridSpec(ncols=10, nrows=7, figure=fig, wspace=5)\n", - " plt.axis(\"off\")\n", - "\n", - " ax1 = fig.add_subplot(gs[:3, :5])\n", - " ax2 = fig.add_subplot(gs[:3, 5:], sharey=ax1)\n", - " ax3 = fig.add_subplot(gs[3:6, :5], sharex=ax1)\n", - " ax4 = fig.add_subplot(gs[3:6, 5:], sharex=ax1, sharey=ax1)\n", - " ax5 = fig.add_subplot(gs[6, :])\n", - " axes = [ax1, ax2, ax3, ax4, ax5]\n", - "\n", - " labels = (\"A\", \"B\", \"C\", \"D\")\n", - " aquifer = (\"Upper aquifer\", \"Lower aquifer\")\n", - " cond = (\"natural conditions\", \"pumping conditions\")\n", - " vmin, vmax = -10, 140\n", - " masked_values = [1e30, -1e30]\n", - " levels = [\n", - " np.arange(0, 130, 10),\n", - " (10, 20, 30, 40, 50, 55, 60),\n", - " ]\n", - " plot_number = 0\n", - " for idx, totim in enumerate(\n", - " (\n", - " 1,\n", - " 2,\n", - " )\n", - " ):\n", - " head = ho.get_data(totim=totim)\n", - " head[head < botm_arr] = -1e30\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " co.get_data(text=\"DATA-SPDIS\", kstpkper=(0, totim - 1))[0],\n", - " gwf,\n", - " )\n", - "\n", - " for k in range(nlay):\n", - " ax = axes[plot_number]\n", - " ax.set_aspect(\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=k)\n", - " mm.plot_grid(lw=0.5, color=\"0.5\")\n", - " cm = mm.plot_array(head, masked_values=masked_values, vmin=vmin, vmax=vmax)\n", - " mm.plot_bc(ftype=\"WEL\", kper=totim - 1)\n", - " mm.plot_bc(ftype=\"RIV\", color=\"green\", kper=0)\n", - " mm.plot_vector(qx, qy, normalize=True, color=\"0.75\")\n", - " cn = mm.contour_array(\n", - " head,\n", - " masked_values=masked_values,\n", - " levels=levels[idx],\n", - " colors=\"black\",\n", - " linewidths=0.5,\n", - " )\n", - " plt.clabel(cn, fmt=\"%3.0f\")\n", - " heading = f\"{aquifer[k]} under {cond[totim - 1]}\"\n", - " fs.heading(ax, letter=labels[plot_number], heading=heading)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " plot_number += 1\n", - "\n", - " # set axis labels\n", - " ax1.set_ylabel(\"y-coordinate, in feet\")\n", - " ax3.set_ylabel(\"y-coordinate, in feet\")\n", - " ax3.set_xlabel(\"x-coordinate, in feet\")\n", - " ax4.set_xlabel(\"x-coordinate, in feet\")\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " ax.set_ylim(1, 0)\n", - " ax.set_xlim(-5, 5)\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " # items for legend\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"green\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"River\",\n", - " )\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"red\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"Well\",\n", - " )\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"none\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"Dry cell\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"$\\u2192$\",\n", - " ms=10,\n", - " mfc=\"0.75\",\n", - " mec=\"0.75\",\n", - " label=\"Normalized specific discharge\",\n", - " )\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " lw=0.5,\n", - " color=\"black\",\n", - " label=\"Head, in feet\",\n", - " )\n", - " fs.graph_legend(\n", - " ax,\n", - " ncol=5,\n", - " frameon=False,\n", - " loc=\"upper center\",\n", - " )\n", - "\n", - " cbar = plt.colorbar(cm, ax=ax, shrink=0.5, orientation=\"horizontal\")\n", - " cbar.ax.set_xlabel(\"Head, in feet\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-{num:02d}{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "b94d9e4a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot simulated results for a simulation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "84d5f148", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(silent=True):\n", - " if config.plotModel:\n", - " verbose = not silent\n", - " if silent:\n", - " verbosity_level = 0\n", - " else:\n", - " verbosity_level = 1\n", - "\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - " name = list(parameters.keys())[0]\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level\n", - " )\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj = gwf.output.head()\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " cobj = gwf.output.budget()\n", - "\n", - " # extract heads\n", - " head = hobj.get_data(totim=1)\n", - "\n", - " # plot grid\n", - " fig = plt.figure(figsize=(6.8, 3.5), constrained_layout=True)\n", - " gs = mpl.gridspec.GridSpec(nrows=8, ncols=10, figure=fig, wspace=5)\n", - " plt.axis(\"off\")\n", - "\n", - " ax = fig.add_subplot(gs[:7, 0:7])\n", - " ax.set_aspect(\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwf, ax=ax)\n", - " mm.plot_bc(ftype=\"WEL\", kper=1, plotAll=True)\n", - " mm.plot_bc(ftype=\"RIV\", color=\"green\", plotAll=True)\n", - " mm.plot_grid(lw=0.5, color=\"0.5\")\n", - " ax.set_ylabel(\"y-coordinate, in feet\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " fs.heading(ax, letter=\"A\", heading=\"Map view\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " ax = fig.add_subplot(gs[:5, 7:])\n", - " mm = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 7})\n", - " mm.plot_array(np.ones((nlay, nrow, ncol)), head=head, cmap=\"jet\")\n", - " mm.plot_bc(ftype=\"WEL\", kper=1)\n", - " mm.plot_bc(ftype=\"RIV\", color=\"green\", head=head)\n", - " mm.plot_grid(lw=0.5, color=\"0.5\")\n", - " ax.set_ylabel(\"Elevation, in feet\")\n", - " ax.set_xlabel(\"x-coordinate along model row 8, in feet\")\n", - " fs.heading(ax, letter=\"B\", heading=\"Cross-section view\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # items for legend\n", - " ax = fig.add_subplot(gs[7, :])\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"green\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"River\",\n", - " )\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"red\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"Well\",\n", - " )\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"blue\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"Steady-state water table\",\n", - " )\n", - " fs.graph_legend(\n", - " ax,\n", - " ncol=3,\n", - " frameon=False,\n", - " loc=\"upper center\",\n", - " )\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " # figure with wetdry array\n", - " fig = plt.figure(figsize=(4.76, 3), constrained_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1)\n", - " ax.set_aspect(\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwf, ax=ax)\n", - " wd = mm.plot_array(wetdry_layer0)\n", - " mm.plot_grid(lw=0.5, color=\"0.5\")\n", - " cbar = plt.colorbar(wd, shrink=0.5)\n", - " cbar.ax.set_ylabel(\"WETDRY parameter\")\n", - " ax.set_ylabel(\"y-coordinate, in feet\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-01{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - "\n", - " # plot simulated rewetting results\n", - " plot_simulated_results(2, gwf, hobj, cobj)\n", - "\n", - " # plot simulated newton results\n", - " name = list(parameters.keys())[1]\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level\n", - " )\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj = gwf.output.head()\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " cobj = gwf.output.budget()\n", - "\n", - " # plot the newton results\n", - " plot_simulated_results(3, gwf, hobj, cobj)" - ] - }, - { - "cell_type": "markdown", - "id": "f1828662", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the TWRI model\n", - "\n", - "1. build_model,\n", - "2. write_model, and\n", - "3. run_model\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "afcfa71b", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - "\n", - " sim = build_model(key, **params)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - "\n", - " assert success, f\"could not run...{key}\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cc732bc6", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_and_plot():\n", - " simulation(0, silent=False)\n", - " simulation(1, silent=False)\n", - " plot_results(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "09a8a325", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d52c2346", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### BCF2SS Simulation\n", - " #\n", - " # Node Property Flow Package with rewetting option\n", - "\n", - " simulation(0)\n", - "\n", - " # Newton-Raphson formulation\n", - "\n", - " simulation(1)\n", - "\n", - " # Simulated water levels and normalized specific discharge vectors in the\n", - " # upper and lower aquifers under natural and pumping conditions using (1) the\n", - " # rewetting option in the Node Property Flow (NPF) Package with the\n", - " # Standard Conductance Formulation and (2) the Newton-Raphson formulation.\n", - " # A. Upper aquifer results under natural conditions. B. Lower aquifer results\n", - " # under natural conditions C. Upper aquifer results under pumping conditions.\n", - " # D. Lower aquifer results under pumping conditions\n", - "\n", - " plot_results()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-bump.ipynb b/notebooks/ex-gwf-bump.ipynb deleted file mode 100644 index 796843eb..00000000 --- a/notebooks/ex-gwf-bump.ipynb +++ /dev/null @@ -1,903 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "9509d5d4", - "metadata": {}, - "source": [ - "## Flow diversion example\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "6ba0aa01", - "metadata": {}, - "source": [ - "### Flow diversion Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5a1ed334", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef6bbb56", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "2e48d2de", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5d19658f", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "69f3cdc9", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "77de87bb", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "4a3439a5", - "metadata": {}, - "source": [ - "Set figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fac8bf03", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (4, 5.33)\n", - "masked_values = (1e30, -1e30)" - ] - }, - { - "cell_type": "markdown", - "id": "7f3b8218", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4993a5f1", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "34127847", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c12565e9", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-bump\"" - ] - }, - { - "cell_type": "markdown", - "id": "a2563cd4", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cfc65f93", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "805939a5", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dc5d4c48", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-bump-p01a\": {\n", - " \"newton\": \"newton\",\n", - " },\n", - " \"ex-gwf-bump-p01b\": {\n", - " \"rewet\": True,\n", - " \"wetfct\": 1.0,\n", - " \"iwetit\": 1,\n", - " \"ihdwet\": 0,\n", - " \"wetdry\": 2.0,\n", - " },\n", - " \"ex-gwf-bump-p01c\": {\n", - " \"newton\": \"newton\",\n", - " \"cylindrical\": True,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "2debb9e0", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0b1c8509", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 51 # Number of rows\n", - "ncol = 51 # Number of columns\n", - "xlen = 100.0 # Model length in x-direction ($m$)\n", - "ylen = 100.0 # Model length in y-direction ($m$)\n", - "top = 25.0 # Top of the model ($m$)\n", - "k11 = 1.0 # Horizontal hydraulic conductivity ($m/day$)\n", - "H1 = 7.5 # Constant head in column 1 and starting head ($m$)\n", - "H2 = 2.5 # Constant head in column 51 ($m$)" - ] - }, - { - "cell_type": "markdown", - "id": "b3fe0d86", - "metadata": {}, - "source": [ - "plotting ranges and contour levels" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9707b71c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "vmin, vmax = H2, H1\n", - "bmin, bmax = 0, 10\n", - "vlevels = np.arange(vmin + 0.5, vmax, 1)\n", - "blevels = np.arange(bmin + 2, bmax, 2)\n", - "bcolor = \"black\"\n", - "vcolor = \"black\"" - ] - }, - { - "cell_type": "markdown", - "id": "74281365", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c353dc76", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((1.0, 1, 1.0),)" - ] - }, - { - "cell_type": "markdown", - "id": "1b954fdb", - "metadata": {}, - "source": [ - "Calculate delr, delc, extents, and shape3d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a51781c9", - "metadata": {}, - "outputs": [], - "source": [ - "delr = xlen / float(ncol)\n", - "delc = ylen / float(nrow)\n", - "extents = (0, xlen, 0, ylen)\n", - "shape3d = (nlay, nrow, ncol)" - ] - }, - { - "cell_type": "markdown", - "id": "32c433dd", - "metadata": {}, - "source": [ - "Load the bottom" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "33ed1f58", - "metadata": {}, - "outputs": [], - "source": [ - "fpth = os.path.join(\"..\", \"data\", sim_name, \"bottom.txt\")\n", - "botm = np.loadtxt(fpth).reshape(shape3d)" - ] - }, - { - "cell_type": "markdown", - "id": "1a13d1a3", - "metadata": {}, - "source": [ - "create a cylinder" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "33dd9760", - "metadata": {}, - "outputs": [], - "source": [ - "cylinder = botm.copy()\n", - "cylinder[cylinder < 7.5] = 0.0\n", - "cylinder[cylinder >= 7.5] = 20.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9158f94e", - "metadata": {}, - "outputs": [], - "source": [ - "# Constant head boundary conditions\n", - "chd_spd = [[0, i, 0, H1] for i in range(nrow)]\n", - "chd_spd += [[0, i, ncol - 1, H2] for i in range(nrow)]" - ] - }, - { - "cell_type": "markdown", - "id": "f2850c08", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f7ab402c", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 500\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "6bc0c25e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "75385c76", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(\n", - " name,\n", - " newton=False,\n", - " rewet=False,\n", - " cylindrical=False,\n", - " wetfct=None,\n", - " iwetit=None,\n", - " ihdwet=None,\n", - " wetdry=None,\n", - "):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " if newton:\n", - " linear_acceleration = \"bicgstab\"\n", - " newtonoptions = \"newton under_relaxation\"\n", - " else:\n", - " linear_acceleration = \"cg\"\n", - " newtonoptions = None\n", - "\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"ALL\",\n", - " linear_acceleration=linear_acceleration,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=sim_name,\n", - " newtonoptions=newtonoptions,\n", - " save_flows=True,\n", - " )\n", - " if cylindrical:\n", - " bot = cylinder\n", - " else:\n", - " bot = botm\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=bot,\n", - " )\n", - " if rewet:\n", - " rewet_record = [\n", - " \"wetfct\",\n", - " wetfct,\n", - " \"iwetit\",\n", - " iwetit,\n", - " \"ihdwet\",\n", - " ihdwet,\n", - " ]\n", - " else:\n", - " rewet_record = None\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " rewet_record=rewet_record,\n", - " icelltype=1,\n", - " k=k11,\n", - " wetdry=wetdry,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=H1)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chd_spd)\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "0b7abce6", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write flow diversion model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3a43abd6", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "9f661aef", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0e5c817b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "19a5da66", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to create a figure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c77f6a38", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def create_figure():\n", - " fig = plt.figure(figsize=figure_size, constrained_layout=False)\n", - " gs = mpl.gridspec.GridSpec(ncols=10, nrows=7, figure=fig, wspace=5)\n", - " plt.axis(\"off\")\n", - "\n", - " # create axes\n", - " ax1 = fig.add_subplot(gs[:5, :])\n", - " ax2 = fig.add_subplot(gs[5:, :])\n", - "\n", - " # set limits for map figure\n", - " ax1.set_xlim(extents[:2])\n", - " ax1.set_ylim(extents[2:])\n", - " ax1.set_aspect(\"equal\")\n", - "\n", - " # set limits for legend area\n", - " ax2.set_xlim(0, 1)\n", - " ax2.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax2.axis(\"off\")\n", - " ax2.set_xticks([])\n", - " ax2.set_yticks([])\n", - " ax2.spines[\"top\"].set_color(\"none\")\n", - " ax2.spines[\"bottom\"].set_color(\"none\")\n", - " ax2.spines[\"left\"].set_color(\"none\")\n", - " ax2.spines[\"right\"].set_color(\"none\")\n", - " ax2.patch.set_alpha(0.0)\n", - "\n", - " axes = [ax1, ax2]\n", - "\n", - " return fig, axes" - ] - }, - { - "cell_type": "markdown", - "id": "92f8ae41", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "83999854", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(gwf, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - "\n", - " bot = gwf.dis.botm.array\n", - "\n", - " fig, axes = create_figure()\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " bot_coll = mm.plot_array(bot, vmin=bmin, vmax=bmax)\n", - " mm.plot_bc(\"CHD\", color=\"cyan\")\n", - " cv = mm.contour_array(\n", - " bot,\n", - " levels=blevels,\n", - " linewidths=0.5,\n", - " linestyles=\":\",\n", - " colors=bcolor,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " ax.set_ylabel(\"y-coordinate, in meters\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # legend\n", - " ax = axes[1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"cyan\",\n", - " mec=\"cyan\",\n", - " label=\"Constant Head\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " ls=\":\",\n", - " color=bcolor,\n", - " label=\"Bottom elevation contour, m\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"center\", ncol=2)\n", - "\n", - " cax = plt.axes([0.275, 0.125, 0.45, 0.025])\n", - " cbar = plt.colorbar(\n", - " bot_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " cax=cax,\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Bottom Elevation, $m$\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "ff7d83d4", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "20c822d2", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(idx, sim, silent=True):\n", - " verbose = not silent\n", - " if config.plotModel:\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - " name = list(parameters.keys())[idx]\n", - " sim_ws = os.path.join(ws, name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " bot = gwf.dis.botm.array\n", - "\n", - " if idx == 0:\n", - " plot_grid(gwf, silent=silent)\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj = gwf.output.head()\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " cobj = gwf.output.budget()\n", - "\n", - " # extract heads and specific discharge\n", - " head = hobj.get_data(totim=1.0)\n", - " imask = (head > -1e30) & (head <= bot)\n", - " head[imask] = -1e30 # botm[imask]\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " cobj.get_data(text=\"DATA-SPDIS\", totim=1.0)[0],\n", - " gwf,\n", - " )\n", - "\n", - " # Create figure for simulation\n", - " fig, axes = create_figure()\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " if bot.max() < 20:\n", - " cv = mm.contour_array(\n", - " bot,\n", - " levels=blevels,\n", - " linewidths=0.5,\n", - " linestyles=\":\",\n", - " colors=bcolor,\n", - " zorder=9,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\", zorder=9)\n", - " h_coll = mm.plot_array(\n", - " head, vmin=vmin, vmax=vmax, masked_values=masked_values, zorder=10\n", - " )\n", - " cv = mm.contour_array(\n", - " head,\n", - " masked_values=masked_values,\n", - " levels=vlevels,\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=vcolor,\n", - " zorder=10,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\", zorder=10)\n", - " mm.plot_bc(\"CHD\", color=\"cyan\", zorder=11)\n", - " mm.plot_vector(qx, qy, normalize=True, color=\"0.75\", zorder=11)\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " ax.set_ylabel(\"y-coordinate, in meters\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # create legend\n", - " ax = axes[-1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"cyan\",\n", - " mec=\"cyan\",\n", - " label=\"Constant Head\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"$\\u2192$\",\n", - " ms=10,\n", - " mfc=\"0.75\",\n", - " mec=\"0.75\",\n", - " label=\"Normalized specific discharge\",\n", - " )\n", - " if bot.max() < 20:\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " ls=\":\",\n", - " color=bcolor,\n", - " label=\"Bottom elevation contour, m\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " ls=\"-\",\n", - " color=vcolor,\n", - " label=\"Head contour, m\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"center\", ncol=2)\n", - "\n", - " cax = plt.axes([0.275, 0.125, 0.45, 0.025])\n", - " cbar = plt.colorbar(h_coll, shrink=0.8, orientation=\"horizontal\", cax=cax)\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Head, $m$\", fontsize=9)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-{idx + 1:02d}{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "e56c6da5", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the TWRI model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b04f5a11", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - "\n", - " sim = build_model(key, **params)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(idx, sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1a5d9a84", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "88b9fe01", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " simulation(1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e21176bb", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " simulation(2, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "54aa892d", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6d430a26", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Zaidel Simulation\n", - " #\n", - " # Simulated heads in the flow diversion model with Newton-Raphson.\n", - "\n", - " simulation(0)\n", - "\n", - " # Simulated heads in the flow diversion model with rewetting.\n", - "\n", - " simulation(1)\n", - "\n", - " # Simulated heads in the flow diversion model with Newton-Raphson and\n", - " # cylinderical topography.\n", - "\n", - " simulation(2)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-capture.ipynb b/notebooks/ex-gwf-capture.ipynb deleted file mode 100644 index fb3b306c..00000000 --- a/notebooks/ex-gwf-capture.ipynb +++ /dev/null @@ -1,838 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "419a0d78", - "metadata": {}, - "source": [ - "## Capture fraction analysis\n", - "\n", - "This problem is an example of a capture fraction analysis based on\n", - "Leake and others (2010) using the model developed by Freyberg (1988) and\n", - "the MODFLOW API. The MODFLOW API is used because the capture fraction\n", - "for each cell can be calculated without regenerating the input files.\n", - "The capture fraction perturbation flux is added to the second well (WEL)\n", - "package model.\n" - ] - }, - { - "cell_type": "markdown", - "id": "f54ae1fb", - "metadata": {}, - "source": [ - "### Capture Fraction Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "880123dc", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import pathlib as pl\n", - "import shutil\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "370eab01", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import modflowapi\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "69cfcfde", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f7b3248e", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "d8b91748", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "536fdd8d", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "93ede7a8", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f1855ac0", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 6)" - ] - }, - { - "cell_type": "markdown", - "id": "cbe4c555", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7be67cc9", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "12e8921d", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e2bce434", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-capture\"" - ] - }, - { - "cell_type": "markdown", - "id": "42c43375", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "20d9c2a6", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "8b040b32", - "metadata": {}, - "source": [ - "Load the bottom, hydraulic conductivity, and idomain arrays" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "838bd833", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "bottom = np.loadtxt(\n", - " os.path.join(\"..\", \"data\", sim_name, \"bottom.txt\"),\n", - ")\n", - "k11 = np.loadtxt(\n", - " os.path.join(\"..\", \"data\", sim_name, \"hydraulic_conductivity.txt\"),\n", - ")\n", - "idomain = np.loadtxt(\n", - " os.path.join(\"..\", \"data\", sim_name, \"idomain.txt\"),\n", - " dtype=np.int32,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "1b239e12", - "metadata": {}, - "source": [ - "Table Capture Fraction Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4cfcf54c", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 40 # Number of rows\n", - "ncol = 20 # Number of columns\n", - "delr = 250.0 # Column width ($m$)\n", - "delc = 250.0 # Row width ($m$)\n", - "top = 35.0 # Top of the model ($m$)\n", - "icelltype = 1 # Cell conversion type\n", - "strt = 45.0 # Starting head ($m$)\n", - "recharge = 1.60000000e-09 # Recharge rate ($m/s$)\n", - "cf_q = -1e-3 # Perturbation flux ($m/s$)" - ] - }, - { - "cell_type": "markdown", - "id": "553bb5ba", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "34c1135e", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "tdis_ds = ((1.0, 1.0, 1),)" - ] - }, - { - "cell_type": "markdown", - "id": "98b939a5", - "metadata": {}, - "source": [ - "### Create Capture Fraction Model Boundary Conditions" - ] - }, - { - "cell_type": "markdown", - "id": "17da7d55", - "metadata": {}, - "source": [ - "Well boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fed722b5", - "metadata": {}, - "outputs": [], - "source": [ - "wel_spd = {\n", - " 0: [\n", - " [0, 8, 15, -0.00820000],\n", - " [0, 10, 12, -0.00410000],\n", - " [0, 19, 13, -0.00390000],\n", - " [0, 25, 9, -8.30000000e-04],\n", - " [0, 28, 5, -7.20000000e-04],\n", - " [0, 33, 11, -0.00430000],\n", - " ]\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "f00eaf84", - "metadata": {}, - "source": [ - "Constant head boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fec85bb8", - "metadata": {}, - "outputs": [], - "source": [ - "chd_spd = {\n", - " 0: [\n", - " [0, 39, 5, 16.90000000],\n", - " [0, 39, 6, 16.40000000],\n", - " [0, 39, 7, 16.10000000],\n", - " [0, 39, 8, 15.60000000],\n", - " [0, 39, 9, 15.10000000],\n", - " [0, 39, 10, 14.00000000],\n", - " [0, 39, 11, 13.00000000],\n", - " [0, 39, 12, 12.50000000],\n", - " [0, 39, 13, 12.00000000],\n", - " [0, 39, 14, 11.40000000],\n", - " ]\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "791b2578", - "metadata": {}, - "source": [ - "River boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f4221b5a", - "metadata": {}, - "outputs": [], - "source": [ - "rbot = np.linspace(20.0, 10.25, num=nrow)\n", - "rstage = np.linspace(20.1, 11.25, num=nrow)\n", - "riv_spd = []\n", - "for idx, (s, b) in enumerate(zip(rstage, rbot)):\n", - " riv_spd.append([0, idx, 14, s, 0.05, b])\n", - "riv_spd = {0: riv_spd}" - ] - }, - { - "cell_type": "markdown", - "id": "097eed06", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4dc81f27", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 100\n", - "ninner = 25\n", - "hclose = 1e-9\n", - "rclose = 1e-3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "25d1d076", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "# Create mapping array for the capture zone analysis\n", - "imap = idomain.copy()\n", - "for _k, i, j, _h in chd_spd[0]:\n", - " imap[i, j] = 0" - ] - }, - { - "cell_type": "markdown", - "id": "3979af47", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 Capture Zone model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "578daa1d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name,\n", - " sim_ws=sim_ws,\n", - " exe_name=\"mf6\",\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose * 10.0,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=sim_name,\n", - " newtonoptions=\"NEWTON UNDER_RELAXATION\",\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=bottom,\n", - " idomain=idomain,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfriv(gwf, stress_period_data=riv_spd, pname=\"RIV-1\")\n", - " flopy.mf6.ModflowGwfwel(gwf, stress_period_data=wel_spd, pname=\"WEL-1\")\n", - " flopy.mf6.ModflowGwfrcha(gwf, recharge=recharge)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chd_spd)\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " maxbound=1,\n", - " pname=\"CF-1\",\n", - " filename=f\"{sim_name}.cf.wel\",\n", - " )\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " printrecord=[\n", - " (\"BUDGET\", \"ALL\"),\n", - " ],\n", - " )\n", - " return sim\n", - " else:\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "69f2225d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 Capture Fraction model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d01c239b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "ce339c69", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to solve the system of equations to convergence" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "66df034b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def capture_fraction_iteration(mobj, q, inode=None):\n", - " mobj.initialize()\n", - " # time loop\n", - " current_time = mobj.get_current_time()\n", - " end_time = mobj.get_end_time()\n", - " if inode is not None:\n", - " update_wel_pak(mobj, inode, q)\n", - " while current_time < end_time:\n", - " mobj.update()\n", - " current_time = mobj.get_current_time()\n", - " qriv = get_streamflow(mobj)\n", - " mobj.finalize()\n", - " return qriv" - ] - }, - { - "cell_type": "markdown", - "id": "cb7eee56", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to update the Capture Fraction Package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "017cfe4e", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def update_wel_pak(mobj, inode, q):\n", - " # set nodelist to inode\n", - " tag = mobj.get_var_address(\"NODELIST\", sim_name, \"CF-1\")\n", - " nodelist = mobj.get_value(tag)\n", - " nodelist[0] = inode + 1 # convert from zero-based to one-based node number\n", - " mobj.set_value(tag, nodelist)\n", - " # set nbound to 1\n", - " tag = mobj.get_var_address(\"NBOUND\", sim_name, \"CF-1\")\n", - " nbound = mobj.get_value(tag)\n", - " nbound[0] = 1\n", - " mobj.set_value(tag, nbound)\n", - " # set bound to q\n", - " tag = mobj.get_var_address(\"BOUND\", sim_name, \"CF-1\")\n", - " bound = mobj.get_value(tag)\n", - " bound[:, 0] = q\n", - " mobj.set_value(tag, bound)" - ] - }, - { - "cell_type": "markdown", - "id": "0129157c", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to get the streamflow from memory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bb3436ab", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def get_streamflow(mobj):\n", - " tag = mobj.get_var_address(\"SIMVALS\", sim_name, \"RIV-1\")\n", - " return mobj.get_value(tag).sum()" - ] - }, - { - "cell_type": "markdown", - "id": "8eef2f92", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the Capture Fraction model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d1e2b6f7", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model():\n", - " success = True\n", - " if config.runModel:\n", - " libmf6_path = (\n", - " pl.Path(shutil.which(\"mf6\")).parent / f\"libmf6{config.soext}\"\n", - " )\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " mf6 = modflowapi.ModflowApi(libmf6_path, working_directory=sim_ws)\n", - " qbase = capture_fraction_iteration(mf6, cf_q)\n", - "\n", - " # create capture fraction array\n", - " capture = np.zeros((nrow, ncol), dtype=float)\n", - "\n", - " # iterate through each active cell\n", - " ireduced_node = -1\n", - " for irow in range(nrow):\n", - " for jcol in range(ncol):\n", - " # skip inactive cells\n", - " if imap[irow, jcol] < 1:\n", - " continue\n", - "\n", - " # increment reduced node number\n", - " ireduced_node += 1\n", - "\n", - " # calculate the perturbed river flow\n", - " qriv = capture_fraction_iteration(mf6, cf_q, inode=ireduced_node)\n", - "\n", - " # add the value to the capture array\n", - " capture[irow, jcol] = (qriv - qbase) / abs(cf_q)\n", - "\n", - " # save the capture fraction array\n", - " fpth = os.path.join(sim_ws, \"capture.npz\")\n", - " np.savez_compressed(fpth, capture=capture)\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "dbec3ec5", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the Capture Fraction model results with heads in each layer.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7708f454", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(silent=True):\n", - " if config.plotModel:\n", - " verbose = not silent\n", - " if silent:\n", - " verbosity_level = 0\n", - " else:\n", - " verbosity_level = 1\n", - "\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level\n", - " )\n", - " gwf = sim.get_model(sim_name)\n", - " wel = gwf.get_package(\"WEL-1\")\n", - "\n", - " # load the capture fraction data\n", - " fpth = os.path.join(sim_ws, \"capture.npz\")\n", - " capture = np.load(fpth)[\"capture\"]\n", - "\n", - " # plot grid\n", - " fig = plt.figure(figsize=(4, 3.75), constrained_layout=True)\n", - " gs = mpl.gridspec.GridSpec(\n", - " 2,\n", - " 2,\n", - " figure=fig,\n", - " width_ratios=(4, 1),\n", - " height_ratios=(1, 6),\n", - " )\n", - "\n", - " ax = fig.add_subplot(gs[:, 0])\n", - " ax.set_aspect(\"equal\")\n", - "\n", - " mm = flopy.plot.PlotMapView(model=gwf, ax=ax)\n", - " cf = mm.plot_array(capture, vmin=0, vmax=1)\n", - " mm.plot_grid(lw=0.5, color=\"0.5\")\n", - " mm.plot_bc(package=wel)\n", - " ax.axvline(x=14.5 * delc, lw=1.25, color=\"cyan\")\n", - " mm.plot_bc(\"CHD\", color=\"green\")\n", - " mm.plot_ibound()\n", - " ax.set_ylabel(\"y-coordinate, in feet\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " ax = fig.add_subplot(gs[0, 1])\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - " cbar = plt.colorbar(cf, ax=ax, orientation=\"horizontal\")\n", - " cbar.ax.set_xlabel(\"Streamflow capture fraction\")\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"green\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"Constant head\",\n", - " )\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " color=\"cyan\",\n", - " lw=1.25,\n", - " label=\"River\",\n", - " )\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"red\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"Well\",\n", - " )\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"black\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"Inactive cell\",\n", - " )\n", - " fs.graph_legend(\n", - " ax,\n", - " ncol=1,\n", - " frameon=False,\n", - " loc=\"upper center\",\n", - " )\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-01{config.figure_ext}\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "082b2905", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the Streamflow Capture model\n", - "\n", - "1. build_model,\n", - "2. write_model, and\n", - "3. run_model\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "63a0e945", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " sim = build_model()\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model()\n", - "\n", - " assert success, f\"could not run...{sim_name}\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "183e81dd", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(silent=False)\n", - " plot_results(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "7b4b6a0e", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "60451192", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Capture Zone Simulation\n", - " #\n", - " # Capture zone examples using the MODFLOW API with the Freyberg (1988) model\n", - "\n", - " simulation()\n", - "\n", - " # Simulated streamflow capture fraction map for the Freyberg (1988) groundwater\n", - " # flow model.\n", - "\n", - " plot_results()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-csub-p01.ipynb b/notebooks/ex-gwf-csub-p01.ipynb deleted file mode 100644 index df10721c..00000000 --- a/notebooks/ex-gwf-csub-p01.ipynb +++ /dev/null @@ -1,793 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6eec192f", - "metadata": {}, - "source": [ - "## Jacob (1939) Elastic Aquifer Loading\n", - "\n", - "This problem simulates elastic compaction of aquifer materials in response to the\n", - "loading of an aquifer by a passing train. Water-level responses were simulated for\n", - "an eastbound train leaving the Smithtown Station in Long Island, New York at 13:04\n", - "on April 23, 1937\n" - ] - }, - { - "cell_type": "markdown", - "id": "d6725bdc", - "metadata": {}, - "source": [ - "### Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e1679fd8", - "metadata": {}, - "outputs": [], - "source": [ - "import datetime\n", - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "227ccc18", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "8df9c0ff", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9f1f2134", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "fc0be912", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "757afb2f", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "32ac5d2f", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9ee9a4df", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.8, 4.5)" - ] - }, - { - "cell_type": "markdown", - "id": "6343dfa8", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "94bdca7f", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "b6542ce5", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7a800ade", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-csub-p01\"" - ] - }, - { - "cell_type": "markdown", - "id": "b5418fad", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f8c58e46", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "6ec033c5", - "metadata": {}, - "source": [ - "Simulation starting date and time" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "50ef2669", - "metadata": {}, - "outputs": [], - "source": [ - "dstart = datetime.datetime(1937, 4, 23, 13, 5, 55)" - ] - }, - { - "cell_type": "markdown", - "id": "0009362b", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "93db262a", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 2 # Number of periods\n", - "nlay = 3 # Number of layers\n", - "ncol = 35 # Number of columns\n", - "nrow = 1 # Number of rows\n", - "delr0 = 0.5 # Initial column width ($m$)\n", - "delrmax = 100.0 # Maximum column width\n", - "delc = 100.6 # Row width ($m$)\n", - "top = 0.0 # Top of the model ($ft$)\n", - "botm_str = \"-12.2, -21.3, -30.5\" # Layer bottom elevations ($m$)\n", - "strt = -10.7 # Starting head ($m$)\n", - "icelltype_str = \"1, 0, 0\" # Cell conversion type\n", - "k11_str = \"1.8e-5, 3.5e-10, 3.1e-5\" # Horizontal hydraulic conductivity ($m/s$)\n", - "sy_str = \"0.1, 0.05, 0.25\" # Specific yield (unitless)\n", - "sgm = 1.7 # Specific gravity of moist soils (unitless)\n", - "sgs = 2.0 # Specific gravity of saturated soils (unitless)\n", - "cg_ske_str = \"3.3e-5, 6.6e-4, 4.5e-7\" # Coarse grained elastic storativity (1/$m$)\n", - "cg_theta_str = \"0.25, 0.50, 0.30\" # Coarse-grained porosity (unitless)" - ] - }, - { - "cell_type": "markdown", - "id": "09b466fd", - "metadata": {}, - "source": [ - "Create delr from delr0 and delrmac" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "315588e1", - "metadata": {}, - "outputs": [], - "source": [ - "delr = np.ones(ncol, dtype=float) * 0.5\n", - "xmax = delr[0]\n", - "for idx in range(1, ncol):\n", - " dx = min(delr[idx - 1] * 1.2, 100.0)\n", - " xmax += dx\n", - " delr[idx] = dx" - ] - }, - { - "cell_type": "markdown", - "id": "36bc6684", - "metadata": {}, - "source": [ - "Location of the observation well" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "28d1e5cd", - "metadata": {}, - "outputs": [], - "source": [ - "locw201 = 11" - ] - }, - { - "cell_type": "markdown", - "id": "4800de50", - "metadata": {}, - "source": [ - "Load the aquifer load time series" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1cd1e9e7", - "metadata": {}, - "outputs": [], - "source": [ - "pth = os.path.join(\"..\", \"data\", sim_name, \"train_load_193704231304.csv\")\n", - "csv_load = np.genfromtxt(pth, names=True, delimiter=\",\")" - ] - }, - { - "cell_type": "markdown", - "id": "c4b794da", - "metadata": {}, - "source": [ - "Reformat csv data into format for MODFLOW 6 timeseries file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "73924090", - "metadata": {}, - "outputs": [], - "source": [ - "csub_ts = []\n", - "for idx in range(csv_load.shape[0]):\n", - " csub_ts.append((csv_load[\"sim_time\"][idx], csv_load[\"load\"][idx]))" - ] - }, - { - "cell_type": "markdown", - "id": "16672b0f", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "925ac697", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "tdis_ds = (\n", - " (0.5, 1, 1.0),\n", - " (csv_load[\"sim_time\"][-1] - 0.5, csv_load[\"sim_time\"].shape[0] - 2, 1),\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "3959ca2e", - "metadata": {}, - "source": [ - "Simulation starting date and time" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "73c8c420", - "metadata": {}, - "outputs": [], - "source": [ - "dstart = datetime.datetime(1937, 4, 23, 13, 5, 55)" - ] - }, - { - "cell_type": "markdown", - "id": "97bb49ab", - "metadata": {}, - "source": [ - "Create a datetime list" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b6b852bc", - "metadata": {}, - "outputs": [], - "source": [ - "date_list = [dstart + datetime.timedelta(seconds=x) for x in csv_load[\"sim_time\"]]" - ] - }, - { - "cell_type": "markdown", - "id": "884a219c", - "metadata": {}, - "source": [ - "parse parameter strings into tuples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "86f4fd8d", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]\n", - "k11 = [float(value) for value in k11_str.split(\",\")]\n", - "icelltype = [int(value) for value in icelltype_str.split(\",\")]\n", - "sy = [float(value) for value in sy_str.split(\",\")]\n", - "cg_ske = [float(value) for value in cg_ske_str.split(\",\")]\n", - "cg_theta = [float(value) for value in cg_theta_str.split(\",\")]" - ] - }, - { - "cell_type": "markdown", - "id": "d2717955", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "39dd823d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 300\n", - "hclose = 1e-9\n", - "rclose = 1e-6\n", - "linaccel = \"bicgstab\"\n", - "relax = 1.0" - ] - }, - { - "cell_type": "markdown", - "id": "0a74a2b1", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ecbfdf6d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " linear_acceleration=linaccel,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " relaxation_factor=relax,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim, modelname=sim_name, save_flows=True, newtonoptions=\"newton\"\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " obs_recarray = {\"gwf_calib_obs.csv\": [(\"w3_1_1\", \"HEAD\", (2, 0, locw201))]}\n", - " flopy.mf6.ModflowUtlobs(\n", - " gwf, digits=10, print_input=True, continuous=obs_recarray\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=icelltype,\n", - " ss=0.0,\n", - " sy=sy,\n", - " steady_state={0: True},\n", - " transient={1: True},\n", - " )\n", - " csub = flopy.mf6.ModflowGwfcsub(\n", - " gwf,\n", - " print_input=True,\n", - " update_material_properties=True,\n", - " save_flows=True,\n", - " ninterbeds=0,\n", - " maxsig0=1,\n", - " compression_indices=None,\n", - " sgm=sgm,\n", - " sgs=sgs,\n", - " cg_theta=cg_theta,\n", - " cg_ske_cr=cg_ske,\n", - " beta=4.65120000e-10,\n", - " packagedata=None,\n", - " stress_period_data={0: [[(0, 0, 0), \"LOAD\"]]},\n", - " )\n", - " # initialize time series\n", - " csubnam = f\"{sim_name}.load.ts\"\n", - " csub.ts.initialize(\n", - " filename=csubnam,\n", - " timeseries=csub_ts,\n", - " time_series_namerecord=[\"LOAD\"],\n", - " interpolation_methodrecord=[\"linear\"],\n", - " sfacrecord=[\"1.05\"],\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " printrecord=[(\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "ad70f5b2", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f7528098", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "e8c9feb3", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9e775f73", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "aedc2187", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "17bdc05f", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " # plot the grid\n", - " fig = plt.figure(figsize=figure_size)\n", - " gs = mpl.gridspec.GridSpec(10, 1, figure=fig)\n", - "\n", - " idx = 0\n", - " ax = fig.add_subplot(gs[0:3])\n", - " extent = (0, xmax, 0, 100)\n", - " ax.set_ylim(0, 100)\n", - " mm = flopy.plot.PlotMapView(model=gwf, ax=ax, extent=extent)\n", - " mm.plot_grid(color=\"0.5\", lw=0.5, zorder=100)\n", - " ax.set_ylabel(\"y-coordinate,\\nin meters\")\n", - " x, y = gwf.modelgrid.xcellcenters[0, locw201], gwf.modelgrid.ycellcenters[0, 0]\n", - " ax.plot(x, y, marker=\"o\", ms=4, zorder=100, mew=0.5, mec=\"black\")\n", - " ax.annotate(\n", - " \"Well S-201\",\n", - " xy=(x + 5, y),\n", - " xytext=(x + 75, y),\n", - " ha=\"left\",\n", - " va=\"center\",\n", - " zorder=100,\n", - " arrowprops=dict(facecolor=\"black\", shrink=0.05, headwidth=5, width=1.5),\n", - " )\n", - " fs.heading(ax, letter=\"A\", heading=\"Map view\")\n", - " fs.remove_edge_ticks(ax)\n", - " ax.axes.get_xaxis().set_ticks([])\n", - "\n", - " idx += 1\n", - " ax = fig.add_subplot(gs[3:])\n", - " extent = (0, xmax, botm[-1], 0)\n", - " mc = flopy.plot.PlotCrossSection(\n", - " model=gwf, line={\"Row\": 0}, ax=ax, extent=extent\n", - " )\n", - " ax.fill_between([0, delr.sum()], y1=top, y2=botm[0], color=\"cyan\", alpha=0.5)\n", - " ax.fill_between(\n", - " [0, delr.sum()], y1=botm[0], y2=botm[1], color=\"#D2B48C\", alpha=0.5\n", - " )\n", - " ax.fill_between(\n", - " [0, delr.sum()], y1=botm[1], y2=botm[2], color=\"#00BFFF\", alpha=0.5\n", - " )\n", - " mc.plot_grid(color=\"0.5\", lw=0.5, zorder=100)\n", - " ax.plot(\n", - " [0, delr.sum()],\n", - " [-35 / 3.28081, -35 / 3.28081],\n", - " lw=0.75,\n", - " color=\"black\",\n", - " ls=\"dashed\",\n", - " )\n", - " ax.text(\n", - " delr.sum() / 2, -10, \"static water-level\", va=\"bottom\", ha=\"center\", size=9\n", - " )\n", - " ax.set_ylabel(\"Elevation, in meters\")\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " fs.heading(ax, letter=\"B\", heading=\"Cross-section view\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " fig.align_ylabels()\n", - "\n", - " plt.tight_layout(pad=1, h_pad=0.001, rect=(0.005, -0.02, 0.99, 0.99))\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - "\n", - " # get the simulated heads\n", - " sim_obs = gwf.obs.output.obs().data\n", - " h0 = sim_obs[\"W3_1_1\"][0]\n", - " sim_obs[\"W3_1_1\"] -= h0\n", - " sim_date = [dstart + datetime.timedelta(seconds=x) for x in sim_obs[\"totim\"]]\n", - "\n", - " # get the observed head\n", - " pth = os.path.join(\"..\", \"data\", sim_name, \"s201_gw_2sec.csv\")\n", - " dtype = [(\"date\", object), (\"dz_m\", float)]\n", - " obs_head = np.genfromtxt(pth, names=True, delimiter=\",\", dtype=dtype)\n", - " obs_date = []\n", - " for s in obs_head[\"date\"]:\n", - " obs_date.append(\n", - " datetime.datetime.strptime(s.decode(\"utf-8\"), \"%m-%d-%Y %H:%M:%S.%f\")\n", - " )\n", - " t0, t1 = obs_date[0], obs_date[-1]\n", - "\n", - " # plot the results\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " fig = plt.figure(figsize=(6.8, 4.0))\n", - " gs = mpl.gridspec.GridSpec(2, 1, figure=fig)\n", - "\n", - " axe = fig.add_subplot(gs[-1])\n", - "\n", - " idx = 0\n", - " ax = fig.add_subplot(gs[idx], sharex=axe)\n", - " ax.set_ylim(0, 3.25)\n", - " ax.set_yticks(np.arange(0, 3.5, 0.5))\n", - " ax.fill_between(\n", - " date_list, csv_load[\"load\"], y2=0, color=\"cyan\", lw=0.5, alpha=0.5\n", - " )\n", - " ax.set_ylabel(\"Load, in meters\\nof water\")\n", - " plt.setp(ax.get_xticklabels(), visible=False)\n", - " fs.heading(ax, letter=\"A\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " ax = axe\n", - " ax.plot(sim_date, sim_obs[\"W3_1_1\"], color=\"black\", lw=0.75, label=\"Simulated\")\n", - " ax.plot(\n", - " obs_date,\n", - " obs_head[\"dz_m\"],\n", - " color=\"red\",\n", - " lw=0,\n", - " ms=4,\n", - " marker=\".\",\n", - " label=\"Offset S-201\",\n", - " )\n", - " ax.axhline(0, lw=0.5, color=\"0.5\")\n", - " ax.set_ylabel(\"Water level fluctuation,\\nin meters\")\n", - " fs.heading(ax, letter=\"B\")\n", - " leg = fs.graph_legend(ax, loc=\"upper right\", ncol=1)\n", - "\n", - " ax.set_xlabel(\"Time\")\n", - " ax.set_ylim(-0.004, 0.008)\n", - " axe.set_xlim(t0, t1)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " fig.align_ylabels()\n", - "\n", - " plt.tight_layout(pad=1, h_pad=0.001, rect=(0.005, -0.02, 0.99, 0.99))\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-01{config.figure_ext}\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "fccff0ca", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "61fad8cd", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " sim = build_model()\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "73088204", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "e2d0897e", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "363ae389", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Jacob (1939) Elastic Aquifer Loading\n", - " #\n", - "\n", - " simulation()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-csub-p02.ipynb b/notebooks/ex-gwf-csub-p02.ipynb deleted file mode 100644 index a4a491ce..00000000 --- a/notebooks/ex-gwf-csub-p02.ipynb +++ /dev/null @@ -1,1322 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a066f648", - "metadata": {}, - "source": [ - "## Delay interbed drainage\n", - "\n", - "This problem simulates the drainage of a thick interbed caused by a step\n", - "decrease in hydraulic head in the aquifer and is based on MODFLOW-2000 subsidence\n", - "package sample problem 1.\n" - ] - }, - { - "cell_type": "markdown", - "id": "3a0b8995", - "metadata": {}, - "source": [ - "### Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "72c98530", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "acf78154", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "4dea619e", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f5c87f00", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "db54745d", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "73bad8ab", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "5e3ce07c", - "metadata": {}, - "source": [ - "Set figure properties specific to the problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5b914889", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.8, 3.4)\n", - "arrow_props = dict(facecolor=\"black\", arrowstyle=\"-\", lw=0.5)" - ] - }, - { - "cell_type": "markdown", - "id": "c7ec24da", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "79329afe", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "6644a8a6", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "775fb742", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-csub-p02\"" - ] - }, - { - "cell_type": "markdown", - "id": "b4164215", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "478fb767", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-csub-p02a\": {\n", - " \"head_based\": True,\n", - " \"bed_thickness\": (1.0,),\n", - " \"kv\": (2.5e-06,),\n", - " \"ndelaycells\": 19,\n", - " },\n", - " \"ex-gwf-csub-p02b\": {\n", - " \"head_based\": False,\n", - " \"bed_thickness\": (1.0,),\n", - " \"kv\": (2.5e-06,),\n", - " \"ndelaycells\": 19,\n", - " },\n", - " \"ex-gwf-csub-p02c\": {\n", - " \"head_based\": True,\n", - " \"bed_thickness\": (1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0),\n", - " \"kv\": (2.5e-06, 1e-05, 6.25e-05, 0.00025, 0.001, 0.00625, 0.025),\n", - " \"ndelaycells\": 1001,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "72764ed4", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e1ae3401", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "08d31de6", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1313b1ec", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "ncol = 3 # Number of columns\n", - "nrow = 1 # Number of rows\n", - "delr = 1.0 # Column width ($m$)\n", - "delc = 1.0 # Row width ($m$)\n", - "top = 0.0 # Top of the model ($ft$)\n", - "botm = -1000.0 # Layer bottom elevations ($m$)\n", - "strt = 0.0 # Starting head ($m$)\n", - "icelltype = 0 # Cell conversion type\n", - "k11 = 1.0e6 # Horizontal hydraulic conductivity ($m/d$)\n", - "sgm = 1.7 # Specific gravity of moist soils (unitless)\n", - "sgs = 2.0 # Specific gravity of saturated soils (unitless)\n", - "tau0 = 1000.0 # Interbed drainage time constant (unitless)\n", - "cg_theta = 0.2 # Coarse-grained material porosity (unitless)\n", - "ske = 1.0e-5 # Elastic specific storage ($1/m$)\n", - "skv = 1.0e-2 # Inelastic specific storage ($1/m$)\n", - "theta = 0.45 # Interbed porosity (unitless)\n", - "h0 = 1.0 # Initial interbed head ($m$)\n", - "head_offset = 1.0 # Initial preconsolidation head ($m$)" - ] - }, - { - "cell_type": "markdown", - "id": "84247b03", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e9e73165", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((1000.0, 100, 1.05),)" - ] - }, - { - "cell_type": "markdown", - "id": "25f83a4a", - "metadata": {}, - "source": [ - "Constant head cells" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a8fec733", - "metadata": {}, - "outputs": [], - "source": [ - "c6 = []\n", - "for j in range(0, ncol, 2):\n", - " c6.append([0, 0, j, strt])" - ] - }, - { - "cell_type": "markdown", - "id": "3dcb2624", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6b3d7e41", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 1000\n", - "ninner = 300\n", - "hclose = 1e-9\n", - "rclose = 1e-6\n", - "linaccel = \"bicgstab\"\n", - "relax = 0.97" - ] - }, - { - "cell_type": "markdown", - "id": "032e85d6", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e5e2904", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(\n", - " name,\n", - " subdir_name=\".\",\n", - " head_based=True,\n", - " bed_thickness=1.0,\n", - " kv=2e-6,\n", - " ndelaycells=19,\n", - "):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, name)\n", - " if subdir_name is not None:\n", - " sim_ws = os.path.join(sim_ws, subdir_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " linear_acceleration=linaccel,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " relaxation_factor=relax,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim, modelname=name, save_flows=True, newtonoptions=\"newton\"\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " # gwf obs\n", - " flopy.mf6.ModflowUtlobs(\n", - " gwf,\n", - " digits=10,\n", - " print_input=True,\n", - " continuous={\"gwf_obs.csv\": [(\"h1_1_2\", \"HEAD\", (0, 0, 1))]},\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf, iconvert=icelltype, ss=0.0, sy=0, transient={0: True}\n", - " )\n", - " if head_based:\n", - " hb_bool = True\n", - " pc0 = head_offset\n", - " tsgm = None\n", - " tsgs = None\n", - " else:\n", - " hb_bool = None\n", - " pc0 = -head_offset\n", - " tsgm = sgm\n", - " tsgs = sgs\n", - " sub6 = [\n", - " [\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 1,\n", - " \"delay\",\n", - " pc0,\n", - " bed_thickness,\n", - " 1.0,\n", - " skv,\n", - " ske,\n", - " theta,\n", - " kv,\n", - " h0,\n", - " \"ib1\",\n", - " ]\n", - " ]\n", - " csub = flopy.mf6.ModflowGwfcsub(\n", - " gwf,\n", - " print_input=True,\n", - " save_flows=True,\n", - " head_based=hb_bool,\n", - " ndelaycells=ndelaycells,\n", - " boundnames=True,\n", - " ninterbeds=1,\n", - " sgm=tsgm,\n", - " sgs=tsgs,\n", - " cg_theta=cg_theta,\n", - " cg_ske_cr=0.0,\n", - " beta=0.0,\n", - " packagedata=sub6,\n", - " )\n", - " opth = f\"{name}.csub.obs\"\n", - " csub_csv = opth + \".csv\"\n", - " obs = [\n", - " (\"tcomp\", \"interbed-compaction\", \"ib1\"),\n", - " (\"sk\", \"sk\", \"ib1\"),\n", - " (\"qtop\", \"delay-flowtop\", (0,)),\n", - " (\"qbot\", \"delay-flowbot\", (0,)),\n", - " ]\n", - " for k in range(ndelaycells):\n", - " tag = f\"H{k + 1:04d}\"\n", - " obs.append((tag, \"delay-head\", (0,), (k,)))\n", - " if not head_based:\n", - " iposm = int(ndelaycells / 2) + 1\n", - " iposb = ndelaycells - 1\n", - " obs += [\n", - " (\"est\", \"delay-estress\", (0,), (0,)),\n", - " (\"esm\", \"delay-estress\", (0,), (iposm,)),\n", - " (\"esb\", \"delay-estress\", (0,), (iposb,)),\n", - " (\"gs\", \"gstress-cell\", (0, 0, 1)),\n", - " (\"es\", \"estress-cell\", (0, 0, 1)),\n", - " ]\n", - " orecarray = {csub_csv: obs}\n", - " csub.obs.initialize(\n", - " filename=opth, digits=10, print_input=True, continuous=orecarray\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data={0: c6})\n", - "\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " printrecord=[(\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "f2e5cd46", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bfbb1480", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "044b9359", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b3b76627", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "0bc7b731", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Analytical solution for plotting" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bafaa2fd", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def analytical_solution(z, t, dh=1.0, b0=1.0, ssk=100.0, vk=0.025, n=100, silent=True):\n", - " v = 0.0\n", - " e = np.exp(1)\n", - " pi = np.pi\n", - " pi2 = np.pi**2\n", - " # calculate infinite sum\n", - " for k in range(n):\n", - " fk = float(k)\n", - " tauk = (0.5 * b0) ** 2.0 * ssk / ((2.0 * fk + 1.0) ** 2.0 * vk)\n", - " ep = ((2.0 * fk + 1.0) ** 2 * pi2 * vk * t) / (4.0 * ssk * (0.5 * b0) ** 2.0)\n", - " rad = (2.0 * fk + 1.0) * pi * z / b0\n", - " v += ((-1.0) ** fk / (2.0 * fk + 1.0)) * (e**-ep) * np.cos(rad)\n", - " if not silent:\n", - " print(f\"{k:5d} {tauk:20g} {rad:20g} {v:20g}\")\n", - " return dh - 4.0 * dh * v / pi" - ] - }, - { - "cell_type": "markdown", - "id": "cb2fb732", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0f4b2959", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(sim, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - " name = sim.name\n", - " gwf = sim.get_model(name)\n", - "\n", - " fig, ax = plt.subplots(figsize=(6.8, 2.0))\n", - " mc = flopy.plot.PlotCrossSection(model=gwf, line={\"Row\": 0}, ax=ax)\n", - "\n", - " ax.fill_between([0, 1], y1=0, y2=botm, color=\"cyan\", alpha=0.5)\n", - " fs.add_text(\n", - " ax=ax,\n", - " text=\"Constant head\",\n", - " x=0.5,\n", - " y=-500.0,\n", - " bold=False,\n", - " italic=False,\n", - " transform=False,\n", - " va=\"center\",\n", - " ha=\"center\",\n", - " fontsize=9,\n", - " )\n", - " ax.fill_between([2, 3], y1=0, y2=botm, color=\"cyan\", alpha=0.5)\n", - " fs.add_text(\n", - " ax=ax,\n", - " text=\"Constant head\",\n", - " x=2.5,\n", - " y=-500.0,\n", - " bold=False,\n", - " italic=False,\n", - " transform=False,\n", - " va=\"center\",\n", - " ha=\"center\",\n", - " fontsize=9,\n", - " )\n", - " ax.fill_between([1, 2], y1=-499.5, y2=-500.5, color=\"brown\", alpha=0.5)\n", - " fs.add_annotation(\n", - " ax=ax,\n", - " text=\"Delay interbed\",\n", - " xy=(1.5, -510.0),\n", - " xytext=(1.6, -300),\n", - " bold=False,\n", - " italic=False,\n", - " fontsize=9,\n", - " ha=\"center\",\n", - " va=\"center\",\n", - " zorder=100,\n", - " arrowprops=arrow_props,\n", - " )\n", - " mc.plot_grid(color=\"0.5\", lw=0.5, zorder=100)\n", - "\n", - " ax.set_xlim(0, 3)\n", - " ax.set_ylabel(\"Elevation, in meters\")\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " plt.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "6f0c9dde", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the head based results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c6e25a07", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_head_based(sim, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - " name = sim.name\n", - "\n", - " # get csub observations\n", - " ws = sim.simulation_data.mfpath.get_sim_path()\n", - " s = flopy.mf6.MFSimulation().load(sim_ws=ws, verbosity_level=0)\n", - " gwf = s.get_model(name)\n", - " cobs = gwf.csub.output.obs().data\n", - "\n", - " # calculate the compaction analytically\n", - " ac = []\n", - " nz = 100\n", - " thick = parameters[name][\"bed_thickness\"][0]\n", - " kv = parameters[name][\"kv\"][0]\n", - " dhalf = thick * 0.5\n", - " az = np.linspace(-dhalf, dhalf, num=nz)\n", - " dz = az[1] - az[0]\n", - " for tt in cobs[\"totim\"]:\n", - " c = 0.0\n", - " for jdx, zz in enumerate(az):\n", - " f = 1.0\n", - " if jdx == 0 or jdx == nz - 1:\n", - " f = 0.5\n", - " h = analytical_solution(zz, tt, ssk=skv, vk=kv, n=200, dh=1.0)\n", - " c += h * skv * f * dz\n", - " ac.append(c)\n", - " ac = np.array(ac)\n", - "\n", - " # calculate normalized simulation time\n", - " tpct = cobs[\"totim\"] * 100 / tau0\n", - "\n", - " # plot the results\n", - " fig = plt.figure(figsize=figure_size)\n", - " gs = mpl.gridspec.GridSpec(1, 2, figure=fig)\n", - "\n", - " idx = 0\n", - " ax = fig.add_subplot(gs[idx])\n", - " ax.plot(\n", - " tpct,\n", - " 100 * ac / skv,\n", - " marker=\".\",\n", - " lw=0,\n", - " ms=3,\n", - " color=\"red\",\n", - " label=\"Analytical\",\n", - " )\n", - " ax.plot(\n", - " tpct,\n", - " 100 * cobs[\"TCOMP\"] / skv,\n", - " label=\"Simulated\",\n", - " color=\"black\",\n", - " lw=1,\n", - " zorder=100,\n", - " )\n", - " leg = fs.graph_legend(ax, loc=\"lower right\")\n", - " ax.set_xticks(np.arange(0, 110, 10))\n", - " ax.set_yticks(np.arange(0, 110, 10))\n", - " ax.set_xlabel(\"Percent of time constant\")\n", - " ax.set_ylabel(\"Compaction, in percent of ultimate value\")\n", - " ax.set_xlim(0, 100)\n", - " ax.set_ylim(0, 100)\n", - " fs.heading(ax, letter=\"A\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " idx += 1\n", - " ax = fig.add_subplot(gs[idx])\n", - " ax.plot(tpct, 100 * (ac - cobs[\"TCOMP\"]) / skv, lw=1, ls=\":\", color=\"black\")\n", - " ax.set_xticks(np.arange(0, 110, 10))\n", - " ax.set_yticks(np.arange(0, 2.2, 0.2))\n", - " ax.set_xlabel(\"Percent of time constant\")\n", - " ax.set_ylabel(\n", - " \"Analytical minus simulated subsidence,\\nin percent of ultimate value\"\n", - " )\n", - " ax.set_xlim(0, 100)\n", - " ax.set_ylim(0, 2)\n", - " fs.heading(ax, letter=\"B\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " plt.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{name}-01{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "15f92764", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_effstress(sim, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - " name = sim.name\n", - "\n", - " # get effective stress csub observations\n", - " gwf = sim.get_model(name)\n", - " cobs = gwf.csub.output.obs().data\n", - "\n", - " # get head-based csub observations\n", - " name0 = name.replace(\"-p02b\", \"-p02a\")\n", - " ws0 = os.path.join(ws, name0)\n", - " sim0 = flopy.mf6.MFSimulation().load(sim_ws=ws0, verbosity_level=0)\n", - " gwf0 = sim0.get_model(name0)\n", - " cobs0 = gwf0.csub.output.obs().data\n", - "\n", - " # calculate normalized simulation time\n", - " tpct = cobs[\"totim\"] * 100 / tau0\n", - "\n", - " # plot the results\n", - " fig = plt.figure(figsize=figure_size)\n", - " gs = mpl.gridspec.GridSpec(1, 2, figure=fig)\n", - "\n", - " idx = 0\n", - " ax = fig.add_subplot(gs[idx])\n", - " ax.plot(\n", - " tpct,\n", - " 100 * cobs0[\"TCOMP\"] / skv,\n", - " lw=0,\n", - " marker=\".\",\n", - " ms=3,\n", - " color=\"#238A8DFF\",\n", - " label=\"Head-based\",\n", - " )\n", - " ax.plot(\n", - " tpct,\n", - " 100 * cobs[\"TCOMP\"] / skv,\n", - " lw=0.75,\n", - " label=\"Effective stress-based\",\n", - " color=\"black\",\n", - " zorder=100,\n", - " )\n", - " leg = fs.graph_legend(ax, loc=\"lower right\")\n", - " ax.set_xticks(np.arange(0, 110, 10))\n", - " ax.set_yticks(np.arange(0, 110, 10))\n", - " ax.set_xlabel(\"Percent of time constant\")\n", - " ax.set_ylabel(\"Compaction, in percent of ultimate value\")\n", - " ax.set_xlim(0, 100)\n", - " ax.set_ylim(0, 100)\n", - " fs.heading(ax, letter=\"A\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " idx += 1\n", - " ax = fig.add_subplot(gs[idx])\n", - " ax.plot(\n", - " tpct,\n", - " 100 * (cobs0[\"TCOMP\"] - cobs[\"TCOMP\"]) / skv,\n", - " lw=1,\n", - " ls=\":\",\n", - " color=\"black\",\n", - " )\n", - " ax.set_xticks(np.arange(0, 110, 10))\n", - " ax.set_xlabel(\"Percent of time constant\")\n", - " ax.set_ylabel(\n", - " \"Head-based minus effective stress-based\\nsubsidence, in percent of ultimate value\"\n", - " )\n", - " ax.set_xlim(0, 100)\n", - " fs.heading(ax, letter=\"B\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " plt.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{name}-01{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "f381685e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to get subdirectory names" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cdc2988f", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def get_subdirs(sim):\n", - " name = sim.name\n", - " # get the subdirectory names\n", - " pth = os.path.join(ws, name)\n", - " hb_dirs = [\n", - " name\n", - " for name in sorted(os.listdir(pth))\n", - " if os.path.isdir(os.path.join(pth, name)) and name.startswith(\"hb-\")\n", - " ]\n", - " es_dirs = [\n", - " name\n", - " for name in sorted(os.listdir(pth))\n", - " if os.path.isdir(os.path.join(pth, name)) and name.startswith(\"es-\")\n", - " ]\n", - " return hb_dirs, es_dirs" - ] - }, - { - "cell_type": "markdown", - "id": "afb7b668", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to process interbed heads" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b38ffdb4", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def fill_heads(rec_arr, ndcells):\n", - " arr = np.zeros((rec_arr.shape[0], ndcells), dtype=float)\n", - " for i in range(100):\n", - " for j in range(ndcells):\n", - " name = f\"H{j + 1:04d}\"\n", - " arr[i, j] = rec_arr[name][i]\n", - " return arr" - ] - }, - { - "cell_type": "markdown", - "id": "cb42d54c", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the results for multiple interbed thicknesses" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "24719296", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_comp_q_comparison(sim, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - " name = sim.name\n", - " thicknesses = parameters[name][\"bed_thickness\"]\n", - "\n", - " # get the subdirectory names\n", - " hb_dirs, es_dirs = get_subdirs(sim)\n", - "\n", - " # setup the figure\n", - " fig = plt.figure(figsize=figure_size)\n", - " gs = mpl.gridspec.GridSpec(1, 2, figure=fig)\n", - "\n", - " # set color\n", - " cmap = plt.get_cmap(\"viridis\")\n", - " cNorm = mpl.colors.Normalize(vmin=0, vmax=6)\n", - " scalarMap = mpl.cm.ScalarMappable(norm=cNorm, cmap=cmap)\n", - "\n", - " axes = []\n", - " for idx in range(2):\n", - " ax = fig.add_subplot(gs[idx])\n", - " if idx == 0:\n", - " ax.set_yticks(np.arange(-0.40, 0.1, 0.05))\n", - " ax.set_ylim(-0.40, 0)\n", - " ax.set_xlim(0, 100)\n", - " ylabel = (\n", - " \"Head-based minus effective stress-based\\nsubsidence, \"\n", - " + \"in percent of ultimate value\"\n", - " )\n", - " else:\n", - " ax.set_ylim(0, 8)\n", - " ax.set_xlim(0, 100)\n", - " ylabel = (\n", - " \"Top minus bottom interbed effective stress-based\\ndrainage \"\n", - " + \"rate, in percent of head-based drainage rate\"\n", - " )\n", - " ax.set_xlabel(\"Percent of time constant\")\n", - " ax.set_ylabel(ylabel)\n", - " fs.heading(ax, letter=chr(ord(\"A\") + idx))\n", - " axes.append(ax)\n", - "\n", - " for idx, (hb_dir, es_dir) in enumerate(zip(hb_dirs, es_dirs)):\n", - " sim_ws = os.path.join(ws, name, hb_dir)\n", - " s = flopy.mf6.MFSimulation().load(sim_ws=sim_ws, verbosity_level=0)\n", - " g = s.get_model(name)\n", - " hb_obs = g.csub.output.obs().data\n", - "\n", - " ws0 = os.path.join(ws, name, es_dir)\n", - " s0 = flopy.mf6.MFSimulation().load(sim_ws=ws0, verbosity_level=0)\n", - " g0 = s0.get_model(name)\n", - " es_obs = g0.csub.output.obs().data\n", - "\n", - " # calculate normalized simulation time\n", - " tpct = hb_obs[\"totim\"] * 100 / tau0\n", - "\n", - " thickness = thicknesses[idx]\n", - " if idx == 0:\n", - " color = \"black\"\n", - " else:\n", - " color = scalarMap.to_rgba(idx - 1)\n", - " label = f\"Thickness = {int(thickness):>3d} m\"\n", - "\n", - " v = 100.0 * (hb_obs[\"TCOMP\"] - es_obs[\"TCOMP\"]) / (skv * thickness)\n", - " ax = axes[0]\n", - " ax.plot(tpct, v, color=color, lw=0.75, label=label)\n", - "\n", - " denom = hb_obs[\"QTOP\"] + hb_obs[\"QBOT\"]\n", - " v = 100 * (es_obs[\"QTOP\"] - es_obs[\"QBOT\"]) / denom\n", - " ax = axes[1]\n", - " ax.plot(tpct, v, color=color, lw=0.75, label=label)\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " leg = fs.graph_legend(ax, loc=\"upper right\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{name}-01{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "19a50278", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the interbed head results for multiple interbed thicknesses" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4e532551", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_head_comparison(sim, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - " name = sim.name\n", - " ndcells = parameters[name][\"ndelaycells\"]\n", - " thicknesses = parameters[name][\"bed_thickness\"]\n", - "\n", - " # get the subdirectory names\n", - " hb_dirs, es_dirs = get_subdirs(sim)\n", - "\n", - " # setup the figure\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.subplots_adjust(left=0.06, right=0.95, top=0.95, bottom=0.15, wspace=0.1)\n", - " gs = mpl.gridspec.GridSpec(1, 6, figure=fig)\n", - " z = np.linspace(0, 1, ndcells)\n", - " yticks = np.arange(0, 1.1, 0.1)\n", - "\n", - " # set color\n", - " cmap = plt.get_cmap(\"viridis\")\n", - " cNorm = mpl.colors.Normalize(vmin=0, vmax=6)\n", - " scalarMap = mpl.cm.ScalarMappable(norm=cNorm, cmap=cmap)\n", - "\n", - " # percentages to evaluate\n", - " pct_vals = (\n", - " 1,\n", - " 5,\n", - " 10,\n", - " 50,\n", - " 100,\n", - " )\n", - "\n", - " axes = []\n", - " for idx in range(6):\n", - " ax = fig.add_subplot(gs[idx])\n", - " ax.set_ylim(1, 0)\n", - " ax.set_xlim(-5, 5)\n", - " if idx < 5:\n", - " fs.heading(ax, letter=chr(ord(\"A\") + idx))\n", - " ax.set_yticks(yticks)\n", - " fs.remove_edge_ticks(ax)\n", - " text = r\"$\\frac{t}{\\tau_0}$ = \" + \"{}\".format(pct_vals[idx] / 100.0)\n", - " ax.text(\n", - " 0.25,\n", - " 0.01,\n", - " text,\n", - " ha=\"center\",\n", - " va=\"bottom\",\n", - " transform=ax.transAxes,\n", - " fontsize=8,\n", - " )\n", - " else:\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - "\n", - " if idx == 0:\n", - " ax.set_ylabel(\"Interbed position, relative to interbed thickness\")\n", - " else:\n", - " if idx == 2:\n", - " text = (\n", - " \"Difference in head-based and effective stress-based\"\n", - " + \"\\ninterbed heads, in percent of head-based interbed heads\"\n", - " )\n", - " ax.set_xlabel(text)\n", - " ax.set_yticklabels([])\n", - " axes.append(ax)\n", - "\n", - " for idx, (hb_dir, es_dir) in enumerate(zip(hb_dirs, es_dirs)):\n", - " sim_ws = os.path.join(ws, name, hb_dir)\n", - " s = flopy.mf6.MFSimulation().load(sim_ws=sim_ws, verbosity_level=0)\n", - " g = s.get_model(name)\n", - " hb_obs = g.csub.output.obs().data\n", - " hb_arr = fill_heads(hb_obs, ndcells)\n", - "\n", - " ws0 = os.path.join(ws, name, es_dir)\n", - " s0 = flopy.mf6.MFSimulation().load(sim_ws=ws0, verbosity_level=0)\n", - " g0 = s0.get_model(name)\n", - " es_obs = g0.csub.output.obs().data\n", - " es_arr = fill_heads(es_obs, ndcells)\n", - " #\n", - " # pth = os.path.join(ws, name, hb_dir, \"{}.csub.obs.csv\".format(name))\n", - " # hb_obs = np.genfromtxt(pth, names=True, delimiter=\",\")\n", - " # hb_arr = fill_heads(hb_obs, ndcells)\n", - " #\n", - " # pth = os.path.join(ws, name, es_dir, \"{}.csub.obs.csv\".format(name))\n", - " # es_obs = np.genfromtxt(pth, names=True, delimiter=\",\")\n", - " # es_arr = fill_heads(es_obs, ndcells)\n", - "\n", - " # calculate normalized simulation time\n", - " tpct = hb_obs[\"totim\"] * 100 / tau0\n", - "\n", - " # calculate location closest to 1, 5, 10, 50, and 100 percent of time constant\n", - " locs = {}\n", - " for i in pct_vals:\n", - " for jdx, t in enumerate(tpct):\n", - " if t <= i:\n", - " locs[i] = jdx\n", - "\n", - " for jdx, (key, ivalue) in enumerate(locs.items()):\n", - " # add data to the subplot\n", - " ax = axes[jdx]\n", - " if idx == 0:\n", - " color = \"black\"\n", - " else:\n", - " color = scalarMap.to_rgba(idx - 1)\n", - " hhb = hb_arr[ivalue, :]\n", - " hes = es_arr[ivalue, :]\n", - " v = 100.0 * (hhb - hes) / hhb\n", - " ax.plot(v, z, lw=0.75, color=color)\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " ax.set_ylim(1, 0)\n", - " ax.set_xlim(-5, 5)\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - " for ic, b in enumerate(thicknesses):\n", - " if ic == 0:\n", - " color = \"black\"\n", - " else:\n", - " color = scalarMap.to_rgba(ic - 1)\n", - " label = f\"Thickness = {int(b):>3d} m\"\n", - " ax.plot([-1, -1], [-1, -1], lw=0.75, color=color, label=label)\n", - "\n", - " leg = fs.graph_legend(ax, loc=\"center\", bbox_to_anchor=(0.64, 0.5))\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{name}-02{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "5bdaf5a8", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9c739a75", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " name = sim.name\n", - "\n", - " if name.endswith(\"a\"):\n", - " plot_grid(sim, silent=silent)\n", - " plot_head_based(sim, silent=silent)\n", - " elif name.endswith(\"b\"):\n", - " plot_effstress(sim, silent=silent)\n", - " elif name.endswith(\"c\"):\n", - " plot_comp_q_comparison(sim, silent=silent)\n", - " plot_head_comparison(sim, silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "6bc8f5ba", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a54efe3c", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " interbed_thickness = parameters[key][\"bed_thickness\"]\n", - " interbed_kv = parameters[key][\"kv\"]\n", - " params = parameters[key].copy()\n", - "\n", - " success = False\n", - " if len(interbed_thickness) == 1:\n", - " params[\"bed_thickness\"] = interbed_thickness[0]\n", - " params[\"kv\"] = interbed_kv[0]\n", - "\n", - " sim = build_model(key, **params)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " if config.runModel:\n", - " success = run_model(sim, silent=silent)\n", - "\n", - " else:\n", - " for b, kv in zip(interbed_thickness, interbed_kv):\n", - " for head_based in (\n", - " True,\n", - " False,\n", - " ):\n", - " if head_based:\n", - " subdir_name = \"hb-\"\n", - " else:\n", - " subdir_name = \"es-\"\n", - " subdir_name += f\"{int(b):03d}\"\n", - " params[\"head_based\"] = head_based\n", - " params[\"bed_thickness\"] = b\n", - " params[\"kv\"] = kv\n", - "\n", - " sim = build_model(key, subdir_name=subdir_name, **params)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " if config.runModel:\n", - " success = run_model(sim, silent=silent)\n", - "\n", - " if config.plotModel and success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "97051ea0", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e7daf246", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " simulation(1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6fa7a023", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " simulation(2, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "6acdb353", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3eed6ae9", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Delay interbed drainage\n", - " #\n", - " # #### Head based solution\n", - "\n", - " simulation(0)\n", - "\n", - " # #### Effective stress solution\n", - "\n", - " simulation(1)\n", - "\n", - " # #### Head based for multiple interbed thicknesses\n", - "\n", - " simulation(2)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-csub-p03.ipynb b/notebooks/ex-gwf-csub-p03.ipynb deleted file mode 100644 index 806e53e5..00000000 --- a/notebooks/ex-gwf-csub-p03.ipynb +++ /dev/null @@ -1,2333 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d1b7c605", - "metadata": {}, - "source": [ - "## One-dimensional compaction\n", - "\n", - "A one-dimensional MODFLOW 6 model was developed by Sneed (2008) to simulate\n", - "aquitard drainage, compaction and, land subsidence at the Holly site, located at\n", - "the Edwards Air Force base, in response to effective stress changes caused by\n", - "groundwater pumpage in the Antelope Valley in southern California.\n" - ] - }, - { - "cell_type": "markdown", - "id": "dc1b6895", - "metadata": {}, - "source": [ - "### Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2612af1e", - "metadata": {}, - "outputs": [], - "source": [ - "import datetime\n", - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "09fc5690", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "id": "3162a57b", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "161a587c", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "c1ba9ea2", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b0b4191c", - "metadata": {}, - "outputs": [], - "source": [ - "import build_table as bt\n", - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "b6893ecc", - "metadata": {}, - "source": [ - "Set figure properties specific to the problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7f76326a", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.8, 3.4)\n", - "arrow_props = dict(facecolor=\"black\", arrowstyle=\"-\", lw=0.5)" - ] - }, - { - "cell_type": "markdown", - "id": "193aa9b6", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9223f72f", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "12d52e84", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "11c05f2f", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-csub-p03\"" - ] - }, - { - "cell_type": "markdown", - "id": "a00e52b8", - "metadata": {}, - "source": [ - "Load the constant time series" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e841a85b", - "metadata": {}, - "outputs": [], - "source": [ - "pth = os.path.join(\"..\", \"data\", sim_name, \"boundary_heads.csv\")\n", - "csv_head = np.genfromtxt(pth, names=True, delimiter=\",\")" - ] - }, - { - "cell_type": "markdown", - "id": "ff6ed67b", - "metadata": {}, - "source": [ - "Reformat csv data into format for MODFLOW 6 timeseries file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "526a71d5", - "metadata": {}, - "outputs": [], - "source": [ - "chd_ts = []\n", - "for idx in range(csv_head.shape[0]):\n", - " chd_ts.append(\n", - " (\n", - " csv_head[\"time\"][idx],\n", - " csv_head[\"CHD_L01\"][idx],\n", - " csv_head[\"CHD_L06\"][idx],\n", - " csv_head[\"CHD_L13\"][idx],\n", - " )\n", - " )" - ] - }, - { - "cell_type": "markdown", - "id": "eca16e4f", - "metadata": {}, - "source": [ - "Simulation starting date and time" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2d9c0f45", - "metadata": {}, - "outputs": [], - "source": [ - "dstart = datetime.datetime(1907, 1, 1, 0, 0, 0)" - ] - }, - { - "cell_type": "markdown", - "id": "c8e3a446", - "metadata": {}, - "source": [ - "Create a datetime list for the simulation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "78412a4f", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "date_list = [dstart + datetime.timedelta(days=x) for x in csv_head[\"time\"]]" - ] - }, - { - "cell_type": "markdown", - "id": "c1e371f5", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d8252a01", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-csub-p03a\": {\n", - " \"head_based\": True,\n", - " \"cg_ske\": (\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 5.42e-6,\n", - " 0.00e0,\n", - " 5.42e-6,\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 5.42e-6,\n", - " 0.00e0,\n", - " 5.42e-6,\n", - " ),\n", - " \"pcs0\": (\n", - " -4.91,\n", - " -5.33,\n", - " -5.76,\n", - " -6.10,\n", - " -6.10,\n", - " -6.10,\n", - " -6.10,\n", - " -6.10,\n", - " -6.71,\n", - " -6.71,\n", - " -6.10,\n", - " -6.10,\n", - " -6.71,\n", - " ),\n", - " \"ssv\": (\n", - " 6.6955e-4,\n", - " 6.6955e-4,\n", - " 6.6955e-4,\n", - " 1.2753e-4,\n", - " 1.2753e-4,\n", - " 1.2116e-3,\n", - " 1.2116e-3,\n", - " 1.2116e-3,\n", - " 1.2753e-4,\n", - " 1.2753e-4,\n", - " 4.7825e-4,\n", - " 4.7825e-4,\n", - " 4.7825e-4,\n", - " ),\n", - " \"sse\": (\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " 5.4202e-6,\n", - " ),\n", - " },\n", - " \"ex-gwf-csub-p03b\": {\n", - " \"head_based\": False,\n", - " \"cg_ske\": (\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 6.88e-6,\n", - " 0.00e0,\n", - " 6.88e-6,\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 0.00e0,\n", - " 6.88e-6,\n", - " 0.00e0,\n", - " 6.88e-6,\n", - " ),\n", - " \"pcs0\": (\n", - " 47.27,\n", - " 55.93,\n", - " 62.76,\n", - " 75.90,\n", - " 98.15,\n", - " 103.33,\n", - " 111.86,\n", - " 117.35,\n", - " 285.60,\n", - " 339.25,\n", - " 75.90,\n", - " 285.60,\n", - " 339.25,\n", - " ),\n", - " \"ssv\": (\n", - " 1.3542e-3,\n", - " 1.3542e-3,\n", - " 1.3542e-3,\n", - " 2.6912e-4,\n", - " 2.7107e-4,\n", - " 1.9249e-3,\n", - " 1.9249e-3,\n", - " 1.9249e-3,\n", - " 1.4632e-4,\n", - " 2.1655e-4,\n", - " 2.2717e-4,\n", - " 4.8671e-4,\n", - " 1.0170e-3,\n", - " ),\n", - " \"sse\": (\n", - " 8.5697e-6,\n", - " 8.5697e-6,\n", - " 8.5697e-6,\n", - " 1.2559e-5,\n", - " 1.1538e-5,\n", - " 3.4235e-5,\n", - " 3.4235e-5,\n", - " 3.4235e-5,\n", - " 6.3990e-6,\n", - " 9.2419e-6,\n", - " 1.0292e-5,\n", - " 7.5887e-6,\n", - " 6.8638e-6,\n", - " ),\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "61c8ba0a", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c7514804", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "2ef2c940", - "metadata": {}, - "source": [ - "Model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e107e203", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 353\n", - "nlay = 14\n", - "ncol = 1\n", - "nrow = 1\n", - "delr = 1.0\n", - "delc = 1.0\n", - "top = 0.0\n", - "botm = (\n", - " -36.8811,\n", - " -42.3676,\n", - " -50.5973,\n", - " -56.9981,\n", - " -69.7998,\n", - " -70.1046,\n", - " -92.0504,\n", - " -97.2321,\n", - " -105.7666,\n", - " -111.2530,\n", - " -111.5578,\n", - " -278.8945,\n", - " -279.1993,\n", - " -332.5398,\n", - ")\n", - "strt = (\n", - " 0.00,\n", - " 1.57,\n", - " 3.38,\n", - " 5.56,\n", - " 6.77,\n", - " 6.77,\n", - " 6.77,\n", - " 6.77,\n", - " 6.77,\n", - " 6.77,\n", - " 6.77,\n", - " 6.77,\n", - " 5.55,\n", - " 5.55,\n", - ")\n", - "icelltype = 0\n", - "k33 = (\n", - " 9.14e-3,\n", - " 3.66e-6,\n", - " 3.66e-6,\n", - " 3.66e-6,\n", - " 9.14e-3,\n", - " 9.14e-3,\n", - " 9.14e-3,\n", - " 4.57e-6,\n", - " 4.57e-6,\n", - " 4.57e-6,\n", - " 9.14e-3,\n", - " 9.14e-3,\n", - " 9.14e-3,\n", - " 9.14e-3,\n", - ")\n", - "iconvert = (\n", - " 1,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - ")\n", - "sgm = 1.7\n", - "sgs = 2.0\n", - "cg_theta = 0.3\n", - "ib_cellid = (\n", - " (1, 0, 0),\n", - " (2, 0, 0),\n", - " (3, 0, 0),\n", - " (4, 0, 0),\n", - " (6, 0, 0),\n", - " (7, 0, 0),\n", - " (8, 0, 0),\n", - " (9, 0, 0),\n", - " (11, 0, 0),\n", - " (13, 0, 0),\n", - " (4, 0, 0),\n", - " (11, 0, 0),\n", - " (13, 0, 0),\n", - ")\n", - "ib_ctype = (\n", - " \"nodelay\",\n", - " \"nodelay\",\n", - " \"nodelay\",\n", - " \"nodelay\",\n", - " \"nodelay\",\n", - " \"nodelay\",\n", - " \"nodelay\",\n", - " \"nodelay\",\n", - " \"nodelay\",\n", - " \"nodelay\",\n", - " \"delay\",\n", - " \"delay\",\n", - " \"delay\",\n", - ")\n", - "ib_thickness = (\n", - " 5.48649,\n", - " 8.22969,\n", - " 6.4008,\n", - " 2.7432,\n", - " 0.6096,\n", - " 5.1817,\n", - " 8.53449,\n", - " 5.4864,\n", - " 7.6201,\n", - " 0.9144,\n", - " 2.7432,\n", - " 3.0480,\n", - " 2.7432,\n", - ")\n", - "ib_rnb = (\n", - " 1.0,\n", - " 1.0,\n", - " 1.0,\n", - " 1.0,\n", - " 1.0,\n", - " 1.0,\n", - " 1.0,\n", - " 1.0,\n", - " 1.0,\n", - " 1.0,\n", - " 1.92,\n", - " 1.66,\n", - " 2.85,\n", - ")\n", - "ib_theta = 0.30\n", - "ib_kv = (\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 4.57e-6,\n", - " 4.57e-6,\n", - " 4.57e-6,\n", - ")\n", - "ib_head = (\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 999.0,\n", - " 6.77,\n", - " 6.77,\n", - " 5.55,\n", - ")\n", - "ib_name = (\n", - " \"CUNIT\",\n", - " \"CUNIT\",\n", - " \"CUNIT\",\n", - " \"NODELAY\",\n", - " \"NODELAY\",\n", - " \"AQUITARD\",\n", - " \"AQUITARD\",\n", - " \"AQUITARD\",\n", - " \"NODELAY\",\n", - " \"NODELAY\",\n", - " \"DELAY\",\n", - " \"DELAY\",\n", - " \"DELAY\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "81b647ac", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fd05bf63", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = []\n", - "for idx in range(82):\n", - " tdis_ds.append((365.25, 12, 1.0))\n", - "for idx in range(82, nper):\n", - " tdis_ds.append((22.0, 22, 1.0))" - ] - }, - { - "cell_type": "markdown", - "id": "f496b02c", - "metadata": {}, - "source": [ - "Constant head cells" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5cf5cc1d", - "metadata": {}, - "outputs": [], - "source": [ - "c6 = []\n", - "for k, tag in zip(\n", - " (\n", - " 0,\n", - " 5,\n", - " 10,\n", - " 12,\n", - " ),\n", - " (\"upper\", \"middle\", \"middle\", \"lower\"),\n", - "):\n", - " c6.append([k, 0, 0, tag])" - ] - }, - { - "cell_type": "markdown", - "id": "de7f2a9e", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eb97080c", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 200\n", - "ninner = 100\n", - "hclose = 1e-6\n", - "rclose = 1e-3\n", - "linaccel = \"cg\"\n", - "relax = 0.97" - ] - }, - { - "cell_type": "markdown", - "id": "5513c55e", - "metadata": {}, - "source": [ - "Create data for plotting" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5454d5c7", - "metadata": {}, - "outputs": [], - "source": [ - "xticks = (1907, 1917, 1927, 1937, 1947, 1957, 1967, 1977, 1987, 1997, 2007)\n", - "s = (\n", - " \"01-01-1907\",\n", - " \"01-01-1917\",\n", - " \"01-01-1927\",\n", - " \"01-01-1937\",\n", - " \"01-01-1947\",\n", - " \"01-01-1957\",\n", - " \"01-01-1967\",\n", - " \"01-01-1977\",\n", - " \"01-01-1987\",\n", - " \"01-01-1997\",\n", - " \"01-01-2007\",\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b6592d35", - "metadata": {}, - "outputs": [], - "source": [ - "df_xticks = [datetime.datetime.strptime(ss, \"%m-%d-%Y\").date() for ss in s]\n", - "df_xticks1 = [\n", - " datetime.datetime.strptime(f\"{yr:04d}-01-01\", \"%Y-%m-%d\").date()\n", - " for yr in range(1990, 2007)\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a1a6d39a", - "metadata": {}, - "outputs": [], - "source": [ - "pcomp = (\n", - " \"TOTAL\",\n", - " \"AQUITARD\",\n", - " \"DELAY\",\n", - " \"CUNIT\",\n", - " \"NODELAY\",\n", - " \"SKELETAL\",\n", - ")\n", - "clabels = (\n", - " \"Total compaction\",\n", - " \"Thick aquitard compaction\",\n", - " \"Delay interbed compaction\",\n", - " \"Confining unit compaction\",\n", - " \"No-delay interbed compaction\",\n", - " \"Elastic coarse-grained material compaction\",\n", - ")\n", - "llabels = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0eddd672", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "zelevs = [top]\n", - "edges = [(0, 0)]\n", - "for z in botm:\n", - " zelevs.append(z)\n", - " edges.append((-z, -z))" - ] - }, - { - "cell_type": "markdown", - "id": "b7438019", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "556c6cab", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(\n", - " name,\n", - " subdir_name=\".\",\n", - " head_based=True,\n", - " cg_ske=1e-3,\n", - " pcs0=0.0,\n", - " ssv=1e-1,\n", - " sse=1e-3,\n", - "):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, name)\n", - " if subdir_name is not None:\n", - " sim_ws = os.path.join(sim_ws, subdir_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " linear_acceleration=linaccel,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " relaxation_factor=relax,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=name,\n", - " save_flows=True,\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " # gwf obs\n", - " opth = f\"{name}.gwf.obs\"\n", - " cpth = opth + \".csv\"\n", - " obs_array = []\n", - " for k in range(nlay):\n", - " obs_array.append(\n", - " [\n", - " f\"HD{k + 1:02d}\",\n", - " \"HEAD\",\n", - " (k, 0, 0),\n", - " ]\n", - " )\n", - " flopy.mf6.ModflowUtlobs(\n", - " gwf,\n", - " digits=10,\n", - " print_input=True,\n", - " filename=opth,\n", - " continuous={cpth: obs_array},\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k33,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf, iconvert=iconvert, ss=0.0, sy=0, transient={0: True}\n", - " )\n", - " if head_based:\n", - " hb_bool = True\n", - " tsgm = None\n", - " tsgs = None\n", - " else:\n", - " hb_bool = None\n", - " tsgm = sgm\n", - " tsgs = sgs\n", - " sub6 = []\n", - " for idx, cdelay in enumerate(ib_ctype):\n", - " sub6.append(\n", - " [\n", - " idx,\n", - " ib_cellid[idx],\n", - " cdelay,\n", - " pcs0[idx],\n", - " ib_thickness[idx],\n", - " ib_rnb[idx],\n", - " ssv[idx],\n", - " sse[idx],\n", - " ib_theta,\n", - " ib_kv[idx],\n", - " ib_head[idx],\n", - " ib_name[idx],\n", - " ]\n", - " )\n", - " csub = flopy.mf6.ModflowGwfcsub(\n", - " gwf,\n", - " print_input=True,\n", - " save_flows=True,\n", - " head_based=hb_bool,\n", - " specified_initial_interbed_state=True,\n", - " update_material_properties=True,\n", - " ndelaycells=39,\n", - " boundnames=True,\n", - " beta=4.65120000e-10,\n", - " gammaw=9806.65,\n", - " ninterbeds=len(sub6),\n", - " sgm=tsgm,\n", - " sgs=tsgs,\n", - " cg_theta=cg_theta,\n", - " cg_ske_cr=cg_ske,\n", - " packagedata=sub6,\n", - " )\n", - " opth = f\"{name}.csub.obs\"\n", - " csub_csv = opth + \".csv\"\n", - " obs = [\n", - " (\"cunit\", \"interbed-compaction\", \"cunit\"),\n", - " (\"aquitard\", \"interbed-compaction\", \"aquitard\"),\n", - " (\"nodelay\", \"interbed-compaction\", \"nodelay\"),\n", - " (\"delay\", \"interbed-compaction\", \"delay\"),\n", - " (\"es14\", \"estress-cell\", (nlay - 1, 0, 0)),\n", - " ]\n", - " for k in (1, 2, 3, 4, 6, 7, 8, 9, 11, 13):\n", - " tag = f\"tc{k + 1:02d}\"\n", - " obs.append(\n", - " (\n", - " tag,\n", - " \"compaction-cell\",\n", - " (k, 0, 0),\n", - " )\n", - " )\n", - " tag = f\"skc{k + 1:02d}\"\n", - " obs.append(\n", - " (\n", - " tag,\n", - " \"coarse-compaction\",\n", - " (k, 0, 0),\n", - " )\n", - " )\n", - " orecarray = {csub_csv: obs}\n", - " csub.obs.initialize(\n", - " filename=opth, digits=10, print_input=True, continuous=orecarray\n", - " )\n", - "\n", - " chd = flopy.mf6.ModflowGwfchd(gwf, stress_period_data={0: c6})\n", - "\n", - " # initialize chd time series\n", - " csubnam = f\"{sim_name}.head.ts\"\n", - " chd.ts.initialize(\n", - " filename=csubnam,\n", - " timeseries=chd_ts,\n", - " time_series_namerecord=[\n", - " \"upper\",\n", - " \"middle\",\n", - " \"lower\",\n", - " ],\n", - " interpolation_methodrecord=[\n", - " \"linear\",\n", - " \"linear\",\n", - " \"linear\",\n", - " ],\n", - " sfacrecord=[\n", - " \"1.0\",\n", - " \"1.0\",\n", - " \"1.0\",\n", - " ],\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " printrecord=[(\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "d925a8c6", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e3893e9d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "66844fa9", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b1948672", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "b7041b82", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to make summary tables" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2aa2b05c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def export_tables(silent=True):\n", - " if config.plotSave:\n", - " name = list(parameters.keys())[1]\n", - "\n", - " caption = f\"Aquifer properties for example {sim_name}.\"\n", - " headings = (\n", - " \"Layer\",\n", - " \"Thickness\",\n", - " \"Hydraulic conductivity\",\n", - " \"Initial head\",\n", - " )\n", - " fpth = os.path.join(\"..\", \"tables\", f\"{sim_name}-01.tex\")\n", - " dtype = [\n", - " (\"k\", \"U30\"),\n", - " (\"thickness\", \"U30\"),\n", - " (\"k33\", \"U30\"),\n", - " (\"h0\", \"U30\"),\n", - " ]\n", - " arr = np.zeros(nlay, dtype=dtype)\n", - " for k in range(nlay):\n", - " arr[\"k\"][k] = bt.int_format(k + 1)\n", - " arr[\"thickness\"][k] = bt.float_format(zelevs[k] - zelevs[k + 1])\n", - " arr[\"k33\"][k] = bt.exp_format(k33[k])\n", - " arr[\"h0\"][k] = bt.float_format(strt[k])\n", - " if not silent:\n", - " print(f\"creating...'{fpth}'\")\n", - " col_widths = (0.1, 0.15, 0.30, 0.25)\n", - " bt.build_table(caption, fpth, arr, headings=headings, col_widths=col_widths)\n", - "\n", - " caption = f\"Interbed properties for example {sim_name}.\"\n", - " headings = (\n", - " \"Interbed\",\n", - " \"Layer\",\n", - " \"Thickness\",\n", - " \"Initial stress\",\n", - " )\n", - " fpth = os.path.join(\"..\", \"tables\", f\"{sim_name}-02.tex\")\n", - " dtype = [\n", - " (\"ib\", \"U30\"),\n", - " (\"k\", \"U30\"),\n", - " (\"thickness\", \"U30\"),\n", - " (\"pcs0\", \"U30\"),\n", - " ]\n", - " arr = np.zeros(len(ib_ctype), dtype=dtype)\n", - " for idx, ctype in enumerate(ib_ctype):\n", - " arr[\"ib\"][idx] = bt.int_format(idx + 1)\n", - " arr[\"k\"][idx] = bt.int_format(ib_cellid[idx][0] + 1)\n", - " if ctype == \"nodelay\":\n", - " arr[\"thickness\"][idx] = bt.float_format(ib_thickness[idx])\n", - " else:\n", - " b = ib_thickness[idx] * ib_rnb[idx]\n", - " arr[\"thickness\"][idx] = bt.float_format(b)\n", - " arr[\"pcs0\"][idx] = bt.float_format(parameters[name][\"pcs0\"][idx])\n", - " if not silent:\n", - " print(f\"creating...'{fpth}'\")\n", - " bt.build_table(caption, fpth, arr, headings=headings)\n", - "\n", - " caption = f\"Aquifer storage properties for example {sim_name}.\"\n", - " headings = (\n", - " \"Layer\",\n", - " \"Specific Storage\",\n", - " )\n", - " fpth = os.path.join(\"..\", \"tables\", f\"{sim_name}-03.tex\")\n", - " dtype = [(\"k\", \"U30\"), (\"ss\", \"U30\")]\n", - " arr = np.zeros(4, dtype=dtype)\n", - " for idx, k in enumerate((4, 6, 11, 13)):\n", - " arr[\"k\"][idx] = bt.int_format(k + 1)\n", - " arr[\"ss\"][idx] = bt.exp_format(parameters[name][\"cg_ske\"][k])\n", - " if not silent:\n", - " print(f\"creating...'{fpth}'\")\n", - " col_widths = (0.1, 0.25)\n", - " bt.build_table(caption, fpth, arr, headings=headings, col_widths=col_widths)\n", - "\n", - " caption = \"Interbed storage properties for example {}.\".format(sim_name)\n", - " headings = (\n", - " \"Interbed\",\n", - " \"Layer\",\n", - " \"Inelastic \\\\newline Specific \\\\newline Storage\",\n", - " \"Elastic \\\\newline Specific \\\\newline Storage\",\n", - " )\n", - " fpth = os.path.join(\"..\", \"tables\", f\"{sim_name}-04.tex\")\n", - " dtype = [\n", - " (\"ib\", \"U30\"),\n", - " (\"k\", \"U30\"),\n", - " (\"ssv\", \"U30\"),\n", - " (\"sse\", \"U30\"),\n", - " ]\n", - " arr = np.zeros(len(ib_ctype), dtype=dtype)\n", - " for idx, ctype in enumerate(ib_ctype):\n", - " arr[\"ib\"][idx] = bt.int_format(idx + 1)\n", - " arr[\"k\"][idx] = bt.int_format(ib_cellid[idx][0] + 1)\n", - " arr[\"ssv\"][idx] = bt.exp_format(parameters[name][\"ssv\"][idx])\n", - " arr[\"sse\"][idx] = bt.exp_format(parameters[name][\"sse\"][idx])\n", - " if not silent:\n", - " print(f\"creating...'{fpth}'\")\n", - " col_widths = (0.2, 0.2, 0.2, 0.2)\n", - " bt.build_table(\n", - " caption,\n", - " fpth,\n", - " arr,\n", - " headings=headings,\n", - " col_widths=col_widths,\n", - " )\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "8bb4a767", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to get observed data as a pandas dataframe" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1c8cec88", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def get_obs_dataframe(file_name=\"008N010W01Q005S_1D.csv\"):\n", - " fpth = os.path.join(\"..\", \"data\", sim_name, file_name)\n", - " df = pd.read_csv(fpth, index_col=0)\n", - " df.index = pd.to_datetime(df.index.values)\n", - " df.rename({\"mean\": \"observed\"}, inplace=True, axis=1)\n", - " return df" - ] - }, - { - "cell_type": "markdown", - "id": "4746d9e2", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to get simulation data as a pandas dataframe" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "631903c6", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def process_sim_csv(\n", - " fpth, index_tag=\"time\", origin_str=\"1908-05-09 00:00:00.000000\", **kwargs\n", - "):\n", - " v = pd.read_csv(fpth, **kwargs)\n", - "\n", - " v[\"date\"] = pd.to_datetime(v[index_tag].values, unit=\"d\", origin=origin_str)\n", - " v.set_index(\"date\", inplace=True)\n", - " v.drop(columns=index_tag, inplace=True)\n", - "\n", - " col_list = list(v.columns)\n", - "\n", - " return v, col_list" - ] - }, - { - "cell_type": "markdown", - "id": "4526d38a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to process compaction data and return a pandas dataframe" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "172ec177", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def get_sim_dataframe(fpth, index_tag=\"time\", origin_str=\"1908-05-09 00:00:00.000000\"):\n", - " v, col_list = process_sim_csv(fpth, index_tag=index_tag, origin_str=origin_str)\n", - "\n", - " # calculate total skeletal and total\n", - " shape = v[col_list[0]].values.shape[0]\n", - " s = np.zeros(shape, dtype=float)\n", - " # skeletal\n", - " for tag in col_list:\n", - " if \"SKC\" in tag[:3]:\n", - " s += v[tag].values\n", - " v[\"SKELETAL\"] = s.copy()\n", - " # total\n", - " s[:] = 0.0\n", - " for tag in col_list:\n", - " if \"TC\" in tag[:2]:\n", - " s += v[tag].values\n", - " v[\"TOTAL\"] = s.copy()\n", - "\n", - " for tag in col_list:\n", - " if \"TC\" in tag[:2] or \"SKC\" in tag[:3]:\n", - " v.drop(columns=tag, inplace=True)\n", - " return v" - ] - }, - { - "cell_type": "markdown", - "id": "1c68e211", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to new DataFrame with all columns values interpolated to new_index values" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "93943212", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def dataframe_interp(df_in, new_index):\n", - " df_out = pd.DataFrame(index=new_index)\n", - " df_out.index.name = df_in.index.name\n", - "\n", - " for colname, col in df_in.items():\n", - " df_out[colname] = np.interp(new_index, df_in.index, col)\n", - "\n", - " return df_out" - ] - }, - { - "cell_type": "markdown", - "id": "09c4b098", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to process compaction data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6f3d59b2", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def process_csub_obs(fpth):\n", - " tdata = flopy.utils.Mf6Obs(fpth).data\n", - " dtype = [\n", - " (\"totim\", float),\n", - " (\"CUNIT\", float),\n", - " (\"AQUITARD\", float),\n", - " (\"NODELAY\", float),\n", - " (\"DELAY\", float),\n", - " (\"SKELETAL\", float),\n", - " (\"TOTAL\", float),\n", - " ]\n", - "\n", - " # create structured array and fill time\n", - " v = np.zeros(tdata.shape[0], dtype=dtype)\n", - " v[\"totim\"] = tdata[\"totim\"]\n", - " v[\"totim\"] /= 365.25\n", - " v[\"totim\"] += 1908.353182752\n", - "\n", - " # transfer data from temporary storage\n", - " for key in pcomp:\n", - " if key != \"TOTAL\" and key != \"SKELETAL\":\n", - " v[key] = tdata[key].copy()\n", - "\n", - " # calculate skeletal\n", - " for key in tdata.dtype.names[1:]:\n", - " if \"SKC\" in key[:3]:\n", - " v[\"SKELETAL\"] += tdata[key]\n", - "\n", - " # calculate total\n", - " for key in tdata.dtype.names[1:]:\n", - " if \"TC\" in key[:2]:\n", - " v[\"TOTAL\"] += tdata[key]\n", - "\n", - " return v" - ] - }, - { - "cell_type": "markdown", - "id": "bd42ee47", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function used for plots" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dd098fee", - "metadata": {}, - "outputs": [], - "source": [ - "def set_label(label, text=\"text\"):\n", - " if label == \"\":\n", - " label = text\n", - " else:\n", - " label = None\n", - " return label" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3fecbffb", - "metadata": {}, - "outputs": [], - "source": [ - "def print_label(ax, zelev, k, fontsize=6):\n", - " zmax = zelev[-1][0]\n", - " z0 = zelev[k][0]\n", - " z1 = zelev[k + 1][0]\n", - " z = 1 - 0.5 * (z0 + z1) / zmax\n", - " text = f\"Layer {k + 1}\"\n", - " if k == 10:\n", - " arrowprops = dict(\n", - " facecolor=\"black\",\n", - " arrowstyle=\"-\",\n", - " lw=0.5,\n", - " connectionstyle=\"angle,angleA=-90,angleB=180,rad=0\",\n", - " shrinkA=0,\n", - " shrinkB=0,\n", - " )\n", - " ax.annotate(\n", - " text,\n", - " xy=(1, z),\n", - " xytext=(1.01, z - 0.025),\n", - " ha=\"left\",\n", - " va=\"top\",\n", - " zorder=103,\n", - " xycoords=\"axes fraction\",\n", - " textcoords=\"axes fraction\",\n", - " arrowprops=arrowprops,\n", - " fontsize=fontsize,\n", - " )\n", - " else:\n", - " ax.text(\n", - " 1.01,\n", - " z,\n", - " text,\n", - " fontsize=fontsize,\n", - " ha=\"left\",\n", - " va=\"center\",\n", - " transform=plt.gca().transAxes,\n", - " zorder=103,\n", - " )\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "187db938", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def constant_heads(ax, annotate=False, fontsize=6, xrange=(0, 1)):\n", - " arrowprops = dict(facecolor=\"black\", arrowstyle=\"-\", lw=0.5, shrinkA=0, shrinkB=0)\n", - " label = \"\"\n", - " for k in [0, 5, 10, 12]:\n", - " label = set_label(label, text=\"Constant head\")\n", - " color = \"cyan\"\n", - " if k == 0:\n", - " zo = 1\n", - " lw = 0.5\n", - " else:\n", - " zo = 200\n", - " lw = 0.5\n", - " ax.fill_between(\n", - " xrange,\n", - " edges[k],\n", - " y2=edges[k + 1],\n", - " color=color,\n", - " lw=lw,\n", - " label=label,\n", - " zorder=zo,\n", - " )\n", - " if annotate:\n", - " text = \"Constant\\nhead\"\n", - " x = 47.5\n", - " if k == 0:\n", - " y = 0.5 * (edges[k][0] + edges[k + 1][0])\n", - " ax.text(\n", - " x,\n", - " y,\n", - " text,\n", - " fontsize=fontsize,\n", - " ha=\"center\",\n", - " va=\"center\",\n", - " zorder=203,\n", - " )\n", - " else:\n", - " y = edges[k + 1][0]\n", - " ax.annotate(\n", - " text,\n", - " xy=(x + 2.25, y),\n", - " xytext=(x, y + 5),\n", - " ha=\"center\",\n", - " va=\"top\",\n", - " zorder=203,\n", - " arrowprops=arrowprops,\n", - " fontsize=fontsize,\n", - " )\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "210b6f7c", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b87f6971", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - " name = list(parameters.keys())[0]\n", - "\n", - " # # load the model\n", - " # sim = flopy.mf6.MFSimulation.load(sim_name=name, sim_ws=sim_ws)\n", - " # gwf = sim.get_model(name)\n", - "\n", - " xrange = (0, 1)\n", - " chds = (5, 10, 12)\n", - "\n", - " fig, axes = plt.subplots(nrows=1, ncols=3, sharey=True, figsize=(5.1, 4.0))\n", - "\n", - " for idx, ax in enumerate(axes):\n", - " ax.set_xlim(xrange)\n", - " ax.set_ylim(edges[-1][0], 0)\n", - " for edge in edges:\n", - " ax.plot(xrange, edge, lw=0.5, color=\"black\")\n", - " ax.tick_params(\n", - " axis=\"x\", which=\"both\", bottom=False, top=False, labelbottom=False\n", - " )\n", - " ax.tick_params(axis=\"y\", which=\"both\", right=False, labelright=False)\n", - "\n", - " ax = axes[0]\n", - " ax.fill_between(\n", - " xrange,\n", - " edges[0],\n", - " y2=edges[1],\n", - " color=\"green\",\n", - " lw=0,\n", - " label=\"Upper aquifer\",\n", - " )\n", - "\n", - " label = \"\"\n", - " for k in (1, 2, 3):\n", - " label = set_label(label, text=\"Confining unit\")\n", - " ax.fill_between(\n", - " xrange, edges[k], y2=edges[k + 1], color=\"brown\", lw=0, label=label\n", - " )\n", - "\n", - " label = \"\"\n", - " for k in (7, 8, 9):\n", - " label = set_label(label, text=\"Thick aquitard\")\n", - " ax.fill_between(\n", - " xrange, edges[k], y2=edges[k + 1], color=\"tan\", lw=0, label=label\n", - " )\n", - "\n", - " # middle aquifer\n", - " midz = 825.0 / 3.8081\n", - " midz = [edges[4], edges[7], edges[10], (midz, midz)]\n", - " ax.fill_between(\n", - " xrange, midz[0], y2=midz[1], color=\"cyan\", lw=0, label=\"Middle aquifer\"\n", - " )\n", - " ax.fill_between(xrange, midz[2], y2=midz[3], color=\"cyan\", lw=0)\n", - "\n", - " # lower aquifer\n", - " ax.fill_between(\n", - " xrange,\n", - " midz[-1],\n", - " y2=edges[-1],\n", - " color=\"blue\",\n", - " lw=0,\n", - " label=\"Lower aquifer\",\n", - " )\n", - "\n", - " fs.graph_legend(ax, loc=\"lower right\", frameon=True, framealpha=1)\n", - " fs.heading(ax=ax, letter=\"A\", heading=\"Hydrostratigraphy\")\n", - " fs.remove_edge_ticks(ax)\n", - " ax.set_ylabel(\"Depth below land surface, in meters\")\n", - "\n", - " # csub interbeds\n", - " ax = axes[1]\n", - "\n", - " nodelay = (1, 2, 3, 6, 7, 8, 9)\n", - " label = \"\"\n", - " for k in nodelay:\n", - " label = set_label(label, text=\"No-delay\")\n", - " ax.fill_between(\n", - " xrange, edges[k], y2=edges[k + 1], color=\"0.5\", lw=0, label=label\n", - " )\n", - "\n", - " comb = [4, 11, 13]\n", - " label = \"\"\n", - " for k in comb:\n", - " label = set_label(label, text=\"No-delay\\nand delay\")\n", - " ax.fill_between(\n", - " xrange, edges[k], y2=edges[k + 1], color=\"brown\", lw=0, label=label\n", - " )\n", - "\n", - " for k in chds:\n", - " ax.fill_between(\n", - " xrange,\n", - " edges[k],\n", - " y2=edges[k + 1],\n", - " color=\"white\",\n", - " lw=0.75,\n", - " zorder=100,\n", - " )\n", - "\n", - " leg = fs.graph_legend(ax, loc=\"lower right\", frameon=True, framealpha=1)\n", - " leg.set_zorder(100)\n", - " fs.heading(ax=ax, letter=\"B\", heading=\"Interbed types\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # boundary conditions\n", - " ax = axes[2]\n", - " constant_heads(ax)\n", - "\n", - " for k in llabels:\n", - " print_label(ax, edges, k)\n", - "\n", - " fs.graph_legend(ax, loc=\"lower left\")\n", - " fs.heading(ax=ax, letter=\"C\", heading=\"Boundary conditions\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " fig.tight_layout(pad=0.5)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "47aa34ec", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the boundary heads" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b2c6e243", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_boundary_heads(silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - "\n", - " def process_dtw_obs(fpth):\n", - " v = flopy.utils.Mf6Obs(fpth).data\n", - " v[\"totim\"] /= 365.25\n", - " v[\"totim\"] += 1908.353182752\n", - " for key in v.dtype.names[1:]:\n", - " v[key] *= -1.0\n", - " return v\n", - "\n", - " name = list(parameters.keys())[0]\n", - " pth = os.path.join(ws, name, f\"{name}.gwf.obs.csv\")\n", - " hdata = process_dtw_obs(pth)\n", - "\n", - " pheads = (\"HD01\", \"HD12\", \"HD14\")\n", - " hlabels = (\"Upper aquifer\", \"Middle aquifer\", \"Lower aquifer\")\n", - " hcolors = (\"green\", \"cyan\", \"blue\")\n", - "\n", - " fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(6.8, 6.8 / 3))\n", - "\n", - " ax.set_xlim(1907, 2007)\n", - " ax.set_xticks(xticks)\n", - " ax.set_ylim(50.0, -10.0)\n", - " ax.set_yticks(sorted([50.0, 40.0, 30.0, 20.0, 10.0, 0.0, -10.0]))\n", - "\n", - " ax.plot([1907, 2007], [0, 0], lw=0.5, color=\"0.5\")\n", - " for idx, key in enumerate(pheads):\n", - " ax.plot(\n", - " hdata[\"totim\"],\n", - " hdata[key],\n", - " lw=0.75,\n", - " color=hcolors[idx],\n", - " label=hlabels[idx],\n", - " )\n", - "\n", - " fs.graph_legend(ax=ax, frameon=False)\n", - " ax.set_ylabel(f\"Depth to water, in {length_units}\")\n", - " ax.set_xlabel(\"Year\")\n", - "\n", - " fs.remove_edge_ticks(ax=ax)\n", - "\n", - " fig.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-01{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "93de9134", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the head and effective stress based results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ddc1233c", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_head_es_comparison(silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - " name = list(parameters.keys())[0]\n", - " pth = os.path.join(ws, name, f\"{name}.csub.obs.csv\")\n", - " hb = process_csub_obs(pth)\n", - "\n", - " name = list(parameters.keys())[1]\n", - " pth = os.path.join(ws, name, f\"{name}.csub.obs.csv\")\n", - " es = process_csub_obs(pth)\n", - "\n", - " ymin = (2.0, 1, 1, 1, 0.1, 0.1)\n", - "\n", - " me = {}\n", - " for idx, key in enumerate(pcomp):\n", - " v = (es[key] - hb[key]).mean()\n", - " me[key] = v\n", - "\n", - " fig, axes = plt.subplots(nrows=6, ncols=1, sharex=True, figsize=(6.8, 4.7))\n", - " for idx, key in enumerate(pcomp):\n", - " label = clabels[idx]\n", - " ax = axes[idx]\n", - " ax.set_xlim(1907, 2007)\n", - " ax.set_ylim(0, ymin[idx])\n", - " ax.set_xticks(xticks)\n", - " stext = \"none\"\n", - " otext = \"none\"\n", - " if idx == 0:\n", - " stext = \"Effective stress-based\"\n", - " otext = \"Head-based\"\n", - " mtext = f\"mean error = {me[key]:7.4f} {length_units}\"\n", - " ax.plot(hb[\"totim\"], hb[key], color=\"#238A8DFF\", lw=1.25, label=otext)\n", - " ax.plot(\n", - " es[\"totim\"],\n", - " es[key],\n", - " color=\"black\",\n", - " lw=0.75,\n", - " label=stext,\n", - " zorder=101,\n", - " )\n", - " ltext = chr(ord(\"A\") + idx)\n", - " htext = f\"{label}\"\n", - " fs.heading(ax, letter=ltext, heading=htext)\n", - " va = \"bottom\"\n", - " ym = 0.15\n", - " if idx in [2, 3]:\n", - " va = \"top\"\n", - " ym = 0.85\n", - " ax.text(\n", - " 0.99,\n", - " ym,\n", - " mtext,\n", - " ha=\"right\",\n", - " va=va,\n", - " transform=ax.transAxes,\n", - " fontsize=7,\n", - " )\n", - " fs.remove_edge_ticks(ax=ax)\n", - " if idx == 0:\n", - " fs.graph_legend(ax, loc=\"center left\", ncol=2)\n", - " if idx == 5:\n", - " ax.set_xlabel(\"Year\")\n", - "\n", - " axp1 = fig.add_subplot(1, 1, 1, frameon=False)\n", - " axp1.tick_params(\n", - " labelcolor=\"none\", top=\"off\", bottom=\"off\", left=\"off\", right=\"off\"\n", - " )\n", - " axp1.set_xlim(0, 1)\n", - " axp1.set_xticks([0, 1])\n", - " axp1.set_ylim(0, 1)\n", - " axp1.set_yticks([0, 1])\n", - " axp1.set_ylabel(f\"Compaction, in {length_units}\")\n", - " axp1.yaxis.set_label_coords(-0.05, 0.5)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " fig.tight_layout(pad=0.0001)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-02{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d887947c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_calibration(silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - "\n", - " name = list(parameters.keys())[1]\n", - " pth = os.path.join(ws, name, f\"{name}.csub.obs.csv\")\n", - " df_sim = get_sim_dataframe(pth)\n", - " df_sim.rename({\"TOTAL\": \"simulated\"}, inplace=True, axis=1)\n", - "\n", - " pth = os.path.join(\"..\", \"data\", sim_name, \"boundary_heads.csv\")\n", - " df_obs_heads, col_list = process_sim_csv(pth)\n", - "\n", - " ccolors = (\n", - " \"black\",\n", - " \"tan\",\n", - " \"cyan\",\n", - " \"brown\",\n", - " \"blue\",\n", - " \"violet\",\n", - " )\n", - "\n", - " xf0 = datetime.datetime(1907, 1, 1, 0, 0, 0)\n", - " xf1 = datetime.datetime(2007, 1, 1, 0, 0, 0)\n", - " xf0s = datetime.datetime(1990, 1, 1, 0, 0, 0)\n", - " xf1s = datetime.datetime(2007, 1, 1, 0, 0, 0)\n", - " xc0 = datetime.datetime(1992, 10, 1, 0, 0, 0)\n", - " xc1 = datetime.datetime(2006, 9, 4, 0, 0, 0)\n", - " dx = xc1 - xc0\n", - " xca = xc0 + dx / 2\n", - "\n", - " # get observation data\n", - " df = get_obs_dataframe(file_name=\"008N010W01Q005S_obs.csv\")\n", - " ix0 = df.index.get_loc(\"2006-09-04 00:00:00\")\n", - " offset = df_sim[\"simulated\"].values[-1] - df.observed.values[ix0]\n", - " df.observed += offset\n", - "\n", - " # -- subplot a -----------------------------------------------------------\n", - " # build box for subplot B\n", - " o = datetime.timedelta(31)\n", - " ix = (xf0s, xf0s, xf1s - o, xf1s - o, xf0s)\n", - " iy = (1.15, 1.45, 1.45, 1.15, 1.15)\n", - " # -- subplot a -----------------------------------------------------------\n", - "\n", - " # -- subplot c -----------------------------------------------------------\n", - " # get observations\n", - " df_pc = get_obs_dataframe()\n", - "\n", - " # get index for start of calibration period for subplot c\n", - " ix0 = df_sim.index.get_loc(\"1992-10-01 12:00:00\")\n", - "\n", - " # get initial simulated compaction\n", - " cstart = df_sim.simulated[ix0]\n", - "\n", - " # cut off initial portion of simulated compaction\n", - " df_sim_pc = df_sim[ix0:].copy()\n", - "\n", - " # reset initial compaction to 0.\n", - " df_sim_pc.simulated -= cstart\n", - "\n", - " # reset simulated so maximum compaction is the same\n", - " offset = df_pc.observed.values.max() - df_sim_pc.simulated.values[-1]\n", - " df_sim.simulated += offset\n", - "\n", - " # interpolate subsidence observations to the simulation index for subplot c\n", - " df_iobs_pc = dataframe_interp(df_pc, df_sim_pc.index)\n", - "\n", - " # truncate head to start of observations\n", - " head_pc = dataframe_interp(df_obs_heads, df_sim_pc.index)\n", - "\n", - " # calculate geostatic stress\n", - " gs = sgm * (0.0 - head_pc.CHD_L01.values) + sgs * (\n", - " head_pc.CHD_L01.values - botm[-1]\n", - " )\n", - "\n", - " # calculate hydrostatic stress for subplot c\n", - " u = head_pc.CHD_L13.values - botm[-1]\n", - "\n", - " # calculate effective stress\n", - " es_obs = gs - u\n", - "\n", - " # set up indices for date text for plot c\n", - " locs = [f\"{yr:04d}-10-01 12:00:00\" for yr in range(1992, 2006)]\n", - " locs += [f\"{yr:04d}-04-01 12:00:00\" for yr in range(1993, 2007)]\n", - " locs += [\"2006-09-04 12:00:00\"]\n", - "\n", - " ixs = [head_pc.index.get_loc(loc) for loc in locs]\n", - " # -- subplot c -----------------------------------------------------------\n", - "\n", - " ctext = \"Calibration period\\n{} to {}\".format(\n", - " xc0.strftime(\"%B %d, %Y\"), xc1.strftime(\"%B %d, %Y\")\n", - " )\n", - "\n", - " fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(6.8, 6.8))\n", - "\n", - " # -- plot a --------------------------------------------------------------\n", - " ax = axes.flat[0]\n", - " ax.set_xlim(xf0, xf1)\n", - " ax.plot([xf0, xf1], [0, 0], lw=0.5, color=\"0.5\")\n", - " ax.plot(\n", - " [\n", - " xf0,\n", - " ],\n", - " [\n", - " -10,\n", - " ],\n", - " marker=\".\",\n", - " ms=1,\n", - " lw=0,\n", - " color=\"red\",\n", - " label=\"Holly site (8N/10W-1Q)\",\n", - " )\n", - " for idx, key in enumerate(pcomp):\n", - " if key == \"TOTAL\":\n", - " key = \"simulated\"\n", - " color = ccolors[idx]\n", - " label = clabels[idx]\n", - " ax.plot(\n", - " df_sim.index.values,\n", - " df_sim[key].values,\n", - " color=color,\n", - " label=label,\n", - " lw=0.75,\n", - " )\n", - " ax.plot(ix, iy, lw=1.0, color=\"red\", zorder=200)\n", - " fs.add_text(ax=ax, text=\"B\", x=xf0s, y=1.14, transform=False)\n", - "\n", - " ax.set_ylim(1.5, -0.1)\n", - " ax.xaxis.set_ticks(df_xticks)\n", - " ax.xaxis.set_major_formatter(mpl.dates.DateFormatter(\"%m/%d/%Y\"))\n", - "\n", - " ax.set_ylabel(f\"Compaction, in {length_units}\")\n", - " ax.set_xlabel(\"Year\")\n", - "\n", - " fs.graph_legend(ax=ax, frameon=False)\n", - " fs.heading(ax, letter=\"A\")\n", - " fs.remove_edge_ticks(ax=ax)\n", - "\n", - " # -- plot b --------------------------------------------------------------\n", - " ax = axes.flat[1]\n", - " ax.set_xlim(xf0s, xf1s)\n", - " ax.set_ylim(1.45, 1.15)\n", - " ax.plot(\n", - " df.index.values,\n", - " df[\"observed\"].values,\n", - " marker=\".\",\n", - " ms=1,\n", - " lw=0,\n", - " color=\"red\",\n", - " )\n", - " ax.plot(\n", - " df_sim.index.values,\n", - " df_sim[\"simulated\"].values,\n", - " color=\"black\",\n", - " label=label,\n", - " lw=0.75,\n", - " )\n", - "\n", - " # plot lines for calibration\n", - " ax.plot([xc0, xc0], [1.45, 1.15], color=\"black\", lw=0.5, ls=\":\")\n", - " ax.plot([xc1, xc1], [1.45, 1.15], color=\"black\", lw=0.5, ls=\":\")\n", - " fs.add_annotation(\n", - " ax=ax,\n", - " text=ctext,\n", - " italic=False,\n", - " bold=False,\n", - " xy=(xc0 - o, 1.2),\n", - " xytext=(xca, 1.2),\n", - " ha=\"center\",\n", - " va=\"center\",\n", - " arrowprops=dict(arrowstyle=\"-|>\", fc=\"black\", lw=0.5),\n", - " color=\"none\",\n", - " bbox=dict(boxstyle=\"square,pad=-0.07\", fc=\"none\", ec=\"none\"),\n", - " )\n", - " fs.add_annotation(\n", - " ax=ax,\n", - " text=ctext,\n", - " italic=False,\n", - " bold=False,\n", - " xy=(xc1 + o, 1.2),\n", - " xytext=(xca, 1.2),\n", - " ha=\"center\",\n", - " va=\"center\",\n", - " arrowprops=dict(arrowstyle=\"-|>\", fc=\"black\", lw=0.5),\n", - " bbox=dict(boxstyle=\"square,pad=-0.07\", fc=\"none\", ec=\"none\"),\n", - " )\n", - "\n", - " ax.yaxis.set_ticks(np.linspace(1.15, 1.45, 7))\n", - " ax.xaxis.set_ticks(df_xticks1)\n", - "\n", - " ax.xaxis.set_major_locator(mpl.dates.YearLocator())\n", - " ax.xaxis.set_minor_locator(mpl.dates.YearLocator(month=6, day=15))\n", - "\n", - " ax.xaxis.set_major_formatter(mpl.ticker.NullFormatter())\n", - " ax.xaxis.set_minor_formatter(mpl.dates.DateFormatter(\"%Y\"))\n", - " ax.tick_params(axis=\"x\", which=\"minor\", length=0)\n", - "\n", - " ax.set_ylabel(f\"Compaction, in {length_units}\")\n", - " ax.set_xlabel(\"Year\")\n", - " fs.heading(ax, letter=\"B\")\n", - " fs.remove_edge_ticks(ax=ax)\n", - "\n", - " # -- plot c --------------------------------------------------------------\n", - " ax = axes.flat[2]\n", - " ax.set_xlim(-0.01, 0.2)\n", - " ax.set_ylim(368, 376)\n", - "\n", - " ax.plot(\n", - " df_iobs_pc.observed.values,\n", - " es_obs,\n", - " marker=\".\",\n", - " ms=1,\n", - " color=\"red\",\n", - " lw=0,\n", - " label=\"Holly site (8N/10W-1Q)\",\n", - " )\n", - " ax.plot(\n", - " df_sim_pc.simulated.values,\n", - " df_sim_pc.ES14.values,\n", - " color=\"black\",\n", - " lw=0.75,\n", - " label=\"Simulated\",\n", - " )\n", - "\n", - " for idx, ixc in enumerate(ixs):\n", - " text = \"{}\".format(df_iobs_pc.index[ixc].strftime(\"%m/%d/%Y\"))\n", - " if df_iobs_pc.index[ixc].month == 4:\n", - " dxc = -0.001\n", - " dyc = -1\n", - " elif df_iobs_pc.index[ixc].month == 9:\n", - " dxc = 0.002\n", - " dyc = 0.75\n", - " else:\n", - " dxc = 0.001\n", - " dyc = 1\n", - " xc = df_iobs_pc.observed[ixc]\n", - " yc = es_obs[ixc]\n", - " fs.add_annotation(\n", - " ax=ax,\n", - " text=text,\n", - " italic=False,\n", - " bold=False,\n", - " xy=(xc, yc),\n", - " xytext=(xc + dxc, yc + dyc),\n", - " ha=\"center\",\n", - " va=\"center\",\n", - " fontsize=7,\n", - " arrowprops=dict(arrowstyle=\"-\", color=\"red\", fc=\"red\", lw=0.5),\n", - " bbox=dict(boxstyle=\"square,pad=-0.15\", fc=\"none\", ec=\"none\"),\n", - " )\n", - "\n", - " xtext = \"Total compaction since {}, in {}\".format(\n", - " df_sim_pc.index[0].strftime(\"%B %d, %Y\"), length_units\n", - " )\n", - " ytext = (\n", - " \"Effective stress at the bottom of\\nthe lower aquifer, in \"\n", - " + f\"{length_units} of water\"\n", - " )\n", - " ax.set_xlabel(xtext)\n", - " ax.set_ylabel(ytext)\n", - " fs.heading(ax, letter=\"C\")\n", - " fs.remove_edge_ticks(ax=ax)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # finalize figure\n", - " fig.tight_layout(pad=0.01)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-03{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "964a770d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot vertical head profiles" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "68e57fd7", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_vertical_head(silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - "\n", - " name = list(parameters.keys())[1]\n", - " pth = os.path.join(ws, name, f\"{name}.gwf.obs.csv\")\n", - " df_heads, col_list = process_sim_csv(pth, origin_str=\"1908-05-09 00:00:00.000000\")\n", - " df_heads_year = df_heads.groupby(df_heads.index.year).mean()\n", - "\n", - " def get_colors(vmax=6):\n", - " # set color\n", - " cmap = plt.get_cmap(\"viridis\")\n", - " cNorm = mpl.colors.Normalize(vmin=0, vmax=vmax)\n", - " scalarMap = mpl.cm.ScalarMappable(norm=cNorm, cmap=cmap)\n", - " colors = []\n", - " for ic in range(vmax):\n", - " colors.append(scalarMap.to_rgba(ic))\n", - " return colors\n", - "\n", - " def build_head_data(df, year=1908):\n", - " dfr = df.loc[df.index == year]\n", - " xlabel = None\n", - " x = []\n", - " y = []\n", - " for k in range(14):\n", - " tag = f\"HD{k + 1:02d}\"\n", - " h = dfr[tag].values[0]\n", - " if k == 0:\n", - " z0 = -25.0\n", - " xlabel = -1.0 * h\n", - " else:\n", - " z0 = zelevs[k]\n", - " z1 = zelevs[k + 1]\n", - " h *= -1.0\n", - " x += [h, h]\n", - " y += [-z0, -z1]\n", - " return xlabel, x, y\n", - "\n", - " iyears = (1908, 1916, 1926, 1936, 1946, 1956, 1966, 1976, 1986, 1996, 2006)\n", - " colors = get_colors(vmax=len(iyears) - 1)\n", - "\n", - " xrange = (-10, 50)\n", - " fig, ax = plt.subplots(nrows=1, ncols=1, sharey=True, figsize=(0.75 * 6.8, 4.0))\n", - "\n", - " ax.set_xlim(xrange)\n", - " ax.set_ylim(-botm[-1], 0)\n", - "\n", - " for z in botm:\n", - " ax.axhline(y=-z, xmin=-30, xmax=160, lw=0.5, color=\"0.5\")\n", - "\n", - " # add confining units\n", - " label = \"\"\n", - " for k in (1, 2, 3):\n", - " label = set_label(label, text=\"Confining unit\")\n", - " ax.fill_between(\n", - " xrange, edges[k], y2=edges[k + 1], color=\"brown\", lw=0, label=label\n", - " )\n", - " ypos = -0.5 * (zelevs[2] + zelevs[3])\n", - " ax.text(\n", - " 40,\n", - " ypos,\n", - " \"Confining unit\",\n", - " ha=\"left\",\n", - " va=\"center\",\n", - " size=8,\n", - " color=\"white\",\n", - " )\n", - "\n", - " label = \"\"\n", - " for k in (7, 8, 9):\n", - " label = set_label(label, text=\"Thick aquitard\")\n", - " ax.fill_between(\n", - " xrange, edges[k], y2=edges[k + 1], color=\"tan\", lw=0, label=label\n", - " )\n", - " ypos = -0.5 * (zelevs[8] + zelevs[9])\n", - " ax.text(\n", - " 40,\n", - " ypos,\n", - " \"Thick aquitard\",\n", - " ha=\"left\",\n", - " va=\"center\",\n", - " size=8,\n", - " color=\"white\",\n", - " )\n", - "\n", - " zo = 105\n", - " for idx, iyear in enumerate(iyears[:-1]):\n", - " xlabel, x, y = build_head_data(df_heads_year, year=iyear)\n", - " xlabel1, x1, y1 = build_head_data(df_heads_year, year=iyears[idx + 1])\n", - " ax.fill_betweenx(y, x, x2=x1, color=colors[idx], zorder=zo, step=\"mid\", lw=0)\n", - " ax.plot(x, y, lw=0.5, color=\"black\", zorder=201)\n", - " ax.text(\n", - " xlabel,\n", - " 24,\n", - " f\"{iyear}\",\n", - " ha=\"center\",\n", - " va=\"bottom\",\n", - " rotation=90,\n", - " size=7,\n", - " )\n", - " if iyear == 1996:\n", - " ax.plot(x1, y1, lw=0.5, color=\"black\", zorder=zo)\n", - " ax.text(\n", - " xlabel1,\n", - " 24,\n", - " f\"{iyears[idx + 1]}\",\n", - " ha=\"center\",\n", - " va=\"bottom\",\n", - " rotation=90,\n", - " size=7,\n", - " )\n", - " zo += 1\n", - "\n", - " # add layer labels\n", - " for k in llabels:\n", - " print_label(ax, edges, k)\n", - "\n", - " constant_heads(ax, annotate=True, xrange=xrange)\n", - "\n", - " ax.set_xlabel(\"Depth to water, in meters below land surface\")\n", - " ax.set_ylabel(\"Depth below land surface, in meters\")\n", - "\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " fig.tight_layout(pad=0.5)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-04{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "79e4b9bd", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "34f805eb", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(silent=True):\n", - " if config.plotModel:\n", - " plot_grid(silent=silent)\n", - " plot_boundary_heads(silent=silent)\n", - " plot_head_es_comparison(silent=silent)\n", - " plot_calibration(silent=silent)\n", - " plot_vertical_head()" - ] - }, - { - "cell_type": "markdown", - "id": "4cd4f2b4", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1e8ec17c", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - "\n", - " sim = build_model(key, **params)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "73af9dcb", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_and_plot():\n", - " simulation(0, silent=False)\n", - " simulation(1, silent=False)\n", - " plot_results(silent=False)\n", - " export_tables(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "a2558099", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9d31cdf5", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### One-dimensional compaction\n", - " #\n", - " # #### Head based solution\n", - "\n", - " simulation(0)\n", - "\n", - " # #### Effective stress solution\n", - "\n", - " simulation(1)\n", - "\n", - " # #### Plot results\n", - "\n", - " plot_results()\n", - "\n", - " # #### Export tables\n", - "\n", - " export_tables()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-csub-p04.ipynb b/notebooks/ex-gwf-csub-p04.ipynb deleted file mode 100644 index 70a464fb..00000000 --- a/notebooks/ex-gwf-csub-p04.ipynb +++ /dev/null @@ -1,1323 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "51432426", - "metadata": {}, - "source": [ - "## One-dimensional compaction in a three-dimensional flow field\n", - "\n", - "This problem is based on the problem presented in the SUB-WT report\n", - "(Leake and Galloway, 2007) and represent groundwater development in a\n", - "hypothetical aquifer that includes some features typical of basin-fill\n", - "aquifers in an arid or semi-arid environment.\n" - ] - }, - { - "cell_type": "markdown", - "id": "f6804d79", - "metadata": {}, - "source": [ - "### Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "495b31e8", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b36a2ecf", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "2c98f073", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bc153e87", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "4910e54c", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c4535c39", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "d26ece75", - "metadata": {}, - "source": [ - "Set figure properties specific to the problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "400b24b0", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.8, 5.5)\n", - "arrow_props = dict(facecolor=\"black\", arrowstyle=\"-\", lw=0.5)\n", - "plot_tags = (\n", - " \"W1L\",\n", - " \"W2L\",\n", - " \"S1L\",\n", - " \"S2L\",\n", - " \"C1L\",\n", - " \"C2L\",\n", - ")\n", - "compaction_heading = (\"row 9, column 10\", \"row 12, column 7\")" - ] - }, - { - "cell_type": "markdown", - "id": "72a807fd", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e2a354e5", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "859df4dd", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d2fa9eb9", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-csub-p04\"" - ] - }, - { - "cell_type": "markdown", - "id": "173731b3", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "87208381", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "5155fa3c", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "32a5c1da", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 3 # Number of periods\n", - "nlay = 4 # Number of layers\n", - "nrow = 20 # Number of rows\n", - "ncol = 15 # Number of columns\n", - "delr = 2000.0 # Column width ($m$)\n", - "delc = 2000.0 # Row width ($m$)\n", - "top = 150.0 # Top of the model ($ft$)\n", - "botm_str = \"50., -100., -150., -350.\" # Layer bottom elevations ($m$)\n", - "strt = 100.0 # Starting head ($m$)\n", - "icelltype_str = \"1, 0, 0, 0\" # Cell conversion type\n", - "k11_str = \"4., 4., 0.01, 4.\" # Horizontal hydraulic conductivity ($m/d$)\n", - "k33_str = \"0.4, 0.4, 0.01, 0.4\" # Vertical hydraulic conductivity ($m/d$)\n", - "sy_str = \"0.3, 0.3, 0.4, 0.3\" # Specific yield (unitless)\n", - "gammaw = 9806.65 # Compressibility of water (Newtons/($m^3$)\n", - "beta = 4.6612e-10 # Specific gravity of water (1/$Pa$)\n", - "sgm_str = \"1.77, 1.77, 1.60, 1.77\" # Specific gravity of moist soils (unitless)\n", - "sgs_str = \"2.06, 2.05, 1.94, 2.06\" # Specific gravity of saturated soils (unitless)\n", - "cg_theta_str = \"0.32, 0.32, 0.45, 0.32\" # Coarse-grained material porosity (unitless)\n", - "cg_ske_str = \"0.005, 0.005, 0.01, 0.005\" # Elastic specific storage ($1/m$)\n", - "ib_thick_str = \"45., 70., 50., 90.\" # Interbed thickness ($m$)\n", - "ib_theta = 0.45 # Interbed initial porosity (unitless)\n", - "ib_cr = 0.01 # Interbed recompression index (unitless)\n", - "ib_cv = 0.25 # Interbed compression index (unitless)\n", - "stress_offset = 15.0 # Initial preconsolidation stress offset ($m$)" - ] - }, - { - "cell_type": "markdown", - "id": "1bdab070", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4efc34b7", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = (\n", - " (0.0, 1, 1.0),\n", - " (21915.0, 60, 1.0),\n", - " (21915.0, 60, 1.0),\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "df8a2cb7", - "metadata": {}, - "source": [ - "parse parameter strings into tuples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d87dc7c5", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]\n", - "icelltype = [int(value) for value in icelltype_str.split(\",\")]\n", - "k11 = [float(value) for value in k11_str.split(\",\")]\n", - "k33 = [float(value) for value in k33_str.split(\",\")]\n", - "sy = [float(value) for value in sy_str.split(\",\")]\n", - "sgm = [float(value) for value in sgm_str.split(\",\")]\n", - "sgs = [float(value) for value in sgs_str.split(\",\")]\n", - "cg_theta = [float(value) for value in cg_theta_str.split(\",\")]\n", - "cg_ske = [float(value) for value in cg_ske_str.split(\",\")]\n", - "ib_thick = [float(value) for value in ib_thick_str.split(\",\")]" - ] - }, - { - "cell_type": "markdown", - "id": "53ab1e3a", - "metadata": {}, - "source": [ - "Load active domain and create idomain array" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0a1e3cde", - "metadata": {}, - "outputs": [], - "source": [ - "pth = os.path.join(\"..\", \"data\", sim_name, \"idomain.txt\")\n", - "ib = np.loadtxt(pth, dtype=int)\n", - "idomain = np.tile(ib, (nlay, 1))" - ] - }, - { - "cell_type": "markdown", - "id": "ffc5546e", - "metadata": {}, - "source": [ - "Constant head boundary cells" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f010a795", - "metadata": {}, - "outputs": [], - "source": [ - "chd_locs = [(nrow - 1, 7), (nrow - 1, 8)]\n", - "c6 = []\n", - "for i, j in chd_locs:\n", - " for k in range(nlay):\n", - " c6.append([k, i, j, strt])" - ] - }, - { - "cell_type": "markdown", - "id": "1f8b6cce", - "metadata": {}, - "source": [ - "Recharge boundary cells" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9460a30a", - "metadata": {}, - "outputs": [], - "source": [ - "rch_rate = 5.5e-4\n", - "rch6 = []\n", - "for i in range(nrow):\n", - " for j in range(ncol):\n", - " if ib[i, j] != 2 or (i, j) in chd_locs:\n", - " continue\n", - " rch6.append([0, i, j, rch_rate])" - ] - }, - { - "cell_type": "markdown", - "id": "6f196c09", - "metadata": {}, - "source": [ - "Well boundary cells" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dff88020", - "metadata": {}, - "outputs": [], - "source": [ - "well_locs = (\n", - " (1, 8, 9),\n", - " (3, 11, 6),\n", - ")\n", - "well_rates = (\n", - " -72000,\n", - " 0.0,\n", - ")\n", - "wel6 = {}\n", - "for idx, q in enumerate(well_rates):\n", - " spd = []\n", - " for k, i, j in well_locs:\n", - " spd.append([k, i, j, q])\n", - " wel6[idx + 1] = spd" - ] - }, - { - "cell_type": "markdown", - "id": "d3b553bf", - "metadata": {}, - "source": [ - "Create interbed package data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9d55cdf0", - "metadata": {}, - "outputs": [], - "source": [ - "icsubno = 0\n", - "csub_pakdata = []\n", - "for i in range(nrow):\n", - " for j in range(ncol):\n", - " if ib[i, j] < 1 or (i, j) in chd_locs:\n", - " continue\n", - " for k in range(nlay):\n", - " boundname = f\"{k + 1:02d}_{i + 1:02d}_{j + 1:02d}\"\n", - " ib_lst = [\n", - " icsubno,\n", - " (k, i, j),\n", - " \"nodelay\",\n", - " stress_offset,\n", - " ib_thick[k],\n", - " 1.0,\n", - " ib_cv,\n", - " ib_cr,\n", - " ib_theta,\n", - " 999.0,\n", - " 999.0,\n", - " boundname,\n", - " ]\n", - " csub_pakdata.append(ib_lst)\n", - " icsubno += 1" - ] - }, - { - "cell_type": "markdown", - "id": "9d4eae47", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e90fabcf", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 100\n", - "ninner = 300\n", - "hclose = 1e-9\n", - "rclose = 1e-6\n", - "linaccel = \"bicgstab\"\n", - "relax = 0.97" - ] - }, - { - "cell_type": "markdown", - "id": "75ae1918", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c22fd715", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " linear_acceleration=linaccel,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " relaxation_factor=relax,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim, modelname=sim_name, save_flows=True, newtonoptions=\"newton\"\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " )\n", - " # gwf obs\n", - " flopy.mf6.ModflowUtlobs(\n", - " gwf,\n", - " digits=10,\n", - " print_input=True,\n", - " continuous={\n", - " \"gwf_obs.csv\": [\n", - " (\"h1l1\", \"HEAD\", (0, 8, 9)),\n", - " (\"h1l2\", \"HEAD\", (1, 8, 9)),\n", - " (\"h1l3\", \"HEAD\", (2, 8, 9)),\n", - " (\"h1l4\", \"HEAD\", (3, 8, 9)),\n", - " (\"h2l1\", \"HEAD\", (0, 11, 6)),\n", - " (\"h2l2\", \"HEAD\", (1, 11, 6)),\n", - " (\"h3l2\", \"HEAD\", (2, 11, 6)),\n", - " (\"h4l2\", \"HEAD\", (3, 11, 6)),\n", - " ]\n", - " },\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=icelltype,\n", - " ss=0.0,\n", - " sy=sy,\n", - " steady_state={0: True},\n", - " transient={1: True},\n", - " )\n", - " csub = flopy.mf6.ModflowGwfcsub(\n", - " gwf,\n", - " print_input=True,\n", - " save_flows=True,\n", - " compression_indices=True,\n", - " update_material_properties=True,\n", - " boundnames=True,\n", - " ninterbeds=len(csub_pakdata),\n", - " sgm=sgm,\n", - " sgs=sgs,\n", - " cg_theta=cg_theta,\n", - " cg_ske_cr=cg_ske,\n", - " beta=beta,\n", - " gammaw=gammaw,\n", - " packagedata=csub_pakdata,\n", - " )\n", - " opth = f\"{sim_name}.csub.obs\"\n", - " csub_csv = opth + \".csv\"\n", - " obs = [\n", - " (\"w1l1\", \"interbed-compaction\", \"01_09_10\"),\n", - " (\"w1l2\", \"interbed-compaction\", \"02_09_10\"),\n", - " (\"w1l3\", \"interbed-compaction\", \"03_09_10\"),\n", - " (\"w1l4\", \"interbed-compaction\", \"04_09_10\"),\n", - " (\"w2l1\", \"interbed-compaction\", \"01_12_07\"),\n", - " (\"w2l2\", \"interbed-compaction\", \"02_12_07\"),\n", - " (\"w2l3\", \"interbed-compaction\", \"03_12_07\"),\n", - " (\"w2l4\", \"interbed-compaction\", \"04_12_07\"),\n", - " (\"s1l1\", \"coarse-compaction\", (0, 8, 9)),\n", - " (\"s1l2\", \"coarse-compaction\", (1, 8, 9)),\n", - " (\"s1l3\", \"coarse-compaction\", (2, 8, 9)),\n", - " (\"s1l4\", \"coarse-compaction\", (3, 8, 9)),\n", - " (\"s2l1\", \"coarse-compaction\", (0, 11, 6)),\n", - " (\"s2l2\", \"coarse-compaction\", (1, 11, 6)),\n", - " (\"s2l3\", \"coarse-compaction\", (2, 11, 6)),\n", - " (\"s2l4\", \"coarse-compaction\", (3, 11, 6)),\n", - " (\"c1l1\", \"compaction-cell\", (0, 8, 9)),\n", - " (\"c1l2\", \"compaction-cell\", (1, 8, 9)),\n", - " (\"c1l3\", \"compaction-cell\", (2, 8, 9)),\n", - " (\"c1l4\", \"compaction-cell\", (3, 8, 9)),\n", - " (\"c2l1\", \"compaction-cell\", (0, 11, 6)),\n", - " (\"c2l2\", \"compaction-cell\", (1, 11, 6)),\n", - " (\"c2l3\", \"compaction-cell\", (2, 11, 6)),\n", - " (\"c2l4\", \"compaction-cell\", (3, 11, 6)),\n", - " (\"w2l4q\", \"csub-cell\", (3, 11, 6)),\n", - " (\"gs1\", \"gstress-cell\", (0, 8, 9)),\n", - " (\"es1\", \"estress-cell\", (0, 8, 9)),\n", - " (\"pc1\", \"preconstress-cell\", (0, 8, 9)),\n", - " (\"gs2\", \"gstress-cell\", (1, 8, 9)),\n", - " (\"es2\", \"estress-cell\", (1, 8, 9)),\n", - " (\"pc2\", \"preconstress-cell\", (1, 8, 9)),\n", - " (\"gs3\", \"gstress-cell\", (2, 8, 9)),\n", - " (\"es3\", \"estress-cell\", (2, 8, 9)),\n", - " (\"pc3\", \"preconstress-cell\", (2, 8, 9)),\n", - " (\"gs4\", \"gstress-cell\", (3, 8, 9)),\n", - " (\"es4\", \"estress-cell\", (3, 8, 9)),\n", - " (\"pc4\", \"preconstress-cell\", (3, 8, 9)),\n", - " (\"sk1l2\", \"ske-cell\", (1, 8, 9)),\n", - " (\"sk2l4\", \"ske-cell\", (3, 11, 6)),\n", - " (\"t1l2\", \"theta\", \"02_09_10\"),\n", - " (\"w1qie\", \"elastic-csub\", \"02_09_10\"),\n", - " (\"w1qii\", \"inelastic-csub\", \"02_09_10\"),\n", - " (\"w1qaq\", \"coarse-csub\", (1, 8, 9)),\n", - " (\"w1qt\", \"csub-cell\", (1, 8, 9)),\n", - " (\"w1wc\", \"wcomp-csub-cell\", (1, 8, 9)),\n", - " (\"w2qie\", \"elastic-csub\", \"04_12_07\"),\n", - " (\"w2qii\", \"inelastic-csub\", \"04_12_07\"),\n", - " (\"w2qaq\", \"coarse-csub\", (3, 11, 6)),\n", - " (\"w2qt \", \"csub-cell\", (3, 11, 6)),\n", - " (\"w2wc\", \"wcomp-csub-cell\", (3, 11, 6)),\n", - " ]\n", - " orecarray = {csub_csv: obs}\n", - " csub.obs.initialize(\n", - " filename=opth, digits=10, print_input=True, continuous=orecarray\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data={0: c6})\n", - " flopy.mf6.ModflowGwfrch(gwf, stress_period_data={0: rch6})\n", - " flopy.mf6.ModflowGwfwel(gwf, stress_period_data=wel6)\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " printrecord=[(\"BUDGET\", \"ALL\")],\n", - " saverecord=[(\"BUDGET\", \"ALL\"), (\"HEAD\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "85191e01", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "feeeabfa", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "0411aa2b", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "90df95eb", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "514b6765", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to get csub observations" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "46a1555b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def get_csub_observations(sim):\n", - " name = sim.name\n", - " gwf = sim.get_model(sim_name)\n", - " csub_obs = gwf.csub.output.obs().data\n", - " csub_obs[\"totim\"] /= 365.25\n", - "\n", - " # set initial preconsolidation stress to stress period 1 value\n", - " slist = [name for name in csub_obs.dtype.names if \"PC\" in name]\n", - " for tag in slist:\n", - " csub_obs[tag][0] = csub_obs[tag][1]\n", - "\n", - " # set initial storativity to stress period 1 value\n", - " sk_tags = (\n", - " \"SK1L2\",\n", - " \"SK2L4\",\n", - " )\n", - " for tag in sk_tags:\n", - " if tag in csub_obs.dtype.names:\n", - " csub_obs[tag][0] = csub_obs[tag][1]\n", - "\n", - " return csub_obs" - ] - }, - { - "cell_type": "markdown", - "id": "36a0f78a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to calculate the compaction at the surface" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b626c4de", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def calc_compaction_at_surface(sim):\n", - " csub_obs = get_csub_observations(sim)\n", - " for tag in plot_tags:\n", - " for k in (\n", - " 3,\n", - " 2,\n", - " 1,\n", - " ):\n", - " tag0 = f\"{tag}{k}\"\n", - " tag1 = f\"{tag}{k + 1}\"\n", - " csub_obs[tag0] += csub_obs[tag1]\n", - " return csub_obs" - ] - }, - { - "cell_type": "markdown", - "id": "94aba15f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot compaction results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "de18df5b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_compaction_values(ax, sim, tagbase=\"W1L\"):\n", - " colors = [\"#FFF8DC\", \"#D2B48C\", \"#CD853F\", \"#8B4513\"][::-1]\n", - " obs = calc_compaction_at_surface(sim)\n", - " for k in range(nlay):\n", - " fc = colors[k]\n", - " tag = f\"{tagbase}{k + 1}\"\n", - " label = f\"Model layer {k + 1}\"\n", - " ax.fill_between(obs[\"totim\"], obs[tag], y2=0, color=fc, label=label)" - ] - }, - { - "cell_type": "markdown", - "id": "5b98c893", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e7c7f1e0", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(sim, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - " name = sim.name\n", - " gwf = sim.get_model(name)\n", - " extents = gwf.modelgrid.extent\n", - "\n", - " # read simulated heads\n", - " hobj = gwf.output.head()\n", - " h0 = hobj.get_data(kstpkper=(0, 0))\n", - " h1 = hobj.get_data(kstpkper=(59, 1))\n", - " hsxs0 = h0[0, 8, :]\n", - " hsxs1 = h1[0, 8, :]\n", - "\n", - " # get delr array\n", - " dx = gwf.dis.delr.array\n", - "\n", - " # create x-axis for cross-section\n", - " hxloc = np.arange(1000, 2000.0 * 15, 2000.0)\n", - "\n", - " # set cross-section location\n", - " y = 2000.0 * 11.5\n", - " xsloc = [(extents[0], extents[1]), (y, y)]\n", - "\n", - " # well locations\n", - " w1loc = (9.5 * 2000.0, 11.75 * 2000.0)\n", - " w2loc = (6.5 * 2000.0, 8.5 * 2000.0)\n", - "\n", - " fig = plt.figure(figsize=(6.8, 5), constrained_layout=True)\n", - " gs = mpl.gridspec.GridSpec(7, 10, figure=fig, wspace=5)\n", - " plt.axis(\"off\")\n", - "\n", - " ax = fig.add_subplot(gs[:, 0:6])\n", - " # ax.set_aspect('equal')\n", - " mm = flopy.plot.PlotMapView(model=gwf, ax=ax, extent=extents)\n", - " mm.plot_grid(lw=0.5, color=\"0.5\")\n", - " mm.plot_bc(ftype=\"WEL\", kper=1, plotAll=True)\n", - " mm.plot_bc(ftype=\"CHD\", color=\"blue\")\n", - " mm.plot_bc(ftype=\"RCH\", color=\"green\")\n", - " mm.plot_inactive(color_noflow=\"0.75\")\n", - " mm.ax.plot(xsloc[0], xsloc[1], color=\"orange\", lw=1.5)\n", - " # contour steady state heads\n", - " cl = mm.contour_array(\n", - " h0,\n", - " masked_values=[1.0e30],\n", - " levels=np.arange(115, 200, 5),\n", - " colors=\"black\",\n", - " linestyles=\"dotted\",\n", - " linewidths=0.75,\n", - " )\n", - " ax.clabel(cl, fmt=\"%3i\", inline_spacing=0.1)\n", - " # well text\n", - " fs.add_annotation(\n", - " ax=ax,\n", - " text=\"Well 1, layer 2\",\n", - " bold=False,\n", - " italic=False,\n", - " xy=w1loc,\n", - " xytext=(w1loc[0] - 3200, w1loc[1] + 1500),\n", - " ha=\"right\",\n", - " va=\"center\",\n", - " zorder=100,\n", - " arrowprops=arrow_props,\n", - " )\n", - " fs.add_annotation(\n", - " ax=ax,\n", - " text=\"Well 2, layer 4\",\n", - " bold=False,\n", - " italic=False,\n", - " xy=w2loc,\n", - " xytext=(w2loc[0] + 3000, w2loc[1]),\n", - " ha=\"left\",\n", - " va=\"center\",\n", - " zorder=100,\n", - " arrowprops=arrow_props,\n", - " )\n", - " ax.set_ylabel(\"y-coordinate, in meters\")\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " fs.heading(ax, letter=\"A\", heading=\"Map view\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " ax = fig.add_subplot(gs[0:5, 6:])\n", - " mm = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 8})\n", - " mm.plot_grid(lw=0.5, color=\"0.5\")\n", - " # items for legend\n", - " mm.ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"green\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"Recharge\",\n", - " )\n", - " mm.ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"red\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"Well\",\n", - " )\n", - " mm.ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"blue\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"Constant head\",\n", - " )\n", - " mm.ax.plot(\n", - " -1000,\n", - " -1000,\n", - " \"s\",\n", - " ms=5,\n", - " color=\"0.75\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " label=\"Inactive\",\n", - " )\n", - " mm.ax.plot(\n", - " [-1000, -1001],\n", - " [-1000, -1000],\n", - " color=\"orange\",\n", - " lw=1.5,\n", - " label=\"Cross-section line\",\n", - " )\n", - " # aquifer coloring\n", - " ax.fill_between([0, dx.sum()], y1=150, y2=-100, color=\"cyan\", alpha=0.5)\n", - " ax.fill_between([0, dx.sum()], y1=-100, y2=-150, color=\"#D2B48C\", alpha=0.5)\n", - " ax.fill_between([0, dx.sum()], y1=-150, y2=-350, color=\"#00BFFF\", alpha=0.5)\n", - " # well coloring\n", - " ax.fill_between([dx.cumsum()[8], dx.cumsum()[9]], y1=50, y2=-100, color=\"red\", lw=0)\n", - " # labels\n", - " fs.add_text(\n", - " ax=ax,\n", - " transform=False,\n", - " bold=False,\n", - " italic=False,\n", - " x=300,\n", - " y=-97,\n", - " text=\"Upper aquifer\",\n", - " va=\"bottom\",\n", - " ha=\"left\",\n", - " fontsize=9,\n", - " )\n", - " fs.add_text(\n", - " ax=ax,\n", - " transform=False,\n", - " bold=False,\n", - " italic=False,\n", - " x=300,\n", - " y=-147,\n", - " text=\"Confining unit\",\n", - " va=\"bottom\",\n", - " ha=\"left\",\n", - " fontsize=9,\n", - " )\n", - " fs.add_text(\n", - " ax=ax,\n", - " transform=False,\n", - " bold=False,\n", - " italic=False,\n", - " x=300,\n", - " y=-347,\n", - " text=\"Lower aquifer\",\n", - " va=\"bottom\",\n", - " ha=\"left\",\n", - " fontsize=9,\n", - " )\n", - " fs.add_text(\n", - " ax=ax,\n", - " transform=False,\n", - " bold=False,\n", - " italic=False,\n", - " x=29850,\n", - " y=53,\n", - " text=\"Layer 1\",\n", - " va=\"bottom\",\n", - " ha=\"right\",\n", - " fontsize=9,\n", - " )\n", - " fs.add_text(\n", - " ax=ax,\n", - " transform=False,\n", - " bold=False,\n", - " italic=False,\n", - " x=29850,\n", - " y=-97,\n", - " text=\"Layer 2\",\n", - " va=\"bottom\",\n", - " ha=\"right\",\n", - " fontsize=9,\n", - " )\n", - " fs.add_text(\n", - " ax=ax,\n", - " transform=False,\n", - " bold=False,\n", - " italic=False,\n", - " x=29850,\n", - " y=-147,\n", - " text=\"Layer 3\",\n", - " va=\"bottom\",\n", - " ha=\"right\",\n", - " fontsize=9,\n", - " )\n", - " fs.add_text(\n", - " ax=ax,\n", - " transform=False,\n", - " bold=False,\n", - " italic=False,\n", - " x=29850,\n", - " y=-347,\n", - " text=\"Layer 4\",\n", - " va=\"bottom\",\n", - " ha=\"right\",\n", - " fontsize=9,\n", - " )\n", - " ax.plot(\n", - " hxloc,\n", - " hsxs0,\n", - " lw=0.75,\n", - " color=\"black\",\n", - " ls=\"dotted\",\n", - " label=\"Steady-state\\nwater level\",\n", - " )\n", - " ax.plot(\n", - " hxloc,\n", - " hsxs1,\n", - " lw=0.75,\n", - " color=\"black\",\n", - " ls=\"dashed\",\n", - " label=\"Water-level at the end\\nof stress-period 2\",\n", - " )\n", - " ax.set_ylabel(\"Elevation, in meters\")\n", - " ax.set_xlabel(\"x-coordinate along model row 9, in meters\")\n", - " fs.graph_legend(\n", - " mm.ax,\n", - " ncol=2,\n", - " bbox_to_anchor=(0.5, -0.6),\n", - " borderaxespad=0,\n", - " frameon=False,\n", - " loc=\"lower center\",\n", - " )\n", - " fs.heading(ax, letter=\"B\", heading=\"Cross-section view\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "b263f12f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the stresses" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7b5dc986", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_stresses(sim, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - " name = sim.name\n", - "\n", - " cd = get_csub_observations(sim)\n", - " tmax = cd[\"totim\"][-1]\n", - "\n", - " fig, axes = plt.subplots(\n", - " ncols=1,\n", - " nrows=4,\n", - " figsize=figure_size,\n", - " sharex=True,\n", - " constrained_layout=True,\n", - " )\n", - "\n", - " idx = 0\n", - " ax = axes[idx]\n", - " ax.set_xlim(0, tmax)\n", - " ax.set_ylim(110, 150)\n", - " ax.plot(\n", - " cd[\"totim\"],\n", - " cd[\"PC1\"],\n", - " color=\"blue\",\n", - " lw=1,\n", - " label=\"Preconsolidation stress\",\n", - " )\n", - " ax.plot(cd[\"totim\"], cd[\"ES1\"], color=\"red\", lw=1, label=\"Effective stress\")\n", - " fs.heading(ax, letter=\"A\", heading=\"Model layer 1, row 9, column 10\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " idx += 1\n", - " ax = axes[idx]\n", - " ax.set_ylim(185, 205)\n", - " ax.plot(cd[\"totim\"], cd[\"GS1\"], color=\"black\", lw=1)\n", - " fs.heading(ax, letter=\"B\", heading=\"Model layer 1, row 9, column 10\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " idx += 1\n", - " ax = axes[idx]\n", - " ax.set_ylim(270, 310)\n", - " ax.plot(cd[\"totim\"], cd[\"PC2\"], color=\"blue\", lw=1)\n", - " ax.plot(cd[\"totim\"], cd[\"ES2\"], color=\"red\", lw=1)\n", - " fs.heading(ax, letter=\"C\", heading=\"Model layer 2, row 9, column 10\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " idx += 1\n", - " ax = axes[idx]\n", - " ax.set_ylim(495, 515)\n", - " ax.plot(\n", - " [-100, -50],\n", - " [-100, -100],\n", - " color=\"blue\",\n", - " lw=1,\n", - " label=\"Preconsolidation stress\",\n", - " )\n", - " ax.plot([-100, -50], [-100, -100], color=\"red\", lw=1, label=\"Effective stress\")\n", - " ax.plot(cd[\"totim\"], cd[\"GS2\"], color=\"black\", lw=1, label=\"Geostatic stress\")\n", - " fs.graph_legend(ax, ncol=3, loc=\"upper center\")\n", - " fs.heading(ax, letter=\"D\", heading=\"Model layer 2, row 9, column 10\")\n", - " fs.remove_edge_ticks(ax)\n", - " ax.set_xlabel(\"Simulation time, in years\")\n", - " ax.set_ylabel(\" \")\n", - "\n", - " ax = fig.add_subplot(111, frame_on=False, xticks=[], yticks=[])\n", - " ax.set_ylabel(\"Stress, in meters of water\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{name}-01{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e60e7517", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_compaction(sim, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - " name = sim.name\n", - "\n", - " fig, axes = plt.subplots(\n", - " ncols=2,\n", - " nrows=3,\n", - " figsize=figure_size,\n", - " sharex=True,\n", - " constrained_layout=True,\n", - " )\n", - " axes = axes.flatten()\n", - "\n", - " idx = 0\n", - " ax = axes[idx]\n", - " ax.set_xlim(0, 120)\n", - " ax.set_ylim(0, 1)\n", - " plot_compaction_values(ax, sim, tagbase=plot_tags[idx])\n", - " ht = \"{} {}\".format(\"Interbed compaction\", compaction_heading[0])\n", - " fs.heading(ax, letter=\"A\", heading=ht)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " idx += 1\n", - " ax = axes[idx]\n", - " ax.set_ylim(0, 1)\n", - " plot_compaction_values(ax, sim, tagbase=plot_tags[idx])\n", - " fs.graph_legend(ax, ncol=2, loc=\"upper center\")\n", - " ht = \"{} {}\".format(\"Interbed compaction\", compaction_heading[1])\n", - " fs.heading(ax, letter=\"B\", heading=ht)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " idx += 1\n", - " ax = axes[idx]\n", - " ax.set_ylim(0, 1)\n", - " plot_compaction_values(ax, sim, tagbase=plot_tags[idx])\n", - " ht = \"{} {}\".format(\"Coarse-grained compaction\", compaction_heading[0])\n", - " fs.heading(ax, letter=\"C\", heading=ht)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " idx += 1\n", - " ax = axes[idx]\n", - " ax.set_ylim(0, 1)\n", - " plot_compaction_values(ax, sim, tagbase=plot_tags[idx])\n", - " ht = \"{} {}\".format(\"Coarse-grained compaction\", compaction_heading[1])\n", - " fs.heading(ax, letter=\"D\", heading=ht)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " idx += 1\n", - " ax = axes[idx]\n", - " ax.set_ylim(0, 1)\n", - " plot_compaction_values(ax, sim, tagbase=plot_tags[idx])\n", - " ht = \"{} {}\".format(\"Total compaction\", compaction_heading[0])\n", - " fs.heading(ax, letter=\"E\", heading=ht)\n", - " fs.remove_edge_ticks(ax)\n", - " ax.set_ylabel(\" \")\n", - " ax.set_xlabel(\" \")\n", - "\n", - " idx += 1\n", - " ax = axes.flat[idx]\n", - " ax.set_ylim(0, 1)\n", - " plot_compaction_values(ax, sim, tagbase=plot_tags[idx])\n", - " ht = \"{} {}\".format(\"Total compaction\", compaction_heading[1])\n", - " fs.heading(ax, letter=\"F\", heading=ht)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " ax = fig.add_subplot(111, frame_on=False, xticks=[], yticks=[])\n", - " ax.set_ylabel(\n", - " \"Downward vertical displacement at the top of the model layer, in meters\"\n", - " )\n", - " ax.set_xlabel(\"Simulation time, in years\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{name}-02{config.figure_ext}\")\n", - " if not silent:\n", - " print(f\"saving...'{fpth}'\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "35ae4d0f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bbfbf685", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " plot_grid(sim, silent=silent)\n", - " plot_stresses(sim, silent=silent)\n", - " plot_compaction(sim, silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "673b0471", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "07d7b636", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " sim = build_model()\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2302dc62", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation()" - ] - }, - { - "cell_type": "markdown", - "id": "19ef4d65", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bdaef32b", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### One-dimensional compaction in a three-dimensional flow field\n", - "\n", - " simulation()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-curvilinear-90.ipynb b/notebooks/ex-gwf-curvilinear-90.ipynb deleted file mode 100644 index 630cfb47..00000000 --- a/notebooks/ex-gwf-curvilinear-90.ipynb +++ /dev/null @@ -1,945 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6fbb12a7", - "metadata": {}, - "source": [ - "## Curvilinear example\n", - "\n", - "This example, ex-gwf-curvilinear, shows how the MODFLOW 6 DISV Package\n", - "can be used to simulate a curvilinear models.\n", - "\n", - "The example corresponds to Figure 3d (lower-right) in:\n", - " Romero, D. M., & Silver, S. E. (2006).\n", - " Grid cell distortion and MODFLOW's integrated finite difference\n", - " numerical solution. Groundwater, 44(6), 797-802.\n", - "\n", - "And the numerical result is compared against the analytical solution\n", - "presented in Equation 5.4 of\n", - " Crank, J. (1975). The mathematics of diffusion.\n", - " Oxford. England: Clarendon.\n", - "The equation is transformed here to use head instead of concentration" - ] - }, - { - "cell_type": "markdown", - "id": "23f28237", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c97aca2b", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import flopy\n", - "from math import sqrt" - ] - }, - { - "cell_type": "markdown", - "id": "00936682", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "75744a52", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "111bd326", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "448dafee", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "967acdf9", - "metadata": {}, - "outputs": [], - "source": [ - "from disv_curvilinear_builder import disv_curvilinear_builder" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "57faafd6", - "metadata": {}, - "outputs": [], - "source": [ - "def analytical_model(r1, h1, r2, h2, r):\n", - " # Analytical model from Equation 5.4 of\n", - " # Crank, J. (1975). The mathematics of diffusion.\n", - " # Oxford. England: Clarendon.\n", - " num = h1 * np.log(r2 / r) + h2 * np.log(r / r1)\n", - " den = np.log(r2 / r1)\n", - " return num / den" - ] - }, - { - "cell_type": "markdown", - "id": "9a6dc31f", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "16fc9c8d", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size_grid = (6, 6)\n", - "figure_size_head = (7, 6)\n", - "figure_size_obsv = (6, 6)" - ] - }, - { - "cell_type": "markdown", - "id": "4a793403", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "403010a1", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "24670afe", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a4d25235", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-curve-90\"" - ] - }, - { - "cell_type": "markdown", - "id": "12722e64", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ec37262a", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "4f63d223", - "metadata": {}, - "source": [ - "Table Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "16aa3d02", - "metadata": {}, - "outputs": [], - "source": [ - "_ = \"Steady-State\" # Simulation Type\n", - "nper = 1 # Number of periods\n", - "_ = 1 # Number of time steps" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f03de6d8", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 1 # Number of layers\n", - "nradial = 16 # Number of radial direction cells (radial bands)\n", - "ncol = 18 # Number of columns in radial band (ncol)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "22f46585", - "metadata": {}, - "outputs": [], - "source": [ - "_ = \"0$^{\\circ}$\" # Angle of column 1 boundary\n", - "_ = \"90$^{\\circ}$\" # Angle of column ncol boundary\n", - "_ = \"5$^{\\circ}$\" # Angle width of each column" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "35161c9d", - "metadata": {}, - "outputs": [], - "source": [ - "r_inner = 4 # Model inner radius ($ft$)\n", - "r_outer = 20 # Model outer radius ($ft$)\n", - "r_width = 1 # Model radial band width ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "60095e34", - "metadata": {}, - "outputs": [], - "source": [ - "surface_elevation = 10.0 # Top of the model ($ft$)\n", - "model_base = 0.0 # Base of the model ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "484c3c41", - "metadata": {}, - "outputs": [], - "source": [ - "Tran = 0.19 # Horizontal transmissivity ($ft^2/day$)\n", - "k11 = 0.019 # Horizontal hydraulic conductivity ($ft/day$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5b2b7f67", - "metadata": {}, - "outputs": [], - "source": [ - "bc0 = 10 # Inner Constant Head Boundary ($ft$)\n", - "_ = \"3.334\" # Outer Constant Head Boundary ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6322e007", - "metadata": {}, - "outputs": [], - "source": [ - "# Input specified in table as text\n", - "bc1 = bc0 / 3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "87da43f5", - "metadata": {}, - "outputs": [], - "source": [ - "angle_start = 0\n", - "angle_stop = 90\n", - "angle_step = 5" - ] - }, - { - "cell_type": "markdown", - "id": "6852dcbb", - "metadata": {}, - "source": [ - "Radius for each radial band.\n", - " First value is inner radius, the remaining are outer radii" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fc74e876", - "metadata": {}, - "outputs": [], - "source": [ - "radii = np.arange(r_inner, r_outer + r_width, r_width)" - ] - }, - { - "cell_type": "markdown", - "id": "7ea3365b", - "metadata": {}, - "source": [ - "Get the curvilinear model properties and vertices" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "edb557ac", - "metadata": {}, - "outputs": [], - "source": [ - "curvlin = disv_curvilinear_builder(\n", - " nlay,\n", - " radii,\n", - " angle_start,\n", - " angle_stop,\n", - " angle_step,\n", - " surface_elevation=surface_elevation,\n", - " layer_thickness=surface_elevation,\n", - " single_center_cell=False,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "ded07b51", - "metadata": {}, - "source": [ - "Constant head boundary condition\n", - "Constant head is located along the innermost radial band (rad = 0)\n", - "and outermost radial band (rad = nradial-1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cf7321fe", - "metadata": {}, - "outputs": [], - "source": [ - "chd_inner = []\n", - "chd_outer = []\n", - "for lay in range(nlay):\n", - " for node in curvlin.iter_radial_nodes(rad=0):\n", - " chd_inner.append([(lay, node), bc0])\n", - "for lay in range(nlay):\n", - " for node in curvlin.iter_radial_nodes(rad=nradial - 1):\n", - " chd_outer.append([(lay, node), bc1])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a1a757ae", - "metadata": {}, - "outputs": [], - "source": [ - "chd_inner = {sp: chd_inner for sp in range(nper)}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1dc38591", - "metadata": {}, - "outputs": [], - "source": [ - "chd_outer = {sp: chd_outer for sp in range(nper)}" - ] - }, - { - "cell_type": "markdown", - "id": "0c385b46", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation is steady state so setup only a one day stress period." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2686cb33", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((1.0, 1, 1),)" - ] - }, - { - "cell_type": "markdown", - "id": "e7d9252d", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "25db3e55", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 300\n", - "hclose = 1e-4\n", - "rclose = 1e-4" - ] - }, - { - "cell_type": "markdown", - "id": "6ed6debc", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 Curvilinear Model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5aade551", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(name):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " complexity=\"complex\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " )\n", - "\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - "\n", - " # **curvlin is an alias for **curvlin.disv_kw\n", - " disv = flopy.mf6.ModflowGwfdisv(\n", - " gwf, length_units=length_units, **curvlin\n", - " )\n", - "\n", - " npf = flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " k=k11,\n", - " k33=k11,\n", - " save_flows=True,\n", - " save_specific_discharge=True,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=0,\n", - " steady_state=True,\n", - " save_flows=True,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfic(gwf, strt=surface_elevation)\n", - "\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chd_inner,\n", - " pname=\"CHD-INNER\",\n", - " filename=f\"{sim_name}.inner.chd\",\n", - " save_flows=True,\n", - " )\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chd_outer,\n", - " pname=\"CHD-OUTER\",\n", - " filename=f\"{sim_name}.outer.chd\",\n", - " save_flows=True,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " budget_filerecord=f\"{name}.cbc\",\n", - " head_filerecord=f\"{name}.hds\",\n", - " headprintrecord=[\n", - " (\"COLUMNS\", nradial, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " printrecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " filename=f\"{name}.oc\",\n", - " )\n", - "\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "300a237b", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d7f8ec4d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "b6ed4d2c", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the curvilinear model.\n", - "True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fd631fbb", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(\"\\n\".join(buff))\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "8fe64638", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the curvilinear model grid." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ae626c82", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(sim, verbose=False):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=figure_size_grid)\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " pmv.plot_grid()\n", - " pmv.plot_bc(name=\"CHD-INNER\", alpha=0.75, color=\"blue\")\n", - " pmv.plot_bc(name=\"CHD-OUTER\", alpha=0.75, color=\"blue\")\n", - " ax.set_xlabel(\"x position (ft)\")\n", - " ax.set_ylabel(\"y position (ft)\")\n", - " for i, (x, y) in enumerate(\n", - " zip(gwf.modelgrid.xcellcenters, gwf.modelgrid.ycellcenters)\n", - " ):\n", - " ax.text(\n", - " x,\n", - " y,\n", - " f\"{i + 1}\",\n", - " fontsize=6,\n", - " horizontalalignment=\"center\",\n", - " verticalalignment=\"center\",\n", - " )\n", - " v = gwf.disv.vertices.array\n", - " ax.plot(v[\"xv\"], v[\"yv\"], \"yo\")\n", - " for i in range(v.shape[0]):\n", - " x, y = v[\"xv\"][i], v[\"yv\"][i]\n", - " ax.text(\n", - " x,\n", - " y,\n", - " f\"{i + 1}\",\n", - " fontsize=5,\n", - " color=\"red\",\n", - " horizontalalignment=\"center\",\n", - " verticalalignment=\"center\",\n", - " )\n", - "\n", - " fig.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\"\n", - " )\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "252b3062", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the curvilinear model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dae419e7", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_head(sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=figure_size_head)\n", - "\n", - " head = gwf.output.head().get_data()[:, 0, :]\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " gwf.output.budget().get_data(text=\"DATA-SPDIS\", totim=1.0)[0],\n", - " gwf,\n", - " )\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " cb = pmv.plot_array(head, cmap=\"jet\", vmin=0.0, vmax=head.max())\n", - " pmv.plot_vector(\n", - " qx,\n", - " qy,\n", - " normalize=False,\n", - " color=\"0.75\",\n", - " )\n", - " cbar = plt.colorbar(cb, shrink=0.25)\n", - " cbar.ax.set_xlabel(r\"Head, ($ft$)\")\n", - " ax.set_xlabel(\"x position (ft)\")\n", - " ax.set_ylabel(\"y position (ft)\")\n", - "\n", - " fig.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\", \"figures\", f\"{sim_name}-head{config.figure_ext}\"\n", - " )\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ac29034c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_analytical(sim, verbose=False):\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " head = gwf.output.head().get_data()[:, 0, :]\n", - "\n", - " col = ncol // 2 - 1 # Get head along middle of model\n", - "\n", - " head = [head[0, curvlin.get_node(rad, col)] for rad in range(nradial)]\n", - "\n", - " xrad = [0.5 * (radii[r - 1] + radii[r]) for r in range(1, nradial + 1)]\n", - "\n", - " analytical = [head[0]]\n", - " r1 = xrad[0]\n", - " r2 = xrad[-1]\n", - " h1 = bc0\n", - " h2 = bc1\n", - " for rad in range(2, nradial):\n", - " r = 0.5 * (radii[rad - 1] + radii[rad])\n", - " analytical.append(analytical_model(r1, h1, r2, h2, r))\n", - " analytical.append(head[-1])\n", - "\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - "\n", - " obs_fig = \"obs-head\"\n", - " fig = plt.figure(figsize=figure_size_obsv)\n", - " ax = fig.add_subplot()\n", - " ax.set_xlabel(\"Radial distance (ft)\")\n", - " ax.set_ylabel(\"Head (ft)\")\n", - " ax.plot(xrad, head, \"ob\", label=\"MF6 Solution\", markerfacecolor=\"none\")\n", - " ax.plot(xrad, analytical, \"-b\", label=\"Analytical Solution\")\n", - "\n", - " fs.graph_legend(ax)\n", - "\n", - " fig.tight_layout()\n", - "\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}-{}{}\".format(sim_name, obs_fig, config.figure_ext),\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "dfd99880", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "40b0ddab", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_results(silent=True):\n", - " if not config.plotModel:\n", - " return\n", - "\n", - " if silent:\n", - " verbosity_level = 0\n", - " else:\n", - " verbosity_level = 1\n", - "\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level\n", - " )\n", - "\n", - " verbose = not silent\n", - "\n", - " if config.plotModel:\n", - " plot_grid(sim, verbose)\n", - " plot_head(sim)\n", - " plot_analytical(sim, verbose)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c4a77fd1", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def calculate_model_error():\n", - " if not config.runModel:\n", - " return\n", - "\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=0\n", - " )\n", - "\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " head = gwf.output.head().get_data()[0, 0, :]\n", - "\n", - " xrad = [0.5 * (radii[r - 1] + radii[r]) for r in range(1, nradial + 1)]\n", - "\n", - " analytical = [head[0]]\n", - " r1 = xrad[0]\n", - " r2 = xrad[-1]\n", - " h1 = bc0\n", - " h2 = bc1\n", - " for rad in range(2, nradial):\n", - " r = 0.5 * (radii[rad - 1] + radii[rad])\n", - " analytical.append(analytical_model(r1, h1, r2, h2, r))\n", - " analytical.append(head[-1])\n", - "\n", - " dim = len(head)\n", - " rel = 0.0\n", - " sse = 0.0\n", - " for rad in range(nradial):\n", - " asol = analytical[rad]\n", - " for node in curvlin.iter_radial_nodes(rad):\n", - " diff = head[node] - asol\n", - " rel += abs(diff / asol)\n", - " sse += diff**2\n", - " # for x, y in zip(head, analytical):\n", - " # mae += abs(x-y)\n", - " # sse += (x-y)**2\n", - " rel /= dim\n", - " rmse = sqrt(sse / dim)\n", - " return rel, rmse" - ] - }, - { - "cell_type": "markdown", - "id": "439217b0", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the curvilinear model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c103a8e", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " # key = list(parameters.keys())[idx]\n", - " # params = parameters[key].copy()\n", - "\n", - " sim = build_model(sim_name)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, \"could not run...{}\".format(sim_name)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "942f075a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "id": "8de52eaf", - "metadata": {}, - "source": [ - "### Curvilinear Example" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a37bebca", - "metadata": {}, - "outputs": [], - "source": [ - "# MF6 Curvilinear Model\n", - "simulation()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a1620f9c", - "metadata": {}, - "outputs": [], - "source": [ - "# Solve analytical and plot results with MF6 results\n", - "plot_results()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "be1b6b29", - "metadata": {}, - "outputs": [], - "source": [ - "rel_error, rmse = calculate_model_error()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-curvilinear.ipynb b/notebooks/ex-gwf-curvilinear.ipynb deleted file mode 100644 index e42bbb67..00000000 --- a/notebooks/ex-gwf-curvilinear.ipynb +++ /dev/null @@ -1,1150 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e7387c17", - "metadata": {}, - "source": [ - "## Curvilinear example\n", - "\n", - "This example, ex-gwf-curvilinear, shows how the MODFLOW 6 DISV Package\n", - "can be used to simulate a multipart curvilinear models.\n", - "\n", - "The example reproduces the hypothetical model grid presented in Figure 6 of\n", - " Romero, D. M., & Silver, S. E. (2006).\n", - " Grid cell distortion and MODFLOW's integrated finite difference\n", - " numerical solution. Groundwater, 44(6), 797-802.\n", - "\n", - "The hypothetical, curvilinear grid is built in three parts:\n", - " 1) 180 to 270 degree curvilinear grid\n", - " 2) 16 by 18 structured grid\n", - " 3) 90 to 0 degree curvilinear grid\n", - "that are merged, as 1-2-3, to make the final multipart curvilinear grid." - ] - }, - { - "cell_type": "markdown", - "id": "870d4839", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bff9e573", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import flopy\n", - "from math import sqrt" - ] - }, - { - "cell_type": "markdown", - "id": "a8492a18", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "53678b11", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "4ee046e9", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b1f99c5", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "28abf40a", - "metadata": {}, - "outputs": [], - "source": [ - "from DisvCurvilinearBuilder import DisvCurvilinearBuilder\n", - "from DisvStructuredGridBuilder import DisvStructuredGridBuilder\n", - "from DisvGridMerger import DisvGridMerger" - ] - }, - { - "cell_type": "markdown", - "id": "02021d01", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f4ec118b", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size_grid_com = (6.5, 2.5)\n", - "figure_size_grid = (6.5, 3)\n", - "figure_size_head = (6.5, 2.5)" - ] - }, - { - "cell_type": "markdown", - "id": "b5eebf7b", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a929726d", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "fba2d505", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "acfb54e7", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-curvilin\"" - ] - }, - { - "cell_type": "markdown", - "id": "0103f888", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f07988f2", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "c70ea919", - "metadata": {}, - "source": [ - "Table Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "272e5ab9", - "metadata": {}, - "outputs": [], - "source": [ - "_ = \"Steady-State\" # Simulation Type\n", - "nper = 1 # Number of periods\n", - "_ = 1 # Number of time steps" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "99883d73", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 1 # Number of layers\n", - "_ = 864 # Number cells per layer" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c712faf3", - "metadata": {}, - "outputs": [], - "source": [ - "surface_elevation = 10.0 # Top of the model ($ft$)\n", - "model_base = 0.0 # Base of the model ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8a9ddd01", - "metadata": {}, - "outputs": [], - "source": [ - "Tran = 0.19 # Horizontal transmissivity ($ft^2/day$)\n", - "k11 = 0.019 # Horizontal hydraulic conductivity ($ft/day$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bbfd6d3a", - "metadata": {}, - "outputs": [], - "source": [ - "bc0 = 10 # Left constant head boundary ($ft$)\n", - "_ = \"3.334\" # Right constant head boundary ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8cd3d333", - "metadata": {}, - "outputs": [], - "source": [ - "_ = \" \" # --- Left Curvilinear Grid Properties ---" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c728d313", - "metadata": {}, - "outputs": [], - "source": [ - "_ = \"180\" # Degree angle of column 1 boundary\n", - "_ = \"270\" # Degree angle of column ncol boundary\n", - "_ = \"5\" # Degree angle width of each column" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e6ed6c0e", - "metadata": {}, - "outputs": [], - "source": [ - "nradial1 = 16 # Number of radial direction cells (radial bands)\n", - "_ = 18 # Number of columns in radial band (ncol)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2f6569b5", - "metadata": {}, - "outputs": [], - "source": [ - "r_inner1 = 4 # Grid inner radius ($ft$)\n", - "r_outer1 = 20 # Grid outer radius ($ft$)\n", - "r_width1 = 1 # Radial band width ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6303d7ed", - "metadata": {}, - "outputs": [], - "source": [ - "_ = \" \" # --- Middle Structured Grid Properties ---\n", - "nrow = 16 # Number of rows\n", - "ncol = 18 # Number of columns\n", - "row_width = 1 # Row width ($ft$)\n", - "col_width = 1 # Column width ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "70f3bc3e", - "metadata": {}, - "outputs": [], - "source": [ - "_ = \" \" # --- Right Curvilinear Grid Properties ---" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "33bf56cf", - "metadata": {}, - "outputs": [], - "source": [ - "_ = \"0\" # Degree angle of column 1 boundary\n", - "_ = \"90\" # Degree angle of column ncol boundary\n", - "_ = \"5\" # Degree angle width of each column" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1d0bd439", - "metadata": {}, - "outputs": [], - "source": [ - "nradial2 = 16 # Number of radial direction cells (radial bands)\n", - "_ = 18 # Number of columns in radial band (ncol)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f4193f1c", - "metadata": {}, - "outputs": [], - "source": [ - "r_inner2 = 4 # Grid inner radius ($ft$)\n", - "r_outer2 = 20 # Grid outer radius ($ft$)\n", - "r_width2 = 1 # Grid radial band width ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "60b3b073", - "metadata": {}, - "outputs": [], - "source": [ - "# Set up input that is not used in the table\n", - "# Left Curvilinear Model Angle and discretization\n", - "angle_start1 = 180\n", - "angle_stop1 = 270\n", - "angle_step1 = 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8225d5eb", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "# Right Curvilinear Model Angles\n", - "angle_start2 = 0\n", - "angle_stop2 = 90\n", - "angle_step2 = 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "34f97b6c", - "metadata": {}, - "outputs": [], - "source": [ - "# Right Curvilinear Model Boundary Condition\n", - "bc1 = bc0 / 3" - ] - }, - { - "cell_type": "markdown", - "id": "58ae650d", - "metadata": {}, - "source": [ - "Radius for each radial band.\n", - " First value is inner radius, the remaining are outer radii" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5b39ee7c", - "metadata": {}, - "outputs": [], - "source": [ - "radii = np.arange(r_inner1, r_outer1 + r_width1, r_width1)" - ] - }, - { - "cell_type": "markdown", - "id": "09a2a5db", - "metadata": {}, - "source": [ - "Get the curvilinear model properties and vertices" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b67bf5f6", - "metadata": {}, - "outputs": [], - "source": [ - "# Left Curvilinear Model\n", - "curvlin1 = DisvCurvilinearBuilder(\n", - " nlay,\n", - " radii,\n", - " angle_start1,\n", - " angle_stop1,\n", - " angle_step1,\n", - " surface_elevation=surface_elevation,\n", - " layer_thickness=surface_elevation,\n", - " single_center_cell=False,\n", - " origin_x=radii[-1], # Shift to make merged image have (0, 0) for origin\n", - " origin_y=radii[-1] + radii[0],\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fda844cd", - "metadata": {}, - "outputs": [], - "source": [ - "# Middle Structured Grid Model\n", - "rectgrid = DisvStructuredGridBuilder(\n", - " nlay,\n", - " nrow,\n", - " ncol,\n", - " row_width,\n", - " col_width,\n", - " surface_elevation,\n", - " surface_elevation,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "72c74782", - "metadata": {}, - "outputs": [], - "source": [ - "# Right Curvilinear Model\n", - "curvlin2 = DisvCurvilinearBuilder(\n", - " nlay,\n", - " radii,\n", - " angle_start2,\n", - " angle_stop2,\n", - " angle_step2,\n", - " surface_elevation=surface_elevation,\n", - " layer_thickness=surface_elevation,\n", - " single_center_cell=False,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "7149ad4c", - "metadata": {}, - "source": [ - "Combine the three models into one new vertex grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fcb60a31", - "metadata": {}, - "outputs": [], - "source": [ - "grid_merger = DisvGridMerger()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f3b3a597", - "metadata": {}, - "outputs": [], - "source": [ - "grid_merger.add_grid(\"curvlin1\", curvlin1)\n", - "grid_merger.add_grid(\"rectgrid\", rectgrid)\n", - "grid_merger.add_grid(\"curvlin2\", curvlin2)" - ] - }, - { - "cell_type": "markdown", - "id": "1fa6e5cc", - "metadata": {}, - "source": [ - "# Plot individual grids to find vertex connections\n", - "grid_merger.plot_grid(\"curvlin1\", show=False)\n", - "grid_merger.plot_grid(\"rectgrid\", show=False)\n", - "grid_merger.plot_grid(\"curvlin2\", show=False)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2d114c25", - "metadata": {}, - "outputs": [], - "source": [ - "# Setup vertex connections between model grids\n", - "grid_merger.set_vertex_connection(\"curvlin1\", \"rectgrid\", 19 - 1, 1 - 1)\n", - "grid_merger.set_vertex_connection(\"rectgrid\", \"curvlin2\", 19 - 1, 323 - 1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b38d44b5", - "metadata": {}, - "outputs": [], - "source": [ - "# Merge grids into one single model grid\n", - "grid_merger.merge_grids()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c031ceb8", - "metadata": {}, - "outputs": [], - "source": [ - "# Shift first curvilinear grid for plotting against the orgin.\n", - "# (Note, grid_merger no longer needs curvlin1)\n", - "curvlin1.change_origin(0.0, 0.0)" - ] - }, - { - "cell_type": "markdown", - "id": "2748a680", - "metadata": {}, - "source": [ - "grid_merger.plot_grid(show=False, figsize=(23, 10))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e128937", - "metadata": {}, - "outputs": [], - "source": [ - "# Constant head boundary condition\n", - "# Constant head is located along column 1 of curvlin1\n", - "# and column 1 of curvlin2\n", - "chd_left = []\n", - "chd_right = []\n", - "for lay in range(nlay):\n", - " for cellid_old in curvlin1.iter_column_cellid(col=0):\n", - " node = grid_merger.get_merged_cell2d(\"curvlin1\", cellid_old)\n", - " chd_left.append([(lay, node), bc0])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7699a86f", - "metadata": {}, - "outputs": [], - "source": [ - "for lay in range(nlay):\n", - " for cellid_old in curvlin2.iter_column_cellid(col=0):\n", - " node = grid_merger.get_merged_cell2d(\"curvlin2\", cellid_old)\n", - " chd_right.append([(lay, node), bc1])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a96e91d4", - "metadata": {}, - "outputs": [], - "source": [ - "chd_left = {sp: chd_left for sp in range(nper)}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "92032846", - "metadata": {}, - "outputs": [], - "source": [ - "chd_right = {sp: chd_right for sp in range(nper)}" - ] - }, - { - "cell_type": "markdown", - "id": "d5d93eba", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation is steady state so setup only a one day stress period." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e2746aaf", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((1.0, 1, 1),)" - ] - }, - { - "cell_type": "markdown", - "id": "4d3f3480", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6bdedada", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 300\n", - "hclose = 1e-4\n", - "rclose = 1e-4" - ] - }, - { - "cell_type": "markdown", - "id": "94bf2f05", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 Curvilinear Model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aed4b4c1", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(name):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " complexity=\"complex\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " )\n", - "\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - "\n", - " disv = flopy.mf6.ModflowGwfdisv(\n", - " gwf, length_units=length_units, **grid_merger.get_disv_kwargs()\n", - " )\n", - "\n", - " npf = flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " k=k11,\n", - " k33=k11,\n", - " save_flows=True,\n", - " save_specific_discharge=True,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=0,\n", - " steady_state=True,\n", - " save_flows=True,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfic(gwf, strt=surface_elevation)\n", - "\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chd_left,\n", - " pname=\"CHD-LEFT\",\n", - " filename=f\"{sim_name}.left.chd\",\n", - " save_flows=True,\n", - " )\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chd_right,\n", - " pname=\"CHD-RIGHT\",\n", - " filename=f\"{sim_name}.right.chd\",\n", - " save_flows=True,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " budget_filerecord=f\"{name}.cbc\",\n", - " head_filerecord=f\"{name}.hds\",\n", - " headprintrecord=[\n", - " (\n", - " \"COLUMNS\",\n", - " curvlin1.ncol + ncol + curvlin2.ncol,\n", - " \"WIDTH\",\n", - " 15,\n", - " \"DIGITS\",\n", - " 6,\n", - " \"GENERAL\",\n", - " )\n", - " ],\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " printrecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " filename=f\"{name}.oc\",\n", - " )\n", - "\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "98502c78", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "934b1c95", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "f32e1e9b", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the curvilinear model.\n", - "True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a8733bd0", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(\"\\n\".join(buff))\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "6af7032d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the curvilinear model grid." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3a682734", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(sim, verbose=False):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=figure_size_grid)\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " pmv.plot_grid()\n", - " pmv.plot_bc(name=\"CHD-LEFT\", alpha=0.75, color=\"blue\")\n", - " pmv.plot_bc(name=\"CHD-RIGHT\", alpha=0.75, color=\"blue\")\n", - " ax.set_xlabel(\"x position (ft)\")\n", - " ax.set_ylabel(\"y position (ft)\")\n", - " for i, (x, y) in enumerate(\n", - " zip(gwf.modelgrid.xcellcenters, gwf.modelgrid.ycellcenters)\n", - " ):\n", - " ax.text(\n", - " x,\n", - " y,\n", - " f\"{i + 1}\",\n", - " fontsize=3,\n", - " horizontalalignment=\"center\",\n", - " verticalalignment=\"center\",\n", - " )\n", - " v = gwf.disv.vertices.array\n", - " vert_size = 2\n", - " ax.plot(v[\"xv\"], v[\"yv\"], \"yo\", markersize=vert_size)\n", - " for i in range(v.shape[0]):\n", - " x, y = v[\"xv\"][i], v[\"yv\"][i]\n", - " ax.text(\n", - " x,\n", - " y,\n", - " f\"{i + 1}\",\n", - " fontsize=vert_size,\n", - " color=\"red\",\n", - " horizontalalignment=\"center\",\n", - " verticalalignment=\"center\",\n", - " )\n", - "\n", - " fig.tight_layout()\n", - "\n", - " # Save components that made up the main grid\n", - " fig2, ax2 = plt.subplots(\n", - " 1,\n", - " 3,\n", - " figsize=figure_size_grid_com,\n", - " )\n", - "\n", - " curvlin1.plot_grid(\n", - " \"Left Curvilinear Grid\",\n", - " ax_override=ax2[0],\n", - " cell_dot=False,\n", - " cell_num=False,\n", - " vertex_dot=True,\n", - " vertex_num=False,\n", - " vertex_dot_size=3,\n", - " vertex_dot_color=\"y\",\n", - " )\n", - "\n", - " rectgrid.plot_grid(\n", - " \"Center Rectangular Grid\",\n", - " ax_override=ax2[1],\n", - " cell_dot=False,\n", - " cell_num=False,\n", - " vertex_dot=True,\n", - " vertex_num=False,\n", - " vertex_dot_size=3,\n", - " vertex_dot_color=\"y\",\n", - " )\n", - "\n", - " curvlin2.plot_grid(\n", - " \"Right Curvilinear Grid\",\n", - " ax_override=ax2[2],\n", - " cell_dot=False,\n", - " cell_num=False,\n", - " vertex_dot=True,\n", - " vertex_num=False,\n", - " vertex_dot_size=3,\n", - " vertex_dot_color=\"y\",\n", - " )\n", - "\n", - " for ax_tmp in ax2:\n", - " ax_tmp.set_xlabel(\"x position (ft)\")\n", - " ax_tmp.set_ylabel(\"y position (ft)\")\n", - "\n", - " xshift, yshift = 0.0, 0.0\n", - " for ax_tmp in ax2:\n", - " xmin, xmax = ax_tmp.get_xlim()\n", - " ymin, ymax = ax_tmp.get_ylim()\n", - " if xshift < xmax - xmin:\n", - " xshift = xmax - xmin\n", - " if yshift < ymax - ymin:\n", - " yshift = ymax - ymin\n", - "\n", - " for ax_tmp in ax2:\n", - " xmin, xmax = ax_tmp.get_xlim()\n", - " ymin, ymax = ax_tmp.get_ylim()\n", - " ax_tmp.set_xlim(xmin, xmin + xshift)\n", - " ax_tmp.set_ylim(ymin, ymin + yshift)\n", - "\n", - " ax2[0].annotate(\n", - " \"A\",\n", - " (-0.05, 1.05),\n", - " xycoords=\"axes fraction\",\n", - " fontweight=\"black\",\n", - " fontsize=\"xx-large\",\n", - " )\n", - "\n", - " ax2[1].annotate(\n", - " \"B\",\n", - " (-0.05, 1.05),\n", - " xycoords=\"axes fraction\",\n", - " fontweight=\"black\",\n", - " fontsize=\"xx-large\",\n", - " )\n", - "\n", - " ax2[2].annotate(\n", - " \"C\",\n", - " (-0.05, 1.05),\n", - " xycoords=\"axes fraction\",\n", - " fontweight=\"black\",\n", - " fontsize=\"xx-large\",\n", - " )\n", - "\n", - " fig2.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth, dpi=600)\n", - "\n", - " fpth2 = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-grid-components{config.figure_ext}\",\n", - " )\n", - " fig2.savefig(fpth2, dpi=300)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "52e76f63", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the curvilinear model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b3c88ebe", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_head(sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=figure_size_head)\n", - "\n", - " head = gwf.output.head().get_data()[:, 0, :]\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " gwf.output.budget().get_data(text=\"DATA-SPDIS\", totim=1.0)[0],\n", - " gwf,\n", - " )\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " cb = pmv.plot_array(head, cmap=\"jet\", vmin=0.0, vmax=head.max())\n", - " pmv.plot_vector(\n", - " qx,\n", - " qy,\n", - " normalize=False,\n", - " color=\"0.75\",\n", - " )\n", - " cbar = plt.colorbar(cb, shrink=0.25)\n", - " cbar.ax.set_xlabel(r\"Head, ($ft$)\")\n", - " ax.set_xlabel(\"x position (ft)\")\n", - " ax.set_ylabel(\"y position (ft)\")\n", - "\n", - " fig.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\", \"figures\", f\"{sim_name}-head{config.figure_ext}\"\n", - " )\n", - " fig.savefig(fpth, dpi=300)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "567290b7", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "89c890c5", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(silent=True):\n", - " if not config.plotModel:\n", - " return\n", - "\n", - " if silent:\n", - " verbosity_level = 0\n", - " else:\n", - " verbosity_level = 1\n", - "\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level\n", - " )\n", - "\n", - " verbose = not silent\n", - "\n", - " if config.plotModel:\n", - " plot_grid(sim, verbose)\n", - " plot_head(sim)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "957e7a04", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the curvilinear model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2ee7d508", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " # key = list(parameters.keys())[idx]\n", - " # params = parameters[key].copy()\n", - "\n", - " sim = build_model(sim_name)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, \"could not run...{}\".format(sim_name)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6736d0d2", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "id": "25d36658", - "metadata": {}, - "source": [ - "### Curvilinear Example" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f46cec99", - "metadata": {}, - "outputs": [], - "source": [ - "# MF6 Curvilinear Model\n", - "simulation()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9736775d", - "metadata": {}, - "outputs": [], - "source": [ - "# Solve analytical and plot results with MF6 results\n", - "plot_results()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-disvmesh.ipynb b/notebooks/ex-gwf-disvmesh.ipynb deleted file mode 100644 index 10386d97..00000000 --- a/notebooks/ex-gwf-disvmesh.ipynb +++ /dev/null @@ -1,657 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d9d8b1aa", - "metadata": {}, - "source": [ - "## USG1DISV example\n", - "\n", - "Demonstration of a triangular mesh with the DISV Package to discretize a\n", - "circular island with a radius of 1500 meters. The model has 2 layers and\n", - "uses 2778 vertices (NVERT) to delineate 5240 cells per layer (NCPL).\n", - "General-head boundaries are assigned to model layer 1 for cells outside of\n", - "a 1025 m radius circle. Recharge is applied to the top of the model.\n" - ] - }, - { - "cell_type": "markdown", - "id": "87096657", - "metadata": {}, - "source": [ - "### USG1DISV Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c4e5df81", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c4c813e", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import flopy.utils.cvfdutil\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from flopy.utils.geometry import get_polygon_area\n", - "from flopy.utils.gridintersect import GridIntersect\n", - "from shapely.geometry import Polygon" - ] - }, - { - "cell_type": "markdown", - "id": "53440d1f", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a044fbbe", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "27cbaceb", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "16d550b7", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "f0cdeb33", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a77aee85", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (5, 5)" - ] - }, - { - "cell_type": "markdown", - "id": "189920c6", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3fa0ad4c", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "91a70389", - "metadata": {}, - "outputs": [], - "source": [ - "# Simulation name\n", - "sim_name = \"ex-gwf-disvmesh\"" - ] - }, - { - "cell_type": "markdown", - "id": "cdb8c36a", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "10525bac", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "b589ddd0", - "metadata": {}, - "source": [ - "Table USG1DISV Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c87c64c", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 2 # Number of layers\n", - "top = 0.0 # Top of the model ($m$)\n", - "botm_str = \"-20.0, -40.0\" # Layer bottom elevations ($m$)\n", - "strt = 0.0 # Starting head ($m$)\n", - "icelltype = 0 # Cell conversion type\n", - "k11 = 10.0 # Horizontal hydraulic conductivity ($m/d$)\n", - "k33 = 0.2 # Vertical hydraulic conductivity ($m/d$)\n", - "recharge = 4.0e-3 # Recharge rate ($m/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "0398599e", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation has 1 steady stress period (1 day)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a5dbba54", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [1.0]\n", - "nstp = [1]\n", - "tsmult = [1.0]\n", - "tdis_ds = list(zip(perlen, nstp, tsmult))" - ] - }, - { - "cell_type": "markdown", - "id": "03bc15b9", - "metadata": {}, - "source": [ - "Parse strings into lists" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b7e55a37", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]" - ] - }, - { - "cell_type": "markdown", - "id": "6ad8b42b", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "create the disv grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ecec4132", - "metadata": {}, - "outputs": [], - "source": [ - "def from_argus_export(fname):\n", - " f = open(fname)\n", - " line = f.readline()\n", - " ll = line.split()\n", - " ncells, nverts = ll[0:2]\n", - " ncells = int(ncells)\n", - " nverts = int(nverts)\n", - " verts = np.empty((nverts, 2), dtype=float)\n", - "\n", - " # read the vertices\n", - " f.readline()\n", - " for ivert in range(nverts):\n", - " line = f.readline()\n", - " ll = line.split()\n", - " c, iv, x, y = ll[0:4]\n", - " verts[ivert, 0] = x\n", - " verts[ivert, 1] = y\n", - "\n", - " # read the cell information and create iverts\n", - " iverts = []\n", - " for icell in range(ncells):\n", - " line = f.readline()\n", - " ll = line.split()\n", - " ivlist = []\n", - " for ic in ll[2:5]:\n", - " ivlist.append(int(ic) - 1)\n", - " if ivlist[0] != ivlist[-1]:\n", - " ivlist.append(ivlist[0])\n", - " ivlist.reverse()\n", - " iverts.append(ivlist)\n", - "\n", - " # close file and return spatial reference\n", - " f.close()\n", - " return verts, iverts" - ] - }, - { - "cell_type": "markdown", - "id": "0380fe5c", - "metadata": {}, - "source": [ - "Load argus mesh and get disv grid properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "54a46473", - "metadata": {}, - "outputs": [], - "source": [ - "fname = os.path.join(config.data_ws, \"ex-gwf-disvmesh\", \"argus.exp\")\n", - "verts, iverts = from_argus_export(fname)\n", - "gridprops = flopy.utils.cvfdutil.get_disv_gridprops(verts, iverts)\n", - "cell_areas = []\n", - "for i in range(gridprops[\"ncpl\"]):\n", - " x = verts[iverts[i], 0]\n", - " y = verts[iverts[i], 1]\n", - " cell_verts = np.vstack((x, y)).transpose()\n", - " cell_areas.append(get_polygon_area(cell_verts))" - ] - }, - { - "cell_type": "markdown", - "id": "992ab9d4", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "92afb645", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 50\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "ee7cec6c", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 DISVMESH model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8c201740", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " linear_acceleration=\"bicgstab\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdisv(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " top=top,\n", - " botm=botm,\n", - " **gridprops,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " xt3doptions=True,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - "\n", - " theta = np.arange(0.0, 2 * np.pi, 0.2)\n", - " radius = 1500.0\n", - " x = radius * np.cos(theta)\n", - " y = radius * np.sin(theta)\n", - " outer = [(x, y) for x, y in zip(x, y)]\n", - " radius = 1025.0\n", - " x = radius * np.cos(theta)\n", - " y = radius * np.sin(theta)\n", - " hole = [(x, y) for x, y in zip(x, y)]\n", - " p = Polygon(outer, holes=[hole])\n", - " ix = GridIntersect(gwf.modelgrid, method=\"vertex\", rtree=True)\n", - " result = ix.intersect(p)\n", - " ghb_cellids = np.array(result[\"cellids\"], dtype=int)\n", - "\n", - " ghb_spd = []\n", - " ghb_spd += [[0, i, 0.0, k33 * cell_areas[i] / 10.0] for i in ghb_cellids]\n", - " ghb_spd = {0: ghb_spd}\n", - " flopy.mf6.ModflowGwfghb(\n", - " gwf,\n", - " stress_period_data=ghb_spd,\n", - " pname=\"GHB\",\n", - " )\n", - "\n", - " ncpl = gridprops[\"ncpl\"]\n", - " rchcells = np.array(list(range(ncpl)), dtype=int)\n", - " rchcells[ghb_cellids] = -1\n", - " rch_spd = [(0, rchcells[i], recharge) for i in range(ncpl) if rchcells[i] > 0]\n", - " rch_spd = {0: rch_spd}\n", - " flopy.mf6.ModflowGwfrch(gwf, stress_period_data=rch_spd, pname=\"RCH\")\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - "\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "e8aaf0ee", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 DISVMESH model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eff7720d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "7360bfdc", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the FHB model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e9b5bfca", - "metadata": {}, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=False):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c13abe5", - "metadata": {}, - "outputs": [], - "source": [ - "# Function to plot the DISVMESH model results.\n", - "#\n", - "def plot_grid(idx, sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " pmv.plot_grid(linewidth=1)\n", - " pmv.plot_bc(name=\"GHB\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a8c7c375", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_head(idx, sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=(7.5, 5))\n", - " fig.tight_layout()\n", - "\n", - " head = gwf.output.head().get_data()[:, 0, :]\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " gwf.output.budget().get_data(text=\"DATA-SPDIS\", totim=1.0)[0],\n", - " gwf,\n", - " )\n", - "\n", - " ax = fig.add_subplot(1, 2, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " cb = pmv.plot_array(head, cmap=\"jet\", vmin=0.0, vmax=head.max())\n", - " pmv.plot_vector(\n", - " qx,\n", - " qy,\n", - " normalize=False,\n", - " color=\"0.75\",\n", - " )\n", - " cbar = plt.colorbar(cb, shrink=0.25)\n", - " cbar.ax.set_xlabel(r\"Head, ($m$)\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - " fs.heading(ax, letter=\"A\", heading=\"Layer 1\")\n", - "\n", - " ax = fig.add_subplot(1, 2, 2, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=1)\n", - " cb = pmv.plot_array(head, cmap=\"jet\", vmin=0.0, vmax=head.max())\n", - " pmv.plot_vector(\n", - " qx,\n", - " qy,\n", - " normalize=False,\n", - " color=\"0.75\",\n", - " )\n", - " cbar = plt.colorbar(cb, shrink=0.25)\n", - " cbar.ax.set_xlabel(r\"Head, ($m$)\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - " fs.heading(ax, letter=\"B\", heading=\"Layer 2\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-head{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "68b1eb06", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(idx, sim, silent=True):\n", - " if config.plotModel:\n", - " if idx == 0:\n", - " plot_grid(idx, sim)\n", - " plot_head(idx, sim)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "a796b5cd", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the FHB model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8b72e068", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " sim = build_model(sim_name)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(idx, sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c9a5484", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "adcb66de", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "54930513", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### DISVMESH Simulation\n", - " #\n", - " # Model grid and simulated heads in the DISVMESH model\n", - "\n", - " simulation(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-drn-p01.ipynb b/notebooks/ex-gwf-drn-p01.ipynb deleted file mode 100644 index 65160b82..00000000 --- a/notebooks/ex-gwf-drn-p01.ipynb +++ /dev/null @@ -1,1854 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d6081b32", - "metadata": {}, - "source": [ - "## Unsaturated Zone Flow (UZF) Package problem 2\n", - "\n", - "This is the unsaturated zone package example problem (test 2) from the\n", - "Unsaturated Zone Flow Package documentation (Niswonger and others, 2006).\n", - "All reaches have been converted to rectangular reaches.\n" - ] - }, - { - "cell_type": "markdown", - "id": "5e668e0a", - "metadata": {}, - "source": [ - "### UZF Package Problem 2 Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "872b797c", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e779d7ea", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "39f21084", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "19dc9ef8", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "b99b87ad", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fe535f1d", - "metadata": {}, - "outputs": [], - "source": [ - "import build_table as bt\n", - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "cca6828c", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9401ecee", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.3, 5.6)\n", - "masked_values = (0, 1e30, -1e30)" - ] - }, - { - "cell_type": "markdown", - "id": "998c4eeb", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ab855d8c", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "741fa1fc", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c792a6fd", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-drn-p01\"" - ] - }, - { - "cell_type": "markdown", - "id": "ba57f296", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f2d530f8", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "248f561c", - "metadata": {}, - "source": [ - "Model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1feefd9c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-drn-p01a\": {\n", - " \"uzf_gwseep\": None,\n", - " },\n", - " \"ex-gwf-drn-p01b\": {\n", - " \"uzf_gwseep\": True,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "da450a2e", - "metadata": {}, - "source": [ - "Table UZF Package Problem 2 Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b2804fbb", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 12 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 15 # Number of rows\n", - "ncol = 10 # Number of columns\n", - "delr = 5000.0 # Column width ($ft$)\n", - "delc = 5000.0 # Row width ($ft$)\n", - "strt = 1050.0 # Starting head ($ft$)\n", - "k11_stream = 0.002 # Hydraulic conductivity near the stream ($ft/s$)\n", - "k11_basin = 0.0004 # Hydraulic conductivity in the basin ($ft/s$)\n", - "ss = 1e-6 # Specific storage ($1/s)$\n", - "sy_stream = 0.2 # Specific yield near the stream (unitless)\n", - "sy_basin = 0.1 # Specific yield in the basin (unitless)\n", - "uzf_kv = 1e-6 # Vertical saturated hydraulic conductivity ($ft/s$)\n", - "thts = 0.3 # Saturated water content (unitless)\n", - "thti = 0.1 # Initial water content (unitless)\n", - "thtr = 0.1 # Base residual water content (unitless)\n", - "eps = 3.5 # Epsilon exponent (unitless)\n", - "evap_rate = 5.0e-8 # Evapotranspiration rate ($ft/s$)\n", - "extwc = 0.10005 # Evapotranspiration extinction wilting content (unitless)\n", - "ext_depth = 15.0 # Evapotranspiration extinction depth ($ft$)\n", - "surf_dep = 1.0 # Surface depression depth ($ft$)" - ] - }, - { - "cell_type": "markdown", - "id": "cedebbed", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "528137f5", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = [(2628000.0, 1, 1.0)]\n", - "for n in range(nper - 1):\n", - " tdis_ds.append((2628000.0, 15, 1.1))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e9a614e9", - "metadata": {}, - "outputs": [], - "source": [ - "# Define dimensions\n", - "extents = (0.0, delr * ncol, 0.0, delc * nrow)\n", - "shape2d = (nrow, ncol)\n", - "shape3d = (nlay, nrow, ncol)" - ] - }, - { - "cell_type": "markdown", - "id": "7b0434bc", - "metadata": {}, - "source": [ - "Load the idomain, top, bottom, and uzf/mvr arrays" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "87d8b5b8", - "metadata": {}, - "outputs": [], - "source": [ - "data_pth = os.path.join(\"..\", \"data\", \"ex-gwf-sfr-p01\")\n", - "fpth = os.path.join(data_pth, \"idomain.txt\")\n", - "idomain = np.loadtxt(fpth, dtype=int)\n", - "fpth = os.path.join(data_pth, \"bottom.txt\")\n", - "botm = np.loadtxt(fpth, dtype=float)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1a1c0b24", - "metadata": {}, - "outputs": [], - "source": [ - "data_pth = os.path.join(\"..\", \"data\", sim_name)\n", - "fpth = os.path.join(data_pth, \"top.txt\")\n", - "top = np.loadtxt(fpth, dtype=float)\n", - "fpth = os.path.join(data_pth, \"infilt_mult.txt\")\n", - "infilt_mult = np.loadtxt(fpth, dtype=float)\n", - "fpth = os.path.join(data_pth, \"extwc_mult.txt\")\n", - "extwc_mult = np.loadtxt(fpth, dtype=float)\n", - "fpth = os.path.join(data_pth, \"routing_map.txt\")\n", - "routing_map = np.loadtxt(fpth, dtype=int)" - ] - }, - { - "cell_type": "markdown", - "id": "ffe345ae", - "metadata": {}, - "source": [ - "convert routing map to zero-based reach numbers" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1a6cc357", - "metadata": {}, - "outputs": [], - "source": [ - "routing_map -= 1" - ] - }, - { - "cell_type": "markdown", - "id": "f8b06893", - "metadata": {}, - "source": [ - "Create hydraulic conductivity and specific yield" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "468bfacf", - "metadata": {}, - "outputs": [], - "source": [ - "k11 = np.zeros(shape2d, dtype=float)\n", - "k11[idomain == 1] = k11_stream\n", - "k11[idomain == 2] = k11_basin\n", - "sy = np.zeros(shape2d, dtype=float)\n", - "sy[idomain == 1] = sy_stream\n", - "sy[idomain == 2] = sy_basin" - ] - }, - { - "cell_type": "markdown", - "id": "0acf794d", - "metadata": {}, - "source": [ - "Infiltration rates" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0b1663f6", - "metadata": {}, - "outputs": [], - "source": [ - "infiltration = (\n", - " 1.0e-9,\n", - " 8.0e-9,\n", - " 1.0e-8,\n", - " 2.0e-8,\n", - " 5.0e-9,\n", - " 1.0e-8,\n", - " 3.0e-9,\n", - " 5.0e-9,\n", - " 3.0e-9,\n", - " 2.0e-9,\n", - " 1.0e-9,\n", - " 1.0e-9,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "7741fa16", - "metadata": {}, - "source": [ - "Pumping rates" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3964a3fd", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "well_rates = (\n", - " -2.0,\n", - " -2.0,\n", - " -1.0,\n", - " -1.0,\n", - " -3.0,\n", - " 0.0,\n", - " -2.0,\n", - " 0.0,\n", - " -1.0,\n", - " 0.0,\n", - " -3.0,\n", - " 0.0,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "d755dd34", - "metadata": {}, - "source": [ - "### Create UZF Package Problem 2 Model Boundary Conditions\n", - "\n", - "General head boundary conditions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a739b468", - "metadata": {}, - "outputs": [], - "source": [ - "ghb_spd = [\n", - " [0, 12, 0, 988.0, 0.038],\n", - " [0, 13, 8, 1045.0, 0.038],\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "48544fbf", - "metadata": {}, - "source": [ - "Well boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "655c9c3a", - "metadata": {}, - "outputs": [], - "source": [ - "wel_spd = {}\n", - "for n in range(nper):\n", - " q = well_rates[n]\n", - " if q == 0.0:\n", - " wel_spd[n] = [[]]\n", - " else:\n", - " wel_spd[n] = [\n", - " [0, 5, 3, q],\n", - " [0, 5, 4, q],\n", - " [0, 6, 3, q],\n", - " [0, 6, 4, q],\n", - " [0, 7, 3, q],\n", - " [0, 7, 4, q],\n", - " [0, 8, 3, q],\n", - " [0, 8, 4, q],\n", - " [0, 9, 3, q],\n", - " [0, 9, 4, q],\n", - " ]" - ] - }, - { - "cell_type": "markdown", - "id": "f3403807", - "metadata": {}, - "source": [ - "Drain boundary" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b7b98988", - "metadata": {}, - "outputs": [], - "source": [ - "drn_spd = []\n", - "for i in range(nrow):\n", - " for j in range(ncol):\n", - " if idomain[i, j] == 0:\n", - " continue\n", - " drncell = [\n", - " 0,\n", - " i,\n", - " j,\n", - " top[i, j] - 0.5 * surf_dep,\n", - " 25.0,\n", - " 1.0,\n", - " \"surfrate\",\n", - " ]\n", - " drn_spd.append(drncell)" - ] - }, - { - "cell_type": "markdown", - "id": "d9266c2a", - "metadata": {}, - "source": [ - "UZF package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7db8e95c", - "metadata": {}, - "outputs": [], - "source": [ - "uzf_pakdata = []\n", - "iuzf = 0\n", - "for i in range(nrow):\n", - " for j in range(ncol):\n", - " if idomain[i, j] == 0:\n", - " continue\n", - " uzfcell = [\n", - " iuzf,\n", - " 0,\n", - " i,\n", - " j,\n", - " 1,\n", - " -1,\n", - " surf_dep,\n", - " uzf_kv,\n", - " thtr * extwc_mult[i, j],\n", - " thts,\n", - " thti * extwc_mult[i, j],\n", - " eps,\n", - " \"surfrate\",\n", - " ]\n", - " uzf_pakdata.append(uzfcell)\n", - " iuzf += 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6beeb677", - "metadata": {}, - "outputs": [], - "source": [ - "uzf_spd = {}\n", - "for n in range(nper):\n", - " spd = []\n", - " iuzf = 0\n", - " for i in range(nrow):\n", - " for j in range(ncol):\n", - " if idomain[i, j] == 0:\n", - " continue\n", - " uzfcell = [\n", - " iuzf,\n", - " infiltration[n] * infilt_mult[i, j],\n", - " evap_rate,\n", - " ext_depth,\n", - " extwc * extwc_mult[i, j],\n", - " 0,\n", - " 0,\n", - " 0,\n", - " ]\n", - " spd.append(uzfcell)\n", - " iuzf += 1\n", - " uzf_spd[n] = spd" - ] - }, - { - "cell_type": "markdown", - "id": "91465e7e", - "metadata": {}, - "source": [ - "SFR Package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ce194d9a", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_pakdata = [\n", - " [\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 4500.0,\n", - " 12,\n", - " 8.6767896e-04,\n", - " 1093.048,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 1,\n", - " 0,\n", - " 1,\n", - " 1,\n", - " 7000.0,\n", - " 12,\n", - " 8.6767896e-04,\n", - " 1088.059,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 2,\n", - " 0,\n", - " 2,\n", - " 2,\n", - " 6000.0,\n", - " 12,\n", - " 8.6767896e-04,\n", - " 1082.419,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 3,\n", - " 0,\n", - " 2,\n", - " 3,\n", - " 5550.0,\n", - " 12,\n", - " 8.6767896e-04,\n", - " 1077.408,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 3,\n", - " 1.0,\n", - " 1,\n", - " ],\n", - " [\n", - " 4,\n", - " 0,\n", - " 3,\n", - " 4,\n", - " 6500.0,\n", - " 12,\n", - " 9.4339624e-04,\n", - " 1071.934,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 5,\n", - " 0,\n", - " 4,\n", - " 5,\n", - " 5000.0,\n", - " 12,\n", - " 9.4339624e-04,\n", - " 1066.509,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 6,\n", - " 0,\n", - " 5,\n", - " 5,\n", - " 5000.0,\n", - " 12,\n", - " 9.4339624e-04,\n", - " 1061.792,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 7,\n", - " 0,\n", - " 6,\n", - " 5,\n", - " 5000.0,\n", - " 12,\n", - " 9.4339624e-04,\n", - " 1057.075,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 8,\n", - " 0,\n", - " 7,\n", - " 5,\n", - " 5000.0,\n", - " 12,\n", - " 9.4339624e-04,\n", - " 1052.359,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 9,\n", - " 0,\n", - " 2,\n", - " 4,\n", - " 5000.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1073.636,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 0.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 10,\n", - " 0,\n", - " 2,\n", - " 5,\n", - " 5000.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1070.909,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 11,\n", - " 0,\n", - " 2,\n", - " 6,\n", - " 4500.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1068.318,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 12,\n", - " 0,\n", - " 3,\n", - " 7,\n", - " 6000.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1065.455,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 13,\n", - " 0,\n", - " 4,\n", - " 7,\n", - " 5000.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1062.455,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 14,\n", - " 0,\n", - " 5,\n", - " 7,\n", - " 2000.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1060.545,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 15,\n", - " 0,\n", - " 4,\n", - " 9,\n", - " 2500.0,\n", - " 10,\n", - " 1.8181818e-03,\n", - " 1077.727,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 16,\n", - " 0,\n", - " 4,\n", - " 8,\n", - " 5000.0,\n", - " 10,\n", - " 1.8181818e-03,\n", - " 1070.909,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 17,\n", - " 0,\n", - " 5,\n", - " 7,\n", - " 3500.0,\n", - " 10,\n", - " 1.8181818e-03,\n", - " 1063.182,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 18,\n", - " 0,\n", - " 5,\n", - " 7,\n", - " 4000.0,\n", - " 15,\n", - " 1.0000000e-03,\n", - " 1058.000,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 3,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 19,\n", - " 0,\n", - " 6,\n", - " 6,\n", - " 5000.0,\n", - " 15,\n", - " 1.0000000e-03,\n", - " 1053.500,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 20,\n", - " 0,\n", - " 7,\n", - " 6,\n", - " 3500.0,\n", - " 15,\n", - " 1.0000000e-03,\n", - " 1049.250,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 21,\n", - " 0,\n", - " 7,\n", - " 5,\n", - " 2500.0,\n", - " 15,\n", - " 1.0000000e-03,\n", - " 1046.250,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 22,\n", - " 0,\n", - " 8,\n", - " 5,\n", - " 5000.0,\n", - " 12,\n", - " 9.0909092e-04,\n", - " 1042.727,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 3,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 23,\n", - " 0,\n", - " 9,\n", - " 6,\n", - " 5000.0,\n", - " 12,\n", - " 9.0909092e-04,\n", - " 1038.182,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 24,\n", - " 0,\n", - " 10,\n", - " 6,\n", - " 5000.0,\n", - " 12,\n", - " 9.0909092e-04,\n", - " 1033.636,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 25,\n", - " 0,\n", - " 11,\n", - " 6,\n", - " 5000.0,\n", - " 12,\n", - " 9.0909092e-04,\n", - " 1029.091,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 26,\n", - " 0,\n", - " 12,\n", - " 6,\n", - " 2000.0,\n", - " 12,\n", - " 9.0909092e-04,\n", - " 1025.909,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 27,\n", - " 0,\n", - " 13,\n", - " 8,\n", - " 5000.0,\n", - " 55,\n", - " 9.6774194e-04,\n", - " 1037.581,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 28,\n", - " 0,\n", - " 12,\n", - " 7,\n", - " 5500.0,\n", - " 55,\n", - " 9.6774194e-04,\n", - " 1032.500,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 29,\n", - " 0,\n", - " 12,\n", - " 6,\n", - " 5000.0,\n", - " 55,\n", - " 9.6774194e-04,\n", - " 1027.419,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 30,\n", - " 0,\n", - " 12,\n", - " 5,\n", - " 5000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 1021.875,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 3,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 31,\n", - " 0,\n", - " 12,\n", - " 4,\n", - " 5000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 1015.625,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 32,\n", - " 0,\n", - " 12,\n", - " 3,\n", - " 5000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 1009.375,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 33,\n", - " 0,\n", - " 12,\n", - " 2,\n", - " 5000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 1003.125,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 34,\n", - " 0,\n", - " 12,\n", - " 1,\n", - " 5000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 996.8750,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 35,\n", - " 0,\n", - " 12,\n", - " 0,\n", - " 3000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 991.8750,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "16ad37e9", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_conn = [\n", - " [0, -1],\n", - " [1, 0, -2],\n", - " [2, 1, -3],\n", - " [3, 2, -4, -9],\n", - " [4, 3, -5],\n", - " [5, 4, -6],\n", - " [6, 5, -7],\n", - " [7, 6, -8],\n", - " [8, 7, -22],\n", - " [9, 3, -10],\n", - " [10, 9, -11],\n", - " [11, 10, -12],\n", - " [12, 11, -13],\n", - " [13, 12, -14],\n", - " [14, 13, -18],\n", - " [15, -16],\n", - " [16, 15, -17],\n", - " [17, 16, -18],\n", - " [18, 14, 17, -19],\n", - " [19, 18, -20],\n", - " [20, 19, -21],\n", - " [21, 20, -22],\n", - " [22, 8, 21, -23],\n", - " [23, 22, -24],\n", - " [24, 23, -25],\n", - " [25, 24, -26],\n", - " [26, 25, -30],\n", - " [27, -28],\n", - " [28, 27, -29],\n", - " [29, 28, -30],\n", - " [30, 26, 29, -31],\n", - " [31, 30, -32],\n", - " [32, 31, -33],\n", - " [33, 32, -34],\n", - " [34, 33, -35],\n", - " [35, 34],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d2a92a0e", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_div = [[3, 0, 9, \"UPTO\"]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6f236978", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_spd = [\n", - " [0, \"inflow\", 25.0],\n", - " [15, \"inflow\", 10.0],\n", - " [27, \"inflow\", 150.0],\n", - " [3, \"diversion\", 0, 10.0],\n", - " [9, \"status\", \"simple\"],\n", - " [10, \"status\", \"simple\"],\n", - " [11, \"status\", \"simple\"],\n", - " [12, \"status\", \"simple\"],\n", - " [13, \"status\", \"simple\"],\n", - " [14, \"status\", \"simple\"],\n", - " [9, \"stage\", 1075.545],\n", - " [10, \"stage\", 1072.636],\n", - " [11, \"stage\", 1069.873],\n", - " [12, \"stage\", 1066.819],\n", - " [13, \"stage\", 1063.619],\n", - " [14, \"stage\", 1061.581],\n", - "]\n", - "# MVR package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3476fcb1", - "metadata": {}, - "outputs": [], - "source": [ - "mvr_paks = [\n", - " [\"SFR-1\"],\n", - " [\"UZF-1\"],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d5ad3ef8", - "metadata": {}, - "outputs": [], - "source": [ - "uzf_mvr_spd = []\n", - "iuzf = 0\n", - "for i in range(nrow):\n", - " for j in range(ncol):\n", - " if idomain[i, j] == 0:\n", - " continue\n", - " uzf_mvr_spd.append(\n", - " [\n", - " \"UZF-1\",\n", - " iuzf,\n", - " \"SFR-1\",\n", - " routing_map[i, j],\n", - " \"FACTOR\",\n", - " 1.0,\n", - " ]\n", - " )\n", - " iuzf += 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a142d0a1", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "drn_mvr_spd = []\n", - "idrn = 0\n", - "for i in range(nrow):\n", - " for j in range(ncol):\n", - " if idomain[i, j] == 0:\n", - " continue\n", - " drn_mvr_spd.append(\n", - " [\n", - " \"DRN-1\",\n", - " idrn,\n", - " \"SFR-1\",\n", - " routing_map[i, j],\n", - " \"FACTOR\",\n", - " 1.0,\n", - " ]\n", - " )\n", - " idrn += 1" - ] - }, - { - "cell_type": "markdown", - "id": "1e1ea441", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9a280cbb", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 100\n", - "ninner = 50\n", - "hclose = 1e-6\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "a4f11347", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 UZF Package Problem 2 model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4b406b79", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(name, uzf_gwseep=None):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " linear_acceleration=\"bicgstab\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, newtonoptions=\"newton\")\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " idomain=idomain,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=1,\n", - " k=k11,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=1,\n", - " sy=sy,\n", - " ss=ss,\n", - " steady_state={0: True},\n", - " transient={1: True},\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfghb(gwf, stress_period_data=ghb_spd)\n", - " flopy.mf6.ModflowGwfwel(gwf, stress_period_data=wel_spd)\n", - " sfr = flopy.mf6.ModflowGwfsfr(\n", - " gwf,\n", - " pname=\"SFR-1\",\n", - " length_conversion=3.28081,\n", - " mover=True,\n", - " nreaches=len(sfr_pakdata),\n", - " packagedata=sfr_pakdata,\n", - " connectiondata=sfr_conn,\n", - " diversions=sfr_div,\n", - " perioddata=sfr_spd,\n", - " )\n", - " uzf = flopy.mf6.ModflowGwfuzf(\n", - " gwf,\n", - " pname=\"UZF-1\",\n", - " simulate_gwseep=uzf_gwseep,\n", - " simulate_et=True,\n", - " linear_gwet=True,\n", - " boundnames=True,\n", - " mover=True,\n", - " nuzfcells=len(uzf_pakdata),\n", - " ntrailwaves=25,\n", - " nwavesets=20,\n", - " packagedata=uzf_pakdata,\n", - " perioddata=uzf_spd,\n", - " )\n", - "\n", - " mvr_packages = mvr_paks.copy()\n", - " mvr_spd = uzf_mvr_spd.copy()\n", - " obs_file = f\"{sim_name}.surfrate.obs\"\n", - " csv_file = obs_file + \".csv\"\n", - " if uzf_gwseep:\n", - " obs_dict = {\n", - " csv_file: [\n", - " (\"surfrate\", \"uzf-gwd-to-mvr\", \"surfrate\"),\n", - " (\"netinfil\", \"net-infiltration\", \"surfrate\"),\n", - " ]\n", - " }\n", - " uzf.obs.initialize(\n", - " filename=obs_file,\n", - " digits=10,\n", - " print_input=True,\n", - " continuous=obs_dict,\n", - " )\n", - " else:\n", - " mvr_packages.append([\"DRN-1\"])\n", - " mvr_spd += drn_mvr_spd.copy()\n", - " drn = flopy.mf6.ModflowGwfdrn(\n", - " gwf,\n", - " pname=\"DRN-1\",\n", - " auxiliary=[(\"draindepth\")],\n", - " auxdepthname=\"draindepth\",\n", - " boundnames=True,\n", - " mover=True,\n", - " stress_period_data=drn_spd,\n", - " )\n", - " obs_dict = {\n", - " csv_file: [\n", - " (\"surfrate\", \"to-mvr\", \"surfrate\"),\n", - " ]\n", - " }\n", - " drn.obs.initialize(\n", - " filename=obs_file,\n", - " digits=10,\n", - " print_input=True,\n", - " continuous=obs_dict,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfmvr(\n", - " gwf,\n", - " maxpackages=len(mvr_packages),\n", - " maxmvr=len(mvr_spd),\n", - " packages=mvr_packages,\n", - " perioddata=mvr_spd,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " printrecord=[(\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "23142eae", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 UZF Package Problem 2 model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e6f81d5d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "41d01f77", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the UZF Package Problem 2 model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e288d80", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "2755ac3f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "plot vertical bars for stress periods" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d3947751", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_stress_periods(ax):\n", - " vmin, vmax = ax.get_ylim()\n", - " x0 = 0.0\n", - " x1 = 0.0\n", - " for n in range(nper):\n", - " if n % 2 == 0:\n", - " color = \"#3399FF\"\n", - " else:\n", - " color = \"#FFCC99\"\n", - " x1 += 30.42\n", - " ax.fill_between(\n", - " [x0, x1],\n", - " vmin,\n", - " y2=vmax,\n", - " lw=0,\n", - " color=color,\n", - " step=\"post\",\n", - " alpha=0.25,\n", - " ec=\"none\",\n", - " )\n", - " x0 = x1\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "16fdeacd", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "plot the groundwater seepage results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a9d2372e", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_gwseep_results(silent=True):\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " # load the observations\n", - " name = list(parameters.keys())[0]\n", - " fpth = os.path.join(ws, name, f\"{sim_name}.surfrate.obs.csv\")\n", - " drn = flopy.utils.Mf6Obs(fpth).data\n", - " name = list(parameters.keys())[1]\n", - " fpth = os.path.join(ws, name, f\"{sim_name}.surfrate.obs.csv\")\n", - " uzf = flopy.utils.Mf6Obs(fpth).data\n", - "\n", - " time = drn[\"totim\"] / 86400.0\n", - " q0 = drn[\"SURFRATE\"]\n", - " q1 = uzf[\"SURFRATE\"]\n", - " mean_error = np.mean(q0 - q1)\n", - "\n", - " # create the figure\n", - " fig, axes = plt.subplots(\n", - " ncols=2,\n", - " nrows=1,\n", - " sharex=True,\n", - " figsize=(6.3, 3.15),\n", - " constrained_layout=True,\n", - " )\n", - "\n", - " ax = axes[0]\n", - " ax.set_xlim(0, 365)\n", - " ax.set_ylim(0, 175)\n", - "\n", - " xp, yp = [0.0], [uzf[\"NETINFIL\"][0]]\n", - " for idx in range(time.shape[0]):\n", - " if idx == 0:\n", - " x0, x1 = 0.0, time[idx]\n", - " else:\n", - " x0, x1 = time[idx - 1], time[idx]\n", - " y2 = uzf[\"NETINFIL\"][idx]\n", - " xp.append(x0)\n", - " xp.append(x1)\n", - " yp.append(y2)\n", - " yp.append(y2)\n", - " ax.fill_between(\n", - " [x0, x1],\n", - " 0,\n", - " y2=y2,\n", - " lw=0,\n", - " color=\"blue\",\n", - " step=\"post\",\n", - " ec=\"none\",\n", - " zorder=100,\n", - " )\n", - " ax.plot(xp, yp, lw=0.5, color=\"black\", zorder=101)\n", - " plot_stress_periods(ax)\n", - " fs.heading(ax, idx=0)\n", - "\n", - " ax.set_xlabel(\"Simulation time, in days\")\n", - " ax.set_ylabel(\"Infiltration to the unsaturated zone,\\nin cubic feet per second\")\n", - "\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 365)\n", - " ax.set_ylim(50.8, 51.8)\n", - " ax.plot(\n", - " time,\n", - " -drn[\"SURFRATE\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"blue\",\n", - " label=\"Drainage package\",\n", - " )\n", - " ax.plot(\n", - " time,\n", - " -uzf[\"SURFRATE\"],\n", - " marker=\"o\",\n", - " ms=3,\n", - " mfc=\"none\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " lw=0.0,\n", - " ls=\"-\",\n", - " color=\"red\",\n", - " label=\"UZF groundwater seepage\",\n", - " )\n", - " plot_stress_periods(ax)\n", - "\n", - " fs.graph_legend(ax, loc=\"upper center\", ncol=1, frameon=True, edgecolor=\"none\")\n", - " fs.heading(ax, idx=1)\n", - " fs.add_text(\n", - " ax,\n", - " f\"Mean Error {mean_error:.2e} cubic feet per second\",\n", - " bold=False,\n", - " italic=False,\n", - " x=1.0,\n", - " y=1.01,\n", - " va=\"bottom\",\n", - " ha=\"right\",\n", - " fontsize=7,\n", - " )\n", - "\n", - " ax.set_xlabel(\"Simulation time, in days\")\n", - " ax.set_ylabel(\"Groundwater seepage to the land surface,\\nin cubic feet per second\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-01{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6ee1577c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def export_tables(silent=True):\n", - " if config.plotSave:\n", - " caption = \"Infiltration and pumping rates for example {}.\".format(sim_name)\n", - " headings = (\n", - " \"Stress period\",\n", - " \"Infiltration rate\",\n", - " \"Pumping rate\",\n", - " )\n", - " fpth = os.path.join(\"..\", \"tables\", f\"{sim_name}-02.tex\")\n", - " dtype = [\n", - " (\"nper\", \"U30\"),\n", - " (\"infilt\", \"U30\"),\n", - " (\"rate\", \"U30\"),\n", - " ]\n", - " arr = np.zeros(nper, dtype=dtype)\n", - " for n in range(nper):\n", - " arr[\"nper\"][n] = bt.int_format(n + 1)\n", - " arr[\"infilt\"][n] = bt.exp_format(infiltration[n])\n", - " arr[\"rate\"][n] = bt.float_format(well_rates[n])\n", - " if not silent:\n", - " print(f\"creating...'{fpth}'\")\n", - " col_widths = (0.1, 0.30, 0.30)\n", - " bt.build_table(caption, fpth, arr, headings=headings, col_widths=col_widths)" - ] - }, - { - "cell_type": "markdown", - "id": "e6bc3ad7", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the UZF Package Problem 2 model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "50e2ef95", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(silent=True):\n", - " if config.plotModel:\n", - " plot_gwseep_results(silent=silent)\n", - " export_tables(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "2884d6d2", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the UZF Package Problem 2 model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "483a7c6a", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - "\n", - " sim = build_model(key, **params)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, f\"could not run...{sim_name}\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "29333b74", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_and_plot():\n", - " simulation(0, silent=False)\n", - " simulation(1, silent=False)\n", - " plot_results(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "b9bdfe37", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d55ee73e", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### UZF Package Problem 2 Simulation\n", - "\n", - " # drain used to simulate discharge to the land surface\n", - " simulation(0)\n", - "\n", - " # uzf used to simulate discharge to the land surface\n", - " simulation(1)\n", - "\n", - " # plot the results\n", - " plot_results()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-fhb.ipynb b/notebooks/ex-gwf-fhb.ipynb deleted file mode 100644 index 109414fc..00000000 --- a/notebooks/ex-gwf-fhb.ipynb +++ /dev/null @@ -1,589 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "4006c165", - "metadata": {}, - "source": [ - "## FHB example\n", - "\n", - "This example shows how the time series capability in MODFLOW 6 can be\n", - "combined with the constant head and well packages to replicate the\n", - "functionality of the Flow and Head Boundary (FHB) Package in previous\n", - "versions of MODFLOW.\n" - ] - }, - { - "cell_type": "markdown", - "id": "8024c07e", - "metadata": {}, - "source": [ - "### FHB Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c7c9c601", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8c52a3f0", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "b7b72001", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "83fdd51a", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "25584133", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c12ace9f", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "ae24c8a5", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4fca210e", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (4, 4)" - ] - }, - { - "cell_type": "markdown", - "id": "9a7d8916", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "103a7828", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "2cbd8139", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d45105ea", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-fhb\"" - ] - }, - { - "cell_type": "markdown", - "id": "2025ea2c", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6b65c37d", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "11178810", - "metadata": {}, - "source": [ - "Table FHB Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "754d1938", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 3 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "ncol = 10 # Number of columns\n", - "nrow = 3 # Number of rows\n", - "delr = 1000.0 # Column width ($m$)\n", - "delc = 1000.0 # Row width ($m$)\n", - "top = 50.0 # Top of the model ($m$)\n", - "botm_str = \"-200.0\" # Layer bottom elevations ($m$)\n", - "strt = 0.0 # Starting head ($m$)\n", - "icelltype_str = \"0\" # Cell conversion type\n", - "k11_str = \"20.0\" # Horizontal hydraulic conductivity ($m/d$)\n", - "ss = 0.01 # Specific storage ($/m$)" - ] - }, - { - "cell_type": "markdown", - "id": "93539610", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation has 1 steady stress period (1 day)\n", - "and 3 transient stress periods (10 days each).\n", - "Each transient stress period has 120 2-hour time steps." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6aefb475", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [400.0, 200.0, 400.0]\n", - "nstp = [10, 4, 6]\n", - "tsmult = [1.0, 1.0, 1.0]\n", - "tdis_ds = list(zip(perlen, nstp, tsmult))" - ] - }, - { - "cell_type": "markdown", - "id": "8dc8b47c", - "metadata": {}, - "source": [ - "parse parameter strings into tuples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8c75b896", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]\n", - "k11 = [float(value) for value in k11_str.split(\",\")]\n", - "icelltype = [int(value) for value in icelltype_str.split(\",\")]" - ] - }, - { - "cell_type": "markdown", - "id": "a79802a5", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1b2feaf2", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 50\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "124b8a94", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 FHB model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0ab64a55", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " storagecoefficient=True,\n", - " iconvert=0,\n", - " ss=1.0e-6,\n", - " sy=None,\n", - " transient={0: True},\n", - " )\n", - "\n", - " chd_spd = []\n", - " chd_spd += [[0, i, 9, \"CHDHEAD\"] for i in range(3)]\n", - " chd_spd = {0: chd_spd}\n", - " tsdata = [(0.0, 0.0), (307.0, 1.0), (791.0, 5.0), (1000.0, 2.0)]\n", - " tsdict = {\n", - " \"timeseries\": tsdata,\n", - " \"time_series_namerecord\": \"CHDHEAD\",\n", - " \"interpolation_methodrecord\": \"LINEAREND\",\n", - " }\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chd_spd,\n", - " timeseries=tsdict,\n", - " pname=\"CHD\",\n", - " )\n", - "\n", - " wel_spd = []\n", - " wel_spd += [[0, 1, 0, \"FLOWRATE\"]]\n", - " wel_spd = {0: wel_spd}\n", - " tsdata = [\n", - " (0.0, 2000.0),\n", - " (307.0, 6000.0),\n", - " (791.0, 5000.0),\n", - " (1000.0, 9000.0),\n", - " ]\n", - " tsdict = {\n", - " \"timeseries\": tsdata,\n", - " \"time_series_namerecord\": \"FLOWRATE\",\n", - " \"interpolation_methodrecord\": \"LINEAREND\",\n", - " }\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " stress_period_data=wel_spd,\n", - " timeseries=tsdict,\n", - " pname=\"WEL\",\n", - " )\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - "\n", - " obsdict = {}\n", - " obslist = [\n", - " [\"h1_2_1\", \"head\", (0, 1, 0)],\n", - " [\"h1_2_10\", \"head\", (0, 1, 9)],\n", - " ]\n", - " obsdict[f\"{sim_name}.obs.head.csv\"] = obslist\n", - " obslist = [[\"icf1\", \"flow-ja-face\", (0, 1, 1), (0, 1, 0)]]\n", - " obsdict[f\"{sim_name}.obs.flow.csv\"] = obslist\n", - " obs = flopy.mf6.ModflowUtlobs(gwf, print_input=False, continuous=obsdict)\n", - "\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "83a6dd37", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 FHB model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6a327761", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "0ce01620", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the FHB model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b9c0c0e3", - "metadata": {}, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=False):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "397d5325", - "metadata": {}, - "outputs": [], - "source": [ - "# Function to plot the FHB model results.\n", - "#\n", - "def plot_grid(sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=(4, 3.0))\n", - " fig.tight_layout()\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " pmv.plot_grid()\n", - " pmv.plot_bc(name=\"CHD\")\n", - " pmv.plot_bc(name=\"WEL\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "291df36b", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_ts(sim):\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - " obsnames = gwf.obs.output.obs_names\n", - " obs_list = [\n", - " gwf.obs.output.obs(f=obsnames[0]),\n", - " gwf.obs.output.obs(f=obsnames[1]),\n", - " ]\n", - " ylabel = [\"head (m)\", \"flow ($m^3/d$)\"]\n", - " obs_fig = (\"obs-head\", \"obs-flow\", \"ghb-obs\")\n", - " for iplot, obstype in enumerate(obs_list):\n", - " fig = plt.figure(figsize=(5, 3))\n", - " ax = fig.add_subplot()\n", - " tsdata = obstype.data\n", - " for name in tsdata.dtype.names[1:]:\n", - " ax.plot(tsdata[\"totim\"], tsdata[name], label=name, marker=\"o\")\n", - " ax.set_xlabel(\"time (d)\")\n", - " ax.set_ylabel(ylabel[iplot])\n", - " fs.graph_legend(ax)\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}-{}{}\".format(sim_name, obs_fig[iplot], config.figure_ext),\n", - " )\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9a2c6707", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " plot_grid(sim)\n", - " plot_ts(sim)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "924622ce", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the FHB model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "90831f24", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " sim = build_model()\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d921ce23", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "15a2626e", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bd4379ec", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### FHB Simulation\n", - " #\n", - " # Model grid and simulation results\n", - "\n", - " simulation()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-hani.ipynb b/notebooks/ex-gwf-hani.ipynb deleted file mode 100644 index a2e39433..00000000 --- a/notebooks/ex-gwf-hani.ipynb +++ /dev/null @@ -1,557 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f7a20e7b", - "metadata": {}, - "source": [ - "## Hani example\n", - "\n", - "Simple steady state model using a regular MODFLOW grid to simulate the\n", - "response of an anisotropic confined aquifer to a pumping well. A\n", - "constant-head boundary condition surrounds the active domain. K22 is set\n", - "to 0.01. Drawdown is more pronounced in the K11 direction.\n" - ] - }, - { - "cell_type": "markdown", - "id": "0bffbb43", - "metadata": {}, - "source": [ - "### Hani Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ed33f2a8", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1ae74d1e", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import flopy.utils.cvfdutil\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "b0dad088", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3cb5b62d", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "acd6008e", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b20f4a44", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "c07f4827", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5cfea9a3", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (3.5, 3.5)" - ] - }, - { - "cell_type": "markdown", - "id": "c1561d48", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "61351ab0", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "6ed83db4", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "19765999", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "1680a954", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c7309870", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-hanir\": {\"angle1\": 0, \"xt3d\": False},\n", - " \"ex-gwf-hanix\": {\"angle1\": 25, \"xt3d\": True},\n", - " \"ex-gwf-hanic\": {\"angle1\": 90, \"xt3d\": False},\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "cf058d78", - "metadata": {}, - "source": [ - "Table Hani Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "df35c2c1", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 51 # Number of rows\n", - "ncol = 51 # Number of columns\n", - "delr = 10.0 # Spacing along rows ($m$)\n", - "delc = 10.0 # Spacing along columns ($m$)\n", - "top = 0.0 # Top of the model ($m$)\n", - "botm = -10.0 # Layer bottom elevations ($m$)\n", - "strt = 0.0 # Starting head ($m$)\n", - "icelltype = 0 # Cell conversion type\n", - "k11 = 1.0 # Horizontal hydraulic conductivity in the 11 direction ($m/d$)\n", - "k22 = 0.01 # Horizontal hydraulic conductivity in the 22 direction ($m/d$)\n", - "pumping_rate = -1.0 # Pumping rate ($m^3/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "5d1031d4", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation has 1 steady stress period (1 day)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1cf4e94a", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [1.0]\n", - "nstp = [1]\n", - "tsmult = [1.0]\n", - "tdis_ds = list(zip(perlen, nstp, tsmult))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fe49c36b", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 50\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "859259fd", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 Hani model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "45fe562a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, angle1, xt3d):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " linear_acceleration=\"bicgstab\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k22=k22,\n", - " angle1=angle1,\n", - " save_specific_discharge=True,\n", - " xt3doptions=xt3d,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - "\n", - " ibd = -1 * np.ones((nrow, ncol), dtype=int)\n", - " ibd[1:-1, 1:-1] = 1\n", - " chdrow, chdcol = np.where(ibd == -1)\n", - " chd_spd = [[0, i, j, 0.0] for i, j in zip(chdrow, chdcol)]\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chd_spd,\n", - " pname=\"CHD\",\n", - " )\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " stress_period_data=[0, 25, 25, pumping_rate],\n", - " pname=\"WEL\",\n", - " )\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - "\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "8b1dacd4", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 Hani model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "671bfc40", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "d5eacd57", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the FHB model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e580bc97", - "metadata": {}, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=False):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c83fda4", - "metadata": {}, - "outputs": [], - "source": [ - "# Function to plot the Hani model results.\n", - "#\n", - "def plot_grid(idx, sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = list(parameters.keys())[idx]\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " pmv.plot_grid()\n", - " pmv.plot_bc(name=\"CHD\")\n", - " pmv.plot_bc(name=\"WEL\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1219ee7c", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_head(idx, sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = list(parameters.keys())[idx]\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " head = gwf.output.head().get_data()\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " cb = pmv.plot_array(0 - head, cmap=\"jet\", alpha=0.25)\n", - " cs = pmv.contour_array(0 - head, levels=np.arange(0.1, 1, 0.1))\n", - " cbar = plt.colorbar(cb, shrink=0.25)\n", - " cbar.ax.set_xlabel(r\"Drawdown, ($m$)\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-head{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d26cc2e3", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(idx, sim, silent=True):\n", - " if config.plotModel:\n", - " if idx == 0:\n", - " plot_grid(idx, sim)\n", - " plot_head(idx, sim)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "a19eb77e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the FHB model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06678f21", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - " sim = build_model(key, **params)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(idx, sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f7f06079", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "68c2d46b", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " simulation(1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8950eb57", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " simulation(2, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "056c39bb", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b8137d96", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Hani Simulation\n", - " #\n", - " # Simulated heads in the Hani model with anisotropy in x direction.\n", - "\n", - " simulation(0)\n", - "\n", - " # Simulated heads in the Hani model with anisotropy in y direction.\n", - "\n", - " simulation(1)\n", - "\n", - " # Simulated heads in the Hani model with anisotropy rotated 15 degrees.\n", - "\n", - " simulation(2)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-lak-p01.ipynb b/notebooks/ex-gwf-lak-p01.ipynb deleted file mode 100644 index de068dfa..00000000 --- a/notebooks/ex-gwf-lak-p01.ipynb +++ /dev/null @@ -1,1005 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "4310e083", - "metadata": {}, - "source": [ - "## Lake package (LAK) Package problem 1\n", - "\n", - "This is the lake package example problem (test 1) from the\n", - "Lake Package documentation (Merritt and Konikow, 2000).\n" - ] - }, - { - "cell_type": "markdown", - "id": "889bbb3f", - "metadata": {}, - "source": [ - "### LAK Package Problem 1 Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ca73e242", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "af205d26", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "b044a0ff", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0255d529", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "a50acc7a", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bc140e56", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "e9c423a5", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "32858787", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.3, 5.6)\n", - "masked_values = (0, 1e30, -1e30)" - ] - }, - { - "cell_type": "markdown", - "id": "ebbd4d10", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "93287e58", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "151b5d60", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c2afd686", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-lak-p01\"" - ] - }, - { - "cell_type": "markdown", - "id": "14594c9d", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef86822f", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "8c20c3e9", - "metadata": {}, - "source": [ - "Table LAK Package Problem 1 Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7f039b0e", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 5 # Number of layers\n", - "nrow = 17 # Number of rows\n", - "ncol = 17 # Number of columns\n", - "top = 500.0 # Top of the model ($ft$)\n", - "botm_str = \"107., 97., 87., 77., 67.\" # Bottom elevations ($ft$)\n", - "strt = 115.0 # Starting head ($ft$)\n", - "k11 = 30.0 # Horizontal hydraulic conductivity ($ft/d$)\n", - "k33_str = \"1179., 30., 30., 30., 30.\" # Vertical hydraulic conductivity ($ft/d$)\n", - "ss = 3e-4 # Specific storage ($1/d$)\n", - "sy = 0.2 # Specific yield (unitless)\n", - "H1 = 160.0 # Constant head on left side of model ($ft$)\n", - "H2 = 140.0 # Constant head on right side of model ($ft$)\n", - "recharge = 0.0116 # Aereal recharge rate ($ft/d$)\n", - "etvrate = 0.0141 # Maximum evapotranspiration rate ($ft/d$)\n", - "etvdepth = 15.0 # Evapotranspiration extinction depth ($ft$)\n", - "lak_strt = 110.0 # Starting lake stage ($ft$)\n", - "lak_etrate = 0.0103 # Lake evaporation rate ($ft/d$)\n", - "lak_bedleak = 0.1 # Lakebed leakance ($1/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "c47e0dbe", - "metadata": {}, - "source": [ - "parse parameter strings into tuples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "60a0f63b", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]\n", - "k33 = [float(value) for value in k33_str.split(\",\")]" - ] - }, - { - "cell_type": "markdown", - "id": "9eacf280", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bb23b2de", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((5000.0, 100, 1.02),)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7b40807e", - "metadata": {}, - "outputs": [], - "source": [ - "# define delr and delc\n", - "delr = np.array(\n", - " [\n", - " 250.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 500.00,\n", - " 500.00,\n", - " 500.00,\n", - " 500.0,\n", - " 500.00,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 250.0,\n", - " ]\n", - ")\n", - "delc = np.array(\n", - " [\n", - " 250.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 500.00,\n", - " 500.00,\n", - " 500.00,\n", - " 500.0,\n", - " 500.00,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 250.0,\n", - " ]\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f0e6e954", - "metadata": {}, - "outputs": [], - "source": [ - "# Define dimensions\n", - "extents = (0.0, delr.sum(), 0.0, delc.sum())\n", - "shape2d = (nrow, ncol)\n", - "shape3d = (nlay, nrow, ncol)" - ] - }, - { - "cell_type": "markdown", - "id": "3603a0e1", - "metadata": {}, - "source": [ - "Create the array defining the lake location" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5c12df3d", - "metadata": {}, - "outputs": [], - "source": [ - "lake_map = np.ones(shape3d, dtype=np.int32) * -1\n", - "lake_map[0, 6:11, 6:11] = 0\n", - "lake_map[1, 7:10, 7:10] = 0\n", - "lake_map = np.ma.masked_where(lake_map < 0, lake_map)" - ] - }, - { - "cell_type": "markdown", - "id": "56e2fd7e", - "metadata": {}, - "source": [ - "create linearly varying evapotranspiration surface" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f49fc975", - "metadata": {}, - "outputs": [], - "source": [ - "xlen = delr.sum() - 0.5 * (delr[0] + delr[-1])\n", - "x = 0.0\n", - "s1d = H1 * np.ones(ncol, dtype=float)\n", - "for idx in range(1, ncol):\n", - " x += 0.5 * (delr[idx - 1] + delr[idx])\n", - " frac = x / xlen\n", - " s1d[idx] = H1 + (H2 - H1) * frac\n", - "surf = np.tile(s1d, (nrow, 1))\n", - "surf[lake_map[0] == 0] = botm[0] - 2\n", - "surf[lake_map[1] == 0] = botm[1] - 2" - ] - }, - { - "cell_type": "markdown", - "id": "1b01f1b6", - "metadata": {}, - "source": [ - "### Create LAK Package Problem 1 Model Boundary Conditions\n", - "\n", - "Constant head boundary conditions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c8e25312", - "metadata": {}, - "outputs": [], - "source": [ - "chd_spd = []\n", - "for k in range(nlay):\n", - " chd_spd += [[k, i, 0, H1] for i in range(nrow)]\n", - " chd_spd += [[k, i, ncol - 1, H2] for i in range(nrow)]" - ] - }, - { - "cell_type": "markdown", - "id": "53cc94b4", - "metadata": {}, - "source": [ - "LAK Package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "846842f9", - "metadata": {}, - "outputs": [], - "source": [ - "lak_spd = [\n", - " [0, \"rainfall\", recharge],\n", - " [0, \"evaporation\", lak_etrate],\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "73795e74", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "778f5cd1", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "c03d68c5", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 LAK Package Problem 1 model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4e69aea8", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " linear_acceleration=\"bicgstab\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim, modelname=sim_name, newtonoptions=\"newton\", save_flows=True\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " idomain=np.ones(shape3d, dtype=int),\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " obs_file = f\"{sim_name}.gwf.obs\"\n", - " csv_file = obs_file + \".csv\"\n", - " obslist = [\n", - " [\"A\", \"head\", (0, 3, 3)],\n", - " [\"B\", \"head\", (0, 13, 13)],\n", - " ]\n", - " obsdict = {csv_file: obslist}\n", - " flopy.mf6.ModflowUtlobs(\n", - " gwf, filename=obs_file, print_input=False, continuous=obsdict\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=1,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=1,\n", - " sy=sy,\n", - " ss=ss,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chd_spd)\n", - " flopy.mf6.ModflowGwfrcha(gwf, recharge=recharge)\n", - " flopy.mf6.ModflowGwfevta(gwf, surface=surf, rate=etvrate, depth=etvdepth)\n", - " (\n", - " idomain_wlakes,\n", - " pakdata_dict,\n", - " lak_conn,\n", - " ) = flopy.mf6.utils.get_lak_connections(\n", - " gwf.modelgrid,\n", - " lake_map,\n", - " bedleak=lak_bedleak,\n", - " )\n", - " lak_packagedata = [[0, lak_strt, pakdata_dict[0]]]\n", - " lak = flopy.mf6.ModflowGwflak(\n", - " gwf,\n", - " print_stage=True,\n", - " nlakes=1,\n", - " noutlets=0,\n", - " packagedata=lak_packagedata,\n", - " connectiondata=lak_conn,\n", - " perioddata=lak_spd,\n", - " )\n", - " obs_file = f\"{sim_name}.lak.obs\"\n", - " csv_file = obs_file + \".csv\"\n", - " obs_dict = {\n", - " csv_file: [\n", - " (\"stage\", \"stage\", (0,)),\n", - " ]\n", - " }\n", - " lak.obs.initialize(\n", - " filename=obs_file, digits=10, print_input=True, continuous=obs_dict\n", - " )\n", - " gwf.dis.idomain = idomain_wlakes\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "f54f46cd", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 LAK Package Problem 1 model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8617bcc4", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "c129e339", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the LAK Package Problem 1 model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bf4f157c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "6d5b8c40", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fac9cfe3", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(gwf, silent=True):\n", - " sim_ws = os.path.join(ws, sim_name)\n", - "\n", - " # load the observations\n", - " lak_results = gwf.lak.output.obs().data\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj = gwf.output.head()\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " cobj = gwf.output.budget()\n", - "\n", - " kstpkper = hobj.get_kstpkper()\n", - "\n", - " head = hobj.get_data(kstpkper=kstpkper[0])\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " cobj.get_data(text=\"DATA-SPDIS\", kstpkper=kstpkper[0])[0],\n", - " gwf,\n", - " )\n", - "\n", - " # add lake stage to heads\n", - " head[head == 1e30] = lak_results[\"STAGE\"][-1]\n", - "\n", - " # observation locations\n", - " xcenters, ycenters = gwf.modelgrid.xycenters[0], gwf.modelgrid.xycenters[1]\n", - " p1 = (xcenters[3], ycenters[3])\n", - " p2 = (xcenters[13], ycenters[13])\n", - "\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " fig = plt.figure(\n", - " figsize=(4, 6.9),\n", - " tight_layout=True,\n", - " )\n", - " plt.axis(\"off\")\n", - "\n", - " nrows, ncols = 10, 1\n", - " axes = [fig.add_subplot(nrows, ncols, (1, 5))]\n", - " axes.append(fig.add_subplot(nrows, ncols, (6, 8), sharex=axes[0]))\n", - "\n", - " for idx, ax in enumerate(axes):\n", - " ax.set_xlim(extents[:2])\n", - " if idx == 0:\n", - " ax.set_ylim(extents[2:])\n", - " ax.set_aspect(\"equal\")\n", - "\n", - " # legend axis\n", - " axes.append(fig.add_subplot(nrows, ncols, (9, 10)))\n", - "\n", - " # set limits for legend area\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " mm.plot_bc(\"CHD\", color=\"cyan\")\n", - " mm.plot_inactive(color_noflow=\"#5DBB63\")\n", - " mm.plot_grid(lw=0.5, color=\"black\")\n", - " cv = mm.contour_array(\n", - " head,\n", - " levels=np.arange(140, 160, 2),\n", - " linewidths=0.75,\n", - " linestyles=\"-\",\n", - " colors=\"blue\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " mm.plot_vector(qx, qy, normalize=True, color=\"0.75\")\n", - " ax.plot(p1[0], p1[1], marker=\"o\", mfc=\"red\", mec=\"black\", ms=4)\n", - " ax.plot(p2[0], p2[1], marker=\"o\", mfc=\"red\", mec=\"black\", ms=4)\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " ax.set_ylabel(\"y-coordinate, in feet\")\n", - " fs.heading(ax, heading=\"Map view\", idx=0)\n", - " fs.add_text(\n", - " ax,\n", - " \"A\",\n", - " x=p1[0] + 150,\n", - " y=p1[1] + 150,\n", - " transform=False,\n", - " bold=False,\n", - " color=\"red\",\n", - " ha=\"left\",\n", - " va=\"bottom\",\n", - " )\n", - " fs.add_text(\n", - " ax,\n", - " \"B\",\n", - " x=p2[0] + 150,\n", - " y=p2[1] + 150,\n", - " transform=False,\n", - " bold=False,\n", - " color=\"red\",\n", - " ha=\"left\",\n", - " va=\"bottom\",\n", - " )\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " ax = axes[1]\n", - " xs = flopy.plot.PlotCrossSection(gwf, ax=ax, line={\"row\": 8})\n", - " xs.plot_array(np.ones(shape3d), head=head, cmap=\"jet\")\n", - " xs.plot_bc(\"CHD\", color=\"cyan\", head=head)\n", - " xs.plot_ibound(color_noflow=\"#5DBB63\", head=head)\n", - " xs.plot_grid(lw=0.5, color=\"black\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " ax.set_ylim(67, 160)\n", - " ax.set_ylabel(\"Elevation, in feet\")\n", - " fs.heading(ax, heading=\"Cross-section view\", idx=1)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"#5DBB63\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Lake boundary\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"cyan\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Constant-head boundary\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"blue\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Water table\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"o\",\n", - " ms=4,\n", - " mfc=\"red\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Observation well\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"blue\",\n", - " label=r\"Head contour, $ft$\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"$\\u2192$\",\n", - " ms=10,\n", - " mfc=\"0.75\",\n", - " mec=\"0.75\",\n", - " label=\"Normalized specific discharge\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"lower center\", ncol=2)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "68168956", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the lake results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b0cff21", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_lak_results(gwf, silent=True):\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " # load the observations\n", - " lak_results = gwf.lak.output.obs().data\n", - " gwf_results = gwf.obs[0].output.obs().data\n", - "\n", - " dtype = [\n", - " (\"time\", float),\n", - " (\"STAGE\", float),\n", - " (\"A\", float),\n", - " (\"B\", float),\n", - " ]\n", - "\n", - " results = np.zeros((lak_results.shape[0] + 1), dtype=dtype)\n", - " results[\"time\"][1:] = lak_results[\"totim\"]\n", - " results[\"STAGE\"][0] = 110.0\n", - " results[\"STAGE\"][1:] = lak_results[\"STAGE\"]\n", - " results[\"A\"][0] = 115.0\n", - " results[\"A\"][1:] = gwf_results[\"A\"]\n", - " results[\"B\"][0] = 115.0\n", - " results[\"B\"][1:] = gwf_results[\"B\"]\n", - "\n", - " # create the figure\n", - " fig, ax = plt.subplots(\n", - " ncols=1,\n", - " nrows=1,\n", - " sharex=True,\n", - " figsize=(6.3, 3.15),\n", - " constrained_layout=True,\n", - " )\n", - "\n", - " ax.set_xlim(0, 3000)\n", - " ax.set_ylim(110, 160)\n", - " ax.plot(\n", - " results[\"time\"],\n", - " results[\"STAGE\"],\n", - " lw=0.75,\n", - " ls=\"--\",\n", - " color=\"black\",\n", - " label=\"Lake stage\",\n", - " )\n", - " ax.plot(\n", - " results[\"time\"],\n", - " results[\"A\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"0.5\",\n", - " label=\"Point A\",\n", - " )\n", - " ax.plot(\n", - " results[\"time\"],\n", - " results[\"B\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"black\",\n", - " label=\"Point B\",\n", - " )\n", - " ax.set_xlabel(\"Simulation time, in days\")\n", - " ax.set_ylabel(\"Head or stage, in feet\")\n", - " fs.graph_legend(ax, loc=\"lower right\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-01{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "76bcaeb5", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the LAK Package Problem 1 model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a9f69b72", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " plot_grid(gwf, silent=silent)\n", - "\n", - " plot_lak_results(gwf, silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "87ba84a6", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the LAK Package Problem 1 model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d0b5c020", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " sim = build_model()\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, f\"could not run...{sim_name}\"\n", - "\n", - " if success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4254cf0b", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "f00a6de7", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3c98c979", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### LAK Package Problem 1 Simulation\n", - " #\n", - "\n", - " simulation()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-lak-p02.ipynb b/notebooks/ex-gwf-lak-p02.ipynb deleted file mode 100644 index dd02bcab..00000000 --- a/notebooks/ex-gwf-lak-p02.ipynb +++ /dev/null @@ -1,1626 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "34d35df7", - "metadata": {}, - "source": [ - "## Lake package (LAK) Package problem 2\n", - "\n", - "This is the lake package example problem (test 2) from the\n", - "Lake Package documentation (Merritt and Konikow, 2000).\n" - ] - }, - { - "cell_type": "markdown", - "id": "7e28bc0a", - "metadata": {}, - "source": [ - "### LAK Package problem 2 Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "24697ca5", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5a2142b4", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import shapefile as shp" - ] - }, - { - "cell_type": "markdown", - "id": "06caeacd", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fa0e09b5", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "338f09a1", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ca5169b8", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "eb2976d1", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4d93e182", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.3, 5.6)\n", - "masked_values = (0, 1e30, -1e30)" - ] - }, - { - "cell_type": "markdown", - "id": "3fe76d1a", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c686d98", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "205c44ea", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c7897d62", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-lak-p02\"" - ] - }, - { - "cell_type": "markdown", - "id": "0484c8ff", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "155cebc0", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "9379c4a3", - "metadata": {}, - "source": [ - "Table LAK Package problem 2 Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7404468b", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 5 # Number of layers\n", - "nrow = 27 # Number of rows\n", - "ncol = 17 # Number of columns\n", - "top = 200.0 # Top of the model ($ft$)\n", - "botm_str = \"102., 97., 87., 77., 67.\" # Bottom elevations ($ft$)\n", - "strt = 115.0 # Starting head ($ft$)\n", - "k11 = 30.0 # Horizontal hydraulic conductivity ($ft/d$)\n", - "k33 = 30.0 # Vertical hydraulic conductivity ($ft/d$)\n", - "ss = 3e-4 # Specific storage ($1/d$)\n", - "sy = 0.2 # Specific yield (unitless)\n", - "H1 = 160.0 # Constant head on left side of model ($ft$)\n", - "H2 = 140.0 # Constant head on right side of model ($ft$)\n", - "recharge = 0.0116 # Aereal recharge rate ($ft/d$)\n", - "etvrate = 0.0141 # Maximum evapotranspiration rate ($ft/d$)\n", - "etvdepth = 15.0 # Evapotranspiration extinction depth ($ft$)\n", - "lak_strt = 130.0 # Starting lake stage ($ft$)\n", - "lak_etrate = 0.0103 # Lake evaporation rate ($ft/d$)\n", - "lak_bedleak = 0.1 # Lakebed leakance ($1/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "92858668", - "metadata": {}, - "source": [ - "parse parameter strings into tuples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b4383d2d", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]" - ] - }, - { - "cell_type": "markdown", - "id": "7bb01150", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f39a0220", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((1500.0, 200, 1.005),)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b493ce34", - "metadata": {}, - "outputs": [], - "source": [ - "# define delr and delc\n", - "delr = np.array(\n", - " [\n", - " 250.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 500.0,\n", - " 500.0,\n", - " 500.0,\n", - " 500.0,\n", - " 500.00,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 250.0,\n", - " ]\n", - ")\n", - "delc = np.array(\n", - " [\n", - " 250.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 500.0,\n", - " 500.0,\n", - " 500.0,\n", - " 500.0,\n", - " 500.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 500.0,\n", - " 500.0,\n", - " 500.0,\n", - " 500.0,\n", - " 500.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 1000.0,\n", - " 250.0,\n", - " ]\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "047f79a3", - "metadata": {}, - "outputs": [], - "source": [ - "# Define dimensions\n", - "extents = (0.0, delr.sum(), 0.0, delc.sum())\n", - "shape2d = (nrow, ncol)\n", - "shape3d = (nlay, nrow, ncol)" - ] - }, - { - "cell_type": "markdown", - "id": "7c7f81d5", - "metadata": {}, - "source": [ - "Load the idomain arrays" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7e6aaeea", - "metadata": {}, - "outputs": [], - "source": [ - "data_pth = os.path.join(\"..\", \"data\", sim_name)\n", - "lake_map = np.ones(shape3d, dtype=int) * -1\n", - "fpth = os.path.join(data_pth, \"lakes-01.txt\")\n", - "lake_map[0, :, :] = np.loadtxt(fpth, dtype=int) - 1\n", - "fpth = os.path.join(data_pth, \"lakes-02.txt\")\n", - "lake_map[1, :, :] = np.loadtxt(fpth, dtype=int) - 1" - ] - }, - { - "cell_type": "markdown", - "id": "073d28bc", - "metadata": {}, - "source": [ - "create linearly varying evapotranspiration surface" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "65a48879", - "metadata": {}, - "outputs": [], - "source": [ - "xlen = delr.sum() - 0.5 * (delr[0] + delr[-1])\n", - "x = 0.0\n", - "s1d = H1 * np.ones(ncol, dtype=float)\n", - "for idx in range(1, ncol):\n", - " x += 0.5 * (delr[idx - 1] + delr[idx])\n", - " frac = x / xlen\n", - " s1d[idx] = H1 + (H2 - H1) * frac\n", - "surf = np.tile(s1d, (nrow, 1))\n", - "surf[lake_map[0, :, :] > -1] = botm[0] - 2\n", - "surf[lake_map[1, :, :] > -1] = botm[1] - 2" - ] - }, - { - "cell_type": "markdown", - "id": "6d5c99a4", - "metadata": {}, - "source": [ - "### Create LAK Package problem 2 Model Boundary Conditions\n", - "\n", - "Constant head boundary conditions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ca850f01", - "metadata": {}, - "outputs": [], - "source": [ - "chd_spd = []\n", - "for k in range(nlay):\n", - " chd_spd += [[k, i, 0, H1] for i in range(nrow)]\n", - " chd_spd += [[k, i, ncol - 1, H2] for i in range(nrow)]" - ] - }, - { - "cell_type": "markdown", - "id": "c7cfdf3a", - "metadata": {}, - "source": [ - "LAK Package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fbce3703", - "metadata": {}, - "outputs": [], - "source": [ - "lak_time_conv = 86400.0\n", - "lak_len_conv = 3.28081" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4d6ab1e3", - "metadata": {}, - "outputs": [], - "source": [ - "lak_outlets = [\n", - " [0, 0, -1, \"manning\", 114.85, 5.0, 0.05, 8.206324419006205e-4],\n", - " [1, 1, -1, \"manning\", 109.4286, 5.0, 0.05, 9.458197164349258e-4],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c07c5e4", - "metadata": {}, - "outputs": [], - "source": [ - "lak_spd = [\n", - " [0, \"rainfall\", recharge],\n", - " [0, \"evaporation\", lak_etrate],\n", - " [1, \"rainfall\", recharge],\n", - " [1, \"evaporation\", lak_etrate],\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "1d2ac86a", - "metadata": {}, - "source": [ - "SFR package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "366e01e4", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_pakdata = [\n", - " [\n", - " 0,\n", - " 0,\n", - " 1,\n", - " 4,\n", - " 1000,\n", - " 5,\n", - " 0.001103448,\n", - " 123.94827,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 1,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 1,\n", - " 0,\n", - " 2,\n", - " 4,\n", - " 1000,\n", - " 5,\n", - " 0.001103448,\n", - " 122.84483,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 2,\n", - " 0,\n", - " 3,\n", - " 4,\n", - " 1000,\n", - " 5,\n", - " 0.001103448,\n", - " 121.74138,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 3,\n", - " 0,\n", - " 3,\n", - " 5,\n", - " 1000,\n", - " 5,\n", - " 0.001103448,\n", - " 120.63793,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 4,\n", - " 0,\n", - " 3,\n", - " 6,\n", - " 500,\n", - " 5,\n", - " 0.001103448,\n", - " 119.81035,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 5,\n", - " 0,\n", - " 3,\n", - " 7,\n", - " 750,\n", - " 5,\n", - " 0.001103448,\n", - " 119.12069,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 6,\n", - " 0,\n", - " 4,\n", - " 7,\n", - " 1000,\n", - " 5,\n", - " 0.001103448,\n", - " 118.15517,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 7,\n", - " 0,\n", - " 5,\n", - " 7,\n", - " 1000,\n", - " 5,\n", - " 0.001103448,\n", - " 117.05173,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 1,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 8,\n", - " 0,\n", - " 11,\n", - " 8,\n", - " 1000,\n", - " 5,\n", - " 0.000820632,\n", - " 114.43968,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 1,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 9,\n", - " 0,\n", - " 12,\n", - " 8,\n", - " 1000,\n", - " 5,\n", - " 0.000820632,\n", - " 113.61905,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 10,\n", - " 0,\n", - " 13,\n", - " 9,\n", - " 559,\n", - " 5,\n", - " 0.000820632,\n", - " 112.97937,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 11,\n", - " 0,\n", - " 13,\n", - " 9,\n", - " 559,\n", - " 5,\n", - " 0.000820632,\n", - " 112.52063,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 12,\n", - " 0,\n", - " 14,\n", - " 9,\n", - " 1000,\n", - " 5,\n", - " 0.000820632,\n", - " 111.88095,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 13,\n", - " 0,\n", - " 15,\n", - " 9,\n", - " 1000,\n", - " 5,\n", - " 0.000820632,\n", - " 111.06032,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 1,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 14,\n", - " 0,\n", - " 21,\n", - " 9,\n", - " 1000,\n", - " 5,\n", - " 0.00094582,\n", - " 108.95569,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 1,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 15,\n", - " 0,\n", - " 22,\n", - " 9,\n", - " 750,\n", - " 5,\n", - " 0.00094582,\n", - " 108.1281,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 16,\n", - " 0,\n", - " 22,\n", - " 10,\n", - " 500,\n", - " 5,\n", - " 0.00094582,\n", - " 107.53696,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 17,\n", - " 0,\n", - " 22,\n", - " 11,\n", - " 1000,\n", - " 5,\n", - " 0.00094582,\n", - " 106.82759,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 18,\n", - " 0,\n", - " 22,\n", - " 12,\n", - " 1000,\n", - " 5,\n", - " 0.00094582,\n", - " 105.88177,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 19,\n", - " 0,\n", - " 22,\n", - " 13,\n", - " 1000,\n", - " 5,\n", - " 0.00094582,\n", - " 104.93595,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 20,\n", - " 0,\n", - " 22,\n", - " 14,\n", - " 1000,\n", - " 5,\n", - " 0.00094582,\n", - " 103.99014,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 2,\n", - " 1,\n", - " 0,\n", - " ],\n", - " [\n", - " 21,\n", - " 0,\n", - " 22,\n", - " 15,\n", - " 1000,\n", - " 5,\n", - " 0.00094582,\n", - " 103.04431,\n", - " 0.5,\n", - " 0.5,\n", - " 0.050000001,\n", - " 1,\n", - " 1,\n", - " 0,\n", - " ],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b9ec779", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_conn = [\n", - " [0, -1],\n", - " [1, 0, -2],\n", - " [2, 1, -3],\n", - " [3, 2, -4],\n", - " [4, 3, -5],\n", - " [5, 4, -6],\n", - " [6, 5, -7],\n", - " [7, 6],\n", - " [8, -9],\n", - " [9, 8, -10],\n", - " [10, 9, -11],\n", - " [11, 10, -12],\n", - " [12, 11, -13],\n", - " [13, 12],\n", - " [14, -15],\n", - " [15, 14, -16],\n", - " [16, 15, -17],\n", - " [17, 16, -18],\n", - " [18, 17, -19],\n", - " [19, 18, -20],\n", - " [20, 19, -21],\n", - " [21, 20],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9e8e2a18", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_spd = [[0, \"inflow\", 691200.0]]" - ] - }, - { - "cell_type": "markdown", - "id": "fb2b57bb", - "metadata": {}, - "source": [ - "MVR package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "232008d4", - "metadata": {}, - "outputs": [], - "source": [ - "mvr_paks = [\n", - " [\"SFR-1\"],\n", - " [\"LAK-1\"],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5a1d690a", - "metadata": {}, - "outputs": [], - "source": [ - "mvr_spd = [\n", - " [\"SFR-1\", 7, \"LAK-1\", 0, \"FACTOR\", 1.0],\n", - " [\"LAK-1\", 0, \"SFR-1\", 8, \"FACTOR\", 1.0],\n", - " [\"SFR-1\", 13, \"LAK-1\", 1, \"FACTOR\", 1.0],\n", - " [\"LAK-1\", 1, \"SFR-1\", 14, \"FACTOR\", 0.5],\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "449e072a", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "58ac37f2", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "719ceabc", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 LAK Package problem 2 model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "00523042", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " linear_acceleration=\"bicgstab\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim, modelname=sim_name, newtonoptions=\"newton\", save_flows=True\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " idomain=np.ones(shape3d, dtype=int),\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " obs_file = f\"{sim_name}.gwf.obs\"\n", - " csv_file = obs_file + \".csv\"\n", - " obslist = [\n", - " [\"A\", \"head\", (0, 3, 3)],\n", - " [\"B\", \"head\", (0, 13, 8)],\n", - " [\"C\", \"head\", (0, 23, 13)],\n", - " ]\n", - " obsdict = {csv_file: obslist}\n", - " flopy.mf6.ModflowUtlobs(\n", - " gwf, filename=obs_file, print_input=False, continuous=obsdict\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=1,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=1,\n", - " sy=sy,\n", - " ss=ss,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chd_spd)\n", - " flopy.mf6.ModflowGwfrcha(gwf, recharge=recharge)\n", - " flopy.mf6.ModflowGwfevta(gwf, surface=surf, rate=etvrate, depth=etvdepth)\n", - " (\n", - " idomain_wlakes,\n", - " pakdata_dict,\n", - " lak_conn,\n", - " ) = flopy.mf6.utils.get_lak_connections(\n", - " gwf.modelgrid,\n", - " lake_map,\n", - " bedleak=lak_bedleak,\n", - " )\n", - " lak_packagedata = []\n", - " for key in pakdata_dict.keys():\n", - " lak_packagedata.append([key, lak_strt, pakdata_dict[key]])\n", - " lak = flopy.mf6.ModflowGwflak(\n", - " gwf,\n", - " pname=\"LAK-1\",\n", - " time_conversion=lak_time_conv,\n", - " length_conversion=lak_len_conv,\n", - " mover=True,\n", - " print_stage=True,\n", - " nlakes=2,\n", - " noutlets=len(lak_outlets),\n", - " packagedata=lak_packagedata,\n", - " connectiondata=lak_conn,\n", - " outlets=lak_outlets,\n", - " perioddata=lak_spd,\n", - " )\n", - " obs_file = f\"{sim_name}.lak.obs\"\n", - " csv_file = obs_file + \".csv\"\n", - " obs_dict = {\n", - " csv_file: [\n", - " (\"lake1\", \"stage\", (0,)),\n", - " (\"lake2\", \"stage\", (1,)),\n", - " ]\n", - " }\n", - " lak.obs.initialize(\n", - " filename=obs_file, digits=10, print_input=True, continuous=obs_dict\n", - " )\n", - " gwf.dis.idomain = idomain_wlakes\n", - " flopy.mf6.ModflowGwfsfr(\n", - " gwf,\n", - " pname=\"SFR-1\",\n", - " time_conversion=86400.000,\n", - " length_conversion=3.28081,\n", - " mover=True,\n", - " print_stage=True,\n", - " print_flows=True,\n", - " nreaches=len(sfr_pakdata),\n", - " packagedata=sfr_pakdata,\n", - " connectiondata=sfr_conn,\n", - " perioddata=sfr_spd,\n", - " )\n", - " flopy.mf6.ModflowGwfmvr(\n", - " gwf,\n", - " maxmvr=4,\n", - " maxpackages=2,\n", - " packages=mvr_paks,\n", - " perioddata=mvr_spd,\n", - " )\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "f3c7cb82", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 LAK Package problem 2 model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d2af9b87", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "98b1d959", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the LAK Package problem 2 model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7aea9875", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "4381acda", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "777c59f7", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(gwf, silent=True):\n", - " sim_ws = os.path.join(ws, sim_name)\n", - "\n", - " # create lake array\n", - " ilake = gwf.dis.idomain.array\n", - " ilake[ilake == 0] = 100\n", - " ilake[ilake == 1] = 0\n", - " ilake[ilake == 100] = 1\n", - " for k in range(nlay):\n", - " for i in range(16, nrow):\n", - " for j in range(ncol):\n", - " if ilake[k, i, j] == 1:\n", - " ilake[k, i, j] = 2\n", - "\n", - " # get edges and centers of cells\n", - " xedges, yedges = gwf.modelgrid.xyedges[0], gwf.modelgrid.xyedges[1]\n", - " xcenters, ycenters = gwf.modelgrid.xycenters[0], gwf.modelgrid.xycenters[1]\n", - "\n", - " # create sfr network\n", - " poly0 = [\n", - " [xcenters[4], yedges[1]],\n", - " [xcenters[4], ycenters[4]],\n", - " [xcenters[7], ycenters[4]],\n", - " [xcenters[7], yedges[6]],\n", - " ]\n", - " poly1 = [\n", - " [xcenters[8], yedges[11]],\n", - " [xcenters[8], yedges[13]],\n", - " [xcenters[9], yedges[14]],\n", - " [xcenters[9], yedges[16]],\n", - " ]\n", - " poly2 = [\n", - " [xcenters[9], yedges[21]],\n", - " [xcenters[9], ycenters[22]],\n", - " [xedges[16], ycenters[22]],\n", - " ]\n", - " parts = [poly0, poly1, poly2]\n", - " shape_pth = os.path.join(ws, sim_name, \"sfr.shp\")\n", - " w = shp.Writer(target=shape_pth, shapeType=shp.POLYLINE)\n", - " w.field(\"no\", \"C\")\n", - " w.line([poly0])\n", - " w.record([\"1\"])\n", - " w.line([poly1])\n", - " w.record([\"2\"])\n", - " w.line([poly2])\n", - " w.record([\"3\"])\n", - " w.close()\n", - " sfr = shp.Reader(shape_pth)\n", - "\n", - " # load the observations\n", - " lak_results = gwf.lak.output.obs().data\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj = gwf.output.head()\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " cobj = gwf.output.budget()\n", - "\n", - " kstpkper = hobj.get_kstpkper()\n", - "\n", - " head = hobj.get_data(kstpkper=kstpkper[0])\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " cobj.get_data(text=\"DATA-SPDIS\", kstpkper=kstpkper[0])[0],\n", - " gwf,\n", - " )\n", - "\n", - " # add lake stage to heads\n", - " head[ilake == 1] = lak_results[\"LAKE1\"][-1]\n", - " head[ilake == 2] = lak_results[\"LAKE2\"][-1]\n", - "\n", - " # observation locations\n", - " p1 = (xcenters[3], ycenters[3])\n", - " p2 = (xcenters[8], ycenters[13])\n", - " p3 = (xcenters[13], ycenters[23])\n", - "\n", - " # lake text locations\n", - " pl1 = (xcenters[8], ycenters[8])\n", - " pl2 = (xcenters[8], ycenters[18])\n", - "\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " fig = plt.figure(\n", - " figsize=(4, 6.9),\n", - " tight_layout=True,\n", - " )\n", - " plt.axis(\"off\")\n", - "\n", - " nrows, ncols = 10, 1\n", - " axes = [fig.add_subplot(nrows, ncols, (1, 8))]\n", - "\n", - " for idx, ax in enumerate(axes):\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - " ax.set_aspect(\"equal\")\n", - "\n", - " # legend axis\n", - " axes.append(fig.add_subplot(nrows, ncols, (9, 10)))\n", - "\n", - " # set limits for legend area\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " mm.plot_bc(\"CHD\", color=\"cyan\")\n", - " for shape in sfr.shapeRecords():\n", - " x = [i[0] for i in shape.shape.points[:]]\n", - " y = [i[1] for i in shape.shape.points[:]]\n", - " ax.plot(x, y, color=\"#3BB3D0\", lw=1.5, zorder=1)\n", - " mm.plot_inactive(color_noflow=\"#5DBB63\")\n", - " mm.plot_grid(lw=0.5, color=\"black\")\n", - " cv = mm.contour_array(\n", - " head,\n", - " levels=np.arange(120, 160, 5),\n", - " linewidths=0.75,\n", - " linestyles=\"-\",\n", - " colors=\"blue\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " mm.plot_vector(qx, qy, normalize=True, color=\"0.75\")\n", - " ax.plot(p1[0], p1[1], marker=\"o\", mfc=\"red\", mec=\"black\", ms=4)\n", - " ax.plot(p2[0], p2[1], marker=\"o\", mfc=\"red\", mec=\"black\", ms=4)\n", - " ax.plot(p3[0], p3[1], marker=\"o\", mfc=\"red\", mec=\"black\", ms=4)\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " ax.set_ylabel(\"y-coordinate, in feet\")\n", - " fs.add_text(\n", - " ax,\n", - " \"A\",\n", - " x=p1[0] + 150,\n", - " y=p1[1] + 150,\n", - " transform=False,\n", - " bold=False,\n", - " color=\"red\",\n", - " ha=\"left\",\n", - " va=\"bottom\",\n", - " )\n", - " fs.add_text(\n", - " ax,\n", - " \"B\",\n", - " x=p2[0] + 150,\n", - " y=p2[1] + 150,\n", - " transform=False,\n", - " bold=False,\n", - " color=\"red\",\n", - " ha=\"left\",\n", - " va=\"bottom\",\n", - " )\n", - " fs.add_text(\n", - " ax,\n", - " \"C\",\n", - " x=p3[0] + 150,\n", - " y=p3[1] + 150,\n", - " transform=False,\n", - " bold=False,\n", - " color=\"red\",\n", - " ha=\"left\",\n", - " va=\"bottom\",\n", - " )\n", - " fs.add_text(\n", - " ax,\n", - " \"Lake 1\",\n", - " x=pl1[0],\n", - " y=pl1[1],\n", - " transform=False,\n", - " italic=False,\n", - " color=\"white\",\n", - " ha=\"center\",\n", - " va=\"center\",\n", - " )\n", - " fs.add_text(\n", - " ax,\n", - " \"Lake 2\",\n", - " x=pl2[0],\n", - " y=pl2[1],\n", - " transform=False,\n", - " italic=False,\n", - " color=\"white\",\n", - " ha=\"center\",\n", - " va=\"center\",\n", - " )\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"#5DBB63\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Lake boundary\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"cyan\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Constant-head boundary\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=1.5,\n", - " color=\"#3BB3D0\",\n", - " label=\"Stream network\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"o\",\n", - " ms=4,\n", - " mfc=\"red\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Observation well\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"blue\",\n", - " label=r\"Head contour, $ft$\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"$\\u2192$\",\n", - " ms=10,\n", - " mfc=\"0.75\",\n", - " mec=\"0.75\",\n", - " label=\"Normalized specific discharge\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"lower center\", ncol=2)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "f750542d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the lake results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "93510f20", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_lak_results(gwf, silent=True):\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " # load the observations\n", - " lak_results = gwf.lak.output.obs().data\n", - " gwf_results = gwf.obs[0].output.obs().data\n", - "\n", - " dtype = [\n", - " (\"time\", float),\n", - " (\"LAKE1\", float),\n", - " (\"LAKE2\", float),\n", - " (\"A\", float),\n", - " (\"B\", float),\n", - " (\"C\", float),\n", - " ]\n", - "\n", - " results = np.zeros((lak_results.shape[0] + 1), dtype=dtype)\n", - " results[\"time\"][1:] = lak_results[\"totim\"]\n", - " results[\"LAKE1\"][0] = lak_strt\n", - " results[\"LAKE1\"][1:] = lak_results[\"LAKE1\"]\n", - " results[\"LAKE2\"][0] = lak_strt\n", - " results[\"LAKE2\"][1:] = lak_results[\"LAKE2\"]\n", - " results[\"A\"][0] = strt\n", - " results[\"A\"][1:] = gwf_results[\"A\"]\n", - " results[\"B\"][0] = strt\n", - " results[\"B\"][1:] = gwf_results[\"B\"]\n", - " results[\"C\"][0] = strt\n", - " results[\"C\"][1:] = gwf_results[\"C\"]\n", - "\n", - " # create the figure\n", - " fig, axes = plt.subplots(\n", - " ncols=1,\n", - " nrows=2,\n", - " sharex=True,\n", - " figsize=(6.3, 4.3),\n", - " constrained_layout=True,\n", - " )\n", - "\n", - " ax = axes[0]\n", - " ax.set_xlim(0, 1500)\n", - " ax.set_ylim(110, 130)\n", - " ax.plot(\n", - " results[\"time\"],\n", - " results[\"LAKE1\"],\n", - " lw=0.75,\n", - " ls=\"--\",\n", - " color=\"black\",\n", - " label=\"Lake 1 stage\",\n", - " )\n", - " ax.plot(\n", - " results[\"time\"],\n", - " results[\"LAKE2\"],\n", - " lw=0.75,\n", - " ls=\"-.\",\n", - " color=\"black\",\n", - " label=\"Lake 2 stage\",\n", - " )\n", - " ax.set_xticks([0, 250, 500, 750, 1000, 1250, 1500])\n", - " ax.set_yticks([110, 115, 120, 125, 130])\n", - " ax.set_ylabel(\"Lake stage, in feet\")\n", - " fs.graph_legend(ax, loc=\"upper right\")\n", - " fs.heading(ax, idx=0)\n", - "\n", - " ax = axes[1]\n", - " ax.set_xlim(0, 1500)\n", - " ax.set_ylim(110, 160)\n", - " ax.plot(\n", - " results[\"time\"],\n", - " results[\"A\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"0.5\",\n", - " label=\"Point A\",\n", - " )\n", - " ax.plot(\n", - " results[\"time\"],\n", - " results[\"B\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"black\",\n", - " label=\"Point B\",\n", - " )\n", - " ax.plot(\n", - " results[\"time\"],\n", - " results[\"C\"],\n", - " lw=0.75,\n", - " ls=\"-.\",\n", - " color=\"black\",\n", - " label=\"Point C\",\n", - " )\n", - " ax.set_xticks([0, 250, 500, 750, 1000, 1250, 1500])\n", - " ax.set_xlabel(\"Simulation time, in days\")\n", - " ax.set_yticks([110, 120, 130, 140, 150, 160])\n", - " ax.set_ylabel(\"Head, in feet\")\n", - " fs.graph_legend(ax, loc=\"upper left\")\n", - " fs.heading(ax, idx=1)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-01{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "d055ac6f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the LAK Package problem 2 model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ba0fb3cd", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " plot_grid(gwf, silent=silent)\n", - "\n", - " plot_lak_results(gwf, silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "e064e69f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the LAK Package problem 2 model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8029aef4", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " sim = build_model()\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, f\"could not run...{sim_name}\"\n", - "\n", - " if success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "870eea97", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "baafe468", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "324101dd", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### LAK Package problem 2 Simulation\n", - " #\n", - "\n", - " simulation()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-lgr.ipynb b/notebooks/ex-gwf-lgr.ipynb deleted file mode 100644 index 4e5731aa..00000000 --- a/notebooks/ex-gwf-lgr.ipynb +++ /dev/null @@ -1,1467 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "9c101d64", - "metadata": {}, - "source": [ - "## LGR example with MVR for SFR between two models\n", - "\n", - "This script reproduces the model in Mehl and Hill (2013)." - ] - }, - { - "cell_type": "markdown", - "id": "c3b4a533", - "metadata": {}, - "source": [ - "### MODFLOW 6 LGR Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "3ba1d415", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4861f20a", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e5b7f9aa", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "cee66f58", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "01a3e9cf", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "import flopy\n", - "import flopy.utils.binaryfile as bf\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure\n", - "from flopy.utils.lgrutil import Lgr" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "58883c7b", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "9a4cfda8", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3708aa79", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (7, 5)" - ] - }, - { - "cell_type": "markdown", - "id": "d3193557", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4ecc52fe", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwf-lgr\"" - ] - }, - { - "cell_type": "markdown", - "id": "a6d63df6", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "40338482", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "eebb0440", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "10d19aa9", - "metadata": {}, - "outputs": [], - "source": [ - "nlayp = 3 # Number of layers in parent model\n", - "nrowp = 15 # Number of rows in parent model\n", - "ncolp = 15 # Number of columns in parent model\n", - "delrp = 102.94 # Parent model column width ($m$)\n", - "delcp = 68.63 # Parent model row width ($m$)\n", - "dum1 = 5 # Number of child model columns per parent model columns\n", - "dum2 = 5 # Number of child model rows per parent model rows\n", - "dum3 = 20.588 # Child model column width ($m$)\n", - "dum4 = 13.725 # Child model row width ($m$)\n", - "k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$)\n", - "k33 = 1.0 # Vertical hydraulic conductivity ($m/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "bd9dbc6a", - "metadata": {}, - "source": [ - "Additional model input preparation\n", - "Time related variables" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5e6e869c", - "metadata": {}, - "outputs": [], - "source": [ - "delrp = 1544.1 / ncolp\n", - "delcp = 1029.4 / nrowp\n", - "numdays = 1\n", - "perlen = [1] * numdays\n", - "nper = len(perlen)\n", - "nstp = [1] * numdays\n", - "tsmult = [1.0] * numdays" - ] - }, - { - "cell_type": "markdown", - "id": "1eaa68c5", - "metadata": {}, - "source": [ - "Further parent model grid discretization" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "687f2f70", - "metadata": {}, - "outputs": [], - "source": [ - "x = [round(x, 3) for x in np.linspace(50.0, 45.0, ncolp)]\n", - "topp = np.repeat(x, nrowp).reshape((15, 15)).T\n", - "z = [round(z, 3) for z in np.linspace(50.0, 0.0, nlayp + 1)]\n", - "botmp = [topp - z[len(z) - 2], topp - z[len(z) - 3], topp - z[0]]\n", - "idomainp = np.ones((nlayp, nrowp, ncolp), dtype=int)\n", - "idomainp[0:2, 6:11, 2:8] = 0 # Zero out where the child grid will reside\n", - "icelltype = [1, 0, 0] # Water table resides in layer 1" - ] - }, - { - "cell_type": "markdown", - "id": "10d5e511", - "metadata": {}, - "source": [ - "Solver settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a753378e", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-7, 1e-6, 0.97" - ] - }, - { - "cell_type": "markdown", - "id": "d87e7386", - "metadata": {}, - "source": [ - "Prepping input for SFR package for parent model\n", - "Define the connections" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "012aa22d", - "metadata": {}, - "outputs": [], - "source": [ - "connsp = [\n", - " (0, -1),\n", - " (1, 0, -2),\n", - " (2, 1, -3),\n", - " (3, 2, -4),\n", - " (4, 3, -5),\n", - " (5, 4, -6),\n", - " (6, 5, -7),\n", - " (7, 6),\n", - " (8, -9),\n", - " (9, 8, -10),\n", - " (10, 9, -11),\n", - " (11, 10, -12),\n", - " (12, 11, -13),\n", - " (13, 12, -14),\n", - " (14, 13, -15),\n", - " (15, 14, -16),\n", - " (16, 15, -17),\n", - " (17, 16),\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "1a11a4d3", - "metadata": {}, - "source": [ - "Package_data information" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d2bce22d", - "metadata": {}, - "outputs": [], - "source": [ - "sfrcells = [\n", - " (0, 0, 1),\n", - " (0, 1, 1),\n", - " (0, 2, 1),\n", - " (0, 2, 2),\n", - " (0, 3, 2),\n", - " (0, 4, 2),\n", - " (0, 4, 3),\n", - " (0, 5, 3),\n", - " (0, 8, 8),\n", - " (0, 8, 9),\n", - " (0, 8, 10),\n", - " (0, 8, 11),\n", - " (0, 7, 11),\n", - " (0, 7, 12),\n", - " (0, 6, 12),\n", - " (0, 6, 13),\n", - " (0, 6, 14),\n", - " (0, 5, 14),\n", - "]\n", - "rlen = [\n", - " 65.613029,\n", - " 72.488609,\n", - " 81.424789,\n", - " 35.850410,\n", - " 75.027390,\n", - " 90.887520,\n", - " 77.565651,\n", - " 74.860397,\n", - " 120.44695,\n", - " 112.31332,\n", - " 109.00368,\n", - " 91.234566,\n", - " 67.486000,\n", - " 24.603355,\n", - " 97.547943,\n", - " 104.97595,\n", - " 8.9454498,\n", - " 92.638367,\n", - "]\n", - "rwid = 5\n", - "rgrd1 = 0.12869035e-02\n", - "rgrd2 = 0.12780087e-02\n", - "rbtp = [\n", - " 49.409676,\n", - " 49.320812,\n", - " 49.221775,\n", - " 49.146317,\n", - " 49.074970,\n", - " 48.968212,\n", - " 48.859821,\n", - " 48.761742,\n", - " 45.550678,\n", - " 45.401943,\n", - " 45.260521,\n", - " 45.132568,\n", - " 45.031143,\n", - " 44.972298,\n", - " 44.894241,\n", - " 44.764832,\n", - " 44.692032,\n", - " 44.627121,\n", - "]\n", - "rbth = 1.5\n", - "rbhk = 0.1\n", - "man = 0.04\n", - "ustrf = 1.0\n", - "ndv = 0\n", - "pkdat = []\n", - "for i in np.arange(len(rlen)):\n", - " if i < 8:\n", - " rgrd = rgrd1\n", - " else:\n", - " rgrd = rgrd2\n", - " ncon = len(connsp[i]) - 1\n", - " pkdat.append(\n", - " (\n", - " i,\n", - " sfrcells[i],\n", - " rlen[i],\n", - " rwid,\n", - " rgrd,\n", - " rbtp[i],\n", - " rbth,\n", - " rbhk,\n", - " man,\n", - " ncon,\n", - " ustrf,\n", - " ndv,\n", - " )\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6395ae68", - "metadata": {}, - "outputs": [], - "source": [ - "sfrspd = {0: [[0, \"INFLOW\", 40.0]]}" - ] - }, - { - "cell_type": "markdown", - "id": "59583324", - "metadata": {}, - "source": [ - "Next, set up SFR input for the child model\n", - "Start by defining the connections. Set up with for loop since 1\n", - "stream segment with all linear connections. Cheating a bit by the\n", - "knowledge that there are 89 stream reaches in the child model. This\n", - "is known from the original model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "856daede", - "metadata": {}, - "outputs": [], - "source": [ - "connsc = []\n", - "for i in np.arange(89):\n", - " if i == 0:\n", - " connsc.append((i, -1 * (i + 1)))\n", - " elif i == 88:\n", - " connsc.append((i, i - 1))\n", - " else:\n", - " connsc.append((i, i - 1, -1 * (i + 1)))" - ] - }, - { - "cell_type": "markdown", - "id": "728b248a", - "metadata": {}, - "source": [ - "Package_data information" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "20f0c2ff", - "metadata": {}, - "outputs": [], - "source": [ - "sfrcellsc = [\n", - " (0, 0, 3),\n", - " (0, 1, 3),\n", - " (0, 1, 2),\n", - " (0, 2, 2),\n", - " (0, 2, 1),\n", - " (0, 3, 1),\n", - " (0, 4, 1),\n", - " (0, 5, 1),\n", - " (0, 6, 1),\n", - " (0, 7, 1),\n", - " (0, 7, 2),\n", - " (0, 7, 3),\n", - " (0, 7, 4),\n", - " (0, 6, 4),\n", - " (0, 5, 4),\n", - " (0, 4, 4),\n", - " (0, 3, 4),\n", - " (0, 3, 5),\n", - " (0, 3, 6),\n", - " (0, 4, 6),\n", - " (0, 4, 7),\n", - " (0, 5, 7),\n", - " (0, 5, 8),\n", - " (0, 6, 8),\n", - " (0, 7, 8),\n", - " (0, 7, 7),\n", - " (0, 8, 7),\n", - " (0, 8, 6),\n", - " (0, 8, 5),\n", - " (0, 8, 4),\n", - " (0, 9, 4),\n", - " (0, 9, 3),\n", - " (0, 10, 3),\n", - " (0, 11, 3),\n", - " (0, 12, 3),\n", - " (0, 13, 3),\n", - " (0, 13, 4),\n", - " (0, 14, 4),\n", - " (0, 14, 5),\n", - " (0, 14, 6),\n", - " (0, 13, 6),\n", - " (0, 13, 7),\n", - " (0, 12, 7),\n", - " (0, 11, 7),\n", - " (0, 11, 8),\n", - " (0, 10, 8),\n", - " (0, 9, 8),\n", - " (0, 8, 8),\n", - " (0, 7, 8),\n", - " (0, 7, 9),\n", - " (0, 6, 9),\n", - " (0, 5, 9),\n", - " (0, 4, 9),\n", - " (0, 3, 9),\n", - " (0, 2, 9),\n", - " (0, 2, 10),\n", - " (0, 1, 10),\n", - " (0, 0, 10),\n", - " (0, 0, 11),\n", - " (0, 0, 12),\n", - " (0, 0, 13),\n", - " (0, 1, 13),\n", - " (0, 2, 13),\n", - " (0, 3, 13),\n", - " (0, 4, 13),\n", - " (0, 5, 13),\n", - " (0, 6, 13),\n", - " (0, 6, 12),\n", - " (0, 7, 12),\n", - " (0, 8, 12),\n", - " (0, 9, 12),\n", - " (0, 10, 12),\n", - " (0, 11, 12),\n", - " (0, 12, 12),\n", - " (0, 12, 13),\n", - " (0, 13, 13),\n", - " (0, 13, 14),\n", - " (0, 13, 15),\n", - " (0, 12, 15),\n", - " (0, 11, 15),\n", - " (0, 10, 15),\n", - " (0, 10, 16),\n", - " (0, 9, 16),\n", - " (0, 9, 15),\n", - " (0, 8, 15),\n", - " (0, 7, 15),\n", - " (0, 6, 15),\n", - " (0, 6, 16),\n", - " (0, 6, 17),\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "21eb8640", - "metadata": {}, - "outputs": [], - "source": [ - "rlenc = [\n", - " 24.637711,\n", - " 31.966246,\n", - " 26.376442,\n", - " 11.773884,\n", - " 22.921772,\n", - " 24.949730,\n", - " 23.878050,\n", - " 23.190311,\n", - " 24.762365,\n", - " 24.908625,\n", - " 34.366299,\n", - " 37.834534,\n", - " 6.7398176,\n", - " 25.150850,\n", - " 22.888292,\n", - " 24.630053,\n", - " 24.104542,\n", - " 35.873375,\n", - " 20.101446,\n", - " 35.636936,\n", - " 39.273537,\n", - " 7.8477302,\n", - " 15.480835,\n", - " 22.883194,\n", - " 6.6126003,\n", - " 31.995899,\n", - " 9.4387379,\n", - " 35.385513,\n", - " 35.470993,\n", - " 23.500074,\n", - " 18.414469,\n", - " 12.016913,\n", - " 24.691732,\n", - " 23.105467,\n", - " 23.700483,\n", - " 19.596104,\n", - " 5.7555680,\n", - " 34.423119,\n", - " 36.131992,\n", - " 7.4424477,\n", - " 35.565659,\n", - " 1.6159637,\n", - " 32.316132,\n", - " 20.131876,\n", - " 6.5242062,\n", - " 25.575630,\n", - " 25.575630,\n", - " 24.303566,\n", - " 1.9158504,\n", - " 21.931326,\n", - " 23.847176,\n", - " 23.432203,\n", - " 23.248718,\n", - " 23.455051,\n", - " 15.171843,\n", - " 11.196334,\n", - " 34.931976,\n", - " 4.4492774,\n", - " 36.034172,\n", - " 38.365566,\n", - " 0.8766859,\n", - " 30.059759,\n", - " 25.351671,\n", - " 23.554117,\n", - " 24.691738,\n", - " 26.074226,\n", - " 13.542957,\n", - " 13.303432,\n", - " 28.145079,\n", - " 24.373089,\n", - " 23.213642,\n", - " 23.298107,\n", - " 24.627758,\n", - " 27.715137,\n", - " 1.7645065,\n", - " 39.549232,\n", - " 37.144009,\n", - " 14.943290,\n", - " 24.851254,\n", - " 23.737432,\n", - " 15.967736,\n", - " 10.632832,\n", - " 11.425938,\n", - " 20.009295,\n", - " 24.641207,\n", - " 27.960585,\n", - " 4.6452723,\n", - " 36.717735,\n", - " 34.469074,\n", - "]\n", - "rwidc = 5\n", - "rgrdc = 0.14448310e-02\n", - "rbtpc = [\n", - " 48.622822,\n", - " 48.581932,\n", - " 48.539783,\n", - " 48.512222,\n", - " 48.487160,\n", - " 48.452576,\n", - " 48.417301,\n", - " 48.383297,\n", - " 48.348656,\n", - " 48.312775,\n", - " 48.269951,\n", - " 48.217793,\n", - " 48.185593,\n", - " 48.162552,\n", - " 48.127850,\n", - " 48.093521,\n", - " 48.058315,\n", - " 48.014984,\n", - " 47.974548,\n", - " 47.934284,\n", - " 47.880165,\n", - " 47.846127,\n", - " 47.829273,\n", - " 47.801556,\n", - " 47.780251,\n", - " 47.752357,\n", - " 47.722424,\n", - " 47.690044,\n", - " 47.638855,\n", - " 47.596252,\n", - " 47.565975,\n", - " 47.543991,\n", - " 47.517471,\n", - " 47.482941,\n", - " 47.449127,\n", - " 47.417850,\n", - " 47.399536,\n", - " 47.370510,\n", - " 47.319538,\n", - " 47.288059,\n", - " 47.256992,\n", - " 47.230129,\n", - " 47.205616,\n", - " 47.167728,\n", - " 47.148472,\n", - " 47.125282,\n", - " 47.088329,\n", - " 47.052296,\n", - " 47.033356,\n", - " 47.016129,\n", - " 46.983055,\n", - " 46.948902,\n", - " 46.915176,\n", - " 46.881439,\n", - " 46.853535,\n", - " 46.834484,\n", - " 46.801159,\n", - " 46.772713,\n", - " 46.743465,\n", - " 46.689716,\n", - " 46.661369,\n", - " 46.639019,\n", - " 46.598988,\n", - " 46.563660,\n", - " 46.528805,\n", - " 46.492130,\n", - " 46.463512,\n", - " 46.444118,\n", - " 46.414173,\n", - " 46.376232,\n", - " 46.341858,\n", - " 46.308254,\n", - " 46.273632,\n", - " 46.235821,\n", - " 46.214523,\n", - " 46.184677,\n", - " 46.129272,\n", - " 46.091644,\n", - " 46.062897,\n", - " 46.027794,\n", - " 45.999111,\n", - " 45.979897,\n", - " 45.963959,\n", - " 45.941250,\n", - " 45.908993,\n", - " 45.870995,\n", - " 45.847439,\n", - " 45.817558,\n", - " 45.766132,\n", - "]\n", - "rbthc = 1.5\n", - "rbhkc = 0.1\n", - "manc = 0.04\n", - "ustrfc = 1.0\n", - "ndvc = 0\n", - "pkdatc = []\n", - "for i in np.arange(len(rlenc)):\n", - " nconc = len(connsc[i]) - 1\n", - " pkdatc.append(\n", - " (\n", - " i,\n", - " sfrcellsc[i],\n", - " rlenc[i],\n", - " rwidc,\n", - " rgrdc,\n", - " rbtpc[i],\n", - " rbthc,\n", - " rbhkc,\n", - " manc,\n", - " nconc,\n", - " ustrfc,\n", - " ndvc,\n", - " )\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bd2e6798", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "sfrspdc = {0: [[0, \"INFLOW\", 0.0]]}" - ] - }, - { - "cell_type": "markdown", - "id": "af982128", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function to build models\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "effa93eb", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, silent=False):\n", - " if config.buildModel:\n", - " # Instantiate the MODFLOW 6 simulation\n", - " name = \"lgr\"\n", - " gwfname = \"gwf-\" + name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name,\n", - " version=\"mf6\",\n", - " sim_ws=sim_ws,\n", - " exe_name=mf6exe,\n", - " continue_=True,\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " for i in range(len(perlen)):\n", - " tdis_rc.append((perlen[i], nstp[i], tsmult[i]))\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwfname = gwfname + \"-parent\"\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " newtonoptions=\"newton\",\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " dis = flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " nlay=nlayp,\n", - " nrow=nrowp,\n", - " ncol=ncolp,\n", - " delr=delrp,\n", - " delc=delcp,\n", - " top=topp,\n", - " botm=botmp,\n", - " idomain=idomainp,\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " strt = [topp - 0.25, topp - 0.25, topp - 0.25]\n", - " ic = flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " npf = flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " alternative_cell_averaging=\"AMT-LMK\",\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=False,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " oc = flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " rowList = np.arange(0, nrowp).tolist()\n", - " layList = np.arange(0, nlayp).tolist()\n", - " chdspd_left = []\n", - " chdspd_right = []\n", - "\n", - " # Loop through rows, the left & right sides will appear in separate,\n", - " # dedicated packages\n", - " hd_left = 49.75\n", - " hd_right = 44.75\n", - " for l in layList:\n", - " for r in rowList:\n", - " # first, do left side of model\n", - " chdspd_left.append([(l, r, 0), hd_left])\n", - " # finally, do right side of model\n", - " chdspd_right.append([(l, r, ncolp - 1), hd_right])\n", - "\n", - " chdspd = {0: chdspd_left}\n", - " chd1 = flopy.mf6.modflow.mfgwfchd.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd1.chd\",\n", - " )\n", - " chdspd = {0: chdspd_right}\n", - " chd2 = flopy.mf6.modflow.mfgwfchd.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " pname=\"CHD-2\",\n", - " filename=f\"{gwfname}.chd2.chd\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 Parent model's SFR package\n", - " sfr = flopy.mf6.ModflowGwfsfr(\n", - " gwf,\n", - " print_stage=False,\n", - " print_flows=False,\n", - " budget_filerecord=gwfname + \".sfr.bud\",\n", - " save_flows=True,\n", - " mover=True,\n", - " pname=\"SFR-parent\",\n", - " time_conversion=86400.0,\n", - " boundnames=False,\n", - " nreaches=len(connsp),\n", - " packagedata=pkdat,\n", - " connectiondata=connsp,\n", - " perioddata=sfrspd,\n", - " filename=f\"{gwfname}.sfr\",\n", - " )\n", - "\n", - " # -------------------------------\n", - " # Now pivoting to the child grid\n", - " # -------------------------------\n", - " # Leverage flopy's \"Lgr\" class; was imported at start of script\n", - " ncpp = 3\n", - " ncppl = [3, 3, 0]\n", - " lgr = Lgr(\n", - " nlayp,\n", - " nrowp,\n", - " ncolp,\n", - " delrp,\n", - " delcp,\n", - " topp,\n", - " botmp,\n", - " idomainp,\n", - " ncpp=ncpp,\n", - " ncppl=ncppl,\n", - " xllp=0.0,\n", - " yllp=0.0,\n", - " )\n", - "\n", - " # Get child grid info:\n", - " delrc, delcc = lgr.get_delr_delc()\n", - " idomainc = lgr.get_idomain() # child idomain\n", - " topc, botmc = lgr.get_top_botm() # top/bottom of child grid\n", - "\n", - " # Instantiate MODFLOW 6 child gwf model\n", - " gwfnamec = \"gwf-\" + name + \"-child\"\n", - " gwfc = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfnamec,\n", - " save_flows=True,\n", - " newtonoptions=\"newton\",\n", - " model_nam_file=f\"{gwfnamec}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 discretization package for the child model\n", - " child_dis_shp = lgr.get_shape()\n", - " nlayc = child_dis_shp[0]\n", - " nrowc = child_dis_shp[1]\n", - " ncolc = child_dis_shp[2]\n", - " disc = flopy.mf6.ModflowGwfdis(\n", - " gwfc,\n", - " nlay=nlayc,\n", - " nrow=nrowc,\n", - " ncol=ncolc,\n", - " delr=delrc,\n", - " delc=delcc,\n", - " top=topc,\n", - " botm=botmc,\n", - " idomain=idomainc,\n", - " filename=f\"{gwfnamec}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for child model\n", - " strtc = [\n", - " topc - 0.25,\n", - " topc - 0.25,\n", - " topc - 0.25,\n", - " topc - 0.25,\n", - " topc - 0.25,\n", - " topc - 0.25,\n", - " ]\n", - " icc = flopy.mf6.ModflowGwfic(gwfc, strt=strtc, filename=f\"{gwfnamec}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 node property flow package for child model\n", - " icelltypec = [1, 1, 1, 0, 0, 0]\n", - " npfc = flopy.mf6.ModflowGwfnpf(\n", - " gwfc,\n", - " save_flows=False,\n", - " alternative_cell_averaging=\"AMT-LMK\",\n", - " icelltype=icelltypec,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=False,\n", - " filename=f\"{gwfnamec}.npf\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for the child model\n", - " occ = flopy.mf6.ModflowGwfoc(\n", - " gwfc,\n", - " budget_filerecord=f\"{gwfnamec}.bud\",\n", - " head_filerecord=f\"{gwfnamec}.hds\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 Streamflow routing package for child model\n", - " sfrc = flopy.mf6.ModflowGwfsfr(\n", - " gwfc,\n", - " print_stage=False,\n", - " print_flows=False,\n", - " budget_filerecord=gwfnamec + \".sfr.bud\",\n", - " save_flows=True,\n", - " mover=True,\n", - " pname=\"SFR-child\",\n", - " time_conversion=86400.00,\n", - " boundnames=False,\n", - " nreaches=len(connsc),\n", - " packagedata=pkdatc,\n", - " connectiondata=connsc,\n", - " perioddata=sfrspdc,\n", - " filename=f\"{gwfnamec}.sfr\",\n", - " )\n", - "\n", - " # Retrieve exchange data using Lgr class functionality\n", - " exchange_data = lgr.get_exchange_data()\n", - "\n", - " # Establish MODFLOW 6 GWF-GWF exchange\n", - " gwfgwf = flopy.mf6.ModflowGwfgwf(\n", - " sim,\n", - " exgtype=\"GWF6-GWF6\",\n", - " print_flows=True,\n", - " print_input=True,\n", - " exgmnamea=gwfname,\n", - " exgmnameb=gwfnamec,\n", - " nexg=len(exchange_data),\n", - " exchangedata=exchange_data,\n", - " mvr_filerecord=f\"{name}.mvr\",\n", - " pname=\"EXG-1\",\n", - " filename=f\"{name}.exg\",\n", - " )\n", - "\n", - " # Instantiate MVR package\n", - " mvrpack = [[gwfname, \"SFR-parent\"], [gwfnamec, \"SFR-child\"]]\n", - " maxpackages = len(mvrpack)\n", - "\n", - " # Set up static SFR-to-SFR connections that remain fixed for entire simulation\n", - " static_mvrperioddata = [ # don't forget to use 0-based values\n", - " [\n", - " mvrpack[0][0],\n", - " mvrpack[0][1],\n", - " 7,\n", - " mvrpack[1][0],\n", - " mvrpack[1][1],\n", - " 0,\n", - " \"FACTOR\",\n", - " 1.0,\n", - " ],\n", - " [\n", - " mvrpack[1][0],\n", - " mvrpack[1][1],\n", - " 88,\n", - " mvrpack[0][0],\n", - " mvrpack[0][1],\n", - " 8,\n", - " \"FACTOR\",\n", - " 1,\n", - " ],\n", - " ]\n", - "\n", - " mvrspd = {0: static_mvrperioddata}\n", - " maxmvr = 2\n", - " mvr = flopy.mf6.ModflowMvr(\n", - " gwfgwf,\n", - " modelnames=True,\n", - " maxmvr=maxmvr,\n", - " print_flows=True,\n", - " maxpackages=maxpackages,\n", - " packages=mvrpack,\n", - " perioddata=mvrspd,\n", - " filename=f\"{name}.mvr\",\n", - " )\n", - "\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "e4ea0f23", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fefd6f61", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "583e40eb", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3d030f30", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "7a6e5265", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cfdde59c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mf6, idx):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " sim_name = mf6.name\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " # Start by retrieving some output\n", - " mf6_out_pth = mf6.simulation_data.mfpath.get_sim_path()\n", - " sfr_parent_bud_file = list(mf6.model_names)[0] + \".sfr.bud\"\n", - " sfr_child_bud_file = list(mf6.model_names)[1] + \".sfr.bud\"\n", - " sfr_parent_out = os.path.join(mf6_out_pth, sfr_parent_bud_file)\n", - " sfr_child_out = os.path.join(mf6_out_pth, sfr_child_bud_file)\n", - " modobjp = bf.CellBudgetFile(sfr_parent_out, precision=\"double\")\n", - " modobjc = bf.CellBudgetFile(sfr_child_out, precision=\"double\")\n", - "\n", - " ckstpkper = modobjp.get_kstpkper()\n", - " qp = []\n", - " qc = []\n", - " gwswp = []\n", - " gwswc = []\n", - " toMvrp = []\n", - " fromMvrp = []\n", - " toMvrc = []\n", - " fromMvrc = []\n", - "\n", - " for kstpkper in ckstpkper:\n", - " datp = modobjp.get_data(kstpkper=kstpkper, text=\" FLOW-JA-FACE\")\n", - " datc = modobjc.get_data(kstpkper=kstpkper, text=\" FLOW-JA-FACE\")\n", - " qp.append(datp)\n", - " qc.append(datc)\n", - "\n", - " datp = modobjp.get_data(kstpkper=kstpkper, text=\" GWF\")\n", - " datc = modobjc.get_data(kstpkper=kstpkper, text=\" GWF\")\n", - " gwswp.append(datp[0])\n", - " gwswc.append(datc[0])\n", - "\n", - " # No values for some reason?\n", - " dat_fmp = modobjp.get_data(kstpkper=kstpkper, text=\" FROM-MVR\")\n", - " dat_tmp = modobjp.get_data(kstpkper=kstpkper, text=\" TO-MVR\")\n", - " toMvrp.append(dat_fmp[0])\n", - " fromMvrp.append(dat_tmp[0])\n", - "\n", - " # No values for some reason?\n", - " dat_fmc = modobjc.get_data(kstpkper=kstpkper, text=\" FROM-MVR\")\n", - " dat_tmc = modobjc.get_data(kstpkper=kstpkper, text=\" TO-MVR\")\n", - " toMvrc.append(dat_fmc[0])\n", - " fromMvrc.append(dat_tmc[0])\n", - "\n", - " strmQ = np.zeros(len(connsp) + len(connsc))\n", - " # Hardwire the first reach to the specified inflow rate\n", - " strmQ[0] = 40.0\n", - " for i, itm in enumerate(np.arange(1, len(qp[0][0]), 2)):\n", - " # The first 8 reach of the parent SFR package are upstream of child grid\n", - " if qp[0][0][itm][0] <= 8:\n", - " strmQ[i + 1] = qp[0][0][itm][2]\n", - " if i >= 8:\n", - " break\n", - "\n", - " # The flow that is passed between the parent and child grids comes next\n", - " strmQ[i] = dat_fmc[0][0][2]\n", - "\n", - " # Next, process the child grid\n", - " for j, jtm in enumerate(np.arange(1, len(qc[0][0]), 2)):\n", - " # process all reaches successively\n", - " strmQ[i + (j + 1)] = qc[0][0][jtm][2]\n", - "\n", - " # The flow that is passed between the parent and child grids comes next\n", - " from_mvr = [itm[2] for itm in dat_fmp[0] if itm[2] > 0][0]\n", - " strmQ[i + j + 2] = from_mvr\n", - "\n", - " # Finally, process the remaining parent model stream reaches\n", - " for k, ktm in enumerate(np.arange(15, len(qp[0][0]), 2)):\n", - " strmQ[i + j + 2 + (k + 1)] = qp[0][0][ktm][2]\n", - "\n", - " # Fill out a single vector of stream reach lengths\n", - " all_rch_lengths = rlen[0:8] + rlenc + rlen[8:]\n", - " # Now get center of all the reaches\n", - " rch_lengths = []\n", - " for i in np.arange(len(all_rch_lengths)):\n", - " rch_lengths.append(np.sum(all_rch_lengths[0:i]) + (all_rch_lengths[i] / 2))\n", - "\n", - " # Make a continuous vector of the gw-sw exchanges\n", - " gwsw_exg = np.zeros(len(connsp) + len(connsc))\n", - " for i, itm in enumerate(gwswp[0]):\n", - " if itm[0] <= 8:\n", - " gwsw_exg[i] = itm[2]\n", - " elif itm[0] > 8:\n", - " gwsw_exg[(len(gwsw_exg) - (len(gwswp[0]) - i))] = itm[2]\n", - "\n", - " # Insert the child model gw/sw exchages in their proper sequential spot\n", - " for j, jtm in enumerate(gwswc[0]):\n", - " gwsw_exg[8 + j] = jtm[2]\n", - "\n", - " fig, ax1 = plt.subplots(figsize=figure_size, dpi=300, tight_layout=True)\n", - " pts = ax1.plot(rch_lengths, strmQ, \"r^\", label=\"Stream Flow\", zorder=3)\n", - " ax1.set_zorder(4)\n", - " ax1.set_facecolor(\"none\")\n", - " ax1.text(\n", - " rch_lengths[int(len(rch_lengths) / 2)],\n", - " 160,\n", - " \"Local Grid Refinement\",\n", - " ha=\"center\",\n", - " fontsize=10,\n", - " )\n", - " ax1.arrow(1080, 163, -440, 0, head_width=5, head_length=50, fc=\"k\", ec=\"k\")\n", - " ax1.arrow(2150, 163, 395, 0, head_width=5, head_length=50, fc=\"k\", ec=\"k\")\n", - " ax1.arrow(\n", - " 525,\n", - " 27,\n", - " 80,\n", - " -7,\n", - " head_width=5,\n", - " head_length=50,\n", - " fc=\"deeppink\",\n", - " ec=\"deeppink\",\n", - " linewidth=2,\n", - " ) # deeppink\n", - " ax1.arrow(\n", - " 2550,\n", - " 130,\n", - " 80,\n", - " 7,\n", - " head_width=5,\n", - " head_length=50,\n", - " fc=\"deeppink\",\n", - " ec=\"deeppink\",\n", - " linewidth=2,\n", - " )\n", - " ax1.text(\n", - " ((rch_lengths[7] + rch_lengths[8]) / 2) + 50,\n", - " 27,\n", - " \"First MVR\\ntransfer\",\n", - " ha=\"left\",\n", - " fontsize=10,\n", - " )\n", - " ax1.text(\n", - " (rch_lengths[7] + rch_lengths[8]) / 2 + 15,\n", - " 180 + 3.5,\n", - " \"Child Grid\",\n", - " rotation=90,\n", - " ha=\"left\",\n", - " fontsize=10,\n", - " )\n", - " ax1.text(\n", - " (rch_lengths[7] + rch_lengths[8]) / 2,\n", - " 180,\n", - " \"Parent Grid\",\n", - " rotation=90,\n", - " ha=\"right\",\n", - " fontsize=10,\n", - " )\n", - " ax1.text(\n", - " ((rch_lengths[96] + rch_lengths[97]) / 2) + 100,\n", - " 130,\n", - " \"Second MVR\\ntransfer\",\n", - " ha=\"left\",\n", - " fontsize=10,\n", - " )\n", - " ax1.text(\n", - " (rch_lengths[96] + rch_lengths[97]) / 2 + 15,\n", - " 180,\n", - " \"Parent Grid\",\n", - " rotation=90,\n", - " ha=\"left\",\n", - " fontsize=10,\n", - " )\n", - " ax1.text(\n", - " (rch_lengths[96] + rch_lengths[97]) / 2,\n", - " 180 + 3.5,\n", - " \"Child Grid\",\n", - " rotation=90,\n", - " ha=\"right\",\n", - " fontsize=10,\n", - " )\n", - " ax1.set_xlim([0, 3500])\n", - " ax1.set_ylim([-110, 250])\n", - " ax1.set_xlabel(\"Distance Along River ($m$)\")\n", - " ax1.set_ylabel(r\"Stream Flow ($\\frac{m^3}{s}$)\")\n", - " ax1.vlines(\n", - " x=(rch_lengths[7] + rch_lengths[8]) / 2,\n", - " ymin=-60,\n", - " ymax=235,\n", - " linewidth=2,\n", - " )\n", - " ax1.vlines(\n", - " x=(rch_lengths[96] + rch_lengths[97]) / 2,\n", - " ymin=-65,\n", - " ymax=235,\n", - " linewidth=2,\n", - " )\n", - "\n", - " ax2 = ax1.twinx()\n", - " ax2.set_xlim([0, 3500])\n", - " ax2.set_ylim([-11, 25])\n", - " # [itm/10 for itm in all_rch_lengths]\n", - " bar = ax2.bar(\n", - " rch_lengths,\n", - " gwsw_exg,\n", - " align=\"center\",\n", - " color=\"b\",\n", - " width=[itm / 2 for itm in all_rch_lengths],\n", - " label=\"GW-SW Exchange\",\n", - " )\n", - " ax2.set_zorder(2)\n", - " ax2.set_axisbelow(True)\n", - " ax2.set_ylabel(\n", - " r\"Groundwater Surface-Water Exchange by Stream Reach ($\\frac{m^3}{s}$)\",\n", - " rotation=270,\n", - " labelpad=15,\n", - " )\n", - " ax2.yaxis.grid(color=\"silver\", zorder=1)\n", - " lns = pts + [bar]\n", - " labs = [l.get_label() for l in lns]\n", - " leg = ax2.legend(lns, labs, loc=\"lower right\", frameon=True)\n", - " leg.get_frame().set_linewidth(0.0)\n", - "\n", - " title = \"River conditions with steady flow\"\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}{config.figure_ext}\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "0f7107e1", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cafcadbd", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sim = build_model(example_name)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cb127350", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "185fefb8", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9114755d", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Mehl and Hill (2013) results\n", - " #\n", - " # Two-dimensional transport in a uniform flow field\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-lgrv.ipynb b/notebooks/ex-gwf-lgrv.ipynb deleted file mode 100644 index 280868b3..00000000 --- a/notebooks/ex-gwf-lgrv.ipynb +++ /dev/null @@ -1,1035 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "7a4b6eee", - "metadata": {}, - "source": [ - "## LGRV example\n", - "\n", - "These are the models described in Vilhelmsen et al. (2012). The parent\n", - "model is 9 layers, the child model is 25 layers.\n" - ] - }, - { - "cell_type": "markdown", - "id": "3c549c65", - "metadata": {}, - "source": [ - "### LGRV Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7b5334d5", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c2e2817c", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import flopy.utils.lgrutil\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "b0280214", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2a3ac180", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "254a76f3", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d6234892", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "aa72cedd", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "883c1f98", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (5, 4)" - ] - }, - { - "cell_type": "markdown", - "id": "8af6ddcc", - "metadata": {}, - "source": [ - "Base simulation and data workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b277c7a8", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "data_ws = os.path.join(config.data_ws, \"ex-gwf-lgrv\")" - ] - }, - { - "cell_type": "markdown", - "id": "b7eeed50", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "89188094", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "f942d6aa", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "38abd1d2", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-lgrv-gr\": {\"configuration\": \"Refined\"},\n", - " \"ex-gwf-lgrv-gc\": {\"configuration\": \"Coarse\"},\n", - " \"ex-gwf-lgrv-lgr\": {\"configuration\": \"LGR\"},\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "9c416bb5", - "metadata": {}, - "source": [ - "Table LGRV Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d16fc146", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 25 # Number of layers in refined model\n", - "nrow = 183 # Number of rows in refined model\n", - "ncol = 147 # Number of columns in refined model\n", - "nlaygc = 9 # Number of layers in coarsened model\n", - "nrowcg = 61 # Number of rows in coarsened model\n", - "ncolcg = 49 # Number of columns in coarsened model\n", - "delr = 35.0 # Column width ($m$) in refined model\n", - "delc = 25.0 # Row width ($m$) in refined model\n", - "delv = 5.0 # Layer thickness ($m$) in refined model\n", - "delrgc = 105.0 # Column width ($m$) in coarsened model\n", - "delcgc = 75.0 # Row width ($m$) in coarsened model\n", - "delvgc = 15.0 # Layer thickness ($m$) in coarsened model\n", - "top_str = \"variable\" # Top of the model ($m$)\n", - "botm_str = \"30 to -90\" # Layer bottom elevations ($m$)\n", - "icelltype = 0 # Cell conversion type\n", - "recharge = 1.1098e-09 # Recharge rate ($m/s$)\n", - "k11_str = \"5.e-07, 1.e-06, 5.e-05\" # Horizontal hydraulic conductivity ($m/s$)" - ] - }, - { - "cell_type": "markdown", - "id": "94d361f9", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation has 1 steady stress period (1 day)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dfee3c32", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [1.0]\n", - "nstp = [1]\n", - "tsmult = [1.0]\n", - "tdis_ds = list(zip(perlen, nstp, tsmult))" - ] - }, - { - "cell_type": "markdown", - "id": "760ed847", - "metadata": {}, - "source": [ - "load data files and process into arrays" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7f397431", - "metadata": {}, - "outputs": [], - "source": [ - "fname = os.path.join(data_ws, \"top.dat\")\n", - "top = np.loadtxt(fname)\n", - "ikzone = np.empty((nlay, nrow, ncol), dtype=float)\n", - "for k in range(nlay):\n", - " fname = os.path.join(data_ws, f\"ikzone{k + 1}.dat\")\n", - " ikzone[k, :, :] = np.loadtxt(fname)\n", - "fname = os.path.join(data_ws, \"riv.dat\")\n", - "dt = [\n", - " (\"k\", int),\n", - " (\"i\", int),\n", - " (\"j\", int),\n", - " (\"stage\", float),\n", - " (\"conductance\", float),\n", - " (\"rbot\", float),\n", - "]\n", - "rivdat = np.loadtxt(fname, dtype=dt)\n", - "rivdat[\"k\"] -= 1\n", - "rivdat[\"i\"] -= 1\n", - "rivdat[\"j\"] -= 1\n", - "riv_spd = [[(k, i, j), stage, cond, rbot] for k, i, j, stage, cond, rbot in rivdat]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fbb653a4", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [30 - k * delv for k in range(nlay)]\n", - "botm = np.array(botm)\n", - "k11_values = [float(value) for value in k11_str.split(\",\")]\n", - "k11 = np.zeros((nlay, nrow, ncol), dtype=float)\n", - "for i, kval in enumerate(k11_values):\n", - " k11 = np.where(ikzone == i + 1, kval, k11)" - ] - }, - { - "cell_type": "markdown", - "id": "edbca64c", - "metadata": {}, - "source": [ - "Define model extent and child model extent" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c4779ace", - "metadata": {}, - "outputs": [], - "source": [ - "xmin = 0\n", - "xmax = ncol * delr\n", - "ymin = 0.0\n", - "ymax = nrow * delc\n", - "model_domain = [xmin, xmax, ymin, ymax]\n", - "child_domain = [\n", - " xmin + 15 * 3 * delr,\n", - " xmin + 41 * 3 * delr,\n", - " ymax - 49 * 3 * delc,\n", - " ymax - 19 * 3 * delc,\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "af79df3f", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c45c4011", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 50\n", - "ninner = 100\n", - "hclose = 1e-6\n", - "rclose = 100.0" - ] - }, - { - "cell_type": "markdown", - "id": "eff4568f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 LGRV model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3a4362e1", - "metadata": {}, - "outputs": [], - "source": [ - "def coarsen_shape(icoarsen, nrow, ncol):\n", - " nrowc = int(np.ceil(nrow / icoarsen))\n", - " ncolc = int(np.ceil(ncol / icoarsen))\n", - " return (nrowc, ncolc)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7c66da6b", - "metadata": {}, - "outputs": [], - "source": [ - "def create_resampling_labels(a, icoarsen):\n", - " nrow, ncol = a.shape\n", - " labels = np.zeros((nrow, ncol), dtype=int)\n", - " nodec = 0\n", - " for ic in range(0, nrow, icoarsen):\n", - " for jc in range(0, ncol, icoarsen):\n", - " labels[ic : ic + icoarsen, jc : jc + icoarsen] = nodec\n", - " nodec += 1\n", - " return labels" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "286e8dcd", - "metadata": {}, - "outputs": [], - "source": [ - "def array_resampler(a, icoarsen, method):\n", - " import scipy.ndimage as ndimage\n", - "\n", - " assert method in [\"mean\", \"minimum\", \"maximum\", \"sum\"]\n", - " nrow, ncol = a.shape\n", - " nrowc, ncolc = coarsen_shape(icoarsen, nrow, ncol)\n", - " labels = create_resampling_labels(a, icoarsen)\n", - " idx = np.array(range(nrowc * ncolc))\n", - " if method == \"mean\":\n", - " ar = ndimage.mean(a, labels=labels, index=idx)\n", - " elif method == \"minimum\":\n", - " ar = ndimage.minimum(a, labels=labels, index=idx)\n", - " elif method == \"maximum\":\n", - " ar = ndimage.maximum(a, labels=labels, index=idx)\n", - " elif method == \"sum\":\n", - " ar = ndimage.sum(a, labels=labels, index=idx)\n", - " return ar.reshape((nrowc, ncolc))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4e437123", - "metadata": {}, - "outputs": [], - "source": [ - "def riv_resample(icoarsen, nrow, ncol, rivdat, idomain, rowcolspan):\n", - " stage_grid = np.zeros((nrow, ncol), dtype=float)\n", - " cond_grid = np.zeros((nrow, ncol), dtype=float)\n", - " rbot_grid = np.zeros((nrow, ncol), dtype=float)\n", - " count_grid = np.zeros((nrow, ncol), dtype=int)\n", - " for k, i, j, stage, cond, rbot in rivdat:\n", - " stage_grid[i, j] = stage\n", - " cond_grid[i, j] = cond\n", - " rbot_grid[i, j] = rbot\n", - " count_grid[i, j] += 1\n", - " stagec_grid = array_resampler(stage_grid, icoarsen, \"sum\")\n", - " condc_grid = array_resampler(cond_grid, icoarsen, \"sum\")\n", - " rbotc_grid = array_resampler(rbot_grid, icoarsen, \"sum\")\n", - " countc_grid = array_resampler(count_grid, icoarsen, \"sum\")\n", - " stagec_grid = np.divide(stagec_grid, countc_grid)\n", - " rbotc_grid = np.divide(rbotc_grid, countc_grid)\n", - " if rowcolspan is not None:\n", - " istart, istop, jstart, jstop = rowcolspan\n", - " stagec_grid = stagec_grid[istart:istop, jstart:jstop]\n", - " condc_grid = condc_grid[istart:istop, jstart:jstop]\n", - " rbotc_grid = rbotc_grid[istart:istop, jstart:jstop]\n", - " countc_grid = countc_grid[istart:istop, jstart:jstop]\n", - " rows, cols = np.where(condc_grid > 0.0)\n", - " rivdatc = []\n", - " for i, j in zip(rows, cols):\n", - " k = 0\n", - " if idomain[k, i, j] == 1:\n", - " rivdatc.append(\n", - " [\n", - " (k, i, j),\n", - " stagec_grid[i, j],\n", - " condc_grid[i, j],\n", - " rbotc_grid[i, j],\n", - " ]\n", - " )\n", - " return rivdatc" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d245f899", - "metadata": {}, - "outputs": [], - "source": [ - "def build_lgr_model(sim_name):\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - "\n", - " # parent model with coarse grid\n", - " icoarsen = 3\n", - " ncppl = [1, 3, 3, 3, 3, 3, 3, 3, 3]\n", - " sim = build_parent_model(sim, sim_name, icoarsen=icoarsen, ncppl=ncppl)\n", - " gwf = sim.get_model(\"parent\")\n", - "\n", - " # child model with fine grid\n", - " sim = build_child_model(sim, sim_name)\n", - " gwfc = sim.get_model(\"child\")\n", - "\n", - " # use flopy lgr utility to wire up connections between parent and child\n", - " nlayp = len(ncppl)\n", - " nrowp = gwf.dis.nrow.get_data()\n", - " ncolp = gwf.dis.ncol.get_data()\n", - " delrp = gwf.dis.delr.array\n", - " delcp = gwf.dis.delc.array\n", - " topp = gwf.dis.top.array\n", - " botmp = gwf.dis.botm.array\n", - " idomainp = gwf.dis.idomain.array\n", - " lgr = flopy.utils.lgrutil.Lgr(\n", - " nlayp,\n", - " nrowp,\n", - " ncolp,\n", - " delrp,\n", - " delcp,\n", - " topp,\n", - " botmp,\n", - " idomainp,\n", - " ncpp=icoarsen,\n", - " ncppl=ncppl,\n", - " )\n", - "\n", - " # swap out lgr child top and botm with\n", - " topc = gwfc.dis.top.array\n", - " botmc = gwfc.dis.botm.array\n", - " lgr.top = topc\n", - " lgr.botm = botmc\n", - " exgdata = lgr.get_exchange_data(angldegx=True, cdist=True)\n", - " flopy.mf6.ModflowGwfgwf(\n", - " sim,\n", - " nexg=len(exgdata),\n", - " exgtype=\"GWF6-GWF6\",\n", - " exgmnamea=\"parent\",\n", - " exgmnameb=\"child\",\n", - " exchangedata=exgdata,\n", - " auxiliary=[\"angldegx\", \"cdist\"],\n", - " )\n", - "\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0f49f0ef", - "metadata": {}, - "outputs": [], - "source": [ - "def build_parent_model(sim, sim_name, icoarsen, ncppl):\n", - " xminp, xmaxp, yminp, ymaxp = model_domain\n", - " xminc, xmaxc, yminc, ymaxc = child_domain\n", - " delcp = delc * icoarsen\n", - " delrp = delr * icoarsen\n", - " istart = int((ymaxp - ymaxc) / delcp)\n", - " istop = int((ymaxp - yminc) / delcp)\n", - " jstart = int((xminc - xminp) / delrp)\n", - " jstop = int((xmaxc - xminp) / delrp)\n", - " nrowp, ncolp = coarsen_shape(icoarsen, nrow, ncol)\n", - " nlayp = len(ncppl)\n", - " idomain = np.ones((nlayp, nrowp, ncolp), dtype=int)\n", - " idomain[:, istart:istop, jstart:jstop] = 0\n", - " sim = build_model(\n", - " sim_name,\n", - " icoarsen=icoarsen,\n", - " ncppl=ncppl,\n", - " idomain=idomain,\n", - " sim=sim,\n", - " modelname=\"parent\",\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "235b23f6", - "metadata": {}, - "outputs": [], - "source": [ - "def build_child_model(sim, sim_name):\n", - " icoarsen = 1\n", - " xminp, xmaxp, yminp, ymaxp = model_domain\n", - " xminc, xmaxc, yminc, ymaxc = child_domain\n", - " delcp = delc * icoarsen\n", - " delrp = delr * icoarsen\n", - " istart = int((ymaxp - ymaxc) / delcp)\n", - " istop = int((ymaxp - yminc) / delcp)\n", - " jstart = int((xminc - xminp) / delrp)\n", - " jstop = int((xmaxc - xminp) / delrp)\n", - " nrowp, ncolp = coarsen_shape(icoarsen, nrow, ncol)\n", - " sim = build_model(\n", - " sim_name,\n", - " rowcolspan=[istart, istop, jstart, jstop],\n", - " sim=sim,\n", - " modelname=\"child\",\n", - " xorigin=xminc,\n", - " yorigin=yminc,\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c75c4c90", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(\n", - " sim_name,\n", - " icoarsen=1,\n", - " ncppl=None,\n", - " rowcolspan=None,\n", - " idomain=None,\n", - " sim=None,\n", - " modelname=None,\n", - " xorigin=None,\n", - " yorigin=None,\n", - "):\n", - " if config.buildModel:\n", - " if sim is None:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " if modelname is None:\n", - " modelname = sim_name\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=modelname, save_flows=True)\n", - "\n", - " if ncppl is not None:\n", - " nlayc = len(ncppl)\n", - " layer_index = [ncppl[0] - 1]\n", - " for iln in ncppl[1:]:\n", - " last = layer_index[-1]\n", - " layer_index.append(iln + last)\n", - " else:\n", - " nlayc = nlay\n", - " layer_index = list(range(nlayc))\n", - " nrowc, ncolc = coarsen_shape(icoarsen, nrow, ncol)\n", - " delrc = delr * icoarsen\n", - " delcc = delc * icoarsen\n", - " topc = array_resampler(top, icoarsen, \"mean\")\n", - " if rowcolspan is not None:\n", - " istart, istop, jstart, jstop = rowcolspan\n", - " nrowc = istop - istart\n", - " ncolc = jstop - jstart\n", - " else:\n", - " istart = 0\n", - " istop = nrow\n", - " jstart = 0\n", - " jstop = ncol\n", - " if idomain is None:\n", - " idomain = 1\n", - " topc = topc[istart:istop, jstart:jstop]\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlayc,\n", - " nrow=nrowc,\n", - " ncol=ncolc,\n", - " delr=delrc,\n", - " delc=delcc,\n", - " top=topc,\n", - " botm=botm[layer_index],\n", - " idomain=idomain,\n", - " xorigin=xorigin,\n", - " yorigin=yorigin,\n", - " )\n", - " idomain = gwf.dis.idomain.array\n", - " k11c = []\n", - " for k in range(nlayc):\n", - " ilay = layer_index[k]\n", - " a = array_resampler(k11[ilay], icoarsen, \"maximum\")\n", - " k11c.append(a[istart:istop, jstart:jstop])\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " k33overk=True,\n", - " icelltype=icelltype,\n", - " k=k11c,\n", - " save_specific_discharge=True,\n", - " k33=1.0,\n", - " )\n", - " strt = nlayc * [topc]\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - "\n", - " rivdatc = riv_resample(icoarsen, nrow, ncol, rivdat, idomain, rowcolspan)\n", - " riv_spd = {0: rivdatc}\n", - " flopy.mf6.ModflowGwfriv(\n", - " gwf,\n", - " stress_period_data=riv_spd,\n", - " pname=\"RIV\",\n", - " )\n", - " flopy.mf6.ModflowGwfrcha(gwf, recharge=recharge, pname=\"RCH\")\n", - " head_filerecord = f\"{modelname}.hds\"\n", - " budget_filerecord = f\"{modelname}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "d0454c30", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 LGRV model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e518bc81", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " print(f\"Writing simulation {sim.name}\")\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "879c9687", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the LGRV model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7edc174c", - "metadata": {}, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=False):\n", - " success = True\n", - " if config.runModel:\n", - " print(f\"Running simulation {sim.name}\")\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b5623cf0", - "metadata": {}, - "outputs": [], - "source": [ - "# Function to plot the LGRV model results.\n", - "#\n", - "def plot_grid(sim):\n", - " print(f\"Plotting grid for {sim.name}...\")\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = sim.simulation_data.mfpath.get_sim_path()\n", - " sim_name = sim.name\n", - " gwf = sim.get_model(\"parent\")\n", - " gwfc = None\n", - " if \"child\" in list(sim.model_names):\n", - " gwfc = sim.get_model(\"child\")\n", - "\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " # pmv.plot_grid()\n", - " idomain = gwf.dis.idomain.array\n", - " tp = np.ma.masked_where(idomain[0] == 0, gwf.dis.top.array)\n", - " vmin = tp.min()\n", - " vmax = tp.max()\n", - " if gwfc is not None:\n", - " tpc = gwfc.dis.top.array\n", - " vmin = min(vmin, tpc.min())\n", - " vmax = max(vmax, tpc.max())\n", - "\n", - " cb = pmv.plot_array(tp, cmap=\"jet\", alpha=0.25, vmin=vmin, vmax=vmax)\n", - " pmv.plot_bc(name=\"RIV\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - " cbar = plt.colorbar(cb, shrink=0.5)\n", - " cbar.ax.set_xlabel(r\"Top, ($m$)\")\n", - " if gwfc is not None:\n", - " pmv = flopy.plot.PlotMapView(model=gwfc, ax=ax, layer=0)\n", - " _ = pmv.plot_array(\n", - " tpc,\n", - " cmap=\"jet\",\n", - " alpha=0.25,\n", - " masked_values=[1e30],\n", - " vmin=vmin,\n", - " vmax=vmax,\n", - " )\n", - " pmv.plot_bc(name=\"RIV\")\n", - " if gwfc is not None:\n", - " xmin, xmax, ymin, ymax = child_domain\n", - " ax.plot(\n", - " [xmin, xmax, xmax, xmin, xmin],\n", - " [ymin, ymin, ymax, ymax, ymin],\n", - " \"k--\",\n", - " )\n", - " xmin, xmax, ymin, ymax = model_domain\n", - " ax.set_xlim(xmin, xmax)\n", - " ax.set_ylim(ymin, ymax)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3b664bbe", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_xsect(sim):\n", - " print(f\"Plotting cross section for {sim.name}...\")\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = sim.simulation_data.mfpath.get_sim_path()\n", - " sim_name = sim.name\n", - " gwf = sim.get_model(\"parent\")\n", - "\n", - " fig = plt.figure(figsize=(5, 2.5))\n", - " fig.tight_layout()\n", - "\n", - " ax = fig.add_subplot(1, 1, 1)\n", - " irow, icol = gwf.modelgrid.intersect(3000.0, 3000.0)\n", - " pmv = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"column\": icol})\n", - " pmv.plot_grid(linewidth=0.5)\n", - " hyc = np.log(gwf.npf.k.array)\n", - " cb = pmv.plot_array(hyc, cmap=\"jet\", alpha=0.25)\n", - " ax.set_xlabel(\"y position (m)\")\n", - " ax.set_ylabel(\"z position (m)\")\n", - " cbar = plt.colorbar(cb, shrink=0.5)\n", - " cbar.ax.set_xlabel(r\"K, ($m/s$)\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-xsect{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6ec08b7b", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_heads(sim):\n", - " print(f\"Plotting results for {sim.name} ...\")\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = sim.simulation_data.mfpath.get_sim_path()\n", - " sim_name = sim.name\n", - " gwf = sim.get_model(\"parent\")\n", - " modelname = gwf.name\n", - " gwfc = None\n", - " if \"child\" in list(sim.model_names):\n", - " gwfc = sim.get_model(\"child\")\n", - "\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " print(\" Loading heads...\")\n", - " layer = 0\n", - " head = gwf.output.head().get_data()\n", - " head = np.ma.masked_where(head > 1e29, head)\n", - " vmin = head[layer].min()\n", - " vmax = head[layer].max()\n", - " if gwfc is not None:\n", - " headc = gwfc.output.head().get_data()\n", - " vmin = min(vmin, headc.min())\n", - " vmax = max(vmax, headc.max())\n", - "\n", - " print(\" Making figure...\")\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " cb = pmv.plot_array(head, cmap=\"jet\", masked_values=[1e30], vmin=vmin, vmax=vmax)\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - " cbar = plt.colorbar(cb, shrink=0.5)\n", - " cbar.ax.set_xlabel(r\"Head, ($m$)\")\n", - " if gwfc is not None:\n", - " pmv = flopy.plot.PlotMapView(model=gwfc, ax=ax, layer=0)\n", - " cb = pmv.plot_array(\n", - " headc, cmap=\"jet\", masked_values=[1e30], vmin=vmin, vmax=vmax\n", - " )\n", - " xmin, xmax, ymin, ymax = child_domain\n", - " ax.plot(\n", - " [xmin, xmax, xmax, xmin, xmin],\n", - " [ymin, ymin, ymax, ymax, ymin],\n", - " \"k--\",\n", - " )\n", - " xmin, xmax, ymin, ymax = model_domain\n", - " ax.set_xlim(xmin, xmax)\n", - " ax.set_ylim(ymin, ymax)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-head{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e541e782", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " plot_grid(sim)\n", - " plot_xsect(sim)\n", - " plot_heads(sim)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "fe14db5f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the LGRV model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e0903fe6", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - " if params[\"configuration\"] == \"Refined\":\n", - " sim = build_model(key, modelname=\"parent\")\n", - " elif params[\"configuration\"] == \"Coarse\":\n", - " ncppl = [1, 3, 3, 3, 3, 3, 3, 3, 3]\n", - " sim = build_model(key, icoarsen=3, ncppl=ncppl, modelname=\"parent\")\n", - " elif params[\"configuration\"] == \"LGR\":\n", - " sim = build_lgr_model(key)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8622883e", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4a85a500", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " simulation(1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "10950541", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " simulation(2, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "d289c9d9", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bdbe628e", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### LGRV Simulation\n", - " #\n", - " # Global Refined Model\n", - "\n", - " simulation(0)\n", - "\n", - " # Global Coarse Model\n", - "\n", - " simulation(1)\n", - "\n", - " # Locally Refined Grid Model\n", - "\n", - " simulation(2)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-maw-p01.ipynb b/notebooks/ex-gwf-maw-p01.ipynb deleted file mode 100644 index 5e1197d3..00000000 --- a/notebooks/ex-gwf-maw-p01.ipynb +++ /dev/null @@ -1,885 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e4e3202f", - "metadata": {}, - "source": [ - "## Neville-Tonkin Multi-Aquifer Well Problem,\n", - "\n", - "This is the Neville-Tonkin Multi-Aquifer Well from the\n", - "Lake Package documentation (Neville and Tonkin, 2004).\n" - ] - }, - { - "cell_type": "markdown", - "id": "25048471", - "metadata": {}, - "source": [ - "### Neville-Tonkin MAW Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8d25a200", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5869cc08", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "3be27d44", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2d46993f", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "331b7b6f", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "56635740", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "a579efcc", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "82eea462", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.3, 4.3)\n", - "masked_values = (0, 1e30, -1e30)" - ] - }, - { - "cell_type": "markdown", - "id": "67e4c11c", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3c30fc94", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "d492f475", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f5d407b3", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-maw-p01\"" - ] - }, - { - "cell_type": "markdown", - "id": "5de5d48c", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "45da9335", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "01374fda", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b3802f1", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-maw-p01a\": {\n", - " \"rate\": 0.0,\n", - " },\n", - " \"ex-gwf-maw-p01b\": {\n", - " \"rate\": -1767.0,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "daf2a10d", - "metadata": {}, - "source": [ - "Table Neville-Tonkin MAW Problem Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c7fc312", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 2 # Number of layers\n", - "nrow = 101 # Number of rows\n", - "ncol = 101 # Number of columns\n", - "delr = 142.0 # Column width ($m$)\n", - "delc = 142.0 # Row width ($m$)\n", - "top = -50.0 # Top of the model ($m$)\n", - "botm_str = \"-142.9, -514.5\" # Bottom elevations ($m$)\n", - "strt_str = \"3.05, 9.14\" # Starting head ($m$)\n", - "k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$)\n", - "k33 = 1.0e-16 # Vertical hydraulic conductivity ($m/d$)\n", - "ss = 1e-4 # Specific storage ($1/d$)\n", - "maw_radius = 0.15 # Well radius ($m$)" - ] - }, - { - "cell_type": "markdown", - "id": "30104721", - "metadata": {}, - "source": [ - "parse parameter strings into tuples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a10ff733", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]\n", - "strt = [float(value) for value in strt_str.split(\",\")]" - ] - }, - { - "cell_type": "markdown", - "id": "e53e4e74", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "15030f61", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((2.314815, 50, 1.2),)" - ] - }, - { - "cell_type": "markdown", - "id": "f32e419e", - "metadata": {}, - "source": [ - "Define dimensions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2924446e", - "metadata": {}, - "outputs": [], - "source": [ - "extents = (0.0, delr * ncol, 0.0, delc * nrow)\n", - "shape2d = (nrow, ncol)\n", - "shape3d = (nlay, nrow, ncol)" - ] - }, - { - "cell_type": "markdown", - "id": "752ac9b5", - "metadata": {}, - "source": [ - "create idomain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "35f087bd", - "metadata": {}, - "outputs": [], - "source": [ - "idomain = np.ones(shape3d, dtype=float)\n", - "xw, yw = (ncol / 2) * delr, (nrow / 2) * delc\n", - "y = 0.0\n", - "for i in range(nrow):\n", - " x = 0.0\n", - " y = (float(i) + 0.5) * delc\n", - " for j in range(ncol):\n", - " x = (float(j) + 0.5) * delr\n", - " r = np.sqrt((x - xw) ** 2.0 + (y - yw) ** 2.0)\n", - " if r > 7163.0:\n", - " idomain[:, i, j] = 0" - ] - }, - { - "cell_type": "markdown", - "id": "88897c15", - "metadata": {}, - "source": [ - "### Create Neville-Tonkin MAW Problem Model Boundary Conditions" - ] - }, - { - "cell_type": "markdown", - "id": "cd5f1483", - "metadata": {}, - "source": [ - "MAW Package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef37bba3", - "metadata": {}, - "outputs": [], - "source": [ - "maw_row = int(nrow / 2)\n", - "maw_col = int(ncol / 2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fa9ca8d6", - "metadata": {}, - "outputs": [], - "source": [ - "maw_packagedata = [[0, maw_radius, botm[-1], strt[-1], \"THIEM\", 2]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e7443798", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "maw_conn = [\n", - " [0, 0, 0, maw_row, maw_col, top, botm[-1], -999.0, -999.0],\n", - " [0, 1, 1, maw_row, maw_col, top, botm[-1], -999.0, -999.0],\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "dbb5d8fa", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "50139015", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-4" - ] - }, - { - "cell_type": "markdown", - "id": "bce8c253", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 Neville-Tonkin MAW Problem model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "123cc330", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(name, rate=0.0):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=0,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=0,\n", - " ss=ss,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - "\n", - " maw_spd = [[0, \"rate\", rate]]\n", - " maw = flopy.mf6.ModflowGwfmaw(\n", - " gwf,\n", - " no_well_storage=True,\n", - " nmawwells=1,\n", - " packagedata=maw_packagedata,\n", - " connectiondata=maw_conn,\n", - " perioddata=maw_spd,\n", - " )\n", - " obs_file = f\"{sim_name}.maw.obs\"\n", - " csv_file = obs_file + \".csv\"\n", - " obs_dict = {\n", - " csv_file: [\n", - " (\"head\", \"head\", (0,)),\n", - " (\"Q1\", \"maw\", (0,), (0,)),\n", - " (\"Q2\", \"maw\", (0,), (1,)),\n", - " ]\n", - " }\n", - " maw.obs.initialize(\n", - " filename=obs_file, digits=10, print_input=True, continuous=obs_dict\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " printrecord=[(\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "04197969", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 Neville-Tonkin MAW Problem model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f8dbfe2c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "66e4a732", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the Neville-Tonkin MAW Problem model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "15c9ef05", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "e27bb3b1", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the lake results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "84311774", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_maw_results(silent=True):\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " # load the observations\n", - " name = list(parameters.keys())[0]\n", - " fpth = os.path.join(ws, name, f\"{sim_name}.maw.obs.csv\")\n", - " maw0 = flopy.utils.Mf6Obs(fpth).data\n", - " name = list(parameters.keys())[1]\n", - " fpth = os.path.join(ws, name, f\"{sim_name}.maw.obs.csv\")\n", - " maw1 = flopy.utils.Mf6Obs(fpth).data\n", - "\n", - " time = maw0[\"totim\"] * 86400.0\n", - "\n", - " tmin = time[0]\n", - " tmax = time[-1]\n", - "\n", - " # create the figure\n", - " fig, axes = plt.subplots(\n", - " ncols=1,\n", - " nrows=2,\n", - " sharex=True,\n", - " figsize=figure_size,\n", - " constrained_layout=True,\n", - " )\n", - "\n", - " ax = axes[0]\n", - " ax.set_xlim(tmin, tmax)\n", - " ax.set_ylim(-1000, 1000)\n", - " ax.semilogx(\n", - " time,\n", - " maw0[\"Q1\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"blue\",\n", - " label=\"Upper aquifer\",\n", - " )\n", - " ax.semilogx(\n", - " time,\n", - " maw0[\"Q2\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"red\",\n", - " label=\"Lower aquifer\",\n", - " )\n", - " ax.axhline(0, lw=0.5, color=\"0.5\")\n", - " ax.set_ylabel(\" \")\n", - " fs.heading(ax, heading=\"Non-pumping case\", idx=0)\n", - " fs.graph_legend(ax, loc=\"upper right\", ncol=2)\n", - "\n", - " ax = axes[1]\n", - " ax.set_xlim(tmin, tmax)\n", - " ax.set_ylim(-500, 2500)\n", - " ax.semilogx(\n", - " time,\n", - " maw1[\"Q1\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"blue\",\n", - " label=\"Upper aquifer\",\n", - " )\n", - " ax.semilogx(\n", - " time,\n", - " maw1[\"Q2\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"red\",\n", - " label=\"Lower aquifer\",\n", - " )\n", - " ax.axhline(0, lw=0.5, color=\"0.5\")\n", - " ax.set_xlabel(\" \")\n", - " ax.set_ylabel(\" \")\n", - " for axis in (ax.xaxis,):\n", - " axis.set_major_formatter(mpl.ticker.ScalarFormatter())\n", - " fs.heading(ax, heading=\"Pumping case\", idx=1)\n", - "\n", - " # add y-axis label that spans both subplots\n", - " ax = fig.add_subplot(1, 1, 1)\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " # ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " ax.set_xlabel(\"Simulation time, in seconds\")\n", - " ax.set_ylabel(\"Discharge rate, in cubic meters per day\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-01{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "316fd405", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Plot the grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e95af62b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(silent=True):\n", - " if silent:\n", - " verbosity = 0\n", - " else:\n", - " verbosity = 1\n", - " name = list(parameters.keys())[0]\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity\n", - " )\n", - " gwf = sim.get_model(sim_name)\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " fig = plt.figure(\n", - " figsize=(4, 4.3),\n", - " tight_layout=True,\n", - " )\n", - " plt.axis(\"off\")\n", - "\n", - " nrows, ncols = 10, 1\n", - " axes = [fig.add_subplot(nrows, ncols, (1, 8))]\n", - "\n", - " for idx, ax in enumerate(axes):\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - " ax.set_aspect(\"equal\")\n", - "\n", - " # legend axis\n", - " axes.append(fig.add_subplot(nrows, ncols, (9, 10)))\n", - "\n", - " # set limits for legend area\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " mm.plot_bc(\"MAW\", color=\"red\")\n", - " mm.plot_inactive(color_noflow=\"black\")\n", - " ax.set_xticks([0, extents[1] / 2, extents[1]])\n", - " ax.set_yticks([0, extents[1] / 2, extents[1]])\n", - "\n", - " ax = axes[-1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"black\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Inactive cells\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"red\",\n", - " mec=\"red\",\n", - " markeredgewidth=0.5,\n", - " label=\"Multi-aquifer well\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"lower center\", ncol=2)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "afa19765", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the Neville-Tonkin MAW Problem model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "62fe8d79", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(silent=True):\n", - " if config.plotModel:\n", - " plot_grid(silent=silent)\n", - " plot_maw_results(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "9d1115a0", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the Neville-Tonkin MAW Problem model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4a9fbb82", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx=0, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - "\n", - " sim = build_model(key, **params)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, f\"could not run...{sim_name}\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ae49ce30", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(idx=0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b489ec22", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " simulation(idx=1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c43b71a9", - "metadata": {}, - "outputs": [], - "source": [ - "def test_plot():\n", - " plot_results()" - ] - }, - { - "cell_type": "markdown", - "id": "068049d6", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "09db4111", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Neville-Tonkin MAW Problem Simulation\n", - " #\n", - " # No pumping case\n", - "\n", - " simulation(0)\n", - "\n", - " # Pumping case\n", - "\n", - " simulation(1)\n", - "\n", - " # Plot the results\n", - "\n", - " plot_results()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-maw-p02.ipynb b/notebooks/ex-gwf-maw-p02.ipynb deleted file mode 100644 index 05d9a917..00000000 --- a/notebooks/ex-gwf-maw-p02.ipynb +++ /dev/null @@ -1,830 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "acf112de", - "metadata": {}, - "source": [ - "## Flowing well Multi-Aquifer Well Problem,\n", - "\n", - "This is a modified version of the Neville-Tonkin Multi-Aquifer Well problem\n", - "from Neville and Tonkin, 2004 that uses the flowing well option.\n" - ] - }, - { - "cell_type": "markdown", - "id": "10411fed", - "metadata": {}, - "source": [ - "### Flowing Well Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2d0b35db", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ea1f7427", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "c07ec82d", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c9ab12d", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "83f1c5d1", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b203d161", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "30f357a0", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "235ca699", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.3, 4.3)\n", - "masked_values = (0, 1e30, -1e30)" - ] - }, - { - "cell_type": "markdown", - "id": "dc77924e", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "82c1d11d", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "817ba99c", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06472525", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-maw-p02\"" - ] - }, - { - "cell_type": "markdown", - "id": "52c992d7", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "823ef2a1", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "38cd2d12", - "metadata": {}, - "source": [ - "Table Flowing Well Problem Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "404c8115", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 2 # Number of layers\n", - "nrow = 101 # Number of rows\n", - "ncol = 101 # Number of columns\n", - "delr = 142.0 # Column width ($m$)\n", - "delc = 142.0 # Row width ($m$)\n", - "top = -50.0 # Top of the model ($m$)\n", - "botm_str = \"-142.9, -514.5\" # Bottom elevations ($m$)\n", - "strt_str = \"3.05, 9.14\" # Starting head ($m$)\n", - "k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$)\n", - "k33 = 1.0e-16 # Vertical hydraulic conductivity ($m/d$)\n", - "ss = 1e-4 # Specific storage ($1/d$)\n", - "maw_radius = 0.15 # Well radius ($m$)\n", - "maw_rate = 0.0 # Well pumping rate ($m^{3}/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "56bc0bcc", - "metadata": {}, - "source": [ - "parse parameter strings into tuples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "12dcbd6b", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]\n", - "strt = [float(value) for value in strt_str.split(\",\")]" - ] - }, - { - "cell_type": "markdown", - "id": "4fcbb08e", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c2799ccd", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((2.314815, 50, 1.2),)" - ] - }, - { - "cell_type": "markdown", - "id": "f3730059", - "metadata": {}, - "source": [ - "Define dimensions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6a20e78a", - "metadata": {}, - "outputs": [], - "source": [ - "extents = (0.0, delr * ncol, 0.0, delc * nrow)\n", - "shape2d = (nrow, ncol)\n", - "shape3d = (nlay, nrow, ncol)" - ] - }, - { - "cell_type": "markdown", - "id": "6b44ce71", - "metadata": {}, - "source": [ - "create idomain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f3ee8c75", - "metadata": {}, - "outputs": [], - "source": [ - "idomain = np.ones(shape3d, dtype=float)\n", - "xw, yw = (ncol / 2) * delr, (nrow / 2) * delc\n", - "y = 0.0\n", - "for i in range(nrow):\n", - " x = 0.0\n", - " y = (float(i) + 0.5) * delc\n", - " for j in range(ncol):\n", - " x = (float(j) + 0.5) * delr\n", - " r = np.sqrt((x - xw) ** 2.0 + (y - yw) ** 2.0)\n", - " if r > 7163.0:\n", - " idomain[:, i, j] = 0" - ] - }, - { - "cell_type": "markdown", - "id": "c48d33a9", - "metadata": {}, - "source": [ - "### Create Flowing Well Problem Model Boundary Conditions" - ] - }, - { - "cell_type": "markdown", - "id": "e55fa989", - "metadata": {}, - "source": [ - "MAW Package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b8a6821", - "metadata": {}, - "outputs": [], - "source": [ - "maw_row = int(nrow / 2)\n", - "maw_col = int(ncol / 2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3a5277c4", - "metadata": {}, - "outputs": [], - "source": [ - "maw_packagedata = [[0, maw_radius, botm[-1], strt[-1], \"SPECIFIED\", 2]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "58458650", - "metadata": {}, - "outputs": [], - "source": [ - "maw_conn = [\n", - " [0, 0, 0, maw_row, maw_col, top, botm[-1], 111.3763, -999.0],\n", - " [0, 1, 1, maw_row, maw_col, top, botm[-1], 445.9849, -999.0],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5a35a92b", - "metadata": {}, - "outputs": [], - "source": [ - "maw_spd = [[0, \"rate\", maw_rate], [0, \"flowing_well\", 0.0, 7500.0, 0.5]]" - ] - }, - { - "cell_type": "markdown", - "id": "eb1480c1", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cc69f357", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-4" - ] - }, - { - "cell_type": "markdown", - "id": "75fd83d9", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 Flowing Well Problem model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ae99235f", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=0,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=0,\n", - " ss=ss,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - "\n", - " maw = flopy.mf6.ModflowGwfmaw(\n", - " gwf,\n", - " flowing_wells=True,\n", - " nmawwells=1,\n", - " packagedata=maw_packagedata,\n", - " connectiondata=maw_conn,\n", - " perioddata=maw_spd,\n", - " )\n", - " obs_file = f\"{sim_name}.maw.obs\"\n", - " csv_file = obs_file + \".csv\"\n", - " obs_dict = {\n", - " csv_file: [\n", - " (\"head\", \"head\", (0,)),\n", - " (\"Q1\", \"maw\", (0,), (0,)),\n", - " (\"Q2\", \"maw\", (0,), (1,)),\n", - " (\"FW\", \"fw-rate\", (0,)),\n", - " ]\n", - " }\n", - " maw.obs.initialize(\n", - " filename=obs_file, digits=10, print_input=True, continuous=obs_dict\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " printrecord=[(\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "1cd1c30a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 Flowing Well Problem model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "153ef461", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "1083a011", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the Flowing Well Problem model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e9b3b1f", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "eb795335", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the lake results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "34583646", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_maw_results(silent=True):\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " # load the observations\n", - " fpth = os.path.join(ws, sim_name, f\"{sim_name}.maw.obs.csv\")\n", - " maw = flopy.utils.Mf6Obs(fpth).data\n", - "\n", - " time = maw[\"totim\"] * 86400.0\n", - "\n", - " tmin = time[0]\n", - " tmax = time[-1]\n", - "\n", - " # create the figure\n", - " fig, axes = plt.subplots(\n", - " ncols=1,\n", - " nrows=2,\n", - " sharex=True,\n", - " figsize=figure_size,\n", - " constrained_layout=True,\n", - " )\n", - "\n", - " ax = axes[0]\n", - " ax.set_xlim(tmin, tmax)\n", - " ax.set_ylim(0, 4500)\n", - " ax.semilogx(\n", - " time,\n", - " maw[\"Q1\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"blue\",\n", - " label=\"Upper aquifer\",\n", - " )\n", - " ax.semilogx(\n", - " time,\n", - " maw[\"Q2\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"red\",\n", - " label=\"Lower aquifer\",\n", - " )\n", - " ax.axhline(0, lw=0.5, color=\"0.5\")\n", - " ax.set_ylabel(\" \")\n", - " fs.heading(ax, idx=0)\n", - " # fs.graph_legend(ax, loc=\"upper right\", ncol=2)\n", - "\n", - " ax = axes[1]\n", - " ax.set_xlim(tmin, tmax)\n", - " ax.set_ylim(-4500, 0)\n", - " ax.axhline(\n", - " 10.0,\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"blue\",\n", - " label=\"Upper aquifer\",\n", - " )\n", - " ax.axhline(\n", - " 10.0,\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"red\",\n", - " label=\"Lower aquifer\",\n", - " )\n", - " ax.semilogx(\n", - " time,\n", - " maw[\"FW\"],\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"black\",\n", - " label=\"Flowing well discharge\",\n", - " )\n", - " ax.set_xlabel(\" \")\n", - " ax.set_ylabel(\" \")\n", - " for axis in (ax.xaxis,):\n", - " axis.set_major_formatter(mpl.ticker.ScalarFormatter())\n", - " fs.heading(ax, idx=1)\n", - " fs.graph_legend(ax, loc=\"upper left\", ncol=1)\n", - "\n", - " # add y-axis label that spans both subplots\n", - " ax = fig.add_subplot(1, 1, 1)\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " # ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " ax.set_xlabel(\"Simulation time, in seconds\")\n", - " ax.set_ylabel(\"Discharge rate, in cubic meters per day\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-01{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "c8802cf0", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Plot the grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "820a8435", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(sim, silent=True):\n", - " gwf = sim.get_model(sim_name)\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " fig = plt.figure(\n", - " figsize=(4, 4.3),\n", - " tight_layout=True,\n", - " )\n", - " plt.axis(\"off\")\n", - "\n", - " nrows, ncols = 10, 1\n", - " axes = [fig.add_subplot(nrows, ncols, (1, 8))]\n", - "\n", - " for idx, ax in enumerate(axes):\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - " ax.set_aspect(\"equal\")\n", - "\n", - " # legend axis\n", - " axes.append(fig.add_subplot(nrows, ncols, (9, 10)))\n", - "\n", - " # set limits for legend area\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " mm.plot_bc(\"MAW\", color=\"red\")\n", - " mm.plot_inactive(color_noflow=\"black\")\n", - " ax.set_xticks([0, extents[1] / 2, extents[1]])\n", - " ax.set_yticks([0, extents[1] / 2, extents[1]])\n", - "\n", - " ax = axes[-1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"black\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Inactive cells\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"red\",\n", - " mec=\"red\",\n", - " markeredgewidth=0.5,\n", - " label=\"Multi-aquifer well\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"lower center\", ncol=2)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "25b72139", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the Flowing Well Problem model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5a3b8116", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " plot_grid(sim, silent=silent)\n", - " plot_maw_results(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "821523d0", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the Flowing Well Problem model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "253c5701", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " sim = build_model()\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, f\"could not run...{sim_name}\"\n", - "\n", - " if success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d52acb8f", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "46c7ceb3", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "371aadf8", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Flowing Well Problem Simulation\n", - "\n", - " simulation()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-maw-p03.ipynb b/notebooks/ex-gwf-maw-p03.ipynb deleted file mode 100644 index af035998..00000000 --- a/notebooks/ex-gwf-maw-p03.ipynb +++ /dev/null @@ -1,1360 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "46c0fb12", - "metadata": {}, - "source": [ - "## Reilly Multi-Aquifer Well Problem,\n", - "\n", - "This is the Multi-Aquifer Well from Reilly and others (1989).\n" - ] - }, - { - "cell_type": "markdown", - "id": "ed52c932", - "metadata": {}, - "source": [ - "### Reilly MAW Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e2a1c55", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c6210efb", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "a0489812", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0e68aec8", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "bd9d0565", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3fe48da1", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "0522eb38", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "92e48231", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.3, 4.3)\n", - "masked_values = (0, 1e30, -1e30)\n", - "arrow_props = dict(facecolor=\"black\", arrowstyle=\"-\", lw=0.25, shrinkA=0.1, shrinkB=0.1)" - ] - }, - { - "cell_type": "markdown", - "id": "d11e6f19", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "00e34bd2", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "9a0af7a9", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "30a5bfae", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-maw-p03\"" - ] - }, - { - "cell_type": "markdown", - "id": "d7987805", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ae431e83", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "63be37b4", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1ca02fb6", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-maw-p03a\": {\n", - " \"simulation\": \"regional\",\n", - " },\n", - " \"ex-gwf-maw-p03b\": {\n", - " \"simulation\": \"multi-aquifer well\",\n", - " },\n", - " \"ex-gwf-maw-p03c\": {\n", - " \"simulation\": \"high conductivity\",\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "7db5de89", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "function to calculate the well connection conductance" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d2655be0", - "metadata": {}, - "outputs": [], - "source": [ - "def calc_cond(area, l1, l2, k1, k2):\n", - " c1 = area * k1 / l1\n", - " c2 = area * k2 / l2\n", - " return c1 * c2 / (c1 + c2)" - ] - }, - { - "cell_type": "markdown", - "id": "756dbd7f", - "metadata": {}, - "source": [ - "Table Reilly MAW Problem Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dd5b73d8", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay_r = 21 # Number of layers (regional)\n", - "nrow_r = 1 # Number of rows (regional)\n", - "ncol_r = 200 # Number of columns (regional)\n", - "nlay = 41 # Number of layers (local)\n", - "nrow = 16 # Number of rows (local)\n", - "ncol = 27 # Number of columns (local)\n", - "delr_r = 50.0 # Regional column width ($ft$)\n", - "delc_r = 1.0 # Regional row width ($ft$)\n", - "top = 10.0 # Top of the model ($ft$)\n", - "aq_bottom = -205.0 # Model bottom elevation ($ft$)\n", - "strt = 10.0 # Starting head ($ft$)\n", - "k11 = 250.0 # Horizontal hydraulic conductivity ($ft/d$)\n", - "k33 = 50.0 # Vertical hydraulic conductivity ($ft/d$)\n", - "recharge = 0.004566 # Areal recharge ($ft/d$)\n", - "H1 = 0.0 # Regional downgradient constant head ($ft$)\n", - "maw_loc = (15, 13) # Row, column location of well\n", - "maw_lay = (1, 12) # Layers with well screen\n", - "maw_radius = 0.1333 # Well radius ($ft$)\n", - "maw_bot = -65.0 # Bottom of the well ($ft$)\n", - "maw_highK = 1e9 # Hydraulic conductivity for well ($ft/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "8b76f1aa", - "metadata": {}, - "source": [ - "set delr and delc for the local model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0649eb77", - "metadata": {}, - "outputs": [], - "source": [ - "delr = [\n", - " 10.0,\n", - " 10.0,\n", - " 9.002,\n", - " 6.0,\n", - " 4.0,\n", - " 3.0,\n", - " 2.0,\n", - " 1.33,\n", - " 1.25,\n", - " 1.00,\n", - " 1.00,\n", - " 0.75,\n", - " 0.50,\n", - " 0.333,\n", - " 0.50,\n", - " 0.75,\n", - " 1.00,\n", - " 1.00,\n", - " 1.25,\n", - " 1.333,\n", - " 2.0,\n", - " 3.0,\n", - " 4.0,\n", - " 6.0,\n", - " 9.002,\n", - " 10.0,\n", - " 10.0,\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a791fc05", - "metadata": {}, - "outputs": [], - "source": [ - "delc = [\n", - " 10,\n", - " 9.38,\n", - " 9,\n", - " 6,\n", - " 4,\n", - " 3,\n", - " 2,\n", - " 1.33,\n", - " 1.25,\n", - " 1,\n", - " 1,\n", - " 0.75,\n", - " 0.5,\n", - " 0.3735,\n", - " 0.25,\n", - " 0.1665,\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "fa36b0ee", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d3916a12", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((1.0, 1, 1.0),)" - ] - }, - { - "cell_type": "markdown", - "id": "47789186", - "metadata": {}, - "source": [ - "Define dimensions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "00386635", - "metadata": {}, - "outputs": [], - "source": [ - "extents = (0.0, np.array(delr).sum(), 0.0, np.array(delc).sum())\n", - "shape2d = (nrow, ncol)\n", - "shape3d = (nlay, nrow, ncol)" - ] - }, - { - "cell_type": "markdown", - "id": "f01e2b71", - "metadata": {}, - "source": [ - "### Create Reilly MAW Problem Model Boundary Conditions" - ] - }, - { - "cell_type": "markdown", - "id": "c85e7593", - "metadata": {}, - "source": [ - "MAW Package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5fc56dc6", - "metadata": {}, - "outputs": [], - "source": [ - "nconn = 2 + 3 * (maw_lay[1] - maw_lay[0] + 1)\n", - "maw_packagedata = [[0, maw_radius, maw_bot, strt, \"SPECIFIED\", nconn]]" - ] - }, - { - "cell_type": "markdown", - "id": "a262a05e", - "metadata": {}, - "source": [ - "Build the MAW connection data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "be31c46e", - "metadata": {}, - "outputs": [], - "source": [ - "i, j = maw_loc\n", - "obs_elev = {}\n", - "maw_conn = []\n", - "gwf_obs = []\n", - "for k in range(maw_lay[0], maw_lay[1] + 1, 1):\n", - " gwf_obs.append([f\"H0_{k}\", \"HEAD\", (k, i, j)])\n", - "maw_obs = [\n", - " [\"H0\", \"HEAD\", (0,)],\n", - "]\n", - "iconn = 0\n", - "z = -5.0\n", - "for k in range(maw_lay[0], maw_lay[1] + 1, 1):\n", - " # connection to layer below\n", - " if k == maw_lay[0]:\n", - " area = delc[i] * delr[j]\n", - " l1 = 2.5\n", - " l2 = 2.5\n", - " cond = calc_cond(area, l1, l2, k33, maw_highK)\n", - " maw_conn.append([0, iconn, k - 1, i, j, top, maw_bot, cond, -999.0])\n", - " tag = f\"Q{iconn:02d}\"\n", - " obs_elev[tag] = z\n", - " maw_obs.append([tag, \"maw\", (0,), (iconn,)])\n", - " gwf_obs.append([tag, \"flow-ja-face\", (k, i, j), (k - 1, i, j)])\n", - " iconn += 1\n", - " z -= 2.5\n", - "\n", - " # connection to left\n", - " area = delc[i] * 5.0\n", - " l1 = 0.5 * delr[j]\n", - " l2 = 0.5 * delr[j - 1]\n", - " cond = calc_cond(area, l1, l2, maw_highK, k11)\n", - " maw_conn.append([0, iconn, k, i, j - 1, top, maw_bot, cond, -999.0])\n", - " tag = f\"Q{iconn:02d}\"\n", - " obs_elev[tag] = z\n", - " maw_obs.append([tag, \"maw\", (0,), (iconn,)])\n", - " gwf_obs.append([tag, \"flow-ja-face\", (k, i, j), (k, i, j - 1)])\n", - " iconn += 1\n", - "\n", - " # connection to north\n", - " area = delr[j] * 5.0\n", - " l1 = 0.5 * delc[i]\n", - " l2 = 0.5 * delc[i - 1]\n", - " cond = calc_cond(area, l1, l2, maw_highK, k11)\n", - " maw_conn.append([0, iconn, k, i - 1, j, top, maw_bot, cond, -999.0])\n", - " tag = f\"Q{iconn:02d}\"\n", - " obs_elev[tag] = z\n", - " maw_obs.append([tag, \"maw\", (0,), (iconn,)])\n", - " gwf_obs.append([tag, \"flow-ja-face\", (k, i, j), (k, i - 1, j)])\n", - " iconn += 1\n", - "\n", - " # connection to right\n", - " area = delc[i] * 5.0\n", - " l1 = 0.5 * delr[j]\n", - " l2 = 0.5 * delr[j + 1]\n", - " cond = calc_cond(area, l1, l2, maw_highK, k11)\n", - " maw_conn.append([0, iconn, k, i, j + 1, top, maw_bot, cond, -999.0])\n", - " tag = f\"Q{iconn:02d}\"\n", - " obs_elev[tag] = z\n", - " maw_obs.append([tag, \"maw\", (0,), (iconn,)])\n", - " gwf_obs.append([tag, \"flow-ja-face\", (k, i, j), (k, i, j + 1)])\n", - " iconn += 1\n", - " z -= 5.0\n", - "\n", - " # connection to layer below\n", - " if k == maw_lay[1]:\n", - " z += 2.5\n", - " area = delc[i] * delr[j]\n", - " l1 = 2.5\n", - " l2 = 2.5\n", - " cond = calc_cond(area, l1, l2, maw_highK, k33)\n", - " maw_conn.append([0, iconn, k + 1, i, j, top, maw_bot, cond, -999.0])\n", - " tag = f\"Q{iconn:02d}\"\n", - " obs_elev[tag] = z\n", - " maw_obs.append([tag, \"maw\", (0,), (iconn,)])\n", - " gwf_obs.append([tag, \"flow-ja-face\", (k, i, j), (k + 1, i, j)])\n", - " iconn += 1" - ] - }, - { - "cell_type": "markdown", - "id": "c6686020", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "119350ee", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-4" - ] - }, - { - "cell_type": "markdown", - "id": "7c8e9d40", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 Reilly MAW Problem model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e66139cd", - "metadata": {}, - "outputs": [], - "source": [ - "def build_model(name, simulation=\"regional\"):\n", - " if config.buildModel:\n", - " if simulation == \"regional\":\n", - " sim = build_regional(name)\n", - " else:\n", - " sim = build_local(name, simulation)\n", - "\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f47215ec", - "metadata": {}, - "outputs": [], - "source": [ - "def build_regional(name):\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " botm = np.arange(-5, aq_bottom - 10.0, -10.0)\n", - " icelltype = [1] + [0 for k in range(1, nlay_r)]\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay_r,\n", - " nrow=nrow_r,\n", - " ncol=ncol_r,\n", - " delr=delr_r,\n", - " delc=delc_r,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=[[0, 0, ncol_r - 1, 0.0]])\n", - " flopy.mf6.ModflowGwfrcha(gwf, recharge=recharge)\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " saverecord=[(\"HEAD\", \"LAST\")],\n", - " printrecord=[(\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3e331eff", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_local(name, simulation):\n", - " # get regional heads for constant head boundaries\n", - " pth = list(parameters.keys())[0]\n", - " fpth = os.path.join(ws, pth, f\"{sim_name}.hds\")\n", - " try:\n", - " h = flopy.utils.HeadFile(fpth).get_data()\n", - " except:\n", - " h = np.ones((nlay_r, nrow_r, ncol_r), dtype=float) * strt\n", - "\n", - " # calculate factor for constant heads\n", - " f1 = 0.5 * (delr_r + delr[0]) / delc_r\n", - " f2 = 0.5 * (delr_r + delr[-1]) / delc_r\n", - "\n", - " # build chd for model\n", - " regional_range = [k for k in range(nlay_r)]\n", - " local_range = [[0]] + [[k, k + 1] for k in range(1, nlay, 2)]\n", - " chd_spd = []\n", - " for kr, kl in zip(regional_range, local_range):\n", - " h1 = h[kr, 0, 0]\n", - " h2 = h[kr, 0, 1]\n", - " hi1 = h1 + f1 * (h2 - h1)\n", - " h1 = h[kr, 0, 2]\n", - " h2 = h[kr, 0, 3]\n", - " hi2 = h1 + f2 * (h2 - h1)\n", - " for k in kl:\n", - " for il in range(nrow):\n", - " chd_spd.append([k, il, 0, hi1])\n", - " chd_spd.append([k, il, ncol - 1, hi2])\n", - "\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)\n", - "\n", - " botm = np.arange(-5, aq_bottom - 5.0, -5.0)\n", - " icelltype = [1] + [0 for k in range(1, nlay)]\n", - " i, j = maw_loc\n", - " if simulation == \"multi-aquifer well\":\n", - " k11_sim = k11\n", - " k33_sim = k33\n", - " idomain = np.ones(shape3d, dtype=float)\n", - " for k in range(maw_lay[0], maw_lay[1] + 1, 1):\n", - " idomain[k, i, j] = 0\n", - " else:\n", - " k11_sim = np.ones(shape3d, dtype=float) * k11\n", - " k33_sim = np.ones(shape3d, dtype=float) * k33\n", - " idomain = 1\n", - " for k in range(maw_lay[0], maw_lay[1] + 1, 1):\n", - " k11_sim[k, i, j] = maw_highK\n", - " k33_sim[k, i, j] = maw_highK\n", - "\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11_sim,\n", - " k33=k33_sim,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - "\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chd_spd)\n", - " flopy.mf6.ModflowGwfrcha(gwf, recharge=recharge)\n", - "\n", - " if simulation == \"multi-aquifer well\":\n", - " maw = flopy.mf6.ModflowGwfmaw(\n", - " gwf,\n", - " no_well_storage=True,\n", - " nmawwells=1,\n", - " packagedata=maw_packagedata,\n", - " connectiondata=maw_conn,\n", - " )\n", - " obs_file = f\"{sim_name}.maw.obs\"\n", - " csv_file = obs_file + \".csv\"\n", - " obs_dict = {csv_file: maw_obs}\n", - " maw.obs.initialize(\n", - " filename=obs_file, digits=10, print_input=True, continuous=obs_dict\n", - " )\n", - " else:\n", - " obs_file = f\"{sim_name}.gwf.obs\"\n", - " csv_file = obs_file + \".csv\"\n", - " obsdict = {csv_file: gwf_obs}\n", - " flopy.mf6.ModflowUtlobs(\n", - " gwf, filename=obs_file, print_input=False, continuous=obsdict\n", - " )\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "markdown", - "id": "2c3e4da9", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 Reilly MAW Problem model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "97e21891", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "92b211d4", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the Reilly MAW Problem model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cbfbedde", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "3a9516a2", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the lake results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "da1d22f4", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_maw_results(silent=True):\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " # load the observations\n", - " name = list(parameters.keys())[1]\n", - " fpth = os.path.join(ws, name, f\"{sim_name}.maw.obs.csv\")\n", - " maw = flopy.utils.Mf6Obs(fpth).data\n", - " name = list(parameters.keys())[2]\n", - " fpth = os.path.join(ws, name, f\"{sim_name}.gwf.obs.csv\")\n", - " gwf = flopy.utils.Mf6Obs(fpth).data\n", - "\n", - " # process heads\n", - " hgwf = 0.0\n", - " ihds = 0.0\n", - " for name in gwf.dtype.names:\n", - " if name.startswith(\"H0_\"):\n", - " hgwf += gwf[name]\n", - " ihds += 1.0\n", - " hgwf /= ihds\n", - "\n", - " if silent:\n", - " print(\"MAW head: {} Average head: {}\".format(maw[\"H0\"], hgwf))\n", - "\n", - " zelev = sorted(list(set(list(obs_elev.values()))), reverse=True)\n", - "\n", - " results = {\n", - " \"maw\": {},\n", - " \"gwf\": {},\n", - " }\n", - " for z in zelev:\n", - " results[\"maw\"][z] = 0.0\n", - " results[\"gwf\"][z] = 0.0\n", - "\n", - " for name in maw.dtype.names:\n", - " if name.startswith(\"Q\"):\n", - " z = obs_elev[name]\n", - " results[\"maw\"][z] += 2.0 * maw[name]\n", - "\n", - " for name in gwf.dtype.names:\n", - " if name.startswith(\"Q\"):\n", - " z = obs_elev[name]\n", - " results[\"gwf\"][z] += 2.0 * gwf[name]\n", - "\n", - " q0 = np.array(list(results[\"maw\"].values()))\n", - " q1 = np.array(list(results[\"gwf\"].values()))\n", - " mean_error = np.mean(q0 - q1)\n", - " if silent:\n", - " print(f\"total well inflow: {q0[q0 >= 0].sum()}\")\n", - " print(f\"total well outflow: {q0[q0 < 0].sum()}\")\n", - " print(f\"total cell inflow: {q1[q1 >= 0].sum()}\")\n", - " print(f\"total cell outflow: {q1[q1 < 0].sum()}\")\n", - "\n", - " # create the figure\n", - " fig, ax = plt.subplots(\n", - " ncols=1,\n", - " nrows=1,\n", - " sharex=True,\n", - " figsize=(4, 4),\n", - " constrained_layout=True,\n", - " )\n", - "\n", - " ax.set_xlim(-3.5, 3.5)\n", - " ax.set_ylim(-67.5, -2.5)\n", - " ax.axvline(0, lw=0.5, ls=\":\", color=\"0.5\")\n", - " for z in np.arange(-5, -70, -5):\n", - " ax.axhline(z, lw=0.5, color=\"0.5\")\n", - " ax.plot(\n", - " results[\"maw\"].values(),\n", - " zelev,\n", - " lw=0.75,\n", - " ls=\"-\",\n", - " color=\"blue\",\n", - " label=\"Multi-aquifer well\",\n", - " )\n", - " ax.plot(\n", - " results[\"gwf\"].values(),\n", - " zelev,\n", - " marker=\"o\",\n", - " ms=4,\n", - " mfc=\"red\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " lw=0.0,\n", - " ls=\"-\",\n", - " color=\"red\",\n", - " label=\"High K well\",\n", - " )\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " lw=0.5,\n", - " ls=\"-\",\n", - " color=\"0.5\",\n", - " label=\"Grid cell\",\n", - " )\n", - "\n", - " fs.graph_legend(ax, loc=\"upper left\", ncol=1, frameon=True)\n", - " fs.add_text(\n", - " ax,\n", - " f\"Mean Error {mean_error:.2e} cubic feet per day\",\n", - " bold=False,\n", - " italic=False,\n", - " x=1.0,\n", - " y=1.01,\n", - " va=\"bottom\",\n", - " ha=\"right\",\n", - " fontsize=7,\n", - " )\n", - "\n", - " ax.set_xlabel(\"Discharge rate, in cubic feet per day\")\n", - " ax.set_ylabel(\"Elevation, in feet\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-01{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "f74c39da", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Plot the regional grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0baee18c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_regional_grid(silent=True):\n", - " if silent:\n", - " verbosity = 0\n", - " else:\n", - " verbosity = 1\n", - " name = list(parameters.keys())[0]\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity\n", - " )\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " # get regional heads for constant head boundaries\n", - " h = gwf.output.head().get_data()\n", - "\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " fig = plt.figure(\n", - " figsize=(6.3, 3.5),\n", - " )\n", - " plt.axis(\"off\")\n", - "\n", - " nrows, ncols = 10, 1\n", - " axes = [fig.add_subplot(nrows, ncols, (1, 6))]\n", - "\n", - " # legend axis\n", - " axes.append(fig.add_subplot(nrows, ncols, (7, 10)))\n", - "\n", - " # set limits for legend area\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotCrossSection(gwf, ax=ax, line={\"row\": 0})\n", - " ca = mm.plot_array(h, head=h)\n", - " mm.plot_bc(\"CHD\", color=\"cyan\", head=h)\n", - " mm.plot_grid(lw=0.5, color=\"0.5\")\n", - " cv = mm.contour_array(\n", - " h,\n", - " levels=np.arange(0, 6, 0.5),\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=\"black\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.1f\")\n", - " ax.plot(\n", - " [50, 150, 150, 50, 50],\n", - " [10, 10, aq_bottom, aq_bottom, 10],\n", - " lw=1.25,\n", - " color=\"#39FF14\",\n", - " )\n", - " fs.remove_edge_ticks(ax)\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " ax.set_ylabel(\"Elevation, in feet\")\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"none\",\n", - " mec=\"0.5\",\n", - " markeredgewidth=0.5,\n", - " label=\"Grid cell\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"cyan\",\n", - " mec=\"0.5\",\n", - " markeredgewidth=0.5,\n", - " label=\"Constant head\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"none\",\n", - " mec=\"#39FF14\",\n", - " markeredgewidth=1.25,\n", - " label=\"Local model domain\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " color=\"black\",\n", - " label=\"Head contour, $ft$\",\n", - " )\n", - " cbar = plt.colorbar(ca, shrink=0.5, orientation=\"horizontal\", ax=ax)\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Head, $ft$\", fontsize=9)\n", - " fs.graph_legend(ax, loc=\"lower center\", ncol=4)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-regional-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "ce665b53", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Plot the local grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "045ba081", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_local_grid(silent=True):\n", - " if silent:\n", - " verbosity = 0\n", - " else:\n", - " verbosity = 1\n", - " name = list(parameters.keys())[1]\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity\n", - " )\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " i, j = maw_loc\n", - " dx, dy = delr[j], delc[i]\n", - " px = (\n", - " 50.0 - 0.5 * dx,\n", - " 50.0 + 0.5 * dx,\n", - " )\n", - " py = (\n", - " 0.0 + dy,\n", - " 0.0 + dy,\n", - " )\n", - "\n", - " # get regional heads for constant head boundaries\n", - " h = gwf.output.head().get_data()\n", - "\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " fig = plt.figure(\n", - " figsize=(6.3, 4.1),\n", - " tight_layout=True,\n", - " )\n", - " plt.axis(\"off\")\n", - "\n", - " nrows, ncols = 10, 1\n", - " axes = [fig.add_subplot(nrows, ncols, (1, 8))]\n", - "\n", - " for idx, ax in enumerate(axes):\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - " ax.set_aspect(\"equal\")\n", - "\n", - " # legend axis\n", - " axes.append(fig.add_subplot(nrows, ncols, (8, 10)))\n", - "\n", - " # set limits for legend area\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents, layer=0)\n", - " mm.plot_bc(\"CHD\", color=\"cyan\", plotAll=True)\n", - " mm.plot_grid(lw=0.25, color=\"0.5\")\n", - " cv = mm.contour_array(\n", - " h,\n", - " levels=np.arange(4.0, 5.0, 0.005),\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=\"black\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.3f\")\n", - " ax.fill_between(px, py, y2=0, ec=\"none\", fc=\"red\", lw=0, zorder=200, step=\"post\")\n", - " fs.add_annotation(\n", - " ax,\n", - " text=\"Well location\",\n", - " xy=(50.0, 0.0),\n", - " xytext=(55, 5),\n", - " bold=False,\n", - " italic=False,\n", - " ha=\"left\",\n", - " fontsize=7,\n", - " arrowprops=arrow_props,\n", - " )\n", - " fs.remove_edge_ticks(ax)\n", - " ax.set_xticks([0, 25, 50, 75, 100])\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " ax.set_yticks([0, 25, 50])\n", - " ax.set_ylabel(\"y-coordinate, in feet\")\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"cyan\",\n", - " mec=\"0.5\",\n", - " markeredgewidth=0.25,\n", - " label=\"Constant head\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"red\",\n", - " mec=\"0.5\",\n", - " markeredgewidth=0.25,\n", - " label=\"Multi-aquifer well\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " color=\"black\",\n", - " label=\"Water-table contour, $ft$\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"lower center\", ncol=3)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-local-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "1bc0dd5e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the Reilly MAW Problem model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f84b2fb6", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(silent=True):\n", - " if config.plotModel:\n", - " plot_regional_grid(silent=silent)\n", - " plot_local_grid(silent=silent)\n", - " plot_maw_results(silent=silent)\n", - " pass" - ] - }, - { - "cell_type": "markdown", - "id": "36802e07", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the Reilly MAW Problem model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "912bcdee", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx=0, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - "\n", - " sim = build_model(key, **params)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, f\"could not run...{sim_name}\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "34412d00", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(idx=0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dd4c1683", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " simulation(idx=1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "581d20fc", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " simulation(idx=2, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cb322ed1", - "metadata": {}, - "outputs": [], - "source": [ - "def test_plot():\n", - " plot_results()" - ] - }, - { - "cell_type": "markdown", - "id": "667b77c1", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2451418f", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Reilly MAW Problem Simulation\n", - " #\n", - " # Regional model\n", - "\n", - " simulation(0)\n", - "\n", - " # Local model with MAW well\n", - "\n", - " simulation(1)\n", - "\n", - " # Local model with high K well\n", - "\n", - " simulation(2)\n", - "\n", - " # Plot the results\n", - "\n", - " plot_results()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-nwt-p02.ipynb b/notebooks/ex-gwf-nwt-p02.ipynb deleted file mode 100644 index dc7feb8e..00000000 --- a/notebooks/ex-gwf-nwt-p02.ipynb +++ /dev/null @@ -1,809 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "911b5ddc", - "metadata": {}, - "source": [ - "## Flow diversion example\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "6953f530", - "metadata": {}, - "source": [ - "### Flow diversion Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "117970f1", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bd4a77c8", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "ee949a7c", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "436c6941", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "2473e71d", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "35a8a541", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "0bdf5bfa", - "metadata": {}, - "source": [ - "Set figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1dd981a2", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.3, 6.3)\n", - "masked_values = (1e30, -1e30)" - ] - }, - { - "cell_type": "markdown", - "id": "0c659702", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2e11d72a", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "543a25f2", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f64ddf5e", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-nwt-p02\"" - ] - }, - { - "cell_type": "markdown", - "id": "881c0810", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dbba2e26", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "a4c949b0", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cdfde781", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-nwt-p02a\": {\n", - " \"newton\": \"newton\",\n", - " },\n", - " \"ex-gwf-nwt-p02b\": {\n", - " \"rewet\": True,\n", - " \"wetfct\": 0.5,\n", - " \"iwetit\": 1,\n", - " \"ihdwet\": 1,\n", - " \"wetdry\": -0.5,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "5abc863b", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e3c1cf6e", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nper = 4 # Number of periods\n", - "nlay = 14 # Number of layers\n", - "nrow = 40 # Number of rows\n", - "ncol = 40 # Number of columns\n", - "delr = 125.0 # Column width ($ft$)\n", - "delc = 125.0 # Row width ($ft$)\n", - "top = 80.0 # Top of the model ($ft$)\n", - "k11 = 5.0 # Horizontal hydraulic conductivity ($ft/day$)\n", - "k33 = 0.25 # Horizontal hydraulic conductivity ($ft/day$)\n", - "ss = 0.0002 # Specific storage ($1/day$)\n", - "sy = 0.2 # Specific yield (unitless)\n", - "H1 = 25.0 # Constant head along left and lower edges and starting head ($ft$)\n", - "rech = 0.05 # Recharge rate ($ft/day$)" - ] - }, - { - "cell_type": "markdown", - "id": "14697537", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c3f78410", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = (\n", - " (190.0, 10, 1.0),\n", - " (518.0, 2, 1.0),\n", - " (1921.0, 17, 1.0),\n", - " (1.0, 1, 1.0),\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "ed053ced", - "metadata": {}, - "source": [ - "Calculate extents, and shape3d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a913d35a", - "metadata": {}, - "outputs": [], - "source": [ - "extents = (0, delr * ncol, 20, 65)\n", - "shape3d = (nlay, nrow, ncol)" - ] - }, - { - "cell_type": "markdown", - "id": "293a8d25", - "metadata": {}, - "source": [ - "Create the bottom" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "08e72d6a", - "metadata": {}, - "outputs": [], - "source": [ - "botm = np.arange(65.0, -5.0, -5.0)" - ] - }, - { - "cell_type": "markdown", - "id": "600a1eee", - "metadata": {}, - "source": [ - "Create icelltype (which is the same as iconvert)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "00fb8738", - "metadata": {}, - "outputs": [], - "source": [ - "icelltype = 9 * [1] + 5 * [0]" - ] - }, - { - "cell_type": "markdown", - "id": "e080c065", - "metadata": {}, - "source": [ - "Constant head boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "773f32eb", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "chd_spd = []\n", - "for k in range(9, nlay, 1):\n", - " chd_spd += [[k, i, ncol - 1, H1] for i in range(nrow - 1)]\n", - " chd_spd += [[k, nrow - 1, j, H1] for j in range(ncol)]" - ] - }, - { - "cell_type": "markdown", - "id": "3e260721", - "metadata": {}, - "source": [ - "Recharge boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5441d184", - "metadata": {}, - "outputs": [], - "source": [ - "rch_spd = []\n", - "for i in range(0, 2, 1):\n", - " for j in range(0, 2, 1):\n", - " rch_spd.append([0, i, j, rech])" - ] - }, - { - "cell_type": "markdown", - "id": "73e82073", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "828764c3", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 100\n", - "hclose = 1e-6\n", - "rclose = 1000.0" - ] - }, - { - "cell_type": "markdown", - "id": "f100ff92", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f6ed443a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(\n", - " name,\n", - " newton=False,\n", - " rewet=False,\n", - " wetfct=None,\n", - " iwetit=None,\n", - " ihdwet=None,\n", - " wetdry=None,\n", - "):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " if newton:\n", - " newtonoptions = \"newton\"\n", - " no_ptc = \"ALL\"\n", - " complexity = \"complex\"\n", - " else:\n", - " newtonoptions = None\n", - " no_ptc = None\n", - " complexity = \"simple\"\n", - "\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " complexity=complexity,\n", - " print_option=\"SUMMARY\",\n", - " no_ptcrecord=no_ptc,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=sim_name,\n", - " newtonoptions=newtonoptions,\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " if rewet:\n", - " rewet_record = [\n", - " \"wetfct\",\n", - " wetfct,\n", - " \"iwetit\",\n", - " iwetit,\n", - " \"ihdwet\",\n", - " ihdwet,\n", - " ]\n", - " wetdry = 9 * [wetdry] + 5 * [0]\n", - " else:\n", - " rewet_record = None\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " rewet_record=rewet_record,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " wetdry=wetdry,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=icelltype,\n", - " ss=ss,\n", - " sy=sy,\n", - " steady_state={3: True},\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=H1)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chd_spd)\n", - " flopy.mf6.ModflowGwfrch(gwf, stress_period_data=rch_spd)\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " saverecord=[(\"HEAD\", \"LAST\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "8621d548", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write flow diversion model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "45018a6f", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "937c0b74", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d0ef8666", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "cd97cc1f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Create a water-table array" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5df80472", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def get_water_table(h, bot):\n", - " imask = (h > -1e30) & (h <= bot)\n", - " h[imask] = -1e30\n", - " return np.amax(h, axis=0)" - ] - }, - { - "cell_type": "markdown", - "id": "3595449c", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8ff7a4bf", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(silent=True):\n", - " verbose = not silent\n", - " if verbose:\n", - " verbosity_level = 1\n", - " else:\n", - " verbosity_level = 0\n", - "\n", - " if config.plotModel:\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - "\n", - " # load the newton model\n", - " name = list(parameters.keys())[0]\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level\n", - " )\n", - " gwf = sim.get_model(sim_name)\n", - " bot = gwf.dis.botm.array\n", - " xnode = gwf.modelgrid.xcellcenters[0, :]\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj = gwf.output.head()\n", - "\n", - " # get a list of times\n", - " times = hobj.get_times()\n", - "\n", - " # load rewet model\n", - " name = list(parameters.keys())[1]\n", - " sim_ws = os.path.join(ws, name)\n", - " sim1 = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level\n", - " )\n", - " gwf1 = sim1.get_model(sim_name)\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj1 = gwf1.output.head()\n", - "\n", - " # Create figure for simulation\n", - " fig, axes = plt.subplots(\n", - " ncols=1,\n", - " nrows=4,\n", - " sharex=True,\n", - " figsize=figure_size,\n", - " constrained_layout=False,\n", - " )\n", - "\n", - " # plot the results\n", - " for idx, ax in enumerate(axes):\n", - " # extract heads and specific discharge for newton model\n", - " head = hobj.get_data(totim=times[idx])\n", - " head = get_water_table(head, bot)\n", - "\n", - " # extract heads and specific discharge for newton model\n", - " head1 = hobj1.get_data(totim=times[idx])\n", - " head1 = get_water_table(head1, bot)\n", - "\n", - " # calculate mean error\n", - " diff = np.abs(head - head1)\n", - " # print(\"max\", diff.max(), np.argmax(diff))\n", - " me = diff.sum() / float(ncol * nrow)\n", - " me_text = f\"Mean absolute water-table error {me:.3f} feet\"\n", - "\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - " mm = flopy.plot.PlotCrossSection(\n", - " model=gwf, ax=ax, extent=extents, line={\"row\": 1}\n", - " )\n", - " mm.plot_bc(\"CHD\", color=\"cyan\")\n", - " mm.plot_grid(lw=0.5)\n", - " ax.plot(\n", - " xnode,\n", - " head[0, :],\n", - " lw=0.75,\n", - " color=\"black\",\n", - " label=\"Newton-Raphson\",\n", - " )\n", - " ax.plot(\n", - " xnode,\n", - " head1[0, :],\n", - " lw=0,\n", - " marker=\"o\",\n", - " ms=4,\n", - " mfc=\"none\",\n", - " mec=\"blue\",\n", - " label=\"Rewetting\",\n", - " )\n", - " if idx == 0:\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=4,\n", - " mec=\"0.5\",\n", - " mfc=\"none\",\n", - " label=\"Model cell\",\n", - " )\n", - " ax.plot(\n", - " -1000,\n", - " -1000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=4,\n", - " mec=\"0.5\",\n", - " mfc=\"cyan\",\n", - " label=\"Constant head\",\n", - " )\n", - " fs.graph_legend(\n", - " ax,\n", - " loc=\"upper right\",\n", - " ncol=2,\n", - " frameon=True,\n", - " facecolor=\"white\",\n", - " edgecolor=\"none\",\n", - " )\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, ax=ax)\n", - " fs.add_text(ax, text=me_text, x=1, y=1.01, ha=\"right\", bold=False)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # set fake y-axis label\n", - " ax.set_ylabel(\" \")\n", - "\n", - " # set fake x-axis label\n", - " ax.set_xlabel(\" \")\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, frameon=False)\n", - " ax.tick_params(\n", - " labelcolor=\"none\", top=\"off\", bottom=\"off\", left=\"off\", right=\"off\"\n", - " )\n", - " ax.set_xlim(0, 1)\n", - " ax.set_xticks([0, 1])\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " ax.set_ylim(0, 1)\n", - " ax.set_yticks([0, 1])\n", - " ax.set_ylabel(\"Water-table elevation above arbitrary datum, in meters\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-01{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "afc26f6a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the TWRI model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "03c2b9fa", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - "\n", - " sim = build_model(key, **params)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, f\"could not run...{key}\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "078a22b3", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_and_plot():\n", - " simulation(0, silent=False)\n", - " simulation(1, silent=False)\n", - " plot_results(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "0c38c0f1", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3c9b7a2f", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### MODFLOW-NWT Problem 2 Simulation\n", - " #\n", - " # Newton-Raphson.\n", - "\n", - " simulation(0)\n", - "\n", - " # Rewetting.\n", - "\n", - " simulation(1)\n", - "\n", - " # Plot results\n", - "\n", - " plot_results()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-nwt-p03.ipynb b/notebooks/ex-gwf-nwt-p03.ipynb deleted file mode 100644 index 0652460a..00000000 --- a/notebooks/ex-gwf-nwt-p03.ipynb +++ /dev/null @@ -1,1014 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "72aa557f", - "metadata": {}, - "source": [ - "## MODFLOW-NWT Problem 3 example\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "4150ad75", - "metadata": {}, - "source": [ - "### MODFLOW-NWT Problem 3 Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f01ab3fb", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e6e81de5", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "e25f02c3", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "01fd6cc3", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "8a1b788e", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "996f8c99", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "0a13fcc9", - "metadata": {}, - "source": [ - "Set figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c7be7faa", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.3, 5.6)\n", - "masked_values = (1e30, -1e30)" - ] - }, - { - "cell_type": "markdown", - "id": "5e291741", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5dc46a01", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "947d0adb", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8ce90883", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-nwt-p03\"" - ] - }, - { - "cell_type": "markdown", - "id": "f1dff8d4", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a0a21133", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "25b7b137", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3eedb3f9", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-nwt-p03a\": {\n", - " \"recharge\": \"high\",\n", - " },\n", - " \"ex-gwf-nwt-p03b\": {\n", - " \"recharge\": \"low\",\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "47acc454", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3ce93050", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 80 # Number of rows\n", - "ncol = 80 # Number of columns\n", - "delr = 100.0 # Cell size in the x-direction ($m$)\n", - "delc = 100.0 # Cell size in y-direction ($m$)\n", - "top = 200.0 # Top of the model ($m$)\n", - "k11 = 1.0 # Horizontal hydraulic conductivity ($m/day$)\n", - "H1 = 24.0 # Constant head water level ($m$)" - ] - }, - { - "cell_type": "markdown", - "id": "9656fc0e", - "metadata": {}, - "source": [ - "plotting ranges and contour levels" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "57034ed5", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "vmin, vmax = 20, 60\n", - "smin, smax = 0, 25\n", - "bmin, bmax = 0, 90\n", - "vlevels = np.arange(vmin, vmax + 5, 5)\n", - "slevels = np.arange(smin, smax + 5, 5)\n", - "blevels = np.arange(bmin + 10, bmax, 10)\n", - "vcolor = \"black\"\n", - "scolor = \"black\"\n", - "bcolor = \"black\"" - ] - }, - { - "cell_type": "markdown", - "id": "d06e0a6c", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b43a87cf", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((365.0, 1, 1.0),)" - ] - }, - { - "cell_type": "markdown", - "id": "f760955f", - "metadata": {}, - "source": [ - "Calculate extents, and shape3d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7f3e7791", - "metadata": {}, - "outputs": [], - "source": [ - "extents = (0, delr * ncol, 0, delc * nrow)\n", - "shape3d = (nlay, nrow, ncol)\n", - "ticklabels = np.arange(0, 10000, 2000)" - ] - }, - { - "cell_type": "markdown", - "id": "c8845d2e", - "metadata": {}, - "source": [ - "Load the bottom" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "75ad8278", - "metadata": {}, - "outputs": [], - "source": [ - "fpth = os.path.join(\"..\", \"data\", sim_name, \"bottom.txt\")\n", - "botm = np.loadtxt(fpth).reshape(shape3d)" - ] - }, - { - "cell_type": "markdown", - "id": "eb6d7af9", - "metadata": {}, - "source": [ - "Set the starting heads" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "68a0d1be", - "metadata": {}, - "outputs": [], - "source": [ - "strt = botm + 20.0" - ] - }, - { - "cell_type": "markdown", - "id": "8a302a8b", - "metadata": {}, - "source": [ - "Load the high recharge rate" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ebba19a7", - "metadata": {}, - "outputs": [], - "source": [ - "fpth = os.path.join(\"..\", \"data\", sim_name, \"recharge_high.txt\")\n", - "rch_high = np.loadtxt(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "813481f9", - "metadata": {}, - "source": [ - "Generate the low recharge rate from the high recharge rate" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ffb19a10", - "metadata": {}, - "outputs": [], - "source": [ - "rch_low = rch_high.copy() * 1e-3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4f769154", - "metadata": {}, - "outputs": [], - "source": [ - "# Constant head boundary conditions\n", - "chd_spd = [\n", - " [0, i, ncol - 1, H1]\n", - " for i in (\n", - " 45,\n", - " 46,\n", - " 47,\n", - " )\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "6fabaf15", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "19abb81b", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 500\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "b42302c5", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eccad508", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(\n", - " name,\n", - " recharge=\"high\",\n", - "):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"all\",\n", - " complexity=\"simple\",\n", - " linear_acceleration=\"bicgstab\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=sim_name,\n", - " newtonoptions=\"newton under_relaxation\",\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=1,\n", - " k=k11,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chd_spd)\n", - "\n", - " if recharge == \"high\":\n", - " rch = rch_high\n", - " elif recharge == \"low\":\n", - " rch = rch_low\n", - " flopy.mf6.ModflowGwfrcha(gwf, recharge=rch)\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "09375a7d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW-NWT Problem 3 model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6e651412", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "bd71fab2", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "60793b8c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "39de0da6", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to create a figure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8fea6baa", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def create_figure(nsubs=1, size=(4, 4)):\n", - " fig = plt.figure(figsize=size, constrained_layout=False)\n", - " gs = mpl.gridspec.GridSpec(ncols=10, nrows=7, figure=fig, wspace=5)\n", - " plt.axis(\"off\")\n", - "\n", - " axes = []\n", - " if nsubs == 1:\n", - " axes.append(fig.add_subplot(gs[:5, :]))\n", - " elif nsubs == 2:\n", - " axes.append(fig.add_subplot(gs[:6, :5]))\n", - " axes.append(fig.add_subplot(gs[:6, 5:], sharey=axes[0]))\n", - "\n", - " for ax in axes:\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - " ax.set_aspect(\"equal\")\n", - " ax.set_xticks(ticklabels)\n", - " ax.set_yticks(ticklabels)\n", - "\n", - " # legend axis\n", - " axes.append(fig.add_subplot(gs[5:, :]))\n", - "\n", - " # set limits for legend area\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " return fig, axes" - ] - }, - { - "cell_type": "markdown", - "id": "d0e821ee", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7aa12756", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_grid(gwf, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - "\n", - " bot = gwf.dis.botm.array\n", - "\n", - " fig, axes = create_figure(size=(3.15, 4))\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " bot_coll = mm.plot_array(bot, vmin=bmin, vmax=bmax)\n", - " mm.plot_bc(\"CHD\", color=\"cyan\")\n", - " cv = mm.contour_array(\n", - " bot,\n", - " levels=blevels,\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=bcolor,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " ax.set_ylabel(\"y-coordinate, in meters\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # legend\n", - " ax = axes[1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"cyan\",\n", - " mec=\"cyan\",\n", - " label=\"Constant Head\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " ls=\"-\",\n", - " color=bcolor,\n", - " label=\"Bottom elevation contour, m\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"center\", ncol=2)\n", - "\n", - " cax = plt.axes([0.275, 0.125, 0.45, 0.025])\n", - " cbar = plt.colorbar(\n", - " bot_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " cax=cax,\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Bottom Elevation, $m$\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3c0dd7cb", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_recharge(gwf, silent=True):\n", - " verbose = not silent\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - "\n", - " fig, axes = create_figure(nsubs=2, size=figure_size)\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " rch_coll = mm.plot_array(rch_high)\n", - " mm.plot_bc(\"CHD\", color=\"cyan\")\n", - " cv = mm.contour_array(\n", - " rch_high,\n", - " levels=[1e-6, 2e-6, 3e-6, 4e-6, 5e-6, 6e-6, 7e-6],\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=\"black\",\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0e\")\n", - " cbar = plt.colorbar(\n", - " rch_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " ax=ax,\n", - " format=\"%.0e\",\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Recharge rate, $m/day$\")\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " ax.set_ylabel(\"y-coordinate, in meters\")\n", - " fs.heading(ax, letter=\"A\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " ax = axes[1]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " rch_coll = mm.plot_array(rch_low)\n", - " mm.plot_bc(\"CHD\", color=\"cyan\")\n", - " cv = mm.contour_array(\n", - " rch_low,\n", - " levels=[1e-9, 2e-9, 3e-9, 4e-9, 5e-9, 6e-9, 7e-9],\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=\"black\",\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0e\")\n", - " cbar = plt.colorbar(\n", - " rch_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " ax=ax,\n", - " format=\"%.0e\",\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Recharge rate, $m/day$\")\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " fs.heading(ax, letter=\"B\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"cyan\",\n", - " mec=\"cyan\",\n", - " label=\"Constant Head\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " ls=\"-\",\n", - " color=bcolor,\n", - " label=r\"Recharge rate contour, $m/day$\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"center\", ncol=2)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-01{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "6335d872", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4a202b1b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(idx, sim, silent=True):\n", - " verbose = not silent\n", - " if config.plotModel:\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - " name = list(parameters.keys())[idx]\n", - " sim_ws = os.path.join(ws, name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " bot = gwf.dis.botm.array\n", - "\n", - " if idx == 0:\n", - " plot_grid(gwf, silent=silent)\n", - " plot_recharge(gwf, silent=silent)\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj = gwf.output.head()\n", - "\n", - " # get times\n", - " times = hobj.get_times()\n", - "\n", - " # extract heads and specific discharge\n", - " head = hobj.get_data(totim=times[0])\n", - " imask = head <= bot + 0.001\n", - " head[imask] = -1e30\n", - " sat_thick = head - botm\n", - " sat_thick[imask] = -1e30\n", - "\n", - " # Create figure for simulation\n", - " fig, axes = create_figure(nsubs=2, size=figure_size)\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " h_coll = mm.plot_array(\n", - " head, vmin=vmin, vmax=vmax, masked_values=masked_values, zorder=10\n", - " )\n", - " cv = mm.contour_array(\n", - " head,\n", - " masked_values=masked_values,\n", - " levels=vlevels,\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=vcolor,\n", - " zorder=10,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\", zorder=10)\n", - " mm.plot_bc(\"CHD\", color=\"cyan\", zorder=11)\n", - " cbar = plt.colorbar(\n", - " h_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " ax=ax,\n", - " format=\"%.0f\",\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Water level, $m$\")\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " ax.set_ylabel(\"y-coordinate, in meters\")\n", - " fs.heading(ax, letter=\"A\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " ax = axes[1]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " s_coll = mm.plot_array(\n", - " sat_thick,\n", - " vmin=smin,\n", - " vmax=smax,\n", - " masked_values=masked_values,\n", - " zorder=10,\n", - " )\n", - " cv = mm.contour_array(\n", - " sat_thick,\n", - " masked_values=masked_values,\n", - " levels=slevels,\n", - " linewidths=0.5,\n", - " linestyles=\":\",\n", - " colors=scolor,\n", - " zorder=10,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\", zorder=10)\n", - " mm.plot_bc(\"CHD\", color=\"cyan\", zorder=11)\n", - " cbar = plt.colorbar(\n", - " s_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " ax=ax,\n", - " format=\"%.0f\",\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Saturated thickness, $m$\")\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " # ax.set_ylabel(\"y-coordinate, in meters\")\n", - " fs.heading(ax, letter=\"B\")\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # create legend\n", - " ax = axes[-1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"cyan\",\n", - " mec=\"cyan\",\n", - " label=\"Constant Head\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " ls=\"-\",\n", - " color=vcolor,\n", - " label=\"Head contour, m\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " ls=\":\",\n", - " color=scolor,\n", - " label=\"Saturated thickness contour, m\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"center\", ncol=3)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-{idx + 2:02d}{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "bed0c60d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for MODFLOW-NWT Problem 3 model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b2cd183d", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - "\n", - " sim = build_model(key, **params)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(idx, sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3abf6cce", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bd2096cd", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " simulation(1, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "e516cb1a", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "773164f1", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### MODFLOW-NWT Problem 3 Simulation\n", - " #\n", - " # Simulated heads in the MODFLOW-NWT Problem 3 model with high recharge.\n", - "\n", - " simulation(0)\n", - "\n", - " # Simulated heads in the MODFLOW-NWT Problem 3 model with low recharge.\n", - "\n", - " simulation(1)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-radial.ipynb b/notebooks/ex-gwf-radial.ipynb deleted file mode 100644 index b6eb2b58..00000000 --- a/notebooks/ex-gwf-radial.ipynb +++ /dev/null @@ -1,1539 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "3a5fe181", - "metadata": {}, - "source": [ - "## USG1DISU example\n", - "\n", - "This example, ex-gwf-radial, shows how the MODFLOW 6 DISU Package\n", - "can be used to simulate an axisymmetric radial model.\n", - "\n", - "The example corresponds to the first example described in:\n", - " Bedekar, V., Scantlebury, L., and Panday, S. (2019).\n", - " Axisymmetric Modeling Using MODFLOW-USG.Groundwater, 57(5), 772-777.\n", - "\n", - "And the numerical result is compared against the analytical solution\n", - "presented in Equation 17 of\n", - " Neuman, S. P. (1974). Effect of partial penetration on flow in\n", - " unconfined aquifers considering delayed gravity response.\n", - " Water resources research, 10(2), 303-312" - ] - }, - { - "cell_type": "markdown", - "id": "4b473d40", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "93a07f3f", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from matplotlib.patches import Circle\n", - "import flopy" - ] - }, - { - "cell_type": "markdown", - "id": "c1182d14", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "70f532d5", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "c1dddeb8", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "500e2427", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ce90787e", - "metadata": {}, - "outputs": [], - "source": [ - "from get_disu_radial_kwargs import get_disu_radial_kwargs\n", - "from neuman1974_soln import RadialUnconfinedDrawdown" - ] - }, - { - "cell_type": "markdown", - "id": "f1e51401", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Utility function to return DISU node for given radial band and layer" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dac8c8a1", - "metadata": {}, - "outputs": [], - "source": [ - "def get_radial_node(rad, lay, nradial):\n", - " \"\"\"\n", - " Given nradial dimension (bands per layer),\n", - " returns the 0-based disu node number for given 0-based radial\n", - " band and layer\n", - "\n", - " Parameters\n", - " ----------\n", - " rad : int\n", - " radial band number (0 to nradial-1)\n", - " lay : float or ndarray\n", - " layer number (0 to nlay-1)\n", - " nradial : int\n", - " total number of radial bands\n", - "\n", - " Returns\n", - " -------\n", - " result : int\n", - " 0-based disu node number located at rad and lay\n", - "\n", - " \"\"\"\n", - "\n", - " return nradial * lay + rad" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "31b27727", - "metadata": {}, - "outputs": [], - "source": [ - "def get_radius_lay_from_node(node, nradial):\n", - " \"\"\"\n", - " Given nradial dimension (bands per layer),\n", - " returns 0-based layer and radial band indices for given disu node number\n", - "\n", - " Parameters\n", - " ----------\n", - " node : int\n", - " disu node number\n", - " nradial : int\n", - " total number of radial bands\n", - "\n", - " Returns\n", - " -------\n", - " result : int\n", - " 0-based disu node number located at rad and lay\n", - "\n", - " \"\"\"\n", - " #\n", - " lay = node // nradial\n", - " rad = node - (lay * nradial)\n", - " return rad, lay" - ] - }, - { - "cell_type": "markdown", - "id": "ba1efc91", - "metadata": {}, - "source": [ - "Run Analytical Model - Very slow\n", - "If True, solves the Neuman 1974 analytical model (very slow)\n", - "else uses stored results from solving the Neuman 1974 analytical model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ebab85e0", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "solve_analytical_solution = False" - ] - }, - { - "cell_type": "markdown", - "id": "136c7541", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "82e6dee4", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 6)" - ] - }, - { - "cell_type": "markdown", - "id": "2f5124e1", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1e93bfff", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "c4e910a1", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c4c571a", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-rad-disu\"" - ] - }, - { - "cell_type": "markdown", - "id": "d12dd423", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c2c1c6e4", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "bb38d6b3", - "metadata": {}, - "source": [ - "Table Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b54bf1e", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "_ = 24 # Number of time steps\n", - "_ = \"10\" # Simulation total time ($day$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cc423fe1", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 25 # Number of layers\n", - "nradial = 22 # Number of radial direction cells (radial bands)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c812cdf4", - "metadata": {}, - "outputs": [], - "source": [ - "initial_head = 50.0 # Initial water table elevation ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f461cbb1", - "metadata": {}, - "outputs": [], - "source": [ - "surface_elevation = 50.0 # Top of the radial model ($ft$)\n", - "_ = 0.0 # Base of the radial model ($ft$)\n", - "layer_thickness = 2.0 # Thickness of each radial layer ($ft$)\n", - "_ = \"0.25 to 2000\" # Outer radius of each radial band ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3de3bc36", - "metadata": {}, - "outputs": [], - "source": [ - "k11 = 20.0 # Horizontal hydraulic conductivity ($ft/day$)\n", - "k33 = 20.0 # Vertical hydraulic conductivity ($ft/day$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "480ae446", - "metadata": {}, - "outputs": [], - "source": [ - "ss = 1.0e-5 # Specific storage ($1/day$)\n", - "sy = 0.1 # Specific yield (unitless)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "26d38689", - "metadata": {}, - "outputs": [], - "source": [ - "_ = \"0.0 to 10\" # Well screen elevation ($ft$)\n", - "_ = \"1\" # Well radial band location (unitless)\n", - "_ = \"-4000.0\" # Well pumping rate ($ft^3/day$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fcbf14ab", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "_ = \"40\" # Observation distance from well ($ft$)\n", - "_ = \"1\" # ``Top'' observation elevation ($ft$)\n", - "_ = \"25\" # ``Middle'' observation depth ($ft$)\n", - "_ = \"49\" # ``Bottom'' observation depth ($ft$)" - ] - }, - { - "cell_type": "markdown", - "id": "a7ae350d", - "metadata": {}, - "source": [ - "Outer Radius for each radial band" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3e747a11", - "metadata": {}, - "outputs": [], - "source": [ - "radius_outer = [\n", - " 0.25,\n", - " 0.75,\n", - " 1.5,\n", - " 2.5,\n", - " 4.0,\n", - " 6.0,\n", - " 9.0,\n", - " 13.0,\n", - " 18.0,\n", - " 23.0,\n", - " 33.0,\n", - " 47.0,\n", - " 65.0,\n", - " 90.0,\n", - " 140.0,\n", - " 200.0,\n", - " 300.0,\n", - " 400.0,\n", - " 600.0,\n", - " 1000.0,\n", - " 1500.0,\n", - " 2000.0,\n", - "] # Outer radius of each radial band ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "859036c1", - "metadata": {}, - "outputs": [], - "source": [ - "# Well boundary conditions\n", - "# Well must be located on central radial band (rad = 0)\n", - "# and have a contiguous screen interval and constant pumping rate.\n", - "# This example has the well screen interval from\n", - "# layer 20 to 24 (zero-based index)\n", - "wel_spd = {\n", - " sp: [\n", - " [(get_radial_node(0, lay, nradial),), -800.0] for lay in range(20, 25)\n", - " ]\n", - " for sp in range(nper)\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "fa5f376d", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation has 1 ten-day stress period with 24 time steps.\n", - "The multiplier for the length of successive time steps is 1.62" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f992f794", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((10.0, 24, 1.62),)" - ] - }, - { - "cell_type": "markdown", - "id": "5e82dd93", - "metadata": {}, - "source": [ - "Setup observation location and times" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4408634e", - "metadata": {}, - "outputs": [], - "source": [ - "obslist = [\n", - " [\"h_top\", \"head\", (get_radial_node(11, 0, nradial),)],\n", - " [\"h_mid\", \"head\", (get_radial_node(11, (nlay - 1) // 2, nradial),)],\n", - " [\"h_bot\", \"head\", (get_radial_node(11, nlay - 1, nradial),)],\n", - "]\n", - "obsdict = {\"{}.obs.head.csv\".format(sim_name): obslist}" - ] - }, - { - "cell_type": "markdown", - "id": "172709e9", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "87906f9b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 300\n", - "hclose = 1e-4\n", - "rclose = 1e-4" - ] - }, - { - "cell_type": "markdown", - "id": "70f74e12", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 Axisymmetric Model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6e497f53", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(name):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " complexity=\"complex\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " )\n", - "\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - "\n", - " disukwargs = get_disu_radial_kwargs(\n", - " nlay,\n", - " nradial,\n", - " radius_outer,\n", - " surface_elevation,\n", - " layer_thickness,\n", - " get_vertex=True,\n", - " )\n", - "\n", - " disu = flopy.mf6.ModflowGwfdisu(\n", - " gwf, length_units=length_units, **disukwargs\n", - " )\n", - "\n", - " npf = flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " k=k11,\n", - " k33=k33,\n", - " save_flows=True,\n", - " save_specific_discharge=True,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=1,\n", - " sy=sy,\n", - " ss=ss,\n", - " save_flows=True,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfic(gwf, strt=initial_head)\n", - "\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf, stress_period_data=wel_spd, save_flows=True\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " budget_filerecord=f\"{name}.cbc\",\n", - " head_filerecord=f\"{name}.hds\",\n", - " headprintrecord=[\n", - " (\"COLUMNS\", nradial, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " printrecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " filename=f\"{name}.oc\",\n", - " )\n", - "\n", - " flopy.mf6.ModflowUtlobs(gwf, print_input=False, continuous=obsdict)\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "1ed26d4e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d092cc66", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "8cdcc69e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the Axisymmetric model.\n", - "True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7548ec85", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(\"\\n\".join(buff))\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "06624685", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to solve Axisymmetric model using analytical equation." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b59a07cf", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def solve_analytical(obs2ana, times=None, no_solve=False):\n", - " # obs2ana = {obsdict[file][0] : analytical_name}\n", - " disukwargs = get_disu_radial_kwargs(\n", - " nlay, nradial, radius_outer, surface_elevation, layer_thickness\n", - " )\n", - " model_bottom = disukwargs[\"bot\"][get_radial_node(0, nlay - 1, nradial)]\n", - " sat_thick = initial_head - model_bottom\n", - "\n", - " key = next(iter(wel_spd))\n", - " nodes = []\n", - " rates = []\n", - " for nod, rat in wel_spd[key]:\n", - " nodes.append(nod[0])\n", - " rates.append(rat)\n", - " nodes.sort()\n", - " well_top = disukwargs[\"top\"][nodes[0]]\n", - " well_bot = disukwargs[\"bot\"][nodes[-1]]\n", - " pump = abs(sum(rates))\n", - "\n", - " ana_model = RadialUnconfinedDrawdown(\n", - " bottom_elevation=model_bottom,\n", - " hydraulic_conductivity_radial=k11,\n", - " hydraulic_conductivity_vertical=k33,\n", - " specific_storage=ss,\n", - " specific_yield=sy,\n", - " well_screen_elevation_top=well_top,\n", - " well_screen_elevation_bottom=well_bot,\n", - " saturated_thickness=sat_thick,\n", - " )\n", - "\n", - " build_times = times is None\n", - " if build_times:\n", - " totim = 0.0\n", - " for pertim in tdis_ds:\n", - " totim += pertim[0]\n", - " times_sy_base = np.logspace(-3, max([np.log10(totim), 2]), 100)\n", - "\n", - " analytical = {}\n", - " prop = {}\n", - " if not no_solve:\n", - " print(\"Solving Analytical Model (Very Slow)\")\n", - " for file in obsdict:\n", - " for row in obsdict[file]:\n", - " obs = row[0].upper()\n", - " if obs not in obs2ana:\n", - " continue\n", - " ana = obs2ana[obs]\n", - " nod = row[2][0]\n", - " obs_top = disukwargs[\"top\"][nod]\n", - " obs_bot = disukwargs[\"bot\"][nod]\n", - "\n", - " rad, lay = get_radius_lay_from_node(nod, nradial)\n", - "\n", - " if lay == 0:\n", - " # Uppermost layer has obs elevation at top,\n", - " # otherwise cell center\n", - " obs_el = obs_top\n", - " else:\n", - " obs_el = 0.5 * (obs_top + obs_bot)\n", - "\n", - " if rad == 0:\n", - " obs_rad = 0.0\n", - " else:\n", - " # radius_outer[r-1] + 0.5*(radius_outer[r] - radius_outer[r-1])\n", - " obs_rad = 0.5 * (radius_outer[rad - 1] + radius_outer[rad])\n", - "\n", - " if build_times:\n", - " times_sy = times_sy_base\n", - " times = [\n", - " ty * sy * obs_rad * obs_rad / (k11 * sat_thick)\n", - " for ty in times_sy_base\n", - " ]\n", - " else:\n", - " times_sy = [\n", - " ty * k11 * sat_thick / (sy * obs_rad * obs_rad)\n", - " for ty in times\n", - " ]\n", - "\n", - " times_ss = [ty * k11 / (ss * obs_rad * obs_rad) for ty in times]\n", - "\n", - " if not no_solve:\n", - " print(f\"Solving {ana}\")\n", - " analytical[ana] = ana_model.drawdown_times(\n", - " pump,\n", - " times,\n", - " obs_rad,\n", - " obs_el,\n", - " sumrtol=1.0e-6,\n", - " u_n_rtol=1.0e-5,\n", - " )\n", - " prop[ana] = [\n", - " times,\n", - " times_sy,\n", - " times_ss,\n", - " pump,\n", - " obs_rad,\n", - " sat_thick,\n", - " model_bottom,\n", - " ]\n", - "\n", - " return analytical, prop" - ] - }, - { - "cell_type": "markdown", - "id": "c26e5bb4", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the Axisymmetric model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9393c8f1", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_ts(sim, verbose=False, solve_analytical_solution=False):\n", - " pi = 3.141592653589793\n", - " gwf = sim.get_model(sim_name)\n", - " obs_csv_name = gwf.obs.output.obs_names[0]\n", - " obs_csv_file = gwf.obs.output.obs(f=obs_csv_name)\n", - "\n", - " tsdata = obs_csv_file.data\n", - " fmt = {\n", - " \"H_TOP\": \"og\",\n", - " \"H_MID\": \"or\",\n", - " \"H_BOT\": \"ob\",\n", - " \"a_top\": \"-g\",\n", - " \"a_mid\": \"-r\",\n", - " \"a_bot\": \"-b\",\n", - " }\n", - " obsnames = {\n", - " \"H_TOP\": \"MF6 (Top)\",\n", - " \"H_MID\": \"MF6 (Middle)\",\n", - " \"H_BOT\": \"MF6 (Bottom)\",\n", - " \"a_top\": \"Analytical (Top)\",\n", - " \"a_mid\": \"Analytical (Middle)\",\n", - " \"a_bot\": \"Analytical (Bottom)\",\n", - " }\n", - "\n", - " obs2ana = {\"H_TOP\": \"a_top\", \"H_MID\": \"a_mid\", \"H_BOT\": \"a_bot\"}\n", - "\n", - " if solve_analytical_solution:\n", - " analytical, ana_prop = solve_analytical(obs2ana)\n", - " analytical_time = []\n", - " else:\n", - " analytical, ana_prop = solve_analytical(obs2ana, no_solve=True)\n", - " analytical_time = [\n", - " 0.00016,\n", - " 0.000179732,\n", - " 0.000201897,\n", - " 0.000226796,\n", - " 0.000254765,\n", - " 0.000286184,\n", - " 0.000321477,\n", - " 0.000361123,\n", - " 0.000405658,\n", - " 0.000455686,\n", - " 0.000511883,\n", - " 0.00057501,\n", - " 0.000645923,\n", - " 0.000725581,\n", - " 0.000815062,\n", - " 0.000915579,\n", - " 0.001028492,\n", - " 0.001155329,\n", - " 0.001297809,\n", - " 0.00145786,\n", - " 0.00163765,\n", - " 0.001839611,\n", - " 0.002066479,\n", - " 0.002321326,\n", - " 0.002607601,\n", - " 0.002929181,\n", - " 0.00329042,\n", - " 0.003696208,\n", - " 0.004152039,\n", - " 0.004664085,\n", - " 0.005239279,\n", - " 0.005885408,\n", - " 0.00661122,\n", - " 0.007426542,\n", - " 0.008342413,\n", - " 0.009371233,\n", - " 0.010526932,\n", - " 0.011825155,\n", - " 0.013283481,\n", - " 0.014921654,\n", - " 0.016761852,\n", - " 0.018828991,\n", - " 0.021151058,\n", - " 0.023759492,\n", - " 0.026689609,\n", - " 0.029981079,\n", - " 0.033678466,\n", - " 0.037831831,\n", - " 0.042497405,\n", - " 0.047738356,\n", - " 0.053625642,\n", - " 0.060238973,\n", - " 0.067667886,\n", - " 0.076012963,\n", - " 0.085387188,\n", - " 0.09591748,\n", - " 0.107746411,\n", - " 0.121034132,\n", - " 0.13596055,\n", - " 0.152727753,\n", - " 0.171562756,\n", - " 0.192720566,\n", - " 0.216487644,\n", - " 0.243185773,\n", - " 0.273176424,\n", - " 0.306865642,\n", - " 0.34470955,\n", - " 0.387220522,\n", - " 0.434974119,\n", - " 0.488616881,\n", - " 0.548875086,\n", - " 0.616564575,\n", - " 0.692601805,\n", - " 0.778016253,\n", - " 0.873964355,\n", - " 0.981745164,\n", - " 1.102817937,\n", - " 1.238821892,\n", - " 1.391598404,\n", - " 1.563215932,\n", - " 1.755998025,\n", - " 1.972554783,\n", - " 2.215818194,\n", - " 2.48908183,\n", - " 2.79604544,\n", - " 3.14086504,\n", - " 3.528209184,\n", - " 3.96332217,\n", - " 4.452095044,\n", - " 5.00114536,\n", - " 5.617906775,\n", - " 6.310729695,\n", - " 7.088994332,\n", - " 7.963237703,\n", - " 8.945296292,\n", - " 10.04846631,\n", - " 11.2876837,\n", - " 12.67972637,\n", - " 14.24344137,\n", - " 16,\n", - " ]\n", - "\n", - " analytical[\"a_top\"] = [\n", - " 9.14e-06,\n", - " 1.48e-05,\n", - " 2.32e-05,\n", - " 3.51e-05,\n", - " 5.16e-05,\n", - " 7.39e-05,\n", - " 0.000103386,\n", - " 0.000141564,\n", - " 0.000190115,\n", - " 0.000250872,\n", - " 0.000325813,\n", - " 0.000417056,\n", - " 0.00052686,\n", - " 0.000657611,\n", - " 0.000811829,\n", - " 0.000992179,\n", - " 0.001201482,\n", - " 0.001442755,\n", - " 0.001719253,\n", - " 0.002034538,\n", - " 0.002392557,\n", - " 0.002797739,\n", - " 0.003255095,\n", - " 0.003770324,\n", - " 0.004349925,\n", - " 0.005001299,\n", - " 0.005732852,\n", - " 0.006554096,\n", - " 0.007475752,\n", - " 0.008509865,\n", - " 0.009669933,\n", - " 0.010971051,\n", - " 0.01243007,\n", - " 0.014065786,\n", - " 0.015899134,\n", - " 0.017953402,\n", - " 0.020254465,\n", - " 0.022831026,\n", - " 0.025714866,\n", - " 0.028941104,\n", - " 0.032548456,\n", - " 0.03657948,\n", - " 0.041080814,\n", - " 0.046103371,\n", - " 0.051702489,\n", - " 0.057938,\n", - " 0.064874212,\n", - " 0.072579742,\n", - " 0.081127182,\n", - " 0.090592554,\n", - " 0.101054493,\n", - " 0.112593132,\n", - " 0.125288641,\n", - " 0.139219391,\n", - " 0.154459742,\n", - " 0.171077492,\n", - " 0.189131034,\n", - " 0.208666373,\n", - " 0.229714163,\n", - " 0.252287007,\n", - " 0.276377285,\n", - " 0.301955794,\n", - " 0.328971456,\n", - " 0.357352252,\n", - " 0.387007461,\n", - " 0.417831084,\n", - " 0.449706211,\n", - " 0.482509951,\n", - " 0.516118451,\n", - " 0.550411552,\n", - " 0.585276682,\n", - " 0.620611726,\n", - " 0.656326766,\n", - " 0.692344745,\n", - " 0.72860122,\n", - " 0.765043446,\n", - " 0.801629049,\n", - " 0.838324511,\n", - " 0.875103648,\n", - " 0.911946208,\n", - " 0.94883664,\n", - " 0.985763066,\n", - " 1.022716447,\n", - " 1.059689924,\n", - " 1.0966783,\n", - " 1.133677645,\n", - " 1.170684993,\n", - " 1.207698108,\n", - " 1.24471531,\n", - " 1.281735341,\n", - " 1.318757264,\n", - " 1.355780385,\n", - " 1.392804192,\n", - " 1.429828316,\n", - " 1.466852493,\n", - " 1.503876535,\n", - " 1.540900317,\n", - " 1.577923757,\n", - " 1.614946805,\n", - " 1.651969438,\n", - " ]\n", - "\n", - " analytical[\"a_mid\"] = [\n", - " 0.042573248,\n", - " 0.053215048,\n", - " 0.065047371,\n", - " 0.077900907,\n", - " 0.091562277,\n", - " 0.10578645,\n", - " 0.120308736,\n", - " 0.134861006,\n", - " 0.149179898,\n", - " 0.163017203,\n", - " 0.176149026,\n", - " 0.188382628,\n", - " 0.199562503,\n", - " 0.209575346,\n", - " 0.218353885,\n", - " 0.22587733,\n", - " 0.232171831,\n", - " 0.237306589,\n", - " 0.241387585,\n", - " 0.244548545,\n", - " 0.246940521,\n", - " 0.24872049,\n", - " 0.250040497,\n", - " 0.25103848,\n", - " 0.251831919,\n", - " 0.252514802,\n", - " 0.253157938,\n", - " 0.253811816,\n", - " 0.254511215,\n", - " 0.255280058,\n", - " 0.256135833,\n", - " 0.257093057,\n", - " 0.258165369,\n", - " 0.259366956,\n", - " 0.260713168,\n", - " 0.262220999,\n", - " 0.263909262,\n", - " 0.265798794,\n", - " 0.267912645,\n", - " 0.270276262,\n", - " 0.272917675,\n", - " 0.27586768,\n", - " 0.279160018,\n", - " 0.28283153,\n", - " 0.286922294,\n", - " 0.291475727,\n", - " 0.296538626,\n", - " 0.302161152,\n", - " 0.308396727,\n", - " 0.31530182,\n", - " 0.322935596,\n", - " 0.331359479,\n", - " 0.340636352,\n", - " 0.350829851,\n", - " 0.362003212,\n", - " 0.374217985,\n", - " 0.387532593,\n", - " 0.402000693,\n", - " 0.417669407,\n", - " 0.434577538,\n", - " 0.452753827,\n", - " 0.472215504,\n", - " 0.492966953,\n", - " 0.514999008,\n", - " 0.538288679,\n", - " 0.562799606,\n", - " 0.588483025,\n", - " 0.615279515,\n", - " 0.643120962,\n", - " 0.671933085,\n", - " 0.701637983,\n", - " 0.732156526,\n", - " 0.763410706,\n", - " 0.795325415,\n", - " 0.827829825,\n", - " 0.860858334,\n", - " 0.894351053,\n", - " 0.928253957,\n", - " 0.962518747,\n", - " 0.997102451,\n", - " 1.031967356,\n", - " 1.067080013,\n", - " 1.102411044,\n", - " 1.137934722,\n", - " 1.17362841,\n", - " 1.209472238,\n", - " 1.245448747,\n", - " 1.281542585,\n", - " 1.317740238,\n", - " 1.354029805,\n", - " 1.390400789,\n", - " 1.426843932,\n", - " 1.463351049,\n", - " 1.499914938,\n", - " 1.53652918,\n", - " 1.573188127,\n", - " 1.609886766,\n", - " 1.64662066,\n", - " 1.683385875,\n", - " 1.720178921,\n", - " ]\n", - "\n", - " analytical[\"a_bot\"] = [\n", - " 0.086684154,\n", - " 0.103649206,\n", - " 0.12188172,\n", - " 0.141163805,\n", - " 0.16124535,\n", - " 0.181846061,\n", - " 0.202667182,\n", - " 0.223392774,\n", - " 0.243699578,\n", - " 0.263275092,\n", - " 0.281824849,\n", - " 0.299088528,\n", - " 0.31485153,\n", - " 0.328955429,\n", - " 0.341304221,\n", - " 0.351868481,\n", - " 0.360684432,\n", - " 0.367848506,\n", - " 0.373508853,\n", - " 0.377853369,\n", - " 0.381094083,\n", - " 0.383450902,\n", - " 0.385136877,\n", - " 0.386345028,\n", - " 0.387238663,\n", - " 0.387947536,\n", - " 0.388568938,\n", - " 0.389170336,\n", - " 0.389796684,\n", - " 0.390476869,\n", - " 0.39123089,\n", - " 0.392073081,\n", - " 0.393015962,\n", - " 0.39407278,\n", - " 0.395256673,\n", - " 0.396583156,\n", - " 0.398068337,\n", - " 0.399731151,\n", - " 0.401591476,\n", - " 0.403672105,\n", - " 0.405997893,\n", - " 0.408596189,\n", - " 0.411497001,\n", - " 0.414733164,\n", - " 0.418340479,\n", - " 0.422357833,\n", - " 0.426826999,\n", - " 0.431793796,\n", - " 0.437306073,\n", - " 0.443415589,\n", - " 0.450176656,\n", - " 0.457646089,\n", - " 0.46588273,\n", - " 0.47494648,\n", - " 0.484898814,\n", - " 0.495799471,\n", - " 0.507707617,\n", - " 0.520679174,\n", - " 0.534765662,\n", - " 0.550012634,\n", - " 0.566458073,\n", - " 0.584130854,\n", - " 0.60304937,\n", - " 0.623219948,\n", - " 0.644638018,\n", - " 0.667285046,\n", - " 0.691130674,\n", - " 0.716132499,\n", - " 0.742239678,\n", - " 0.76939134,\n", - " 0.797520861,\n", - " 0.826557513,\n", - " 0.85642935,\n", - " 0.887062398,\n", - " 0.918386519,\n", - " 0.950334816,\n", - " 0.982842103,\n", - " 1.015851071,\n", - " 1.049306941,\n", - " 1.083160734,\n", - " 1.117368294,\n", - " 1.151890127,\n", - " 1.186690934,\n", - " 1.221739246,\n", - " 1.257007172,\n", - " 1.292471077,\n", - " 1.32810677,\n", - " 1.363895877,\n", - " 1.399822391,\n", - " 1.435868577,\n", - " 1.472023401,\n", - " 1.508273605,\n", - " 1.544607161,\n", - " 1.581017341,\n", - " 1.617494414,\n", - " 1.654030939,\n", - " 1.690620311,\n", - " 1.72725511,\n", - " 1.763933202,\n", - " 1.800648435,\n", - " ]\n", - "\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=verbose)\n", - "\n", - " obs_fig = \"obs-head\"\n", - " fig = plt.figure(figsize=(5, 3))\n", - " ax = fig.add_subplot()\n", - " ax.set_xlabel(\"time (d)\")\n", - " ax.set_ylabel(\"head (ft)\")\n", - " for name in tsdata.dtype.names[1:]:\n", - " ax.plot(\n", - " tsdata[\"totim\"],\n", - " tsdata[name],\n", - " fmt[name],\n", - " label=obsnames[name],\n", - " markerfacecolor=\"none\",\n", - " )\n", - " # , markersize=3\n", - "\n", - " for name in analytical:\n", - " n = len(analytical[name])\n", - " if solve_analytical_solution:\n", - " ana_times = ana_prop[name][0]\n", - " else:\n", - " ana_times = analytical_time\n", - "\n", - " ax.plot(\n", - " ana_times[:n],\n", - " [50.0 - h for h in analytical[name]],\n", - " fmt[name],\n", - " label=obsnames[name],\n", - " )\n", - "\n", - " fs.graph_legend(ax)\n", - "\n", - " fig.tight_layout()\n", - "\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}-{}{}\".format(sim_name, obs_fig, config.figure_ext),\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " obs_fig = \"obs-dimensionless\"\n", - " fig = plt.figure(figsize=(5, 3))\n", - " fig.tight_layout()\n", - " ax = fig.add_subplot()\n", - " ax.set_xlim(0.001, 100.0)\n", - " ax.set_ylim(0.001, 100.0)\n", - " ax.grid(visible=True, which=\"major\", axis=\"both\")\n", - " ax.set_ylabel(\"Dimensionless Drawdown, $s_d$\")\n", - " ax.set_xlabel(\"Dimensionless Time, $t_y$\")\n", - " for name in tsdata.dtype.names[1:]:\n", - " q = ana_prop[obs2ana[name]][3]\n", - " r = ana_prop[obs2ana[name]][4]\n", - " b = ana_prop[obs2ana[name]][5]\n", - " ax.loglog(\n", - " [k11 * b * ts / (sy * r * r) for ts in tsdata[\"totim\"]],\n", - " [4 * pi * k11 * b * (initial_head - h) / q for h in tsdata[name]],\n", - " fmt[name],\n", - " label=obsnames[name],\n", - " markerfacecolor=\"none\",\n", - " )\n", - "\n", - " for name in analytical:\n", - " q = ana_prop[name][3]\n", - " b = ana_prop[name][5] # [pump, radius, sat_thick, model_bottom]\n", - " if solve_analytical_solution:\n", - " ana_times = ana_prop[name][0]\n", - " else:\n", - " ana_times = analytical_time\n", - "\n", - " n = len(analytical[name])\n", - " time_sy = [k11 * b * ts / (sy * r * r) for ts in ana_times[:n]]\n", - " ana = [4 * pi * k11 * b * s / q for s in analytical[name]]\n", - " ax.plot(time_sy, ana, fmt[name], label=obsnames[name])\n", - "\n", - " fs.graph_legend(ax)\n", - "\n", - " fig.tight_layout()\n", - "\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}-{}{}\".format(sim_name, obs_fig, config.figure_ext),\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "8c8db5db", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model radial bands." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e8ee9706", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(verbose=False):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - "\n", - " # Print all radial bands\n", - " fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(6.4, 3.1))\n", - " # fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 4.5))\n", - " ax = axs[0]\n", - "\n", - " max_rad = radius_outer[-1]\n", - " max_rad = max_rad + (max_rad * 0.1)\n", - " ax.set_xlim(-max_rad, max_rad)\n", - " ax.set_ylim(-max_rad, max_rad)\n", - " ax.set_aspect(\"equal\", adjustable=\"box\")\n", - "\n", - " circle_center = (0.0, 0.0)\n", - " for r in radius_outer:\n", - " circle = Circle(circle_center, r, color=\"black\", fill=False, lw=0.3)\n", - " ax.add_artist(circle)\n", - "\n", - " ax.set_xlabel(\"x-position (ft)\")\n", - " ax.set_ylabel(\"y-position (ft)\")\n", - " ax.annotate(\n", - " \"A\",\n", - " (-0.11, 1.02),\n", - " xycoords=\"axes fraction\",\n", - " fontweight=\"black\",\n", - " fontsize=\"xx-large\",\n", - " )\n", - "\n", - " # Print first 5 radial bands\n", - " nband = 5\n", - " ax = axs[1]\n", - "\n", - " radius_subset = radius_outer[:nband]\n", - " max_rad = radius_subset[-1]\n", - " max_rad = max_rad + (max_rad * 0.3)\n", - "\n", - " ax.set_xlim(-max_rad, max_rad)\n", - " ax.set_ylim(-max_rad, max_rad)\n", - " ax.set_aspect(\"equal\", adjustable=\"box\")\n", - "\n", - " circle_center = (0.0, 0.0)\n", - "\n", - " r = radius_subset[0]\n", - " circle = Circle(circle_center, r, color=\"red\", label=\"Well\")\n", - " ax.add_artist(circle)\n", - " for r in radius_subset:\n", - " circle = Circle(circle_center, r, color=\"black\", lw=1, fill=False)\n", - " ax.add_artist(circle)\n", - "\n", - " ax.set_xlabel(\"x-position (ft)\")\n", - " ax.set_ylabel(\"y-position (ft)\")\n", - "\n", - " ax.annotate(\n", - " \"B\",\n", - " (-0.06, 1.02),\n", - " xycoords=\"axes fraction\",\n", - " fontweight=\"black\",\n", - " fontsize=\"xx-large\",\n", - " )\n", - "\n", - " fs.graph_legend(ax)\n", - "\n", - " fig.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\", \"figures\", \"{}-grid{}\".format(sim_name, config.figure_ext)\n", - " )\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "f05046a7", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "93ee4c39", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(silent=True):\n", - " if not config.plotModel:\n", - " return\n", - "\n", - " if silent:\n", - " verbosity_level = 0\n", - " else:\n", - " verbosity_level = 1\n", - "\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation.load(\n", - " sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level\n", - " )\n", - "\n", - " verbose = not silent\n", - "\n", - " if config.plotModel:\n", - " plot_grid(verbose)\n", - " plot_ts(\n", - " sim, verbose, solve_analytical_solution=solve_analytical_solution\n", - " )\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "02ba73b0", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the Axisymmetric model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0fbd0e8a", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " # key = list(parameters.keys())[idx]\n", - " # params = parameters[key].copy()\n", - "\n", - " sim = build_model(sim_name)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, \"could not run...{}\".format(sim_name)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b4d826f8", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_and_plot():\n", - " simulation(silent=False)\n", - " plot_results(silent=False)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "6046fac3", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9c7cdb27", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Axisymmetric Example\n", - "\n", - " # MF6 Axisymmetric Model\n", - " simulation()\n", - "\n", - " # Solve analytical and plot results with MF6 results\n", - " plot_results()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-sagehen.ipynb b/notebooks/ex-gwf-sagehen.ipynb deleted file mode 100644 index 4bedb914..00000000 --- a/notebooks/ex-gwf-sagehen.ipynb +++ /dev/null @@ -1,1193 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6d9b3615", - "metadata": {}, - "source": [ - "## Sagehen example with UZF, SFR, and MVR advanced packages activated\n", - "\n", - "This script reproduces example 1 in the UZF1 Techniques and Methods\n", - "(Niswonger et al., 2006)." - ] - }, - { - "cell_type": "markdown", - "id": "eb2bafd3", - "metadata": {}, - "source": [ - "### MODFLOW 6 Sagehen Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "e2de4fe7", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a51cf3e7", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "536b636c", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))\n", - "import config\n", - "import flopy\n", - "import flopy.utils.binaryfile as bf\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "import sfr_uzf_mvr_support_funcs as sageBld\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "9152d058", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fdca92b4", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"data\", \"ex-gwf-sagehen\"))\n", - "import sfr_static as sfrDat" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d05721ca", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "3cb62acc", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4edef11c", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 6)\n", - "figure_size_ts = (6, 3)" - ] - }, - { - "cell_type": "markdown", - "id": "26a622a0", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5fb59464", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwf-sagehen\"" - ] - }, - { - "cell_type": "markdown", - "id": "59251472", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "98c9c842", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "98ffca7e", - "metadata": {}, - "source": [ - "Table Sagehen Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "36c76c80", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nlay = 1 # Number of layers in parent model\n", - "nrow = 73 # Number of rows in parent model\n", - "ncol = 81 # Number of columns in parent model\n", - "delr = 90.0 # Parent model column width ($m$)\n", - "delc = 90.0 # Parent model row width ($m$)\n", - "k11 = \"0.005 - 0.3\" # Horizontal hydraulic conductivity ($m/d$)\n", - "k33 = \"0.01 - 0.3\" # Vertical hydraulic conductivity ($m/d$)\n", - "sydum = \"0.1 - 0.2\" # Specific Yield\n", - "dum1 = \"0.15 - 0.25\" # Saturated water content\n", - "dum2 = 0.10 # Extinction water content\n", - "dum3 = \"0.005 - 0.3\" # Saturated hydraulic conductivity of unsaturated zone\n", - "eps = 4.0 # Brooks-Corey Epsilon\n", - "sfrdum1 = 213 # Number of SFR stream reaches\n", - "sfrdum2 = 0.3 # Hydraulic conductivity of streambed ($m/d$)\n", - "sfrdum3 = 3 # Width of stream reaches ($m$)\n", - "sfrdum4 = 1 # Streambed thickness ($m$)" - ] - }, - { - "cell_type": "markdown", - "id": "8cd81e89", - "metadata": {}, - "source": [ - "Additional model input preparation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "112993e2", - "metadata": {}, - "outputs": [], - "source": [ - "# Time related variables\n", - "num_ts = 399\n", - "perlen = [1] * num_ts\n", - "nper = len(perlen)\n", - "nstp = [1] * num_ts\n", - "tsmult = [1.0] * num_ts" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1bddbba5", - "metadata": {}, - "outputs": [], - "source": [ - "# from mf-nwt .dis file\n", - "dat_pth = os.path.join(config.data_ws, example_name)\n", - "top = np.loadtxt(os.path.join(dat_pth, \"top1.txt\"))\n", - "bot1 = np.loadtxt(os.path.join(dat_pth, \"bot1.txt\"))\n", - "# from mf-nwt .bas file\n", - "idomain1 = np.loadtxt(os.path.join(dat_pth, \"ibnd1.txt\"))\n", - "strt = np.loadtxt(os.path.join(dat_pth, \"strt1.txt\"))\n", - "# peel out locations of negative values for setting constant head data\n", - "tmp1 = np.where(idomain1 < 0)\n", - "listOfChdCoords = list(zip(np.zeros_like(tmp1[0]), tmp1[0], tmp1[1]))\n", - "# get the corresponding constant head values\n", - "if len(listOfChdCoords) > 0:\n", - " chd_lay1 = list(np.take(strt, np.ravel_multi_index(tmp1, strt.shape)))\n", - "chdspd = []\n", - "for i in np.arange(len(listOfChdCoords)):\n", - " chdspd.append([listOfChdCoords[i], chd_lay1[i]])\n", - "# finally, get rid of the negative values in idomain since mf6 treats\n", - "# negatives like zeros\n", - "idomain = np.abs(idomain1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1a094d8b", - "metadata": {}, - "outputs": [], - "source": [ - "# from mf-nwt .upw file\n", - "k11 = np.loadtxt(os.path.join(dat_pth, \"kh1.txt\"))\n", - "sy = np.loadtxt(os.path.join(dat_pth, \"sy1.txt\"))\n", - "k33 = np.loadtxt(os.path.join(dat_pth, \"kv1.txt\"))\n", - "icelltype = 1 # Water table resides in layer 1\n", - "iconvert = np.ones_like(strt)" - ] - }, - { - "cell_type": "markdown", - "id": "a1075693", - "metadata": {}, - "source": [ - "Solver settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8a6a21d7", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 300, 500\n", - "hclose, rclose, relax = 3e-2, 3e-2, 0.97" - ] - }, - { - "cell_type": "markdown", - "id": "22ee3376", - "metadata": {}, - "source": [ - "#### Prepping input for SFR package\n", - "Get package_data information" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3386d8c0", - "metadata": {}, - "outputs": [], - "source": [ - "segs = sfrDat.get_sfrsegs()\n", - "rchs = sfrDat.get_sfrrchs()\n", - "sfrcells = sfrDat.get_sfrcells()\n", - "rlen = sfrDat.get_sfrlen()\n", - "rgrd = sfrDat.get_rgrd()\n", - "rtp = sfrDat.get_rtp()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5272a293", - "metadata": {}, - "outputs": [], - "source": [ - "# Define the connections\n", - "conns = sageBld.gen_mf6_sfr_connections(segs, rchs)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9acb4e01", - "metadata": {}, - "outputs": [], - "source": [ - "rwid = 3.0\n", - "rbth = 1.0\n", - "rhk = 0.6\n", - "man = 0.04\n", - "ustrf = 1.0\n", - "ndv = 0\n", - "pkdat = []\n", - "for i in np.arange(len(rlen)):\n", - " ncon = len(conns[i]) - 1\n", - " pkdat.append(\n", - " (\n", - " i,\n", - " sfrcells[i],\n", - " rlen[i],\n", - " rwid,\n", - " rgrd[i],\n", - " rtp[i],\n", - " rbth,\n", - " rhk,\n", - " man,\n", - " ncon,\n", - " ustrf,\n", - " ndv,\n", - " )\n", - " )" - ] - }, - { - "cell_type": "markdown", - "id": "14c9e29c", - "metadata": {}, - "source": [ - "#### Prepping input for DRN package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "30fe2e98", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "# Instantiating MODFLOW 6 drain package\n", - "# Here, the drain (DRN) package is used to simulate groundwater discharge to\n", - "# land surface to keep this water separate from rejected infiltrated simulated\n", - "# by the UZF package. Need to cycle through all land surface cells and create a\n", - "# drain for handling groundwater discharge to land surface\n", - "drn_spd = []\n", - "drn_dict = {}\n", - "drn_dict_rev = {}\n", - "# Use an arbitrarily high conductance term to avoid impeding groundwater disch.\n", - "cond = 10000\n", - "# See definition of auxdepthname in DRN package doc to learn more about param\n", - "ddrn = -0.25\n", - "idrnno = 0\n", - "for i in np.arange(0, top.shape[0]):\n", - " for j in np.arange(0, top.shape[1]):\n", - " # Don't add drains to sfr and chd cells:\n", - " sfrCell_bool = (\n", - " 1\n", - " if len([itm for itm in sfrcells if itm[1] == i and itm[2] == j]) > 0\n", - " else 0\n", - " )\n", - " chdCell_bool = (\n", - " 1\n", - " if len([itm for itm in listOfChdCoords if itm[1] == i and itm[2] == j]) > 0\n", - " else 0\n", - " )\n", - " if idomain1[i, j] and not sfrCell_bool and not chdCell_bool:\n", - " drn_spd.append([(0, i, j), top[i, j], cond, ddrn]) # 'ddrn',\n", - " # append dictionary of drain indices\n", - " drn_dict.update({(i, j): idrnno})\n", - " drn_dict_rev.update({idrnno: (i, j)})\n", - " idrnno += 1" - ] - }, - { - "cell_type": "markdown", - "id": "8c71b346", - "metadata": {}, - "source": [ - "#### Prepping input for UZF package\n", - "Package_data information" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d5b936a7", - "metadata": {}, - "outputs": [], - "source": [ - "iuzbnd = np.loadtxt(os.path.join(dat_pth, \"iuzbnd.txt\"))\n", - "thts = np.loadtxt(os.path.join(dat_pth, \"thts.txt\"))\n", - "uzk33 = np.loadtxt(os.path.join(dat_pth, \"vks.txt\"))\n", - "finf_grad = np.loadtxt(os.path.join(dat_pth, \"finf_gradient.txt\"))\n", - "# next, load time series of multipliers\n", - "uz_ts = pd.read_csv(\n", - " os.path.join(dat_pth, \"uzf_ts.dat\"), delim_whitespace=True, header=0\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a97f36bb", - "metadata": {}, - "outputs": [], - "source": [ - "# Need to set iuzbnd inactive where there are constant head cells, or where the\n", - "# model grid is inactive\n", - "cells2inactivate = idomain1 - iuzbnd\n", - "iuzbnd = iuzbnd + cells2inactivate\n", - "for chd_cell in listOfChdCoords:\n", - " iuzbnd[chd_cell[1], chd_cell[2]] = 0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a87d1048", - "metadata": {}, - "outputs": [], - "source": [ - "ha = 0.0\n", - "hroot = 0.0\n", - "rootact = 0.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d25bf3e2", - "metadata": {}, - "outputs": [], - "source": [ - "uzf_packagedata = []\n", - "pd0 = []\n", - "iuzno_cell_dict = {}\n", - "iuzno_dict_rev = {}\n", - "iuzno = 0\n", - "surfdep = 0.1\n", - "# Set up the UZF static variables\n", - "nuzfcells = 0\n", - "for k in range(nlay):\n", - " for i in range(0, iuzbnd.shape[0] - 1):\n", - " for j in range(0, iuzbnd.shape[1] - 1):\n", - " if iuzbnd[i, j] != 0:\n", - " nuzfcells += 1\n", - " if k == 0:\n", - " lflag = 1\n", - " # establish new dictionary entry for current cell\n", - " # addresses & iuzno connections are both 0-based\n", - " iuzno_cell_dict.update({(i, j): iuzno})\n", - " # For post-processing the mvr output, need reverse dict\n", - " iuzno_dict_rev.update({iuzno: (i, j)})\n", - " else:\n", - " lflag = 0\n", - "\n", - " # Set the vertical connection, which is the cell below,\n", - " # but in this 1 layer model set to -1 which flopy adjusts to 0\n", - " ivertcon = -1\n", - "\n", - " vks = uzk33[i, j]\n", - " thtr = uz_ts[\"extwc\"].iloc[0]\n", - " thtsx = thts[i, j]\n", - " thti = thtr + 0.01\n", - " eps = 4.0\n", - "\n", - " # Set the boundname for the land surface cells\n", - " bndnm = \"sage\"\n", - "\n", - " uz = [\n", - " iuzno,\n", - " (k, i, j),\n", - " lflag,\n", - " ivertcon,\n", - " surfdep,\n", - " vks,\n", - " thtr,\n", - " thtsx,\n", - " thti,\n", - " eps,\n", - " bndnm,\n", - " ]\n", - " uzf_packagedata.append(uz)\n", - "\n", - " iuzno += 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ffc7c81c", - "metadata": {}, - "outputs": [], - "source": [ - "# Next prepare the stress period data for UZF\n", - "# Store the steady state uzf stresses in dictionary\n", - "uzf_perioddata = {}\n", - "for t in range(num_ts):\n", - " iuzno = 0\n", - " spdx = []\n", - " for i in range(0, iuzbnd.shape[0] - 1):\n", - " for j in range(0, iuzbnd.shape[1] - 1):\n", - " if iuzbnd[i, j] != 0:\n", - " finf = finf_grad[i, j] * uz_ts[\"finf\"].iloc[t]\n", - " pet = uz_ts[\"pet\"].iloc[t]\n", - " extdp = uz_ts[\"rootdepth\"].iloc[t]\n", - " extwc = uz_ts[\"extwc\"].iloc[t]\n", - " spdx.append([iuzno, finf, pet, extdp, extwc, ha, hroot, rootact])\n", - " iuzno += 1\n", - " uzf_perioddata.update({t: spdx})" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "920107f2", - "metadata": {}, - "outputs": [], - "source": [ - "# Set up runoff connections, which relies on a helper function inside a\n", - "# companion script\n", - "#\n", - "# Leverages a function that uses the top elevation array and SFR locations to\n", - "# calculate an array that is the equivalent of the irunbnd array from the UZF1\n", - "# package. The MVR package will be used to establish these connection in MF6\n", - "# since the IRUNBND functionality went away in the new MF6 framework.\n", - "irunbnd = sageBld.determine_runoff_conns_4mvr(dat_pth, top, idomain1, rchs, nrow, ncol)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "526b4d5f", - "metadata": {}, - "outputs": [], - "source": [ - "iuzno = 0\n", - "k = 0 # Hard-wire the layer no.\n", - "first0ok = True\n", - "static_mvrperioddata = []\n", - "for i in range(0, iuzbnd.shape[0]):\n", - " for j in range(0, iuzbnd.shape[1]):\n", - " if irunbnd[i, j] > 0: # This is a uzf -> sfr connection\n", - " iuzno = iuzno_cell_dict.get((i, j))\n", - " if iuzno or first0ok:\n", - " static_mvrperioddata.append(\n", - " (\"UZF-1\", iuzno, \"SFR-1\", irunbnd[i, j] - 1, \"FACTOR\", 1.0)\n", - " )\n", - "\n", - " drn_idx = drn_dict.get((i, j))\n", - " if drn_idx:\n", - " static_mvrperioddata.append(\n", - " (\"DRN-1\", drn_idx, \"SFR-1\", irunbnd[i, j] - 1, \"FACTOR\", 1.0)\n", - " )\n", - " first0ok = False" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "516f62f5", - "metadata": {}, - "outputs": [], - "source": [ - "mvrspd = {0: static_mvrperioddata}\n", - "mvrpack = [[\"UZF-1\"], [\"SFR-1\"], [\"DRN-1\"]]\n", - "maxpackages = len(mvrpack)\n", - "maxmvr = 10000 # Something arbitrarily high" - ] - }, - { - "cell_type": "markdown", - "id": "31128652", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function to build models\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4749742a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, silent=False):\n", - " if config.buildModel:\n", - " # Instantiate the MODFLOW 6 simulation\n", - " sim_ws = os.path.join(ws, example_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=example_name,\n", - " version=\"mf6\",\n", - " sim_ws=sim_ws,\n", - " exe_name=mf6exe,\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " for i in range(len(perlen)):\n", - " tdis_rc.append((perlen[i], nstp[i], tsmult[i]))\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwfname = example_name\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " newtonoptions=\"newton\",\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"dbd\",\n", - " linear_acceleration=\"BICGSTAB\",\n", - " under_relaxation_theta=0.7,\n", - " under_relaxation_kappa=0.08,\n", - " under_relaxation_gamma=0.05,\n", - " under_relaxation_momentum=0.0,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=\"1000.0 strict\",\n", - " inner_maximum=ninner,\n", - " relaxation_factor=relax,\n", - " number_orthogonalizations=2,\n", - " preconditioner_levels=8,\n", - " preconditioner_drop_tolerance=0.001,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=bot1,\n", - " idomain=idomain,\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " alternative_cell_averaging=\"AMT-HMK\",\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=False,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiate MODFLOW 6 storage package\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " ss=2e-6,\n", - " sy=sy,\n", - " iconvert=iconvert,\n", - " steady_state={0: True},\n", - " transient={1: True},\n", - " filename=f\"{gwfname}.sto\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " chdspdx = {0: chdspd}\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspdx,\n", - " save_flows=False,\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " maxbound = len(drn_spd) # The total number\n", - " spd = {0: drn_spd}\n", - " flopy.mf6.ModflowGwfdrn(\n", - " gwf,\n", - " pname=\"DRN-1\",\n", - " auxiliary=[\"ddrn\"],\n", - " auxdepthname=\"ddrn\",\n", - " print_input=False,\n", - " print_flows=False,\n", - " maxbound=maxbound,\n", - " mover=True,\n", - " stress_period_data=spd, # wel_spd established in the MVR setup\n", - " boundnames=False,\n", - " save_flows=True,\n", - " filename=f\"{gwfname}.drn\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 streamflow routing package\n", - " flopy.mf6.ModflowGwfsfr(\n", - " gwf,\n", - " print_stage=False,\n", - " print_flows=False,\n", - " budget_filerecord=gwfname + \".sfr.bud\",\n", - " save_flows=True,\n", - " mover=True,\n", - " pname=\"SFR-1\",\n", - " time_conversion=86400.0,\n", - " boundnames=True,\n", - " nreaches=len(conns),\n", - " packagedata=pkdat,\n", - " connectiondata=conns,\n", - " perioddata=None,\n", - " filename=f\"{gwfname}.sfr\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 unsaturated zone flow package\n", - " flopy.mf6.ModflowGwfuzf(\n", - " gwf,\n", - " nuzfcells=nuzfcells,\n", - " boundnames=True,\n", - " mover=True,\n", - " ntrailwaves=15,\n", - " nwavesets=150,\n", - " print_flows=False,\n", - " save_flows=True,\n", - " simulate_et=True,\n", - " linear_gwet=True,\n", - " packagedata=uzf_packagedata,\n", - " perioddata=uzf_perioddata,\n", - " budget_filerecord=f\"{gwfname}.uzf.bud\",\n", - " pname=\"UZF-1\",\n", - " filename=f\"{gwfname}.uzf\",\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfmvr(\n", - " gwf,\n", - " pname=\"MVR-1\",\n", - " maxmvr=maxmvr,\n", - " print_flows=False,\n", - " maxpackages=maxpackages,\n", - " packages=mvrpack,\n", - " perioddata=mvrspd,\n", - " budget_filerecord=gwfname + \".mvr.bud\",\n", - " filename=f\"{gwfname}.mvr\",\n", - " )\n", - "\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "5f22919e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "29c41b41", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "9d6c041e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c1b51a8e", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "66bcb08e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "afd6a034", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mf6, idx):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " sim_name = mf6.name\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " # Generate a plot of FINF distribution\n", - " finf_plt = finf_grad.copy()\n", - " finf_plt[idomain1 == 0] = np.nan\n", - "\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1)\n", - " plt.imshow(finf_plt, cmap=\"jet\")\n", - " title = \"Precipitation distribution\"\n", - " cbar = plt.colorbar(shrink=0.5)\n", - " cbar.ax.set_title(\"Infiltration\\nrate\\nfactor\", pad=20)\n", - " plt.xlabel(\"Column Number\")\n", - " plt.ylabel(\"Row Number\")\n", - " fs.heading(heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(sim_name + \"-finfFact\", config.figure_ext),\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " # Start by retrieving some output\n", - " gwf = mf6.get_model(list(mf6.model_names)[0])\n", - " hdsobj = gwf.output.head()\n", - " modobj = gwf.output.budget()\n", - " sfrobj = gwf.sfr.output.budget()\n", - " uzfobj = gwf.uzf.output.budget()\n", - "\n", - " ckstpkper = modobj.get_kstpkper()\n", - "\n", - " hds = []\n", - " depths = []\n", - " hd_tmp = hdsobj.get_data(kstpkper=ckstpkper[0])\n", - " hd_tmp = np.where(hd_tmp == 1e30, 0, hd_tmp)\n", - " hds.append(hd_tmp)\n", - " depths.append(top - hd_tmp[0, :, :])\n", - " depths = np.array(depths)\n", - " depths = depths[0, :, :]\n", - "\n", - " # Generate a plot of the gw table depths for the steady state stress per\n", - " depths[idomain1 == 0] = np.nan\n", - "\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1)\n", - " plt.imshow(depths, vmin=0, vmax=25, cmap=\"jet\")\n", - " cbar = plt.colorbar(shrink=0.5, ticks=[0, 5, 10, 15, 20, 25])\n", - " cbar.ax.set_yticklabels([\"0\", \"5\", \"10\", \"15\", \"20\", \"> 25\"])\n", - " cbar.ax.set_title(\"Depth to\\nwater\\ntable,\\nin m\", pad=20)\n", - " plt.xlabel(\"Column Number\")\n", - " plt.ylabel(\"Row Number\")\n", - " title = \"Depth To Groundwater\"\n", - " fs.heading(heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(sim_name + \"-gwDepth\", config.figure_ext),\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " drn_disQ = []\n", - " uzrech = []\n", - " finf_tot = []\n", - " sfr_gwsw = []\n", - " sfr_flow = []\n", - " rejinf = []\n", - " uzet = []\n", - " gwet = []\n", - " outflow = []\n", - "\n", - " for kstpkper in ckstpkper:\n", - " # 1. Compile groundwater discharge to land surface\n", - " drn_tmp = modobj.get_data(kstpkper=kstpkper, text=\" DRN-TO-MVR\")\n", - " drn_arr = np.zeros_like(top)\n", - " for itm in drn_tmp[0]:\n", - " i, j = drn_dict_rev[itm[1] - 1]\n", - " drn_arr[i, j] = itm[2]\n", - " drn_disQ.append(drn_arr)\n", - "\n", - " # 2. Compile groundwater discharge to stream cells\n", - " sfr_tmp = sfrobj.get_data(kstpkper=kstpkper, text=\" GWF\")\n", - " sfr_arr = np.zeros_like(top)\n", - " for x, itm in enumerate(sfr_tmp[0]):\n", - " i = sfrcells[x][1]\n", - " j = sfrcells[x][2]\n", - " sfr_arr[i, j] = itm[2]\n", - " sfr_gwsw.append(sfr_arr)\n", - "\n", - " # 3. Compile Infiltrated amount\n", - " uzf_tmp = uzfobj.get_data(kstpkper=kstpkper, text=\" INFILTRATION\")\n", - " finf_arr = np.zeros_like(top)\n", - " for itm in uzf_tmp[0]:\n", - " i, j = iuzno_dict_rev[itm[0] - 1]\n", - " finf_arr[i, j] = itm[2]\n", - " finf_tot.append(finf_arr)\n", - "\n", - " # 4. Compile recharge from UZF\n", - " uzrch_tmp = uzfobj.get_data(kstpkper=kstpkper, text=\" GWF\")\n", - " uzrch_arr = np.zeros_like(top)\n", - " for itm in uzrch_tmp[0]:\n", - " i, j = iuzno_dict_rev[itm[0] - 1]\n", - " uzrch_arr[i, j] = itm[2]\n", - " uzrech.append(uzrch_arr)\n", - "\n", - " # 5. Compile rejected infiltration\n", - " rejinf_tmp = uzfobj.get_data(kstpkper=kstpkper, text=\" REJ-INF-TO-MVR\")\n", - " rejinf_arr = np.zeros_like(top)\n", - " for itm in rejinf_tmp[0]:\n", - " i, j = iuzno_dict_rev[itm[0] - 1]\n", - " rejinf_arr[i, j] = itm[2]\n", - " rejinf.append(rejinf_arr)\n", - "\n", - " # 6. Compile unsat ET\n", - " uzet_tmp = uzfobj.get_data(kstpkper=kstpkper, text=\" UZET\")\n", - " uzet_arr = np.zeros_like(top)\n", - " for itm in uzet_tmp[0]:\n", - " i, j = iuzno_dict_rev[itm[0] - 1]\n", - " uzet_arr[i, j] = itm[2]\n", - " uzet.append(uzet_arr)\n", - "\n", - " # 7. Compile groundwater ET\n", - " gwet_tmp = modobj.get_data(kstpkper=kstpkper, text=\" UZF-GWET\")\n", - " gwet_arr = np.zeros_like(top)\n", - " for itm in gwet_tmp[0]:\n", - " i, j = iuzno_dict_rev[itm[1] - 1]\n", - " gwet_arr[i, j] = itm[2]\n", - " gwet.append(gwet_arr)\n", - "\n", - " # 8. Get flows at outlet\n", - " outletQ = sfrobj.get_data(kstpkper=kstpkper, text=\" FLOW-JA-FACE\")\n", - " outflow.append(outletQ[0][-1][2])\n", - "\n", - " drn_disQ = np.array(drn_disQ)\n", - " sfr_gwsw = np.array(sfr_gwsw)\n", - " finf_tot = np.array(finf_tot)\n", - " uzrech = np.array(uzrech)\n", - " rejinf = np.array(rejinf)\n", - " uzet = np.array(uzet)\n", - " gwet = np.array(gwet)\n", - " outflow = np.array(outflow)\n", - "\n", - " drn_disQ_ts = drn_disQ.sum(axis=-1).sum(axis=-1)\n", - " sfr_gwsw_ts = sfr_gwsw.sum(axis=-1).sum(axis=-1)\n", - " finf_tot_ts = finf_tot.sum(axis=-1).sum(axis=-1)\n", - " uzrech_ts = uzrech.sum(axis=-1).sum(axis=-1)\n", - " rejinf_ts = rejinf.sum(axis=-1).sum(axis=-1)\n", - " uzet_ts = uzet.sum(axis=-1).sum(axis=-1)\n", - " gwet_ts = gwet.sum(axis=-1).sum(axis=-1)\n", - "\n", - " rng = pd.date_range(start=\"11/1/1999\", end=\"10/31/2000\", freq=\"D\")\n", - " data = {\n", - " \"Recharge\": abs(uzrech_ts[0:366]),\n", - " \"Infiltration\": abs(finf_tot_ts[0:366]),\n", - " \"GroundwaterET\": abs(gwet_ts[0:366]),\n", - " \"UnsaturatedZoneET\": abs(uzet_ts[0:366]),\n", - " }\n", - " vals1 = pd.DataFrame(data, index=rng)\n", - "\n", - " fig = plt.figure(figsize=figure_size_ts, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1)\n", - " vals1.Infiltration.plot(style=\"k-\", linewidth=0.3)\n", - " vals1.Recharge.plot(style=\"b-\", linewidth=0.7)\n", - " vals1.GroundwaterET.plot(\n", - " style=\"-\", color=\"darkgreen\", linewidth=0.7, label=\"Groundwater ET\"\n", - " )\n", - " vals1.UnsaturatedZoneET.plot(\n", - " style=\"-\", color=\"orange\", linewidth=1, label=\"Unsaturated Zone ET\"\n", - " )\n", - " ax.set_ylim(0, 700000)\n", - " plt.tick_params(\n", - " axis=\"x\", # changes apply to the x-axis\n", - " which=\"both\", # both major and minor ticks are affected\n", - " bottom=False, # ticks along the bottom edge are off\n", - " top=False, # ticks along the top edge are off\n", - " labelbottom=True,\n", - " ) # labels along the bottom edge are off\n", - " ax.set_xlabel(\"Month\")\n", - " ax.set_ylabel(\"Volumetric Rate, $m^3$ per day\")\n", - " fs.graph_legend(ax)\n", - " title = \"Unsaturated Zone Flow Budget\"\n", - " fs.heading(heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(sim_name + \"-uzFlow\", config.figure_ext),\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " data_sfr = {\n", - " \"GroundwaterDischarge\": abs(drn_disQ_ts[0:366]),\n", - " \"RejectedInfiltration\": abs(rejinf_ts[0:366]),\n", - " \"gwswExchange\": abs(sfr_gwsw_ts[0:366]),\n", - " \"outflow\": outflow[0:366],\n", - " }\n", - " vals2 = pd.DataFrame(data_sfr, index=rng)\n", - "\n", - " fig = plt.figure(figsize=figure_size_ts, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1)\n", - " vals2.outflow.plot(\n", - " style=\"-\",\n", - " linewidth=0.5,\n", - " color=\"royalblue\",\n", - " label=\"Streamflow at Outlet\",\n", - " )\n", - " vals2.GroundwaterDischarge.plot(\n", - " style=\"k-\", linewidth=0.7, label=\"Groundwater Discharge\"\n", - " )\n", - " vals2.RejectedInfiltration.plot(\n", - " style=\"-\",\n", - " linewidth=0.7,\n", - " color=\"brown\",\n", - " label=\"Rejected Infiltration\",\n", - " )\n", - " vals2.gwswExchange.plot(\n", - " style=\"-\",\n", - " color=\"darkgreen\",\n", - " linewidth=0.7,\n", - " label=\"GW Discharge to Streams\",\n", - " )\n", - " ax.set_ylim(0, 350000)\n", - " plt.tick_params(\n", - " axis=\"x\", # changes apply to the x-axis\n", - " which=\"both\", # both major and minor ticks are affected\n", - " bottom=False, # ticks along the bottom edge are off\n", - " top=False, # ticks along the top edge are off\n", - " labelbottom=True,\n", - " ) # labels along the bottom edge are off\n", - " ax.set_xlabel(\"Month\")\n", - " ax.set_ylabel(\"Volumetric Rate, $m^3$ per day\")\n", - " fs.graph_legend(ax)\n", - " title = \"Surface Water Flow\"\n", - " fs.heading(heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(sim_name + \"-swFlow\", config.figure_ext),\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "af27c925", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e3873c86", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sim = build_model(example_name)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "24c15294", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "0f15b0ed", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7233cf92", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Sagehen Model Results\n", - " #\n", - " # Two-dimensional transport in a uniform flow field\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-sfr-p01.ipynb b/notebooks/ex-gwf-sfr-p01.ipynb deleted file mode 100644 index 70352418..00000000 --- a/notebooks/ex-gwf-sfr-p01.ipynb +++ /dev/null @@ -1,1769 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "435525af", - "metadata": {}, - "source": [ - "## Streamflow Routing (SFR) Package problem 1\n", - "\n", - "This is the stream-aquifer interaction example problem (test 1) from the\n", - "Streamflow Routing Package documentation (Prudic, 1989). All reaches have\n", - "been converted to rectangular reaches.\n" - ] - }, - { - "cell_type": "markdown", - "id": "c874447b", - "metadata": {}, - "source": [ - "### SFR Package Problem 1 Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3624e016", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "21a28925", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "dc43ac23", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "398c2067", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "f2c14b1b", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "24372933", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "5e2aaece", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0785d47c", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.3, 5.6)\n", - "masked_values = (0, 1e30, -1e30)" - ] - }, - { - "cell_type": "markdown", - "id": "af8769fe", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e329c1f3", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "3480f152", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b2551c38", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-sfr-p01\"" - ] - }, - { - "cell_type": "markdown", - "id": "7057e859", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "204b4b3e", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "5b04b2ea", - "metadata": {}, - "source": [ - "Table SFR Package Problem 1 Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "83abc3b6", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 3 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 15 # Number of rows\n", - "ncol = 10 # Number of columns\n", - "delr = 5000.0 # Column width ($ft$)\n", - "delc = 5000.0 # Row width ($ft$)\n", - "strt = 1050.0 # Starting head ($ft$)\n", - "k11_stream = 0.002 # Hydraulic conductivity near the stream ($ft/s$)\n", - "k11_basin = 0.0004 # Hydraulic conductivity in the basin ($ft/s$)\n", - "ss = 1e-6 # Specific storage ($1/s)$\n", - "sy_stream = 0.2 # Specific yield near the stream (unitless)\n", - "sy_basin = 0.1 # Specific yield in the basin (unitless)\n", - "evap_rate = 9.5e-8 # Evapotranspiration rate ($ft/s$)\n", - "ext_depth = 15.0 # Evapotranspiration extinction depth ($ft$)" - ] - }, - { - "cell_type": "markdown", - "id": "f27d51d5", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e925a461", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = (\n", - " (0.0, 1, 1.0),\n", - " (1.577880e9, 50, 1.1),\n", - " (1.577880e9, 50, 1.1),\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4ff6eb51", - "metadata": {}, - "outputs": [], - "source": [ - "# Define dimensions\n", - "extents = (0.0, delr * ncol, 0.0, delc * nrow)\n", - "shape2d = (nrow, ncol)\n", - "shape3d = (nlay, nrow, ncol)" - ] - }, - { - "cell_type": "markdown", - "id": "8815eb23", - "metadata": {}, - "source": [ - "Load the idomain, top, bottom, and evapotranspiration surface arrays" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "32fee67a", - "metadata": {}, - "outputs": [], - "source": [ - "data_pth = os.path.join(\"..\", \"data\", sim_name)\n", - "fpth = os.path.join(data_pth, \"idomain.txt\")\n", - "idomain = np.loadtxt(fpth, dtype=int)\n", - "fpth = os.path.join(data_pth, \"top.txt\")\n", - "top = np.loadtxt(fpth, dtype=float)\n", - "fpth = os.path.join(data_pth, \"bottom.txt\")\n", - "botm = np.loadtxt(fpth, dtype=float)\n", - "fpth = os.path.join(data_pth, \"recharge.txt\")\n", - "recharge = np.loadtxt(fpth, dtype=float)\n", - "fpth = os.path.join(data_pth, \"surf.txt\")\n", - "surf = np.loadtxt(fpth, dtype=float)" - ] - }, - { - "cell_type": "markdown", - "id": "9e12ee88", - "metadata": {}, - "source": [ - "Create hydraulic conductivity and specific yield" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c62e791b", - "metadata": {}, - "outputs": [], - "source": [ - "k11 = np.zeros(shape2d, dtype=float)\n", - "k11[idomain == 1] = k11_stream\n", - "k11[idomain == 2] = k11_basin\n", - "sy = np.zeros(shape2d, dtype=float)\n", - "sy[idomain == 1] = sy_stream\n", - "sy[idomain == 2] = sy_basin" - ] - }, - { - "cell_type": "markdown", - "id": "7c30a5a4", - "metadata": {}, - "source": [ - "### Create SFR Package Problem 1 Model Boundary Conditions\n", - "\n", - "General head boundary conditions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "57b3320a", - "metadata": {}, - "outputs": [], - "source": [ - "ghb_spd = [\n", - " [0, 12, 0, 988.0, 0.038],\n", - " [0, 13, 8, 1045.0, 0.038],\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "e6f30845", - "metadata": {}, - "source": [ - "Well boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eb8b1876", - "metadata": {}, - "outputs": [], - "source": [ - "wel_spd = {\n", - " 1: [\n", - " [0, 5, 3, -10.0],\n", - " [0, 5, 4, -10.0],\n", - " [0, 6, 3, -10.0],\n", - " [0, 6, 4, -10.0],\n", - " [0, 7, 3, -10.0],\n", - " [0, 7, 4, -10.0],\n", - " [0, 8, 3, -10.0],\n", - " [0, 8, 4, -10.0],\n", - " [0, 9, 3, -10.0],\n", - " [0, 9, 4, -10.0],\n", - " ],\n", - " 2: [\n", - " [],\n", - " ],\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "46cff455", - "metadata": {}, - "source": [ - "SFR Package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "49d74927", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_pakdata = [\n", - " [\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 4500.0,\n", - " 12,\n", - " 8.6767896e-04,\n", - " 1093.048,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 1,\n", - " 0,\n", - " 1,\n", - " 1,\n", - " 7000.0,\n", - " 12,\n", - " 8.6767896e-04,\n", - " 1088.059,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 2,\n", - " 0,\n", - " 2,\n", - " 2,\n", - " 6000.0,\n", - " 12,\n", - " 8.6767896e-04,\n", - " 1082.419,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 3,\n", - " 0,\n", - " 2,\n", - " 3,\n", - " 5550.0,\n", - " 12,\n", - " 8.6767896e-04,\n", - " 1077.408,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 3,\n", - " 1.0,\n", - " 1,\n", - " ],\n", - " [\n", - " 4,\n", - " 0,\n", - " 3,\n", - " 4,\n", - " 6500.0,\n", - " 12,\n", - " 9.4339624e-04,\n", - " 1071.934,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 5,\n", - " 0,\n", - " 4,\n", - " 5,\n", - " 5000.0,\n", - " 12,\n", - " 9.4339624e-04,\n", - " 1066.509,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 6,\n", - " 0,\n", - " 5,\n", - " 5,\n", - " 5000.0,\n", - " 12,\n", - " 9.4339624e-04,\n", - " 1061.792,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 7,\n", - " 0,\n", - " 6,\n", - " 5,\n", - " 5000.0,\n", - " 12,\n", - " 9.4339624e-04,\n", - " 1057.075,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 8,\n", - " 0,\n", - " 7,\n", - " 5,\n", - " 5000.0,\n", - " 12,\n", - " 9.4339624e-04,\n", - " 1052.359,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 9,\n", - " 0,\n", - " 2,\n", - " 4,\n", - " 5000.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1073.636,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 0.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 10,\n", - " 0,\n", - " 2,\n", - " 5,\n", - " 5000.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1070.909,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 11,\n", - " 0,\n", - " 2,\n", - " 6,\n", - " 4500.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1068.318,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 12,\n", - " 0,\n", - " 3,\n", - " 7,\n", - " 6000.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1065.455,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 13,\n", - " 0,\n", - " 4,\n", - " 7,\n", - " 5000.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1062.455,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 14,\n", - " 0,\n", - " 5,\n", - " 7,\n", - " 2000.0,\n", - " 10,\n", - " 5.4545456e-04,\n", - " 1060.545,\n", - " 2.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 15,\n", - " 0,\n", - " 4,\n", - " 9,\n", - " 2500.0,\n", - " 10,\n", - " 1.8181818e-03,\n", - " 1077.727,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 16,\n", - " 0,\n", - " 4,\n", - " 8,\n", - " 5000.0,\n", - " 10,\n", - " 1.8181818e-03,\n", - " 1070.909,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 17,\n", - " 0,\n", - " 5,\n", - " 7,\n", - " 3500.0,\n", - " 10,\n", - " 1.8181818e-03,\n", - " 1063.182,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 18,\n", - " 0,\n", - " 5,\n", - " 7,\n", - " 4000.0,\n", - " 15,\n", - " 1.0000000e-03,\n", - " 1058.000,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 3,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 19,\n", - " 0,\n", - " 6,\n", - " 6,\n", - " 5000.0,\n", - " 15,\n", - " 1.0000000e-03,\n", - " 1053.500,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 20,\n", - " 0,\n", - " 7,\n", - " 6,\n", - " 3500.0,\n", - " 15,\n", - " 1.0000000e-03,\n", - " 1049.250,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 21,\n", - " 0,\n", - " 7,\n", - " 5,\n", - " 2500.0,\n", - " 15,\n", - " 1.0000000e-03,\n", - " 1046.250,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 22,\n", - " 0,\n", - " 8,\n", - " 5,\n", - " 5000.0,\n", - " 12,\n", - " 9.0909092e-04,\n", - " 1042.727,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 3,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 23,\n", - " 0,\n", - " 9,\n", - " 6,\n", - " 5000.0,\n", - " 12,\n", - " 9.0909092e-04,\n", - " 1038.182,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 24,\n", - " 0,\n", - " 10,\n", - " 6,\n", - " 5000.0,\n", - " 12,\n", - " 9.0909092e-04,\n", - " 1033.636,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 25,\n", - " 0,\n", - " 11,\n", - " 6,\n", - " 5000.0,\n", - " 12,\n", - " 9.0909092e-04,\n", - " 1029.091,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 26,\n", - " 0,\n", - " 12,\n", - " 6,\n", - " 2000.0,\n", - " 12,\n", - " 9.0909092e-04,\n", - " 1025.909,\n", - " 3.0,\n", - " 0.00003,\n", - " 0.030,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 27,\n", - " 0,\n", - " 13,\n", - " 8,\n", - " 5000.0,\n", - " 55,\n", - " 9.6774194e-04,\n", - " 1037.581,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 28,\n", - " 0,\n", - " 12,\n", - " 7,\n", - " 5500.0,\n", - " 55,\n", - " 9.6774194e-04,\n", - " 1032.500,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 29,\n", - " 0,\n", - " 12,\n", - " 6,\n", - " 5000.0,\n", - " 55,\n", - " 9.6774194e-04,\n", - " 1027.419,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 30,\n", - " 0,\n", - " 12,\n", - " 5,\n", - " 5000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 1021.875,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 3,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 31,\n", - " 0,\n", - " 12,\n", - " 4,\n", - " 5000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 1015.625,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 32,\n", - " 0,\n", - " 12,\n", - " 3,\n", - " 5000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 1009.375,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 33,\n", - " 0,\n", - " 12,\n", - " 2,\n", - " 5000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 1003.125,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 34,\n", - " 0,\n", - " 12,\n", - " 1,\n", - " 5000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 996.8750,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - " [\n", - " 35,\n", - " 0,\n", - " 12,\n", - " 0,\n", - " 3000.0,\n", - " 40,\n", - " 1.2500000e-03,\n", - " 991.8750,\n", - " 3.0,\n", - " 0.00006,\n", - " 0.025,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " ],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fe4ba175", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_conn = [\n", - " [0, -1],\n", - " [1, 0, -2],\n", - " [2, 1, -3],\n", - " [3, 2, -4, -9],\n", - " [4, 3, -5],\n", - " [5, 4, -6],\n", - " [6, 5, -7],\n", - " [7, 6, -8],\n", - " [8, 7, -22],\n", - " [9, 3, -10],\n", - " [10, 9, -11],\n", - " [11, 10, -12],\n", - " [12, 11, -13],\n", - " [13, 12, -14],\n", - " [14, 13, -18],\n", - " [15, -16],\n", - " [16, 15, -17],\n", - " [17, 16, -18],\n", - " [18, 14, 17, -19],\n", - " [19, 18, -20],\n", - " [20, 19, -21],\n", - " [21, 20, -22],\n", - " [22, 8, 21, -23],\n", - " [23, 22, -24],\n", - " [24, 23, -25],\n", - " [25, 24, -26],\n", - " [26, 25, -30],\n", - " [27, -28],\n", - " [28, 27, -29],\n", - " [29, 28, -30],\n", - " [30, 26, 29, -31],\n", - " [31, 30, -32],\n", - " [32, 31, -33],\n", - " [33, 32, -34],\n", - " [34, 33, -35],\n", - " [35, 34],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "91986955", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_div = [[3, 0, 9, \"UPTO\"]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0225083d", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_spd = [\n", - " [0, \"inflow\", 25.0],\n", - " [15, \"inflow\", 10.0],\n", - " [27, \"inflow\", 150.0],\n", - " [3, \"diversion\", 0, 10.0],\n", - " [9, \"status\", \"simple\"],\n", - " [10, \"status\", \"simple\"],\n", - " [11, \"status\", \"simple\"],\n", - " [12, \"status\", \"simple\"],\n", - " [13, \"status\", \"simple\"],\n", - " [14, \"status\", \"simple\"],\n", - " [9, \"stage\", 1075.545],\n", - " [10, \"stage\", 1072.636],\n", - " [11, \"stage\", 1069.873],\n", - " [12, \"stage\", 1066.819],\n", - " [13, \"stage\", 1063.619],\n", - " [14, \"stage\", 1061.581],\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "4d9732ee", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "556201d2", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 100\n", - "ninner = 50\n", - "hclose = 1e-6\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "29fb2264", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 SFR Package Problem 1 model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4cf0ceaf", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " linear_acceleration=\"bicgstab\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim, modelname=sim_name, newtonoptions=\"newton\", save_flows=True\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " idomain=idomain,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=1,\n", - " k=k11,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=1,\n", - " sy=sy,\n", - " ss=ss,\n", - " steady_state={0: True},\n", - " transient={1: True},\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfghb(gwf, stress_period_data=ghb_spd)\n", - " flopy.mf6.ModflowGwfwel(gwf, stress_period_data=wel_spd)\n", - " flopy.mf6.ModflowGwfrcha(gwf, recharge=recharge)\n", - " flopy.mf6.ModflowGwfevta(gwf, surface=surf, rate=evap_rate, depth=ext_depth)\n", - " sfr = flopy.mf6.ModflowGwfsfr(\n", - " gwf,\n", - " length_conversion=3.28081,\n", - " nreaches=len(sfr_pakdata),\n", - " packagedata=sfr_pakdata,\n", - " connectiondata=sfr_conn,\n", - " diversions=sfr_div,\n", - " perioddata=sfr_spd,\n", - " )\n", - " obs_file = f\"{sim_name}.sfr.obs\"\n", - " csv_file = obs_file + \".csv\"\n", - " obs_dict = {\n", - " csv_file: [\n", - " (\"r01_stage\", \"stage\", (3,)),\n", - " (\"r02_stage\", \"stage\", (14,)),\n", - " (\"r03_stage\", \"stage\", (26,)),\n", - " (\"r04_stage\", \"stage\", (35,)),\n", - " (\"r01_flow\", \"downstream-flow\", (3,)),\n", - " (\"r02_flow\", \"downstream-flow\", (14,)),\n", - " (\"r03_flow\", \"downstream-flow\", (26,)),\n", - " (\"r04_flow\", \"downstream-flow\", (35,)),\n", - " ]\n", - " }\n", - " sfr.obs.initialize(\n", - " filename=obs_file, digits=10, print_input=True, continuous=obs_dict\n", - " )\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "cf01699e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 SFR Package Problem 1 model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1f69533a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "c0c82f61", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the SFR Package Problem 1 model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f1065336", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "70e07aa1", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2f109498", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(gwf, silent=True):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " fig = plt.figure(figsize=figure_size, constrained_layout=False)\n", - " gs = mpl.gridspec.GridSpec(ncols=10, nrows=7, figure=fig, wspace=5)\n", - " plt.axis(\"off\")\n", - "\n", - " axes = []\n", - " axes.append(fig.add_subplot(gs[:6, :5]))\n", - " axes.append(fig.add_subplot(gs[:6, 5:], sharey=axes[0]))\n", - "\n", - " for ax in axes:\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - " ax.set_aspect(\"equal\")\n", - " # ax.set_xticks(ticklabels)\n", - " # ax.set_yticks(ticklabels)\n", - "\n", - " # legend axis\n", - " axes.append(fig.add_subplot(gs[6:, :]))\n", - "\n", - " # set limits for legend area\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " top_coll = mm.plot_array(\n", - " top, vmin=1000, vmax=1120, masked_values=masked_values, alpha=0.5\n", - " )\n", - " mm.plot_bc(\"SFR\", color=\"green\")\n", - " cv = mm.contour_array(\n", - " top,\n", - " levels=np.arange(1000, 1100, 20),\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=\"black\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " mm.plot_inactive(color_noflow=\"0.5\")\n", - " mm.plot_grid(lw=0.5, color=\"black\")\n", - " cbar = plt.colorbar(\n", - " top_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " ax=ax,\n", - " format=\"%.0f\",\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Land surface elevation, $ft$\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " ax.set_ylabel(\"y-coordinate, in feet\")\n", - " fs.heading(ax, heading=\"Land surface elevation\", idx=0)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " ax = axes[1]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " bot_coll = mm.plot_array(\n", - " botm, vmin=500, vmax=1000, masked_values=masked_values, alpha=0.5\n", - " )\n", - " mm.plot_bc(\"GHB\", color=\"purple\")\n", - " mm.plot_bc(\"WEL\", color=\"red\", kper=1)\n", - " cv = mm.contour_array(\n", - " botm,\n", - " levels=np.arange(600, 1000, 100),\n", - " linewidths=0.5,\n", - " linestyles=\":\",\n", - " colors=\"black\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " mm.plot_inactive(color_noflow=\"0.5\")\n", - " mm.plot_grid(lw=0.5, color=\"black\")\n", - " cbar = plt.colorbar(\n", - " bot_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " ax=ax,\n", - " format=\"%.0f\",\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Bottom elevation, $ft$\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " fs.heading(ax, heading=\"Bottom elevation\", idx=1)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"0.5\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Inactive cells\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"green\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Stream boundary\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"purple\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"General head boundary\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"red\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Well boundary\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " ls=\"-\",\n", - " color=\"black\",\n", - " label=r\"Land surface elevation contour, $ft$\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " ls=\":\",\n", - " color=\"black\",\n", - " label=r\"Bottom elevation contour, $ft$\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"center\", ncol=3)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "d852f748", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9114b448", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_head_results(gwf, silent=True):\n", - " sim_ws = os.path.join(ws, sim_name)\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj = gwf.output.head()\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " cobj = gwf.output.budget()\n", - "\n", - " kstpkper = hobj.get_kstpkper()\n", - "\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " fig = plt.figure(figsize=figure_size, constrained_layout=False)\n", - " gs = mpl.gridspec.GridSpec(ncols=10, nrows=7, figure=fig, wspace=5)\n", - " plt.axis(\"off\")\n", - "\n", - " axes = [fig.add_subplot(gs[:6, :5])]\n", - " axes.append(fig.add_subplot(gs[:6, 5:], sharey=axes[0]))\n", - "\n", - " for ax in axes:\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - " ax.set_aspect(\"equal\")\n", - "\n", - " # legend axis\n", - " axes.append(fig.add_subplot(gs[6:, :]))\n", - "\n", - " # set limits for legend area\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " # extract heads and specific discharge for first stress period\n", - " head = hobj.get_data(kstpkper=kstpkper[0])\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " cobj.get_data(text=\"DATA-SPDIS\", kstpkper=kstpkper[0])[0],\n", - " gwf,\n", - " )\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " head_coll = mm.plot_array(head, vmin=900, vmax=1120, masked_values=masked_values)\n", - " cv = mm.contour_array(\n", - " head,\n", - " levels=np.arange(900, 1100, 10),\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=\"black\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " mm.plot_vector(qx, qy, normalize=True, color=\"0.75\")\n", - " mm.plot_inactive(color_noflow=\"0.5\")\n", - " mm.plot_grid(lw=0.5, color=\"black\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " ax.set_ylabel(\"y-coordinate, in feet\")\n", - " fs.heading(ax, heading=\"Steady-state\", idx=0)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # extract heads and specific discharge for second stress period\n", - " head = hobj.get_data(kstpkper=kstpkper[1])\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " cobj.get_data(text=\"DATA-SPDIS\", kstpkper=kstpkper[1])[0],\n", - " gwf,\n", - " )\n", - "\n", - " ax = axes[1]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " head_coll = mm.plot_array(head, vmin=900, vmax=1120, masked_values=masked_values)\n", - " cv = mm.contour_array(\n", - " head,\n", - " levels=np.arange(900, 1100, 10),\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=\"black\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " mm.plot_vector(qx, qy, normalize=True, color=\"0.75\")\n", - " mm.plot_inactive(color_noflow=\"0.5\")\n", - " mm.plot_grid(lw=0.5, color=\"black\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " fs.heading(ax, heading=\"Pumping\", idx=1)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " cbar = plt.colorbar(\n", - " head_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " ax=ax,\n", - " format=\"%.0f\",\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Head, $ft$\")\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"$\\u2192$\",\n", - " ms=10,\n", - " mfc=\"0.75\",\n", - " mec=\"0.75\",\n", - " label=\"Normalized specific discharge\",\n", - " )\n", - " ax.plot(-10000, -10000, lw=0.5, color=\"black\", label=r\"Head contour, $ft$\")\n", - " fs.graph_legend(ax, loc=\"upper center\", ncol=2)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-01{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "514d6a6f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the sfr results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "26cb06d3", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_sfr_results(gwf, silent=True):\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " # load the observations\n", - " results = gwf.sfr.output.obs().data\n", - "\n", - " # modify the time\n", - " results[\"totim\"] /= 365.25 * 86400.0\n", - "\n", - " rnos = (\n", - " 3,\n", - " 14,\n", - " 26,\n", - " 35,\n", - " )\n", - " sfr = gwf.sfr.packagedata.array[\"rtp\"]\n", - " offsets = []\n", - " for rno in rnos:\n", - " offsets.append(sfr[rno])\n", - "\n", - " # create the figure\n", - " fig, axes = plt.subplots(\n", - " ncols=2,\n", - " nrows=4,\n", - " sharex=True,\n", - " figsize=(6.3, 6.3),\n", - " constrained_layout=True,\n", - " )\n", - " ipos = 0\n", - " for i in range(4):\n", - " heading = f\"Reach {rnos[i] + 1}\"\n", - " for j in range(2):\n", - " ax = axes[i, j]\n", - " ax.set_xlim(0, 100)\n", - " if j == 0:\n", - " tag = f\"R{i + 1:02d}_STAGE\"\n", - " offset = offsets[i]\n", - " scale = 1.0\n", - " ylabel = \"Reach depth, in feet\"\n", - " color = \"blue\"\n", - " else:\n", - " tag = f\"R{i + 1:02d}_FLOW\"\n", - " offset = 0.0\n", - " scale = -1.0\n", - " ylabel = \"Downstream reach flow,\\nin cubic feet per second\"\n", - " color = \"red\"\n", - "\n", - " ax.plot(\n", - " results[\"totim\"],\n", - " scale * results[tag] - offset,\n", - " lw=0.5,\n", - " color=color,\n", - " zorder=10,\n", - " )\n", - " ax.axvline(50, lw=0.5, ls=\"--\", color=\"black\", zorder=10)\n", - " if ax.get_ylim()[0] < 0.0:\n", - " ax.axhline(0, lw=0.5, color=\"0.5\", zorder=9)\n", - " fs.add_text(\n", - " ax,\n", - " text=\"Pumping\",\n", - " x=0.49,\n", - " y=0.8,\n", - " ha=\"right\",\n", - " bold=False,\n", - " fontsize=7,\n", - " )\n", - " fs.add_text(\n", - " ax,\n", - " text=\"Recovery\",\n", - " x=0.51,\n", - " y=0.8,\n", - " ha=\"left\",\n", - " bold=False,\n", - " fontsize=7,\n", - " )\n", - " ax.set_ylabel(ylabel)\n", - " ax.yaxis.set_label_coords(-0.1, 0.5)\n", - " fs.heading(ax, heading=heading, idx=ipos)\n", - " if i == 3:\n", - " ax.set_xlabel(\"Time since pumping began, in years\")\n", - " ipos += 1\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-02{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "26453693", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the SFR Package Problem 1 model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "af06383c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " plot_grid(gwf, silent=silent)\n", - "\n", - " plot_sfr_results(gwf, silent=silent)\n", - "\n", - " plot_head_results(gwf, silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "ce75acbb", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the SFR Package Problem 1 model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "38c95801", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " sim = build_model()\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, f\"could not run...{sim_name}\"\n", - "\n", - " if success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "af4d2533", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "1bee925d", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e1407dff", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### SFR Package Problem 1 Simulation\n", - " #\n", - " # Simulated heads in model the unconfined, middle, and lower aquifers (model layers\n", - " # 1, 3, and 5) are shown in the figure below. MODFLOW-2005 results for a quasi-3D\n", - " # model are also shown. The location of drain (green) and well (gray) boundary\n", - " # conditions, normalized specific discharge, and head contours (25 ft contour\n", - " # intervals) are also shown.\n", - "\n", - " simulation()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-sfr-p01b.ipynb b/notebooks/ex-gwf-sfr-p01b.ipynb deleted file mode 100644 index c92ecadd..00000000 --- a/notebooks/ex-gwf-sfr-p01b.ipynb +++ /dev/null @@ -1,5120 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a7ea5799", - "metadata": {}, - "source": [ - "## Streamflow Routing (SFR) Package problem 1 with MVR applied among advanced packages\n", - "\n", - "This is the stream-aquifer interaction example problem (test 1) from the\n", - "Streamflow Routing Package documentation (Prudic, 1989) with a couple of\n", - "modifications for demonstrating MVR connections among the advanced packages.\n", - "All reaches have been converted to rectangular reaches.\n" - ] - }, - { - "cell_type": "markdown", - "id": "3becf664", - "metadata": {}, - "source": [ - "### SFR Package Problem 1 with MVR Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4e8a3390", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "99a101db", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import flopy.utils.binaryfile as bf\n", - "import matplotlib as mpl\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "id": "280c21eb", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ab838b3a", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "09ef2cda", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9a41b40b", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "a221bd6d", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7ee90740", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.3, 5.6)\n", - "masked_values = (0, 1e30, -1e30)" - ] - }, - { - "cell_type": "markdown", - "id": "c461d237", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "82c4f99c", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "e6ab60ea", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c484af58", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-sfr-p01b\"" - ] - }, - { - "cell_type": "markdown", - "id": "67783265", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "636343d9", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "c8e1c54d", - "metadata": {}, - "source": [ - "Table SFR Package Problem 1 with MVR Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c5c0bf8c", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 24 # Number of periods\n", - "nlay = 2 # Number of layers\n", - "nrow = 15 # Number of rows\n", - "ncol = 10 # Number of columns\n", - "delr = 5000.0 # Column width ($ft$)\n", - "delc = 5000.0 # Row width ($ft$)\n", - "strt = \"varies\" # Starting head ($ft$)\n", - "k11_stream = 0.002 # Hydraulic conductivity near the stream ($ft/s$)\n", - "k11_basin = \"varies\" # Hydraulic conductivity in the basin ($ft/s$)\n", - "lake_leakance = 2e-9 # Lakebed leakance ($1/s$)\n", - "ss = 0.1e-5 # Specific storage ($1/s$)\n", - "sy_stream = 0.2 # Specific yield near the stream (unitless)\n", - "sy_basin = 0.1 # Specific yield in the basin (unitless)\n", - "evap_rate = 9.5e-8 # Evapotranspiration rate ($ft/s$)\n", - "ext_depth = 15.0 # Evapotranspiration extinction depth ($ft$)" - ] - }, - { - "cell_type": "markdown", - "id": "fcb8be5c", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cee36871", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = (\n", - " (2628000.0, 1, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - " (2628000.0, 15, 1.0),\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a40b8851", - "metadata": {}, - "outputs": [], - "source": [ - "# Define dimensions\n", - "extents = (0.0, delr * ncol, 0.0, delc * nrow)\n", - "shape2d = (nrow, ncol)\n", - "shape3d = (nlay, nrow, ncol)" - ] - }, - { - "cell_type": "markdown", - "id": "133e623e", - "metadata": {}, - "source": [ - "Load the idomain, lake locations, top, bottom, and evapotranspiration surface arrays" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "19d55862", - "metadata": {}, - "outputs": [], - "source": [ - "data_pth = os.path.join(\"..\", \"data\", sim_name)\n", - "fpth = os.path.join(data_pth, \"strt1.txt\")\n", - "strt1 = np.loadtxt(fpth, dtype=float)\n", - "strt2 = strt1\n", - "strt = [strt1, strt2]\n", - "fpth = os.path.join(data_pth, \"idomain.txt\")\n", - "idomain1 = np.loadtxt(fpth, dtype=int)\n", - "idomain = [idomain1, idomain1]\n", - "lake_map = np.ones(shape3d, dtype=int) * -1\n", - "fpth = os.path.join(data_pth, \"lakes.txt\")\n", - "lake_map[0, :, :] = np.loadtxt(fpth, dtype=int) - 1\n", - "lake_map = np.ma.masked_where(lake_map < 0, lake_map)\n", - "fpth = os.path.join(data_pth, \"top1.txt\")\n", - "top = np.loadtxt(fpth, dtype=float)\n", - "fpth = os.path.join(data_pth, \"bot1.txt\")\n", - "bot1 = np.loadtxt(fpth, dtype=float)\n", - "bot2 = np.ones_like(bot1) * 300.0\n", - "botm = [bot1, bot2]" - ] - }, - { - "cell_type": "markdown", - "id": "47cc7c0d", - "metadata": {}, - "source": [ - "Create hydraulic conductivity and specific yield" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6b96de25", - "metadata": {}, - "outputs": [], - "source": [ - "fpth = os.path.join(data_pth, \"k11_lay1.txt\")\n", - "k11_lay1 = np.loadtxt(fpth, dtype=float) * 2.5\n", - "k11_lay2 = np.ones_like(k11_lay1) * 0.35e-2\n", - "k11 = [k11_lay1, k11_lay2]\n", - "k33 = 0.5e-5\n", - "fpth = os.path.join(data_pth, \"sy1.txt\")\n", - "sy1 = np.loadtxt(fpth, dtype=float)\n", - "sy2 = np.ones_like(sy1) * 0.20\n", - "sy = [sy1, sy2]" - ] - }, - { - "cell_type": "markdown", - "id": "702de126", - "metadata": {}, - "source": [ - "### Create SFR Package Problem 1 Model Boundary Conditions\n", - "\n", - "General head boundary conditions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "65e4ae6e", - "metadata": {}, - "outputs": [], - "source": [ - "ghb_spd = [\n", - " [0, 12, 0, 988.0, 0.038],\n", - " [0, 13, 8, 1045.0, 0.038],\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "d6381bf7", - "metadata": {}, - "source": [ - "Well boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2341641b", - "metadata": {}, - "outputs": [], - "source": [ - "wel_spd = {\n", - " 0: [\n", - " [0, 5, 3, 0],\n", - " [0, 5, 4, 0],\n", - " [0, 6, 3, 0],\n", - " [0, 6, 4, 0],\n", - " [0, 7, 3, 0],\n", - " [0, 7, 4, 0],\n", - " [0, 8, 3, 0],\n", - " [0, 8, 4, 0],\n", - " [0, 9, 3, 0],\n", - " [0, 9, 4, 0],\n", - " ],\n", - " 2: [\n", - " [0, 5, 3, -0.85],\n", - " [0, 5, 4, -0.85],\n", - " [0, 6, 3, -0.85],\n", - " [0, 6, 4, -0.85],\n", - " [0, 7, 3, -0.85],\n", - " [0, 7, 4, -0.85],\n", - " [0, 8, 3, -0.85],\n", - " [0, 8, 4, -0.85],\n", - " [0, 9, 3, -0.85],\n", - " [0, 9, 4, -0.85],\n", - " ],\n", - " 4: [\n", - " [0, 5, 3, -1.7],\n", - " [0, 5, 4, -1.7],\n", - " [0, 6, 3, -1.7],\n", - " [0, 6, 4, -1.7],\n", - " [0, 7, 3, -1.7],\n", - " [0, 7, 4, -1.7],\n", - " [0, 8, 3, -1.7],\n", - " [0, 8, 4, -1.7],\n", - " [0, 9, 3, -1.7],\n", - " [0, 9, 4, -1.7],\n", - " ],\n", - " 5: [\n", - " [0, 5, 3, 0.00],\n", - " [0, 5, 4, 0.00],\n", - " [0, 6, 3, 0.00],\n", - " [0, 6, 4, 0.00],\n", - " [0, 7, 3, 0.00],\n", - " [0, 7, 4, 0.00],\n", - " [0, 8, 3, 0.00],\n", - " [0, 8, 4, 0.00],\n", - " [0, 9, 3, 0.00],\n", - " [0, 9, 4, 0.00],\n", - " ],\n", - " 6: [\n", - " [0, 5, 3, -0.85],\n", - " [0, 5, 4, -0.85],\n", - " [0, 6, 3, -0.85],\n", - " [0, 6, 4, -0.85],\n", - " [0, 7, 3, -0.85],\n", - " [0, 7, 4, -0.85],\n", - " [0, 8, 3, -0.85],\n", - " [0, 8, 4, -0.85],\n", - " [0, 9, 3, -0.85],\n", - " [0, 9, 4, -0.85],\n", - " ],\n", - " 7: [\n", - " [0, 5, 3, 0.00],\n", - " [0, 5, 4, 0.00],\n", - " [0, 6, 3, 0.00],\n", - " [0, 6, 4, 0.00],\n", - " [0, 7, 3, 0.00],\n", - " [0, 7, 4, 0.00],\n", - " [0, 8, 3, 0.00],\n", - " [0, 8, 4, 0.00],\n", - " [0, 9, 3, 0.00],\n", - " [0, 9, 4, 0.00],\n", - " ],\n", - " 8: [\n", - " [0, 5, 3, -0.85],\n", - " [0, 5, 4, -0.85],\n", - " [0, 6, 3, -0.85],\n", - " [0, 6, 4, -0.85],\n", - " [0, 7, 3, -0.85],\n", - " [0, 7, 4, -0.85],\n", - " [0, 8, 3, -0.85],\n", - " [0, 8, 4, -0.85],\n", - " [0, 9, 3, -0.85],\n", - " [0, 9, 4, -0.85],\n", - " ],\n", - " 9: [\n", - " [0, 5, 3, 0.00],\n", - " [0, 5, 4, 0.00],\n", - " [0, 6, 3, 0.00],\n", - " [0, 6, 4, 0.00],\n", - " [0, 7, 3, 0.00],\n", - " [0, 7, 4, 0.00],\n", - " [0, 8, 3, 0.00],\n", - " [0, 8, 4, 0.00],\n", - " [0, 9, 3, 0.00],\n", - " [0, 9, 4, 0.00],\n", - " ],\n", - " 10: [\n", - " [0, 5, 3, -2.55],\n", - " [0, 5, 4, -2.55],\n", - " [0, 6, 3, -2.55],\n", - " [0, 6, 4, -2.55],\n", - " [0, 7, 3, -2.55],\n", - " [0, 7, 4, -2.55],\n", - " [0, 8, 3, -2.55],\n", - " [0, 8, 4, -2.55],\n", - " [0, 9, 3, -2.55],\n", - " [0, 9, 4, -2.55],\n", - " ],\n", - " 11: [\n", - " [0, 5, 3, 0.00],\n", - " [0, 5, 4, 0.00],\n", - " [0, 6, 3, 0.00],\n", - " [0, 6, 4, 0.00],\n", - " [0, 7, 3, 0.00],\n", - " [0, 7, 4, 0.00],\n", - " [0, 8, 3, 0.00],\n", - " [0, 8, 4, 0.00],\n", - " [0, 9, 3, 0.00],\n", - " [0, 9, 4, 0.00],\n", - " ],\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "e77a1512", - "metadata": {}, - "source": [ - "SFR Package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "72e16707", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_pakdata = [\n", - " (\n", - " 0,\n", - " (0, 0, 0),\n", - " 4500.0,\n", - " 12.0,\n", - " 0.0008677,\n", - " 1093.048,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 1,\n", - " (0, 1, 1),\n", - " 7000.0,\n", - " 12.0,\n", - " 0.0008677,\n", - " 1088.059,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 2,\n", - " (0, 2, 2),\n", - " 6000.0,\n", - " 12.0,\n", - " 0.0008677,\n", - " 1082.419,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 3,\n", - " (0, 2, 3),\n", - " 5550.0,\n", - " 12.0,\n", - " 0.0008677,\n", - " 1077.408,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 3,\n", - " 1.0,\n", - " 1,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 4,\n", - " (0, 3, 4),\n", - " 6500.0,\n", - " 12.0,\n", - " 0.0009434,\n", - " 1071.934,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 5,\n", - " (0, 4, 5),\n", - " 5000.0,\n", - " 12.0,\n", - " 0.0009434,\n", - " 1066.509,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 6,\n", - " (0, 5, 5),\n", - " 5000.0,\n", - " 12.0,\n", - " 0.0009434,\n", - " 1061.792,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 7,\n", - " (0, 6, 5),\n", - " 5000.0,\n", - " 12.0,\n", - " 0.0009434,\n", - " 1057.075,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 8,\n", - " (0, 7, 5),\n", - " 5000.0,\n", - " 12.0,\n", - " 0.0009434,\n", - " 1052.359,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 9,\n", - " (0, 2, 4),\n", - " 5000.0,\n", - " 9.636364,\n", - " 0.0005455,\n", - " 1073.636,\n", - " 2,\n", - " 3.0e-07,\n", - " 0.03,\n", - " 2,\n", - " 0.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 10,\n", - " (0, 2, 5),\n", - " 5000.0,\n", - " 8.909091,\n", - " 0.0005455,\n", - " 1070.909,\n", - " 2,\n", - " 3.0e-07,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 11,\n", - " (0, 2, 6),\n", - " 4500.0,\n", - " 8.218182,\n", - " 0.0005455,\n", - " 1068.318,\n", - " 2,\n", - " 3.0e-07,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 12,\n", - " (0, 3, 7),\n", - " 6000.0,\n", - " 7.454545,\n", - " 0.0005455,\n", - " 1065.455,\n", - " 2,\n", - " 3.0e-07,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 13,\n", - " (0, 4, 7),\n", - " 5000.0,\n", - " 6.654546,\n", - " 0.0005455,\n", - " 1062.455,\n", - " 2,\n", - " 3.0e-07,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 14,\n", - " (0, 5, 7),\n", - " 2000.0,\n", - " 6.145454,\n", - " 0.0005455,\n", - " 1060.545,\n", - " 2,\n", - " 3.0e-07,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 15,\n", - " (0, 4, 9),\n", - " 2500.0,\n", - " 10.0,\n", - " 0.0018182,\n", - " 1077.727,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 16,\n", - " (0, 4, 8),\n", - " 5000.0,\n", - " 10.0,\n", - " 0.0018182,\n", - " 1070.909,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 17,\n", - " (0, 5, 7),\n", - " 3500.0,\n", - " 10.0,\n", - " 0.0018182,\n", - " 1063.182,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 18,\n", - " (0, 5, 7),\n", - " 4000.0,\n", - " 10.0,\n", - " 0.0006667,\n", - " 1058.667,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 3,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 19,\n", - " (0, 6, 6),\n", - " 5000.0,\n", - " 10.0,\n", - " 0.0006667,\n", - " 1055.667,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 20,\n", - " (0, 7, 6),\n", - " 3500.0,\n", - " 10.0,\n", - " 0.0006667,\n", - " 1052.833,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 21,\n", - " (0, 7, 5),\n", - " 2500.0,\n", - " 10.0,\n", - " 0.0006667,\n", - " 1050.833,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 22,\n", - " (0, 8, 5),\n", - " 5000.0,\n", - " 12.0,\n", - " 0.0018000,\n", - " 1045.500,\n", - " 3,\n", - " 3.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 23,\n", - " (0, 11, 6),\n", - " 5000.0,\n", - " 12.0,\n", - " 0.0014286,\n", - " 1036.429,\n", - " 3,\n", - " 3.0e-07,\n", - " 0.03,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 24,\n", - " (0, 12, 6),\n", - " 5500.0,\n", - " 12.0,\n", - " 0.0014286,\n", - " 1028.929,\n", - " 3,\n", - " 3.0e-07,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 25,\n", - " (0, 13, 8),\n", - " 5000.0,\n", - " 60.0,\n", - " 0.0006667,\n", - " 1033.333,\n", - " 3,\n", - " 6.0e-06,\n", - " 0.03,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 26,\n", - " (0, 12, 7),\n", - " 5000.0,\n", - " 60.0,\n", - " 0.0006667,\n", - " 1030.000,\n", - " 3,\n", - " 6.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 27,\n", - " (0, 12, 6),\n", - " 5000.0,\n", - " 60.0,\n", - " 0.0006667,\n", - " 1026.667,\n", - " 3,\n", - " 6.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 28,\n", - " (0, 12, 5),\n", - " 5000.0,\n", - " 60.0,\n", - " 0.0048000,\n", - " 1013.000,\n", - " 3,\n", - " 6.0e-06,\n", - " 0.03,\n", - " 2,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 29,\n", - " (0, 12, 1),\n", - " 5000.0,\n", - " 60.0,\n", - " 0.0012500,\n", - " 996.875,\n", - " 3,\n", - " 6.0e-06,\n", - " 0.03,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - " (\n", - " 30,\n", - " (0, 12, 0),\n", - " 3000.0,\n", - " 60.0,\n", - " 0.0012500,\n", - " 991.875,\n", - " 3,\n", - " 6.0e-06,\n", - " 0.03,\n", - " 1,\n", - " 1.0,\n", - " 0,\n", - " \"allreaches\",\n", - " ),\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c25ef086", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_conn = [\n", - " [0, -1],\n", - " [1, 0, -2],\n", - " [2, 1, -3],\n", - " [3, 2, -4, -9],\n", - " [4, 3, -5],\n", - " [5, 4, -6],\n", - " [6, 5, -7],\n", - " [7, 6, -8],\n", - " [8, 7, -22],\n", - " [9, 3, -10],\n", - " [10, 9, -11],\n", - " [11, 10, -12],\n", - " [12, 11, -13],\n", - " [13, 12, -14],\n", - " [14, 13, -18],\n", - " [15, -16],\n", - " [16, 15, -17],\n", - " [17, 16, -18],\n", - " [18, 14, 17, -19],\n", - " [19, 18, -20],\n", - " [20, 19, -21],\n", - " [21, 20, -22],\n", - " [22, 8, 21],\n", - " [23, -24],\n", - " [24, 23, -28],\n", - " [25, -26],\n", - " [26, 25, -27],\n", - " [27, 26, -28],\n", - " [28, 24, 27],\n", - " [29, -30],\n", - " [30, 29],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0f260d28", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_div = [[3, 0, 9, \"UPTO\"]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d73c227b", - "metadata": {}, - "outputs": [], - "source": [ - "sfr_spd = [\n", - " [0, \"inflow\", 25.0],\n", - " [3, \"diversion\", 0, 10.0],\n", - " [15, \"inflow\", 10.0],\n", - " [25, \"inflow\", 150.0],\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "75960bcd", - "metadata": {}, - "source": [ - "UZF Package" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e8fc6307", - "metadata": {}, - "outputs": [], - "source": [ - "uzf_pakdata = [\n", - " (0, (0, 0, 0), 1, 100, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (1, (0, 0, 1), 1, 101, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (2, (0, 1, 0), 1, 102, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (3, (0, 1, 1), 1, 103, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (4, (0, 1, 2), 1, 104, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (5, (0, 1, 5), 1, 105, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (6, (0, 1, 6), 1, 106, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (7, (0, 1, 7), 1, 107, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (8, (0, 2, 1), 1, 108, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (9, (0, 2, 2), 1, 109, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (10, (0, 2, 3), 1, 110, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (11, (0, 2, 4), 1, 111, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (12, (0, 2, 5), 1, 112, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (13, (0, 2, 6), 1, 113, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (14, (0, 2, 7), 1, 114, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (15, (0, 3, 0), 1, 115, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (16, (0, 3, 1), 1, 116, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (17, (0, 3, 2), 1, 117, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (18, (0, 3, 3), 1, 118, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (19, (0, 3, 4), 1, 119, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (20, (0, 3, 5), 1, 120, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (21, (0, 3, 6), 1, 121, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (22, (0, 3, 7), 1, 122, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (23, (0, 3, 8), 1, 123, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (24, (0, 4, 0), 1, 124, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (25, (0, 4, 1), 1, 125, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (26, (0, 4, 2), 1, 126, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (27, (0, 4, 3), 1, 127, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (28, (0, 4, 4), 1, 128, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (29, (0, 4, 5), 1, 129, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (30, (0, 4, 6), 1, 130, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (31, (0, 4, 7), 1, 131, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (32, (0, 4, 8), 1, 132, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (33, (0, 4, 9), 1, 133, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (34, (0, 5, 0), 1, 134, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (35, (0, 5, 1), 1, 135, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (36, (0, 5, 2), 1, 136, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (37, (0, 5, 3), 1, 137, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (38, (0, 5, 4), 1, 138, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (39, (0, 5, 5), 1, 139, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (40, (0, 5, 6), 1, 140, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (41, (0, 5, 7), 1, 141, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (42, (0, 5, 8), 1, 142, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (43, (0, 5, 9), 1, 143, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (44, (0, 6, 0), 1, 144, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (45, (0, 6, 1), 1, 145, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (46, (0, 6, 2), 1, 146, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (47, (0, 6, 3), 1, 147, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (48, (0, 6, 4), 1, 148, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (49, (0, 6, 5), 1, 149, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (50, (0, 6, 6), 1, 150, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (51, (0, 6, 7), 1, 151, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (52, (0, 6, 8), 1, 152, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (53, (0, 7, 1), 1, 153, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (54, (0, 7, 2), 1, 154, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (55, (0, 7, 3), 1, 155, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (56, (0, 7, 4), 1, 156, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (57, (0, 7, 5), 1, 157, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (58, (0, 7, 6), 1, 158, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (59, (0, 7, 7), 1, 159, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (60, (0, 7, 8), 1, 160, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (61, (0, 8, 1), 1, 161, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (62, (0, 8, 2), 1, 162, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (63, (0, 8, 3), 1, 163, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (64, (0, 8, 4), 1, 164, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (65, (0, 8, 5), 1, 165, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (66, (0, 8, 6), 1, 166, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (67, (0, 8, 7), 1, 167, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (68, (0, 8, 8), 1, 168, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (69, (0, 9, 1), 1, 169, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (70, (0, 9, 2), 1, 170, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (71, (0, 9, 3), 1, 171, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (72, (0, 9, 4), 1, 172, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (73, (0, 9, 5), 1, 173, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (74, (0, 9, 8), 1, 174, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (75, (0, 9, 9), 1, 175, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (76, (0, 10, 1), 1, 176, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (77, (0, 10, 5), 1, 177, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (78, (0, 10, 8), 1, 178, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (79, (0, 11, 0), 1, 179, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (80, (0, 11, 1), 1, 180, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (81, (0, 11, 5), 1, 181, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (82, (0, 11, 6), 1, 182, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (83, (0, 11, 7), 1, 183, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (84, (0, 11, 8), 1, 184, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (85, (0, 12, 0), 1, 185, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (86, (0, 12, 1), 1, 186, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (87, (0, 12, 5), 1, 187, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (88, (0, 12, 6), 1, 188, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (89, (0, 12, 7), 1, 189, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (90, (0, 12, 8), 1, 190, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (91, (0, 13, 1), 1, 191, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (92, (0, 13, 5), 1, 192, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (93, (0, 13, 6), 1, 193, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (94, (0, 13, 7), 1, 194, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (95, (0, 13, 8), 1, 195, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (96, (0, 14, 2), 1, 196, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (97, (0, 14, 3), 1, 197, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (98, (0, 14, 4), 1, 198, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (99, (0, 14, 5), 1, 199, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (100, (1, 0, 0), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (101, (1, 0, 1), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (102, (1, 1, 0), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (103, (1, 1, 1), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (104, (1, 1, 2), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (105, (1, 1, 5), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (106, (1, 1, 6), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (107, (1, 1, 7), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (108, (1, 2, 1), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (109, (1, 2, 2), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (110, (1, 2, 3), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (111, (1, 2, 4), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (112, (1, 2, 5), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (113, (1, 2, 6), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (114, (1, 2, 7), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (115, (1, 3, 0), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (116, (1, 3, 1), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (117, (1, 3, 2), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (118, (1, 3, 3), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (119, (1, 3, 4), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (120, (1, 3, 5), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (121, (1, 3, 6), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (122, (1, 3, 7), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (123, (1, 3, 8), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (124, (1, 4, 0), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (125, (1, 4, 1), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (126, (1, 4, 2), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (127, (1, 4, 3), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (128, (1, 4, 4), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (129, (1, 4, 5), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (130, (1, 4, 6), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (131, (1, 4, 7), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (132, (1, 4, 8), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (133, (1, 4, 9), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (134, (1, 5, 0), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (135, (1, 5, 1), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (136, (1, 5, 2), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (137, (1, 5, 3), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (138, (1, 5, 4), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (139, (1, 5, 5), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (140, (1, 5, 6), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (141, (1, 5, 7), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (142, (1, 5, 8), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (143, (1, 5, 9), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (144, (1, 6, 0), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (145, (1, 6, 1), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (146, (1, 6, 2), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (147, (1, 6, 3), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (148, (1, 6, 4), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (149, (1, 6, 5), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (150, (1, 6, 6), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (151, (1, 6, 7), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (152, (1, 6, 8), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (153, (1, 7, 1), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (154, (1, 7, 2), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (155, (1, 7, 3), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (156, (1, 7, 4), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (157, (1, 7, 5), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (158, (1, 7, 6), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (159, (1, 7, 7), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (160, (1, 7, 8), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (161, (1, 8, 1), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (162, (1, 8, 2), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (163, (1, 8, 3), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (164, (1, 8, 4), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (165, (1, 8, 5), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (166, (1, 8, 6), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (167, (1, 8, 7), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (168, (1, 8, 8), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (169, (1, 9, 1), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (170, (1, 9, 2), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (171, (1, 9, 3), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (172, (1, 9, 4), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"ag\"),\n", - " (173, (1, 9, 5), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (174, (1, 9, 8), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (175, (1, 9, 9), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (176, (1, 10, 1), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (177, (1, 10, 5), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (178, (1, 10, 8), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (179, (1, 11, 0), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (180, (1, 11, 1), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (181, (1, 11, 5), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (182, (1, 11, 6), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (183, (1, 11, 7), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (184, (1, 11, 8), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (185, (1, 12, 0), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (186, (1, 12, 1), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (187, (1, 12, 5), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (188, (1, 12, 6), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (189, (1, 12, 7), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (190, (1, 12, 8), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (191, (1, 13, 1), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (192, (1, 13, 5), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (193, (1, 13, 6), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (194, (1, 13, 7), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (195, (1, 13, 8), 0, -1, 0.1, 0.000001, 0.1, 0.3, 0.11, 3.5, \"uzfcells\"),\n", - " (196, (1, 14, 2), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (197, (1, 14, 3), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (198, (1, 14, 4), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - " (199, (1, 14, 5), 0, -1, 0.1, 0.000001, 0.2, 0.3, 0.21, 3.5, \"uzfcells\"),\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a1567395", - "metadata": {}, - "outputs": [], - "source": [ - "finf = [\n", - " [\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 2.68e-09,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 2.68e-09,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 1.67e-09,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 1.67e-09,\n", - " 2.68e-09,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 1.67e-09,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 2.68e-09,\n", - " 2.68e-09,\n", - " 2.68e-09,\n", - " 2.68e-09,\n", - " ],\n", - " [\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " ],\n", - " [\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-08,\n", - " 8.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " ],\n", - " [\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 1.60e-07,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.60e-07,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-07,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-07,\n", - " 1.60e-07,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-07,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 1.60e-07,\n", - " 1.60e-07,\n", - " 1.60e-07,\n", - " 1.60e-07,\n", - " ],\n", - " [\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.25e-07,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 1.25e-07,\n", - " 2.00e-07,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.25e-07,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " ],\n", - " [\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " ],\n", - " [\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " ],\n", - " [\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.50e-08,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 2.50e-08,\n", - " 4.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.50e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " ],\n", - " [\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " ],\n", - " [\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 1.60e-08,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.60e-08,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-08,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-08,\n", - " 1.60e-08,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-08,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 1.60e-08,\n", - " 1.60e-08,\n", - " 1.60e-08,\n", - " 1.60e-08,\n", - " ],\n", - " [\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " ],\n", - " [\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " ],\n", - " [\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 2.68e-09,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 2.68e-09,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 1.67e-09,\n", - " 2.68e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 1.67e-09,\n", - " 2.68e-09,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 1.67e-09,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 3.34e-10,\n", - " 6.68e-10,\n", - " 1.67e-09,\n", - " 1.67e-09,\n", - " 6.68e-10,\n", - " 3.34e-10,\n", - " 2.68e-09,\n", - " 2.68e-09,\n", - " 2.68e-09,\n", - " 2.68e-09,\n", - " ],\n", - " [\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " ],\n", - " [\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-08,\n", - " 8.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-08,\n", - " 8.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " ],\n", - " [\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 1.60e-07,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.60e-07,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-07,\n", - " 1.60e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-07,\n", - " 1.60e-07,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 1.00e-07,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 2.00e-08,\n", - " 4.00e-08,\n", - " 1.00e-07,\n", - " 1.00e-07,\n", - " 4.00e-08,\n", - " 2.00e-08,\n", - " 1.60e-07,\n", - " 1.60e-07,\n", - " 1.60e-07,\n", - " 1.60e-07,\n", - " ],\n", - " [\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.25e-07,\n", - " 2.00e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 1.25e-07,\n", - " 2.00e-07,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.25e-07,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-08,\n", - " 1.25e-07,\n", - " 1.25e-07,\n", - " 5.00e-08,\n", - " 2.50e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " ],\n", - " [\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 3.20e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.00e-07,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 8.00e-08,\n", - " 2.00e-07,\n", - " 2.00e-07,\n", - " 8.00e-08,\n", - " 4.00e-08,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " 3.20e-07,\n", - " ],\n", - " [\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " ],\n", - " [\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.50e-08,\n", - " 4.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 2.50e-08,\n", - " 4.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.50e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-08,\n", - " 2.50e-08,\n", - " 2.50e-08,\n", - " 1.00e-08,\n", - " 5.00e-09,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " 4.00e-08,\n", - " ],\n", - " [\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 2.40e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 1.50e-08,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 3.00e-09,\n", - " 6.00e-09,\n", - " 1.50e-08,\n", - " 1.50e-08,\n", - " 6.00e-09,\n", - " 3.00e-09,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " 2.40e-08,\n", - " ],\n", - " [\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 1.60e-08,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.60e-08,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-08,\n", - " 1.60e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-08,\n", - " 1.60e-08,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-08,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 4.00e-09,\n", - " 1.00e-08,\n", - " 1.00e-08,\n", - " 4.00e-09,\n", - " 2.00e-09,\n", - " 1.60e-08,\n", - " 1.60e-08,\n", - " 1.60e-08,\n", - " 1.60e-08,\n", - " ],\n", - " [\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " ],\n", - " [\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 8.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 5.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 1.00e-09,\n", - " 2.00e-09,\n", - " 5.00e-09,\n", - " 5.00e-09,\n", - " 2.00e-09,\n", - " 1.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " 8.00e-09,\n", - " ],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e6642442", - "metadata": {}, - "outputs": [], - "source": [ - "extwc = [\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.100005,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - " 0.200010,\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d7fcd185", - "metadata": {}, - "outputs": [], - "source": [ - "uzf_spd = {}\n", - "pET = 1.00e-08\n", - "extdp = 15.0\n", - "ha = 0.0\n", - "hroot = 0.0\n", - "rootact = 0.0\n", - "for tm in range(len(tdis_ds)):\n", - " sp = []\n", - " iuzno = 0\n", - " for i in range(len(extwc)):\n", - " sp.append((iuzno, finf[tm][i], pET, extdp, extwc[i], ha, hroot, rootact))\n", - " iuzno += 1\n", - " uzf_spd.update({int(tm): sp})" - ] - }, - { - "cell_type": "markdown", - "id": "f2fc6c33", - "metadata": {}, - "source": [ - "LAK Package" - ] - }, - { - "cell_type": "markdown", - "id": "a72127a4", - "metadata": {}, - "source": [ - "\n", - "lak_pakdata = [[0, 1040.0, 12], [1, 1010.0, 26]]\n", - "\n", - "lak_conn = [\n", - " [0, 0, (0, 8, 6), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [0, 1, (0, 8, 7), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [0, 2, (0, 9, 5), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [0, 3, (0, 9, 8), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [0, 4, (0, 10, 5), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [0, 5, (0, 10, 8), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [0, 6, (0, 11, 6), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [0, 7, (0, 11, 7), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [0, 8, (1, 9, 6), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [0, 9, (1, 9, 7), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [0, 10, (1, 10, 6), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [0, 11, (1, 10, 7), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 0, (0, 9, 2), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 1, (0, 9, 3), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 2, (0, 9, 4), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 3, (0, 10, 1), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 4, (0, 10, 5), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 5, (0, 11, 1), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 6, (0, 11, 5), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 7, (0, 12, 1), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 8, (0, 12, 5), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 9, (0, 13, 1), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 10, (0, 13, 5), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 11, (0, 14, 2), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 12, (0, 14, 3), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 13, (0, 14, 4), \"HORIZONTAL\", 2.00e-09, 0.0, 0.0, 2500.0, 5000.0],\n", - " [1, 14, (1, 10, 2), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 15, (1, 10, 3), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 16, (1, 10, 4), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 17, (1, 11, 2), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 18, (1, 11, 3), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 19, (1, 11, 4), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 20, (1, 12, 2), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 21, (1, 12, 3), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 22, (1, 12, 4), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 23, (1, 13, 2), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 24, (1, 13, 3), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - " [1, 25, (1, 13, 4), \"VERTICAL\", 2.00e-09, 0.0, 0.0, 0.0, 0.0],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "085ac295", - "metadata": {}, - "outputs": [], - "source": [ - "lak_stage = (\n", - " 1040.0,\n", - " 1010.0,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "47a8dbf4", - "metadata": {}, - "outputs": [], - "source": [ - "lak_outlets = [\n", - " [0, 0, -1, \"MANNING\", 1040.0004, 12.0, 0.29999999e-01, 0.14285709e-02],\n", - " [1, 1, -1, \"MANNING\", 1000.0000, 60.0, 0.29999999e-01, 0.12500000e-02],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f6f3d7a2", - "metadata": {}, - "outputs": [], - "source": [ - "lk_spd = {\n", - " 0: [\n", - " [0, \"rainfall\", 0.500e-07],\n", - " [0, \"evaporation\", 0.100e-07],\n", - " [0, \"runoff\", 1.50],\n", - " [0, \"withdrawal\", 0.00],\n", - " [1, \"rainfall\", 0.120e-07],\n", - " [1, \"evaporation\", 0.110e-07],\n", - " [1, \"runoff\", 3.00],\n", - " [1, \"withdrawal\", 0.12],\n", - " ]\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ee07a7bc", - "metadata": {}, - "outputs": [], - "source": [ - "# MVR Package\n", - "mvr_pack = [[\"UZF-1\"], [\"SFR-1\"], [\"LAK-1\"], [\"WEL-1\"]]\n", - "maxpackages = len(mvr_pack)\n", - "max_mvr = 200\n", - "mvr_spd = {\n", - " 0: [\n", - " (\"SFR-1\", 22, \"LAK-1\", 0, \"FACTOR\", 1.0),\n", - " (\"LAK-1\", 0, \"SFR-1\", 23, \"FACTOR\", 1.0),\n", - " (\"SFR-1\", 28, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"LAK-1\", 1, \"SFR-1\", 29, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 0, \"SFR-1\", 0, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 1, \"SFR-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 2, \"SFR-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 3, \"SFR-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 4, \"SFR-1\", 2, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 5, \"SFR-1\", 10, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 6, \"SFR-1\", 11, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 7, \"SFR-1\", 11, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 8, \"SFR-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 9, \"SFR-1\", 2, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 10, \"SFR-1\", 3, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 11, \"SFR-1\", 9, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 12, \"SFR-1\", 10, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 13, \"SFR-1\", 11, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 14, \"SFR-1\", 12, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 15, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 16, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 17, \"SFR-1\", 2, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 18, \"SFR-1\", 3, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 19, \"SFR-1\", 4, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 20, \"SFR-1\", 5, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 21, \"SFR-1\", 5, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 22, \"SFR-1\", 12, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 23, \"SFR-1\", 16, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 24, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 25, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 26, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 27, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 28, \"SFR-1\", 4, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 29, \"SFR-1\", 5, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 30, \"SFR-1\", 5, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 31, \"SFR-1\", 13, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 32, \"SFR-1\", 16, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 33, \"SFR-1\", 15, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 34, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 35, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 36, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 37, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 38, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 39, \"SFR-1\", 6, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 40, \"SFR-1\", 6, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 41, \"SFR-1\", 18, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 42, \"SFR-1\", 16, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 43, \"SFR-1\", 15, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 44, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 45, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 46, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 47, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 48, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 49, \"SFR-1\", 7, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 50, \"SFR-1\", 19, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 51, \"SFR-1\", 19, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 52, \"SFR-1\", 19, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 53, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 54, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 55, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 56, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 57, \"SFR-1\", 8, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 58, \"SFR-1\", 20, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 59, \"SFR-1\", 20, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 60, \"SFR-1\", 20, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 61, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 62, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 63, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 64, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 65, \"SFR-1\", 22, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 66, \"LAK-1\", 0, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 67, \"LAK-1\", 0, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 68, \"LAK-1\", 0, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 69, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 70, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 71, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 72, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 73, \"LAK-1\", 0, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 74, \"LAK-1\", 0, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 75, \"LAK-1\", 0, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 76, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 77, \"SFR-1\", 8, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 78, \"LAK-1\", 0, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 79, \"SFR-1\", 30, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 80, \"SFR-1\", 29, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 81, \"SFR-1\", 8, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 82, \"SFR-1\", 23, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 83, \"LAK-1\", 0, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 84, \"LAK-1\", 0, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 85, \"SFR-1\", 30, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 86, \"SFR-1\", 29, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 87, \"SFR-1\", 28, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 88, \"SFR-1\", 27, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 89, \"SFR-1\", 26, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 90, \"SFR-1\", 25, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 91, \"SFR-1\", 29, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 92, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 93, \"SFR-1\", 27, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 94, \"SFR-1\", 26, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 95, \"SFR-1\", 25, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 96, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 97, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 98, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"UZF-1\", 99, \"LAK-1\", 1, \"FACTOR\", 1.0),\n", - " (\"WEL-1\", 0, \"UZF-1\", 37, \"FACTOR\", 1.0),\n", - " (\"WEL-1\", 1, \"UZF-1\", 38, \"FACTOR\", 1.0),\n", - " (\"WEL-1\", 2, \"UZF-1\", 47, \"FACTOR\", 1.0),\n", - " (\"WEL-1\", 3, \"UZF-1\", 48, \"FACTOR\", 1.0),\n", - " (\"WEL-1\", 4, \"UZF-1\", 55, \"FACTOR\", 1.0),\n", - " (\"WEL-1\", 5, \"UZF-1\", 56, \"FACTOR\", 1.0),\n", - " (\"WEL-1\", 6, \"UZF-1\", 63, \"FACTOR\", 1.0),\n", - " (\"WEL-1\", 7, \"UZF-1\", 64, \"FACTOR\", 1.0),\n", - " (\"WEL-1\", 8, \"UZF-1\", 71, \"FACTOR\", 1.0),\n", - " (\"WEL-1\", 9, \"UZF-1\", 72, \"FACTOR\", 1.0),\n", - " ]\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "6b65284e", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4bd479d0", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 100\n", - "ninner = 50\n", - "hclose = 1e-6\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "d8300852", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 SFR Package Problem 1 model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "205f41e0", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " complexity=\"complex\",\n", - " outer_dvclose=1.0e-4,\n", - " outer_maximum=2000,\n", - " under_relaxation=\"dbd\",\n", - " linear_acceleration=\"BICGSTAB\",\n", - " under_relaxation_theta=0.7,\n", - " under_relaxation_kappa=0.08,\n", - " under_relaxation_gamma=0.05,\n", - " under_relaxation_momentum=0.0,\n", - " backtracking_number=20,\n", - " backtracking_tolerance=2.0,\n", - " backtracking_reduction_factor=0.2,\n", - " backtracking_residual_limit=5.0e-4,\n", - " inner_dvclose=1.0e-5,\n", - " rcloserecord=\"0.0001 relative_rclose\",\n", - " inner_maximum=100,\n", - " relaxation_factor=0.0,\n", - " number_orthogonalizations=2,\n", - " preconditioner_levels=8,\n", - " preconditioner_drop_tolerance=0.001,\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim, modelname=sim_name, newtonoptions=\"newton\", save_flows=True\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " idomain=idomain,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " alternative_cell_averaging=\"AMT-HMK\",\n", - " icelltype=1,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " iconvert=1,\n", - " sy=sy,\n", - " ss=ss,\n", - " steady_state={0: True},\n", - " transient={1: True},\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfghb(gwf, stress_period_data=ghb_spd)\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " print_input=True,\n", - " print_flows=True,\n", - " save_flows=True,\n", - " mover=True,\n", - " pname=\"WEL-1\",\n", - " stress_period_data=wel_spd,\n", - " )\n", - " sfr = flopy.mf6.ModflowGwfsfr(\n", - " gwf,\n", - " print_flows=True,\n", - " print_stage=True,\n", - " save_flows=True,\n", - " boundnames=True,\n", - " budget_filerecord=sim_name + \".sfr.bud\",\n", - " mover=True,\n", - " pname=\"SFR-1\",\n", - " maximum_depth_change=0.1e-05,\n", - " length_conversion=3.28081,\n", - " nreaches=len(sfr_pakdata),\n", - " packagedata=sfr_pakdata,\n", - " connectiondata=sfr_conn,\n", - " diversions=sfr_div,\n", - " perioddata=sfr_spd,\n", - " filename=f\"{sim_name}.sfr\",\n", - " )\n", - " sfr_obs_file = f\"{sim_name}.sfr.obs\"\n", - " sfr_obs_dict = {\n", - " \"sfr.reach01.csv\": [\n", - " (\"extin\", \"ext-inflow\", (0,)),\n", - " (\"inflow\", \"inflow\", (0,)),\n", - " (\"frommvr\", \"from-mvr\", (0,)),\n", - " (\"gwf\", \"sfr\", (0,)),\n", - " (\"outflow\", \"outflow\", (0,)),\n", - " (\"extout\", \"ext-outflow\", (0,)),\n", - " (\"tomvr\", \"to-mvr\", (0,)),\n", - " ],\n", - " \"sfr.reach24.csv\": [\n", - " (\"extin\", \"ext-inflow\", (23,)),\n", - " (\"inflow\", \"inflow\", (23,)),\n", - " (\"frommvr\", \"from-mvr\", (23,)),\n", - " (\"gwf\", \"sfr\", (23,)),\n", - " (\"outflow\", \"outflow\", (23,)),\n", - " (\"extout\", \"ext-outflow\", (23,)),\n", - " (\"tomvr\", \"to-mvr\", (23,)),\n", - " ],\n", - " \"sfr.reach29.csv\": [\n", - " (\"extin\", \"ext-inflow\", (28,)),\n", - " (\"inflow\", \"inflow\", (28,)),\n", - " (\"frommvr\", \"from-mvr\", (28,)),\n", - " (\"gwf\", \"sfr\", (28,)),\n", - " (\"outflow\", \"outflow\", (28,)),\n", - " (\"extout\", \"ext-outflow\", (28,)),\n", - " (\"tomvr\", \"to-mvr\", (28,)),\n", - " ],\n", - " \"sfr.reach31.csv\": [\n", - " (\"extin\", \"ext-inflow\", (30,)),\n", - " (\"inflow\", \"inflow\", (30,)),\n", - " (\"frommvr\", \"from-mvr\", (30,)),\n", - " (\"gwf\", \"sfr\", (30,)),\n", - " (\"outflow\", \"outflow\", (30,)),\n", - " (\"extout\", \"ext-outflow\", (30,)),\n", - " (\"tomvr\", \"to-mvr\", (30,)),\n", - " ],\n", - " \"sfr.allreaches.csv\": [\n", - " (\"extin\", \"ext-inflow\", \"allreaches\"),\n", - " (\"inflow\", \"inflow\", \"allreaches\"),\n", - " (\"frommvr\", \"from-mvr\", \"allreaches\"),\n", - " (\"gwf\", \"sfr\", \"allreaches\"),\n", - " (\"outflow\", \"outflow\", \"allreaches\"),\n", - " (\"extout\", \"ext-outflow\", \"allreaches\"),\n", - " (\"tomvr\", \"to-mvr\", \"allreaches\"),\n", - " ],\n", - " \"sfr.stage.csv\": [\n", - " (\"s01\", \"stage\", (0,)),\n", - " (\"s24\", \"stage\", (23,)),\n", - " (\"s29\", \"stage\", (28,)),\n", - " (\"s31\", \"stage\", (30,)),\n", - " ],\n", - " }\n", - " sfr.obs.initialize(\n", - " filename=sfr_obs_file,\n", - " digits=10,\n", - " print_input=True,\n", - " continuous=sfr_obs_dict,\n", - " )\n", - "\n", - " (\n", - " idomain_wlakes,\n", - " lakepakdata_dict,\n", - " lakeconnectiondata,\n", - " ) = flopy.mf6.utils.get_lak_connections(\n", - " gwf.modelgrid,\n", - " lake_map,\n", - " idomain=gwf.dis.idomain.array,\n", - " bedleak=lake_leakance,\n", - " )\n", - " lak_pakdata = []\n", - " for key in lakepakdata_dict.keys():\n", - " lak_pakdata.append([key, lak_stage[key], lakepakdata_dict[key]])\n", - " lak = flopy.mf6.ModflowGwflak(\n", - " gwf,\n", - " print_stage=True,\n", - " print_flows=True,\n", - " save_flows=True,\n", - " budget_filerecord=sim_name + \".lak.bud\",\n", - " length_conversion=3.28081,\n", - " mover=True,\n", - " pname=\"LAK-1\",\n", - " boundnames=False,\n", - " nlakes=len(lak_pakdata),\n", - " noutlets=len(lak_outlets),\n", - " outlets=lak_outlets,\n", - " packagedata=lak_pakdata,\n", - " connectiondata=lakeconnectiondata,\n", - " perioddata=lk_spd,\n", - " filename=f\"{sim_name}.lak\",\n", - " )\n", - " lak_obs_file = f\"{sim_name}.lak.obs\"\n", - " lak_obs_dict = {\n", - " \"obs_lak.csv\": [\n", - " (\"LAK1_STAGE\", \"STAGE\", 1),\n", - " (\"LAK2_STAGE\", \"STAGE\", 2),\n", - " (\"LAK1_TO-MVR\", \"TO-MVR\", 1),\n", - " (\"LAK1_FROM-MVR\", \"FROM-MVR\", 1),\n", - " (\"LAK2_TO-MVR\", \"TO-MVR\", 2),\n", - " (\"LAK2_FROM-MVR\", \"FROM-MVR\", 2),\n", - " ]\n", - " }\n", - " lak.obs.initialize(filename=lak_obs_file, digits=10, continuous=lak_obs_dict)\n", - " uzf = flopy.mf6.ModflowGwfuzf(\n", - " gwf,\n", - " nuzfcells=len(uzf_pakdata),\n", - " boundnames=True,\n", - " ntrailwaves=10,\n", - " nwavesets=50,\n", - " print_flows=False,\n", - " save_flows=True,\n", - " simulate_et=True,\n", - " linear_gwet=True,\n", - " simulate_gwseep=True,\n", - " mover=True,\n", - " packagedata=uzf_pakdata,\n", - " perioddata=uzf_spd,\n", - " budget_filerecord=f\"{sim_name}.uzf.bud\",\n", - " pname=\"UZF-1\",\n", - " filename=f\"{sim_name}.uzf\",\n", - " )\n", - " uzf_obs_file = f\"{sim_name}.uzf.obs\"\n", - " uzf_obs_dict = {\n", - " \"obs_uzf.csv\": [\n", - " (\"ninfil\", \"net-infiltration\", \"ag\"),\n", - " (\"rejinf\", \"rej-inf\", \"ag\"),\n", - " (\"rejinfmvr\", \"rej-inf-to-mvr\", \"ag\"),\n", - " (\"infil\", \"infiltration\", \"ag\"),\n", - " (\"frommvr\", \"from-mvr\", \"ag\"),\n", - " (\"gwrch\", \"uzf-gwrch\", \"ag\"),\n", - " (\"gwet\", \"uzf-gwet\", \"ag\"),\n", - " (\"uzet\", \"uzet\", \"ag\"),\n", - " ],\n", - " \"obs_uzf_column.csv\": [\n", - " (\"id26_infil\", \"infiltration\", 26),\n", - " (\"id126_infil\", \"infiltration\", 126),\n", - " (\"id26_dpth=20\", \"water-content\", 26, 20.0),\n", - " (\n", - " \"id126_dpth=51\",\n", - " \"water-content\",\n", - " 126,\n", - " 1.0,\n", - " ), # DEPTH IS BELOW CELTOP\n", - " (\"id26_rch\", \"uzf-gwrch\", 26),\n", - " (\"id126_rch\", \"uzf-gwrch\", 126),\n", - " (\"id26_gwet\", \"uzf-gwet\", 26),\n", - " (\"id126_gwet\", \"uzf-gwet\", 126),\n", - " (\"id26_uzet\", \"uzet\", 26),\n", - " (\"id126_uzet\", \"uzet\", 126),\n", - " (\"id26_gwd2mvr\", \"uzf-gwd-to-mvr\", 26),\n", - " (\"id126_gwd2mvr\", \"uzf-gwd-to-mvr\", 126),\n", - " (\"id26_rejinf\", \"rej-inf-to-mvr\", 26),\n", - " (\"id126_rejinf\", \"rej-inf-to-mvr\", 126),\n", - " ],\n", - " }\n", - " uzf.obs.initialize(\n", - " filename=uzf_obs_file, print_input=True, continuous=uzf_obs_dict\n", - " )\n", - " flopy.mf6.ModflowGwfmvr(\n", - " gwf,\n", - " maxmvr=max_mvr,\n", - " print_flows=True,\n", - " maxpackages=maxpackages,\n", - " packages=mvr_pack,\n", - " perioddata=mvr_spd,\n", - " pname=\"MVR-1\",\n", - " budget_filerecord=sim_name + \".mvr.bud\",\n", - " filename=f\"{sim_name}.mvr\",\n", - " )\n", - "\n", - " # rest idomain with lake adjustments\n", - " gwf.dis.idomain = idomain_wlakes\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "3781a712", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 SFR Package Problem 1 model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "63ecbbaa", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "61199277", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the SFR Package Problem 1 model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "91968b82", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "2bef39aa", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c054fcb7", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_grid(gwf, silent=True):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " fig = plt.figure(figsize=figure_size, constrained_layout=False)\n", - " gs = mpl.gridspec.GridSpec(ncols=10, nrows=7, figure=fig, wspace=5)\n", - " plt.axis(\"off\")\n", - "\n", - " axes = []\n", - " axes.append(fig.add_subplot(gs[:6, :5]))\n", - " axes.append(fig.add_subplot(gs[:6, 5:], sharey=axes[0]))\n", - "\n", - " for ax in axes:\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - " ax.set_aspect(\"equal\")\n", - "\n", - " # legend axis\n", - " axes.append(fig.add_subplot(gs[6:, :]))\n", - "\n", - " # set limits for legend area\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " top_coll = mm.plot_array(\n", - " top, vmin=1000, vmax=1120, masked_values=masked_values, alpha=0.5\n", - " )\n", - " mm.plot_bc(\"SFR\", color=\"green\")\n", - " cv = mm.contour_array(\n", - " top,\n", - " levels=np.arange(1000, 1100, 20),\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=\"black\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " mm.plot_inactive(color_noflow=\"0.5\")\n", - " mm.plot_grid(lw=0.5, color=\"black\")\n", - " cbar = plt.colorbar(\n", - " top_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " ax=ax,\n", - " format=\"%.0f\",\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Land surface elevation, $ft$\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " ax.set_ylabel(\"y-coordinate, in feet\")\n", - " fs.heading(ax, heading=\"Land surface elevation\", idx=0)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " ax = axes[1]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " bot_coll = mm.plot_array(\n", - " botm, vmin=950, vmax=1100, masked_values=masked_values, alpha=0.5\n", - " )\n", - " mm.plot_bc(\"GHB\", color=\"purple\")\n", - " mm.plot_bc(\"WEL\", color=\"red\", kper=1)\n", - " cv = mm.contour_array(\n", - " botm,\n", - " levels=np.arange(950, 1100, 20),\n", - " linewidths=0.5,\n", - " linestyles=\":\",\n", - " colors=\"black\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " mm.plot_inactive(color_noflow=\"0.5\")\n", - " mm.plot_grid(lw=0.5, color=\"black\")\n", - " cbar = plt.colorbar(\n", - " bot_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " ax=ax,\n", - " format=\"%.0f\",\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Bottom elevation, $ft$\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " fs.heading(ax, heading=\"Bottom elevation\", idx=1)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"0.5\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Inactive cells\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"green\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Stream boundary\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"purple\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"General head boundary\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"red\",\n", - " mec=\"black\",\n", - " markeredgewidth=0.5,\n", - " label=\"Well boundary\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " ls=\"-\",\n", - " color=\"black\",\n", - " label=r\"Land surface elevation contour, $ft$\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0.5,\n", - " ls=\":\",\n", - " color=\"black\",\n", - " label=r\"Bottom elevation contour, $ft$\",\n", - " )\n", - " fs.graph_legend(ax, loc=\"center\", ncol=3)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-grid{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "58ed46ce", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "46120f61", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_head_results(gwf, silent=True):\n", - " sim_ws = os.path.join(ws, sim_name)\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj = gwf.output.head()\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " cobj = gwf.output.budget()\n", - "\n", - " kstpkper = hobj.get_kstpkper()\n", - "\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " fig = plt.figure(figsize=figure_size, constrained_layout=False)\n", - " gs = mpl.gridspec.GridSpec(ncols=10, nrows=7, figure=fig, wspace=5)\n", - " plt.axis(\"off\")\n", - "\n", - " axes = [fig.add_subplot(gs[:6, :5])]\n", - " axes.append(fig.add_subplot(gs[:6, 5:], sharey=axes[0]))\n", - "\n", - " for ax in axes:\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - " ax.set_aspect(\"equal\")\n", - "\n", - " # legend axis\n", - " axes.append(fig.add_subplot(gs[6:, :]))\n", - "\n", - " # set limits for legend area\n", - " ax = axes[-1]\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - "\n", - " # get rid of ticks and spines for legend area\n", - " ax.axis(\"off\")\n", - " ax.set_xticks([])\n", - " ax.set_yticks([])\n", - " ax.spines[\"top\"].set_color(\"none\")\n", - " ax.spines[\"bottom\"].set_color(\"none\")\n", - " ax.spines[\"left\"].set_color(\"none\")\n", - " ax.spines[\"right\"].set_color(\"none\")\n", - " ax.patch.set_alpha(0.0)\n", - "\n", - " # extract heads and specific discharge for first stress period\n", - " head = hobj.get_data(kstpkper=kstpkper[0])\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " cobj.get_data(text=\"DATA-SPDIS\", kstpkper=kstpkper[0])[0],\n", - " gwf,\n", - " )\n", - "\n", - " ax = axes[0]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " head_coll = mm.plot_array(head, vmin=900, vmax=1120, masked_values=masked_values)\n", - " cv = mm.contour_array(\n", - " head,\n", - " levels=np.arange(900, 1100, 10),\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=\"black\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " mm.plot_vector(qx, qy, normalize=True, color=\"0.75\")\n", - " mm.plot_inactive(color_noflow=\"0.5\")\n", - " mm.plot_grid(lw=0.5, color=\"black\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " ax.set_ylabel(\"y-coordinate, in feet\")\n", - " fs.heading(ax, heading=\"Steady-state\", idx=0)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # extract heads and specific discharge for second stress period\n", - " head = hobj.get_data(kstpkper=kstpkper[1])\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " cobj.get_data(text=\"DATA-SPDIS\", kstpkper=kstpkper[1])[0],\n", - " gwf,\n", - " )\n", - "\n", - " ax = axes[1]\n", - " mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)\n", - " head_coll = mm.plot_array(head, vmin=900, vmax=1120, masked_values=masked_values)\n", - " cv = mm.contour_array(\n", - " head,\n", - " levels=np.arange(900, 1100, 10),\n", - " linewidths=0.5,\n", - " linestyles=\"-\",\n", - " colors=\"black\",\n", - " masked_values=masked_values,\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " mm.plot_vector(qx, qy, normalize=True, color=\"0.75\")\n", - " mm.plot_inactive(color_noflow=\"0.5\")\n", - " mm.plot_grid(lw=0.5, color=\"black\")\n", - " ax.set_xlabel(\"x-coordinate, in feet\")\n", - " fs.heading(ax, heading=\"Pumping\", idx=1)\n", - " fs.remove_edge_ticks(ax)\n", - "\n", - " # legend\n", - " ax = axes[-1]\n", - " cbar = plt.colorbar(\n", - " head_coll,\n", - " shrink=0.8,\n", - " orientation=\"horizontal\",\n", - " ax=ax,\n", - " format=\"%.0f\",\n", - " )\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Head, $ft$\")\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"$\\u2192$\",\n", - " ms=10,\n", - " mfc=\"0.75\",\n", - " mec=\"0.75\",\n", - " label=\"Normalized specific discharge\",\n", - " )\n", - " ax.plot(-10000, -10000, lw=0.5, color=\"black\", label=r\"Head contour, $ft$\")\n", - " fs.graph_legend(ax, loc=\"upper center\", ncol=2)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-01{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "b1c5092e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the mvr results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c4c5b62b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_mvr_results(idx, gwf, silent=True):\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - "\n", - " # load the observations\n", - " mvr = gwf.get_package(\"MVR-1\")\n", - " mvr_Q = mvr.output.budget()\n", - " # This retrieves all of the MOVER fluxes:\n", - " mvr_all = mvr_Q.get_data(text=\" MOVER-FLOW\")\n", - "\n", - " ckstpkper = mvr_Q.get_kstpkper()\n", - "\n", - " # The following will tell us the contents of MVR recarrays\n", - " # mvr_Q.list_records()\n", - " # Connections specified in MVR input include:\n", - " # SFR -> LAK\n", - " # LAK -> SFR\n", - " # UZF -> SFR\n", - " # UZF -> LAK\n", - " # WEL -> UZF\n", - " provider = b\"WEL-1 \"\n", - " receiver1 = b\"UZF-1 \"\n", - " gwirrig = []\n", - " for i, kstpkper in enumerate(ckstpkper):\n", - " # The following gets the actual indexes of where the conditions are\n", - " # satisfied, which is what the recarray needs\n", - " mvr_idxs = np.where(\n", - " np.all(\n", - " (\n", - " np.array(mvr_Q.recordarray[\"kper\"] == i),\n", - " np.array(mvr_Q.recordarray[\"paknam\"] == provider), # Provider\n", - " np.array(mvr_Q.recordarray[\"paknam2\"] == receiver1),\n", - " ),\n", - " axis=0,\n", - " )\n", - " ) # Receiver\n", - "\n", - " tot_stp_gwirrig = 0\n", - " if len(mvr_idxs[0]) > 0:\n", - " mvr_welirrig = mvr_all[mvr_idxs[0][0]]\n", - " # Loop through each row of the mvr_welirrig recarray for tallying\n", - " # gw irrigation events on a cell-by-cell basis\n", - "\n", - " for k, itm in enumerate(mvr_welirrig):\n", - " # itm[1]: the receiver identifier. 2.6280e6: len of stress\n", - " # period - about 1 month\n", - " tot_stp_gwirrig += itm[2]\n", - "\n", - " gwirrig.append(abs(tot_stp_gwirrig) * 2.6280e6 / 43560) # results in ac*ft\n", - "\n", - " # Get all groundwater discharge:\n", - " provider = b\"UZF-1 \"\n", - " receiver1 = b\"SFR-1 \"\n", - " receiver2 = b\"LAK-1 \"\n", - " tot_mvr_runoff = []\n", - " for i, kstpkper in enumerate(ckstpkper):\n", - " mvr_runoff = 0 # Initialize\n", - " # The following gets the actual indexes of where the conditions are satisfied, which is what the recarray needs\n", - " mvr_idxs = np.where(\n", - " np.all(\n", - " (\n", - " np.array(mvr_Q.recordarray[\"kper\"] == i),\n", - " np.array(mvr_Q.recordarray[\"paknam\"] == provider), # Provider\n", - " np.logical_or(\n", - " mvr_Q.recordarray[\"paknam2\"] == receiver1, # Receiver\n", - " mvr_Q.recordarray[\"paknam2\"] == receiver2,\n", - " ),\n", - " ),\n", - " axis=0,\n", - " )\n", - " )\n", - " # For each index (there will be two in this case because there are two receivers)\n", - " for j in range(len(mvr_idxs[0])):\n", - " mvr_rnf2sw = mvr_all[mvr_idxs[0][j]]\n", - " # Loop through each row of the mvr_uzf2sw for tallying flow totals\n", - " for k, itm in enumerate(mvr_rnf2sw):\n", - " mvr_runoff += itm[2]\n", - " # Tally the result\n", - " tot_mvr_runoff.append(abs(mvr_runoff) * 2.6280e6 / 43560)\n", - "\n", - " # Barplot of pumping and runoff\n", - " # set width of bar\n", - " barWidth = 0.25\n", - " fig, ax = plt.subplots(figsize=figure_size)\n", - "\n", - " # set height of bar\n", - " bardat = [gwirrig, tot_mvr_runoff]\n", - "\n", - " # Set position of bar on X axis\n", - " br1 = np.arange(len(gwirrig)) + 1\n", - " br2 = [x + barWidth for x in br1]\n", - "\n", - " # Make the plot\n", - " plt.bar(\n", - " br1,\n", - " gwirrig,\n", - " color=\"r\",\n", - " width=barWidth,\n", - " edgecolor=\"grey\",\n", - " label=\"GW Irrig\",\n", - " )\n", - " plt.bar(\n", - " br2,\n", - " tot_mvr_runoff,\n", - " color=\"g\",\n", - " width=barWidth,\n", - " edgecolor=\"grey\",\n", - " label=\"Runoff\",\n", - " )\n", - "\n", - " # Adding Xticks\n", - " plt.xlabel(\"Month\")\n", - " plt.ylabel(\"Acre-feet\")\n", - " plt.legend()\n", - "\n", - " title = \"Total monthly mvr flux\"\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-mvr{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "dba3c14e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the mvr results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b74730bf", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_uzfcolumn_results(idx, gwf, silent=True):\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " fname = os.path.join(sim_ws, \"obs_uzf_column.csv\")\n", - " uzf_dat = pd.read_csv(fname, header=0)\n", - " uzf_dat[\"time_days\"] = uzf_dat[\"time\"] / 86400\n", - " x = uzf_dat[\"time_days\"]\n", - " finf = uzf_dat[\"ID26_INFIL\"] * 86400 / 43560\n", - " wc = uzf_dat[\"ID26_DPTH=20\"]\n", - " rch = (uzf_dat[\"ID26_RCH\"] + uzf_dat[\"ID126_RCH\"]) * 86400 / 43560\n", - " gwet = (uzf_dat[\"ID26_GWET\"] + uzf_dat[\"ID126_GWET\"]) * 86400 / 43560\n", - " uzet = (uzf_dat[\"ID26_UZET\"] + uzf_dat[\"ID126_UZET\"]) * 86400 / 43560\n", - " gwdisq = (uzf_dat[\"ID26_GWD2MVR\"] + uzf_dat[\"ID126_GWD2MVR\"]) * 86400 / 43560\n", - " rejinf = (uzf_dat[\"ID26_REJINF\"] + uzf_dat[\"ID126_REJINF\"]) * 86400 / 43560\n", - "\n", - " fig = plt.figure(figsize=figure_size)\n", - " ax1 = fig.add_subplot(1, 1, 1)\n", - "\n", - " ln1 = ax1.plot(x, finf, color=\"b\", label=\"Infiltration\")\n", - " ln2 = ax1.plot(x, rch, color=\"g\", label=\"Recharge\")\n", - " ax2 = ax1.twinx()\n", - " ln3 = ax2.plot(x, wc, \"r--\", label=\"Water Content\")\n", - "\n", - " ax1.set_xlabel(\"Days\")\n", - " ax1.set_ylabel(\"UZ Fluxes - Row 5, Column 2, in ac*ft\")\n", - " ax1.set_xlim(0, 740)\n", - " ax1.set_ylim(0, 16)\n", - " ax2.set_ylim(0.14, 0.3)\n", - " ax2.set_ylabel(\"Water Content\")\n", - " ax1.yaxis.grid(\"on\")\n", - "\n", - " lns = ln1 + ln2 + ln3\n", - " labs = [l.get_label() for l in lns]\n", - " ax1.legend(lns, labs, loc=\"upper left\")\n", - "\n", - " title = \"Time series of UZ fluxes for row 5, column 2\"\n", - " letter = chr(ord(\"@\") + idx + 2)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-uz{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "c2bdbd71", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the SFR Package Problem 1 model results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "487cf0c0", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(idx, sim, silent=True):\n", - " if config.plotModel:\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " plot_grid(gwf, silent=silent)\n", - "\n", - " plot_head_results(gwf, silent=silent)\n", - "\n", - " plot_mvr_results(idx, gwf, silent=silent)\n", - "\n", - " plot_uzfcolumn_results(idx, gwf, silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "b4d32b63", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the SFR Package Problem 1 model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "93609108", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " sim = build_model()\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - " assert success, f\"could not run...{sim_name}\"\n", - "\n", - " if success:\n", - " plot_results(idx, sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1412be6b", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "87c14269", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "45271911", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### SFR Package Problem 1 Simulation\n", - " #\n", - " # Simulated heads in model the unconfined, middle, and lower aquifers (model layers\n", - " # 1, 3, and 5) are shown in the figure below. MODFLOW-2005 results for a quasi-3D\n", - " # model are also shown. The location of drain (green) and well (gray) boundary\n", - " # conditions, normalized specific discharge, and head contours (25 ft contour\n", - " # intervals) are also shown.\n", - "\n", - " simulation(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-spbc.ipynb b/notebooks/ex-gwf-spbc.ipynb deleted file mode 100644 index a22762c7..00000000 --- a/notebooks/ex-gwf-spbc.ipynb +++ /dev/null @@ -1,537 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "fdcfb257", - "metadata": {}, - "source": [ - "## SPBC example\n", - "\n", - "Periodic boundary condition problem is based on Laattoe and others (2014).\n", - "A MODFLOW 6 GWF-GWF Exchange is used to connect the left column with the\n", - "right column.\n" - ] - }, - { - "cell_type": "markdown", - "id": "1a3801fe", - "metadata": {}, - "source": [ - "### SPBC Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d32aa47a", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f73e6edb", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "da970088", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dc33a7c5", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "32074beb", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f34e9b55", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "6c800f7d", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2f1d8f97", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 4)" - ] - }, - { - "cell_type": "markdown", - "id": "0f4c10e6", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef507e3f", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "684ee581", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "42703b60", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-spbc\"" - ] - }, - { - "cell_type": "markdown", - "id": "a53c291e", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "feb4a017", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "d95bcfe8", - "metadata": {}, - "source": [ - "Table SPBC Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d49d9c9c", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 190 # Number of layers\n", - "ncol = 100 # Number of columns\n", - "nrow = 1 # Number of rows\n", - "delr = 0.06 # Column width ($m$)\n", - "delc = 1.0 # Row width ($m$)\n", - "delv = 0.03 # Layer thickness ($m$)\n", - "top = 0.0 # Top of the model ($m$)\n", - "strt = 0.0 # Starting head ($m$)\n", - "icelltype = 0 # Cell conversion type\n", - "hydraulic_conductivity = 1.0 # Horizontal hydraulic conductivity ($m/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "66bdd9ba", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation has 1 steady stress period (1 day)\n", - "and 3 transient stress periods (10 days each).\n", - "Each transient stress period has 120 2-hour time steps." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "49c6a9f7", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [1.0]\n", - "nstp = [1]\n", - "tsmult = [1.0]\n", - "tdis_ds = list(zip(perlen, nstp, tsmult))" - ] - }, - { - "cell_type": "markdown", - "id": "de270abb", - "metadata": {}, - "source": [ - "assign botm" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "82b3b769", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [top - k * delv for k in range(1, nlay + 1)]" - ] - }, - { - "cell_type": "markdown", - "id": "a2c8add1", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0eb818b6", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 50\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "c4ddcd0f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 SPBC model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9785f996", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " ihc, cl1, cl2, hwva = 1, delr / 2.0, delr / 2.0, delc\n", - " angldegx = 90.0\n", - " cdist = delr\n", - " exgdata = [\n", - " [(k, 0, 0), (k, 0, ncol - 1), ihc, cl1, cl2, hwva, angldegx, cdist]\n", - " for k in range(nlay)\n", - " ]\n", - " exg = flopy.mf6.ModflowGwfgwf(\n", - " sim,\n", - " exgtype=\"GWF6-GWF6\",\n", - " nexg=len(exgdata),\n", - " auxiliary=[\"ANGLDEGX\", \"CDIST\"],\n", - " exgmnamea=sim_name,\n", - " exgmnameb=sim_name,\n", - " exchangedata=exgdata,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=hydraulic_conductivity,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - "\n", - " hm = 1.0\n", - " lmbda = ncol * delr\n", - " wv = 2 * np.pi / lmbda\n", - " x = gwf.modelgrid.xcellcenters\n", - " chd_head = hm * np.sin(wv * x)\n", - " chd_spd = []\n", - " for j in range(ncol):\n", - " chd_spd.append([0, 0, j, chd_head[0, j]])\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chd_spd,\n", - " pname=\"CHD\",\n", - " )\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "22c3922f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 SPBC model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bfe607a5", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "a1c921a1", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the SPBC model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c92b3b14", - "metadata": {}, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=False):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1c6cef63", - "metadata": {}, - "outputs": [], - "source": [ - "# Function to plot the SPBC model results.\n", - "#\n", - "def plot_grid(sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " # create MODFLOW 6 head object\n", - " head = gwf.output.head().get_data()\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " gwf.output.budget().get_data(text=\"DATA-SPDIS\", totim=1.0)[0],\n", - " gwf,\n", - " )\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 0})\n", - " # pxs.plot_grid()\n", - " pxs.plot_bc(name=\"CHD\")\n", - " pxs.plot_array(head, cmap=\"jet\")\n", - " levels = np.arange(-1, 1, 0.1)\n", - " cs = pxs.contour_array(\n", - " head, levels=levels, colors=\"k\", linewidths=1.0, linestyles=\"-\"\n", - " )\n", - " pxs.plot_vector(qx, qy, qz, normalize=False, kstep=5, hstep=5)\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"z position (m)\")\n", - " ax.set_ylim(-3, 0)\n", - " fs.remove_edge_ticks(ax)\n", - " plt.clabel(cs, fmt=\"%3.1f\", fontsize=5)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c1e3d58a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " plot_grid(sim)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "f9c74ad8", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the SPBC model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e0f1cfbc", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " sim = build_model()\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c79f312f", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "a421a4ce", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ba13d58f", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### SPBC Simulation\n", - " #\n", - " # Model grid and simulation results\n", - "\n", - " simulation()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-twri.ipynb b/notebooks/ex-gwf-twri.ipynb deleted file mode 100644 index 5a708522..00000000 --- a/notebooks/ex-gwf-twri.ipynb +++ /dev/null @@ -1,878 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "9c67bf5e", - "metadata": {}, - "source": [ - "## Original TWRI MODFLOW example\n", - "\n", - "This problem is described in McDonald and Harbaugh (1988) and duplicated in\n", - "Harbaugh and McDonald (1996). This problem is also is distributed with\n", - "MODFLOW-2005 (Harbaugh, 2005) and MODFLOW 6 (Langevin and others, 2017).\n" - ] - }, - { - "cell_type": "markdown", - "id": "3c076f38", - "metadata": {}, - "source": [ - "### TWRI Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "622cfee3", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "26e48beb", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "d1b5c951", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "66e81f65", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "ed160c8d", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e348058", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "0b85c74b", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "113cde60", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 6)" - ] - }, - { - "cell_type": "markdown", - "id": "c850dea7", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "62ef7a88", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "577344bc", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a4964e52", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-twri01\"" - ] - }, - { - "cell_type": "markdown", - "id": "a545e2ab", - "metadata": {}, - "source": [ - "Scenario parameter units - make sure there is at least one blank line before next item\n", - "add parameter_units to add units to the scenario parameter table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7a923d3e", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_units = {\"recharge\": \"$ft/s$\"}" - ] - }, - { - "cell_type": "markdown", - "id": "92b9b16e", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c4cc62fe", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "5065a537", - "metadata": {}, - "source": [ - "Table TWRI Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ad270d07", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 5 # Number of layers\n", - "ncol = 15 # Number of columns\n", - "nrow = 15 # Number of rows\n", - "delr = 5000.0 # Column width ($ft$)\n", - "delc = 5000.0 # Row width ($ft$)\n", - "top = 200.0 # Top of the model ($ft$)\n", - "botm_str = \"-150.0, -200.0, -300.0, -350.0, -450.0\" # Layer bottom elevations ($ft$)\n", - "strt = 0.0 # Starting head ($ft$)\n", - "icelltype_str = \"1, 0, 0, 0, 0\" # Cell conversion type\n", - "k11_str = \"1.0e-3, 1.0e-8, 1.0e-4, 5.0e-7, 2.0e-4\" # Horizontal hydraulic conductivity ($ft/s$)\n", - "k33_str = (\n", - " \"1.0e-3, 1.0e-8, 1.0e-4, 5.0e-7, 2.0e-4\" # Vertical hydraulic conductivity ($ft/s$)\n", - ")\n", - "recharge = 3e-8 # Recharge rate ($ft/s$)" - ] - }, - { - "cell_type": "markdown", - "id": "6a235f5f", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5c0c6c86", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = 8.640e04\n", - "nstp = 1\n", - "tsmult = 1.0\n", - "tdis_ds = ((perlen, nstp, tsmult),)" - ] - }, - { - "cell_type": "markdown", - "id": "ba26090b", - "metadata": {}, - "source": [ - "parse parameter strings into tuples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b375448f", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]\n", - "k11 = [float(value) for value in k11_str.split(\",\")]\n", - "k33 = [float(value) for value in k33_str.split(\",\")]\n", - "icelltype = [int(value) for value in icelltype_str.split(\",\")]" - ] - }, - { - "cell_type": "markdown", - "id": "4e2e63e8", - "metadata": {}, - "source": [ - "### Create TWRI Model Boundary Conditions\n", - "\n", - "Constant head cells are specified on the west edge of the model\n", - "in model layers 1 and 2 `(k, i, j)` = $(1 \\rightarrow 2, 1 \\rightarrow 15, 1)$\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "99fe40e5", - "metadata": {}, - "outputs": [], - "source": [ - "chd_spd = []\n", - "for k in (0, 2):\n", - " chd_spd += [[k, i, 0, 0.0] for i in range(nrow)]\n", - "chd_spd = {0: chd_spd}" - ] - }, - { - "cell_type": "markdown", - "id": "58bd2b92", - "metadata": {}, - "source": [ - "Constant head cells for MODFLOW-2005 model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "12f0fcf7", - "metadata": {}, - "outputs": [], - "source": [ - "chd_spd0 = []\n", - "for k in (0, 1):\n", - " chd_spd0 += [[k, i, 0, 0.0, 0.0] for i in range(nrow)]\n", - "chd_spd0 = {0: chd_spd0}" - ] - }, - { - "cell_type": "markdown", - "id": "efca84b8", - "metadata": {}, - "source": [ - "Well boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7e0f9a91", - "metadata": {}, - "outputs": [], - "source": [ - "wel_spd = {\n", - " 0: [\n", - " [4, 4, 10, -5.0],\n", - " [2, 3, 5, -5.0],\n", - " [2, 5, 11, -5.0],\n", - " [0, 8, 7, -5.0],\n", - " [0, 8, 9, -5.0],\n", - " [0, 8, 11, -5.0],\n", - " [0, 8, 13, -5.0],\n", - " [0, 10, 7, -5.0],\n", - " [0, 10, 9, -5.0],\n", - " [0, 10, 11, -5.0],\n", - " [0, 10, 13, -5.0],\n", - " [0, 12, 7, -5.0],\n", - " [0, 12, 9, -5.0],\n", - " [0, 12, 11, -5.0],\n", - " [0, 12, 13, -5.0],\n", - " ]\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "20920993", - "metadata": {}, - "source": [ - "Well boundary conditions for MODFLOW-2005 model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "986fc3e4", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "wel_spd0 = []\n", - "layer_map = {0: 0, 2: 1, 4: 2}\n", - "for k, i, j, q in wel_spd[0]:\n", - " kk = layer_map[k]\n", - " wel_spd0.append([kk, i, j, q])\n", - "wel_spd0 = {0: wel_spd0}" - ] - }, - { - "cell_type": "markdown", - "id": "66afb49c", - "metadata": {}, - "source": [ - "Drain boundary conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cd8b6155", - "metadata": {}, - "outputs": [], - "source": [ - "drn_spd = {\n", - " 0: [\n", - " [0, 7, 1, 0.0, 1.0e0],\n", - " [0, 7, 2, 0.0, 1.0e0],\n", - " [0, 7, 3, 10.0, 1.0e0],\n", - " [0, 7, 4, 20.0, 1.0e0],\n", - " [0, 7, 5, 30.0, 1.0e0],\n", - " [0, 7, 6, 50.0, 1.0e0],\n", - " [0, 7, 7, 70.0, 1.0e0],\n", - " [0, 7, 8, 90.0, 1.0e0],\n", - " [0, 7, 9, 100.0, 1.0e0],\n", - " ]\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "bbdb3bf7", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "51350b71", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 50\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "9b7951f7", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 TWRI model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3e05f51b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " cvoptions=\"perched\",\n", - " perched=True,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chd_spd)\n", - " flopy.mf6.ModflowGwfdrn(gwf, stress_period_data=drn_spd)\n", - " flopy.mf6.ModflowGwfwel(gwf, stress_period_data=wel_spd)\n", - " flopy.mf6.ModflowGwfrcha(gwf, recharge=recharge)\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "5b2bb7c6", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "MODFLOW-2005 model object (mf) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "66ab86ea", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_mf5model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name, \"mf2005\")\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=sim_name, model_ws=sim_ws, exe_name=\"mf2005dbl\"\n", - " )\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=3,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " laycbd=[1, 1, 0],\n", - " top=top,\n", - " botm=botm,\n", - " nper=1,\n", - " perlen=perlen,\n", - " nstp=nstp,\n", - " tsmult=tsmult,\n", - " )\n", - " flopy.modflow.ModflowBas(mf, strt=strt)\n", - " flopy.modflow.ModflowLpf(\n", - " mf,\n", - " laytyp=[1, 0, 0],\n", - " hk=[k11[0], k11[2], k11[4]],\n", - " vka=[k11[0], k11[2], k11[4]],\n", - " vkcb=[k11[1], k11[3], 0],\n", - " ss=0,\n", - " sy=0.0,\n", - " )\n", - " flopy.modflow.ModflowChd(mf, stress_period_data=chd_spd0)\n", - " flopy.modflow.ModflowDrn(mf, stress_period_data=drn_spd)\n", - " flopy.modflow.ModflowWel(mf, stress_period_data=wel_spd0)\n", - " flopy.modflow.ModflowRch(mf, rech=recharge)\n", - " flopy.modflow.ModflowPcg(\n", - " mf, mxiter=nouter, iter1=ninner, hclose=hclose, rclose=rclose\n", - " )\n", - " oc = flopy.modflow.ModflowOc(\n", - " mf, stress_period_data={(0, 0): [\"save head\", \"save budget\"]}\n", - " )\n", - " oc.reset_budgetunit()\n", - " return mf\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "5b762162", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 TWRI model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a24234d2", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, mf, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)\n", - " mf.write_input()" - ] - }, - { - "cell_type": "markdown", - "id": "6af3bbc2", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the TWRI model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "59d1569a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, mf, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " else:\n", - " success, buff = mf.run_model(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "52f2ed58", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the TWRI model results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f2debda6", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, mf, silent=True):\n", - " if config.plotModel:\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj = gwf.output.head()\n", - "\n", - " # create MODFLOW-2005 head object\n", - " file_name = gwf.oc.head_filerecord.get_data()[0][0]\n", - " fpth = os.path.join(sim_ws, \"mf2005\", file_name)\n", - " hobj0 = flopy.utils.HeadFile(fpth)\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " cobj = gwf.output.budget()\n", - "\n", - " # create MODFLOW-2005 cell-by-cell budget object\n", - " file_name = gwf.oc.budget_filerecord.get_data()[0][0]\n", - " fpth = os.path.join(sim_ws, \"mf2005\", file_name)\n", - " cobj0 = flopy.utils.CellBudgetFile(fpth, precision=\"double\")\n", - "\n", - " # extract heads\n", - " head = hobj.get_data()\n", - " head0 = hobj0.get_data()\n", - " print(head0.shape)\n", - " vmin, vmax = -25, 100\n", - "\n", - " # check that the results are comparable\n", - " for idx, k in enumerate(\n", - " (\n", - " 0,\n", - " 2,\n", - " 4,\n", - " )\n", - " ):\n", - " diff = np.abs(head[k] - head0[idx])\n", - " msg = (\n", - " \"aquifer {}: \".format(idx + 1)\n", - " + f\"maximum absolute head difference is {diff.max()}\"\n", - " )\n", - " assert diff.max() < 0.05, msg\n", - " if not silent:\n", - " print(msg)\n", - "\n", - " # extract specific discharge\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " cobj.get_data(text=\"DATA-SPDIS\", kstpkper=(0, 0))[0],\n", - " gwf,\n", - " )\n", - " frf = cobj0.get_data(text=\"FLOW RIGHT FACE\", kstpkper=(0, 0))[0]\n", - " fff = cobj0.get_data(text=\"FLOW FRONT FACE\", kstpkper=(0, 0))[0]\n", - " flf = cobj0.get_data(text=\"FLOW LOWER FACE\", kstpkper=(0, 0))[0]\n", - " sqx, sqy, sqz = flopy.utils.postprocessing.get_specific_discharge(\n", - " (frf, fff, flf), mf, head0\n", - " )\n", - "\n", - " # modflow 6 layers to extract\n", - " layers_mf6 = [0, 2, 4]\n", - " titles = [\"Unconfined aquifer\", \"Middle aquifer\", \"Lower aquifer\"]\n", - "\n", - " # Create figure for simulation\n", - " extents = (0, ncol * delc, 0, nrow * delr)\n", - " fig, axes = plt.subplots(\n", - " 3,\n", - " 3,\n", - " figsize=figure_size,\n", - " dpi=300,\n", - " constrained_layout=True,\n", - " sharey=True,\n", - " )\n", - " for ax in axes.flatten():\n", - " ax.set_aspect(\"equal\")\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - "\n", - " for idx, ax in enumerate(axes.flatten()[:3]):\n", - " k = layers_mf6[idx]\n", - " fmp = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=k, extent=extents)\n", - " ax.get_xaxis().set_ticks([])\n", - " fmp.plot_grid(lw=0.5)\n", - " plot_obj = fmp.plot_array(head, vmin=vmin, vmax=vmax)\n", - " fmp.plot_bc(\"DRN\", color=\"green\")\n", - " fmp.plot_bc(\"WEL\", color=\"0.5\")\n", - " cv = fmp.contour_array(\n", - " head,\n", - " levels=[-25, 0, 25, 75, 100],\n", - " linewidths=0.5,\n", - " colors=\"black\",\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " fmp.plot_vector(qx, qy, normalize=True, color=\"0.75\")\n", - " title = titles[idx]\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title, ax=ax)\n", - "\n", - " for idx, ax in enumerate(axes.flatten()[3:6]):\n", - " fmp = flopy.plot.PlotMapView(model=mf, ax=ax, layer=idx, extent=extents)\n", - " fmp.plot_grid(lw=0.5)\n", - " plot_obj = fmp.plot_array(head0, vmin=vmin, vmax=vmax)\n", - " fmp.plot_bc(\"DRN\", color=\"green\")\n", - " fmp.plot_bc(\"WEL\", color=\"0.5\")\n", - " cv = fmp.contour_array(\n", - " head0,\n", - " levels=[-25, 0, 25, 75, 100],\n", - " linewidths=0.5,\n", - " colors=\"black\",\n", - " )\n", - " plt.clabel(cv, fmt=\"%1.0f\")\n", - " # fmp.plot_discharge(\n", - " # frf, fff, flf, head=head0, normalize=True, color=\"0.75\",\n", - " # )\n", - " fmp.plot_vector(sqx, sqy, normalize=True, color=\"0.75\")\n", - " title = titles[idx]\n", - " letter = chr(ord(\"@\") + idx + 4)\n", - " fs.heading(letter=letter, heading=title, ax=ax)\n", - "\n", - " # create legend\n", - " ax = plt.subplot(313)\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - "\n", - " # ax = axes.flatten()[-2]\n", - " ax.axis(\"off\")\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"green\",\n", - " mec=\"green\",\n", - " label=\"Drain\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"0.5\",\n", - " mec=\"0.5\",\n", - " label=\"Well\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"$\\u2192$\",\n", - " ms=10,\n", - " mfc=\"0.75\",\n", - " mec=\"0.75\",\n", - " label=\"Normalized specific discharge\",\n", - " )\n", - " ax.plot(-10000, -10000, lw=0.5, color=\"black\", label=r\"Head contour, $ft$\")\n", - " fs.graph_legend(ax, loc=\"upper center\")\n", - "\n", - " # plot colorbar\n", - " cax = plt.axes([0.325, 0.125, 0.35, 0.025])\n", - " cbar = plt.colorbar(plot_obj, shrink=0.8, orientation=\"horizontal\", cax=cax)\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Head, $ft$\", fontsize=9)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}{config.figure_ext}\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "bc874821", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the TWRI model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ec9bf32f", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(silent=True):\n", - " sim = build_model()\n", - " mf = build_mf5model()\n", - "\n", - " write_model(sim, mf, silent=silent)\n", - "\n", - " success = run_model(sim, mf, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(sim, mf, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "56befbb7", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "6eec2fa2", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3ecba0bc", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### TWRI Simulation\n", - " #\n", - " # Simulated heads in model the unconfined, middle, and lower aquifers (model layers\n", - " # 1, 3, and 5) are shown in the figure below. MODFLOW-2005 results for a quasi-3D\n", - " # model are also shown. The location of drain (green) and well (gray) boundary\n", - " # conditions, normalized specific discharge, and head contours (25 ft contour\n", - " # intervals) are also shown.\n", - "\n", - " simulation()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-u1disv.ipynb b/notebooks/ex-gwf-u1disv.ipynb deleted file mode 100644 index cf34be81..00000000 --- a/notebooks/ex-gwf-u1disv.ipynb +++ /dev/null @@ -1,659 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d32164ec", - "metadata": {}, - "source": [ - "## USG1DISV example\n", - "\n", - "This example shows how the MODFLOW 6 DISV Package can be used to simulate\n", - "a nested grid problem. The example corresponds to the first example\n", - "described in the MODFLOW-USG documentation. The problem is run without and\n", - "with the XT3D option of the NPF Package to improve the solution.\n" - ] - }, - { - "cell_type": "markdown", - "id": "e2c1d3a1", - "metadata": {}, - "source": [ - "### USG1DISV Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "55dea31b", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bff4b39f", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import flopy.utils.cvfdutil\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "a4ff2766", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eedec58c", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "da21b7aa", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a16d8cc8", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "e348cd15", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c72c8b03", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 6)" - ] - }, - { - "cell_type": "markdown", - "id": "898d3fb8", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6834e6fb", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "5c2a5144", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "74cd9cf5", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "3ce93751", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6f4baf5f", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-u1disv\": {\n", - " \"xt3d\": False,\n", - " },\n", - " \"ex-gwf-u1disv-x\": {\n", - " \"xt3d\": True,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "3325044d", - "metadata": {}, - "source": [ - "Table USG1DISV Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "38a14f93", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "top = 0.0 # Top of the model ($m$)\n", - "botm = -100.0 # Layer bottom elevations ($m$)\n", - "strt = 0.0 # Starting head ($m$)\n", - "icelltype = 0 # Cell conversion type\n", - "k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "4328be7d", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation has 1 steady stress period (1 day)\n", - "and 3 transient stress periods (10 days each).\n", - "Each transient stress period has 120 2-hour time steps." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a6f130d7", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [1.0]\n", - "nstp = [1]\n", - "tsmult = [1.0, 1.0, 1.0]\n", - "tdis_ds = list(zip(perlen, nstp, tsmult))" - ] - }, - { - "cell_type": "markdown", - "id": "57cf4549", - "metadata": {}, - "source": [ - "create the disv grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b3bf52ca", - "metadata": {}, - "outputs": [], - "source": [ - "# outer grid\n", - "nlay = 1\n", - "nrow = ncol = 7\n", - "delr = 100.0 * np.ones(ncol)\n", - "delc = 100.0 * np.ones(nrow)\n", - "tp = np.zeros((nrow, ncol))\n", - "bt = -100.0 * np.ones((nlay, nrow, ncol))\n", - "idomain = np.ones((nlay, nrow, ncol))\n", - "idomain[:, 2:5, 2:5] = 0\n", - "sg1 = flopy.discretization.StructuredGrid(\n", - " delr=delr, delc=delc, top=tp, botm=bt, idomain=idomain\n", - ")\n", - "# inner grid\n", - "nlay = 1\n", - "nrow = ncol = 9\n", - "delr = 100.0 / 3.0 * np.ones(ncol)\n", - "delc = 100.0 / 3.0 * np.ones(nrow)\n", - "tp = np.zeros((nrow, ncol))\n", - "bt = -100 * np.ones((nlay, nrow, ncol))\n", - "idomain = np.ones((nlay, nrow, ncol))\n", - "sg2 = flopy.discretization.StructuredGrid(\n", - " delr=delr,\n", - " delc=delc,\n", - " top=tp,\n", - " botm=bt,\n", - " xoff=200.0,\n", - " yoff=200,\n", - " idomain=idomain,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "03e983b9", - "metadata": {}, - "outputs": [], - "source": [ - "# get the disv grid arguments\n", - "gridprops = flopy.utils.cvfdutil.gridlist_to_disv_gridprops([sg1, sg2])" - ] - }, - { - "cell_type": "markdown", - "id": "96ed796f", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d9578292", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 50\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "b8e1c9b8", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 USG1DISV model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "743e863f", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, xt3d):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " linear_acceleration=\"bicgstab\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdisv(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " top=top,\n", - " botm=botm,\n", - " **gridprops,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " save_specific_discharge=True,\n", - " xt3doptions=xt3d,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - "\n", - " chd_spd = []\n", - " chd_spd += [[0, i, 1.0] for i in [0, 7, 14, 18, 22, 26, 33]]\n", - " chd_spd = {0: chd_spd}\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chd_spd,\n", - " pname=\"CHD-LEFT\",\n", - " filename=f\"{sim_name}.left.chd\",\n", - " )\n", - "\n", - " chd_spd = []\n", - " chd_spd += [[0, i, 0.0] for i in [6, 13, 17, 21, 25, 32, 39]]\n", - " chd_spd = {0: chd_spd}\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chd_spd,\n", - " pname=\"CHD-RIGHT\",\n", - " filename=f\"{sim_name}.right.chd\",\n", - " )\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - "\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "33d917a2", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 USG1DISV model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "288a0ee0", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "c2569469", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the FHB model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3b035558", - "metadata": {}, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=False):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "763c91d0", - "metadata": {}, - "outputs": [], - "source": [ - "# Function to plot the USG1DISV model results.\n", - "#\n", - "def plot_grid(idx, sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = list(parameters.keys())[idx]\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " pmv.plot_grid()\n", - " pmv.plot_bc(name=\"CHD-LEFT\", alpha=0.75)\n", - " pmv.plot_bc(name=\"CHD-RIGHT\", alpha=0.75)\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - " for i, (x, y) in enumerate(\n", - " zip(gwf.modelgrid.xcellcenters, gwf.modelgrid.ycellcenters)\n", - " ):\n", - " ax.text(\n", - " x,\n", - " y,\n", - " f\"{i + 1}\",\n", - " fontsize=6,\n", - " horizontalalignment=\"center\",\n", - " verticalalignment=\"center\",\n", - " )\n", - " v = gwf.disv.vertices.array\n", - " ax.plot(v[\"xv\"], v[\"yv\"], \"yo\")\n", - " for i in range(v.shape[0]):\n", - " x, y = v[\"xv\"][i], v[\"yv\"][i]\n", - " ax.text(\n", - " x,\n", - " y,\n", - " f\"{i + 1}\",\n", - " fontsize=5,\n", - " color=\"red\",\n", - " horizontalalignment=\"center\",\n", - " verticalalignment=\"center\",\n", - " )\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b9ef6825", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_head(idx, sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = list(parameters.keys())[idx]\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=(7.5, 5))\n", - " fig.tight_layout()\n", - "\n", - " head = gwf.output.head().get_data()[:, 0, :]\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " gwf.output.budget().get_data(text=\"DATA-SPDIS\", totim=1.0)[0],\n", - " gwf,\n", - " )\n", - "\n", - " ax = fig.add_subplot(1, 2, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " pmv.plot_grid()\n", - " cb = pmv.plot_array(head, cmap=\"jet\")\n", - " pmv.plot_vector(\n", - " qx,\n", - " qy,\n", - " normalize=False,\n", - " color=\"0.75\",\n", - " )\n", - " cbar = plt.colorbar(cb, shrink=0.25)\n", - " cbar.ax.set_xlabel(r\"Head, ($m$)\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - " fs.heading(ax, letter=\"A\", heading=\"Simulated Head\")\n", - "\n", - " ax = fig.add_subplot(1, 2, 2, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0)\n", - " pmv.plot_grid()\n", - " x = np.array(gwf.modelgrid.xcellcenters) - 50.0\n", - " slp = (1.0 - 0.0) / (50.0 - 650.0)\n", - " heada = slp * x + 1.0\n", - " cb = pmv.plot_array(head - heada, cmap=\"jet\")\n", - " cbar = plt.colorbar(cb, shrink=0.25)\n", - " cbar.ax.set_xlabel(r\"Error, ($m$)\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - " fs.heading(ax, letter=\"B\", heading=\"Error\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-head{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "79e500b6", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(idx, sim, silent=True):\n", - " if config.plotModel:\n", - " if idx == 0:\n", - " plot_grid(idx, sim)\n", - " plot_head(idx, sim)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "f3b09197", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the FHB model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0b63e3b1", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - " sim = build_model(key, **params)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(idx, sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "af642f7f", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5839db2b", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " simulation(1, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "609cd0b4", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "da4199b8", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### USG1DISV Simulation\n", - " #\n", - " # Simulated heads in the USG1DISV model without XT3D.\n", - "\n", - " simulation(0)\n", - "\n", - " # Simulated heads in the USG1DISV model with XT3D.\n", - "\n", - " simulation(1)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-u1gwfgwf.ipynb b/notebooks/ex-gwf-u1gwfgwf.ipynb deleted file mode 100644 index 8645af46..00000000 --- a/notebooks/ex-gwf-u1gwfgwf.ipynb +++ /dev/null @@ -1,942 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "8e712002", - "metadata": {}, - "source": [ - "## USG-ex1 with GWF-GWF Exchange and XT3D\n", - "\n", - "This example shows how the MODFLOW 6 GWF-GWF Exchange can be used to simulate\n", - "a nested grid problem. The example corresponds to the first example\n", - "described in the MODFLOW-USG documentation. Instead of the ghost node feature,\n", - "we use the XT3D option in the NPF package to improve the accuracy at the\n", - "interface between the models.\n", - "\n", - "The problem is run for three different scenarios:\n", - "\n", - "1. without XT3D enabled in the NPF package\n", - "2. with XT3D enabled in both models\n", - "3. with XT3D enabled in both models and at the interface\n", - "4. with XT3D enabled _only_ at the interface between the models\n", - "\n", - "### Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c4b63938", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cbae84d9", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from flopy.utils.lgrutil import Lgr\n", - "from matplotlib.colors import ListedColormap" - ] - }, - { - "cell_type": "markdown", - "id": "cb2b730f", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ee209db2", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "5e428063", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7ff3af73", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "767419f2", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0cef19d9", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (5, 5)\n", - "figure_size_double = (7, 3)" - ] - }, - { - "cell_type": "markdown", - "id": "1ad9fca1", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "713269b2", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "c5d53a81", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2e1a25ce", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "c5abee1a", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4f4d6d41", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-u1gwfgwf-s1\": {\n", - " \"XT3D_in_models\": False,\n", - " \"XT3D_at_exchange\": False,\n", - " },\n", - " \"ex-gwf-u1gwfgwf-s2\": {\n", - " \"XT3D_in_models\": True,\n", - " \"XT3D_at_exchange\": False,\n", - " },\n", - " \"ex-gwf-u1gwfgwf-s3\": {\n", - " \"XT3D_in_models\": True,\n", - " \"XT3D_at_exchange\": True,\n", - " },\n", - " \"ex-gwf-u1gwfgwf-s4\": {\n", - " \"XT3D_in_models\": False,\n", - " \"XT3D_at_exchange\": True,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "bf3cfac7", - "metadata": {}, - "source": [ - "Table with Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "16e86f22", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "top = 0.0 # Top of the model ($m$)\n", - "botm = -100.0 # Layer bottom elevations ($m$)\n", - "strt = 0.0 # Starting head ($m$)\n", - "h_left = 1.0 # Constant head boundary LEFT ($m$)\n", - "h_right = 0.0 # Constant head boundary RIGHT ($m$)\n", - "icelltype = 0 # Cell conversion type\n", - "k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "a7e3865b", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation has 1 steady stress period (1 day)\n", - "with 1 time step" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5e36bd91", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [1.0]\n", - "nstp = [1]\n", - "tsmult = [1.0, 1.0, 1.0]\n", - "tdis_ds = list(zip(perlen, nstp, tsmult))" - ] - }, - { - "cell_type": "markdown", - "id": "efeed491", - "metadata": {}, - "source": [ - "Coarse model grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "22aae35b", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 1\n", - "nrow = ncol = 7\n", - "delr = 100.0\n", - "delc = 100.0\n", - "tp = 0.0\n", - "bt = -100.0\n", - "idomain = np.ones((nlay, nrow, ncol))\n", - "idomain[:, 2:5, 2:5] = 0\n", - "gwfname_outer = \"outer\"" - ] - }, - { - "cell_type": "markdown", - "id": "7b49a2e7", - "metadata": {}, - "source": [ - "Refined model grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4f31c925", - "metadata": {}, - "outputs": [], - "source": [ - "rfct = 3\n", - "nrow_inner = ncol_inner = 9\n", - "delr_inner = 100.0 / rfct\n", - "delc_inner = 100.0 / rfct\n", - "idomain_inner = np.ones((nlay, nrow_inner, ncol_inner))\n", - "xorigin = 200.0\n", - "yorigin = 200.0\n", - "gwfname_inner = \"inner\"" - ] - }, - { - "cell_type": "markdown", - "id": "f9e05f92", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e5996c64", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter = 50\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "9da5ab89", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "42744437", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, XT3D_in_models, XT3D_at_exchange):\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " linear_acceleration=\"bicgstab\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - "\n", - " # The coarse, outer model\n", - " gwf_outer = flopy.mf6.ModflowGwf(sim, modelname=gwfname_outer, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf_outer,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " idomain=idomain,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf_outer,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " save_specific_discharge=True,\n", - " xt3doptions=XT3D_in_models,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf_outer, strt=strt)\n", - "\n", - " # constant head boundary LEFT\n", - " left_chd = [\n", - " [(ilay, irow, 0), h_left] for ilay in range(nlay) for irow in range(nrow)\n", - " ]\n", - " chd_spd = {0: left_chd}\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf_outer,\n", - " stress_period_data=chd_spd,\n", - " pname=\"CHD-LEFT\",\n", - " filename=f\"{gwfname_outer}.left.chd\",\n", - " )\n", - "\n", - " # constant head boundary RIGHT\n", - " right_chd = [\n", - " [(ilay, irow, ncol - 1), h_right]\n", - " for ilay in range(nlay)\n", - " for irow in range(nrow)\n", - " ]\n", - " chd_spd = {0: right_chd}\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf_outer,\n", - " stress_period_data=chd_spd,\n", - " pname=\"CHD-RIGHT\",\n", - " filename=f\"{gwfname_outer}.right.chd\",\n", - " )\n", - "\n", - " head_filerecord = f\"{gwfname_outer}.hds\"\n", - " budget_filerecord = f\"{gwfname_outer}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf_outer,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - "\n", - " # the refined, inner model\n", - " gwf_inner = flopy.mf6.ModflowGwf(sim, modelname=gwfname_inner, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf_inner,\n", - " nlay=nlay,\n", - " nrow=nrow_inner,\n", - " ncol=ncol_inner,\n", - " delr=delr_inner,\n", - " delc=delc_inner,\n", - " top=top,\n", - " botm=botm,\n", - " xorigin=xorigin,\n", - " yorigin=yorigin,\n", - " length_units=length_units,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf_inner, strt=strt)\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf_inner,\n", - " save_specific_discharge=True,\n", - " xt3doptions=XT3D_in_models,\n", - " save_flows=True,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " )\n", - "\n", - " head_filerecord = f\"{gwfname_inner}.hds\"\n", - " budget_filerecord = f\"{gwfname_inner}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf_inner,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - "\n", - " # Use Lgr to get the exchange data\n", - " nrowp = gwf_outer.dis.nrow.get_data()\n", - " ncolp = gwf_outer.dis.ncol.get_data()\n", - " delrp = gwf_outer.dis.delr.array\n", - " delcp = gwf_outer.dis.delc.array\n", - " topp = gwf_outer.dis.top.array\n", - " botmp = gwf_outer.dis.botm.array\n", - " idomainp = gwf_outer.dis.idomain.array\n", - "\n", - " lgr = Lgr(\n", - " nlay,\n", - " nrowp,\n", - " ncolp,\n", - " delrp,\n", - " delcp,\n", - " topp,\n", - " botmp,\n", - " idomainp,\n", - " ncpp=rfct,\n", - " ncppl=1,\n", - " )\n", - "\n", - " exgdata = lgr.get_exchange_data(angldegx=True, cdist=True)\n", - " for exg in exgdata:\n", - " l = exg\n", - " angle = l[-2]\n", - " if angle == 0:\n", - " bname = \"left\"\n", - " elif angle == 90.0:\n", - " bname = \"bottom\"\n", - " elif angle == 180.0:\n", - " bname = \"right\"\n", - " elif angle == 270.0:\n", - " bname = \"top\"\n", - " l.append(bname)\n", - "\n", - " # group exchanges based on boundname\n", - " exgdata.sort(key=lambda x: x[-3])\n", - "\n", - " flopy.mf6.ModflowGwfgwf(\n", - " sim,\n", - " exgtype=\"GWF6-GWF6\",\n", - " nexg=len(exgdata),\n", - " exgmnamea=gwfname_outer,\n", - " exgmnameb=gwfname_inner,\n", - " exchangedata=exgdata,\n", - " xt3d=XT3D_at_exchange,\n", - " print_input=True,\n", - " print_flows=True,\n", - " save_flows=True,\n", - " boundnames=True,\n", - " auxiliary=[\"ANGLDEGX\", \"CDIST\"],\n", - " )\n", - "\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "4a6b0d4b", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1844a75b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "38da08d5", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "94245f45", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=False):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "47d67cb4", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Functions to plot model results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "70f88c78", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_grid(idx, sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = list(parameters.keys())[idx]\n", - " gwf_outer = sim.get_model(gwfname_outer)\n", - " gwf_inner = sim.get_model(gwfname_inner)\n", - "\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf_outer, ax=ax, layer=0)\n", - " pmv_inner = flopy.plot.PlotMapView(model=gwf_inner, ax=ax, layer=0)\n", - "\n", - " pmv.plot_grid()\n", - " pmv_inner.plot_grid()\n", - "\n", - " pmv.plot_bc(name=\"CHD-LEFT\", alpha=0.75)\n", - " pmv.plot_bc(name=\"CHD-RIGHT\", alpha=0.75)\n", - "\n", - " ax.plot([200, 500, 500, 200, 200], [200, 200, 500, 500, 200], \"r--\", linewidth=2.0)\n", - "\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-grid{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "12906597", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_stencils(idx, sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = list(parameters.keys())[idx]\n", - " gwf_outer = sim.get_model(gwfname_outer)\n", - " gwf_inner = sim.get_model(gwfname_inner)\n", - "\n", - " fig = plt.figure(figsize=figure_size_double)\n", - " fig.tight_layout()\n", - "\n", - " # left plot, with stencils at the interface\n", - " ax = fig.add_subplot(1, 2, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf_outer, ax=ax, layer=0)\n", - " pmv_inner = flopy.plot.PlotMapView(\n", - " model=gwf_inner, ax=ax, layer=0, extent=pmv.extent\n", - " )\n", - " pmv.plot_grid()\n", - " pmv_inner.plot_grid()\n", - "\n", - " stencil = np.zeros(pmv.mg.shape, dtype=int)\n", - " stencil_inner = np.zeros(pmv_inner.mg.shape, dtype=int)\n", - "\n", - " # stencil 1\n", - " stencil[0, 0, 3] = 1\n", - " stencil[0, 1, 2] = 1\n", - " stencil[0, 1, 3] = 1\n", - " stencil[0, 1, 4] = 1\n", - " stencil_inner[0, 0, 3] = 1\n", - " stencil_inner[0, 0, 4] = 1\n", - " stencil_inner[0, 0, 5] = 1\n", - " stencil_inner[0, 1, 4] = 1\n", - "\n", - " # stencil 2\n", - " stencil[0, 4, 1] = 1\n", - " stencil[0, 5, 1] = 1\n", - " stencil[0, 5, 2] = 1\n", - " stencil[0, 5, 3] = 1\n", - " stencil[0, 6, 2] = 1\n", - " stencil_inner[0, 7, 0] = 1\n", - " stencil_inner[0, 8, 0] = 1\n", - " stencil_inner[0, 8, 1] = 1\n", - "\n", - " # markers\n", - " x = [350.0, 216.666]\n", - " y = [500.0, 200.0]\n", - "\n", - " stencil = np.ma.masked_equal(stencil, 0)\n", - " stencil_inner = np.ma.masked_equal(stencil_inner, 0)\n", - " cmap = ListedColormap([\"dodgerblue\"])\n", - " pmv.plot_array(stencil, cmap=cmap)\n", - " pmv_inner.plot_array(stencil_inner, cmap=cmap)\n", - " plt.scatter(x, y, facecolors=\"r\")\n", - "\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - "\n", - " # right plot, with stencils '1 connection away from the interface'\n", - " ax = fig.add_subplot(1, 2, 2, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf_outer, ax=ax, layer=0)\n", - " pmv_inner = flopy.plot.PlotMapView(\n", - " model=gwf_inner, ax=ax, layer=0, extent=pmv.extent\n", - " )\n", - " pmv.plot_grid()\n", - " pmv_inner.plot_grid()\n", - "\n", - " stencil = np.zeros(pmv.mg.shape, dtype=int)\n", - " stencil_inner = np.zeros(pmv_inner.mg.shape, dtype=int)\n", - "\n", - " # stencil 1\n", - " stencil[0, 0, 1] = 1\n", - " stencil[0, 1, 1] = 1\n", - " stencil[0, 1, 2] = 1\n", - " stencil[0, 1, 0] = 1\n", - " stencil[0, 2, 1] = 1\n", - " stencil[0, 2, 0] = 1\n", - " stencil[0, 3, 1] = 1\n", - " stencil_inner[0, 0, 0] = 1\n", - " stencil_inner[0, 1, 0] = 1\n", - " stencil_inner[0, 2, 0] = 1\n", - "\n", - " # stencil 2\n", - " stencil_inner[0, 6, 7] = 1\n", - " stencil_inner[0, 7, 6] = 1\n", - " stencil_inner[0, 7, 7] = 1\n", - " stencil_inner[0, 7, 8] = 1\n", - " stencil_inner[0, 8, 6] = 1\n", - " stencil_inner[0, 8, 7] = 1\n", - " stencil_inner[0, 8, 8] = 1\n", - " stencil[0, 5, 4] = 1\n", - "\n", - " # markers\n", - " x = [150.0, 450.0]\n", - " y = [500.0, 233.333]\n", - "\n", - " stencil = np.ma.masked_equal(stencil, 0)\n", - " stencil_inner = np.ma.masked_equal(stencil_inner, 0)\n", - " cmap = ListedColormap([\"dodgerblue\"])\n", - " pmv.plot_array(stencil, cmap=cmap)\n", - " pmv_inner.plot_array(stencil_inner, cmap=cmap)\n", - " plt.scatter(x, y, facecolors=\"r\")\n", - "\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-stencils{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2ade411b", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_head(idx, sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = list(parameters.keys())[idx]\n", - " gwf_outer = sim.get_model(gwfname_outer)\n", - " gwf_inner = sim.get_model(gwfname_inner)\n", - "\n", - " fig = plt.figure(figsize=figure_size_double)\n", - " fig.tight_layout()\n", - "\n", - " head = gwf_outer.output.head().get_data()[0]\n", - " head_inner = gwf_inner.output.head().get_data()[0]\n", - " head[head == 1e30] = np.nan\n", - " head_inner[head_inner == 1e30] = np.nan\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget objects\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " gwf_outer.output.budget().get_data(text=\"DATA-SPDIS\", totim=1.0)[0],\n", - " gwf_outer,\n", - " )\n", - " qx_inner, qy_inner, qz_inner = flopy.utils.postprocessing.get_specific_discharge(\n", - " gwf_inner.output.budget().get_data(text=\"DATA-SPDIS\", totim=1.0)[0],\n", - " gwf_inner,\n", - " )\n", - "\n", - " # create plot with head values and spdis\n", - " ax = fig.add_subplot(1, 2, 1, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf_outer, ax=ax, layer=0)\n", - " pmv_inner = flopy.plot.PlotMapView(\n", - " model=gwf_inner, ax=ax, layer=0, extent=pmv.extent\n", - " )\n", - " cb = pmv.plot_array(head, cmap=\"jet\", vmin=0.0, vmax=1.0)\n", - " cb = pmv_inner.plot_array(head_inner, cmap=\"jet\", vmin=0.0, vmax=1.0)\n", - " pmv.plot_grid()\n", - " pmv_inner.plot_grid()\n", - " pmv.plot_vector(\n", - " qx,\n", - " qy,\n", - " normalize=False,\n", - " color=\"0.75\",\n", - " )\n", - " pmv_inner.plot_vector(\n", - " qx_inner,\n", - " qy_inner,\n", - " normalize=False,\n", - " color=\"0.75\",\n", - " )\n", - " cbar = plt.colorbar(cb, shrink=0.25)\n", - " cbar.ax.set_xlabel(r\"Head, ($m$)\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - " fs.heading(ax, letter=\"A\", heading=\"Simulated Head\")\n", - "\n", - " # create plot with error in head\n", - " ax = fig.add_subplot(1, 2, 2, aspect=\"equal\")\n", - " pmv = flopy.plot.PlotMapView(model=gwf_outer, ax=ax, layer=0)\n", - " pmv_inner = flopy.plot.PlotMapView(\n", - " model=gwf_inner, ax=ax, layer=0, extent=pmv.extent\n", - " )\n", - " pmv.plot_grid()\n", - " pmv_inner.plot_grid()\n", - " x = np.array(gwf_outer.modelgrid.xcellcenters) - 50.0\n", - " x_inner = np.array(gwf_inner.modelgrid.xcellcenters) - 50.0\n", - " slp = (h_left - h_right) / (50.0 - 650.0)\n", - " head_exact = slp * x + h_left\n", - " head_exact_inner = slp * x_inner + h_left\n", - " err = head - head_exact\n", - " err_inner = head_inner - head_exact_inner\n", - " vmin = min(np.nanmin(err), np.nanmin(err_inner))\n", - " vmax = min(np.nanmax(err), np.nanmax(err_inner))\n", - " cb = pmv.plot_array(err, cmap=\"jet\", vmin=vmin, vmax=vmax)\n", - " cb = pmv_inner.plot_array(err_inner, cmap=\"jet\", vmin=vmin, vmax=vmax)\n", - "\n", - " cbar = plt.colorbar(cb, shrink=0.25)\n", - " cbar.ax.set_xlabel(r\"Error, ($m$)\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - " fs.heading(ax, letter=\"B\", heading=\"Error\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-head{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "02790070", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(idx, sim, silent=True):\n", - " if config.plotModel:\n", - " if idx == 0:\n", - " plot_grid(idx, sim)\n", - " plot_stencils(idx, sim)\n", - " plot_head(idx, sim)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "be490a7e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the FHB model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2353b47c", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - " sim = build_model(key, **params)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(idx, sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5e872a16", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5d1aab01", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " simulation(1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aa9328c6", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " simulation(2, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d2e0c073", - "metadata": {}, - "outputs": [], - "source": [ - "def test_04():\n", - " simulation(3, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "d7fa4632", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5ed62009", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### USG-ex1 GWF-GWF Exchange Simulation\n", - " #\n", - " # Simulated heads without XT3D.\n", - "\n", - " simulation(0)\n", - "\n", - " # Simulated heads with XT3D enabled globally, but not at the exchange\n", - "\n", - " simulation(1)\n", - "\n", - " # Simulated heads with XT3D enabled globally\n", - "\n", - " simulation(2)\n", - "\n", - " # Simulated heads with XT3D enabled _only_ at the model interface.\n", - "\n", - " simulation(3)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-whirl.ipynb b/notebooks/ex-gwf-whirl.ipynb deleted file mode 100644 index 47f6a3bc..00000000 --- a/notebooks/ex-gwf-whirl.ipynb +++ /dev/null @@ -1,510 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e6177858", - "metadata": {}, - "source": [ - "## Whirl example\n", - "\n", - "This is a 10 layer steady-state problem involving anisotropic groundwater\n", - "flow. The XT3D formulation is used to represent variable hydraulic\n", - "conductivitity ellipsoid orientations. The resulting flow pattern consists\n", - "of groundwater whirls, as described in the XT3D documentation report.\n" - ] - }, - { - "cell_type": "markdown", - "id": "a66e82bf", - "metadata": {}, - "source": [ - "### Whirl Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1ed490f5", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8396e2aa", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "46d64584", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "32e0ab80", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "8891246f", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2ab56a19", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "dfa0c576", - "metadata": {}, - "source": [ - "Set default figure properties" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "35b2b7e3", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (3.5, 3.5)" - ] - }, - { - "cell_type": "markdown", - "id": "9a45c4de", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f9f25a44", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-whirl\"\n", - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "cc245ce2", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8ba7345c", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "3fa6cde2", - "metadata": {}, - "source": [ - "Scenario parameters" - ] - }, - { - "cell_type": "markdown", - "id": "50b28730", - "metadata": {}, - "source": [ - "Table Whirl Model Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "11ffda67", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 10 # Number of layers\n", - "nrow = 10 # Number of rows\n", - "ncol = 51 # Number of columns\n", - "delr = 100.0 # Spacing along rows ($m$)\n", - "delc = 100.0 # Spacing along columns ($m$)\n", - "top = 0.0 # Top of the model ($m$)\n", - "botm_str = \"-100, -200, -300, -400, -500, -600, -700, -800, -900, -1000\" # Layer bottom elevations ($m$)\n", - "strt = 0.0 # Starting head ($m$)\n", - "icelltype = 0 # Cell conversion type\n", - "k11 = 1.0 # Hydraulic conductivity in the 11 direction ($m/d$)\n", - "k22 = 0.1 # Hydraulic conductivity in the 22 direction ($m/d$)\n", - "k33 = 1.0 # Hydraulic conductivity in the 33 direction ($m/d$)\n", - "angle1_str = \"45, 45, 45, 45, 45, -45, -45, -45, -45, -45\" # Rotation of the hydraulic conductivity ellipsoid in the x-y plane\n", - "inflow_rate = 0.01 # Inflow rate ($m^3/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "d5a565fe", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file\n", - "Simulation has 1 steady stress period (1 day)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eb369c7d", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [1.0]\n", - "nstp = [1]\n", - "tsmult = [1.0]\n", - "tdis_ds = list(zip(perlen, nstp, tsmult))" - ] - }, - { - "cell_type": "markdown", - "id": "73ae9db1", - "metadata": {}, - "source": [ - "Parse strings into lists" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "34520b1f", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [float(value) for value in botm_str.split(\",\")]\n", - "angle1 = [float(value) for value in angle1_str.split(\",\")]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f665a23e", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 50\n", - "ninner = 100\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "36e9cb49", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the MODFLOW 6 Whirl model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7a7b99e7", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model():\n", - " if config.buildModel:\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " linear_acceleration=\"bicgstab\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k22=k22,\n", - " k33=k33,\n", - " angle1=angle1,\n", - " save_specific_discharge=True,\n", - " xt3doptions=True,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " rate = np.zeros((nlay, nrow, ncol), dtype=float)\n", - " rate[:, :, 0] = inflow_rate\n", - " rate[:, :, -1] = -inflow_rate\n", - " wellay, welrow, welcol = np.where(rate != 0.0)\n", - " wel_spd = [\n", - " ((k, i, j), rate[k, i, j]) for k, i, j in zip(wellay, welrow, welcol)\n", - " ]\n", - " wel_spd = {0: wel_spd}\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " stress_period_data=wel_spd,\n", - " pname=\"WEL\",\n", - " )\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " budget_filerecord = f\"{sim_name}.cbc\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "d23dad6c", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write MODFLOW 6 Whirl model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3d84a5c3", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "f48adb3a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the FHB model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "553bcad6", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=False):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent, report=True)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "4bc9b62b", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the Whirl model results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7b1846f1", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_spdis(sim):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - "\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " # create MODFLOW 6 cell-by-cell budget object\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " gwf.output.budget().get_data(text=\"DATA-SPDIS\", totim=1.0)[0],\n", - " gwf,\n", - " )\n", - "\n", - " ax = fig.add_subplot(1, 1, 1)\n", - " pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"column\": 0})\n", - " pxs.plot_grid(linewidth=0.5)\n", - " pxs.plot_vector(qx, qy, qz, normalize=True)\n", - " ax.set_xlabel(\"y position (m)\")\n", - " ax.set_ylabel(\"z position (m)\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-spdis{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "12af4a3b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, silent=True):\n", - " if config.plotModel:\n", - " plot_spdis(sim)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "416a8836", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the FHB model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cd413a22", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " sim = build_model()\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9b9172ff", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "d61cc002", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8c4282f8", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Whirl Simulation\n", - " #\n", - " # Simulated heads in the Whirl model with anisotropy in x direction.\n", - "\n", - " simulation(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwf-zaidel.ipynb b/notebooks/ex-gwf-zaidel.ipynb deleted file mode 100644 index 684b16e4..00000000 --- a/notebooks/ex-gwf-zaidel.ipynb +++ /dev/null @@ -1,586 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "3c5a6931", - "metadata": {}, - "source": [ - "## Zaidel (2013) example\n", - "\n", - "This problem is described in Zaidel (2013) and represents a discontinuous\n", - "water table configuration over a stairway impervious base.\n" - ] - }, - { - "cell_type": "markdown", - "id": "fd0dfe99", - "metadata": {}, - "source": [ - "### Zaidel (2013) Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c3311472", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7d6a7fea", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "dfdc39f8", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "56276bae", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "b1ceea37", - "metadata": {}, - "source": [ - "import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3a7058b3", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "11eedf24", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ab689948", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6.3, 2.5)" - ] - }, - { - "cell_type": "markdown", - "id": "60550a7f", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "41a75280", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "3d856a96", - "metadata": {}, - "source": [ - "Simulation name" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cd4d5b92", - "metadata": {}, - "outputs": [], - "source": [ - "sim_name = \"ex-gwf-zaidel\"" - ] - }, - { - "cell_type": "markdown", - "id": "d7f93264", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2875163d", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"\n", - "# Scenario parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7ac75d70", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwf-zaidel-p01a\": {\n", - " \"H2\": 1.0,\n", - " },\n", - " \"ex-gwf-zaidel-p02a\": {\n", - " \"H2\": 10.0,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "f70c4dff", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "db630b55", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 200 # Number of columns\n", - "delr = 5.0 # Column width ($m$)\n", - "delc = 1.0 # Row width ($m$)\n", - "top = 25.0 # Top of the model ($m$)\n", - "strt = 23.0 # Starting head ($m$)\n", - "icelltype = 1 # Cell conversion type\n", - "k11 = 0.0001 # Horizontal hydraulic conductivity ($m/day$)\n", - "H1 = 23.0 # Constant head in column 1 ($m$)" - ] - }, - { - "cell_type": "markdown", - "id": "504f7661", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0b8a6b18", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_ds = ((1.0, 1, 1.0),)" - ] - }, - { - "cell_type": "markdown", - "id": "8de93f36", - "metadata": {}, - "source": [ - "Build stairway bottom" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "08bbcb3d", - "metadata": {}, - "outputs": [], - "source": [ - "botm = np.zeros((nlay, nrow, ncol), dtype=float)\n", - "base = 20.0\n", - "for j in range(ncol):\n", - " botm[0, :, j] = base\n", - " if j + 1 in (40, 80, 120, 160):\n", - " base -= 5" - ] - }, - { - "cell_type": "markdown", - "id": "b37e1ca2", - "metadata": {}, - "source": [ - "Solver parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "31fe359a", - "metadata": {}, - "outputs": [], - "source": [ - "nouter = 500\n", - "ninner = 50\n", - "hclose = 1e-9\n", - "rclose = 1e-6" - ] - }, - { - "cell_type": "markdown", - "id": "69af5fc9", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot the Zaidel model\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "df29a96f", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(H2=1.0):\n", - " if config.buildModel:\n", - " # Constant head cells are specified on the left and right edge of the model\n", - " chd_spd = [\n", - " [0, 0, 0, H1],\n", - " [0, 0, ncol - 1, H2],\n", - " ]\n", - "\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=sim_name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " linear_acceleration=\"bicgstab\",\n", - " outer_maximum=nouter,\n", - " outer_dvclose=hclose,\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=f\"{rclose} strict\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, newtonoptions=\"newton\")\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chd_spd)\n", - "\n", - " head_filerecord = f\"{sim_name}.hds\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\")],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "2de894f6", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write Zaidel model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "baa68ca7", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "c53f479a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the Zaidel model.\n", - "True is returned if the model runs successfully\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "01d6e18e", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - "\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "bda779e0", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the Zaidel model results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "992f4402", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(idx, sim, silent=True):\n", - " verbose = not silent\n", - " if config.plotModel:\n", - " fs = USGSFigure(figure_type=\"map\", verbose=verbose)\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(sim_name)\n", - " xedge = gwf.modelgrid.xvertices[0]\n", - " zedge = np.array([botm[0, 0, 0]] + botm.flatten().tolist())\n", - "\n", - " # create MODFLOW 6 head object\n", - " hobj = gwf.output.head()\n", - "\n", - " # extract heads\n", - " head = hobj.get_data()\n", - " vmin, vmax = 0, 25\n", - "\n", - " # Create figure for simulation\n", - " extents = (0, ncol * delr, -1, 25.0)\n", - " fig, ax = plt.subplots(\n", - " ncols=1,\n", - " nrows=1,\n", - " figsize=figure_size,\n", - " dpi=300,\n", - " constrained_layout=True,\n", - " sharey=True,\n", - " )\n", - "\n", - " ax.set_xlim(extents[:2])\n", - " ax.set_ylim(extents[2:])\n", - "\n", - " fmp = flopy.plot.PlotCrossSection(\n", - " model=gwf, ax=ax, extent=extents, line={\"row\": 0}\n", - " )\n", - " ax.fill_between(xedge, zedge, y2=-1, color=\"0.75\", step=\"pre\", lw=0.0)\n", - " plot_obj = fmp.plot_array(head, head=head, vmin=vmin, vmax=vmax)\n", - " fmp.plot_bc(\"CHD\", color=\"cyan\", head=head)\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " ax.set_ylabel(\"Elevation, in meters\")\n", - "\n", - " # create legend\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"cyan\",\n", - " mec=\"cyan\",\n", - " label=\"Constant Head\",\n", - " )\n", - " ax.plot(\n", - " -10000,\n", - " -10000,\n", - " lw=0,\n", - " marker=\"s\",\n", - " ms=10,\n", - " mfc=\"0.75\",\n", - " mec=\"0.75\",\n", - " label=\"Model Base\",\n", - " )\n", - " fs.graph_legend(ax, ncol=2, loc=\"upper right\")\n", - "\n", - " # plot colorbar\n", - " cax = plt.axes([0.62, 0.76, 0.325, 0.025])\n", - " cbar = plt.colorbar(plot_obj, shrink=0.8, orientation=\"horizontal\", cax=cax)\n", - " cbar.ax.tick_params(size=0)\n", - " cbar.ax.set_xlabel(r\"Head, $m$\", fontsize=9)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}-{idx + 1:02d}{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "871b8390", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for the TWRI model\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0065d4b2", - "metadata": {}, - "outputs": [], - "source": [ - "def simulation(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " params = parameters[key].copy()\n", - "\n", - " sim = build_model(**params)\n", - "\n", - " write_model(sim, silent=silent)\n", - "\n", - " success = run_model(sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(idx, sim, silent=silent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "83ab223a", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " simulation(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cdec902b", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " simulation(1, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "b6f1f02f", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0604e36f", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Zaidel Simulation\n", - " #\n", - " # Simulated heads in the Zaidel model with H2 = 1.\n", - "\n", - " simulation(0)\n", - "\n", - " # Simulated heads in the Zaidel model with H2 = 10.\n", - "\n", - " simulation(1)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-gwtgwt-p10.ipynb b/notebooks/ex-gwt-gwtgwt-p10.ipynb deleted file mode 100644 index ed6f9c03..00000000 --- a/notebooks/ex-gwt-gwtgwt-p10.ipynb +++ /dev/null @@ -1,1569 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "305635f2", - "metadata": {}, - "source": [ - "## Comparing MODFLOW 6 GWT-GWT to the single model results from MT3DMS problem 10\n", - "\n", - "The purpose of this example is to demonstrate the model setup for\n", - "a coupled GWF-GWT simulation with submodels. It replicates the\n", - "three-dimensional field case study model from the 1999 MT3DMS report.\n", - "The results are checked for equivalence with the MODFLOW 6 GWT\n", - "solutions as produced by the example 'MT3DMS problem 10'." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6ced9451", - "metadata": {}, - "outputs": [], - "source": [ - "import os" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c34cdc06", - "metadata": {}, - "outputs": [], - "source": [ - "# Imports and extend system path to include the common subdirectory\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f86855b8", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e5224bdd", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure\n", - "from flopy.utils.util_array import read1d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "77ba6305", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"" - ] - }, - { - "cell_type": "markdown", - "id": "67762032", - "metadata": {}, - "source": [ - "### Model Input Parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eec277fe", - "metadata": {}, - "outputs": [], - "source": [ - "# Set figure properties specific to this problem\n", - "figure_size = (6, 8)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c123766d", - "metadata": {}, - "outputs": [], - "source": [ - "# Base simulation and model name and workspace\n", - "ws = config.base_ws\n", - "example_name = \"ex-gwt-gwtgwt-mt3dms-p10\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "50a5b5d9", - "metadata": {}, - "outputs": [], - "source": [ - "# Model units\n", - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c5487b9", - "metadata": {}, - "outputs": [], - "source": [ - "# Note: the (relative) dimensions of the two models are not configurable\n", - "nlay = 4 # Number of layers\n", - "nlay_inn = 4 # Number of layers\n", - "nrow = 61 # Number of rows\n", - "nrow_inn = 45 # Number of rows inner model\n", - "ncol = 40 # Number of columns\n", - "ncol_inn = 28 # Number of columns inner model\n", - "delr = \"varies\" # Column width ($ft$)\n", - "delr_inn = 50 # Column width inner model ($ft$)\n", - "delc = \"varies\" # Row width ($ft$)\n", - "delc_inn = 50 # Row width inner model ($ft$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3e92c623", - "metadata": {}, - "outputs": [], - "source": [ - "xshift = 5100.0 # X offset inner model\n", - "yshift = 9100.0 # Y offset inner model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c4aaa2d", - "metadata": {}, - "outputs": [], - "source": [ - "delz = 25.0 # Layer thickness ($ft$)\n", - "top = 780.0 # Top of the model ($ft$)\n", - "satthk = 100.0 # Saturated thickness ($ft$)\n", - "k1 = 60.0 # Horiz. hyd. conductivity of layers 1 and 2 ($ft/day$)\n", - "k2 = 520.0 # Horiz. hyd. conductivity of layers 3 and 4 ($ft/day$)\n", - "vka = 0.1 # Ratio of vertical to horizontal hydraulic conductivity\n", - "rech = 5.0 # Recharge rate ($in/yr$)\n", - "crech = 0.0 # Concentration of recharge ($ppm$)\n", - "prsity = 0.3 # Porosity\n", - "al = 10.0 # Longitudinal dispersivity ($ft$)\n", - "trpt = 0.2 # Ratio of horizontal transverse dispersivity to longitudinal dispersivity\n", - "trpv = 0.2 # Ratio of vertical transverse dispersivity to longitudinal dispersivity\n", - "rhob = 1.7 # Aquifer bulk density ($g/cm^3$)\n", - "sp1 = 0.176 # Distribution coefficient ($cm^3/g$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "626b671c", - "metadata": {}, - "outputs": [], - "source": [ - "# Time discretization parameters\n", - "perlen = 1000.0 # Simulation time ($days$)\n", - "nstp = 500 # Number of time steps\n", - "ttsmult = 1.0 # multiplier" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a6f78fa2", - "metadata": {}, - "outputs": [], - "source": [ - "# Additional model input\n", - "delr = [2000, 1600, 800, 400, 200, 100] + 28 * [50] + [100, 200, 400, 800, 1600, 2000]\n", - "delc = (\n", - " [2000, 2000, 2000, 1600, 800, 400, 200, 100]\n", - " + 45 * [50]\n", - " + [100, 200, 400, 800, 1600, 2000, 2000, 2000]\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "93f2f454", - "metadata": {}, - "outputs": [], - "source": [ - "hk = [k1, k1, k2, k2]\n", - "laytyp = icelltype = 0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "40a2d776", - "metadata": {}, - "outputs": [], - "source": [ - "# Starting heads from file:\n", - "f = open(os.path.join(\"..\", \"data\", \"ex-gwt-mt3dms-p10\", \"p10shead.dat\"))\n", - "s0 = np.empty((nrow * ncol), dtype=float)\n", - "s0 = read1d(f, s0).reshape((nrow, ncol))\n", - "f.close()\n", - "strt = np.zeros((nlay, nrow, ncol), dtype=float)\n", - "for k in range(nlay):\n", - " strt[k] = s0\n", - "strt_inn = strt[:, 8:53, 6:34]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f804fece", - "metadata": {}, - "outputs": [], - "source": [ - "# Active model domain\n", - "idomain = np.ones((nlay, nrow, ncol), dtype=int)\n", - "idomain[:, 8:53, 6:34] = 0\n", - "idomain_inn = 1\n", - "icbund = idomain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c4d2e4e", - "metadata": {}, - "outputs": [], - "source": [ - "# Boundary conditions\n", - "rech = 12.7 / 365 / 30.48 # cm/yr -> ft/day\n", - "crch = 0.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6d05e751", - "metadata": {}, - "outputs": [], - "source": [ - "# MF6 pumping information for inner DIS\n", - "welspd_mf6 = []\n", - "# [(layer, row, column), flow, conc]\n", - "welspd_mf6.append([(3 - 1, 3 - 1, 23 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 11 - 1, 20 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 18 - 1, 17 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 25 - 1, 14 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 32 - 1, 11 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 40 - 1, 8 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 40 - 1, 3 - 1), -15384.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 44 - 1, 11 - 1), -17307.0, 0.00])\n", - "wel_mf6_spd = {0: welspd_mf6}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "66507be2", - "metadata": {}, - "outputs": [], - "source": [ - "# Transport related\n", - "# Starting concentrations from file:\n", - "f = open(os.path.join(\"..\", \"data\", \"ex-gwt-mt3dms-p10\", \"p10cinit.dat\"))\n", - "c0 = np.empty((nrow * ncol), dtype=float)\n", - "c0 = read1d(f, c0).reshape((nrow, ncol))\n", - "f.close()\n", - "sconc = np.zeros((nlay, nrow, ncol), dtype=float)\n", - "sconc[1] = 0.2 * c0\n", - "sconc[2] = c0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "85351b9c", - "metadata": {}, - "outputs": [], - "source": [ - "# starting concentration for inner model\n", - "sconc_inn = sconc[:, 8:53, 6:34]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "de6bc9bf", - "metadata": {}, - "outputs": [], - "source": [ - "# Dispersion\n", - "ath1 = al * trpt\n", - "atv = al * trpv\n", - "dmcoef = 0.0 # ft^2/day" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a1abbf30", - "metadata": {}, - "outputs": [], - "source": [ - "#\n", - "c0 = 0.0\n", - "botm = [top - delz * k for k in range(1, nlay + 1)]\n", - "mixelm = 0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9fe84528", - "metadata": {}, - "outputs": [], - "source": [ - "# Reactive transport related terms\n", - "isothm = 1 # sorption type; 1=linear isotherm (equilibrium controlled)\n", - "sp2 = 0.0 # w/ isothm = 1 this is read but not used\n", - "# ***Note: In the original documentation for this problem, the following two\n", - "# values are specified in units of g/cm^3 and cm^3/g, respectively.\n", - "# All other units in this problem appear to use ft, including the\n", - "# grid discretization, aquifer K (ft/day), recharge (ft/yr),\n", - "# pumping (ft^3/day), & dispersion (ft). Because this problem\n", - "# attempts to recreate the original problem for comparison purposes,\n", - "# we are sticking with these values while also acknowledging this\n", - "# discrepancy.\n", - "rhob = 1.7 # g/cm^3\n", - "sp1 = 0.176 # cm^3/g (Kd: \"Distribution coefficient\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "725447cd", - "metadata": {}, - "outputs": [], - "source": [ - "# Transport observations\n", - "# Instantiate the basic transport package for the inner model\n", - "obs = [\n", - " [3 - 1, 3 - 1, 23 - 1],\n", - " [3 - 1, 11 - 1, 20 - 1],\n", - " [3 - 1, 18 - 1, 17 - 1],\n", - " [3 - 1, 25 - 1, 14 - 1],\n", - " [3 - 1, 32 - 1, 11 - 1],\n", - " [3 - 1, 40 - 1, 8 - 1],\n", - " [3 - 1, 40 - 1, 3 - 1],\n", - " [3 - 1, 44 - 1, 11 - 1],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0af7660b", - "metadata": {}, - "outputs": [], - "source": [ - "# Solver settings\n", - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-6, 1e-6, 1.0\n", - "hclose_gwt, rclose_gwt = 1e-6, 1e-6\n", - "percel = 1.0 # HMOC parameters\n", - "itrack = 2\n", - "wd = 0.5\n", - "dceps = 1.0e-5\n", - "nplane = 0\n", - "npl = 0\n", - "nph = 16\n", - "npmin = 2\n", - "npmax = 32\n", - "dchmoc = 1.0e-3\n", - "nlsink = nplane\n", - "npsink = nph\n", - "nadvfd = 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9f26b467", - "metadata": {}, - "outputs": [], - "source": [ - "# Model names\n", - "gwfname_out = \"gwf-outer\"\n", - "gwfname_inn = \"gwf-inner\"\n", - "gwtname_out = \"gwt-outer\"\n", - "gwtname_inn = \"gwt-inner\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6d752c02", - "metadata": {}, - "outputs": [], - "source": [ - "# Exchange data for GWF-GWF and GWT-GWT\n", - "exgdata = None" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "044a2fd3", - "metadata": {}, - "outputs": [], - "source": [ - "# Advection\n", - "scheme = \"Undefined\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6298b73e", - "metadata": {}, - "outputs": [], - "source": [ - "# ### Build the MODFLOW 6 simulation\n", - "def build_model(sim_name):\n", - " if not config.buildModel:\n", - " return\n", - "\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name=mf6exe)\n", - "\n", - " # Instantiating time discretization\n", - " tdis_rc = [(perlen, nstp, 1.0)]\n", - " flopy.mf6.ModflowTdis(sim, nper=1, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # add both solutions to the simulation\n", - " add_flow(sim)\n", - " add_transport(sim)\n", - "\n", - " # add flow-transport coupling\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname_out,\n", - " exgmnameb=gwtname_out,\n", - " filename=\"{}.gwfgwt\".format(\"outer\"),\n", - " )\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname_inn,\n", - " exgmnameb=gwtname_inn,\n", - " filename=\"{}.gwfgwt\".format(\"inner\"),\n", - " )\n", - "\n", - " sim.write_simulation()\n", - "\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d002f68f", - "metadata": {}, - "outputs": [], - "source": [ - "# Function to add the two GWF models, and their exchange\n", - "def add_flow(sim):\n", - " global exgdata\n", - "\n", - " # Instantiating solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"CG\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=\"{}.ims\".format(\"gwfsolver\"),\n", - " )\n", - "\n", - " gwf_outer = add_outer_gwfmodel(sim)\n", - " gwf_inner = add_inner_gwfmodel(sim)\n", - "\n", - " sim.register_ims_package(imsgwf, [gwf_outer.name, gwf_inner.name])\n", - "\n", - " # LGR\n", - " exgdata = []\n", - " # east\n", - " for ilay in range(nlay):\n", - " for irow in range(nrow_inn):\n", - " irow_outer = irow + 8\n", - " exgdata.append(\n", - " ((ilay, irow_outer, 5), (ilay, irow, 0), 1, 50.0, 25.0, 50.0, 0.0, 75.0)\n", - " )\n", - " # west\n", - " for ilay in range(nlay):\n", - " for irow in range(nrow_inn):\n", - " irow_outer = irow + 8\n", - " exgdata.append(\n", - " (\n", - " (ilay, irow_outer, ncol - 6),\n", - " (ilay, irow, ncol_inn - 1),\n", - " 1,\n", - " 50.0,\n", - " 25.0,\n", - " 50.0,\n", - " 180.0,\n", - " 75.0,\n", - " )\n", - " )\n", - " # north\n", - " for ilay in range(nlay):\n", - " for icol in range(ncol_inn):\n", - " icol_outer = icol + 6\n", - " exgdata.append(\n", - " (\n", - " (ilay, 7, icol_outer),\n", - " (ilay, 0, icol),\n", - " 1,\n", - " 50.0,\n", - " 25.0,\n", - " 50.0,\n", - " 270.0,\n", - " 75.0,\n", - " )\n", - " )\n", - " # south\n", - " for ilay in range(nlay):\n", - " for icol in range(ncol_inn):\n", - " icol_outer = icol + 6\n", - " exgdata.append(\n", - " (\n", - " (ilay, nrow - 8, icol_outer),\n", - " (ilay, nrow_inn - 1, icol),\n", - " 1,\n", - " 50.0,\n", - " 25.0,\n", - " 50.0,\n", - " 90.0,\n", - " 75.0,\n", - " )\n", - " )\n", - "\n", - " gwfgwf = flopy.mf6.ModflowGwfgwf(\n", - " sim,\n", - " exgtype=\"GWF6-GWF6\",\n", - " nexg=len(exgdata),\n", - " exgmnamea=gwf_outer.name,\n", - " exgmnameb=gwf_inner.name,\n", - " exchangedata=exgdata,\n", - " xt3d=False,\n", - " print_flows=True,\n", - " auxiliary=[\"ANGLDEGX\", \"CDIST\"],\n", - " # dev_interfacemodel_on=True,\n", - " )\n", - "\n", - " # Observe flow for exchange 439\n", - " gwfgwfobs = {}\n", - " gwfgwfobs[\"gwfgwf.output.obs.csv\"] = [\n", - " [\"exchange439\", \"FLOW-JA-FACE\", (439 - 1,)],\n", - " ]\n", - " fname = \"gwfgwf.input.obs\"\n", - " # cdl -- turn off for now as it causes a flopy load fail\n", - " # gwfgwf.obs.initialize(\n", - " # filename=fname, digits=25, print_input=True, continuous=gwfgwfobs\n", - " # )" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9de74e36", - "metadata": {}, - "outputs": [], - "source": [ - "# Create the outer GWF model\n", - "def add_outer_gwfmodel(sim):\n", - " mname = gwfname_out\n", - "\n", - " # Instantiating groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=mname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{mname}.nam\",\n", - " )\n", - "\n", - " # Instantiating discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{mname}.dis\",\n", - " )\n", - "\n", - " # Instantiating initial conditions package for flow model\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{mname}.ic\")\n", - "\n", - " # Instantiating node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " k33overk=True,\n", - " icelltype=laytyp,\n", - " k=hk,\n", - " k33=vka,\n", - " save_specific_discharge=True,\n", - " filename=f\"{mname}.npf\",\n", - " )\n", - "\n", - " # Instantiate storage package\n", - " flopy.mf6.ModflowGwfsto(gwf, ss=0, sy=0, filename=f\"{mname}.sto\")\n", - "\n", - " # Instantiating constant head package\n", - " # MF6 constant head boundaries:\n", - " chdspd = []\n", - " # Loop through the left & right sides for all layers.\n", - " # These boundaries are imposed on the outer model.\n", - " for k in np.arange(nlay):\n", - " for i in np.arange(nrow):\n", - " # (l, r, c), head, conc\n", - " chdspd.append([(k, i, 0), strt[k, i, 0], 0.0]) # left\n", - " chdspd.append([(k, i, ncol - 1), strt[k, i, ncol - 1], 0.0]) # right\n", - "\n", - " for j in np.arange(1, ncol - 1): # skip corners, already added above\n", - " # (l, r, c), head, conc\n", - " chdspd.append([(k, 0, j), strt[k, 0, j], 0.0]) # top\n", - " chdspd.append([(k, nrow - 1, j), strt[k, nrow - 1, j], 0.0]) # bottom\n", - "\n", - " chdspd = {0: chdspd}\n", - "\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"CHD-1\",\n", - " filename=f\"{mname}.chd\",\n", - " )\n", - "\n", - " # Instantiate recharge package\n", - " flopy.mf6.ModflowGwfrcha(\n", - " gwf,\n", - " print_flows=True,\n", - " recharge=rech,\n", - " pname=\"RCH-1\",\n", - " filename=f\"{mname}.rch\",\n", - " )\n", - "\n", - " # Instantiating output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{mname}.hds\",\n", - " budget_filerecord=f\"{mname}.bud\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[\n", - " (\"HEAD\", \"LAST\"),\n", - " (\"HEAD\", \"STEPS\", \"1\", \"250\", \"375\", \"500\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " printrecord=[\n", - " (\"HEAD\", \"LAST\"),\n", - " (\"BUDGET\", \"FIRST\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " )\n", - "\n", - " return gwf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a6057d5f", - "metadata": {}, - "outputs": [], - "source": [ - "# Create the inner GWF model\n", - "def add_inner_gwfmodel(sim):\n", - " mname = gwfname_inn\n", - "\n", - " # Instantiating groundwater flow submodel\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=mname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{mname}.nam\",\n", - " )\n", - "\n", - " # Instantiating discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay_inn,\n", - " nrow=nrow_inn,\n", - " ncol=ncol_inn,\n", - " delr=delr_inn,\n", - " delc=delc_inn,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain_inn,\n", - " xorigin=xshift,\n", - " yorigin=yshift,\n", - " filename=f\"{mname}.dis\",\n", - " )\n", - "\n", - " # Instantiating initial conditions package for flow model\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt_inn, filename=f\"{mname}.ic\")\n", - "\n", - " # Instantiating node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " k33overk=True,\n", - " icelltype=laytyp,\n", - " k=hk,\n", - " k33=vka,\n", - " save_specific_discharge=True,\n", - " filename=f\"{mname}.npf\",\n", - " )\n", - "\n", - " # Instantiate storage package\n", - " flopy.mf6.ModflowGwfsto(gwf, ss=0, sy=0, filename=f\"{mname}.sto\")\n", - "\n", - " # Instantiate recharge package\n", - " flopy.mf6.ModflowGwfrcha(\n", - " gwf,\n", - " print_flows=True,\n", - " recharge=rech,\n", - " pname=\"RCH-1\",\n", - " filename=f\"{mname}.rch\",\n", - " )\n", - "\n", - " # Instantiate the wel package\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " print_input=True,\n", - " print_flows=True,\n", - " stress_period_data=wel_mf6_spd,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"WEL-1\",\n", - " filename=f\"{mname}.wel\",\n", - " )\n", - "\n", - " # Instantiating output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{mname}.hds\",\n", - " budget_filerecord=f\"{mname}.bud\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[\n", - " (\"HEAD\", \"LAST\"),\n", - " (\"HEAD\", \"STEPS\", \"1\", \"250\", \"375\", \"500\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " printrecord=[\n", - " (\"HEAD\", \"LAST\"),\n", - " (\"BUDGET\", \"FIRST\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " )\n", - "\n", - " return gwf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6b7d52f8", - "metadata": {}, - "outputs": [], - "source": [ - "# Function to add the transport models and exchange to the simulation\n", - "def add_transport(sim):\n", - " # Create iterative model solution\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose_gwt,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose_gwt,\n", - " rcloserecord=rclose_gwt,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=\"{}.ims\".format(\"gwtsolver\"),\n", - " )\n", - "\n", - " # Instantiating transport advection package\n", - " global scheme\n", - " if mixelm >= 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - "\n", - " # Add transport models\n", - " gwt_outer = add_outer_gwtmodel(sim)\n", - " gwt_inner = add_inner_gwtmodel(sim)\n", - "\n", - " sim.register_ims_package(imsgwt, [gwt_outer.name, gwt_inner.name])\n", - "\n", - " # Create transport-transport coupling\n", - " assert exgdata is not None\n", - " gwtgwt = flopy.mf6.ModflowGwtgwt(\n", - " sim,\n", - " exgtype=\"GWT6-GWT6\",\n", - " gwfmodelname1=gwfname_out,\n", - " gwfmodelname2=gwfname_inn,\n", - " adv_scheme=scheme,\n", - " nexg=len(exgdata),\n", - " exgmnamea=gwt_outer.name,\n", - " exgmnameb=gwt_inner.name,\n", - " exchangedata=exgdata,\n", - " auxiliary=[\"ANGLDEGX\", \"CDIST\"],\n", - " )\n", - "\n", - " # Observe mass flow for exchange 439\n", - " gwtgwtobs = {}\n", - " gwtgwtobs[\"gwtgwt.output.obs.csv\"] = [\n", - " [\"exchange439\", \"FLOW-JA-FACE\", (439 - 1,)],\n", - " ]\n", - " fname = \"gwtgwt.input.obs\"\n", - " # cdl -- turn off for now as it causes a flopy load fail\n", - " # gwtgwt.obs.initialize(\n", - " # filename=fname, digits=25, print_input=True, continuous=gwtgwtobs\n", - " # )\n", - "\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "10cbece0", - "metadata": {}, - "outputs": [], - "source": [ - "# Create the outer GWT model\n", - "def add_outer_gwtmodel(sim):\n", - " mname = gwtname_out\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=mname,\n", - " model_nam_file=f\"{mname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # Instantiating transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{mname}.dis\",\n", - " )\n", - "\n", - " # Instantiating transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{mname}.ic\")\n", - "\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{mname}.adv\")\n", - "\n", - " # Instantiating transport dispersion package\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=al,\n", - " ath1=ath1,\n", - " atv=atv,\n", - " pname=\"DSP-1\",\n", - " filename=f\"{mname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating transport mass storage package\n", - " kd = sp1\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=\"linear\",\n", - " bulk_density=rhob,\n", - " distcoef=kd,\n", - " pname=\"MST-1\",\n", - " filename=f\"{mname}.mst\",\n", - " )\n", - "\n", - " # Instantiating transport source-sink mixing package\n", - " sourcerecarray = [(\"CHD-1\", \"AUX\", \"CONCENTRATION\")]\n", - " flopy.mf6.ModflowGwtssm(\n", - " gwt,\n", - " sources=sourcerecarray,\n", - " print_flows=True,\n", - " filename=f\"{mname}.ssm\",\n", - " )\n", - "\n", - " # Instantiating transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{mname}.cbc\",\n", - " concentration_filerecord=f\"{mname}.ucn\",\n", - " concentrationprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[\n", - " (\"CONCENTRATION\", \"LAST\"),\n", - " (\"CONCENTRATION\", \"STEPS\", \"1\", \"250\", \"375\", \"500\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " filename=f\"{mname}.oc\",\n", - " )\n", - "\n", - " return gwt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "163e75f7", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "# Create the inner GWT model\n", - "def add_inner_gwtmodel(sim):\n", - " mname = gwtname_inn\n", - "\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=mname,\n", - " model_nam_file=f\"{mname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # Instantiating transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay_inn,\n", - " nrow=nrow_inn,\n", - " ncol=ncol_inn,\n", - " delr=delr_inn,\n", - " delc=delc_inn,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain_inn,\n", - " xorigin=xshift,\n", - " yorigin=yshift,\n", - " filename=f\"{mname}.dis\",\n", - " )\n", - "\n", - " # Instantiating transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc_inn, filename=f\"{mname}.ic\")\n", - "\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{mname}.adv\")\n", - "\n", - " # Instantiating transport dispersion package\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=al,\n", - " ath1=ath1,\n", - " atv=atv,\n", - " pname=\"DSP-1\",\n", - " filename=f\"{mname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating transport mass storage package\n", - " kd = sp1\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=\"linear\",\n", - " bulk_density=rhob,\n", - " distcoef=kd,\n", - " pname=\"MST-1\",\n", - " filename=f\"{mname}.mst\",\n", - " )\n", - "\n", - " # Instantiating transport source-sink mixing package\n", - " sourcerecarray = None\n", - " flopy.mf6.ModflowGwtssm(\n", - " gwt,\n", - " sources=sourcerecarray,\n", - " print_flows=True,\n", - " filename=f\"{mname}.ssm\",\n", - " )\n", - "\n", - " # Instantiating transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{mname}.cbc\",\n", - " concentration_filerecord=f\"{mname}.ucn\",\n", - " concentrationprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[\n", - " (\"CONCENTRATION\", \"LAST\"),\n", - " (\"CONCENTRATION\", \"STEPS\", \"1\", \"250\", \"375\", \"500\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " filename=f\"{mname}.oc\",\n", - " )\n", - "\n", - " return gwt" - ] - }, - { - "cell_type": "markdown", - "id": "f60c5f9d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Simulation Run and Results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0e752a53", - "metadata": {}, - "outputs": [], - "source": [ - "# Run the simulation and generate the results\n", - "def run_model(sim):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = sim.run_simulation()\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7f04bec1", - "metadata": {}, - "outputs": [], - "source": [ - "# Load MODFLOW 6 reference for the concentrations (GWT MT3DMS p10)\n", - "def get_reference_data_conc():\n", - " fpath = open(\n", - " os.path.join(\n", - " \"..\", \"data\", \"ex-gwt-gwtgwt-p10\", \"gwt-p10-mf6_conc_lay3_1days.txt\"\n", - " )\n", - " )\n", - " conc1 = np.loadtxt(fpath)\n", - " fpath = open(\n", - " os.path.join(\n", - " \"..\", \"data\", \"ex-gwt-gwtgwt-p10\", \"gwt-p10-mf6_conc_lay3_500days.txt\"\n", - " )\n", - " )\n", - " conc500 = np.loadtxt(fpath)\n", - " fpath = open(\n", - " os.path.join(\n", - " \"..\", \"data\", \"ex-gwt-gwtgwt-p10\", \"gwt-p10-mf6_conc_lay3_750days.txt\"\n", - " )\n", - " )\n", - " conc750 = np.loadtxt(fpath)\n", - " fpath = open(\n", - " os.path.join(\n", - " \"..\", \"data\", \"ex-gwt-gwtgwt-p10\", \"gwt-p10-mf6_conc_lay3_1000days.txt\"\n", - " )\n", - " )\n", - " conc1000 = np.loadtxt(fpath)\n", - "\n", - " return [conc1, conc500, conc750, conc1000]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef5aafc0", - "metadata": {}, - "outputs": [], - "source": [ - "# Load MODFLOW 6 reference for heads (GWT MT3DMS p10)\n", - "def get_reference_data_heads():\n", - " fpath = open(\n", - " os.path.join(\n", - " \"..\", \"data\", \"ex-gwt-gwtgwt-p10\", \"gwt-p10-mf6_head_lay3_1days.txt\"\n", - " )\n", - " )\n", - " head1 = np.loadtxt(fpath)\n", - " fpath = open(\n", - " os.path.join(\n", - " \"..\", \"data\", \"ex-gwt-gwtgwt-p10\", \"gwt-p10-mf6_head_lay3_500days.txt\"\n", - " )\n", - " )\n", - " head500 = np.loadtxt(fpath)\n", - " fpath = open(\n", - " os.path.join(\n", - " \"..\", \"data\", \"ex-gwt-gwtgwt-p10\", \"gwt-p10-mf6_head_lay3_750days.txt\"\n", - " )\n", - " )\n", - " head750 = np.loadtxt(fpath)\n", - " fpath = open(\n", - " os.path.join(\n", - " \"..\", \"data\", \"ex-gwt-gwtgwt-p10\", \"gwt-p10-mf6_head_lay3_1000days.txt\"\n", - " )\n", - " )\n", - " head1000 = np.loadtxt(fpath)\n", - "\n", - " return [head1, head500, head750, head1000]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "96f289b3", - "metadata": {}, - "outputs": [], - "source": [ - "# Plot the inner and outer grid\n", - "def plot_grids(sim):\n", - " xmin = xshift\n", - " ymin = yshift\n", - " xmax = xshift + 1400\n", - " ymax = yshift + 2250\n", - "\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " gwt_outer = sim.get_model(gwtname_out)\n", - " mm = flopy.plot.PlotMapView(model=gwt_outer)\n", - " mm.plot_grid(color=\"0.2\", alpha=0.7)\n", - " ax.plot(\n", - " [xmin, xmax, xmax, xmin, xmin],\n", - " [ymin, ymin, ymax, ymax, ymin],\n", - " \"r--\",\n", - " )\n", - " fpath = os.path.join(\"..\", \"figures\", \"ex-gwtgwt-p10-modelgrid.png\")\n", - " fig.savefig(fpath)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f9f30501", - "metadata": {}, - "outputs": [], - "source": [ - "# Plot the difference in concentration after 1,500,750,1000 days\n", - "# between this coupled model setup using a GWT-GWT exchange and the\n", - "# single model reference\n", - "def plot_difference_conc(sim):\n", - " conc_singlemodel_lay3 = get_reference_data_conc()\n", - "\n", - " # Get the concentration output\n", - " gwt_outer = sim.get_model(gwtname_out)\n", - " gwt = sim.get_model(gwtname_inn)\n", - "\n", - " ucnobj_mf6 = gwt.output.concentration()\n", - " conc_mf6 = ucnobj_mf6.get_alldata()\n", - " ucnobj_mf6_outer = gwt_outer.output.concentration()\n", - " conc_mf6_outer = ucnobj_mf6_outer.get_alldata()\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - "\n", - " # Difference in concentration @ 1 day\n", - " ax = fig.add_subplot(2, 2, 1, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwt_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " istep = 0\n", - " ilayer = 2\n", - " c_1day = conc_mf6_outer[istep]\n", - " c_1day[:, 8:53, 6:34] = conc_mf6[istep]\n", - " c_1day_singlemodel_lay3 = conc_singlemodel_lay3[istep]\n", - " pa = mm.plot_array(c_1day[ilayer] - c_1day_singlemodel_lay3)\n", - " xc, yc = gwt.modelgrid.xycenters\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.colorbar(pa, shrink=0.5)\n", - "\n", - " # Plot the wells as well\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Difference Layer 3 Time = 1 day\"\n", - " fs.heading(letter=\"A\", heading=title)\n", - "\n", - " # Difference in concentration @ 500 days\n", - " ax = fig.add_subplot(2, 2, 2, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwt_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " istep = 1\n", - " ilayer = 2\n", - " c_500days = conc_mf6_outer[istep]\n", - " c_500days[:, 8:53, 6:34] = conc_mf6[istep]\n", - " c_500days_singlemodel_lay3 = conc_singlemodel_lay3[istep]\n", - " pa = mm.plot_array(c_500days[ilayer] - c_500days_singlemodel_lay3)\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.colorbar(pa, shrink=0.5)\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Difference Layer 3 Time = 500 days\"\n", - " fs.heading(letter=\"B\", heading=title)\n", - "\n", - " # Difference in concentration @ 750 days\n", - " ax = fig.add_subplot(2, 2, 3, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwt_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " istep = 2\n", - " ilayer = 2\n", - " c_750days = conc_mf6_outer[istep]\n", - " c_750days[:, 8:53, 6:34] = conc_mf6[istep]\n", - " c_750days_singlemodel_lay3 = conc_singlemodel_lay3[istep]\n", - " pa = mm.plot_array(c_750days[ilayer] - c_750days_singlemodel_lay3)\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.colorbar(pa, shrink=0.5)\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Difference Layer 3 Time = 750 days\"\n", - " fs.heading(letter=\"C\", heading=title)\n", - "\n", - " # Difference in concentration @ 1000 days\n", - " ax = fig.add_subplot(2, 2, 4, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwt_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " istep = 3\n", - " ilayer = 2\n", - " c_1000days = conc_mf6_outer[istep]\n", - " c_1000days[:, 8:53, 6:34] = conc_mf6[istep]\n", - " c_1000days_singlemodel_lay3 = conc_singlemodel_lay3[istep]\n", - " pa = mm.plot_array(c_1000days[ilayer] - c_1000days_singlemodel_lay3)\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.colorbar(pa, shrink=0.5)\n", - "\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Difference Layer 3 Time = 1000 days\"\n", - " fs.heading(letter=\"D\", heading=title)\n", - "\n", - " fpath = os.path.join(\"..\", \"figures\", \"ex-gwtgwt-p10-diffconc.png\")\n", - " fig.savefig(fpath)\n", - "\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a8394d00", - "metadata": {}, - "outputs": [], - "source": [ - "# Plot the difference in head after 1,500,750,1000 days\n", - "# between this coupled model and the single model reference\n", - "def plot_difference_heads(sim):\n", - " head_singlemodel_lay3 = get_reference_data_heads()\n", - "\n", - " # Get the concentration output\n", - " gwf_outer = sim.get_model(gwfname_out)\n", - " gwf = sim.get_model(gwfname_inn)\n", - "\n", - " hobj_mf6 = gwf.output.head()\n", - " head_mf6 = hobj_mf6.get_alldata()\n", - " hobj_mf6_outer = gwf_outer.output.head()\n", - " head_mf6_outer = hobj_mf6_outer.get_alldata()\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - "\n", - " # Difference in heads @ 1 day\n", - " ax = fig.add_subplot(2, 2, 1, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwf_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " istep = 0\n", - " ilayer = 2\n", - " h_1day = head_mf6_outer[istep]\n", - " h_1day[:, 8:53, 6:34] = head_mf6[istep]\n", - " h_1day_singlemodel_lay3 = head_singlemodel_lay3[istep]\n", - " pa = mm.plot_array(h_1day[ilayer] - h_1day_singlemodel_lay3)\n", - " xc, yc = gwf.modelgrid.xycenters\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.colorbar(pa, shrink=0.5)\n", - "\n", - " # Plot the wells as well\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Difference Layer 3 Time = 1 day\"\n", - " fs.heading(letter=\"A\", heading=title)\n", - "\n", - " # Difference in heads @ 500 days\n", - " ax = fig.add_subplot(2, 2, 2, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwf_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " istep = 1\n", - " ilayer = 2\n", - " h_500days = head_mf6_outer[istep]\n", - " h_500days[:, 8:53, 6:34] = head_mf6[istep]\n", - " h_500days_singlemodel_lay3 = head_singlemodel_lay3[istep]\n", - " pa = mm.plot_array(h_500days[ilayer] - h_500days_singlemodel_lay3)\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.colorbar(pa, shrink=0.5)\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Difference Layer 3 Time = 500 days\"\n", - " fs.heading(letter=\"B\", heading=title)\n", - "\n", - " # Difference in heads @ 750 days\n", - " ax = fig.add_subplot(2, 2, 3, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwf_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " istep = 2\n", - " ilayer = 2\n", - " h_750days = head_mf6_outer[istep]\n", - " h_750days[:, 8:53, 6:34] = head_mf6[istep]\n", - " h_750days_singlemodel_lay3 = head_singlemodel_lay3[istep]\n", - " pa = mm.plot_array(h_750days[ilayer] - h_750days_singlemodel_lay3)\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.colorbar(pa, shrink=0.5)\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Difference Layer 3 Time = 750 days\"\n", - " fs.heading(letter=\"C\", heading=title)\n", - "\n", - " # Difference in heads @ 1000 days\n", - " ax = fig.add_subplot(2, 2, 4, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwf_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " istep = 3\n", - " ilayer = 2\n", - " h_1000days = head_mf6_outer[istep]\n", - " h_1000days[:, 8:53, 6:34] = head_mf6[istep]\n", - " h_1000days_singlemodel_lay3 = head_singlemodel_lay3[istep]\n", - " pa = mm.plot_array(h_1000days[ilayer] - h_1000days_singlemodel_lay3)\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.colorbar(pa, shrink=0.5)\n", - "\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Difference Layer 3 Time = 1000 days\"\n", - " fs.heading(letter=\"D\", heading=title)\n", - "\n", - " fpath = os.path.join(\"..\", \"figures\", \"ex-gwtgwt-p10-diffhead.png\")\n", - " fig.savefig(fpath)\n", - "\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "327c9619", - "metadata": {}, - "outputs": [], - "source": [ - "# Plot the concentration, this figure should be compared to the same figure in MT3DMS problem 10\n", - "def plot_concentration(sim):\n", - " # Get the concentration output\n", - " gwt_outer = sim.get_model(gwtname_out)\n", - " gwt = sim.get_model(gwtname_inn)\n", - "\n", - " ucnobj_mf6 = gwt.output.concentration()\n", - " conc_mf6 = ucnobj_mf6.get_alldata()\n", - " ucnobj_mf6_outer = gwt_outer.output.concentration()\n", - " conc_mf6_outer = ucnobj_mf6_outer.get_alldata()\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - "\n", - " xc, yc = gwt.modelgrid.xycenters\n", - "\n", - " # Plot init. concentration (lay=3)\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - "\n", - " ax = fig.add_subplot(2, 2, 1, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwt_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - "\n", - " cs = mm.contour_array(sconc[2], levels=np.arange(20, 200, 20))\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.clabel(cs, fmt=r\"%3d\")\n", - " # Plot the wells as well\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Layer 3 Initial Concentration\"\n", - " fs.heading(letter=\"A\", heading=title)\n", - "\n", - " ax = fig.add_subplot(2, 2, 2, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwt_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " c_500days = conc_mf6_outer[1]\n", - " c_500days[:, 8:53, 6:34] = conc_mf6[1] # Concentration @ 500 days\n", - " cs = mm.contour_array(c_500days[2], levels=np.arange(10, 200, 10))\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.clabel(cs, fmt=r\"%3d\")\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Layer 3 Time = 500 days\"\n", - " fs.heading(letter=\"B\", heading=title)\n", - "\n", - " ax = fig.add_subplot(2, 2, 3, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwt_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " c_750days = conc_mf6_outer[2]\n", - " c_750days[:, 8:53, 6:34] = conc_mf6[2] # Concentration @ 750 days\n", - " cs = mm.contour_array(c_750days[2], levels=np.arange(10, 200, 10))\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.clabel(cs, fmt=r\"%3d\")\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Layer 3 Time = 750 days\"\n", - " fs.heading(letter=\"C\", heading=title)\n", - "\n", - " ax = fig.add_subplot(2, 2, 4, aspect=\"equal\")\n", - " mm = flopy.plot.PlotMapView(model=gwt_outer)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " c_1000days = conc_mf6_outer[3]\n", - " c_1000days[:, 8:53, 6:34] = conc_mf6[3] # Concentration @ 1000 days\n", - " cs = mm.contour_array(c_1000days[2], levels=np.arange(10, 200, 10))\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.clabel(cs, fmt=r\"%3d\")\n", - " for cid, f, c in welspd_mf6:\n", - " plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], \"ks\")\n", - " title = \"Layer 3 Time = 1000 days\"\n", - " fs.heading(letter=\"D\", heading=title)\n", - "\n", - " fpath = os.path.join(\"..\", \"figures\", \"ex-gwtgwt-p10-concentration.png\")\n", - " fig.savefig(fpath)\n", - "\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "07338ba8", - "metadata": {}, - "outputs": [], - "source": [ - "# Generates all plots\n", - "def plot_results(sim):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " plot_grids(sim)\n", - " plot_concentration(sim)\n", - " plot_difference_conc(sim)\n", - " plot_difference_heads(sim)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2abd0a43", - "metadata": {}, - "outputs": [], - "source": [ - "def test_01():\n", - " sim = build_model(example_name)\n", - " run_model(sim)\n", - " plot_results(sim)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ad78e74f", - "metadata": {}, - "outputs": [], - "source": [ - "# Main\n", - "if __name__ == \"__main__\":\n", - " sim = build_model(example_name)\n", - " run_model(sim)\n", - " plot_results(sim)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-hecht-mendez.ipynb b/notebooks/ex-gwt-hecht-mendez.ipynb deleted file mode 100644 index 8749e444..00000000 --- a/notebooks/ex-gwt-hecht-mendez.ipynb +++ /dev/null @@ -1,1304 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "dd07cfae", - "metadata": {}, - "source": [ - "## Three-Dimensional Heat Transport Study\n", - "\n", - "The purpose of this script is to (1) recreate the 3D heat transport example\n", - "first published in Groundwater in 2010 titled, \"Evaluating MT3DMS for Heat\n", - "Transport Simulation of Closed Geothermal Systems,\" and (2) compare MF6-GWT\n", - "solutions to the published MT3DMS solution.\n", - "\n", - "Note: The original problem employed the FHB boundary package to specify\n", - " heads on the left and right boundaries. For this script, the same\n", - " boundary conditions are achieved using the specified head option\n", - " within the .bas package (specifies -1 for ibound which locks in the\n", - " starting heads and constant heads)\n", - "\n", - "Within the script that generates and runs the model, a user seeking to\n", - "compare MODFLOW results with MT3D-USGS may do so by setting the parameter\n", - "runMT3D equal to True on (or near). The correct line of script to adjust\n", - "will look similar to scenario(1, runMT3D=False, silent=False).\n", - "\n", - "For the first simulated scenario with a Peclet value of 1.0, simulated fits\n", - "to the analytical solution can be improved by refining the temporal\n", - "resolution of the simulation." - ] - }, - { - "cell_type": "markdown", - "id": "50d02c09", - "metadata": {}, - "source": [ - "### MODFLOW 6 GWT MT3DMS Heat Transport Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "cfc8920a", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "11f91b15", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "338dad4f", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "a88fbc7f", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "23209383", - "metadata": {}, - "outputs": [], - "source": [ - "import analytical\n", - "import config\n", - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure\n", - "from flopy.utils.util_array import read1d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "623c4fac", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dusgs\"" - ] - }, - { - "cell_type": "markdown", - "id": "6c29eb2b", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "27c52309", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (5.5, 2.75)" - ] - }, - { - "cell_type": "markdown", - "id": "66b22e4b", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bfb03a2c", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "name = \"hecht-mendez\"" - ] - }, - { - "cell_type": "markdown", - "id": "ca32ca80", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9b4f3086", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "e184bd10", - "metadata": {}, - "source": [ - "Set scenario parameters (make sure there is at least one blank line before next item)\n", - "This entire dictionary is passed to _build_model()_ using the kwargs argument" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f52396bd", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwt-hecht-mendez-a\": {\n", - " \"peclet\": 0.0,\n", - " \"gradient\": 0.0,\n", - " \"seepagevelocity\": 0.0,\n", - " \"constantheadright\": 14,\n", - " },\n", - " \"ex-gwt-hecht-mendez-b\": {\n", - " \"peclet\": 1.0,\n", - " \"gradient\": 1.2e-4,\n", - " \"seepagevelocity\": 3.7e-6,\n", - " \"constantheadright\": 13.964,\n", - " },\n", - " \"ex-gwt-hecht-mendez-c\": {\n", - " \"peclet\": 10.0,\n", - " \"gradient\": 1.2e-3,\n", - " \"seepagevelocity\": 3.7e-5,\n", - " \"constantheadright\": 13.64,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "ccb8c982", - "metadata": {}, - "source": [ - "Scenario parameter units\n", - "\n", - "add parameter_units to add units to the scenario parameter table that is automatically\n", - "built and used by the .tex input" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ac4d4719", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_units = {\n", - " \"peclet\": \"$unitless$\",\n", - " \"gradient\": \"$m/m$\",\n", - " \"seepagevelocity\": \"$m/s$\",\n", - " \"constantheadright\": \"$m$\",\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "8b686f35", - "metadata": {}, - "source": [ - "Table Flow and transport parameters used in Hecht-Mendez example" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "19229924", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 13 # Number of layers\n", - "nrow = 83 # Number of rows\n", - "ncol = 247 # Number of columns\n", - "delr = \"varies\" # Column width ($m$)\n", - "delc = \"varies\" # Row width ($m$)\n", - "width = 200 # Simulation width ($m$)\n", - "length = 300 # Simulation length ($m$)\n", - "delz = 1.0 # Layer thickness ($m$)\n", - "top = 13.0 # Top of the model ($m$)\n", - "satthk = 13.0 # Saturated thickness ($m$)\n", - "hk = 8.0e-3 # Horizontal hydraulic conductivity($m/s$)\n", - "vk = 8.0e-3 # Vertical hydraulic conductivity($m/s$)\n", - "T0 = 285.15 # Initial temperature of aquifer ($K$)\n", - "prsity = 0.26 # Porosity\n", - "al = 0.50 # Longitudinal dispersivity ($m$)\n", - "trpt = 0.1 # Ratio of horizontal transverse dispersivity to longitudinal dispersivity\n", - "trpv = 0.1 # Ratio of vertical transverse dispersivity to longitudinal dispersivity\n", - "rhob = 1961.0 # Aquifer bulk density ($kg/m^3$)\n", - "sp1 = 2.103e-4 # Distribution coefficient ($m^3/kg$)\n", - "perlen = 12960000.0 # Simulation time ($seconds$) (=~150 days)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a3f51176", - "metadata": {}, - "outputs": [], - "source": [ - "# Additional model input\n", - "delr = (\n", - " 3 * [10.0]\n", - " + 2 * [8.0]\n", - " + 2 * [4.0]\n", - " + 2 * [2.0]\n", - " + 4 * [1.0]\n", - " + 8 * [0.5]\n", - " + 1 * [0.1]\n", - " + 200 * [0.5]\n", - " + 10 * [1.0]\n", - " + 2 * [2.0]\n", - " + 2 * [4.0]\n", - " + 2 * [8.0]\n", - " + 8 * [10.0]\n", - " + 1 * [15.9]\n", - ")\n", - "delc = (\n", - " 6 * [10.0]\n", - " + 1 * [8.0]\n", - " + 2 * [4.0]\n", - " + 2 * [2.0]\n", - " + 10 * [1.0]\n", - " + 20 * [0.5]\n", - " + 1 * [0.1]\n", - " + 20 * [0.5]\n", - " + 10 * [1.0]\n", - " + 2 * [2.0]\n", - " + 2 * [4.0]\n", - " + 1 * [8.0]\n", - " + 6 * [10.0]\n", - ")\n", - "botm = [top - delz * k for k in range(1, nlay + 1)]\n", - "laytyp = icelltype = 0\n", - "# Starting Heads:\n", - "strt = np.ones((nlay, nrow, ncol), dtype=float) * 14.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "32d0d298", - "metadata": {}, - "outputs": [], - "source": [ - "# Active model domain\n", - "ibound = np.ones((nlay, nrow, ncol), dtype=int)\n", - "ibound[:, :, 0] = -1 # left side\n", - "ibound[:, :, -1] = -1 # right side" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c3970a3", - "metadata": {}, - "outputs": [], - "source": [ - "idomain = 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "38ed8299", - "metadata": {}, - "outputs": [], - "source": [ - "# Transport related\n", - "icbund = np.ones((nlay, nrow, ncol))\n", - "icbund[:, :, 0] = -1\n", - "# Starting concentrations:\n", - "sconc = T0\n", - "# Dispersion\n", - "ath1 = al * trpt\n", - "atv = al * trpv\n", - "dmcoef_arr = 1.84e-6 # m^2/s\n", - "# From the Hecht-Mendez manuscript:\n", - "# \"The 3D analytical solutions A4 and A5 consider a semi-infinite medium and\n", - "# therefore they neglect upgradient spreading. Accordingly, for consistency,\n", - "# thermal conductivity and dispersivity are set to zero in the area upgradient\n", - "# from the source in MT3DMS\"\n", - "# dmcoef_arr = np.ones((nlay, nrow, ncol)) * 1.84e-6 # m^2/s\n", - "# dmcoef_arr[:, 0:82, 0:21] = 0.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e66d0ec9", - "metadata": {}, - "outputs": [], - "source": [ - "# Time variables\n", - "nstp = 1\n", - "transport_stp_len = 60000 # seconds simulated per transport step (16.66 hr)\n", - "ttsmult = 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4534b425", - "metadata": {}, - "outputs": [], - "source": [ - "# Advection\n", - "mixelm = -1\n", - "percel = 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7dd1ad35", - "metadata": {}, - "outputs": [], - "source": [ - "# Boundary condition (BHE: \"Borehole Heat Exchanger\")\n", - "# Note: The manuscript is a bit different than the actual model input file. In\n", - "# the manuscript, it states, \"The BHE for the 3D scenarios is\n", - "# represented as [a] point source by three cells within the three middle\n", - "# layers (sixth, seventh, and eighth layers).\" However, the model input\n", - "# file that was obtained from Hecht-Mendez only included the 7th layer.\n", - "# So, for now, the script will mimic the original MT3DMS input and omit\n", - "# layers 6 and 8 as stated in the text.\n", - "ssm_bhe = [[7 - 1, 42 - 1, 22 - 1, -1.434e-5, 15]]\n", - "mf6_bhe = [[(7 - 1, 42 - 1, 22 - 1), -1.434e-5]]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3beed627", - "metadata": {}, - "outputs": [], - "source": [ - "# Reactive transport related terms\n", - "isothm = 1 # sorption type; 1=linear isotherm (equilibrium controlled)\n", - "sp2 = 2.0 # w/ isothm = 1 this is read but not used\n", - "rhob = 1.7 # g/cm^3\n", - "sp1 = 0.176 # cm^3/g (Kd: \"Distribution coefficient\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3452d84b", - "metadata": {}, - "outputs": [], - "source": [ - "# Transport observations\n", - "cobs = [(7 - 1, 42 - 1, k - 1) for k in range(22, 224, 2)]" - ] - }, - { - "cell_type": "markdown", - "id": "ec85c7d3", - "metadata": {}, - "source": [ - "Solver settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "57648887", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 5e-5, 1e-8, 1.0" - ] - }, - { - "cell_type": "markdown", - "id": "e635e134", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, and run models published in Hecht-Mendez 2010\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5e08c2b6", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_mf2k5_flow_model(\n", - " sim_name,\n", - " peclet=0.0,\n", - " gradient=0,\n", - " seepagevelocity=0,\n", - " constantheadright=14,\n", - " silent=False,\n", - "):\n", - " if config.buildModel:\n", - " print(f\"Building mf2005 model...{sim_name}\")\n", - " mt3d_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " modelname_mf = \"hecht-mendez\"\n", - "\n", - " # Instantiate the MODFLOW model\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=modelname_mf, model_ws=mt3d_ws, exe_name=exe_name_mf\n", - " )\n", - "\n", - " # Instantiate discretization package\n", - " # units: itmuni=4 (days), lenuni=2 (m)\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " perlen=perlen,\n", - " nstp=nstp,\n", - " itmuni=4,\n", - " lenuni=1,\n", - " steady=True,\n", - " )\n", - "\n", - " # Instantiate basic package\n", - " strt[:, :, -1] = constantheadright\n", - " flopy.modflow.ModflowBas(mf, ibound=ibound, strt=strt)\n", - "\n", - " # Instantiate layer property flow package\n", - " flopy.modflow.ModflowLpf(mf, hk=hk, layvka=0, vka=vk, laytyp=laytyp)\n", - "\n", - " # Instantiate solver package\n", - " flopy.modflow.ModflowPcg(\n", - " mf,\n", - " mxiter=90,\n", - " iter1=20,\n", - " npcond=1,\n", - " hclose=hclose,\n", - " rclose=rclose,\n", - " relax=relax,\n", - " nbpol=2,\n", - " iprpcg=2,\n", - " mutpcg=0.0,\n", - " )\n", - "\n", - " # Instantiate link mass transport package (for writing linker file)\n", - " flopy.modflow.ModflowLmt(mf)\n", - "\n", - " # Instantiate output control (OC) package\n", - " spd = {\n", - " (0, 0): [\"save head\"],\n", - " }\n", - " oc = flopy.modflow.ModflowOc(mf, stress_period_data=spd)\n", - "\n", - " return mf\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "b09cfc4a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "MODFLOW 6" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "32e34bc7", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6_flow_model(\n", - " sim_name,\n", - " peclet=0.0,\n", - " gradient=0,\n", - " seepagevelocity=0,\n", - " constantheadright=14,\n", - " silent=False,\n", - "):\n", - " if config.buildModel:\n", - " print(f\"Building mf6gwf model...{sim_name}\")\n", - " gwfname = \"gwf-\" + name\n", - " sim_ws = os.path.join(ws, sim_name, \"mf6gwf\")\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=gwfname, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " tdis_rc.append((perlen, 1, 1.0))\n", - " flopy.mf6.ModflowTdis(sim, nper=1, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"CG\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " strt[:, :, -1] = constantheadright\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=True,\n", - " k33overk=False,\n", - " icelltype=laytyp,\n", - " k=hk,\n", - " k33=vk,\n", - " save_specific_discharge=True,\n", - " save_saturation=True,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiate storage package\n", - " flopy.mf6.ModflowGwfsto(gwf, ss=0, sy=0, filename=f\"{gwfname}.sto\")\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " # MF6 constant head boundaries:\n", - " chdspd = []\n", - " # Loop through the left & right sides for all layers.\n", - " for k in range(nlay):\n", - " for i in range(nrow):\n", - " # left-most column:\n", - " # (l, r, c), head, conc\n", - " chdspd.append([(k, i, 0), strt[k, i, 0], T0]) # left\n", - " # right-most column:\n", - " chdspd.append([(k, i, ncol - 1), strt[k, i, ncol - 1], T0])\n", - "\n", - " chdspd = {0: chdspd}\n", - "\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[\n", - " (\"HEAD\", \"LAST\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " printrecord=[\n", - " (\"HEAD\", \"LAST\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " )\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c4ffbb8d", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mt3d_transport_model(\n", - " mf,\n", - " sim_name,\n", - " peclet=0.0,\n", - " gradient=0,\n", - " seepagevelocity=0,\n", - " constantheadright=14,\n", - " silent=False,\n", - "):\n", - " if config.buildModel:\n", - " # Transport\n", - " print(f\"Building mt3dms model...{sim_name}\")\n", - "\n", - " modelname_mt = \"hecht-mendez_mt\"\n", - " mt3d_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=modelname_mt,\n", - " model_ws=mt3d_ws,\n", - " exe_name=exe_name_mt,\n", - " modflowmodel=mf,\n", - " )\n", - "\n", - " # Instantiate basic transport package\n", - " if seepagevelocity == 0:\n", - " dt0 = 50000\n", - " else:\n", - " dt0 = 0.0\n", - "\n", - " flopy.mt3d.Mt3dBtn(\n", - " mt,\n", - " icbund=icbund,\n", - " prsity=prsity,\n", - " sconc=sconc,\n", - " cinact=-1e10,\n", - " thkmin=0.01,\n", - " ifmtcn=-2,\n", - " nprs=2,\n", - " timprs=[864000, 12960000], # 10, 150 days\n", - " dt0=dt0,\n", - " obs=cobs,\n", - " chkmas=False,\n", - " perlen=perlen,\n", - " nstp=nstp,\n", - " tsmult=ttsmult,\n", - " mxstrn=20000,\n", - " )\n", - "\n", - " # Instatiate the advection package\n", - " flopy.mt3d.Mt3dAdv(mt, mixelm=mixelm, percel=percel)\n", - "\n", - " # Instantiate the dispersion package\n", - " flopy.mt3d.Mt3dDsp(\n", - " mt, multiDiff=True, al=al, trpt=trpt, trpv=trpv, dmcoef=dmcoef_arr\n", - " )\n", - "\n", - " # Instantiate the source/sink mixing package\n", - " ssmspd = {0: ssm_bhe}\n", - " flopy.mt3d.Mt3dSsm(\n", - " mt, mxss=nrow * ncol * 2 + len(ssm_bhe), stress_period_data=ssmspd\n", - " )\n", - "\n", - " # Instantiate the reaction package\n", - " flopy.mt3d.Mt3dRct(mt, isothm=isothm, igetsc=0, rhob=rhob, sp1=sp1, sp2=sp2)\n", - "\n", - " # Instantiate the GCG solver in MT3DMS\n", - " flopy.mt3d.Mt3dGcg(mt, mxiter=100, iter1=50, isolve=1, ncrs=1, cclose=1e-7)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "adf762c8", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_mf6_transport_model(\n", - " sim_name,\n", - " peclet=0.0,\n", - " gradient=0,\n", - " seepagevelocity=0,\n", - " constantheadright=14,\n", - " silent=False,\n", - "):\n", - " if config.buildModel:\n", - " # Instantiating MODFLOW 6 groundwater transport package\n", - " print(f\"Building mf6gwt model...{sim_name}\")\n", - " gwtname = \"gwt-\" + name\n", - " sim_ws = os.path.join(ws, sim_name, \"mf6gwt\")\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=gwtname, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - "\n", - " # MF6 time discretization is a bit different than corresponding flow simulation\n", - " tdis_rc = None\n", - " if peclet == 1.0:\n", - " # use tsmult to and hardwired number of steps to make it run fast\n", - " tdis_rc = [(perlen, 25, 1.3)]\n", - " elif peclet == 10.0:\n", - " transport_stp_len = 1.296e5 * 3\n", - " nstp_transport = perlen / transport_stp_len\n", - " tdis_rc = [(perlen, nstp_transport, 1.0)]\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=len(tdis_rc), perioddata=tdis_rc, time_units=time_units\n", - " )\n", - "\n", - " gwtname = \"gwt-\" + name\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=gwtname,\n", - " model_nam_file=f\"{gwtname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # create iterative model solution and register the gwt model with it\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwtname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - "\n", - " # Instantiating MODFLOW 6 transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwtname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{gwtname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 transport advection package\n", - " if mixelm >= 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{gwtname}.adv\")\n", - "\n", - " # Instantiating MODFLOW 6 transport dispersion package\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=al,\n", - " ath1=ath1,\n", - " atv=atv,\n", - " diffc=dmcoef_arr,\n", - " pname=\"DSP-1\",\n", - " filename=f\"{gwtname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport mass storage package\n", - " Kd = sp1\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=\"linear\",\n", - " bulk_density=rhob,\n", - " distcoef=Kd,\n", - " pname=\"MST-1\",\n", - " filename=f\"{gwtname}.mst\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport source-sink mixing package\n", - " sourcerecarray = [(\"CHD-1\", \"AUX\", \"CONCENTRATION\")]\n", - " flopy.mf6.ModflowGwtssm(\n", - " gwt,\n", - " sources=sourcerecarray,\n", - " print_flows=True,\n", - " filename=f\"{gwtname}.ssm\",\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwtsrc(\n", - " gwt,\n", - " print_flows=True,\n", - " maxbound=len(mf6_bhe),\n", - " stress_period_data={0: mf6_bhe},\n", - " pname=\"SRC-1\",\n", - " filename=f\"{gwtname}.src\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 Flow-Model Interface package\n", - " flow_name = gwtname.replace(\"gwt\", \"gwf\")\n", - " pd = [\n", - " (\"GWFHEAD\", \"../mf6gwf/\" + flow_name + \".hds\", None),\n", - " (\"GWFBUDGET\", \"../mf6gwf/\" + flow_name + \".bud\", None),\n", - " ]\n", - " flopy.mf6.ModflowGwtfmi(gwt, packagedata=pd)\n", - "\n", - " # Instantiating MODFLOW 6 transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwtname}.cbc\",\n", - " concentration_filerecord=f\"{gwtname}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[\n", - " (\"CONCENTRATION\", \"LAST\"),\n", - " (\"CONCENTRATION\", \"STEPS\", \"15\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " filename=f\"{gwtname}.oc\",\n", - " )\n", - "\n", - " return sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "e21f02cd", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "90ddf0cd", - "metadata": {}, - "outputs": [], - "source": [ - "def write_mf2k5_models(mf2k5, mt3d, silent=True):\n", - " if config.writeModel:\n", - " mf2k5.write_input()\n", - " mt3d.write_input()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "412e0669", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_mf6_models(sim_mf6gwf, sim_mf6gwt, silent=True):\n", - " if config.writeModel:\n", - " sim_mf6gwf.write_simulation(silent=silent)\n", - " sim_mf6gwt.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "7b95a6a7", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4be829bc", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim_mf6gwf, sim_mf6gwt, mf2k5=None, mt3d=None, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " if mf2k5 is not None:\n", - " success, buff = mf2k5.run_model(silent=silent)\n", - "\n", - " if mt3d is not None:\n", - " success, buff = mt3d.run_model(silent=silent)\n", - "\n", - " success, buff = sim_mf6gwf.run_simulation(silent=silent)\n", - " success, buff = sim_mf6gwt.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "abdf64a3", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "36dde588", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(\n", - " sim_mf6gwf,\n", - " sim_mf6gwt,\n", - " idx,\n", - " mf2k5=None,\n", - " mt3d=None,\n", - " ax=None,\n", - " peclet=0.0,\n", - " gradient=0,\n", - " seepagevelocity=0,\n", - " constantheadright=14,\n", - "):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " if mt3d is not None:\n", - " mt3d_out_path = mt3d.model_ws\n", - "\n", - " # Get the MT3DMS concentration output\n", - " fname_mt3d = os.path.join(mt3d_out_path, \"MT3D001.UCN\")\n", - " ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d)\n", - " times_mt3d = ucnobj_mt3d.get_times()\n", - " conc_mt3d = ucnobj_mt3d.get_alldata()\n", - "\n", - " mf6_out_path = sim_mf6gwt.simulation_data.mfpath.get_sim_path()\n", - "\n", - " # Get the MF6 concentration output\n", - " gwt = sim_mf6gwt.get_model(\"gwt-\" + name)\n", - " ucnobj_mf6 = gwt.output.concentration()\n", - "\n", - " times_mf6 = ucnobj_mf6.get_times()\n", - " conc_mf6 = ucnobj_mf6.get_alldata()\n", - "\n", - " # Get the x location of the cell centroids\n", - " model_centroids_x = []\n", - " for i, (cum_pos, half_width) in enumerate(\n", - " zip(np.cumsum(delr), np.divide(delr, 2))\n", - " ):\n", - " if i > 0:\n", - " model_centroids_x.append(cum_pos - half_width)\n", - " else:\n", - " model_centroids_x.append(half_width)\n", - "\n", - " # Next subtract off the location of the BHE\n", - " model_centroids_x_BHE = [\n", - " val - model_centroids_x[21] for val in model_centroids_x\n", - " ]\n", - " # Drop the negative locations to the left of the BHE\n", - " model_centroids_x_right_of_BHE = model_centroids_x_BHE[22:] # Does not include\n", - "\n", - " # Analytical solution(s)\n", - " To = T0 # deg K (initial temperature of the ground)\n", - " Y3d = 0.1 # m\n", - " Z3d = delz # m\n", - " ath = al * trpt # m\n", - " atv = al * trpv # m\n", - " F0 = -60 # W/m\n", - " Fplanar = -600 # W/m^2\n", - " va = seepagevelocity\n", - " n = prsity # porosity\n", - " rhow = 1000.0 # density of water\n", - " cw = 4185.0 # heat capacity of water\n", - " thermdiff = 1.86e-6 # \"molecular diffusion\" representing heat\n", - " # conduction\n", - "\n", - " x_pos = np.array(model_centroids_x_right_of_BHE)\n", - " ss_sln = analytical.hechtMendez_SS_3d(\n", - " x_pos, To, Y3d, Z3d, ath, atv, Fplanar, va, n, rhow, cw, thermdiff\n", - " )\n", - "\n", - " t = 864000 # seconds (10 days)\n", - " Y = 0.1 # dimension of source in the y direction\n", - " Z = delz # dimension of source in the z direction\n", - " R = 2.59 # From Hecht-Mendez manuscript\n", - "\n", - " tr_sln = analytical.hechtMendez3d(\n", - " x_pos,\n", - " t,\n", - " Y,\n", - " Z,\n", - " al,\n", - " ath,\n", - " atv,\n", - " thermdiff,\n", - " va,\n", - " n,\n", - " R,\n", - " Fplanar,\n", - " cw,\n", - " rhow,\n", - " )\n", - "\n", - " # list of where to draw vertical lines\n", - " avlines = list(range(10)) + list(range(10, 110, 10))\n", - "\n", - " # fill variables with analytical solutions\n", - " y_ss_anly_sln = ss_sln\n", - " y_tr_anly_sln = [285.15 + val for val in tr_sln]\n", - "\n", - " # fill variables containing the simulated solutions\n", - " if mt3d is not None:\n", - " y_10_mt_sln = conc_mt3d[0, 6, (42 - 1), 22:]\n", - " y_150_mt_sln = conc_mt3d[-1, 6, (42 - 1), 22:]\n", - "\n", - " y_10_mf6_sln = conc_mf6[0, 6, (42 - 1), 22:]\n", - " y_150_mf6_sln = conc_mf6[-1, 6, (42 - 1), 22:]\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_name = sim_mf6gwt.name\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - "\n", - " if ax is None:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1)\n", - "\n", - " for xc in avlines:\n", - " ax.axvline(x=xc, color=\"k\", linestyle=\":\", alpha=0.1)\n", - "\n", - " ss_ln = ax.plot(\n", - " x_pos,\n", - " y_ss_anly_sln,\n", - " \"r-\",\n", - " label=\"Steady state analytical solution\",\n", - " )\n", - " tr_ln = ax.plot(\n", - " x_pos, y_tr_anly_sln, \"b-\", label=\"Transient analytical solution\"\n", - " )\n", - "\n", - " if mt3d is not None:\n", - " mt_ss_ln = ax.plot(\n", - " x_pos, y_150_mt_sln, \"r+\", label=\"Steady state MT3DMS, TVD\"\n", - " )\n", - " mt_tr_ln = ax.plot(x_pos, y_10_mt_sln, \"b+\", label=\"Transient MT3DMS\")\n", - "\n", - " mf6_ss_ln = ax.plot(x_pos, y_150_mf6_sln, \"rx\", label=\"Steady-state MF6-GWT\")\n", - " mf6_tr_ln = ax.plot(\n", - " x_pos,\n", - " y_10_mf6_sln,\n", - " \"bo\",\n", - " markerfacecolor=\"none\",\n", - " label=\"Transient MF6-GWT\",\n", - " )\n", - " ax.set_xlim(1, 100)\n", - " ax.set_ylim(285.15 - 2.1, 285.15 + 0.5)\n", - " ax.set_xscale(\"log\")\n", - " ax.set_xlabel(\"x-coordinate, in meters\")\n", - " ax.set_ylabel(\"temperature, in Kelvins\")\n", - " ax.legend()\n", - " plt.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(\n", - " \"ex-\" + sim_name + \"-\" + letter,\n", - " config.figure_ext,\n", - " ),\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "82fcf9da", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function that wraps all of the steps for each MT3DMS Example 10 Problem scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6a5a4458", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def scenario(idx, runMT3D=False, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " parameter_dict = parameters[key]\n", - "\n", - " if runMT3D:\n", - " mf2k5 = build_mf2k5_flow_model(key, **parameter_dict)\n", - " else:\n", - " mf2k5 = None\n", - "\n", - " sim_mf6gwf = build_mf6_flow_model(key, **parameter_dict)\n", - "\n", - " if runMT3D:\n", - " mt3d = build_mt3d_transport_model(mf2k5, key, **parameter_dict)\n", - " else:\n", - " mt3d = None\n", - "\n", - " sim_mf6gwt = build_mf6_transport_model(key, **parameter_dict)\n", - "\n", - " if runMT3D:\n", - " write_mf2k5_models(mf2k5, mt3d, silent=silent)\n", - "\n", - " write_mf6_models(sim_mf6gwf, sim_mf6gwt, silent=silent)\n", - "\n", - " success = run_model(sim_mf6gwf, sim_mf6gwt, mf2k5=mf2k5, mt3d=mt3d, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(\n", - " sim_mf6gwf, sim_mf6gwt, idx, mf2k5=mf2k5, mt3d=mt3d, **parameter_dict\n", - " )" - ] - }, - { - "cell_type": "markdown", - "id": "88d3ce7b", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2fff287b", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " scenario(1, runMT3D=False, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b3cfab0f", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " scenario(2, runMT3D=False, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "b829e269", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8265c636", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Two-Dimensional Transport in a Diagonal Flow Field\n", - " #\n", - " # Compares the standard finite difference solutions between MT3D MF 6\n", - " # when the Peclet number is 0\n", - " # Not simulated because no known analytical solution to compare to\n", - " # scenario(0, silent=False)\n", - "\n", - " # Compares the standard finite difference solutions between MT3D MF 6\n", - " # when the Peclet number is 0\n", - " scenario(1, silent=False)\n", - "\n", - " # Compares the standard finite difference solutions between MT3D MF 6\n", - " # when the Peclet number is 0\n", - " scenario(2, silent=False)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-henry.ipynb b/notebooks/ex-gwt-henry.ipynb deleted file mode 100644 index e6bfe1c2..00000000 --- a/notebooks/ex-gwt-henry.ipynb +++ /dev/null @@ -1,618 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "ffe038f4", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Henry Problem\n", - "\n", - "Classic saltwater intrusion\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "289f066c", - "metadata": {}, - "source": [ - "### Henry Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "6caef225", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0876716f", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "13d0516c", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "9880a955", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e85bbc4d", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "755ee74d", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "960d0b00", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8908c8f5", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "0af5f615", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2295f3e1", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 4)" - ] - }, - { - "cell_type": "markdown", - "id": "cc4729ff", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "753e5d80", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "c0f67c94", - "metadata": {}, - "source": [ - "Scenario parameters - make sure there is at least one blank line before next item" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2ef9b8a7", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwt-henry-a\": {\n", - " \"inflow\": 5.7024,\n", - " },\n", - " \"ex-gwt-henry-b\": {\n", - " \"inflow\": 2.851,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "9321637e", - "metadata": {}, - "source": [ - "Scenario parameter units - make sure there is at least one blank line before next item\n", - "add parameter_units to add units to the scenario parameter table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "57d4f473", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_units = {\n", - " \"inflow\": \"$m^3/d$\",\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "67ab4994", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e127b5ce", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"centimeters\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "8d306483", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "641ef9b5", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nstp = 500 # Number of time steps\n", - "perlen = 0.5 # Simulation time length ($d$)\n", - "nlay = 40 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 80 # Number of columns\n", - "system_length = 2.0 # Length of system ($m$)\n", - "delr = 0.025 # Column width ($m$)\n", - "delc = 1.0 # Row width ($m$)\n", - "delv = 0.025 # Layer thickness\n", - "top = 1.0 # Top of the model ($m$)\n", - "hydraulic_conductivity = 864.0 # Hydraulic conductivity ($m d^{-1}$)\n", - "initial_concentration = 35.0 # Initial concentration (unitless)\n", - "porosity = 0.35 # porosity (unitless)\n", - "diffusion_coefficient = 0.57024 # diffusion coefficient ($m^2/d$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8d1de14b", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [top - k * delv for k in range(1, nlay + 1)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "12762c5e", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-10, 1e-6, 0.97" - ] - }, - { - "cell_type": "markdown", - "id": "8ff7176b", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy GWF simulation object (sim) is returned\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "91a74e70", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_folder, inflow):\n", - " print(f\"Building model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder)\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = ((perlen, nstp, 1.0),)\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " ims = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"ALL\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwf.name}.ims\",\n", - " )\n", - " sim.register_ims_package(ims, [gwf.name])\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " icelltype=0,\n", - " k=hydraulic_conductivity,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=initial_concentration)\n", - " pd = [(0, 0.7, 0.0, \"trans\", \"concentration\")]\n", - " flopy.mf6.ModflowGwfbuy(gwf, packagedata=pd)\n", - " ghbcond = hydraulic_conductivity * delv * delc / (0.5 * delr)\n", - " ghbspd = [[(k, 0, ncol - 1), top, ghbcond, 35.0] for k in range(nlay)]\n", - " flopy.mf6.ModflowGwfghb(\n", - " gwf,\n", - " stress_period_data=ghbspd,\n", - " pname=\"GHB-1\",\n", - " auxiliary=\"CONCENTRATION\",\n", - " )\n", - "\n", - " welspd = [[(k, 0, 0), inflow / nlay, 0.0] for k in range(nlay)]\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " stress_period_data=welspd,\n", - " pname=\"WEL-1\",\n", - " auxiliary=\"CONCENTRATION\",\n", - " )\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - "\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=\"trans\")\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"ALL\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwt.name}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwtmst(gwt, porosity=porosity)\n", - " flopy.mf6.ModflowGwtic(gwt, strt=initial_concentration)\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=\"UPSTREAM\")\n", - " flopy.mf6.ModflowGwtdsp(gwt, xt3d_off=True, diffc=diffusion_coefficient)\n", - " sourcerecarray = [\n", - " (\"GHB-1\", \"AUX\", \"CONCENTRATION\"),\n", - " (\"WEL-1\", \"AUX\", \"CONCENTRATION\"),\n", - " ]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwt.name}.cbc\",\n", - " concentration_filerecord=f\"{gwt.name}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"ALL\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim, exgtype=\"GWF6-GWT6\", exgmnamea=gwf.name, exgmnameb=gwt.name\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "markdown", - "id": "537f64ba", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "010ecf77", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "c8acd162", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6cf430cf", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "5693c250", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a7b5040f", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_conc(sim, idx):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = list(parameters.keys())[idx]\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(\"flow\")\n", - " gwt = sim.get_model(\"trans\")\n", - "\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " # get MODFLOW 6 concentration\n", - " conc = gwt.output.concentration().get_data()\n", - "\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 0})\n", - " pxs.plot_array(conc, cmap=\"jet\")\n", - " levels = [35 * f for f in [0.01, 0.1, 0.5, 0.9, 0.99]]\n", - " cs = pxs.contour_array(\n", - " conc, levels=levels, colors=\"w\", linewidths=1.0, linestyles=\"-\"\n", - " )\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"z position (m)\")\n", - " plt.clabel(cs, fmt=\"%4.2f\", fontsize=5)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\", \"figures\", f\"{sim_name}-conc{config.figure_ext}\"\n", - " )\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "420ffe2b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, idx):\n", - " if config.plotModel:\n", - " plot_conc(sim, idx)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "cb4f3bff", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "081f9ee1", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " parameter_dict = parameters[key]\n", - " sim = build_model(key, **parameter_dict)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2343900c", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a8b00f2e", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " scenario(1, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "2c9f6ed6", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "34b7e8af", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Henry Problem\n", - "\n", - " # Scenario 1 - Classic henry problem\n", - "\n", - " scenario(0)\n", - "\n", - " # Scenario 2 - Modified Henry problem with half the inflow rate\n", - "\n", - " scenario(1)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-keating.ipynb b/notebooks/ex-gwt-keating.ipynb deleted file mode 100644 index 2f3a5274..00000000 --- a/notebooks/ex-gwt-keating.ipynb +++ /dev/null @@ -1,895 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "13bcfd63", - "metadata": {}, - "source": [ - "## Keating Problem\n", - "\n", - "This problem uses a two-dimensional cross-section model to simulate a perched\n", - "aquifer overlying a water table aquifer. The presence of a discontinuous\n", - "low permeability lens causes the perched aquifer to form in response to\n", - "recharge. The problem also represents solute transport through the system.\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "286f77c9", - "metadata": {}, - "source": [ - "### Keating Problem\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "23c25542", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "21482eba", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.patches\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "e77fb8fe", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "83b6d997", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "6c1bce60", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6802b8d0", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "1a231f30", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "35c2193f", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (7.5, 3)" - ] - }, - { - "cell_type": "markdown", - "id": "912fdd57", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "55fc35f9", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-keating\"" - ] - }, - { - "cell_type": "markdown", - "id": "8b3ae801", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4ec41902", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "6eae56de", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b4eccaf", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 80 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 400 # Number of columns\n", - "delr = 25.0 # Column width ($m$)\n", - "delc = 1.0 # Row width ($m$)\n", - "delz = 25.0 # Layer thickness ($m$)\n", - "top = 2000.0 # Top of model domain ($m$)\n", - "bottom = 0.0 # Bottom of model domain ($m$)\n", - "hka = 1.0e-12 # Permeability of aquifer ($m^2$)\n", - "hkc = 1.0e-18 # Permeability of aquitard ($m^2$)\n", - "h1 = 800.0 # Head on left side ($m$)\n", - "h2 = 100.0 # Head on right side ($m$)\n", - "recharge = 0.5 # Recharge ($kg/s$)\n", - "recharge_conc = 1.0 # Normalized recharge concentration (unitless)\n", - "alpha_l = 1.0 # Longitudinal dispersivity ($m$)\n", - "alpha_th = 1.0 # Transverse horizontal dispersivity ($m$)\n", - "alpha_tv = 1.0 # Transverse vertical dispersivity ($m$)\n", - "period1 = 730 # Length of first simulation period ($d$)\n", - "period2 = 29270.0 # Length of second simulation period ($d$)\n", - "porosity = 0.1 # Porosity of mobile domain (unitless)\n", - "obs1 = (49, 1, 119) # Layer, row, and column for observation 1\n", - "obs2 = (77, 1, 359) # Layer, row, and column for observation 2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3cfc1ac9", - "metadata": {}, - "outputs": [], - "source": [ - "obs1 = tuple([i - 1 for i in obs1])\n", - "obs2 = tuple([i - 1 for i in obs2])\n", - "seconds_to_days = 24.0 * 60.0 * 60.0\n", - "permeability_to_conductivity = 1000.0 * 9.81 / 1.0e-3 * seconds_to_days\n", - "hka = hka * permeability_to_conductivity\n", - "hkc = hkc * permeability_to_conductivity\n", - "botm = [top - (k + 1) * delz for k in range(nlay)]\n", - "x = np.arange(0, 10000.0, delr) + delr / 2.0\n", - "plotaspect = 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "010cee54", - "metadata": {}, - "outputs": [], - "source": [ - "# Fill hydraulic conductivity array\n", - "hydraulic_conductivity = np.ones((nlay, nrow, ncol), dtype=float) * hka\n", - "for k in range(nlay):\n", - " if 1000.0 <= botm[k] < 1100.0:\n", - " for j in range(ncol):\n", - " if 3000.0 <= x[j] <= 6000.0:\n", - " hydraulic_conductivity[k, 0, j] = hkc" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1f84dbf9", - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate recharge by converting from kg/s to m/d\n", - "rcol = []\n", - "for jcol in range(ncol):\n", - " if 4200.0 <= x[jcol] <= 4800.0:\n", - " rcol.append(jcol)\n", - "number_recharge_cells = len(rcol)\n", - "rrate = recharge * seconds_to_days / 1000.0\n", - "cell_area = delr * delc\n", - "rrate = rrate / (float(number_recharge_cells) * cell_area)\n", - "rchspd = {}\n", - "rchspd[0] = [[(0, 0, j), rrate, recharge_conc] for j in rcol]\n", - "rchspd[1] = [[(0, 0, j), rrate, 0.0] for j in rcol]" - ] - }, - { - "cell_type": "markdown", - "id": "66512057", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model\n", - "recharge is the only variable\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "97a6ffd9", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwf(sim_folder):\n", - " print(f\"Building mf6gwf model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwf\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = ((period1, 1, 1.0), (period2, 1, 1.0))\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=len(tdis_ds), perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " complexity=\"complex\",\n", - " no_ptcrecord=\"all\",\n", - " outer_dvclose=1.0e-4,\n", - " outer_maximum=2000,\n", - " under_relaxation=\"dbd\",\n", - " linear_acceleration=\"BICGSTAB\",\n", - " under_relaxation_theta=0.7,\n", - " under_relaxation_kappa=0.08,\n", - " under_relaxation_gamma=0.05,\n", - " under_relaxation_momentum=0.0,\n", - " backtracking_number=20,\n", - " backtracking_tolerance=2.0,\n", - " backtracking_reduction_factor=0.2,\n", - " backtracking_residual_limit=5.0e-4,\n", - " inner_dvclose=1.0e-5,\n", - " rcloserecord=\"0.0001 relative_rclose\",\n", - " inner_maximum=100,\n", - " relaxation_factor=0.0,\n", - " number_orthogonalizations=2,\n", - " preconditioner_levels=8,\n", - " preconditioner_drop_tolerance=0.001,\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim, modelname=name, save_flows=True, newtonoptions=[\"newton\"]\n", - " )\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " save_saturation=True,\n", - " icelltype=1,\n", - " k=hydraulic_conductivity,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=600.0)\n", - " chdspd = [[(k, 0, 0), h1] for k in range(nlay) if botm[k] < h1]\n", - " chdspd += [[(k, 0, ncol - 1), h2] for k in range(nlay) if botm[k] < h2]\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chdspd,\n", - " print_input=True,\n", - " print_flows=True,\n", - " save_flows=False,\n", - " pname=\"CHD-1\",\n", - " )\n", - " flopy.mf6.ModflowGwfrch(\n", - " gwf,\n", - " stress_period_data=rchspd,\n", - " auxiliary=[\"concentration\"],\n", - " pname=\"RCH-1\",\n", - " )\n", - "\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "22b05abc", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwt(sim_folder):\n", - " print(f\"Building mf6gwt model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwt\")\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name,\n", - " sim_ws=sim_ws,\n", - " exe_name=\"mf6\",\n", - " continue_=True,\n", - " )\n", - " tdis_ds = ((period1, 73, 1.0), (period2, 2927, 1.0))\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=len(tdis_ds), perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " outer_dvclose=1.0e-4,\n", - " outer_maximum=100,\n", - " under_relaxation=\"none\",\n", - " linear_acceleration=\"BICGSTAB\",\n", - " rcloserecord=\"1000.0 strict\",\n", - " inner_maximum=20,\n", - " inner_dvclose=1.0e-4,\n", - " relaxation_factor=0.0,\n", - " number_orthogonalizations=2,\n", - " preconditioner_levels=8,\n", - " preconditioner_drop_tolerance=0.001,\n", - " )\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwtic(gwt, strt=0)\n", - " flopy.mf6.ModflowGwtmst(gwt, porosity=porosity)\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=\"upstream\")\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt, xt3d_off=True, alh=alpha_l, ath1=alpha_th, atv=alpha_tv\n", - " )\n", - " pd = [\n", - " (\"GWFHEAD\", f\"../mf6gwf/flow.hds\", None),\n", - " (\"GWFBUDGET\", \"../mf6gwf/flow.bud\", None),\n", - " ]\n", - " flopy.mf6.ModflowGwtfmi(\n", - " gwt, flow_imbalance_correction=True, packagedata=pd\n", - " )\n", - " sourcerecarray = [\n", - " (\"RCH-1\", \"AUX\", \"CONCENTRATION\"),\n", - " ]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - " saverecord = {\n", - " 0: [\n", - " (\"CONCENTRATION\", \"STEPS\", 10),\n", - " (\"CONCENTRATION\", \"LAST\"),\n", - " (\"CONCENTRATION\", \"FREQUENCY\", 10),\n", - " ],\n", - " 1: [\n", - " (\"CONCENTRATION\", \"STEPS\", 27, 227),\n", - " (\"CONCENTRATION\", \"LAST\"),\n", - " (\"CONCENTRATION\", \"FREQUENCY\", 10),\n", - " ],\n", - " }\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{name}.cbc\",\n", - " concentration_filerecord=f\"{name}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", ncol, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=saverecord,\n", - " printrecord=[\n", - " (\"CONCENTRATION\", \"LAST\"),\n", - " (\n", - " \"BUDGET\",\n", - " \"ALL\",\n", - " ),\n", - " ],\n", - " )\n", - " obs_data = {\n", - " f\"{name}.obs.csv\": [\n", - " (\"obs1\", \"CONCENTRATION\", obs1),\n", - " (\"obs2\", \"CONCENTRATION\", obs2),\n", - " ],\n", - " }\n", - " flopy.mf6.ModflowUtlobs(\n", - " gwt, digits=10, print_input=True, continuous=obs_data\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "81ef19b8", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name):\n", - " sims = None\n", - " if config.buildModel:\n", - " sim_mf6gwf = build_mf6gwf(sim_name)\n", - " sim_mf6gwt = build_mf6gwt(sim_name)\n", - " sim_mf2005 = None # build_mf2005(sim_name)\n", - " sim_mt3dms = None # build_mt3dms(sim_name, sim_mf2005)\n", - " sims = (sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms)\n", - " return sims" - ] - }, - { - "cell_type": "markdown", - "id": "a13575df", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4385f597", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sims, silent=True):\n", - " if config.writeModel:\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " sim_mf6gwf.write_simulation(silent=silent)\n", - " sim_mf6gwt.write_simulation(silent=silent)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "00d55d34", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "53030b43", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sims, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " print(\"Running mf6gwf model...\")\n", - " success, buff = sim_mf6gwf.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " print(\"Running mf6gwt model...\")\n", - " success, buff = sim_mf6gwt.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "68ee6a4a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7cfbae85", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_results(sims, idx):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " plot_head_results(sims, idx)\n", - " plot_conc_results(sims, idx)\n", - " plot_cvt_results(sims, idx)\n", - " if config.plotSave and config.createGif:\n", - " make_animated_gif(sims, idx)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "95eb8d49", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_head_results(sims, idx):\n", - " print(\"Plotting head model results...\")\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " gwf = sim_mf6gwf.flow\n", - " botm = gwf.dis.botm.array\n", - " # gwt = sim_mf6gwt.trans\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = sim_mf6gwf.simulation_data.mfpath.get_sim_path()\n", - " head = gwf.output.head().get_data()\n", - " head = np.where(head > botm, head, np.nan)\n", - " fig, ax = plt.subplots(\n", - " 1, 1, figsize=figure_size, dpi=300, tight_layout=True\n", - " )\n", - " pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 0})\n", - " pa = pxs.plot_array(head, head=head, cmap=\"jet\")\n", - " pxs.plot_bc(ftype=\"RCH\", color=\"red\")\n", - " pxs.plot_bc(ftype=\"CHD\")\n", - " plt.colorbar(pa, shrink=0.5)\n", - " confining_rect = matplotlib.patches.Rectangle(\n", - " (3000, 1000), 3000, 100, color=\"gray\", alpha=0.5\n", - " )\n", - " ax.add_patch(confining_rect)\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"elevation (m)\")\n", - " ax.set_aspect(plotaspect)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-head{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0292c3ed", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_conc_results(sims, idx):\n", - " print(\"Plotting conc model results...\")\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " gwf = sim_mf6gwf.flow\n", - " gwt = sim_mf6gwt.trans\n", - " botm = gwf.dis.botm.array\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " head = gwf.output.head().get_data()\n", - " head = np.where(head > botm, head, np.nan)\n", - " sim_ws = sim_mf6gwt.simulation_data.mfpath.get_sim_path()\n", - " cobj = gwt.output.concentration()\n", - " conc_times = cobj.get_times()\n", - " conc_times = np.array(conc_times)\n", - " fig, axes = plt.subplots(\n", - " 3, 1, figsize=(7.5, 4.5), dpi=300, tight_layout=True\n", - " )\n", - " xgrid, _, zgrid = gwt.modelgrid.xyzcellcenters\n", - " # Desired plot times\n", - " plot_times = [100.0, 1000.0, 3000.0]\n", - " nplots = len(plot_times)\n", - " for iplot in range(nplots):\n", - " print(f\" Plotting conc {iplot + 1}\")\n", - " time_in_pub = plot_times[iplot]\n", - " idx_conc = (np.abs(conc_times - time_in_pub)).argmin()\n", - " totim = conc_times[idx_conc]\n", - " ax = axes[iplot]\n", - " pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 0})\n", - " conc = cobj.get_data(totim=totim)\n", - " conc = np.where(head > botm, conc, np.nan)\n", - " pa = pxs.plot_array(conc, head=head, cmap=\"jet\", vmin=0, vmax=1.0)\n", - " pxs.plot_bc(ftype=\"RCH\", color=\"red\")\n", - " pxs.plot_bc(ftype=\"CHD\")\n", - " confining_rect = matplotlib.patches.Rectangle(\n", - " (3000, 1000), 3000, 100, color=\"gray\", alpha=0.5\n", - " )\n", - " ax.add_patch(confining_rect)\n", - " if iplot == 2:\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"elevation (m)\")\n", - " title = f\"Time = {totim}\"\n", - " letter = chr(ord(\"@\") + iplot + 1)\n", - " fs.heading(letter=letter, heading=title, ax=ax)\n", - " ax.set_aspect(plotaspect)\n", - "\n", - " for k, i, j in [obs1, obs2]:\n", - " x = xgrid[i, j]\n", - " z = zgrid[k, i, j]\n", - " ax.plot(\n", - " x,\n", - " z,\n", - " markerfacecolor=\"yellow\",\n", - " markeredgecolor=\"black\",\n", - " marker=\"o\",\n", - " markersize=\"4\",\n", - " )\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-conc{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "17f588c5", - "metadata": {}, - "outputs": [], - "source": [ - "def make_animated_gif(sims, idx):\n", - " import copy\n", - "\n", - " import matplotlib as mpl\n", - " from matplotlib.animation import FuncAnimation, PillowWriter\n", - "\n", - " print(\"Animating conc model results...\")\n", - " sim_name = example_name\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " gwf = sim_mf6gwf.flow\n", - " gwt = sim_mf6gwt.trans\n", - " botm = gwf.dis.botm.array\n", - "\n", - " # load head\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " head = gwf.output.head().get_data()\n", - " head = np.where(head > botm, head, np.nan)\n", - "\n", - " # load concentration\n", - " cobj = gwt.output.concentration()\n", - " conc_times = cobj.get_times()\n", - " conc_times = np.array(conc_times)\n", - " conc = cobj.get_alldata()\n", - "\n", - " # set up the figure\n", - " fig = plt.figure(figsize=(7.5, 3))\n", - " ax = fig.add_subplot(1, 1, 1)\n", - " pxs = flopy.plot.PlotCrossSection(\n", - " model=gwf,\n", - " ax=ax,\n", - " line={\"row\": 0},\n", - " extent=(0, 10000, 0, 2000),\n", - " )\n", - "\n", - " cmap = copy.copy(mpl.cm.get_cmap(\"jet\"))\n", - " cmap.set_bad(\"white\")\n", - " nodata = -999.0\n", - " a = np.where(head > botm, conc[0], nodata)\n", - " a = np.ma.masked_where(a < 0, a)\n", - " pc = pxs.plot_array(a, head=head, cmap=cmap, vmin=0, vmax=1)\n", - " pxs.plot_bc(ftype=\"RCH\", color=\"red\")\n", - " pxs.plot_bc(ftype=\"CHD\")\n", - "\n", - " def init():\n", - " ax.set_title(f\"Time = {conc_times[0]} days\")\n", - "\n", - " def update(i):\n", - " a = np.where(head > botm, conc[i], nodata)\n", - " a = np.ma.masked_where(a < 0, a)\n", - " a = a[~a.mask]\n", - " pc.set_array(a.flatten())\n", - " ax.set_title(f\"Time = {conc_times[i]} days\")\n", - "\n", - " # Stop the animation at 18,000 days\n", - " idx_end = (np.abs(conc_times - 18000.0)).argmin()\n", - " ani = FuncAnimation(fig, update, range(1, idx_end), init_func=init)\n", - " writer = PillowWriter(fps=25)\n", - " fpth = os.path.join(\"..\", \"figures\", \"{}{}\".format(sim_name, \".gif\"))\n", - " ani.save(fpth, writer=writer)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eb3d46e0", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_cvt_results(sims, idx):\n", - " print(\"Plotting cvt model results...\")\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " gwf = sim_mf6gwf.flow\n", - " gwt = sim_mf6gwt.trans\n", - " botm = gwf.dis.botm.array\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_ws = sim_mf6gwt.simulation_data.mfpath.get_sim_path()\n", - " mf6gwt_ra = gwt.obs.output.obs().data\n", - " dt = [(\"totim\", \"f8\"), (\"obs\", \"f8\")]\n", - " fname = os.path.join(config.data_ws, \"ex-gwt-keating\", \"keating_obs1.csv\")\n", - " obs1ra = np.genfromtxt(fname, delimiter=\",\", deletechars=\"\", dtype=dt)\n", - " fname = os.path.join(config.data_ws, \"ex-gwt-keating\", \"keating_obs2.csv\")\n", - " obs2ra = np.genfromtxt(fname, delimiter=\",\", deletechars=\"\", dtype=dt)\n", - " fig, axes = plt.subplots(2, 1, figsize=(6, 4), dpi=300, tight_layout=True)\n", - " ax = axes[0]\n", - " ax.plot(\n", - " mf6gwt_ra[\"totim\"],\n", - " mf6gwt_ra[\"OBS1\"],\n", - " \"b-\",\n", - " alpha=1.0,\n", - " label=\"MODFLOW 6\",\n", - " )\n", - " ax.plot(\n", - " obs1ra[\"totim\"],\n", - " obs1ra[\"obs\"],\n", - " markerfacecolor=\"None\",\n", - " markeredgecolor=\"k\",\n", - " marker=\"o\",\n", - " markersize=\"4\",\n", - " linestyle=\"None\",\n", - " label=\"Keating and Zyvolosky (2009)\",\n", - " )\n", - " ax.set_xlim(0, 8000)\n", - " ax.set_ylim(0, 0.80)\n", - " ax.set_xlabel(\"time, in days\")\n", - " ax.set_ylabel(\"normalized concentration, unitless\")\n", - " fs.graph_legend(ax)\n", - " ax = axes[1]\n", - " ax.plot(\n", - " mf6gwt_ra[\"totim\"],\n", - " mf6gwt_ra[\"OBS2\"],\n", - " \"b-\",\n", - " alpha=1.0,\n", - " label=\"MODFLOW 6\",\n", - " )\n", - " ax.plot(\n", - " obs2ra[\"totim\"],\n", - " obs2ra[\"obs\"],\n", - " markerfacecolor=\"None\",\n", - " markeredgecolor=\"k\",\n", - " marker=\"o\",\n", - " markersize=\"4\",\n", - " linestyle=\"None\",\n", - " label=\"Keating and Zyvolosky (2009)\",\n", - " )\n", - " ax.set_xlim(0, 30000)\n", - " ax.set_ylim(0, 0.20)\n", - " ax.set_xlabel(\"time, in days\")\n", - " ax.set_ylabel(\"normalized concentration, unitless\")\n", - " fs.graph_legend(ax)\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-cvt{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "4ffb64be", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ae84e136", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sim = build_model(example_name)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bb2b5f9b", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "32a87fa6", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ac7e7ede", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Simulate Keating Problem\n", - "\n", - " # Plot showing MODFLOW 6 results\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-moc3d-p01.ipynb b/notebooks/ex-gwt-moc3d-p01.ipynb deleted file mode 100644 index 4f7572f2..00000000 --- a/notebooks/ex-gwt-moc3d-p01.ipynb +++ /dev/null @@ -1,839 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "40f59369", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## One-Dimensional Steady Flow with Transport\n", - "\n", - "MOC3D Problem 1\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "b55800ab", - "metadata": {}, - "source": [ - "### One-Dimensional Steady Flow with Transport Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "6f844b82", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "986a5143", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0bca6705", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "892ddd00", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eb745552", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "e13989f5", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "04438faa", - "metadata": {}, - "outputs": [], - "source": [ - "import analytical\n", - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b24f8c1", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "a0da522b", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7b9e65a6", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (5, 3)" - ] - }, - { - "cell_type": "markdown", - "id": "40e38cc8", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7e0eb60e", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-moc3dp1\"" - ] - }, - { - "cell_type": "markdown", - "id": "96260c42", - "metadata": {}, - "source": [ - "Scenario parameters - make sure there is at least one blank line before next item" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1076d677", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwt-moc3d-p01a\": {\n", - " \"longitudinal_dispersivity\": 0.1,\n", - " \"retardation_factor\": 1.0,\n", - " \"decay_rate\": 0.0,\n", - " },\n", - " \"ex-gwt-moc3d-p01b\": {\n", - " \"longitudinal_dispersivity\": 1.0,\n", - " \"retardation_factor\": 1.0,\n", - " \"decay_rate\": 0.0,\n", - " },\n", - " \"ex-gwt-moc3d-p01c\": {\n", - " \"longitudinal_dispersivity\": 1.0,\n", - " \"retardation_factor\": 2.0,\n", - " \"decay_rate\": 0.0,\n", - " },\n", - " \"ex-gwt-moc3d-p01d\": {\n", - " \"longitudinal_dispersivity\": 1.0,\n", - " \"retardation_factor\": 1.0,\n", - " \"decay_rate\": 0.01,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "3b004ad8", - "metadata": {}, - "source": [ - "Scenario parameter units - make sure there is at least one blank line before next item\n", - "add parameter_units to add units to the scenario parameter table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9c1e2e09", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_units = {\n", - " \"longitudinal_dispersivity\": \"$cm$\",\n", - " \"retardation_factor\": \"unitless\",\n", - " \"decay_rate\": \"$s^{-1}$\",\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "681db0ff", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fa14252f", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"centimeters\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "11f46eac", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bef2e4f7", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 122 # Number of columns\n", - "system_length = 12.0 # Length of system ($cm$)\n", - "delr = 0.1 # Column width ($cm$)\n", - "delc = 0.1 # Row width ($cm$)\n", - "top = 1.0 # Top of the model ($cm$)\n", - "botm = 0 # Layer bottom elevation ($cm$)\n", - "specific_discharge = 0.1 # Specific discharge ($cm s^{-1}$)\n", - "hydraulic_conductivity = 0.01 # Hydraulic conductivity ($cm s^{-1}$)\n", - "porosity = 0.1 # Porosity of mobile domain (unitless)\n", - "total_time = 120.0 # Simulation time ($s$)\n", - "source_concentration = 1.0 # Source concentration (unitless)\n", - "initial_concentration = 0.0 # Initial concentration (unitless)" - ] - }, - { - "cell_type": "markdown", - "id": "6d17f217", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy GWF simulation object (sim) is returned\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8515f0b9", - "metadata": {}, - "outputs": [], - "source": [ - "def get_sorption_dict(retardation_factor):\n", - " sorption = None\n", - " bulk_density = None\n", - " distcoef = None\n", - " if retardation_factor > 1.0:\n", - " sorption = \"linear\"\n", - " bulk_density = 1.0\n", - " distcoef = (retardation_factor - 1.0) * porosity / bulk_density\n", - " sorption_dict = {\n", - " \"sorption\": sorption,\n", - " \"bulk_density\": bulk_density,\n", - " \"distcoef\": distcoef,\n", - " }\n", - " return sorption_dict" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "940600b5", - "metadata": {}, - "outputs": [], - "source": [ - "def get_decay_dict(decay_rate, sorption=False):\n", - " first_order_decay = None\n", - " decay = None\n", - " decay_sorbed = None\n", - " if decay_rate != 0.0:\n", - " first_order_decay = True\n", - " decay = decay_rate\n", - " if sorption:\n", - " decay_sorbed = decay_rate\n", - " decay_dict = {\n", - " \"first_order_decay\": first_order_decay,\n", - " \"decay\": decay,\n", - " \"decay_sorbed\": decay_sorbed,\n", - " }\n", - " return decay_dict" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "94fce17a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_mf6gwf(sim_folder):\n", - " print(f\"Building mf6gwf model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwf\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = ((total_time, 1, 1.0),)\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(sim)\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " save_saturation=True,\n", - " icelltype=0,\n", - " k=hydraulic_conductivity,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=1.0)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=[[(0, 0, ncol - 1), 1.0]])\n", - " wel_spd = {\n", - " 0: [\n", - " [\n", - " (0, 0, 0),\n", - " specific_discharge * delc * delr * top,\n", - " source_concentration,\n", - " ]\n", - " ],\n", - " }\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " stress_period_data=wel_spd,\n", - " pname=\"WEL-1\",\n", - " auxiliary=[\"CONCENTRATION\"],\n", - " )\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "markdown", - "id": "7e50c4db", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "MODFLOW 6 flopy GWF simulation object (sim) is returned" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "478ec8a8", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwt(\n", - " sim_folder, longitudinal_dispersivity, retardation_factor, decay_rate\n", - "):\n", - " print(f\"Building mf6gwt model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwt\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = ((total_time, 240, 1.0),)\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(sim, linear_acceleration=\"bicgstab\")\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwtic(gwt, strt=0)\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=porosity,\n", - " **get_sorption_dict(retardation_factor),\n", - " **get_decay_dict(decay_rate, retardation_factor > 1.0),\n", - " )\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=\"TVD\")\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " xt3d_off=True,\n", - " alh=longitudinal_dispersivity,\n", - " ath1=longitudinal_dispersivity,\n", - " )\n", - " pd = [\n", - " (\"GWFHEAD\", f\"../mf6gwf/flow.hds\", None),\n", - " (\"GWFBUDGET\", \"../mf6gwf/flow.bud\", None),\n", - " ]\n", - " flopy.mf6.ModflowGwtfmi(gwt, packagedata=pd)\n", - " sourcerecarray = [[\"WEL-1\", \"AUX\", \"CONCENTRATION\"]]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - " # flopy.mf6.ModflowGwtcnc(gwt, stress_period_data=[((0, 0, 0), source_concentration),])\n", - " obs_data = {\n", - " f\"{name}.obs.csv\": [\n", - " (\"X005\", \"CONCENTRATION\", (0, 0, 0)),\n", - " (\"X405\", \"CONCENTRATION\", (0, 0, 40)),\n", - " (\"X1105\", \"CONCENTRATION\", (0, 0, 110)),\n", - " ],\n", - " }\n", - " obs_package = flopy.mf6.ModflowUtlobs(\n", - " gwt, digits=10, print_input=True, continuous=obs_data\n", - " )\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{name}.cbc\",\n", - " concentration_filerecord=f\"{name}.ucn\",\n", - " saverecord=[(\"CONCENTRATION\", \"ALL\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1d82272a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(\n", - " sim_name, longitudinal_dispersivity, retardation_factor, decay_rate\n", - "):\n", - " sims = None\n", - " if config.buildModel:\n", - " sim_mf6gwf = build_mf6gwf(sim_name)\n", - " sim_mf6gwt = build_mf6gwt(\n", - " sim_name, longitudinal_dispersivity, retardation_factor, decay_rate\n", - " )\n", - " sims = (sim_mf6gwf, sim_mf6gwt)\n", - " return sims" - ] - }, - { - "cell_type": "markdown", - "id": "34e9b406", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d6f0d6ec", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sims, silent=True):\n", - " if config.writeModel:\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " sim_mf6gwf.write_simulation(silent=silent)\n", - " sim_mf6gwt.write_simulation(silent=silent)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "3c0777ef", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a286f7a9", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sims, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " success, buff = sim_mf6gwf.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mf6gwt.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "b132652c", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3bb6632a", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_results_ct(\n", - " sims, idx, longitudinal_dispersivity, retardation_factor, decay_rate\n", - "):\n", - " if config.plotModel:\n", - " print(\"Plotting C versus t model results...\")\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " sim_ws = sim_mf6gwt.simulation_data.mfpath.get_sim_path()\n", - " mf6gwt_ra = sim_mf6gwt.get_model(\"trans\").obs.output.obs().data\n", - " fig, axs = plt.subplots(\n", - " 1, 1, figsize=figure_size, dpi=300, tight_layout=True\n", - " )\n", - " alabel = [\"ANALYTICAL\", \"\", \"\"]\n", - " mlabel = [\"MODFLOW 6\", \"\", \"\"]\n", - " iskip = 5\n", - " atimes = np.arange(0, total_time, 0.1)\n", - " obsnames = [\"X005\", \"X405\", \"X1105\"]\n", - " simtimes = mf6gwt_ra[\"totim\"]\n", - " dispersion_coefficient = (\n", - " longitudinal_dispersivity * specific_discharge / retardation_factor\n", - " )\n", - " for i, x in enumerate([0.05, 4.05, 11.05]):\n", - " a1 = analytical.Wexler1d().analytical2(\n", - " x,\n", - " atimes,\n", - " specific_discharge / retardation_factor,\n", - " system_length,\n", - " dispersion_coefficient,\n", - " decay_rate,\n", - " )\n", - " if idx == 0:\n", - " idx_filter = a1 < 0\n", - " a1[idx_filter] = 0\n", - " idx_filter = a1 > 1\n", - " a1[idx_filter] = 0\n", - " idx_filter = atimes > 0\n", - " if i == 2:\n", - " idx_filter = atimes > 79\n", - " elif idx > 0:\n", - " idx_filter = atimes > 0\n", - " axs.plot(\n", - " atimes[idx_filter], a1[idx_filter], color=\"k\", label=alabel[i]\n", - " )\n", - " axs.plot(\n", - " simtimes[::iskip],\n", - " mf6gwt_ra[obsnames[i]][::iskip],\n", - " marker=\"o\",\n", - " ls=\"none\",\n", - " mec=\"blue\",\n", - " mfc=\"none\",\n", - " markersize=\"4\",\n", - " label=mlabel[i],\n", - " )\n", - " axs.set_ylim(0, 1.2)\n", - " axs.set_xlim(0, 120)\n", - " axs.set_xlabel(\"Time (seconds)\")\n", - " axs.set_ylabel(\"Normalized Concentration (unitless)\")\n", - " if idx in [0, 1]:\n", - " axs.text(1, 0.5, \"x=0.05\")\n", - " axs.text(45, 0.5, \"x=4.05\")\n", - " axs.text(100, 0.5, \"x=11.05\")\n", - " axs.legend()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-ct{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9de5e63c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results_cd(\n", - " sims, idx, longitudinal_dispersivity, retardation_factor, decay_rate\n", - "):\n", - " if config.plotModel:\n", - " print(\"Plotting C versus x model results...\")\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " ucnobj_mf6 = sim_mf6gwt.trans.output.concentration()\n", - "\n", - " fig, axs = plt.subplots(\n", - " 1, 1, figsize=figure_size, dpi=300, tight_layout=True\n", - " )\n", - " alabel = [\"ANALYTICAL\", \"\", \"\"]\n", - " mlabel = [\"MODFLOW 6\", \"\", \"\"]\n", - " iskip = 5\n", - " ctimes = [6.0, 60.0, 120.0]\n", - " x = np.linspace(0.5 * delr, system_length - 0.5 * delr, ncol - 1)\n", - " dispersion_coefficient = (\n", - " longitudinal_dispersivity * specific_discharge / retardation_factor\n", - " )\n", - "\n", - " for i, t in enumerate(ctimes):\n", - " a1 = analytical.Wexler1d().analytical2(\n", - " x,\n", - " t,\n", - " specific_discharge / retardation_factor,\n", - " system_length,\n", - " dispersion_coefficient,\n", - " decay_rate,\n", - " )\n", - " if idx == 0:\n", - " idx_filter = x > system_length\n", - " if i == 0:\n", - " idx_filter = x > 6\n", - " if i == 1:\n", - " idx_filter = x > 9\n", - " a1[idx_filter] = 0.0\n", - " axs.plot(x, a1, color=\"k\", label=alabel[i])\n", - " simconc = ucnobj_mf6.get_data(totim=t).flatten()\n", - " axs.plot(\n", - " x[::iskip],\n", - " simconc[::iskip],\n", - " marker=\"o\",\n", - " ls=\"none\",\n", - " mec=\"blue\",\n", - " mfc=\"none\",\n", - " markersize=\"4\",\n", - " label=mlabel[i],\n", - " )\n", - " axs.set_ylim(0, 1.1)\n", - " axs.set_xlim(0, 12)\n", - " if idx in [0, 1]:\n", - " axs.text(0.5, 0.7, \"t=6 s\")\n", - " axs.text(5.5, 0.7, \"t=60 s\")\n", - " axs.text(11, 0.7, \"t=120 s\")\n", - " axs.set_xlabel(\"Distance (cm)\")\n", - " axs.set_ylabel(\"Normalized Concentration (unitless)\")\n", - " plt.legend()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_ws = sim_mf6gwt.simulation_data.mfpath.get_sim_path()\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-cd{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "7768b499", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "db65091b", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " parameter_dict = parameters[key]\n", - " sims = build_model(key, **parameter_dict)\n", - " write_model(sims, silent=silent)\n", - " success = run_model(sims, silent=silent)\n", - " if success:\n", - " plot_results_ct(sims, idx, **parameter_dict)\n", - " plot_results_cd(sims, idx, **parameter_dict)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f315582f", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "acc7749a", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " scenario(1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f42c1776", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " scenario(2, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5629d1a6", - "metadata": {}, - "outputs": [], - "source": [ - "def test_04():\n", - " scenario(3, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "a7a0789b", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "00693057", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Simulated Zero-Order Growth in a Uniform Flow Field\n", - "\n", - " # Scenario 1 - description\n", - "\n", - " scenario(0)\n", - "\n", - " # Scenario 2 - description\n", - "\n", - " scenario(1)\n", - "\n", - " # Scenario 3 - description\n", - "\n", - " scenario(2)\n", - "\n", - " # Scenario 4 - description\n", - "\n", - " scenario(3)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-moc3d-p02.ipynb b/notebooks/ex-gwt-moc3d-p02.ipynb deleted file mode 100644 index 51d5f120..00000000 --- a/notebooks/ex-gwt-moc3d-p02.ipynb +++ /dev/null @@ -1,601 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a55a59e1", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Three-Dimensional Steady Flow with Transport\n", - "\n", - "MOC3D Problem 2\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "0b3b3a4b", - "metadata": {}, - "source": [ - "### Three-Dimensional Steady Flow with Transport Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "7eb09ea6", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "607897b9", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "52314f97", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "eac68de1", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b90be4c4", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "b2aeedd2", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "194d9cb3", - "metadata": {}, - "outputs": [], - "source": [ - "import analytical\n", - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "efd526df", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "7f6734e0", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "31356508", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 4)" - ] - }, - { - "cell_type": "markdown", - "id": "8d2f22d9", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "28f8138c", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-moc3d-p02\"" - ] - }, - { - "cell_type": "markdown", - "id": "4e4fd0e5", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fc604a08", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "54a64446", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "244aef6a", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 40 # Number of layers\n", - "nrow = 12 # Number of rows\n", - "ncol = 30 # Number of columns\n", - "delr = 3 # Column width ($m$)\n", - "delc = 0.5 # Row width ($m$)\n", - "delv = 0.05 # Layer thickness ($m$)\n", - "top = 0.0 # Top of the model ($m$)\n", - "bottom = -2.0 # Model bottom elevation ($m$)\n", - "velocity_x = 0.1 # Velocity in x-direction ($m d^{-1}$)\n", - "hydraulic_conductivity = 0.0125 # Hydraulic conductivity ($m d^{-1}$)\n", - "porosity = 0.25 # Porosity of mobile domain (unitless)\n", - "alpha_l = 0.6 # Longitudinal dispersivity ($m$)\n", - "alpha_th = 0.03 # Transverse horizontal dispersivity ($m$)\n", - "alpha_tv = 0.006 # Transverse vertical dispersivity ($m$)\n", - "total_time = 400.0 # Simulation time ($d$)\n", - "solute_mass_flux = 2.5 # Solute mass flux ($g d^{-1}$)\n", - "source_location = (1, 12, 8) # Source location (layer, row, column)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3716a435", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [-(k + 1) * delv for k in range(nlay)]\n", - "specific_discharge = velocity_x * porosity\n", - "source_location0 = tuple([idx - 1 for idx in source_location])" - ] - }, - { - "cell_type": "markdown", - "id": "e132c42b", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy GWF simulation object (sim) is returned\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "08d802f4", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_mf6gwf(sim_folder):\n", - " print(f\"Building mf6gwf model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwf\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = ((total_time, 1, 1.0),)\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(sim, print_option=\"summary\", inner_maximum=300)\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " save_saturation=True,\n", - " icelltype=0,\n", - " k=hydraulic_conductivity,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=0.0)\n", - " chdspd = []\n", - " welspd = []\n", - " for k in range(nlay):\n", - " for i in range(nrow):\n", - " rec = [(k, i, ncol - 1), 0.0]\n", - " chdspd.append(rec)\n", - " rec = [(k, i, 0), specific_discharge * delc * delv]\n", - " welspd.append(rec)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chdspd)\n", - " flopy.mf6.ModflowGwfwel(gwf, stress_period_data=welspd)\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "markdown", - "id": "c940b73d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "MODFLOW 6 flopy GWF simulation object (sim) is returned" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f4ffa6b0", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwt(sim_folder):\n", - " print(f\"Building mf6gwt model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwt\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = ((total_time, 400, 1.0),)\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(sim, linear_acceleration=\"bicgstab\")\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwtic(gwt, strt=0)\n", - " flopy.mf6.ModflowGwtmst(gwt, porosity=porosity)\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=\"TVD\")\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " xt3d_off=True,\n", - " alh=alpha_l,\n", - " ath1=alpha_th,\n", - " ath2=alpha_tv,\n", - " )\n", - " pd = [\n", - " (\"GWFHEAD\", f\"../mf6gwf/flow.hds\", None),\n", - " (\"GWFBUDGET\", \"../mf6gwf/flow.bud\", None),\n", - " ]\n", - " flopy.mf6.ModflowGwtfmi(gwt, packagedata=pd)\n", - " sourcerecarray = [[]]\n", - " srcspd = [[source_location0, solute_mass_flux]]\n", - " flopy.mf6.ModflowGwtsrc(gwt, stress_period_data=srcspd)\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - " obs_data = {\n", - " f\"{name}.obs.csv\": [\n", - " (\"SOURCELOC\", \"CONCENTRATION\", source_location0),\n", - " ],\n", - " }\n", - " obs_package = flopy.mf6.ModflowUtlobs(\n", - " gwt, digits=10, print_input=True, continuous=obs_data\n", - " )\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{name}.cbc\",\n", - " concentration_filerecord=f\"{name}.ucn\",\n", - " saverecord=[(\"CONCENTRATION\", \"ALL\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1bbe8de3", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name):\n", - " sims = None\n", - " if config.buildModel:\n", - " sim_mf6gwf = build_mf6gwf(sim_name)\n", - " sim_mf6gwt = build_mf6gwt(sim_name)\n", - " sims = (sim_mf6gwf, sim_mf6gwt)\n", - " return sims" - ] - }, - { - "cell_type": "markdown", - "id": "c94857a8", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "657a335f", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sims, silent=True):\n", - " if config.writeModel:\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " sim_mf6gwf.write_simulation(silent=silent)\n", - " sim_mf6gwt.write_simulation(silent=silent)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "f4176f03", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9d6d000b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sims, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " success, buff = sim_mf6gwf.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mf6gwt.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "fb80ccc4", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c56acfb2", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_analytical(ax, levels):\n", - " n = porosity\n", - " v = velocity_x\n", - " al = alpha_l\n", - " ath = alpha_th\n", - " atv = alpha_tv\n", - " c0 = 10.0\n", - " xc = [22.5]\n", - " yc = [0]\n", - " zc = [0]\n", - " q = [1.0]\n", - " dx = v * al\n", - " dy = v * ath\n", - " dz = v * atv\n", - " lam = 0.0\n", - " x = np.arange(0 + delr / 2.0, ncol * delr + delr / 2.0, delr)\n", - " y = np.arange(0 + delc / 2.0, nrow * delc + delc / 2.0, delc)\n", - " x, y = np.meshgrid(x, y)\n", - " z = 0\n", - " t = 400.0\n", - " c400 = analytical.Wexler3d().multiwell(\n", - " x, y, z, t, v, xc, yc, zc, dx, dy, dz, n, q, lam, c0\n", - " )\n", - " cs = ax.contour(x, y, c400, levels=levels, colors=\"k\")\n", - " return cs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a20ce7a6", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sims):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - "\n", - " conc = sim_mf6gwt.trans.output.concentration().get_data()\n", - "\n", - " fig, axs = plt.subplots(\n", - " 1, 1, figsize=figure_size, dpi=300, tight_layout=True\n", - " )\n", - "\n", - " gwt = sim_mf6gwt.trans\n", - " pmv = flopy.plot.PlotMapView(model=gwt, ax=axs)\n", - " levels = [1, 3, 10, 30, 100, 300]\n", - " cs1 = plot_analytical(axs, levels)\n", - " cs2 = pmv.contour_array(\n", - " conc, colors=\"blue\", linestyles=\"--\", levels=levels\n", - " )\n", - " axs.set_xlabel(\"x position (m)\")\n", - " axs.set_ylabel(\"y position (m)\")\n", - " axs.set_aspect(4.0)\n", - "\n", - " labels = [\"Analytical\", \"MODFLOW 6\"]\n", - " lines = [cs1.collections[0], cs2.collections[0]]\n", - " axs.legend(lines, labels, loc=\"upper left\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_ws = sim_mf6gwt.simulation_data.mfpath.get_sim_path()\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-map{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "dbfe3f5a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0a974e8d", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sims = build_model(example_name)\n", - " write_model(sims, silent=silent)\n", - " success = run_model(sims, silent=silent)\n", - " if success:\n", - " plot_results(sims)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "72854740", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "fb0fb44d", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e63430dd", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Model\n", - "\n", - " # Model run\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-moc3d-p02tg.ipynb b/notebooks/ex-gwt-moc3d-p02tg.ipynb deleted file mode 100644 index 7ab712c6..00000000 --- a/notebooks/ex-gwt-moc3d-p02tg.ipynb +++ /dev/null @@ -1,741 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a2b950a8", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Three-Dimensional Steady Flow with Transport\n", - "\n", - "MOC3D Problem 2 simulated with a triangular grid\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "df2e80d4", - "metadata": {}, - "source": [ - "### Three-Dimensional Steady Flow with Transport Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "b1f02f75", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "600d54a1", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1f7f48ab", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import flopy.utils.cvfdutil\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "533dff7b", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "20d8a2e1", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "ff27daa2", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4aab7612", - "metadata": {}, - "outputs": [], - "source": [ - "import analytical\n", - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aa311711", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "0b7c7f8b", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9bcc10c0", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 4)" - ] - }, - { - "cell_type": "markdown", - "id": "28f0ca4d", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2cab5d77", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-moc3d-p02tg\"" - ] - }, - { - "cell_type": "markdown", - "id": "3d17de4b", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1a979f35", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"m\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "baa945fa", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "37979dfb", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 40 # Number of layers\n", - "nrow = 12 # Number of rows\n", - "ncol = 30 # Number of columns\n", - "delr = 3 # Column width ($m$)\n", - "delc = 0.5 # Row width ($m$)\n", - "delv = 0.05 # Layer thickness ($m$)\n", - "top = 0.0 # Top of the model ($m$)\n", - "bottom = -2.0 # Model bottom elevation ($m$)\n", - "velocity_x = 0.1 # Velocity in x-direction ($m d^{-1}$)\n", - "hydraulic_conductivity = 0.0125 # Hydraulic conductivity ($m d^{-1}$)\n", - "porosity = 0.25 # Porosity of mobile domain (unitless)\n", - "alpha_l = 0.6 # Longitudinal dispersivity ($m$)\n", - "alpha_th = 0.03 # Transverse horizontal dispersivity ($m$)\n", - "alpha_tv = 0.006 # Transverse vertical dispersivity ($m$)\n", - "total_time = 400.0 # Simulation time ($d$)\n", - "solute_mass_flux = 2.5 # Solute mass flux ($g d^{-1}$)\n", - "source_location = (1, 12, 8) # Source location (layer, row, column)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d4321980", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [-(k + 1) * delv for k in range(nlay)]\n", - "specific_discharge = velocity_x * porosity\n", - "source_location0 = tuple([idx - 1 for idx in source_location])" - ] - }, - { - "cell_type": "markdown", - "id": "76dd27da", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy GWF simulation object (sim) is returned\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e1a5b9fe", - "metadata": {}, - "outputs": [], - "source": [ - "def grid_triangulator(itri, delr, delc):\n", - " regular_grid = flopy.discretization.StructuredGrid(delc, delr)\n", - " vertdict = {}\n", - " icell = 0\n", - " for i in range(nrow):\n", - " for j in range(ncol):\n", - " vs = regular_grid.get_cell_vertices(i, j)\n", - " vs.reverse()\n", - " if itri[i, j] == 0:\n", - " vertdict[icell] = [vs[0], vs[3], vs[2], vs[1], vs[0]]\n", - " icell += 1\n", - " elif itri[i, j] == 1:\n", - " vertdict[icell] = [vs[0], vs[3], vs[1], vs[0]]\n", - " icell += 1\n", - " vertdict[icell] = [vs[1], vs[3], vs[2], vs[1]]\n", - " icell += 1\n", - " elif itri[i, j] == 2:\n", - " vertdict[icell] = [vs[0], vs[2], vs[1], vs[0]]\n", - " icell += 1\n", - " vertdict[icell] = [vs[0], vs[3], vs[2], vs[0]]\n", - " icell += 1\n", - " else:\n", - " raise Exception(f\"Unknown itri value: {itri[i, j]}\")\n", - " verts, iverts = flopy.utils.cvfdutil.to_cvfd(vertdict)\n", - " return verts, iverts" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a95ace92", - "metadata": {}, - "outputs": [], - "source": [ - "def cvfd_to_cell2d(verts, iverts):\n", - " vertices = []\n", - " for i in range(verts.shape[0]):\n", - " x = verts[i, 0]\n", - " y = verts[i, 1]\n", - " vertices.append([i, x, y])\n", - " cell2d = []\n", - " for icell2d, vs in enumerate(iverts):\n", - " points = [tuple(verts[ip]) for ip in vs]\n", - " xc, yc = flopy.utils.cvfdutil.centroid_of_polygon(points)\n", - " cell2d.append([icell2d, xc, yc, len(vs), *vs])\n", - " return vertices, cell2d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7173ccd2", - "metadata": {}, - "outputs": [], - "source": [ - "def make_grid():\n", - " # itri 0 means do not split the cell\n", - " # itri 1 means split from upper right to lower left\n", - " # itri 2 means split from upper left to lower right\n", - " itri = np.zeros((nrow, ncol), dtype=int)\n", - " itri[:, 1 : ncol - 1] = 2\n", - " itri[source_location0[1], source_location0[2]] = 0\n", - " delra = delr * np.ones(ncol, dtype=float)\n", - " delca = delc * np.ones(nrow, dtype=float)\n", - " verts, iverts = grid_triangulator(itri, delra, delca)\n", - " vertices, cell2d = cvfd_to_cell2d(verts, iverts)\n", - "\n", - " # A grid array that has the cellnumber of the first triangular cell in\n", - " # the original grid\n", - " itricellnum = np.empty((nrow, ncol), dtype=int)\n", - " icell = 0\n", - " for i in range(nrow):\n", - " for j in range(ncol):\n", - " itricellnum[i, j] = icell\n", - " if itri[i, j] != 0:\n", - " icell += 2\n", - " else:\n", - " icell += 1\n", - " return vertices, cell2d, itricellnum" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1025ca51", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_mf6gwf(sim_folder):\n", - " print(f\"Building mf6gwf model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwf\")\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " tdis_ds = ((total_time, 1, 1.0),)\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " inner_maximum=300,\n", - " linear_acceleration=\"bicgstab\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " vertices, cell2d, itricellnum = make_grid()\n", - " flopy.mf6.ModflowGwfdisv(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nvert=len(vertices),\n", - " ncpl=len(cell2d),\n", - " vertices=vertices,\n", - " cell2d=cell2d,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " xt3doptions=True,\n", - " save_specific_discharge=True,\n", - " save_saturation=True,\n", - " icelltype=0,\n", - " k=hydraulic_conductivity,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=0.0)\n", - " chdspd = []\n", - " welspd = []\n", - " for k in range(nlay):\n", - " for i in range(nrow):\n", - " icpl = itricellnum[i, ncol - 1]\n", - " rec = [(k, icpl), 0.0]\n", - " chdspd.append(rec)\n", - " icpl = itricellnum[i, 0]\n", - " rec = [(k, icpl), specific_discharge * delc * delv]\n", - " welspd.append(rec)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chdspd)\n", - " flopy.mf6.ModflowGwfwel(gwf, stress_period_data=welspd)\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "markdown", - "id": "3ef089e4", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "MODFLOW 6 flopy GWF simulation object (sim) is returned" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ebb33296", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwt(sim_folder):\n", - " print(f\"Building mf6gwt model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwt\")\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " tdis_ds = ((total_time, 100, 1.0),)\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=0.01,\n", - " inner_dvclose=0.01,\n", - " under_relaxation=\"simple\",\n", - " under_relaxation_gamma=0.9,\n", - " relaxation_factor=0.99,\n", - " linear_acceleration=\"bicgstab\",\n", - " )\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=name, save_flows=True)\n", - " vertices, cell2d, itricellnum = make_grid()\n", - " flopy.mf6.ModflowGwfdisv(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nvert=len(vertices),\n", - " ncpl=len(cell2d),\n", - " vertices=vertices,\n", - " cell2d=cell2d,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwtic(gwt, strt=0)\n", - " flopy.mf6.ModflowGwtmst(gwt, porosity=porosity)\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=\"TVD\")\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=alpha_l,\n", - " ath1=alpha_th,\n", - " ath2=alpha_tv,\n", - " )\n", - " pd = [\n", - " (\"GWFHEAD\", f\"../mf6gwf/flow.hds\", None),\n", - " (\"GWFBUDGET\", \"../mf6gwf/flow.bud\", None),\n", - " ]\n", - " flopy.mf6.ModflowGwtfmi(gwt, packagedata=pd)\n", - " sourcerecarray = [[]]\n", - " icpl = itricellnum[source_location0[1], source_location0[2]]\n", - " srcspd = [[(0, icpl), solute_mass_flux]]\n", - " flopy.mf6.ModflowGwtsrc(gwt, stress_period_data=srcspd)\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - " obs_data = {\n", - " f\"{name}.obs.csv\": [\n", - " (\"SOURCELOC\", \"CONCENTRATION\", source_location0),\n", - " ],\n", - " }\n", - " obs_package = flopy.mf6.ModflowUtlobs(\n", - " gwt, digits=10, print_input=True, continuous=obs_data\n", - " )\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{name}.cbc\",\n", - " concentration_filerecord=f\"{name}.ucn\",\n", - " saverecord=[(\"CONCENTRATION\", \"ALL\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "157f98ce", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name):\n", - " sims = None\n", - " if config.buildModel:\n", - " sim_mf6gwf = build_mf6gwf(sim_name)\n", - " sim_mf6gwt = build_mf6gwt(sim_name)\n", - " sims = (sim_mf6gwf, sim_mf6gwt)\n", - " return sims" - ] - }, - { - "cell_type": "markdown", - "id": "71292887", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c348683", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sims, silent=True):\n", - " if config.writeModel:\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " sim_mf6gwf.write_simulation(silent=silent)\n", - " sim_mf6gwt.write_simulation(silent=silent)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "a4a57a2c", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6f1b682d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sims, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " success, buff = sim_mf6gwf.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mf6gwt.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "b448109f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fa19236b", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_analytical(ax, levels):\n", - " n = porosity\n", - " v = velocity_x\n", - " al = alpha_l\n", - " ath = alpha_th\n", - " atv = alpha_tv\n", - " c0 = 10.0\n", - " xc = [22.5]\n", - " yc = [0]\n", - " zc = [0]\n", - " q = [1.0]\n", - " dx = v * al\n", - " dy = v * ath\n", - " dz = v * atv\n", - " lam = 0.0\n", - " x = np.arange(0 + delr / 2.0, ncol * delr + delr / 2.0, delr)\n", - " y = np.arange(0 + delc / 2.0, nrow * delc + delc / 2.0, delc)\n", - " x, y = np.meshgrid(x, y)\n", - " z = 0\n", - " t = 400.0\n", - " c400 = analytical.Wexler3d().multiwell(\n", - " x, y, z, t, v, xc, yc, zc, dx, dy, dz, n, q, lam, c0\n", - " )\n", - " cs = ax.contour(x, y, c400, levels=levels, colors=\"k\")\n", - " return cs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d1a74b6e", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_grid(sims):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - "\n", - " sim_ws = sim_mf6gwt.simulation_data.mfpath.get_sim_path()\n", - " fig, axs = plt.subplots(1, 1, figsize=figure_size, dpi=300, tight_layout=True)\n", - " gwt = sim_mf6gwt.trans\n", - " pmv = flopy.plot.PlotMapView(model=gwt, ax=axs)\n", - " pmv.plot_grid()\n", - " axs.set_xlabel(\"x position (m)\")\n", - " axs.set_ylabel(\"y position (m)\")\n", - " axs.set_aspect(4.0)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-grid{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cda5ddfd", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sims):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - "\n", - " gwt = sim_mf6gwt.get_model(\"trans\")\n", - " conc = gwt.output.concentration().get_data()\n", - "\n", - " fig, axs = plt.subplots(1, 1, figsize=figure_size, dpi=300, tight_layout=True)\n", - "\n", - " gwt = sim_mf6gwt.trans\n", - " pmv = flopy.plot.PlotMapView(model=gwt, ax=axs)\n", - " # pmv.plot_array(conc, alpha=0.5)\n", - " # pmv.plot_grid()\n", - " levels = [1, 3, 10, 30, 100, 300]\n", - " cs1 = plot_analytical(axs, levels)\n", - " cs2 = pmv.contour_array(conc, colors=\"blue\", linestyles=\"--\", levels=levels)\n", - " axs.set_xlabel(\"x position (m)\")\n", - " axs.set_ylabel(\"y position (m)\")\n", - " axs.set_aspect(4.0)\n", - "\n", - " labels = [\"Analytical\", \"MODFLOW 6\"]\n", - " lines = [cs1.collections[0], cs2.collections[0]]\n", - " axs.legend(lines, labels, loc=\"upper left\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(\n", - " sim_mf6gwt.simulation_data.mfpath.get_sim_path()\n", - " )[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-map{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "0a6de8fa", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "02b26ad4", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sims = build_model(example_name)\n", - " write_model(sims, silent=silent)\n", - " success = run_model(sims, silent=silent)\n", - " if success:\n", - " plot_grid(sims)\n", - " plot_results(sims)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0e9d39a9", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "450aec06", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "166d0332", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Model\n", - "\n", - " # Model run\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dms-p01.ipynb b/notebooks/ex-gwt-mt3dms-p01.ipynb deleted file mode 100644 index e23ca652..00000000 --- a/notebooks/ex-gwt-mt3dms-p01.ipynb +++ /dev/null @@ -1,988 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e5cd34be", - "metadata": {}, - "source": [ - "## One-Dimensional Transport in a Uniform Flow Field Comparison of MODFLOW 6 transport with MT3DMS\n", - "\n", - "The purpose of this script is to (1) recreate the example problems that were first\n", - "described in the 1999 MT3DMS report, and (2) compare MODFLOW 6-GWT solutions to the\n", - "established MT3DMS solutions.\n", - "\n", - "Ten example problems appear in the 1999 MT3DMS manual, starting on page 130.\n", - "This notebook demonstrates example 1 from the list below:\n", - "\n", - " 1. *One-Dimensional Transport in a Uniform Flow Field*,\n", - " 2. One-Dimensional Transport with Nonlinear or Nonequilibrium Sorption,\n", - " 3. Two-Dimensional Transport in a Uniform Flow Field,\n", - " 4. Two-Dimensional Transport in a Diagonal Flow Field,\n", - " 5. Two-Dimensional Transport in a Radial Flow Field,\n", - " 6. Concentration at an Injection/Extraction Well,\n", - " 7. Three-Dimensional Transport in a Uniform Flow Field,\n", - " 8. Two-Dimensional, Vertical Transport in a Heterogeneous Aquifer,\n", - " 9. Two-Dimensional Application Example, and\n", - " 10. Three-Dimensional Field Case Study.\n" - ] - }, - { - "cell_type": "markdown", - "id": "c0e33847", - "metadata": {}, - "source": [ - "### MODFLOW 6 GWT MT3DMS Example 1 Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "55ba84e0", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f4563b57", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9ef6f9c1", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "894c3e57", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c54c8a7a", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "6a9f7808", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9ea9de38", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "926dc04f", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "7c8ab521", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0f9ad310", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (5, 3.5)" - ] - }, - { - "cell_type": "markdown", - "id": "a2da2cf1", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "65fbbaa0", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "e108bc61", - "metadata": {}, - "source": [ - "Set scenario parameters (make sure there is at least one blank line before next item)\n", - "This entire dictionary is passed to _build_model()_ using the kwargs argument" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e70dfb19", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwt-mt3dms-p01a\": {\n", - " \"dispersivity\": 0.0,\n", - " \"retardation\": 1.0,\n", - " \"decay\": 0.0,\n", - " },\n", - " \"ex-gwt-mt3dms-p01b\": {\n", - " \"dispersivity\": 10.0,\n", - " \"retardation\": 1.0,\n", - " \"decay\": 0.0,\n", - " },\n", - " \"ex-gwt-mt3dms-p01c\": {\n", - " \"dispersivity\": 10.0,\n", - " \"retardation\": 5.0,\n", - " \"decay\": 0.0,\n", - " },\n", - " \"ex-gwt-mt3dms-p01d\": {\n", - " \"dispersivity\": 10.0,\n", - " \"retardation\": 5.0,\n", - " \"decay\": 0.002,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "368a9962", - "metadata": {}, - "source": [ - "Scenario parameter units\n", - "\n", - "add parameter_units to add units to the scenario parameter table that is automatically\n", - "built and used by the .tex input" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bb7406e2", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_units = {\n", - " \"dispersivity\": \"$m$\",\n", - " \"retardation\": \"unitless\",\n", - " \"decay\": \"$d^{-1}$\",\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "0aa88fd3", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e91422bb", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "7d81bd2f", - "metadata": {}, - "source": [ - "Table MODFLOW 6 GWT MT3DMS Example 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6fe3bad0", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "ncol = 101 # Number of columns\n", - "nrow = 1 # Number of rows\n", - "delr = 10.0 # Column width ($m$)\n", - "delc = 1.0 # Row width ($m$)\n", - "top = 0.0 # Top of the model ($m$)\n", - "botm = -1.0 # Layer bottom elevations ($m$)\n", - "prsity = 0.25 # Porosity\n", - "perlen = 2000 # Simulation time ($days$)\n", - "k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "a18313dd", - "metadata": {}, - "source": [ - "Set some static model parameter values" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f08e83fe", - "metadata": {}, - "outputs": [], - "source": [ - "k33 = k11 # Vertical hydraulic conductivity ($m/d$)\n", - "laytyp = 1\n", - "nstp = 100.0\n", - "dt0 = perlen / nstp\n", - "Lx = (ncol - 1) * delr\n", - "v = 0.24\n", - "q = v * prsity\n", - "h1 = q * Lx\n", - "strt = np.zeros((nlay, nrow, ncol), dtype=float)\n", - "strt[0, 0, 0] = h1 # Starting head ($m$)\n", - "l = 1000.0 # Needed for plots\n", - "icelltype = 1 # Cell conversion type\n", - "ibound = np.ones((nlay, nrow, ncol), dtype=int)\n", - "ibound[0, 0, 0] = -1\n", - "ibound[0, 0, -1] = -1" - ] - }, - { - "cell_type": "markdown", - "id": "df25ab43", - "metadata": {}, - "source": [ - "Set some static transport related model parameter values" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dcbf564d", - "metadata": {}, - "outputs": [], - "source": [ - "mixelm = 0 # TVD\n", - "rhob = 0.25\n", - "sp2 = 0.0 # red, but not used in this problem\n", - "sconc = np.zeros((nlay, nrow, ncol), dtype=float)\n", - "dmcoef = 0.0 # Molecular diffusion coefficient" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "844212df", - "metadata": {}, - "outputs": [], - "source": [ - "# Set solver parameter values (and related)\n", - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-6, 1e-6, 1.0\n", - "ttsmult = 1.0\n", - "dceps = 1.0e-5 # HMOC parameters in case they are invoked\n", - "nplane = 1 # HMOC\n", - "npl = 0 # HMOC\n", - "nph = 4 # HMOC\n", - "npmin = 0 # HMOC\n", - "npmax = 8 # HMOC\n", - "nlsink = nplane # HMOC\n", - "npsink = nph # HMOC" - ] - }, - { - "cell_type": "markdown", - "id": "ad1b497b", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "53b6c9bb", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_rc = []\n", - "tdis_rc.append((perlen, nstp, 1.0))" - ] - }, - { - "cell_type": "markdown", - "id": "c8fa80bd", - "metadata": {}, - "source": [ - "### Create MODFLOW 6 GWT MT3DMS Example 1 Boundary Conditions\n", - "\n", - "Constant head cells are specified on both ends of the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef1796cf", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "chdspd = [[(0, 0, 0), h1], [(0, 0, ncol - 1), 0.0]]\n", - "c0 = 1.0\n", - "cncspd = [[(0, 0, 0), c0]]" - ] - }, - { - "cell_type": "markdown", - "id": "9c8da769", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot MODFLOW 6 GWT MT3DMS Example 1 model results\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e9f66889", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(\n", - " sim_name,\n", - " dispersivity=0.0,\n", - " retardation=0.0,\n", - " decay=0.0,\n", - " mixelm=0,\n", - " silent=False,\n", - "):\n", - " if config.buildModel:\n", - " mt3d_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " modelname_mf = \"p01-mf\"\n", - "\n", - " # Instantiate the MODFLOW model\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=modelname_mf, model_ws=mt3d_ws, exe_name=exe_name_mf\n", - " )\n", - "\n", - " # Instantiate discretization package\n", - " # units: itmuni=4 (days), lenuni=2 (m)\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " nstp=nstp,\n", - " botm=botm,\n", - " perlen=perlen,\n", - " itmuni=4,\n", - " lenuni=2,\n", - " )\n", - "\n", - " # Instantiate basic package\n", - " flopy.modflow.ModflowBas(mf, ibound=ibound, strt=strt)\n", - "\n", - " # Instantiate layer property flow package\n", - " flopy.modflow.ModflowLpf(mf, hk=k11, laytyp=laytyp)\n", - "\n", - " # Instantiate solver package\n", - " flopy.modflow.ModflowPcg(mf)\n", - "\n", - " # Instantiate link mass transport package (for writing linker file)\n", - " flopy.modflow.ModflowLmt(mf)\n", - "\n", - " # Transport\n", - " modelname_mt = \"p01-mt\"\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=modelname_mt,\n", - " model_ws=mt3d_ws,\n", - " exe_name=exe_name_mt,\n", - " modflowmodel=mf,\n", - " )\n", - "\n", - " c0 = 1.0\n", - " icbund = np.ones((nlay, nrow, ncol), dtype=int)\n", - " icbund[0, 0, 0] = -1\n", - " sconc = np.zeros((nlay, nrow, ncol), dtype=float)\n", - " sconc[0, 0, 0] = c0\n", - " flopy.mt3d.Mt3dBtn(\n", - " mt,\n", - " laycon=laytyp,\n", - " icbund=icbund,\n", - " prsity=prsity,\n", - " sconc=sconc,\n", - " dt0=dt0,\n", - " ifmtcn=1,\n", - " )\n", - "\n", - " # Instatiate the advection package\n", - " flopy.mt3d.Mt3dAdv(\n", - " mt,\n", - " mixelm=mixelm,\n", - " dceps=dceps,\n", - " nplane=nplane,\n", - " npl=npl,\n", - " nph=nph,\n", - " npmin=npmin,\n", - " npmax=npmax,\n", - " nlsink=nlsink,\n", - " npsink=npsink,\n", - " percel=0.5,\n", - " )\n", - "\n", - " # Instantiate the dispersion package\n", - " flopy.mt3d.Mt3dDsp(mt, al=dispersivity)\n", - "\n", - " # Set reactive variables and instantiate chemical reaction package\n", - " if retardation == 1.0:\n", - " isothm = 0.0\n", - " rc1 = 0.0\n", - " else:\n", - " isothm = 1\n", - " if decay != 0:\n", - " ireact = 1\n", - " rc1 = decay\n", - " else:\n", - " ireact = 0.0\n", - " rc1 = 0.0\n", - " kd = (retardation - 1.0) * prsity / rhob\n", - " flopy.mt3d.Mt3dRct(\n", - " mt,\n", - " isothm=isothm,\n", - " ireact=ireact,\n", - " igetsc=0,\n", - " rhob=rhob,\n", - " sp1=kd,\n", - " rc1=rc1,\n", - " rc2=rc1,\n", - " )\n", - "\n", - " # Instantiate the source/sink mixing package\n", - " flopy.mt3d.Mt3dSsm(mt)\n", - "\n", - " # Instantiate the GCG solver in MT3DMS\n", - " flopy.mt3d.Mt3dGcg(mt, mxiter=10)\n", - "\n", - " # MODFLOW 6\n", - " name = \"p01-mf6\"\n", - " gwfname = \"gwf-\" + name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name=mf6exe)\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"CG\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=np.ones((nlay, nrow, ncol), dtype=int),\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " budget_filerecord=f\"{gwfname}.cbc\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 groundwater transport package\n", - " gwtname = \"gwt-\" + name\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=gwtname,\n", - " model_nam_file=f\"{gwtname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwtname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - "\n", - " # Instantiating MODFLOW 6 transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=1,\n", - " filename=f\"{gwtname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{gwtname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 transport advection package\n", - " if mixelm == 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{gwtname}.adv\")\n", - "\n", - " # Instantiating MODFLOW 6 transport dispersion package\n", - " if dispersivity != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " xt3d_off=True,\n", - " alh=dispersivity,\n", - " ath1=dispersivity,\n", - " filename=f\"{gwtname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport mass storage package (formerly \"reaction\" package in MT3DMS)\n", - " if retardation != 1.0:\n", - " sorption = \"linear\"\n", - " bulk_density = rhob\n", - " kd = (retardation - 1.0) * prsity / rhob # prsity & rhob defined in\n", - " else: # global variable section\n", - " sorption = None\n", - " bulk_density = None\n", - " kd = None\n", - " if decay != 0.0:\n", - " first_order_decay = True\n", - " decay_arg = decay\n", - " else:\n", - " first_order_decay = False\n", - " decay_arg = None\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " sorption=sorption,\n", - " bulk_density=bulk_density,\n", - " distcoef=kd,\n", - " first_order_decay=first_order_decay,\n", - " decay=decay_arg,\n", - " decay_sorbed=decay_arg,\n", - " filename=f\"{gwtname}.mst\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport constant concentration package\n", - " flopy.mf6.ModflowGwtcnc(\n", - " gwt,\n", - " maxbound=len(cncspd),\n", - " stress_period_data=cncspd,\n", - " save_flows=False,\n", - " pname=\"CNC-1\",\n", - " filename=f\"{gwtname}.cnc\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport source-sink mixing package\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=[[]], filename=f\"{gwtname}.ssm\")\n", - "\n", - " # Instantiating MODFLOW 6 transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwtname}.cbc\",\n", - " concentration_filerecord=f\"{gwtname}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 flow-transport exchange mechanism\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname,\n", - " exgmnameb=gwtname,\n", - " filename=f\"{name}.gwfgwt\",\n", - " )\n", - " return mf, mt, sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "19c116d2", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c66e7d1c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(mf2k5, mt3d, sim, silent=True):\n", - " if config.writeModel:\n", - " mf2k5.write_input()\n", - " mt3d.write_input()\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "6beaca7a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the models.\n", - "_True_ is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f42f263a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(mf2k5, mt3d, sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = mf2k5.run_model(silent=silent)\n", - " success, buff = mt3d.run_model(silent=silent)\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "9ad1b24c", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8438a8c0", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mt3d, mf6, idx, ax=None):\n", - " if config.plotModel:\n", - " mt3d_out_path = mt3d.model_ws\n", - " mf6_out_path = mf6.simulation_data.mfpath.get_sim_path()\n", - " mf6.simulation_data.mfpath.get_sim_path()\n", - "\n", - " # Get the MT3DMS concentration output\n", - " fname_mt3d = os.path.join(mt3d_out_path, \"MT3D001.UCN\")\n", - " ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d)\n", - " conc_mt3d = ucnobj_mt3d.get_alldata()\n", - "\n", - " # Get the MF6 concentration output\n", - " gwt = mf6.get_model(list(mf6.model_names)[1])\n", - " ucnobj_mf6 = gwt.output.concentration()\n", - " conc_mf6 = ucnobj_mf6.get_alldata()\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_name = mf6.name\n", - " if ax is None:\n", - " fig, ax = plt.subplots(\n", - " 1, 1, figsize=figure_size, dpi=300, tight_layout=True\n", - " )\n", - "\n", - " ax.plot(\n", - " np.linspace(0, l, ncol),\n", - " conc_mt3d[0, 0, 0, :],\n", - " color=\"k\",\n", - " label=\"MT3DMS\",\n", - " linewidth=0.5,\n", - " )\n", - " ax.plot(\n", - " np.linspace(0, l, ncol),\n", - " conc_mf6[0, 0, 0, :],\n", - " \"^\",\n", - " markeredgewidth=0.5,\n", - " color=\"blue\",\n", - " fillstyle=\"none\",\n", - " label=\"MF6\",\n", - " markersize=3,\n", - " )\n", - " ax.set_ylim(0, 1.2)\n", - " ax.set_xlim(0, 1000)\n", - " ax.set_xlabel(\"Distance, in m\")\n", - " ax.set_ylabel(\"Concentration\")\n", - " title = \"Concentration Profile at Time = 2,000 \" + \"{}\".format(time_units)\n", - " ax.legend()\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}{config.figure_ext}\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "283e5807", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario.\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e478bba0", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " parameter_dict = parameters[key]\n", - " mf2k5, mt3d, sim = build_model(key, **parameter_dict)\n", - "\n", - " write_model(mf2k5, mt3d, sim, silent=silent)\n", - "\n", - " success = run_model(mf2k5, mt3d, sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(mt3d, sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4b9fdec0", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aa608166", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " scenario(1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bb042c01", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " scenario(2, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0d6267e9", - "metadata": {}, - "outputs": [], - "source": [ - "def test_04():\n", - " scenario(3, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "09fc1ad6", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "afb3ff65", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Advection only\n", - "\n", - " scenario(0)\n", - "\n", - " # ### Advection and dispersion\n", - "\n", - " scenario(1)\n", - "\n", - " # ### Advection, dispersion, and retardation\n", - "\n", - " scenario(2)\n", - "\n", - " # ### Advection, dispersion, retardation, and decay\n", - "\n", - " scenario(3)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dms-p02.ipynb b/notebooks/ex-gwt-mt3dms-p02.ipynb deleted file mode 100644 index 9c7ea46c..00000000 --- a/notebooks/ex-gwt-mt3dms-p02.ipynb +++ /dev/null @@ -1,964 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "73dd5933", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## One-Dimensional Steady Flow with Transport\n", - "\n", - "MT3DMS Problem 2\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "cee401f6", - "metadata": {}, - "source": [ - "### One-Dimensional Steady Flow with Transport Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "5906c077", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a9581a9d", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e532f890", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "7fcb7777", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "27f36170", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "f19d538d", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f4643052", - "metadata": {}, - "outputs": [], - "source": [ - "import analytical\n", - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2defba86", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"" - ] - }, - { - "cell_type": "markdown", - "id": "12be02ac", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d2c07941", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (5, 3)" - ] - }, - { - "cell_type": "markdown", - "id": "c3cf6340", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9e3a34bf", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-mt3dms-p02\"" - ] - }, - { - "cell_type": "markdown", - "id": "5a429a1a", - "metadata": {}, - "source": [ - "Scenario parameters - make sure there is at least one blank line before next item" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bd954e14", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwt-mt3dms-p02a\": {\n", - " \"sorption\": \"freundlich\",\n", - " \"Kf\": 0.3,\n", - " \"a\": 0.7,\n", - " },\n", - " \"ex-gwt-mt3dms-p02b\": {\n", - " \"sorption\": \"langmuir\",\n", - " \"Kl\": 100.0,\n", - " \"S\": 0.003,\n", - " },\n", - " \"ex-gwt-mt3dms-p02c\": {\n", - " \"beta\": 0.0,\n", - " },\n", - " \"ex-gwt-mt3dms-p02d\": {\n", - " \"beta\": 0.002,\n", - " },\n", - " \"ex-gwt-mt3dms-p02e\": {\n", - " \"beta\": 0.01,\n", - " },\n", - " \"ex-gwt-mt3dms-p02f\": {\n", - " \"beta\": 20.0,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "3e0b0c54", - "metadata": {}, - "source": [ - "Scenario parameter units - make sure there is at least one blank line before next item\n", - "add parameter_units to add units to the scenario parameter table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f092aecc", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_units = {\n", - " \"beta\": \"$s^{-1}$\",\n", - " \"sorption\": \"text string\",\n", - " \"Kf\": r\"$\\mu g L g^{} mg^{-1}$\",\n", - " \"a\": \"unitless\",\n", - " \"Kl\": \"$L mg^{-1}$\",\n", - " \"S\": r\"$\\mu g g^{-1}$\",\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "be376107", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3ce7c144", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"centimeters\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "41a816ee", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4db75ac2", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 2 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 101 # Number of columns\n", - "period1 = 160 # Length of period 1 ($s$)\n", - "period2 = 1340 # Length of period 2 ($s$)\n", - "delta_time = 1.0 # Length of time steps ($s$)\n", - "delr = 0.16 # Column width ($cm$)\n", - "delc = 0.16 # Row width ($cm$)\n", - "top = 1.0 # Top of the model ($cm$)\n", - "botm = 0 # Layer bottom elevation ($cm$)\n", - "velocity = 0.1 # Velocity ($cm s^{-1}$)\n", - "hydraulic_conductivity = 0.01 # Hydraulic conductivity ($cm s^{-1}$)\n", - "porosity = 0.37 # Porosity of mobile domain (unitless)\n", - "bulk_density = 1.587 # Bulk density ($g cm^{-3}$)\n", - "distribution_coefficient = 0.933 # Distribution coefficient ($cm^3 g^{-1}$)\n", - "dispersivity = 1.0 # Longitudinal dispersivity ($cm$)\n", - "source_concentration = 0.05 # Source concentration (unitless)\n", - "initial_concentration = 0.0 # Initial concentration (unitless)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "db9ac0dc", - "metadata": {}, - "outputs": [], - "source": [ - "specific_discharge = velocity * porosity\n", - "inflow_rate = specific_discharge * delc * (top - botm)\n", - "system_length = ncol * delr" - ] - }, - { - "cell_type": "markdown", - "id": "748f252f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy GWF simulation object (sim) is returned\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bb74eb31", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_mf6gwf(sim_folder):\n", - " print(f\"Building mf6gwf model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwf\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = (\n", - " (period1, int(period1 / delta_time), 1.0),\n", - " (period2, int(period2 / delta_time), 1.0),\n", - " )\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " htol = 1.0e-8\n", - " flopy.mf6.ModflowIms(\n", - " sim, print_option=\"summary\", outer_dvclose=htol, inner_dvclose=htol\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " save_saturation=True,\n", - " icelltype=0,\n", - " k=hydraulic_conductivity,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=1.0)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=[[(0, 0, ncol - 1), 1.0]])\n", - " wel_spd = {\n", - " 0: [\n", - " [\n", - " (0, 0, 0),\n", - " inflow_rate,\n", - " source_concentration,\n", - " ]\n", - " ],\n", - " 1: [\n", - " [\n", - " (0, 0, 0),\n", - " inflow_rate,\n", - " 0.0,\n", - " ]\n", - " ],\n", - " }\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " stress_period_data=wel_spd,\n", - " pname=\"WEL-1\",\n", - " auxiliary=[\"CONCENTRATION\"],\n", - " )\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "markdown", - "id": "8159894d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "MODFLOW 6 flopy GWF simulation object (sim) is returned" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "105702af", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwt(\n", - " sim_folder, sorption=None, Kf=None, a=None, Kl=None, S=None, beta=None\n", - "):\n", - " print(f\"Building mf6gwt model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwt\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = (\n", - " (period1, int(period1 / delta_time), 1.0),\n", - " (period2, int(period2 / delta_time), 1.0),\n", - " )\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " ctol = 1.0e-8\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " linear_acceleration=\"bicgstab\",\n", - " print_option=\"summary\",\n", - " outer_dvclose=ctol,\n", - " inner_dvclose=ctol,\n", - " )\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwtic(gwt, strt=initial_concentration)\n", - " distcoef = None\n", - " if Kf is not None:\n", - " distcoef = Kf\n", - " if Kl is not None:\n", - " distcoef = Kl\n", - " sp2 = None\n", - " if a is not None:\n", - " sp2 = a\n", - " if S is not None:\n", - " sp2 = S\n", - " volfracim = 0.0\n", - " if beta is not None:\n", - " if beta > 0:\n", - " volfracim = bulk_density / (bulk_density + porosity)\n", - "\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=porosity / (1.0 - volfracim),\n", - " bulk_density=bulk_density if sorption else None,\n", - " sorption=sorption,\n", - " distcoef=distcoef,\n", - " sp2=sp2,\n", - " )\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=\"UPSTREAM\")\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt, xt3d_off=True, alh=dispersivity, ath1=dispersivity\n", - " )\n", - " if beta is not None:\n", - " if beta > 0:\n", - " porosity_im = bulk_density / volfracim\n", - " flopy.mf6.ModflowGwtist(\n", - " gwt, volfrac=volfracim, porosity=porosity_im, zetaim=beta\n", - " )\n", - " pd = [\n", - " (\"GWFHEAD\", f\"../mf6gwf/flow.hds\", None),\n", - " (\"GWFBUDGET\", \"../mf6gwf/flow.bud\", None),\n", - " ]\n", - " flopy.mf6.ModflowGwtfmi(gwt, packagedata=pd)\n", - " sourcerecarray = [[\"WEL-1\", \"AUX\", \"CONCENTRATION\"]]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - " obs_data = {\n", - " f\"{name}.obs.csv\": [\n", - " (\"X008\", \"CONCENTRATION\", (0, 0, 50)),\n", - " ],\n", - " }\n", - " obs_package = flopy.mf6.ModflowUtlobs(\n", - " gwt, digits=10, print_input=True, continuous=obs_data\n", - " )\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{name}.cbc\",\n", - " concentration_filerecord=f\"{name}.ucn\",\n", - " saverecord=[(\"CONCENTRATION\", \"ALL\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a4bfaf85", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf2005(sim_folder):\n", - " print(f\"Building mf2005 model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf2005\")\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=name, model_ws=sim_ws, exe_name=\"mf2005\"\n", - " )\n", - " perlen = [period1, period2]\n", - " dis = flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " nper=nper,\n", - " perlen=perlen,\n", - " )\n", - " bas = flopy.modflow.ModflowBas(mf)\n", - " lpf = flopy.modflow.ModflowLpf(mf, hk=hydraulic_conductivity)\n", - " pcg = flopy.modflow.ModflowPcg(mf)\n", - " lmt = flopy.modflow.ModflowLmt(mf)\n", - "\n", - " chdspd = [[0, 0, ncol - 1, 1.0, 1.0]]\n", - " chd = flopy.modflow.ModflowChd(mf, stress_period_data=chdspd)\n", - "\n", - " q = inflow_rate\n", - " welspd = [[0, 0, 0, q]]\n", - " wel = flopy.modflow.ModflowWel(mf, stress_period_data=welspd)\n", - " return mf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a8de2b7f", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mt3dms(\n", - " sim_folder,\n", - " modflowmodel,\n", - " sorption=None,\n", - " Kf=None,\n", - " a=None,\n", - " Kl=None,\n", - " S=None,\n", - " beta=None,\n", - "):\n", - " print(f\"Building mt3dms model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mt3d\")\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=name,\n", - " model_ws=sim_ws,\n", - " exe_name=\"mt3dms\",\n", - " modflowmodel=modflowmodel,\n", - " ftlfilename=\"../mf2005/mt3d_link.ftl\",\n", - " )\n", - " dt0 = delta_time\n", - " btn = flopy.mt3d.Mt3dBtn(\n", - " mt, laycon=0, prsity=porosity, dt0=dt0, ifmtcn=1, obs=[(0, 0, 50)]\n", - " )\n", - " adv = flopy.mt3d.Mt3dAdv(mt, mixelm=0)\n", - " dsp = flopy.mt3d.Mt3dDsp(mt, al=dispersivity)\n", - " if beta is not None:\n", - " isothm = 4\n", - " sp1 = distribution_coefficient\n", - " sp2 = beta\n", - " if Kf is not None:\n", - " isothm = 2\n", - " sp1 = Kf\n", - " sp2 = a\n", - " if Kl is not None:\n", - " isothm = 3\n", - " sp1 = Kl\n", - " sp2 = S\n", - " rct = flopy.mt3d.Mt3dRct(\n", - " mt, isothm=isothm, igetsc=0, rhob=bulk_density, sp1=sp1, sp2=sp2\n", - " )\n", - "\n", - " ssmspd = {}\n", - " ssmspd[0] = [[0, 0, 0, source_concentration, 2]]\n", - " ssmspd[1] = [[0, 0, 0, 0.0, 2]]\n", - " ssm = flopy.mt3d.Mt3dSsm(mt, mxss=2, stress_period_data=ssmspd)\n", - " gcg = flopy.mt3d.Mt3dGcg(mt, cclose=1.0e-8)\n", - " return mt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "957de71a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, **kwargs):\n", - " sims = None\n", - " if config.buildModel:\n", - " sim_mf6gwf = build_mf6gwf(sim_name)\n", - " sim_mf6gwt = build_mf6gwt(sim_name, **kwargs)\n", - " sim_mf2005 = build_mf2005(sim_name)\n", - " sim_mt3dms = build_mt3dms(sim_name, sim_mf2005, **kwargs)\n", - " sims = (sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms)\n", - " return sims" - ] - }, - { - "cell_type": "markdown", - "id": "808ad1ef", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c2ce191b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sims, silent=True):\n", - " if config.writeModel:\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " sim_mf6gwf.write_simulation(silent=silent)\n", - " sim_mf6gwt.write_simulation(silent=silent)\n", - " sim_mf2005.write_input()\n", - " sim_mt3dms.write_input()\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "0a157570", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c4cfa6fa", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sims, silent=True):\n", - " success = True\n", - " report = True\n", - " if config.runModel:\n", - " success = False\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " print(\"Running mf6gwf...\")\n", - " success, buff = sim_mf6gwf.run_simulation(silent=silent, report=report)\n", - " if not success:\n", - " print(buff)\n", - " print(\"Running mf6gwt...\")\n", - " success, buff = sim_mf6gwt.run_simulation(silent=silent, report=report)\n", - " if not success:\n", - " print(buff)\n", - " print(\"Running mf2005...\")\n", - " success, buff = sim_mf2005.run_model(silent=silent, report=report)\n", - " if not success:\n", - " print(buff)\n", - " print(\"Running mt3dms...\")\n", - " success, buff = sim_mt3dms.run_model(\n", - " silent=silent, normal_msg=\"Program completed\", report=report\n", - " )\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "7fb7721a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ab297c80", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_results_ct(sims, idx, **kwargs):\n", - " if config.plotModel:\n", - " print(\"Plotting C versus t model results...\")\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " sim_ws = sim_mf6gwt.simulation_data.mfpath.get_sim_path()\n", - " mf6gwt_ra = sim_mf6gwt.get_model(\"trans\").obs.output.obs().data\n", - " fig, axs = plt.subplots(\n", - " 1, 1, figsize=figure_size, dpi=300, tight_layout=True\n", - " )\n", - "\n", - " sim_ws = sim_mt3dms.model_ws\n", - " fname = os.path.join(sim_ws, \"MT3D001.OBS\")\n", - " mt_ra = sim_mt3dms.load_obs(fname)\n", - " axs.plot(\n", - " mt_ra[\"time\"],\n", - " mt_ra[\"(1, 1, 51)\"] / source_concentration,\n", - " color=\"k\",\n", - " label=\"MT3DMS\",\n", - " )\n", - "\n", - " axs.plot(\n", - " mf6gwt_ra[\"totim\"],\n", - " mf6gwt_ra[\"X008\"] / source_concentration,\n", - " ls=\"--\",\n", - " color=\"blue\",\n", - " # marker=\"o\",\n", - " # mec=\"blue\",\n", - " # mfc=\"none\",\n", - " # markersize=\"3\",\n", - " label=\"MODFLOW 6\",\n", - " )\n", - " axs.set_ylim(0.0, 1.0)\n", - " if idx == 0:\n", - " axs.set_ylim(0, 0.5)\n", - " if idx == 1:\n", - " axs.set_xlim(0, 500)\n", - " axs.set_xlabel(\"Time (seconds)\")\n", - " axs.set_ylabel(\"Normalized Concentration (unitless)\")\n", - " axs.legend()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-ct{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6e97e074", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results():\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - "\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " fig, axs = plt.subplots(\n", - " 1, 1, figsize=figure_size, dpi=300, tight_layout=True\n", - " )\n", - "\n", - " case_colors = [\"blue\", \"green\", \"red\", \"yellow\"]\n", - " pkeys = list(parameters.keys())\n", - " for icase, sim_name in enumerate(pkeys[2:]):\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " beta = parameters[sim_name][\"beta\"]\n", - "\n", - " fname = os.path.join(sim_ws, \"mf6gwt\", \"trans.obs.csv\")\n", - " mf6gwt_ra = flopy.utils.Mf6Obs(fname).data\n", - " mf6conc = mf6gwt_ra[\"X008\"] / source_concentration\n", - " iskip = 20\n", - " axs.plot(\n", - " mf6gwt_ra[\"totim\"][::iskip],\n", - " mf6conc[::iskip],\n", - " markerfacecolor=\"None\",\n", - " markeredgecolor=\"k\",\n", - " marker=\"o\",\n", - " markersize=\"3\",\n", - " linestyle=\"None\",\n", - " )\n", - "\n", - " fname = os.path.join(sim_ws, \"mt3d\", \"MT3D001.OBS\")\n", - " mt3dms_ra = flopy.mt3d.Mt3dms.load_obs(fname)\n", - " axs.plot(\n", - " mt3dms_ra[\"time\"],\n", - " mt3dms_ra[\"(1, 1, 51)\"] / source_concentration,\n", - " color=case_colors[icase],\n", - " label=f\"beta {beta}\",\n", - " )\n", - "\n", - " axs.set_ylim(0, 1)\n", - " axs.set_xlabel(\"Time (days)\")\n", - " axs.set_ylabel(\"Normalized Concentration (unitless)\")\n", - " axs.legend()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fname = f\"{example_name}{config.figure_ext}\"\n", - " fpth = os.path.join(\"..\", \"figures\", fname)\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "5ebde352", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "efec4225", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " parameter_dict = parameters[key]\n", - " sims = build_model(key, **parameter_dict)\n", - " write_model(sims, silent=silent)\n", - " success = run_model(sims, silent=silent)\n", - " if success:\n", - " plot_results_ct(sims, idx, **parameter_dict)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bcd0aaec", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f7ef5524", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " scenario(1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f16169e2", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " scenario(2, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e2ecfb0f", - "metadata": {}, - "outputs": [], - "source": [ - "def test_04():\n", - " scenario(3, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e831220f", - "metadata": {}, - "outputs": [], - "source": [ - "def test_05():\n", - " scenario(4, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b8b922f4", - "metadata": {}, - "outputs": [], - "source": [ - "def test_06():\n", - " scenario(5, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "822c1bf2", - "metadata": {}, - "outputs": [], - "source": [ - "def test_plot_results():\n", - " plot_results()" - ] - }, - { - "cell_type": "markdown", - "id": "402e11e4", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aab00131", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Simulated Zero-Order Growth in a Uniform Flow Field\n", - "\n", - " # Scenario 1 - description\n", - "\n", - " scenario(0)\n", - "\n", - " # Scenario 2 - description\n", - "\n", - " scenario(1)\n", - "\n", - " # Scenario 3 - description\n", - "\n", - " scenario(2)\n", - "\n", - " # Scenario 4 - description\n", - "\n", - " scenario(3)\n", - "\n", - " # Scenario 5 - description\n", - "\n", - " scenario(4)\n", - "\n", - " # Scenario 6 - description\n", - "\n", - " scenario(5)\n", - "\n", - " # Plot All Results\n", - " plot_results()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dms-p03.ipynb b/notebooks/ex-gwt-mt3dms-p03.ipynb deleted file mode 100644 index 64b8ddb6..00000000 --- a/notebooks/ex-gwt-mt3dms-p03.ipynb +++ /dev/null @@ -1,884 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "049826f3", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Two-Dimensional Transport in a Uniform Flow Field Comparison of MODFLOW 6 transport with MT3DMS\n", - "\n", - "The purpose of this script is to (1) recreate the example problems that were first\n", - "described in the 1999 MT3DMS report, and (2) compare MF6-GWT solutions to the\n", - "established MT3DMS solutions.\n", - "\n", - "Ten example problems appear in the 1999 MT3DMS manual, starting on page 130. This\n", - "notebook demonstrates example 10 from the list below:\n", - "\n", - " 1. One-Dimensional Transport in a Uniform Flow Field\n", - " 2. One-Dimensional Transport with Nonlinear or Nonequilibrium Sorption\n", - " 3. **Two-Dimensional Transport in a Uniform Flow Field**\n", - " 4. Two-Dimensional Transport in a Diagonal Flow Field\n", - " 5. Two-Dimensional Transport in a Radial Flow Field\n", - " 6. Concentration at an Injection/Extraction Well\n", - " 7. Three-Dimensional Transport in a Uniform Flow Field\n", - " 8. Two-Dimensional, Vertical Transport in a Heterogeneous Aquifer\n", - " 9. Two-Dimensional Application Example\n", - " 10. Three-Dimensional Field Case Study" - ] - }, - { - "cell_type": "markdown", - "id": "b6839824", - "metadata": {}, - "source": [ - "### MODFLOW 6 GWT MT3DMS Example 3 Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "b14c2736", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6a11dc22", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d1de6075", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "76702033", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f38d57c9", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3eb9a5fb", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "be29f521", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4359fad8", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 4.5)" - ] - }, - { - "cell_type": "markdown", - "id": "23006617", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6272adf5", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-mt3dms-p03\"" - ] - }, - { - "cell_type": "markdown", - "id": "438039b1", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "60507af1", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "65fdd5a2", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2cdfae13", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 1 # Number of layers\n", - "nrow = 31 # Number of rows\n", - "ncol = 46 # Number of columns\n", - "delr = 10.0 # Column width ($m$)\n", - "delc = 10.0 # Row width ($m$)\n", - "delz = 10.0 # Layer thickness ($m$)\n", - "top = 0.0 # Top of the model ($m$)\n", - "prsity = 0.3 # Porosity\n", - "perlen = 365 # Simulation time ($days$)\n", - "k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$)\n", - "qwell = 1.0 # Volumetric injection rate ($m^3/d$)\n", - "cwell = 1000.0 # Concentration of injected water ($mg/L$)\n", - "al = 10.0 # Longitudinal dispersivity ($m$)\n", - "trpt = 0.3 # Ratio of transverse to longitudinal dispersivity" - ] - }, - { - "cell_type": "markdown", - "id": "81cbd4e6", - "metadata": {}, - "source": [ - "Additional model input" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7047cb88", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [1, 365.0]\n", - "nper = len(perlen)\n", - "nstp = [2, 730]\n", - "tsmult = [1.0, 1.0]\n", - "sconc = 0.0\n", - "dt0 = 0.3\n", - "ath1 = al * trpt\n", - "dmcoef = 0.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "95d23565", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [top - delz] # Model geometry" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3442969e", - "metadata": {}, - "outputs": [], - "source": [ - "k33 = k11 # Vertical hydraulic conductivity ($m/d$)\n", - "icelltype = 0" - ] - }, - { - "cell_type": "markdown", - "id": "ade7b066", - "metadata": {}, - "source": [ - "Initial conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8653f7f5", - "metadata": {}, - "outputs": [], - "source": [ - "Lx = (ncol - 1) * delr\n", - "v = 1.0 / 3.0\n", - "prsity = 0.3\n", - "q = v * prsity\n", - "h1 = q * Lx\n", - "strt = np.zeros((nlay, nrow, ncol), dtype=float)\n", - "strt[0, :, 0] = h1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c63d7cc", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "ibound_mf2k5 = np.ones((nlay, nrow, ncol), dtype=int)\n", - "ibound_mf2k5[0, :, 0] = -1\n", - "ibound_mf2k5[0, :, -1] = -1\n", - "idomain = np.ones((nlay, nrow, ncol), dtype=int)\n", - "icbund = 1\n", - "c0 = 0.0\n", - "cncspd = [[(0, 0, 0), c0]]\n", - "welspd = {0: [[0, 15, 15, qwell]]} # Well pumping info for MF2K5\n", - "spd = {0: [0, 15, 15, cwell, 2]} # Well pupming info for MT3DMS\n", - "# (k, i, j), flow, conc\n", - "spd_mf6 = {0: [[(0, 15, 15), qwell, cwell]]} # MF6 pumping information" - ] - }, - { - "cell_type": "markdown", - "id": "3a9bddf3", - "metadata": {}, - "source": [ - "Set solver parameter values (and related)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c4c1fe2", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-6, 1e-6, 1.0\n", - "ttsmult = 1.0\n", - "percel = 1.0 # HMOC parameters in case they are invoked\n", - "itrack = 3 # HMOC\n", - "wd = 0.5 # HMOC\n", - "dceps = 1.0e-5 # HMOC\n", - "nplane = 1 # HMOC\n", - "npl = 0 # HMOC\n", - "nph = 16 # HMOC\n", - "npmin = 4 # HMOC\n", - "npmax = 32 # HMOC\n", - "dchmoc = 1.0e-3 # HMOC\n", - "nlsink = nplane # HMOC\n", - "npsink = nph # HMOC" - ] - }, - { - "cell_type": "markdown", - "id": "f7cc4a50", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4292290c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "tdis_rc = []\n", - "tdis_rc.append((perlen, nstp, 1.0))" - ] - }, - { - "cell_type": "markdown", - "id": "7ba75214", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, and run models and plot MT3DMS Example 10 Problem results\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6366cff4", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, mixelm=0, silent=False):\n", - " if config.buildModel:\n", - " mt3d_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " modelname_mf = \"p03-mf\"\n", - "\n", - " # Instantiate the MODFLOW model\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=modelname_mf, model_ws=mt3d_ws, exe_name=exe_name_mf\n", - " )\n", - "\n", - " # Instantiate discretization package\n", - " # units: itmuni=4 (days), lenuni=2 (m)\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " nper=nper,\n", - " nstp=nstp,\n", - " perlen=perlen,\n", - " itmuni=4,\n", - " lenuni=2,\n", - " )\n", - "\n", - " # Instantiate basic package\n", - " flopy.modflow.ModflowBas(mf, ibound=ibound_mf2k5, strt=strt)\n", - "\n", - " # Instantiate layer property flow package\n", - " flopy.modflow.ModflowLpf(mf, hk=k11, laytyp=icelltype)\n", - "\n", - " # Instantiate well package\n", - " flopy.modflow.ModflowWel(mf, stress_period_data=welspd)\n", - "\n", - " # Instantiate solver package\n", - " flopy.modflow.ModflowPcg(mf)\n", - "\n", - " # Instantiate link mass transport package (for writing linker file)\n", - " flopy.modflow.ModflowLmt(mf)\n", - "\n", - " # Transport\n", - " modelname_mt = \"p03-mt\"\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=modelname_mt,\n", - " model_ws=mt3d_ws,\n", - " exe_name=exe_name_mt,\n", - " modflowmodel=mf,\n", - " )\n", - "\n", - " # Instantiate basic transport package\n", - " flopy.mt3d.Mt3dBtn(\n", - " mt,\n", - " icbund=icbund,\n", - " prsity=prsity,\n", - " sconc=sconc,\n", - " nstp=nstp,\n", - " perlen=perlen,\n", - " )\n", - "\n", - " # Instatiate the advection package\n", - " flopy.mt3d.Mt3dAdv(\n", - " mt,\n", - " mixelm=mixelm,\n", - " dceps=dceps,\n", - " nplane=nplane,\n", - " npl=npl,\n", - " nph=nph,\n", - " npmin=npmin,\n", - " npmax=npmax,\n", - " nlsink=nlsink,\n", - " npsink=npsink,\n", - " percel=percel,\n", - " itrack=itrack,\n", - " wd=wd,\n", - " )\n", - "\n", - " # Instantiate the dispersion package\n", - " flopy.mt3d.Mt3dDsp(mt, al=al, trpt=trpt, dmcoef=dmcoef)\n", - "\n", - " # Instantiate the source/sink mixing package\n", - " flopy.mt3d.Mt3dSsm(mt, stress_period_data=spd)\n", - "\n", - " # Instantiate the GCG solver in MT3DMS\n", - " flopy.mt3d.Mt3dGcg(mt, mxiter=10)\n", - "\n", - " # MODFLOW 6\n", - " name = \"p03-mf6\"\n", - " gwfname = \"gwf-\" + name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name=mf6exe)\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " for i in range(nper):\n", - " tdis_rc.append((perlen[i], nstp[i], tsmult[i]))\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"CG\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=np.ones((nlay, nrow, ncol), dtype=int),\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiate MODFLOW 6 storage package\n", - " sto = flopy.mf6.ModflowGwfsto(gwf, ss=0, sy=0, filename=f\"{gwfname}.sto\")\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " rowList = np.arange(0, nrow).tolist()\n", - " chdspd = []\n", - " # Loop through the left & right sides.\n", - " for itm in rowList:\n", - " # first, do left side of model\n", - " chdspd.append([(0, itm, 0), h1])\n", - " # finally, do right side of model\n", - " chdspd.append([(0, itm, ncol - 1), 0.0])\n", - "\n", - " chdspd = {0: chdspd}\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " # Instantiate the wel package\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " print_input=True,\n", - " print_flows=True,\n", - " stress_period_data=spd_mf6,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"WEL-1\",\n", - " filename=f\"{gwfname}.wel\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 groundwater transport package\n", - " gwtname = \"gwt_\" + name\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=gwtname,\n", - " model_nam_file=f\"{gwtname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # create iterative model solution and register the gwt model with it\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwtname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - "\n", - " # Instantiating MODFLOW 6 transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=1,\n", - " filename=f\"{gwtname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{gwtname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 transport advection package\n", - " if mixelm == 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{gwtname}.adv\")\n", - "\n", - " # Instantiating MODFLOW 6 transport dispersion package\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " xt3d_off=True,\n", - " alh=al,\n", - " ath1=ath1,\n", - " filename=f\"{gwtname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport mass storage package (formerly \"reaction\" package in MT3DMS)\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=None,\n", - " bulk_density=None,\n", - " distcoef=None,\n", - " filename=f\"{gwtname}.mst\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport constant concentration package\n", - " flopy.mf6.ModflowGwtcnc(\n", - " gwt,\n", - " maxbound=len(cncspd),\n", - " stress_period_data=cncspd,\n", - " save_flows=False,\n", - " pname=\"CNC-1\",\n", - " filename=f\"{gwtname}.cnc\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport source-sink mixing package\n", - " sourcerecarray = [(\"WEL-1\", \"AUX\", \"CONCENTRATION\")]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray, filename=f\"{gwtname}.ssm\")\n", - "\n", - " # Instantiating MODFLOW 6 transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwtname}.cbc\",\n", - " concentration_filerecord=f\"{gwtname}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 flow-transport exchange mechanism\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname,\n", - " exgmnameb=gwtname,\n", - " filename=f\"{name}.gwfgwt\",\n", - " )\n", - " return mf, mt, sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "7865bdcc", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "21460c7e", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(mf2k5, mt3d, sim, silent=True):\n", - " if config.writeModel:\n", - " mf2k5.write_input()\n", - " mt3d.write_input()\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "30af7414", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ce923849", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(mf2k5, mt3d, sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = mf2k5.run_model(silent=silent)\n", - " success, buff = mt3d.run_model(silent=silent)\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "4beddf8f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bc8c3360", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mt3d, mf6, idx, ax=None):\n", - " if config.plotModel:\n", - " mt3d_out_path = mt3d.model_ws\n", - " mf6_out_path = mf6.simulation_data.mfpath.get_sim_path()\n", - " mf6.simulation_data.mfpath.get_sim_path()\n", - "\n", - " # Get the MT3DMS concentration output\n", - " fname_mt3d = os.path.join(mt3d_out_path, \"MT3D001.UCN\")\n", - " ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d)\n", - " conc_mt3d = ucnobj_mt3d.get_alldata()\n", - "\n", - " # Get the MF6 concentration output\n", - " gwt = mf6.get_model(list(mf6.model_names)[1])\n", - " ucnobj_mf6 = gwt.output.concentration()\n", - " conc_mf6 = ucnobj_mf6.get_alldata()\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_name = mf6.name\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - " if ax is None:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - "\n", - " mm = flopy.plot.PlotMapView(model=mt3d)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " cs1 = mm.contour_array(conc_mt3d[1], levels=[0.1, 1.0, 10.0, 50.0], colors=\"k\")\n", - " plt.clabel(cs1, inline=1, fontsize=10)\n", - " cs2 = mm.contour_array(\n", - " conc_mf6[1],\n", - " levels=[0.1, 1.0, 10.0, 50.0],\n", - " colors=\"r\",\n", - " linestyles=\"--\",\n", - " )\n", - " plt.clabel(cs2, inline=1, fontsize=10)\n", - " labels = [\"MT3DMS\", \"MODFLOW 6\"]\n", - " lines = [cs1.collections[0], cs2.collections[0]]\n", - "\n", - " plt.xlabel(\"DISTANCE ALONG X-AXIS, IN METERS\")\n", - " plt.ylabel(\"DISTANCE ALONG Y-AXIS, IN METERS\")\n", - " title = \"Plume at Time = 365 \" + f\"{time_units}\"\n", - "\n", - " ax.legend(lines, labels, loc=\"upper left\")\n", - "\n", - " # ax.plot(np.linspace(0, l, ncol), conc_mt3d[0,0,0,:], color='k', label='MT3DMS')\n", - " # ax.plot(np.linspace(0, l, ncol), conc_mf6[0,0,0,:], '^', color='b', label='MF6')\n", - " # ax.set_ylim(0, 1.2)\n", - " # ax.set_xlim(0, 1000)\n", - " # ax.set_xlabel('Distance, in m')\n", - " # ax.set_ylabel('Concentration')\n", - " # title = 'Concentration Profile at Time = 1,000 ' + '{}'.format(\n", - " # time_units)\n", - " # ax.legend()\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}{config.figure_ext}\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "acb51bf6", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function that wraps all of the steps for each MT3DMS Example 10 Problem scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d1ae751c", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " mf2k5, mt3d, sim = build_model(example_name)\n", - " write_model(mf2k5, mt3d, sim, silent=silent)\n", - " success = run_model(mf2k5, mt3d, sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(mt3d, sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4508c5ed", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "c4589549", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "30339969", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Two-Dimensional Transport in a Uniform Flow Field\n", - " #\n", - " # Describe what is plotted here...\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dms-p04.ipynb b/notebooks/ex-gwt-mt3dms-p04.ipynb deleted file mode 100644 index ab31a538..00000000 --- a/notebooks/ex-gwt-mt3dms-p04.ipynb +++ /dev/null @@ -1,1005 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "dd561f53", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Two-Dimensional Transport in a Uniform Flow Field Comparison of MODFLOW 6 transport with MT3DMS\n", - "\n", - "The purpose of this script is to (1) recreate the example problems that were first\n", - "described in the 1999 MT3DMS report, and (2) compare MF6-GWT solutions to the\n", - "established MT3DMS solutions.\n", - "\n", - "Ten example problems appear in the 1999 MT3DMS manual, starting on page 130. This\n", - "notebook demonstrates example 10 from the list below:\n", - "\n", - " 1. One-Dimensional Transport in a Uniform Flow Field\n", - " 2. One-Dimensional Transport with Nonlinear or Nonequilibrium Sorption\n", - " 3. Two-Dimensional Transport in a Uniform Flow Field\n", - " 4. **Two-Dimensional Transport in a Diagonal Flow Field**\n", - " 5. Two-Dimensional Transport in a Radial Flow Field\n", - " 6. Concentration at an Injection/Extraction Well\n", - " 7. Three-Dimensional Transport in a Uniform Flow Field\n", - " 8. Two-Dimensional, Vertical Transport in a Heterogeneous Aquifer\n", - " 9. Two-Dimensional Application Example\n", - " 10. Three-Dimensional Field Case Study" - ] - }, - { - "cell_type": "markdown", - "id": "cf65379d", - "metadata": {}, - "source": [ - "### MODFLOW 6 GWT MT3DMS Example 4 Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "e239dd25", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b1e5f095", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d98bb2db", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "59355d8d", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2a7484fa", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7bdcb3ad", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "dab7ab84", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "da181255", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 4.5)" - ] - }, - { - "cell_type": "markdown", - "id": "4a0b5eb3", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0b3351c0", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-mt3dms-p04\"" - ] - }, - { - "cell_type": "markdown", - "id": "29daf52b", - "metadata": {}, - "source": [ - "Set scenario parameters (make sure there is at least one blank line before next item)\n", - "This entire dictionary is passed to _build_model()_ using the kwargs argument" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eaca04ff", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwt-mt3dms-p04a\": {\"mixelm\": 0},\n", - " \"ex-gwt-mt3dms-p04b\": {\"mixelm\": -1},\n", - " \"ex-gwt-mt3dms-p04c\": {\"mixelm\": 1},\n", - "}\n", - "# Scenario parameter units\n", - "#\n", - "# add parameter_units to add units to the scenario parameter table that is automatically\n", - "# built and used by the .tex input" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d7e9f166", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_units = {\"mixelm\": \"unitless\"}" - ] - }, - { - "cell_type": "markdown", - "id": "0428ecab", - "metadata": {}, - "source": [ - "Setup some lists that will assist with labeling contours in the figures" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e06357df", - "metadata": {}, - "outputs": [], - "source": [ - "legendtxt_mod1 = [\"MT3DMS - FD\", \"MT3DMS - TVD\", \"MT3DMS - MOC\", \"MF6 - FD\"]\n", - "legendtxt_mod2 = [\"MF6 - FD\", \"MF6 - TVD\", \"MF6 - FD\", \"MF6 - TVD\"]" - ] - }, - { - "cell_type": "markdown", - "id": "033b7aae", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a36aed80", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "07c97e38", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "becf86ed", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 1 # Number of layers\n", - "nrow = 100 # Number of rows\n", - "ncol = 100 # Number of columns\n", - "delr = 10.0 # Column width ($m$)\n", - "delc = 10.0 # Row width ($m$)\n", - "delz = 1.0 # Layer thickness ($m$)\n", - "top = 0.0 # Top of the model ($m$)\n", - "prsity = 0.14 # Porosity\n", - "perlen = 365 # Simulation time ($days$)\n", - "k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$)\n", - "qwell = 0.01 # Volumetric injection rate ($m^3/d$)\n", - "cwell = 1000.0 # Concentration of injected water ($mg/L$)\n", - "al = 2.0 # Longitudinal dispersivity ($m$)\n", - "trpt = 0.1 # Ratio of transverse to longitudinal dispersitivity\n", - "dmcoef = 1.0e-9 # Molecular diffusion coefficient ($m^2/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "fef811b4", - "metadata": {}, - "source": [ - "Additional model input" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c0f5e7fd", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [1000.0]\n", - "nper = len(perlen)\n", - "nstp = [100]\n", - "tsmult = [1.0]\n", - "sconc = 0.0\n", - "dt0 = 0.3\n", - "ath1 = al * trpt\n", - "xt3d = [False]\n", - "botm = [top - delz] # Model geometry\n", - "k33 = k11 # Vertical hydraulic conductivity ($m/d$)\n", - "icelltype = 0" - ] - }, - { - "cell_type": "markdown", - "id": "afc17357", - "metadata": {}, - "source": [ - "Initial conditions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f5d690a9", - "metadata": {}, - "outputs": [], - "source": [ - "Lx = (ncol - 1) * delr\n", - "Ly = (nrow - 1) * delc\n", - "Ls = np.sqrt(Lx**2 + Ly**2)\n", - "v = 1.0\n", - "q = v * prsity\n", - "h1 = q * Ls\n", - "a = -1\n", - "b = -1\n", - "c = 1" - ] - }, - { - "cell_type": "markdown", - "id": "c25dd5e6", - "metadata": {}, - "source": [ - "Active model domain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "86dd634f", - "metadata": {}, - "outputs": [], - "source": [ - "ibound_mf2k5 = np.ones((nlay, nrow, ncol), dtype=int) * -1\n", - "ibound_mf2k5[:, 1 : nrow - 1, 1 : ncol - 1] = 1\n", - "idomain = np.ones((nlay, nrow, ncol), dtype=int)\n", - "icbund = 1" - ] - }, - { - "cell_type": "markdown", - "id": "bb54fa26", - "metadata": {}, - "source": [ - "Boundary conditions\n", - "MF2K5 pumping info:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "31986aa6", - "metadata": {}, - "outputs": [], - "source": [ - "welspd = {0: [[0, 79, 20, qwell]]} # Well pumping info for MF2K5\n", - "spd = {0: [0, 79, 20, cwell, 2]} # Well pupming info for MT3DMS" - ] - }, - { - "cell_type": "markdown", - "id": "57677b21", - "metadata": {}, - "source": [ - "MF6 pumping information\n", - " (k, i, j), flow, conc" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b360e742", - "metadata": {}, - "outputs": [], - "source": [ - "spd_mf6 = {0: [[(0, 79, 20), qwell, cwell]]}" - ] - }, - { - "cell_type": "markdown", - "id": "2549533f", - "metadata": {}, - "source": [ - "MF6 constant head boundaries are defined below because additional variables\n", - "from the instantiation of model properties are required" - ] - }, - { - "cell_type": "markdown", - "id": "95c52236", - "metadata": {}, - "source": [ - "Solver settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "35c558ee", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-6, 1e-6, 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "132a8896", - "metadata": {}, - "outputs": [], - "source": [ - "percel = 0.5 # HMOC parameters\n", - "itrack = 3\n", - "wd = 0.5\n", - "dceps = 1.0e-5\n", - "nplane = 1\n", - "npl = 0\n", - "nph = 16\n", - "npmin = 2\n", - "npmax = 32\n", - "dchmoc = 1.0e-3\n", - "nlsink = nplane\n", - "npsink = nph" - ] - }, - { - "cell_type": "markdown", - "id": "404b5d60", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e6d4eb6c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "tdis_rc = []\n", - "tdis_rc.append((perlen, nstp, 1.0))" - ] - }, - { - "cell_type": "markdown", - "id": "27073bb8", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, and run models and plot MT3DMS Example 10 Problem results\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ec88dfae", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, mixelm=0, silent=False):\n", - " if config.buildModel:\n", - " mt3d_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " modelname_mf = \"p04-mf\"\n", - "\n", - " # Instantiate the MODFLOW model\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=modelname_mf, model_ws=mt3d_ws, exe_name=exe_name_mf\n", - " )\n", - "\n", - " # Instantiate discretization package\n", - " # units: itmuni=4 (days), lenuni=2 (m)\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " nper=nper,\n", - " nstp=nstp,\n", - " perlen=perlen,\n", - " itmuni=4,\n", - " lenuni=2,\n", - " )\n", - "\n", - " # Instantiate basic package\n", - " x = mf.modelgrid.xcellcenters\n", - " y = mf.modelgrid.ycellcenters\n", - " d = abs(a * x + b * y + c) / np.sqrt(2)\n", - " strt = h1 - d / Ls * h1\n", - " flopy.modflow.ModflowBas(mf, ibound=ibound_mf2k5, strt=strt)\n", - "\n", - " # Instantiate layer property flow package\n", - " flopy.modflow.ModflowLpf(mf, hk=k11, laytyp=icelltype)\n", - "\n", - " # Instantiate well package\n", - " flopy.modflow.ModflowWel(mf, stress_period_data=welspd)\n", - "\n", - " # Instantiate solver package\n", - " flopy.modflow.ModflowPcg(mf)\n", - "\n", - " # Instantiate link mass transport package (for writing linker file)\n", - " flopy.modflow.ModflowLmt(mf)\n", - "\n", - " # Transport\n", - " modelname_mt = \"p04-mt\"\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=modelname_mt,\n", - " model_ws=mt3d_ws,\n", - " exe_name=exe_name_mt,\n", - " modflowmodel=mf,\n", - " )\n", - "\n", - " # Instantiate basic transport package\n", - " flopy.mt3d.Mt3dBtn(\n", - " mt,\n", - " icbund=icbund,\n", - " prsity=prsity,\n", - " sconc=sconc,\n", - " nstp=nstp,\n", - " perlen=perlen,\n", - " )\n", - "\n", - " # Instatiate the advection package\n", - " flopy.mt3d.Mt3dAdv(\n", - " mt,\n", - " mixelm=mixelm,\n", - " dceps=dceps,\n", - " nplane=nplane,\n", - " npl=npl,\n", - " nph=nph,\n", - " npmin=npmin,\n", - " npmax=npmax,\n", - " nlsink=nlsink,\n", - " npsink=npsink,\n", - " percel=percel,\n", - " itrack=itrack,\n", - " wd=wd,\n", - " )\n", - "\n", - " # Instantiate the dispersion package\n", - " flopy.mt3d.Mt3dDsp(mt, al=al, trpt=trpt, dmcoef=dmcoef)\n", - "\n", - " # Instantiate the source/sink mixing package\n", - " flopy.mt3d.Mt3dSsm(mt, stress_period_data=spd)\n", - "\n", - " # Instantiate the GCG solver in MT3DMS\n", - " flopy.mt3d.Mt3dGcg(mt, mxiter=10)\n", - "\n", - " # MODFLOW 6\n", - " name = \"p04-mf6\"\n", - " gwfname = \"gwf-\" + name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name=mf6exe)\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " for i in range(nper):\n", - " tdis_rc.append((perlen[i], nstp[i], tsmult[i]))\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"CG\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 storage package (steady flow conditions, so no actual storage, using to print values in .lst file)\n", - " flopy.mf6.ModflowGwfsto(gwf, ss=0, sy=0, filename=f\"{gwfname}.sto\")\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " x = gwf.modelgrid.xcellcenters\n", - " y = gwf.modelgrid.ycellcenters\n", - " d = abs(a * x + b * y + c) / np.sqrt(2)\n", - " strt = h1 - d / Ls * h1\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " chdspd = []\n", - " # Loop through the left & right sides.\n", - " for i in np.arange(nrow):\n", - " chdspd.append([(0, i, 0), strt[i, 0]])\n", - " chdspd.append([(0, i, ncol - 1), strt[i, ncol - 1]])\n", - " # Loop through the top & bottom while omitting the corner cells\n", - " for j in np.arange(1, ncol - 1):\n", - " chdspd.append([(0, 0, j), strt[0, j]])\n", - " chdspd.append([(0, nrow - 1, j), strt[nrow - 1, j]])\n", - " chdspd = {0: chdspd}\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " # Instantiate the wel package\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " print_input=True,\n", - " print_flows=True,\n", - " stress_period_data=spd_mf6,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"WEL-1\",\n", - " filename=f\"{gwfname}.wel\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 groundwater transport package\n", - " gwtname = \"gwt_\" + name\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=gwtname,\n", - " model_nam_file=f\"{gwtname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # create iterative model solution and register the gwt model with it\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwtname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - "\n", - " # Instantiating MODFLOW 6 transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=1,\n", - " filename=f\"{gwtname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{gwtname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 transport advection package\n", - " if mixelm >= 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{gwtname}.adv\")\n", - "\n", - " # Instantiating MODFLOW 6 transport dispersion package\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=al,\n", - " ath1=ath1,\n", - " filename=f\"{gwtname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport mass storage package (formerly \"reaction\" package in MT3DMS)\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=None,\n", - " bulk_density=None,\n", - " distcoef=None,\n", - " filename=f\"{gwtname}.mst\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport source-sink mixing package\n", - " sourcerecarray = [(\"WEL-1\", \"AUX\", \"CONCENTRATION\")]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray, filename=f\"{gwtname}.ssm\")\n", - "\n", - " # Instantiating MODFLOW 6 transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwtname}.cbc\",\n", - " concentration_filerecord=f\"{gwtname}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 flow-transport exchange mechanism\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname,\n", - " exgmnameb=gwtname,\n", - " filename=f\"{name}.gwfgwt\",\n", - " )\n", - " return mf, mt, sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "97692516", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d240ade1", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(mf2k5, mt3d, sim, silent=True):\n", - " if config.writeModel:\n", - " mf2k5.write_input()\n", - " mt3d.write_input()\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "30108b02", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d73545a4", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(mf2k5, mt3d, sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = mf2k5.run_model(silent=silent)\n", - " success, buff = mt3d.run_model(silent=silent)\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "a23b5cbc", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0321b5db", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mt3d, mf6, idx, leglab1, leglab2, ax=None):\n", - " if config.plotModel:\n", - " mt3d_out_path = mt3d.model_ws\n", - " mf6_out_path = mf6.simulation_data.mfpath.get_sim_path()\n", - " mf6.simulation_data.mfpath.get_sim_path()\n", - "\n", - " # Get the MT3DMS concentration output\n", - " fname_mt3d = os.path.join(mt3d_out_path, \"MT3D001.UCN\")\n", - " ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d)\n", - " conc_mt3d = ucnobj_mt3d.get_alldata()\n", - "\n", - " # Get the MF6 concentration output\n", - " gwt = mf6.get_model(list(mf6.model_names)[1])\n", - " ucnobj_mf6 = gwt.output.concentration()\n", - " conc_mf6 = ucnobj_mf6.get_alldata()\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_name = mf6.name\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - " if ax is None:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - "\n", - " x = mt3d.modelgrid.xcellcenters\n", - " y = mt3d.modelgrid.ycellcenters\n", - "\n", - " levels = [0.15, 1.0, 2.0, 5.0]\n", - " mm = flopy.plot.PlotMapView(model=mt3d)\n", - "\n", - " cf = plt.contourf(x, y, conc_mt3d[0, 0, :, :], levels=levels, alpha=0.5)\n", - " cbar = plt.colorbar(cf, shrink=0.25)\n", - " cbar.ax.set_title(leglab1)\n", - "\n", - " cs2 = mm.contour_array(\n", - " conc_mf6[0, 0, :, :], levels=levels, colors=\"r\", linestyles=\"--\"\n", - " )\n", - " plt.clabel(cs2)\n", - " labels = [leglab2]\n", - " for i in range(len(labels)):\n", - " cs2.collections[i].set_label(labels[i])\n", - " plt.legend(loc=\"upper left\")\n", - "\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " title = \"MT3DMS-MF6 Comparison\"\n", - "\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}{config.figure_ext}\")\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "3e0b5d61", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function that wraps all of the steps for each MT3DMS Example 10 Problem scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "411761b2", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " parameter_dict = parameters[key]\n", - " mf2k5, mt3d, sim = build_model(key, **parameter_dict)\n", - "\n", - " write_model(mf2k5, mt3d, sim, silent=silent)\n", - "\n", - " success = run_model(mf2k5, mt3d, sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(mt3d, sim, idx, legendtxt_mod1[idx], legendtxt_mod2[idx])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fbb19bdc", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a0fbf0e4", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " scenario(1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "67bac2af", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " scenario(2, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "6bc288b5", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "156be3ae", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Two-Dimensional Transport in a Diagonal Flow Field\n", - "\n", - " # Compares the standard finite difference solutions between MT3D MF 6\n", - "\n", - " scenario(0)\n", - "\n", - " # Compares the respective TVD solutions between MT3D MF 6\n", - "\n", - " scenario(1)\n", - "\n", - " # Compares a MOC solution in MT3D with the standard FD method of MF 6\n", - "\n", - " scenario(2)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dms-p05.ipynb b/notebooks/ex-gwt-mt3dms-p05.ipynb deleted file mode 100644 index 9023090b..00000000 --- a/notebooks/ex-gwt-mt3dms-p05.ipynb +++ /dev/null @@ -1,954 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "ac561e97", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Two-Dimensional Transport in a Radial Flow Field Comparison of MODFLOW 6 transport with MT3DMS\n", - "\n", - "The purpose of this script is to (1) recreate the example problems that were first\n", - "described in the 1999 MT3DMS report, and (2) compare MF6-GWT solutions to the\n", - "established MT3DMS solutions.\n", - "\n", - "Ten example problems appear in the 1999 MT3DMS manual, starting on page 130. This\n", - "notebook demonstrates example 10 from the list below:\n", - "\n", - " 1. One-Dimensional Transport in a Uniform Flow Field\n", - " 2. One-Dimensional Transport with Nonlinear or Nonequilibrium Sorption\n", - " 3. Two-Dimensional Transport in a Uniform Flow Field\n", - " 4. Two-Dimensional Transport in a Diagonal Flow Field\n", - " 5. **Two-Dimensional Transport in a Radial Flow Field**\n", - " 6. Concentration at an Injection/Extraction Well\n", - " 7. Three-Dimensional Transport in a Uniform Flow Field\n", - " 8. Two-Dimensional, Vertical Transport in a Heterogeneous Aquifer\n", - " 9. Two-Dimensional Application Example\n", - " 10. Three-Dimensional Field Case Study" - ] - }, - { - "cell_type": "markdown", - "id": "23c1790c", - "metadata": {}, - "source": [ - "### MODFLOW 6 GWT MT3DMS Example 5 Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "9247f23e", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b53d4274", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "03d1dc8e", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "767ee7ec", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a43893b9", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a8bc26a0", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "84845fa9", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "589e482d", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 4.5)" - ] - }, - { - "cell_type": "markdown", - "id": "813384ee", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1df98586", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-mt3dms-p05\"" - ] - }, - { - "cell_type": "markdown", - "id": "a6b3fd6b", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ce001b86", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "a67004e5", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4cbdb2d7", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 1 # Number of layers\n", - "nrow = 31 # Number of rows\n", - "ncol = 31 # Number of columns\n", - "delr = 10.0 # Column width ($m$)\n", - "delc = 10.0 # Row width ($m$)\n", - "delz = 1.0 # Layer thickness ($m$)\n", - "top = 0.0 # Top of the model ($m$)\n", - "prsity = 0.3 # Porosity\n", - "perlen = 27 # Simulation time ($days$)\n", - "k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$)\n", - "qwell = 100.0 # Volumetric injection rate ($m^3/d$)\n", - "cwell = 1.0 # Concentration of injected water ($mg/L$)\n", - "al = 10.0 # Longitudinal dispersivity ($m$)\n", - "trpt = 1.0 # Ratio of transverse to longitudinal dispersitivity\n", - "dmcoef = 1.0e-9 # Molecular diffusion coefficient ($m^2/d$)" - ] - }, - { - "cell_type": "markdown", - "id": "eac45204", - "metadata": {}, - "source": [ - "Additional model input" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "450f6382", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [27]\n", - "nper = len(perlen)\n", - "nstp = [27]\n", - "tsmult = [1.0]\n", - "sconc = 0.0\n", - "c0 = 0.0\n", - "dt0 = 0.3\n", - "ath1 = al * trpt\n", - "botm = [top - delz] # Model geometry\n", - "k33 = k11 # Vertical hydraulic conductivity ($m/d$)\n", - "icelltype = 0\n", - "mixelm = -1\n", - "strt = np.zeros((nlay, nrow, ncol), dtype=float)" - ] - }, - { - "cell_type": "markdown", - "id": "6ecd175a", - "metadata": {}, - "source": [ - "Active model domain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "11644d83", - "metadata": {}, - "outputs": [], - "source": [ - "ibound_mf2k5 = np.ones((nlay, nrow, ncol), dtype=int) * -1\n", - "ibound_mf2k5[:, 1 : nrow - 1, 1 : ncol - 1] = 1\n", - "idomain = np.ones((nlay, nrow, ncol), dtype=int)\n", - "icbund = 1" - ] - }, - { - "cell_type": "markdown", - "id": "08fc6040", - "metadata": {}, - "source": [ - "Boundary conditions\n", - "MF2K5 pumping info:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "763623ab", - "metadata": {}, - "outputs": [], - "source": [ - "welspd = {0: [[0, 15, 15, qwell]]} # Well pumping info for MF2K5\n", - "spd = {0: [0, 15, 15, cwell, -1]} # Well pupming info for MT3DMS" - ] - }, - { - "cell_type": "markdown", - "id": "c7f174dc", - "metadata": {}, - "source": [ - "MF6 pumping information" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8817d5a8", - "metadata": {}, - "outputs": [], - "source": [ - "# (k, i, j), flow, conc\n", - "spd_mf6 = {0: [[(0, 15, 15), qwell, c0]]}" - ] - }, - { - "cell_type": "markdown", - "id": "df7ac4da", - "metadata": {}, - "source": [ - "MF6 constant head boundaries:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ca208771", - "metadata": {}, - "outputs": [], - "source": [ - "chdspd = []\n", - "# Loop through the left & right sides.\n", - "for i in np.arange(nrow):\n", - " chdspd.append([(0, i, 0), strt[0, i, 0]])\n", - " chdspd.append([(0, i, ncol - 1), strt[0, i, ncol - 1]])\n", - "# Loop through the top & bottom while omitting the corner cells\n", - "for j in np.arange(1, ncol - 1):\n", - " chdspd.append([(0, 0, j), strt[0, 0, j]])\n", - " chdspd.append([(0, nrow - 1, j), strt[0, nrow - 1, j]])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bf766b68", - "metadata": {}, - "outputs": [], - "source": [ - "chdspd = {0: chdspd}" - ] - }, - { - "cell_type": "markdown", - "id": "9f95f2cd", - "metadata": {}, - "source": [ - "Solver settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "13892eeb", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-6, 1e-6, 1.0\n", - "percel = 1.0 # HMOC parameters\n", - "itrack = 3\n", - "wd = 0.5\n", - "dceps = 1.0e-5\n", - "nplane = 1\n", - "npl = 0\n", - "nph = 16\n", - "npmin = 2\n", - "npmax = 32\n", - "dchmoc = 1.0e-3\n", - "nlsink = nplane\n", - "npsink = nph" - ] - }, - { - "cell_type": "markdown", - "id": "e8c5f514", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "05f0d29c", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_rc = []\n", - "tdis_rc.append((perlen, nstp, 1.0))" - ] - }, - { - "cell_type": "markdown", - "id": "b7da7b76", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, and run models and plot MT3DMS Example 10 Problem results\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4ce34c6d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, mixelm=0, silent=False):\n", - " if config.buildModel:\n", - " mt3d_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " modelname_mf = \"p05-mf\"\n", - "\n", - " # Instantiate the MODFLOW model\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=modelname_mf, model_ws=mt3d_ws, exe_name=exe_name_mf\n", - " )\n", - "\n", - " # Instantiate discretization package\n", - " # units: itmuni=4 (days), lenuni=2 (m)\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " nper=nper,\n", - " nstp=nstp,\n", - " perlen=perlen,\n", - " itmuni=4,\n", - " lenuni=2,\n", - " )\n", - "\n", - " # Instantiate basic package\n", - " flopy.modflow.ModflowBas(mf, ibound=ibound_mf2k5, strt=strt)\n", - "\n", - " # Instantiate layer property flow package\n", - " flopy.modflow.ModflowLpf(mf, hk=k11, laytyp=icelltype)\n", - "\n", - " # Instantiate well package\n", - " flopy.modflow.ModflowWel(mf, stress_period_data=welspd)\n", - "\n", - " # Instantiate solver package\n", - " flopy.modflow.ModflowSip(mf)\n", - "\n", - " # Instantiate link mass transport package (for writing linker file)\n", - " flopy.modflow.ModflowLmt(mf)\n", - "\n", - " # Transport\n", - " modelname_mt = \"p05-mt\"\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=modelname_mt,\n", - " model_ws=mt3d_ws,\n", - " exe_name=exe_name_mt,\n", - " modflowmodel=mf,\n", - " )\n", - "\n", - " # Instantiate basic transport package\n", - " flopy.mt3d.Mt3dBtn(\n", - " mt,\n", - " icbund=icbund,\n", - " prsity=prsity,\n", - " sconc=sconc,\n", - " nper=nper,\n", - " nstp=nstp,\n", - " perlen=perlen,\n", - " dt0=dt0,\n", - " tsmult=tsmult,\n", - " )\n", - "\n", - " # Instatiate the advection package\n", - " flopy.mt3d.Mt3dAdv(\n", - " mt,\n", - " mixelm=mixelm,\n", - " dceps=dceps,\n", - " nplane=nplane,\n", - " npl=npl,\n", - " nph=nph,\n", - " npmin=npmin,\n", - " npmax=npmax,\n", - " nlsink=nlsink,\n", - " npsink=npsink,\n", - " percel=percel,\n", - " itrack=itrack,\n", - " wd=wd,\n", - " )\n", - "\n", - " # Instantiate the dispersion package\n", - " flopy.mt3d.Mt3dDsp(mt, al=al, trpt=trpt, dmcoef=dmcoef)\n", - "\n", - " # Instantiate the source/sink mixing package\n", - " flopy.mt3d.Mt3dSsm(mt, stress_period_data=spd)\n", - "\n", - " # Instantiate the GCG solver in MT3DMS\n", - " flopy.mt3d.Mt3dGcg(mt, mxiter=10)\n", - "\n", - " # MODFLOW 6\n", - " name = \"p05-mf6\"\n", - " gwfname = \"gwf-\" + name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name=mf6exe)\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " for i in range(nper):\n", - " tdis_rc.append((perlen[i], nstp[i], tsmult[i]))\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"CG\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 storage package (steady flow conditions, so no actual storage, using to print values in .lst file)\n", - " flopy.mf6.ModflowGwfsto(gwf, ss=0, sy=0, filename=f\"{gwfname}.sto\")\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " # Instantiate the wel package\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " print_input=True,\n", - " print_flows=True,\n", - " stress_period_data=spd_mf6,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"WEL-1\",\n", - " filename=f\"{gwfname}.wel\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 groundwater transport package\n", - " gwtname = \"gwt_\" + name\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=gwtname,\n", - " model_nam_file=f\"{gwtname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # create iterative model solution and register the gwt model with it\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwtname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - "\n", - " # Instantiating MODFLOW 6 transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=1,\n", - " filename=f\"{gwtname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{gwtname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 transport advection package\n", - " if mixelm >= 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{gwtname}.adv\")\n", - "\n", - " # Instantiating MODFLOW 6 transport dispersion package\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=al,\n", - " ath1=ath1,\n", - " filename=f\"{gwtname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport mass storage package (formerly \"reaction\" package in MT3DMS)\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=None,\n", - " bulk_density=None,\n", - " distcoef=None,\n", - " filename=f\"{gwtname}.mst\",\n", - " )\n", - "\n", - " # Instantiate constant concentration\n", - " c0 = 1.0\n", - " cncspd = [[(0, 15, 15), c0]]\n", - " flopy.mf6.ModflowGwtcnc(\n", - " gwt,\n", - " maxbound=len(cncspd),\n", - " stress_period_data=cncspd,\n", - " save_flows=False,\n", - " pname=\"CNC-1\",\n", - " filename=f\"{gwtname}.cnc\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport source-sink mixing package\n", - " sourcerecarray = [(\"WEL-1\", \"AUX\", \"CONCENTRATION\")]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray, filename=f\"{gwtname}.ssm\")\n", - "\n", - " # Instantiating MODFLOW 6 transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwtname}.cbc\",\n", - " concentration_filerecord=f\"{gwtname}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 flow-transport exchange mechanism\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname,\n", - " exgmnameb=gwtname,\n", - " filename=f\"{name}.gwfgwt\",\n", - " )\n", - " return mf, mt, sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "eff6c939", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f5a60c77", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(mf2k5, mt3d, sim, silent=True):\n", - " if config.writeModel:\n", - " mf2k5.write_input()\n", - " mt3d.write_input()\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "2bb5d253", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5b70a963", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(mf2k5, mt3d, sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = mf2k5.run_model(silent=silent)\n", - " success, buff = mt3d.run_model(silent=silent)\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "9f01cb45", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "395ff38d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mt3d, mf6, idx, ax=None, ax2=None):\n", - " if config.plotModel:\n", - " mt3d_out_path = mt3d.model_ws\n", - " mf6_out_path = mf6.simulation_data.mfpath.get_sim_path()\n", - " mf6.simulation_data.mfpath.get_sim_path()\n", - "\n", - " # Get the MT3DMS concentration output\n", - " fname_mt3d = os.path.join(mt3d_out_path, \"MT3D001.UCN\")\n", - " ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d)\n", - " conc_mt3d = ucnobj_mt3d.get_alldata()\n", - "\n", - " # Get the MF6 concentration output\n", - " gwt = mf6.get_model(list(mf6.model_names)[1])\n", - " ucnobj_mf6 = gwt.output.concentration()\n", - " conc_mf6 = ucnobj_mf6.get_alldata()\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_name = mf6.name\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - " if ax is None:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1)\n", - "\n", - " conc1 = conc_mt3d[0, 0, :, :]\n", - " conc2 = conc_mf6[0, 0, :, :]\n", - " x = mt3d.modelgrid.xcellcenters[15, 15:] - mt3d.modelgrid.xcellcenters[15, 15]\n", - " y_mt3d = conc1[15, 15:]\n", - " y_mf6 = conc2[15, 15:]\n", - "\n", - " plt.plot(x, y_mt3d, label=\"MT3DMS\", marker=\"o\")\n", - " plt.plot(x, y_mf6, label=\"MODFLOW 6\", marker=\"^\", color=\"k\")\n", - " ax.set_ylim(0, 1.025)\n", - "\n", - " plt.xlabel(\"Radial Distance From The Source, in meters\")\n", - " plt.ylabel(\"Normalized Concentration, unitless\")\n", - " plt.legend()\n", - "\n", - " title = \"Concentration as a Function of Distance From The Source\"\n", - "\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(sim_name + \"-xsec\", config.figure_ext),\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " # second plot\n", - " if ax2 is None:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax2 = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - "\n", - " levels = np.arange(0.2, 1, 0.2)\n", - "\n", - " mm = flopy.plot.PlotMapView(model=mt3d)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " mm.plot_ibound()\n", - " cs1 = mm.contour_array(conc_mt3d[0], levels=levels, colors=\"r\")\n", - " plt.clabel(cs1, inline=1, fontsize=10)\n", - " cs2 = mm.contour_array(conc_mf6[0], levels=levels, colors=\"k\", linestyles=\":\")\n", - " plt.clabel(cs2, inline=1, fontsize=10)\n", - " labels = [\"MT3DMS\", \"MODFLOW 6\"]\n", - " lines = [cs1.collections[0], cs2.collections[0]]\n", - "\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " title = \"Comparison of MT3DMS and MF6 isoconcentration lines\"\n", - " ax2.legend(lines, labels, loc=\"upper left\")\n", - "\n", - " # draw line representing location of cross-section shown in previous figure\n", - " plt.plot([155, 300], [155, 155], \"k-\", lw=2)\n", - "\n", - " # Add labels to the plot\n", - " # style = dict(size=10, color='black')\n", - " # ax2.text(235, 140, \"Location of x-section \\nshown in Fig. x\", **style)\n", - "\n", - " letter = chr(ord(\"@\") + idx + 2)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(sim_name + \"-planView\", config.figure_ext),\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "81414927", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function that wraps all of the steps for each MT3DMS Example 10 Problem scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "02963123", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " mf2k5, mt3d, sim = build_model(example_name)\n", - "\n", - " write_model(mf2k5, mt3d, sim, silent=silent)\n", - "\n", - " success = run_model(mf2k5, mt3d, sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(mt3d, sim, idx)" - ] - }, - { - "cell_type": "markdown", - "id": "ba0182ca", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "nosetest - exclude block from this nosetest to the next nosetest" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "28968d7d", - "metadata": {}, - "outputs": [], - "source": [ - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "510c8c57", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e6fa2f97", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Two-Dimensional Transport in a Diagonal Flow Field\n", - " #\n", - " # Compares the standard finite difference solutions between MT3D MF 6\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dms-p06.ipynb b/notebooks/ex-gwt-mt3dms-p06.ipynb deleted file mode 100644 index ae567cba..00000000 --- a/notebooks/ex-gwt-mt3dms-p06.ipynb +++ /dev/null @@ -1,921 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "1cdf832a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Concentration at an Injection/Extraction Well, Comparison of MODFLOW 6 transport with MT3DMS\n", - "\n", - "The purpose of this script is to (1) recreate the example problems that were first\n", - "described in the 1999 MT3DMS report, and (2) compare MF6-GWT solutions to the\n", - "established MT3DMS solutions.\n", - "\n", - "Ten example problems appear in the 1999 MT3DMS manual, starting on page 130. This\n", - "notebook demonstrates example 10 from the list below:\n", - "\n", - " 1. One-Dimensional Transport in a Uniform Flow Field\n", - " 2. One-Dimensional Transport with Nonlinear or Nonequilibrium Sorption\n", - " 3. Two-Dimensional Transport in a Uniform Flow Field\n", - " 4. Two-Dimensional Transport in a Diagonal Flow Field\n", - " 5. Two-Dimensional Transport in a Radial Flow Field\n", - " 6. _Concentration at an Injection/Extraction Well_\n", - " 7. Three-Dimensional Transport in a Uniform Flow Field\n", - " 8. Two-Dimensional, Vertical Transport in a Heterogeneous Aquifer\n", - " 9. Two-Dimensional Application Example\n", - " 10. Three-Dimensional Field Case Study" - ] - }, - { - "cell_type": "markdown", - "id": "7cab4300", - "metadata": {}, - "source": [ - "### MODFLOW 6 GWT MT3DMS Example 6 Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "c94688d6", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "97bfd849", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7859401a", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "31d32d38", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "41b9afa9", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "614e34ee", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dusgs\"" - ] - }, - { - "cell_type": "markdown", - "id": "64e2f377", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "51ce5d3f", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 4.5)" - ] - }, - { - "cell_type": "markdown", - "id": "63ed6783", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2aa77cd6", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-mt3dms-p06\"" - ] - }, - { - "cell_type": "markdown", - "id": "84d76d11", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e8203344", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "b454629f", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f58419c3", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 1 # Number of layers\n", - "nrow = 31 # Number of rows\n", - "ncol = 31 # Number of columns\n", - "delr = 900.0 # Column width ($ft$)\n", - "delc = 900.0 # Row width ($ft$)\n", - "delz = 20.0 # Layer thickness ($ft$)\n", - "top = 0.0 # Top of the model ($ft$)\n", - "prsity = 0.35 # Porosity\n", - "dum1 = 2.5 # Length of the injection period ($years$)\n", - "dum2 = 7.5 # Length of the extraction period ($years$)\n", - "k11 = 432.0 # Horizontal hydraulic conductivity ($ft/d$)\n", - "qwell = 1.0 # Volumetric injection rate ($ft^3/d$)\n", - "cwell = 100.0 # Relative concentration of injected water ($\\%$)\n", - "al = 100.0 # Longitudinal dispersivity ($ft$)\n", - "trpt = 1.0 # Ratio of transverse to longitudinal dispersitivity" - ] - }, - { - "cell_type": "markdown", - "id": "38efc8a9", - "metadata": {}, - "source": [ - "Additional model input" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "975d04e4", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [912.5, 2737.5]\n", - "nper = len(perlen)\n", - "nstp = [365, 1095]\n", - "tsmult = [1.0, 1.0]\n", - "k11 = 0.005 * 86400 # established above, but explicitly writing out its origin here\n", - "sconc = 0.0\n", - "c0 = 0.0\n", - "dt0 = 56.25\n", - "dmcoef = 0\n", - "ath1 = al * trpt\n", - "botm = [top - delz] # Model geometry\n", - "k33 = k11 # Vertical hydraulic conductivity ($m/d$)\n", - "icelltype = 0\n", - "mixelm = -1\n", - "strt = np.zeros((nlay, nrow, ncol), dtype=float)" - ] - }, - { - "cell_type": "markdown", - "id": "1f6ac3ee", - "metadata": {}, - "source": [ - "Active model domain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "38b51421", - "metadata": {}, - "outputs": [], - "source": [ - "ibound_mf2k5 = np.ones((nlay, nrow, ncol), dtype=int) * -1\n", - "ibound_mf2k5[:, 1 : nrow - 1, 1 : ncol - 1] = 1\n", - "idomain = np.ones((nlay, nrow, ncol), dtype=int)\n", - "icbund = 1" - ] - }, - { - "cell_type": "markdown", - "id": "f62718ce", - "metadata": {}, - "source": [ - "Boundary conditions\n", - "MF2K5 pumping info:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d921fb1f", - "metadata": {}, - "outputs": [], - "source": [ - "qwell = 86400.0\n", - "welspd = {\n", - " 0: [[0, 15, 15, qwell]], # Well pumping info for MF2K5\n", - " 1: [[0, 15, 15, -qwell]],\n", - "}\n", - "cwell = 100.0\n", - "spd = {\n", - " 0: [0, 15, 15, cwell, 2], # Well pupming info for MT3DMS\n", - " 1: [0, 15, 15, 0.0, 2],\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef7e7c8d", - "metadata": {}, - "outputs": [], - "source": [ - "# MF6 pumping information\n", - "# (k, i, j), flow, conc\n", - "spd_mf6 = {0: [[(0, 15, 15), qwell, cwell]], 1: [[(0, 15, 15), -qwell, 0.0]]}" - ] - }, - { - "cell_type": "markdown", - "id": "78526241", - "metadata": {}, - "source": [ - "MF6 constant head boundaries:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3383e122", - "metadata": {}, - "outputs": [], - "source": [ - "chdspd = []\n", - "# Loop through the left & right sides.\n", - "for i in np.arange(nrow):\n", - " chdspd.append([(0, i, 0), strt[0, i, 0]])\n", - " chdspd.append([(0, i, ncol - 1), strt[0, i, ncol - 1]])\n", - "# Loop through the top & bottom while omitting the corner cells\n", - "for j in np.arange(1, ncol - 1):\n", - " chdspd.append([(0, 0, j), strt[0, 0, j]])\n", - " chdspd.append([(0, nrow - 1, j), strt[0, nrow - 1, j]])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8906350b", - "metadata": {}, - "outputs": [], - "source": [ - "chdspd = {0: chdspd}" - ] - }, - { - "cell_type": "markdown", - "id": "2e340341", - "metadata": {}, - "source": [ - "Solver settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6a83b0a2", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-6, 1e-6, 1.0\n", - "percel = 1.0 # HMOC parameters\n", - "itrack = 3\n", - "wd = 0.5\n", - "dceps = 1.0e-5\n", - "nplane = 1\n", - "npl = 0\n", - "nph = 16\n", - "npmin = 2\n", - "npmax = 32\n", - "dchmoc = 1.0e-3\n", - "nlsink = nplane\n", - "npsink = nph" - ] - }, - { - "cell_type": "markdown", - "id": "5c0bfde3", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c280f3d", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_rc = []\n", - "tdis_rc.append((perlen, nstp, 1.0))" - ] - }, - { - "cell_type": "markdown", - "id": "3784241d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, and run models and plot MT3DMS Example 10 Problem results\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eca76045", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, mixelm=0, silent=False):\n", - " if config.buildModel:\n", - " mt3d_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " modelname_mf = \"p06-mf\"\n", - "\n", - " # Instantiate the MODFLOW model\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=modelname_mf, model_ws=mt3d_ws, exe_name=exe_name_mf\n", - " )\n", - "\n", - " # Instantiate discretization package\n", - " # units: itmuni=4 (days), lenuni=2 (m)\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " nper=nper,\n", - " nstp=nstp,\n", - " perlen=perlen,\n", - " itmuni=4,\n", - " lenuni=1,\n", - " )\n", - "\n", - " # Instantiate basic package\n", - " flopy.modflow.ModflowBas(mf, ibound=ibound_mf2k5, strt=strt)\n", - "\n", - " # Instantiate layer property flow package\n", - " flopy.modflow.ModflowLpf(mf, hk=k11, laytyp=icelltype)\n", - "\n", - " # Instantiate well package\n", - " flopy.modflow.ModflowWel(mf, stress_period_data=welspd)\n", - "\n", - " # Instantiate solver package\n", - " flopy.modflow.ModflowSip(mf)\n", - "\n", - " # Instantiate link mass transport package (for writing linker file)\n", - " flopy.modflow.ModflowLmt(mf)\n", - "\n", - " # Transport\n", - " modelname_mt = \"p06-mt\"\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=modelname_mt,\n", - " model_ws=mt3d_ws,\n", - " exe_name=exe_name_mt,\n", - " modflowmodel=mf,\n", - " )\n", - "\n", - " # Instantiate basic transport package\n", - " flopy.mt3d.Mt3dBtn(\n", - " mt,\n", - " icbund=icbund,\n", - " prsity=prsity,\n", - " sconc=sconc,\n", - " nper=nper,\n", - " perlen=perlen,\n", - " dt0=dt0,\n", - " obs=[(0, 15, 15)],\n", - " )\n", - "\n", - " # Instatiate the advection package\n", - " flopy.mt3d.Mt3dAdv(\n", - " mt,\n", - " mixelm=mixelm,\n", - " dceps=dceps,\n", - " nplane=nplane,\n", - " npl=npl,\n", - " nph=nph,\n", - " npmin=npmin,\n", - " npmax=npmax,\n", - " nlsink=nlsink,\n", - " npsink=npsink,\n", - " percel=percel,\n", - " itrack=itrack,\n", - " wd=wd,\n", - " )\n", - "\n", - " # Instantiate the dispersion package\n", - " flopy.mt3d.Mt3dDsp(mt, al=al, trpt=trpt, dmcoef=dmcoef)\n", - "\n", - " # Instantiate the source/sink mixing package\n", - " flopy.mt3d.Mt3dSsm(mt, stress_period_data=spd)\n", - "\n", - " # Instantiate the GCG solver in MT3DMS\n", - " flopy.mt3d.Mt3dGcg(mt)\n", - "\n", - " # MODFLOW 6\n", - " name = \"p06-mf6\"\n", - " gwfname = \"gwf-\" + name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name=mf6exe)\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " for i in range(nper):\n", - " tdis_rc.append((perlen[i], nstp[i], tsmult[i]))\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"CG\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 storage package (steady flow conditions, so no actual storage, using to print values in .lst file)\n", - " flopy.mf6.ModflowGwfsto(gwf, ss=0, sy=0, filename=f\"{gwfname}.sto\")\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " # Instantiate the wel package\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " print_input=True,\n", - " print_flows=True,\n", - " stress_period_data=spd_mf6,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"WEL-1\",\n", - " filename=f\"{gwfname}.wel\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 groundwater transport package\n", - " gwtname = \"gwt_\" + name\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=gwtname,\n", - " model_nam_file=f\"{gwtname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # create iterative model solution and register the gwt model with it\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwtname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - "\n", - " # Instantiating MODFLOW 6 transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwtname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{gwtname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 transport advection package\n", - " if mixelm >= 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{gwtname}.adv\")\n", - "\n", - " # Instantiating MODFLOW 6 transport dispersion package\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " xt3d_off=True,\n", - " alh=al,\n", - " ath1=ath1,\n", - " filename=f\"{gwtname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport mass storage package (formerly \"reaction\" package in MT3DMS)\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=None,\n", - " bulk_density=None,\n", - " distcoef=None,\n", - " filename=f\"{gwtname}.mst\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport source-sink mixing package\n", - " sourcerecarray = [(\"WEL-1\", \"AUX\", \"CONCENTRATION\")]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray, filename=f\"{gwtname}.ssm\")\n", - "\n", - " # Instantiating MODFLOW 6 transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwtname}.cbc\",\n", - " concentration_filerecord=f\"{gwtname}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiate observation package (for transport)\n", - " obslist = [[\"bckgrnd_cn\", \"concentration\", (0, 15, 15)]]\n", - " obsdict = {f\"{gwtname}.obs.csv\": obslist}\n", - " obs = flopy.mf6.ModflowUtlobs(gwt, print_input=False, continuous=obsdict)\n", - "\n", - " # Instantiating MODFLOW 6 flow-transport exchange mechanism\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname,\n", - " exgmnameb=gwtname,\n", - " filename=f\"{name}.gwfgwt\",\n", - " )\n", - " return mf, mt, sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "96eeacca", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "af41a252", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(mf2k5, mt3d, sim, silent=True):\n", - " if config.writeModel:\n", - " mf2k5.write_input()\n", - " mt3d.write_input()\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "65892bc6", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1605e770", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(mf2k5, mt3d, sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = mf2k5.run_model(silent=silent)\n", - " success, buff = mt3d.run_model(silent=silent)\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "54e85f72", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4544bd3d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mt3d, mf6, idx, ax=None):\n", - " if config.plotModel:\n", - " mt3d_out_path = mt3d.model_ws\n", - " mf6_out_path = mf6.simulation_data.mfpath.get_sim_path()\n", - " mf6.simulation_data.mfpath.get_sim_path()\n", - "\n", - " # Get the MT3DMS observation output file\n", - " fname = os.path.join(mt3d_out_path, \"MT3D001.OBS\")\n", - " if os.path.isfile(fname):\n", - " cvt = mt3d.load_obs(fname)\n", - " else:\n", - " cvt = None\n", - "\n", - " # Get the MODFLOW 6 concentration observation output file\n", - " fname = os.path.join(mf6_out_path, list(mf6.model_names)[1] + \".obs.csv\")\n", - " mf6cobs = flopy.utils.Mf6Obs(fname).data\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_name = mf6.name\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - " if ax is None:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1)\n", - "\n", - " x = cvt[\"time\"] / 365.0\n", - " y = cvt[\"(1, 16, 16)\"]\n", - " # Pare down the list length to clean plot\n", - " x_pare = x[::20]\n", - " y_pare = y[::20]\n", - " ax.plot(x_pare, y_pare, label=\"Upstream FD\", marker=\"^\")\n", - "\n", - " # Add MF6 output\n", - " x_mf6 = mf6cobs[\"totim\"] / 365.0\n", - " y_mf6 = mf6cobs[\"BCKGRND_CN\"]\n", - " x_mf6_pare = x_mf6[::20]\n", - " y_mf6_pare = y_mf6[::20]\n", - " ax.plot(\n", - " x_mf6_pare,\n", - " y_mf6_pare,\n", - " label=\"MODFLOW 6\",\n", - " marker=\"x\",\n", - " linestyle=\":\",\n", - " )\n", - "\n", - " plt.xlim(0, 10)\n", - " plt.ylim(0, 100.0)\n", - " plt.xlabel(\"Time, in years\")\n", - " plt.ylabel(\"Normalized Concentration, in percent\")\n", - " plt.legend()\n", - " title = \"Calculated Concentration at an Injection/Pumping Well\"\n", - "\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "9e5e0296", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function that wraps all of the steps for each MT3DMS Example 10 Problem scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7228b557", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " mf2k5, mt3d, sim = build_model(example_name, mixelm=mixelm)\n", - "\n", - " write_model(mf2k5, mt3d, sim, silent=silent)\n", - "\n", - " success = run_model(mf2k5, mt3d, sim, silent=silent)\n", - "\n", - " if success:\n", - " plot_results(mt3d, sim, idx)" - ] - }, - { - "cell_type": "markdown", - "id": "f452fc0d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "nosetest - exclude block from this nosetest to the next nosetest" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ff50e5ef", - "metadata": {}, - "outputs": [], - "source": [ - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "cdc5286c", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8c3a31fc", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Two-Dimensional Transport in a Diagonal Flow Field\n", - " #\n", - " # Compares the standard finite difference solutions between MT3D MF 6\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dms-p07.ipynb b/notebooks/ex-gwt-mt3dms-p07.ipynb deleted file mode 100644 index fc973818..00000000 --- a/notebooks/ex-gwt-mt3dms-p07.ipynb +++ /dev/null @@ -1,945 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "ec961a25", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Three Dimensional Transport in a Uniform Flow Field, Comparison of MODFLOW 6 transport with MT3DMS\n", - "\n", - "The purpose of this script is to (1) recreate the example problems that were first\n", - "described in the 1999 MT3DMS report, and (2) compare MF6-GWT solutions to the\n", - "established MT3DMS solutions.\n", - "\n", - "Ten example problems appear in the 1999 MT3DMS manual, starting on page 130. This\n", - "notebook demonstrates example 10 from the list below:\n", - "\n", - " 1. One-Dimensional Transport in a Uniform Flow Field\n", - " 2. One-Dimensional Transport with Nonlinear or Nonequilibrium Sorption\n", - " 3. Two-Dimensional Transport in a Uniform Flow Field\n", - " 4. Two-Dimensional Transport in a Diagonal Flow Field\n", - " 5. Two-Dimensional Transport in a Radial Flow Field\n", - " 6. Concentration at an Injection/Extraction Well\n", - " 7. _Three-Dimensional Transport in a Uniform Flow Field_\n", - " 8. Two-Dimensional, Vertical Transport in a Heterogeneous Aquifer\n", - " 9. Two-Dimensional Application Example\n", - " 10. Three-Dimensional Field Case Study" - ] - }, - { - "cell_type": "markdown", - "id": "5f279cf1", - "metadata": {}, - "source": [ - "### MODFLOW 6 GWT MT3DMS Example 6 Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "d824665c", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef80d501", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "49fea876", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "28928fca", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "01500510", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0b01c65c", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dusgs\"" - ] - }, - { - "cell_type": "markdown", - "id": "9a87e7d6", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef9542d0", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (4, 8)" - ] - }, - { - "cell_type": "markdown", - "id": "20f6b275", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b6132cd4", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-mt3dms-p07\"" - ] - }, - { - "cell_type": "markdown", - "id": "da4a5ca8", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "96d3ba2b", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "0cb9d75b", - "metadata": {}, - "source": [ - "Table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "be062106", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 8 # Number of layers\n", - "nrow = 15 # Number of rows\n", - "ncol = 21 # Number of columns\n", - "delr = 10.0 # Column width ($m$)\n", - "delc = 10.0 # Row width ($m$)\n", - "delz = 10.0 # Layer thickness ($m$)\n", - "top = 0.0 # Top of the model ($m$)\n", - "prsity = 0.2 # Porosity\n", - "k11 = 0.5 # Horizontal hydraulic conductivity ($m/d$)\n", - "qwell = 0.5 # Volumetric injection rate ($m^3/d$)\n", - "al = 10.0 # Longitudinal dispersivity ($m$)\n", - "trpt = 0.3 # Ratio of transverse to longitudinal dispersitivity\n", - "trpv = 0.3 # Ratio of vertical to longitudinal dispersitivity\n", - "perlen = 100.0 # Simulation time ($days$)" - ] - }, - { - "cell_type": "markdown", - "id": "62ebea5e", - "metadata": {}, - "source": [ - "Additional model input" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9746d165", - "metadata": {}, - "outputs": [], - "source": [ - "perlen = [100]\n", - "nper = len(perlen)\n", - "nstp = [10]\n", - "tsmult = [1.0]\n", - "sconc = 0.0\n", - "c0 = 0.0\n", - "dt0 = 10.0\n", - "dmcoef = 0.0\n", - "ath1 = al * trpt\n", - "atv = al * trpv\n", - "botm = [-delz * k for k in range(1, nlay + 1)]\n", - "k33 = k11 # Vertical hydraulic conductivity ($m/d$)\n", - "icelltype = 0\n", - "mixelm = -1\n", - "# Initial conditions\n", - "strt = np.zeros((nlay, nrow, ncol), dtype=float)\n", - "Lx = (ncol - 1) * delr\n", - "v = 1.0 / 3.0\n", - "prsity = 0.2\n", - "q = v * prsity\n", - "h1 = q * Lx\n", - "strt[:, :, 0] = h1" - ] - }, - { - "cell_type": "markdown", - "id": "a2bc9354", - "metadata": {}, - "source": [ - "Active model domain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6a094ba4", - "metadata": {}, - "outputs": [], - "source": [ - "ibound_mf2k5 = np.ones((nlay, nrow, ncol), dtype=int)\n", - "ibound_mf2k5[:, :, 0] = -1\n", - "ibound_mf2k5[:, :, -1] = -1\n", - "idomain = np.ones((nlay, nrow, ncol), dtype=int)\n", - "icbund = 1" - ] - }, - { - "cell_type": "markdown", - "id": "c6408c27", - "metadata": {}, - "source": [ - "Boundary conditions\n", - "MF2K5 pumping info:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7a87d9f5", - "metadata": {}, - "outputs": [], - "source": [ - "qwell = 0.5\n", - "welspd = {\n", - " 0: [[6, 7, 2, qwell]], # Well pumping info for MF2K5\n", - "}\n", - "cwell = 100.0\n", - "spd = {\n", - " 0: [6, 7, 2, cwell, 2], # Well pupming info for MT3DMS\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "1d20430f", - "metadata": {}, - "source": [ - "MF6 pumping information" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "83f9f436", - "metadata": {}, - "outputs": [], - "source": [ - "# (k, i, j), flow, conc\n", - "spd_mf6 = {0: [[(6, 7, 2), qwell, cwell]]}" - ] - }, - { - "cell_type": "markdown", - "id": "05598ccb", - "metadata": {}, - "source": [ - "MF6 constant head boundaries:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "951503ed", - "metadata": {}, - "outputs": [], - "source": [ - "chdspd = []\n", - "# Loop through the left & right sides.\n", - "for k in np.arange(nlay):\n", - " for i in np.arange(nrow):\n", - " # (l, r, c), head, conc\n", - " chdspd.append([(k, i, 0), strt[k, i, 0], 0.0])\n", - " chdspd.append([(k, i, ncol - 1), strt[k, i, ncol - 1], 0.0])\n", - "chdspd = {0: chdspd}" - ] - }, - { - "cell_type": "markdown", - "id": "12ae0670", - "metadata": {}, - "source": [ - "Solver settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9acff24c", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-6, 1e-6, 1.0\n", - "percel = 1.0 # HMOC parameters\n", - "itrack = 3\n", - "wd = 0.5\n", - "dceps = 1.0e-5\n", - "nplane = 1\n", - "npl = 0\n", - "nph = 16\n", - "npmin = 2\n", - "npmax = 32\n", - "dchmoc = 1.0e-3\n", - "nlsink = nplane\n", - "npsink = nph" - ] - }, - { - "cell_type": "markdown", - "id": "e68203bf", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "79234a14", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_rc = []\n", - "tdis_rc.append((perlen, nstp, 1.0))" - ] - }, - { - "cell_type": "markdown", - "id": "3c22bcf6", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, and run models and plot MT3DMS Example 10 Problem results\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b986dd5a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, mixelm=0, silent=False):\n", - " if config.buildModel:\n", - " mt3d_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " modelname_mf = \"p07-mf\"\n", - "\n", - " # Instantiate the MODFLOW model\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=modelname_mf, model_ws=mt3d_ws, exe_name=exe_name_mf\n", - " )\n", - "\n", - " # Instantiate discretization package\n", - " # units: itmuni=4 (days), lenuni=2 (m)\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " nper=nper,\n", - " nstp=nstp,\n", - " perlen=perlen,\n", - " itmuni=4,\n", - " lenuni=2,\n", - " )\n", - "\n", - " # Instantiate basic package\n", - " flopy.modflow.ModflowBas(mf, ibound=ibound_mf2k5, strt=strt)\n", - "\n", - " # Instantiate layer property flow package\n", - " flopy.modflow.ModflowLpf(mf, hk=k11, laytyp=icelltype)\n", - "\n", - " # Instantiate well package\n", - " flopy.modflow.ModflowWel(mf, stress_period_data=welspd)\n", - "\n", - " # Instantiate solver package\n", - " flopy.modflow.ModflowPcg(mf)\n", - "\n", - " # Instantiate link mass transport package (for writing linker file)\n", - " flopy.modflow.ModflowLmt(mf)\n", - "\n", - " # Transport\n", - " modelname_mt = \"p07-mt\"\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=modelname_mt,\n", - " model_ws=mt3d_ws,\n", - " exe_name=exe_name_mt,\n", - " modflowmodel=mf,\n", - " )\n", - "\n", - " # Instantiate basic transport package\n", - " flopy.mt3d.Mt3dBtn(\n", - " mt,\n", - " icbund=icbund,\n", - " prsity=prsity,\n", - " sconc=sconc,\n", - " nper=nper,\n", - " perlen=perlen,\n", - " dt0=dt0,\n", - " )\n", - "\n", - " # Instatiate the advection package\n", - " flopy.mt3d.Mt3dAdv(\n", - " mt,\n", - " mixelm=mixelm,\n", - " dceps=dceps,\n", - " nplane=nplane,\n", - " npl=npl,\n", - " nph=nph,\n", - " npmin=npmin,\n", - " npmax=npmax,\n", - " nlsink=nlsink,\n", - " npsink=npsink,\n", - " percel=percel,\n", - " itrack=itrack,\n", - " wd=wd,\n", - " )\n", - "\n", - " # Instantiate the dispersion package\n", - " flopy.mt3d.Mt3dDsp(mt, al=al, trpt=trpt, trpv=trpv, dmcoef=dmcoef)\n", - "\n", - " # Instantiate the source/sink mixing package\n", - " flopy.mt3d.Mt3dSsm(mt, stress_period_data=spd)\n", - "\n", - " # Instantiate the GCG solver in MT3DMS\n", - " flopy.mt3d.Mt3dGcg(mt)\n", - "\n", - " # MODFLOW 6\n", - " name = \"p07-mf6\"\n", - " gwfname = \"gwf-\" + name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name=mf6exe)\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " for i in range(nper):\n", - " tdis_rc.append((perlen[i], nstp[i], tsmult[i]))\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"CG\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k33,\n", - " save_specific_discharge=True,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " # Instantiate the wel package\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " print_input=True,\n", - " print_flows=True,\n", - " stress_period_data=spd_mf6,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"WEL-1\",\n", - " filename=f\"{gwfname}.wel\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 groundwater transport package\n", - " gwtname = \"gwt-\" + name\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=gwtname,\n", - " model_nam_file=f\"{gwtname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # create iterative model solution and register the gwt model with it\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwtname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - "\n", - " # Instantiating MODFLOW 6 transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwtname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{gwtname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 transport advection package\n", - " if mixelm >= 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{gwtname}.adv\")\n", - "\n", - " # Instantiating MODFLOW 6 transport dispersion package\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=al,\n", - " ath1=ath1,\n", - " atv=atv,\n", - " filename=f\"{gwtname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport mass storage package (formerly \"reaction\" package in MT3DMS)\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=None,\n", - " bulk_density=None,\n", - " distcoef=None,\n", - " filename=f\"{gwtname}.mst\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport source-sink mixing package\n", - " sourcerecarray = [\n", - " (\"WEL-1\", \"AUX\", \"CONCENTRATION\"),\n", - " (\"CHD-1\", \"AUX\", \"CONCENTRATION\"),\n", - " ]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray, filename=f\"{gwtname}.ssm\")\n", - "\n", - " # Instantiating MODFLOW 6 transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwtname}.cbc\",\n", - " concentration_filerecord=f\"{gwtname}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 flow-transport exchange mechanism\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname,\n", - " exgmnameb=gwtname,\n", - " filename=f\"{name}.gwfgwt\",\n", - " )\n", - " return mf, mt, sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "960051e8", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9f9e2110", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(mf2k5, mt3d, sim, silent=True):\n", - " if config.writeModel:\n", - " mf2k5.write_input()\n", - " mt3d.write_input()\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "efc2ac0d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1ba6af12", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(mf2k5, mt3d, sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = mf2k5.run_model(silent=silent)\n", - " success, buff = mt3d.run_model(silent=silent)\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "e1287207", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0128746d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mf2k5, mt3d, mf6, idx, ax=None):\n", - " if config.plotModel:\n", - " mt3d_out_path = mt3d.model_ws\n", - " mf6_out_path = mf6.simulation_data.mfpath.get_sim_path()\n", - " mf6.simulation_data.mfpath.get_sim_path()\n", - "\n", - " # Get the MT3DMS concentration output\n", - " fname_mt3d = os.path.join(mt3d_out_path, \"MT3D001.UCN\")\n", - " ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d)\n", - " conc_mt3d = ucnobj_mt3d.get_alldata()\n", - "\n", - " # Get the MF6 concentration output\n", - " gwt = mf6.get_model(list(mf6.model_names)[1])\n", - " ucnobj_mf6 = gwt.output.concentration()\n", - " conc_mf6 = ucnobj_mf6.get_alldata()\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_name = mf6.name\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - " axWasNone = False\n", - " if ax is None:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(3, 1, 1, aspect=\"equal\")\n", - " axWasNone = True\n", - "\n", - " ilay = 4\n", - " mm = flopy.plot.PlotMapView(ax=ax, model=mf2k5, layer=ilay)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " mm.plot_ibound()\n", - " cs1 = mm.contour_array(\n", - " conc_mt3d[0], levels=[0.01, 0.05, 0.15, 0.50], colors=\"k\"\n", - " )\n", - " cs2 = mm.contour_array(\n", - " conc_mf6[0],\n", - " levels=[0.01, 0.05, 0.15, 0.50],\n", - " colors=\"r\",\n", - " linestyles=\":\",\n", - " )\n", - " plt.clabel(cs1)\n", - " plt.xlabel(\"DISTANCE ALONG X-AXIS, IN METERS\")\n", - " plt.ylabel(\"DISTANCE ALONG Y-AXIS, IN METERS\")\n", - " title = f\"Layer {ilay + 1}\"\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " labels = [\"MT3DMS\", \"MODFLOW 6\"]\n", - " lines = [cs1.collections[0], cs2.collections[0]]\n", - " ax.legend(lines, labels, loc=\"upper center\")\n", - "\n", - " if axWasNone:\n", - " ax = fig.add_subplot(3, 1, 2, aspect=\"equal\")\n", - "\n", - " ilay = 5\n", - " mm = flopy.plot.PlotMapView(ax=ax, model=mf2k5, layer=ilay)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " mm.plot_ibound()\n", - " cs = mm.contour_array(conc_mt3d[0], levels=[0.01, 0.05, 0.15, 0.50], colors=\"k\")\n", - " cs = mm.contour_array(\n", - " conc_mf6[0],\n", - " levels=[0.01, 0.05, 0.15, 0.50],\n", - " colors=\"r\",\n", - " linestyles=\":\",\n", - " )\n", - " plt.clabel(cs)\n", - " plt.xlabel(\"DISTANCE ALONG X-AXIS, IN METERS\")\n", - " plt.ylabel(\"DISTANCE ALONG Y-AXIS, IN METERS\")\n", - " title = f\"Layer {ilay + 1}\"\n", - " letter = chr(ord(\"@\") + idx + 2)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " if axWasNone:\n", - " ax = fig.add_subplot(3, 1, 3, aspect=\"equal\")\n", - "\n", - " ilay = 6\n", - " mm = flopy.plot.PlotMapView(ax=ax, model=mf2k5, layer=ilay)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " mm.plot_ibound()\n", - " cs = mm.contour_array(conc_mt3d[0], levels=[0.01, 0.05, 0.15, 0.50], colors=\"k\")\n", - " cs = mm.contour_array(\n", - " conc_mf6[0],\n", - " levels=[0.01, 0.05, 0.15, 0.50],\n", - " colors=\"r\",\n", - " linestyles=\":\",\n", - " )\n", - " plt.clabel(cs)\n", - " plt.xlabel(\"DISTANCE ALONG X-AXIS, IN METERS\")\n", - " plt.ylabel(\"DISTANCE ALONG Y-AXIS, IN METERS\")\n", - " title = f\"Layer {ilay + 1}\"\n", - " letter = chr(ord(\"@\") + idx + 3)\n", - " fs.heading(letter=letter, heading=title)\n", - " plt.plot(\n", - " mf2k5.modelgrid.xcellcenters[7, 2],\n", - " mf2k5.modelgrid.ycellcenters[7, 2],\n", - " \"ko\",\n", - " )\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " f\"{sim_name}{config.figure_ext}\",\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "f6a27ad6", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function that wraps all of the steps for each MT3DMS Example 10 Problem scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d404718e", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " mf2k5, mt3d, sim = build_model(example_name, mixelm=mixelm)\n", - " write_model(mf2k5, mt3d, sim, silent=silent)\n", - " success = run_model(mf2k5, mt3d, sim, silent=silent)\n", - " if success:\n", - " plot_results(mf2k5, mt3d, sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0fa8b08c", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "aaa6f84a", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "11efdaa1", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Two-Dimensional Transport in a Diagonal Flow Field\n", - " #\n", - " # Compares the standard finite difference solutions between MT3D MF 6\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dms-p08.ipynb b/notebooks/ex-gwt-mt3dms-p08.ipynb deleted file mode 100644 index 097b03d9..00000000 --- a/notebooks/ex-gwt-mt3dms-p08.ipynb +++ /dev/null @@ -1,1069 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f139990a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Two Dimensional Vertical Transport in a Heterogeneous Aquifer, Comparison of MODFLOW 6 transport with MT3DMS\n", - "\n", - "The purpose of this script is to (1) recreate the example problems that were first\n", - "described in the 1999 MT3DMS report, and (2) compare MF6-GWT solutions to the\n", - "established MT3DMS solutions.\n", - "\n", - "Ten example problems appear in the 1999 MT3DMS manual, starting on page 130.\n", - "This notebook demonstrates example 10 from the list below:\n", - "\n", - " 1. One-Dimensional Transport in a Uniform Flow Field\n", - " 2. One-Dimensional Transport with Nonlinear or Nonequilibrium Sorption\n", - " 3. Two-Dimensional Transport in a Uniform Flow Field\n", - " 4. Two-Dimensional Transport in a Diagonal Flow Field\n", - " 5. Two-Dimensional Transport in a Radial Flow Field\n", - " 6. Concentration at an Injection/Extraction Well\n", - " 7. Three-Dimensional Transport in a Uniform Flow Field\n", - " 8. _Two-Dimensional, Vertical Transport in a Heterogeneous Aquifer_\n", - " 9. Two-Dimensional Application Example\n", - " 10. Three-Dimensional Field Case Study" - ] - }, - { - "cell_type": "markdown", - "id": "2dda63c0", - "metadata": {}, - "source": [ - "### MODFLOW 6 GWT MT3DMS Example 6 Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "7385f060", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aa8d5ff4", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "30efbd15", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "ad3c7c53", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "36b68163", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure\n", - "from flopy.utils.util_array import read1d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c69b1d34", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dusgs\"" - ] - }, - { - "cell_type": "markdown", - "id": "fef231ef", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ce47e66f", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (5, 7)" - ] - }, - { - "cell_type": "markdown", - "id": "ce11a766", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ec1344be", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-mt3dms-p08\"" - ] - }, - { - "cell_type": "markdown", - "id": "89aa6849", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dca3c4f6", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "a063915f", - "metadata": {}, - "source": [ - "Table MODFLOW 6 GWT MT3DMS Example 8" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "665cea58", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 27 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 50 # Number of columns\n", - "delr = 5.0 # Column width ($m$)\n", - "delc = 1.0 # Row width ($m$)\n", - "delz = 0.25 # Layer thickness ($m$)\n", - "top = 6.75 # Top of the model ($m$)\n", - "prsity = 0.35 # Porosity\n", - "dm = 5.0e-4 # Horiz. hyd. conductivity of fine grain material ($cm/sec$)\n", - "dm = 1.0e-2 # Horiz. hyd. conductivity of medium grain material ($cm/sec$)\n", - "rech = 10.0 # Applied recharge rate ($cm/yr$)\n", - "al = 0.5 # Longitudinal dispersivity ($m$)\n", - "tral = 0.005 # Transverse vertical dispersivity ($m$)\n", - "dmcoef = 1.34e-5 # Effective diffusion coefficient ($cm^2/sec$)\n", - "perlen = 20.0 # Simulation time ($years$)" - ] - }, - { - "cell_type": "markdown", - "id": "61499810", - "metadata": {}, - "source": [ - "Additional model input" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1604a980", - "metadata": {}, - "outputs": [], - "source": [ - "k1 = 5e-4 / 100.0 * 86400 # m/d\n", - "k2 = 1e-2 / 100.0 * 86400 # m/d\n", - "k11 = k1 * np.ones((nlay, nrow, ncol), dtype=float)\n", - "k11[11:19, :, 0:24] = k2\n", - "k11[11:19, :, 36:] = k2\n", - "laytyp = 6 * [1] + 21 * [0]\n", - "# Setting starting head information\n", - "f = open(os.path.join(\"..\", \"data\", \"ex-gwt-mt3dms-p08\", \"p08shead.dat\"))\n", - "strt = np.empty((nlay * ncol), dtype=float)\n", - "strt = read1d(f, strt).reshape((nlay, nrow, ncol))\n", - "f.close()\n", - "# Active model domain\n", - "ibound = np.ones((nlay, nrow, ncol), dtype=int)\n", - "ibound[5:, :, -1] = -1\n", - "ibound[strt < 0] = 0\n", - "idomain = 1\n", - "# Fow boundary condition\n", - "rech = 10.0 / 100 / 365 # cm/yr -> m/d\n", - "# Transport relate`xd\n", - "trpt = 0.01 # Ratio of transverse to longitudinal dispersitivity\n", - "trpv = 0.01 # Ratio of vertical to longitudinal dispersitivity\n", - "dmcoef = 1.34e-5 / 100 / 100 * 86400 # cm^2/s -> m^2/d\n", - "ath1 = al * trpt\n", - "atv = al * trpv\n", - "# Time variables\n", - "perlen = [5 * 365, 15 * 365]\n", - "nper = len(perlen)\n", - "nstp = [365, 1095]\n", - "tsmult = [1.0, 1.0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9674ce5e", - "metadata": {}, - "outputs": [], - "source": [ - "sconc = 0.0\n", - "c0 = 0.0\n", - "botm = [top - delz * k for k in range(1, nlay + 1)]\n", - "k33 = k11 # Vertical hydraulic conductivity ($m/d$)\n", - "icelltype = 6 * [1] + 21 * [0]\n", - "mixelm = -1" - ] - }, - { - "cell_type": "markdown", - "id": "dd61b288", - "metadata": {}, - "source": [ - "Boundary conditions\n", - "MF6 constant head boundaries:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "83b50961", - "metadata": {}, - "outputs": [], - "source": [ - "chdspd = []\n", - "# Left side of model domain is no flow; right side uses constant heads\n", - "for k in np.arange(nlay):\n", - " if strt[k, 0, -1] != -999:\n", - " # (l, r, c), head, conc\n", - " chdspd.append([(k, 0, ncol - 1), strt[k, 0, -1], 0.0])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6c57c992", - "metadata": {}, - "outputs": [], - "source": [ - "chdspd = {0: chdspd}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "03fa6dfd", - "metadata": {}, - "outputs": [], - "source": [ - "# SSM related input data\n", - "crch1 = np.zeros((nrow, ncol), dtype=float)\n", - "crch1[0, 9:18] = 1.0\n", - "cnc0 = [(0, 0, j, 1, -1) for j in range(8, 16)]\n", - "cnc1 = [(0, 0, j, 0.0, -1) for j in range(8, 16)]\n", - "ssmspd = {0: cnc0, 1: cnc1}\n", - "# Setup constant concentration information for MF6\n", - "cncspd_1 = []\n", - "cncspd_2 = []\n", - "cnc_1 = 1.0 # t <= 5 yrs\n", - "cnc_2 = 0.0 # t > 5 yrs\n", - "for col in np.arange(8, 16):\n", - " cncspd_1.append([(0, 0, col), cnc_1]) # t <= 5 yrs\n", - " cncspd_2.append([(0, 0, col), cnc_2]) # t > 5 yrs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "36a02f0b", - "metadata": {}, - "outputs": [], - "source": [ - "cncspd = {0: cncspd_1, 1: cncspd_2}" - ] - }, - { - "cell_type": "markdown", - "id": "694778a0", - "metadata": {}, - "source": [ - "Solver settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d6a5bfd0", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-6, 1e-6, 1.0\n", - "percel = 1.0 # HMOC parameters\n", - "itrack = 3\n", - "wd = 0.5\n", - "dceps = 1.0e-5\n", - "nplane = 0\n", - "npl = 0\n", - "nph = 10\n", - "npmin = 2\n", - "npmax = 20\n", - "dchmoc = 1.0e-3\n", - "nlsink = nplane\n", - "npsink = nph" - ] - }, - { - "cell_type": "markdown", - "id": "f9c687b5", - "metadata": {}, - "source": [ - "Static temporal data used by TDIS file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "be8143e9", - "metadata": {}, - "outputs": [], - "source": [ - "tdis_rc = []\n", - "tdis_rc.append((perlen, nstp, 1.0))" - ] - }, - { - "cell_type": "markdown", - "id": "f14454f5", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, and run models and plot MT3DMS Example 8\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cebda8c4", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, mixelm=0, silent=False):\n", - " if config.buildModel:\n", - " print(f\"Building mf2005 model...{sim_name}\")\n", - " mt3d_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " modelname_mf = \"p08-mf\"\n", - "\n", - " # Instantiate the MODFLOW model\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=modelname_mf, model_ws=mt3d_ws, exe_name=exe_name_mf\n", - " )\n", - "\n", - " # Instantiate discretization package\n", - " # units: itmuni=4 (days), lenuni=2 (m)\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " nper=nper,\n", - " nstp=nstp,\n", - " perlen=perlen,\n", - " itmuni=4,\n", - " lenuni=2,\n", - " steady=[False, False],\n", - " )\n", - "\n", - " # Instantiate basic package\n", - " flopy.modflow.ModflowBas(mf, ibound=ibound, strt=strt)\n", - "\n", - " # Instantiate layer property flow package\n", - " flopy.modflow.ModflowLpf(mf, hk=k11, vka=k11, laytyp=icelltype)\n", - "\n", - " # Instantiate recharge package\n", - " flopy.modflow.ModflowRch(mf, rech=rech)\n", - "\n", - " # Instantiate solver package\n", - " flopy.modflow.ModflowPcg(mf)\n", - "\n", - " # Instantiate link mass transport package (for writing linker file)\n", - " flopy.modflow.ModflowLmt(mf)\n", - "\n", - " # Transport\n", - " print(f\"Building mt3d-usgs model...{sim_name}\")\n", - " modelname_mt = \"p08_mt\"\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=modelname_mt,\n", - " model_ws=mt3d_ws,\n", - " exe_name=exe_name_mt,\n", - " modflowmodel=mf,\n", - " )\n", - "\n", - " # Instantiate basic transport package\n", - " flopy.mt3d.Mt3dBtn(\n", - " mt,\n", - " icbund=1,\n", - " prsity=prsity,\n", - " sconc=sconc,\n", - " nper=nper,\n", - " perlen=perlen,\n", - " timprs=np.arange(1, 21) * 365,\n", - " dt0=5,\n", - " )\n", - "\n", - " # Instatiate the advection package\n", - " flopy.mt3d.Mt3dAdv(\n", - " mt,\n", - " mixelm=mixelm,\n", - " dceps=dceps,\n", - " nplane=nplane,\n", - " npl=npl,\n", - " nph=nph,\n", - " npmin=npmin,\n", - " npmax=npmax,\n", - " nlsink=nlsink,\n", - " npsink=npsink,\n", - " percel=percel,\n", - " itrack=itrack,\n", - " wd=wd,\n", - " )\n", - "\n", - " # Instantiate the dispersion package\n", - " flopy.mt3d.Mt3dDsp(mt, al=al, trpt=trpt, trpv=trpv, dmcoef=dmcoef)\n", - "\n", - " # Instantiate the source/sink mixing package\n", - " flopy.mt3d.Mt3dSsm(mt, stress_period_data=ssmspd)\n", - "\n", - " # Instantiate the GCG solver in MT3DMS\n", - " flopy.mt3d.Mt3dGcg(mt)\n", - "\n", - " # MODFLOW 6\n", - " print(f\"Building mf6gwt model...{sim_name}\")\n", - " name = \"p08_mf6\"\n", - " gwfname = \"gwf_\" + name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name=mf6exe)\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " for i in range(nper):\n", - " tdis_rc.append((perlen[i], nstp[i], tsmult[i]))\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " complexity=\"complex\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"dbd\",\n", - " linear_acceleration=\"BICGSTAB\",\n", - " under_relaxation_theta=0.7,\n", - " under_relaxation_kappa=0.08,\n", - " under_relaxation_gamma=0.05,\n", - " under_relaxation_momentum=0.0,\n", - " backtracking_number=20,\n", - " backtracking_tolerance=2.0,\n", - " backtracking_reduction_factor=0.2,\n", - " backtracking_residual_limit=5.0e-4,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=\"0.0001 relative_rclose\",\n", - " inner_maximum=ninner,\n", - " relaxation_factor=relax,\n", - " number_orthogonalizations=2,\n", - " preconditioner_levels=8,\n", - " preconditioner_drop_tolerance=0.001,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " icelltype=icelltype,\n", - " k=k11,\n", - " k33=k11,\n", - " save_specific_discharge=True,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiate storage package\n", - " sto = flopy.mf6.ModflowGwfsto(gwf, ss=0, sy=0)\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " # Instantiate recharge package\n", - " flopy.mf6.ModflowGwfrcha(\n", - " gwf,\n", - " print_flows=True,\n", - " recharge=rech,\n", - " pname=\"RCH-1\",\n", - " filename=f\"{gwfname}.rch\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 groundwater transport package\n", - " gwtname = \"gwt_\" + name\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=gwtname,\n", - " model_nam_file=f\"{gwtname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # create iterative model solution and register the gwt model with it\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " complexity=\"complex\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"dbd\",\n", - " linear_acceleration=\"BICGSTAB\",\n", - " under_relaxation_theta=0.7,\n", - " under_relaxation_kappa=0.08,\n", - " under_relaxation_gamma=0.05,\n", - " under_relaxation_momentum=0.0,\n", - " backtracking_number=20,\n", - " backtracking_tolerance=2.0,\n", - " backtracking_reduction_factor=0.2,\n", - " backtracking_residual_limit=5.0e-4,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=\"0.0001 relative_rclose\",\n", - " inner_maximum=ninner,\n", - " relaxation_factor=relax,\n", - " number_orthogonalizations=2,\n", - " preconditioner_levels=8,\n", - " preconditioner_drop_tolerance=0.001,\n", - " filename=f\"{gwtname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - "\n", - " # Instantiating MODFLOW 6 transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwtname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{gwtname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 transport advection package\n", - " if mixelm >= 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{gwtname}.adv\")\n", - "\n", - " # Instantiating MODFLOW 6 transport dispersion package\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=al,\n", - " ath1=ath1,\n", - " atv=atv,\n", - " filename=f\"{gwtname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport mass storage package\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=None,\n", - " bulk_density=None,\n", - " distcoef=None,\n", - " filename=f\"{gwtname}.mst\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport source-sink mixing package\n", - " sourcerecarray = [(\"CHD-1\", \"AUX\", \"CONCENTRATION\")]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray, filename=f\"{gwtname}.ssm\")\n", - "\n", - " # Instantiating MODFLOW 6 transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwtname}.cbc\",\n", - " concentration_filerecord=f\"{gwtname}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[\n", - " (\"CONCENTRATION\", \"LAST\"),\n", - " (\n", - " \"CONCENTRATION\",\n", - " \"STEPS\",\n", - " \"73\",\n", - " \"146\",\n", - " \"219\",\n", - " \"292\",\n", - " \"365\",\n", - " \"438\",\n", - " \"511\",\n", - " \"584\",\n", - " \"657\",\n", - " \"730\",\n", - " \"803\",\n", - " \"876\",\n", - " \"949\",\n", - " \"1022\",\n", - " \"1095\",\n", - " \"1168\",\n", - " \"1241\",\n", - " \"1314\",\n", - " \"1387\",\n", - " \"1460\",\n", - " ),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiate constant concentration at upper boundary.\n", - " flopy.mf6.ModflowGwtcnc(\n", - " gwt,\n", - " print_flows=True,\n", - " stress_period_data=cncspd,\n", - " pname=\"CNC-1\",\n", - " filename=f\"{gwtname}.cnc\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 flow-transport exchange mechanism\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname,\n", - " exgmnameb=gwtname,\n", - " filename=f\"{name}.gwfgwt\",\n", - " )\n", - " return mf, mt, sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "13788f38", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1211e546", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(mf2k5, mt3d, sim, silent=True):\n", - " if config.writeModel:\n", - " mf2k5.write_input()\n", - " mt3d.write_input()\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "b8bbf35a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "230a8414", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(mf2k5, mt3d, sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = mf2k5.run_model(silent=silent)\n", - " success, buff = mt3d.run_model(silent=silent)\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "0d63c76b", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6714448f", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mf2k5, mt3d, mf6, idx, ax=None):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " mt3d_out_path = mt3d.model_ws\n", - " mf6_out_path = mf6.simulation_data.mfpath.get_sim_path()\n", - " mf6.simulation_data.mfpath.get_sim_path()\n", - "\n", - " # Get the MT3DMS concentration output\n", - " fname_mt3d = os.path.join(mt3d_out_path, \"MT3D001.UCN\")\n", - " ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d)\n", - " conc_mt3d = ucnobj_mt3d.get_alldata()\n", - "\n", - " # Get the MF6 concentration output\n", - " gwt = mf6.get_model(list(mf6.model_names)[1])\n", - " ucnobj_mf6 = gwt.output.concentration()\n", - " conc_mf6 = ucnobj_mf6.get_alldata()\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_name = mf6.name\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - "\n", - " hk = mf2k5.lpf.hk.array\n", - " # Which year to plot?:\n", - " yr_idx = [7, 11, 19] # 0-based\n", - "\n", - " contourLevels = np.arange(0.05, 0.5, 0.05)\n", - "\n", - " # Plot after 8 years\n", - " i = 0\n", - " axWasNone = False\n", - " if ax is None:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(2, 1, 1)\n", - " axWasNone = True\n", - "\n", - " mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={\"row\": 0})\n", - " mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2)\n", - " mx.plot_ibound()\n", - " mx.plot_grid(color=\"0.5\", alpha=0.2)\n", - " cs = mx.contour_array(\n", - " conc_mt3d[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30]\n", - " )\n", - " plt.clabel(cs, fmt=r\"%4.2f\")\n", - "\n", - " title = \"Migrating plume after \" + str(yr_idx[i] + 1) + \" years, MT3D-USGS\"\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " if axWasNone:\n", - " ax = fig.add_subplot(2, 1, 2)\n", - "\n", - " mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={\"row\": 0})\n", - " mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2)\n", - " mx.plot_ibound()\n", - " mx.plot_grid(color=\"0.5\", alpha=0.2)\n", - " cs = mx.contour_array(\n", - " conc_mf6[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30]\n", - " )\n", - " plt.clabel(cs, fmt=r\"%4.2f\")\n", - "\n", - " title = \"Migrating plume after \" + str(yr_idx[i] + 1) + \" years, MODFLOW 6\"\n", - " letter = chr(ord(\"@\") + idx + 2)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(\n", - " sim_name + \"-\" + str(yr_idx[i] + 1) + \"yrs\",\n", - " config.figure_ext,\n", - " ),\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " # Plot after 12 years\n", - " i = 1\n", - " if axWasNone:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(2, 1, 1)\n", - " axWasNone = True\n", - "\n", - " mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={\"row\": 0})\n", - " mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2)\n", - " mx.plot_ibound()\n", - " mx.plot_grid(color=\"0.5\", alpha=0.2)\n", - " cs = mx.contour_array(\n", - " conc_mt3d[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30]\n", - " )\n", - " plt.clabel(cs, fmt=r\"%4.2f\")\n", - "\n", - " title = \"Migrating plume after \" + str(yr_idx[i] + 1) + \" years, MT3D-USGS\"\n", - " letter = chr(ord(\"@\") + idx + 3)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " if axWasNone:\n", - " ax = fig.add_subplot(2, 1, 2)\n", - "\n", - " mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={\"row\": 0})\n", - " mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2)\n", - " mx.plot_ibound()\n", - " mx.plot_grid(color=\"0.5\", alpha=0.2)\n", - " cs = mx.contour_array(\n", - " conc_mf6[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30]\n", - " )\n", - " plt.clabel(cs, fmt=r\"%4.2f\")\n", - "\n", - " title = \"Migrating plume after \" + str(yr_idx[i] + 1) + \" years, MODFLOW 6\"\n", - " letter = chr(ord(\"@\") + idx + 4)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(\n", - " sim_name + \"-\" + str(yr_idx[i] + 1) + \"yrs\",\n", - " config.figure_ext,\n", - " ),\n", - " )\n", - " fig.savefig(fpth)\n", - "\n", - " # Plot after 20 years\n", - " i = 2\n", - " if axWasNone:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(2, 1, 1)\n", - " axWasNone = True\n", - "\n", - " mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={\"row\": 0})\n", - " mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2)\n", - " mx.plot_ibound()\n", - " mx.plot_grid(color=\"0.5\", alpha=0.2)\n", - " cs = mx.contour_array(\n", - " conc_mt3d[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30]\n", - " )\n", - " plt.clabel(cs, fmt=r\"%4.2f\")\n", - "\n", - " title = \"Migrating plume after \" + str(yr_idx[i] + 1) + \" years, MT3D-USGS\"\n", - " letter = chr(ord(\"@\") + idx + 5)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " if axWasNone:\n", - " ax = fig.add_subplot(2, 1, 2)\n", - "\n", - " mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={\"row\": 0})\n", - " mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2)\n", - " mx.plot_ibound()\n", - " mx.plot_grid(color=\"0.5\", alpha=0.2)\n", - " cs = mx.contour_array(\n", - " conc_mf6[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30]\n", - " )\n", - " plt.clabel(cs, fmt=r\"%4.2f\")\n", - "\n", - " title = \"Migrating plume after \" + str(yr_idx[i] + 1) + \" years, MODFLOW 6\"\n", - " letter = chr(ord(\"@\") + idx + 6)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(\n", - " sim_name + \"-\" + str(yr_idx[i] + 1) + \"yrs\",\n", - " config.figure_ext,\n", - " ),\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "30f1006a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function that wraps all of the steps for each MT3DMS Example 10 Problem scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "64f4d6ef", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " mf2k5, mt3d, sim = build_model(example_name, mixelm=mixelm)\n", - " write_model(mf2k5, mt3d, sim, silent=silent)\n", - " success = run_model(mf2k5, mt3d, sim, silent=silent)\n", - " if success:\n", - " plot_results(mf2k5, mt3d, sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e419375e", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=True)" - ] - }, - { - "cell_type": "markdown", - "id": "f1ec044c", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aad49922", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Two-Dimensional Transport in a Diagonal Flow Field\n", - " #\n", - " # Compares the standard finite difference solutions between MT3D MF 6\n", - " scenario(0, silent=True)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dms-p09.ipynb b/notebooks/ex-gwt-mt3dms-p09.ipynb deleted file mode 100644 index 86a54bdc..00000000 --- a/notebooks/ex-gwt-mt3dms-p09.ipynb +++ /dev/null @@ -1,895 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "c98454f9", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Two Dimensional Application Example, Comparison of MODFLOW 6 Transport with MT3DMS\n", - "\n", - "The purpose of this script is to (1) recreate the example problems that were first\n", - "described in the 1999 MT3DMS report, and (2) compare MF6-GWT solutions to the\n", - "established MT3DMS solutions.\n", - "\n", - "Ten example problems appear in the 1999 MT3DMS manual, starting on page 130.\n", - "This notebook demonstrates example 10 from the list below:\n", - "\n", - " 1. One-Dimensional Transport in a Uniform Flow Field\n", - " 2. One-Dimensional Transport with Nonlinear or Nonequilibrium Sorption\n", - " 3. Two-Dimensional Transport in a Uniform Flow Field\n", - " 4. Two-Dimensional Transport in a Diagonal Flow Field\n", - " 5. Two-Dimensional Transport in a Radial Flow Field\n", - " 6. Concentration at an Injection/Extraction Well\n", - " 7. Three-Dimensional Transport in a Uniform Flow Field\n", - " 8. Two-Dimensional, Vertical Transport in a Heterogeneous Aquifer\n", - " 9. _Two-Dimensional Application Example_\n", - " 10. Three-Dimensional Field Case Study" - ] - }, - { - "cell_type": "markdown", - "id": "5a881c94", - "metadata": {}, - "source": [ - "### MODFLOW 6 GWT MT3DMS Example 9 Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "3f7ec249", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f5219e7c", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3b1f52a9", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "54811074", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3a303006", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure\n", - "from flopy.utils.util_array import read1d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c8597a41", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dusgs\"" - ] - }, - { - "cell_type": "markdown", - "id": "3759c056", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cbc03946", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (7, 5)" - ] - }, - { - "cell_type": "markdown", - "id": "096ffbfa", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "484e8677", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-mt3dms-p09\"" - ] - }, - { - "cell_type": "markdown", - "id": "b3352fad", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6b27ef0f", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "0d9b955f", - "metadata": {}, - "source": [ - "Table MODFLOW 6 GWT MT3DMS Example 8" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ea6ae01d", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 1 # Number of layers\n", - "nrow = 18 # Number of rows\n", - "ncol = 14 # Number of columns\n", - "delr = 100.0 # Column width ($m$)\n", - "delc = 100.0 # Row width ($m$)\n", - "delz = 10.0 # Layer thickness ($m$)\n", - "top = 0.0 # Top of the model ($m$)\n", - "prsity = 0.3 # Porosity\n", - "k1 = 1.474e-4 # Horiz. hyd. conductivity of fine grain material ($m/sec$)\n", - "k2 = 1.474e-7 # Horiz. hyd. conductivity of medium grain material ($m/sec$)\n", - "inj = 0.001 # Injection well rate ($m^3/sec$)\n", - "ext = -0.0189 # Extraction well pumping rate ($m^3/sec$)\n", - "al = 20.0 # Longitudinal dispersivity ($m$)\n", - "trpt = 0.2 # Ratio of horiz. transverse to longitudinal dispersivity ($m$)\n", - "perlen = 2.0 # Simulation time ($years$)" - ] - }, - { - "cell_type": "markdown", - "id": "44b0ec78", - "metadata": {}, - "source": [ - "Additional model input" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5d5a7a39", - "metadata": {}, - "outputs": [], - "source": [ - "hk = k1 * np.ones((nlay, nrow, ncol), dtype=float)\n", - "hk[:, 5:8, 1:8] = k2\n", - "laytyp = icelltype = 0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dddd5226", - "metadata": {}, - "outputs": [], - "source": [ - "# Active model domain\n", - "ibound = np.ones((nlay, nrow, ncol), dtype=int)\n", - "ibound[0, 0, :] = -1\n", - "ibound[0, -1, :] = -1\n", - "idomain = np.ones((nlay, nrow, ncol), dtype=int)\n", - "icbund = 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "99685b1d", - "metadata": {}, - "outputs": [], - "source": [ - "# Boundary conditions\n", - "# MF2K5 pumping info\n", - "qwell1 = 0.001\n", - "qwell2 = -0.0189\n", - "welspd = {0: [[0, 3, 6, qwell1], [0, 10, 6, qwell2]]} # Well pumping info for MF2K5\n", - "cwell1 = 57.87\n", - "cwell0 = 0.0\n", - "spd = {\n", - " 0: [[0, 3, 6, cwell1, 2], [0, 10, 6, cwell0, 2]],\n", - " 1: [[0, 3, 6, cwell0, 2], [0, 10, 6, cwell0, 2]],\n", - "} # Well info 4 MT3D\n", - "# MF6 pumping information\n", - "wellist_sp1 = []\n", - "# (k, i, j), flow, conc\n", - "wellist_sp1.append([(0, 3, 6), qwell1, cwell1]) # Injection well\n", - "wellist_sp1.append([(0, 10, 6), qwell2, cwell0]) # Pumping well\n", - "#\n", - "wellist_sp2 = []\n", - "# (k, i, j), flow, conc\n", - "wellist_sp2.append([(0, 3, 6), qwell1, cwell0]) # Injection well\n", - "wellist_sp2.append([(0, 10, 6), qwell2, cwell0]) # Pumping well\n", - "spd_mf6 = {0: wellist_sp1, 1: wellist_sp2}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2392357a", - "metadata": {}, - "outputs": [], - "source": [ - "# Transport related\n", - "sconc = 0.0\n", - "ath1 = al * trpt\n", - "dmcoef = 0.0 # m^2/s\n", - "# Time variables\n", - "perlen = [365.0 * 86400, 365.0 * 86400]\n", - "steady = [False, False]\n", - "nper = len(perlen)\n", - "nstp = [365, 365]\n", - "tsmult = [1.0, 1.0]\n", - "#\n", - "sconc = 0.0\n", - "c0 = 0.0\n", - "botm = [top - delz]\n", - "mixelm = -1" - ] - }, - { - "cell_type": "markdown", - "id": "5b76ffad", - "metadata": {}, - "source": [ - "Solver settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "96675a49", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-6, 1e-6, 1.0\n", - "percel = 1.0 # HMOC parameters\n", - "itrack = 2\n", - "wd = 0.5\n", - "dceps = 1.0e-5\n", - "nplane = 0\n", - "npl = 0\n", - "nph = 16\n", - "npmin = 2\n", - "npmax = 32\n", - "dchmoc = 1.0e-3\n", - "nlsink = nplane\n", - "npsink = nph\n", - "nadvfd = 1" - ] - }, - { - "cell_type": "markdown", - "id": "a7bcc7ee", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, and run models and plot MT3DMS Example 9\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bf9c7498", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, mixelm=0, silent=False):\n", - " if config.buildModel:\n", - " print(f\"Building mf2005 model...{sim_name}\")\n", - " mt3d_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " modelname_mf = \"p09-mf\"\n", - "\n", - " # Instantiate the MODFLOW model\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=modelname_mf, model_ws=mt3d_ws, exe_name=exe_name_mf\n", - " )\n", - "\n", - " # Instantiate discretization package\n", - " # units: itmuni=4 (days), lenuni=2 (m)\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " nper=nper,\n", - " perlen=perlen,\n", - " itmuni=1,\n", - " lenuni=2,\n", - " steady=steady,\n", - " )\n", - "\n", - " # Instantiate basic package\n", - " strt = np.zeros((nlay, nrow, ncol), dtype=float)\n", - " strt[0, 0, :] = 250.0\n", - " xc = mf.modelgrid.xcellcenters\n", - " for j in range(ncol):\n", - " strt[0, -1, j] = 20.0 + (xc[-1, j] - xc[-1, 0]) * 2.5 / 100\n", - " flopy.modflow.ModflowBas(mf, ibound=ibound, strt=strt)\n", - "\n", - " # Instantiate layer property flow package\n", - " flopy.modflow.ModflowLpf(mf, hk=hk, laytyp=laytyp)\n", - "\n", - " # Instantiate well package\n", - " flopy.modflow.ModflowWel(mf, stress_period_data=welspd)\n", - "\n", - " # Instantiate solver package\n", - " flopy.modflow.ModflowPcg(mf)\n", - "\n", - " # Instantiate link mass transport package (for writing linker file)\n", - " flopy.modflow.ModflowLmt(mf)\n", - "\n", - " # Transport\n", - " print(f\"Building mt3d-usgs model...{sim_name}\")\n", - "\n", - " modelname_mt = \"p09-mt\"\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=modelname_mt,\n", - " model_ws=mt3d_ws,\n", - " exe_name=exe_name_mt,\n", - " modflowmodel=mf,\n", - " )\n", - "\n", - " # Instantiate basic transport package\n", - " flopy.mt3d.Mt3dBtn(\n", - " mt,\n", - " icbund=icbund,\n", - " prsity=prsity,\n", - " sconc=sconc,\n", - " mxstrn=86400,\n", - " nper=nper,\n", - " perlen=perlen,\n", - " timprs=[perlen[0], 2 * perlen[1]],\n", - " dt0=0,\n", - " )\n", - "\n", - " # Instatiate the advection package\n", - " flopy.mt3d.Mt3dAdv(\n", - " mt,\n", - " mixelm=mixelm,\n", - " dceps=dceps,\n", - " nplane=nplane,\n", - " npl=npl,\n", - " nph=nph,\n", - " npmin=npmin,\n", - " npmax=npmax,\n", - " nlsink=nlsink,\n", - " npsink=npsink,\n", - " percel=percel,\n", - " )\n", - "\n", - " # Instantiate the dispersion package\n", - " flopy.mt3d.Mt3dDsp(mt, al=al, trpt=trpt, dmcoef=dmcoef)\n", - "\n", - " # Instantiate the source/sink mixing package\n", - " flopy.mt3d.Mt3dSsm(mt, stress_period_data=spd)\n", - "\n", - " # Instantiate the GCG solver in MT3DMS\n", - " flopy.mt3d.Mt3dGcg(mt)\n", - "\n", - " # MODFLOW 6\n", - " print(f\"Building mf6gwt model...{sim_name}\")\n", - "\n", - " name = \"p09-mf6\"\n", - " gwfname = \"gwf-\" + name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name=mf6exe)\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " for i in range(nper):\n", - " tdis_rc.append((perlen[i], nstp[i], tsmult[i]))\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"CG\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " strt = np.zeros((nlay, nrow, ncol), dtype=float)\n", - " strt[0, 0, :] = 250.0\n", - " xc = mf.modelgrid.xcellcenters\n", - " for j in range(ncol):\n", - " strt[0, -1, j] = 20.0 + (xc[-1, j] - xc[-1, 0]) * 2.5 / 100\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " icelltype=icelltype,\n", - " k=hk,\n", - " k33=hk,\n", - " save_specific_discharge=True,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiate storage package\n", - " sto = flopy.mf6.ModflowGwfsto(gwf, ss=1.0e-05)\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " # MF6 constant head boundaries:\n", - " chdspd = []\n", - " # Loop through the top & bottom sides.\n", - " for j in np.arange(ncol):\n", - " # l, r, c, head, conc\n", - " chdspd.append([(0, 0, j), 250.0, 0.0]) # Top boundary\n", - " hd = 20.0 + (xc[-1, j] - xc[-1, 0]) * 2.5 / 100\n", - " chdspd.append([(0, 17, j), hd, 0.0]) # Bottom boundary\n", - " chdspd = {0: chdspd}\n", - "\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " # Instantiate the wel package\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " print_input=True,\n", - " print_flows=True,\n", - " stress_period_data=spd_mf6,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"WEL-1\",\n", - " filename=f\"{gwfname}.wel\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 groundwater transport package\n", - " gwtname = \"gwt-\" + name\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=gwtname,\n", - " model_nam_file=f\"{gwtname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # create iterative model solution and register the gwt model with it\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwtname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - "\n", - " # Instantiating MODFLOW 6 transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwtname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{gwtname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 transport advection package\n", - " if mixelm >= 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{gwtname}.adv\")\n", - "\n", - " # Instantiating MODFLOW 6 transport dispersion package\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=al,\n", - " ath1=ath1,\n", - " filename=f\"{gwtname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport mass storage package\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=None,\n", - " bulk_density=None,\n", - " distcoef=None,\n", - " filename=f\"{gwtname}.mst\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport source-sink mixing package\n", - " sourcerecarray = [\n", - " (\"WEL-1\", \"AUX\", \"CONCENTRATION\"),\n", - " (\"CHD-1\", \"AUX\", \"CONCENTRATION\"),\n", - " ]\n", - " flopy.mf6.ModflowGwtssm(\n", - " gwt,\n", - " sources=sourcerecarray,\n", - " print_flows=True,\n", - " filename=f\"{gwtname}.ssm\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwtname}.cbc\",\n", - " concentration_filerecord=f\"{gwtname}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " filename=f\"{gwtname}.oc\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 flow-transport exchange mechanism\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname,\n", - " exgmnameb=gwtname,\n", - " filename=f\"{name}.gwfgwt\",\n", - " )\n", - " return mf, mt, sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "3674f04e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "62933796", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(mf2k5, mt3d, sim, silent=True):\n", - " if config.writeModel:\n", - " mf2k5.write_input()\n", - " mt3d.write_input()\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "48505509", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2fee0cad", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(mf2k5, mt3d, sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = mf2k5.run_model(silent=silent)\n", - " success, buff = mt3d.run_model(silent=silent)\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "7a1e9d8c", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a847477e", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mf2k5, mt3d, mf6, idx, ax=None):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " mt3d_out_path = mt3d.model_ws\n", - " mf6_out_path = mf6.simulation_data.mfpath.get_sim_path()\n", - " mf6.simulation_data.mfpath.get_sim_path()\n", - "\n", - " # Get the MT3DMS concentration output\n", - " fname_mt3d = os.path.join(mt3d_out_path, \"MT3D001.UCN\")\n", - " ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d)\n", - " conc_mt3d = ucnobj_mt3d.get_alldata()\n", - "\n", - " # Get the MF6 concentration output\n", - " gwt = mf6.get_model(list(mf6.model_names)[1])\n", - " ucnobj_mf6 = gwt.output.concentration()\n", - " conc_mf6 = ucnobj_mf6.get_alldata()\n", - "\n", - " hk = mf2k5.lpf.hk.array\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_name = mf6.name\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - "\n", - " levels = np.arange(0.2, 10, 0.4)\n", - " stp_idx = 0 # 0-based (out of 2 possible stress periods)\n", - "\n", - " # Plot after 8 years\n", - " axWasNone = False\n", - " if ax is None:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 2, 1, aspect=\"equal\")\n", - " axWasNone = True\n", - "\n", - " ax = fig.add_subplot(1, 2, 1, aspect=\"equal\")\n", - " cflood = np.ma.masked_less_equal(conc_mt3d[stp_idx], 0.2)\n", - " mm = flopy.plot.PlotMapView(ax=ax, model=mf2k5)\n", - " mm.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2)\n", - " mm.plot_ibound()\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " cs = mm.plot_array(cflood[0], alpha=0.5, vmin=0, vmax=3)\n", - " cs = mm.contour_array(conc_mt3d[stp_idx], colors=\"k\", levels=levels)\n", - " plt.clabel(cs)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - "\n", - " title = \"MT3D - End of SP \" + str(stp_idx + 1)\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " if axWasNone:\n", - " ax = fig.add_subplot(1, 2, 2, aspect=\"equal\")\n", - "\n", - " cflood = np.ma.masked_less_equal(conc_mf6[stp_idx], 0.2)\n", - " mm = flopy.plot.PlotMapView(ax=ax, model=mf2k5)\n", - " mm.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2)\n", - " mm.plot_ibound()\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " cs = mm.plot_array(cflood[0], alpha=0.5, vmin=0, vmax=3)\n", - " cs = mm.contour_array(conc_mf6[stp_idx], colors=\"k\", levels=levels)\n", - " plt.clabel(cs)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - "\n", - " title = \"MODFLOW 6 - End of SP \" + str(stp_idx + 1)\n", - " letter = chr(ord(\"@\") + idx + 2)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(\n", - " sim_name,\n", - " config.figure_ext,\n", - " ),\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "9b5ecb3a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function that wraps all of the steps for each MT3DMS Example 10 Problem scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3093ce41", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " mf2k5, mt3d, sim = build_model(example_name, mixelm=mixelm)\n", - " write_model(mf2k5, mt3d, sim, silent=silent)\n", - " success = run_model(mf2k5, mt3d, sim, silent=silent)\n", - " if success:\n", - " plot_results(mf2k5, mt3d, sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "497575f0", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=True)" - ] - }, - { - "cell_type": "markdown", - "id": "30e7346a", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b5c5f8de", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Two-Dimensional Transport in a Diagonal Flow Field\n", - " #\n", - " # Compares the standard finite difference solutions between MT3D MF 6\n", - " scenario(0, silent=True)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dms-p10.ipynb b/notebooks/ex-gwt-mt3dms-p10.ipynb deleted file mode 100644 index 29f268ee..00000000 --- a/notebooks/ex-gwt-mt3dms-p10.ipynb +++ /dev/null @@ -1,1035 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "8217a726", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Three-Dimensional Field Case Study, Comparison of MODFLOW 6 Transport with MT3DMS\n", - "\n", - "The purpose of this script is to (1) recreate the example problems that were first\n", - "described in the 1999 MT3DMS report, and (2) compare MF6-GWT solutions to the\n", - "established MT3DMS solutions.\n", - "\n", - "Ten example problems appear in the 1999 MT3DMS manual, starting on page 130.\n", - "This notebook demonstrates example 10 from the list below:\n", - "\n", - " 1. One-Dimensional Transport in a Uniform Flow Field\n", - " 2. One-Dimensional Transport with Nonlinear or Nonequilibrium Sorption\n", - " 3. Two-Dimensional Transport in a Uniform Flow Field\n", - " 4. Two-Dimensional Transport in a Diagonal Flow Field\n", - " 5. Two-Dimensional Transport in a Radial Flow Field\n", - " 6. Concentration at an Injection/Extraction Well\n", - " 7. Three-Dimensional Transport in a Uniform Flow Field\n", - " 8. Two-Dimensional, Vertical Transport in a Heterogeneous Aquifer\n", - " 9. Two-Dimensional Application Example\n", - " 10. _Three-Dimensional Field Case Study_" - ] - }, - { - "cell_type": "markdown", - "id": "7f9e1e75", - "metadata": {}, - "source": [ - "### MODFLOW 6 GWT MT3DMS Example 10 Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "2620ad92", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "486d0215", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b5c08c2d", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "4d1b6bb5", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ca4d17b2", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure\n", - "from flopy.utils.util_array import read1d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e2207476", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dusgs\"" - ] - }, - { - "cell_type": "markdown", - "id": "b24fd59e", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e911d235", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 8)" - ] - }, - { - "cell_type": "markdown", - "id": "90c7daf4", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1775afb4", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-mt3dms-p10\"" - ] - }, - { - "cell_type": "markdown", - "id": "7c338d2b", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "68f93933", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "dc296c36", - "metadata": {}, - "source": [ - "Table MODFLOW 6 GWT MT3DMS Example 8" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "45df37bb", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 4 # Number of layers\n", - "nrow = 61 # Number of rows\n", - "ncol = 40 # Number of columns\n", - "delr = \"varies\" # Column width ($ft$)\n", - "delc = \"varies\" # Row width ($ft$)\n", - "delz = 25.0 # Layer thickness ($ft$)\n", - "top = 780.0 # Top of the model ($ft$)\n", - "satthk = 100.0 # Saturated thickness ($ft$)\n", - "k1 = 60.0 # Horiz. hyd. conductivity of layers 1 and 2 ($ft/day$)\n", - "k2 = 520.0 # Horiz. hyd. conductivity of layers 3 and 4 ($ft/day$)\n", - "vka = 0.1 # Ratio of vertical to horizontal hydraulic conductivity\n", - "rech = 5.0 # Recharge rate ($in/yr$)\n", - "crech = 0.0 # Concentration of recharge ($ppm$)\n", - "prsity = 0.3 # Porosity\n", - "al = 10.0 # Longitudinal dispersivity ($ft$)\n", - "trpt = 0.2 # Ratio of horizontal transverse dispersivity to longitudinal dispersivity\n", - "trpv = 0.2 # Ratio of vertical transverse dispersivity to longitudinal dispersivity\n", - "rhob = 1.7 # Aquifer bulk density ($g/cm^3$)\n", - "sp1 = 0.176 # Distribution coefficient ($cm^3/g$)\n", - "perlen = 1000.0 # Simulation time ($days$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d436121f", - "metadata": {}, - "outputs": [], - "source": [ - "# Additional model input\n", - "delr = [2000, 1600, 800, 400, 200, 100] + 28 * [50] + [100, 200, 400, 800, 1600, 2000]\n", - "delc = (\n", - " [2000, 2000, 2000, 1600, 800, 400, 200, 100]\n", - " + 45 * [50]\n", - " + [100, 200, 400, 800, 1600, 2000, 2000, 2000]\n", - ")\n", - "hk = [60.0, 60.0, 520.0, 520.0]\n", - "laytyp = icelltype = 0\n", - "# Starting Heads:\n", - "f = open(os.path.join(\"..\", \"data\", \"ex-gwt-mt3dms-p10\", \"p10shead.dat\"))\n", - "s0 = np.empty((nrow * ncol), dtype=float)\n", - "s0 = read1d(f, s0).reshape((nrow, ncol))\n", - "f.close()\n", - "strt = np.zeros((nlay, nrow, ncol), dtype=float)\n", - "for k in range(nlay):\n", - " strt[k] = s0\n", - "# Active model domain\n", - "ibound = np.ones((nlay, nrow, ncol), dtype=int)\n", - "ibound[:, :, 0] = -1 # left side\n", - "ibound[:, :, -1] = -1 # right side\n", - "ibound[:, 0, :] = -1 # top\n", - "ibound[:, -1, :] = -1 # bottom\n", - "icbund = idomain = 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9f28dcff", - "metadata": {}, - "outputs": [], - "source": [ - "# Boundary conditions\n", - "rech = 12.7 / 365 / 30.48 # cm/yr -> ft/day\n", - "crch = 0.0\n", - "# MF2K5 pumping info\n", - "welspd_Q = [\n", - " [3 - 1, 11 - 1, 29 - 1, -19230.00],\n", - " [3 - 1, 19 - 1, 26 - 1, -19230.00],\n", - " [3 - 1, 26 - 1, 23 - 1, -19230.00],\n", - " [3 - 1, 33 - 1, 20 - 1, -19230.00],\n", - " [3 - 1, 40 - 1, 17 - 1, -19230.00],\n", - " [3 - 1, 48 - 1, 14 - 1, -19230.00],\n", - " [3 - 1, 48 - 1, 9 - 1, -15384.00],\n", - " [3 - 1, 52 - 1, 17 - 1, -17307.00],\n", - "]\n", - "# k, i, j, Q, itype\n", - "welspd_ssm = [\n", - " [3 - 1, 11 - 1, 29 - 1, 0.0, 2],\n", - " [3 - 1, 19 - 1, 26 - 1, 0.0, 2],\n", - " [3 - 1, 26 - 1, 23 - 1, 0.0, 2],\n", - " [3 - 1, 33 - 1, 20 - 1, 0.0, 2],\n", - " [3 - 1, 40 - 1, 17 - 1, 0.0, 2],\n", - " [3 - 1, 48 - 1, 14 - 1, 0.0, 2],\n", - " [3 - 1, 48 - 1, 9 - 1, 0.0, 2],\n", - " [3 - 1, 52 - 1, 17 - 1, 0.0, 2],\n", - "]\n", - "# MF6 pumping information\n", - "welspd_mf6 = []\n", - "# [(layer, row, column), flow, conc]\n", - "welspd_mf6.append([(3 - 1, 11 - 1, 29 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 19 - 1, 26 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 26 - 1, 23 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 33 - 1, 20 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 40 - 1, 17 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 48 - 1, 14 - 1), -19230.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 48 - 1, 9 - 1), -15384.0, 0.00])\n", - "welspd_mf6.append([(3 - 1, 52 - 1, 17 - 1), -17307.0, 0.00])\n", - "wel_mf6_spd = {0: welspd_mf6}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "863b4a55", - "metadata": {}, - "outputs": [], - "source": [ - "# Transport related\n", - "# Starting concentrations:\n", - "f = open(os.path.join(\"..\", \"data\", \"ex-gwt-mt3dms-p10\", \"p10cinit.dat\"))\n", - "c0 = np.empty((nrow * ncol), dtype=float)\n", - "c0 = read1d(f, c0).reshape((nrow, ncol))\n", - "f.close()\n", - "sconc = np.zeros((nlay, nrow, ncol), dtype=float)\n", - "sconc[1] = 0.2 * c0\n", - "sconc[2] = c0\n", - "# Dispersion\n", - "ath1 = al * trpt\n", - "atv = al * trpv\n", - "dmcoef = 0.0 # ft^2/day\n", - "# Time variables\n", - "perlen = 1000.0\n", - "nstp = 100\n", - "ttsmult = 1.0\n", - "#\n", - "c0 = 0.0\n", - "botm = [top - delz * k for k in range(1, nlay + 1)]\n", - "mixelm = 0\n", - "# Reactive transport related terms\n", - "isothm = 1 # sorption type; 1=linear isotherm (equilibrium controlled)\n", - "sp2 = 0.0 # w/ isothm = 1 this is read but not used\n", - "# ***Note: In the original documentation for this problem, the following two\n", - "# values are specified in units of g/cm^3 and cm^3/g, respectively.\n", - "# All other units in this problem appear to use ft, including the\n", - "# grid discretization, aquifer K (ft/day), recharge (ft/yr),\n", - "# pumping (ft^3/day), & dispersion (ft). Because this problem\n", - "# attempts to recreate the original problem for comparison purposes,\n", - "# we are sticking with these values while also acknowledging this\n", - "# discrepancy.\n", - "rhob = 1.7 # g/cm^3\n", - "sp1 = 0.176 # cm^3/g (Kd: \"Distribution coefficient\")\n", - "# Transport observations\n", - "# Instantiate the basic transport package\n", - "obs = [\n", - " [3 - 1, 11 - 1, 29 - 1],\n", - " [3 - 1, 19 - 1, 26 - 1],\n", - " [3 - 1, 26 - 1, 23 - 1],\n", - " [3 - 1, 33 - 1, 20 - 1],\n", - " [3 - 1, 40 - 1, 17 - 1],\n", - " [3 - 1, 48 - 1, 14 - 1],\n", - " [3 - 1, 48 - 1, 9 - 1],\n", - " [3 - 1, 52 - 1, 17 - 1],\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "763387a2", - "metadata": {}, - "source": [ - "Solver settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "83cd3518", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-6, 1e-6, 1.0\n", - "percel = 1.0 # HMOC parameters\n", - "itrack = 2\n", - "wd = 0.5\n", - "dceps = 1.0e-5\n", - "nplane = 0\n", - "npl = 0\n", - "nph = 16\n", - "npmin = 2\n", - "npmax = 32\n", - "dchmoc = 1.0e-3\n", - "nlsink = nplane\n", - "npsink = nph\n", - "nadvfd = 1" - ] - }, - { - "cell_type": "markdown", - "id": "bf65be41", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, and run models and plot MT3DMS Example 9\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7ad9a9de", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, mixelm=0, silent=False):\n", - " if config.buildModel:\n", - " print(f\"Building mf2005 model...{sim_name}\")\n", - " mt3d_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " modelname_mf = \"p10-mf\"\n", - "\n", - " # Instantiate the MODFLOW model\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=modelname_mf, model_ws=mt3d_ws, exe_name=exe_name_mf\n", - " )\n", - "\n", - " # Instantiate discretization package\n", - " # units: itmuni=4 (days), lenuni=2 (m)\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " perlen=perlen,\n", - " nstp=nstp,\n", - " itmuni=4,\n", - " lenuni=1,\n", - " )\n", - "\n", - " # Instantiate basic package\n", - " flopy.modflow.ModflowBas(mf, ibound=ibound, strt=strt)\n", - "\n", - " # Instantiate layer property flow package\n", - " flopy.modflow.ModflowLpf(mf, hk=hk, layvka=1, vka=vka, laytyp=laytyp)\n", - "\n", - " # Instantiate recharge package\n", - " flopy.modflow.ModflowRch(mf, rech=rech)\n", - "\n", - " # Instantiate well package\n", - " flopy.modflow.ModflowWel(mf, stress_period_data=welspd_Q)\n", - "\n", - " # Instantiate solver package\n", - " flopy.modflow.ModflowPcg(mf)\n", - "\n", - " # Instantiate link mass transport package (for writing linker file)\n", - " flopy.modflow.ModflowLmt(mf)\n", - "\n", - " # Instantiate output control (OC) package\n", - " spd = {\n", - " (0, 0): [\"save head\"],\n", - " (0, 49): [\"save head\"],\n", - " (0, 74): [\"save head\"],\n", - " (0, 99): [\"save head\"],\n", - " }\n", - " oc = flopy.modflow.ModflowOc(mf, stress_period_data=spd)\n", - "\n", - " # Transport\n", - " print(f\"Building mt3d-usgs model...{sim_name}\")\n", - "\n", - " modelname_mt = \"p10-mt\"\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=modelname_mt,\n", - " model_ws=mt3d_ws,\n", - " exe_name=exe_name_mt,\n", - " modflowmodel=mf,\n", - " )\n", - "\n", - " # Instantiate basic transport package\n", - " flopy.mt3d.Mt3dBtn(\n", - " mt,\n", - " icbund=icbund,\n", - " prsity=prsity,\n", - " sconc=sconc,\n", - " perlen=perlen,\n", - " dt0=2.0,\n", - " ttsmult=ttsmult,\n", - " timprs=[10, 500, 750, 1000],\n", - " obs=obs,\n", - " )\n", - "\n", - " # Instatiate the advection package\n", - " flopy.mt3d.Mt3dAdv(\n", - " mt,\n", - " mixelm=mixelm,\n", - " dceps=dceps,\n", - " nplane=nplane,\n", - " npl=npl,\n", - " nph=nph,\n", - " npmin=npmin,\n", - " npmax=npmax,\n", - " nlsink=nlsink,\n", - " npsink=npsink,\n", - " percel=percel,\n", - " )\n", - "\n", - " # Instantiate the dispersion package\n", - " flopy.mt3d.Mt3dDsp(mt, al=al, trpt=trpt, trpv=trpv, dmcoef=dmcoef)\n", - "\n", - " # Instantiate the source/sink mixing package\n", - " ssmspd = {0: welspd_ssm}\n", - " flopy.mt3d.Mt3dSsm(mt, crch=crch, stress_period_data=ssmspd)\n", - "\n", - " # Instantiate the recharge package\n", - " flopy.mt3d.Mt3dRct(mt, isothm=isothm, igetsc=0, rhob=rhob, sp1=sp1, sp2=sp2)\n", - "\n", - " # Instantiate the GCG solver in MT3DMS\n", - " flopy.mt3d.Mt3dGcg(mt)\n", - "\n", - " # MODFLOW 6\n", - " print(f\"Building mf6gwt model...{sim_name}\")\n", - "\n", - " name = \"p10-mf6\"\n", - " gwfname = \"gwf-\" + name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name=mf6exe)\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " tdis_rc.append((perlen, 500, 1.0))\n", - " flopy.mf6.ModflowTdis(sim, nper=1, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"CG\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " k33overk=True,\n", - " icelltype=laytyp,\n", - " k=hk,\n", - " k33=vka,\n", - " save_specific_discharge=True,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiate storage package\n", - " flopy.mf6.ModflowGwfsto(gwf, ss=0, sy=0, filename=f\"{gwfname}.sto\")\n", - "\n", - " # Instantiating MODFLOW 6 constant head package\n", - " # MF6 constant head boundaries:\n", - " chdspd = []\n", - " # Loop through the left & right sides for all layers.\n", - " for k in np.arange(nlay):\n", - " for i in np.arange(nrow):\n", - " # (l, r, c), head, conc\n", - " chdspd.append([(k, i, 0), strt[k, i, 0], 0.0]) # left\n", - " chdspd.append([(k, i, ncol - 1), strt[k, i, ncol - 1], 0.0]) # right\n", - "\n", - " for j in np.arange(1, ncol - 1): # skip corners, already added above\n", - " # (l, r, c), head, conc\n", - " chdspd.append([(k, 0, j), strt[k, 0, j], 0.0]) # top\n", - " chdspd.append([(k, nrow - 1, j), strt[k, nrow - 1, j], 0.0]) # bottom\n", - "\n", - " chdspd = {0: chdspd}\n", - "\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " # Instantiate recharge package\n", - " flopy.mf6.ModflowGwfrcha(\n", - " gwf,\n", - " print_flows=True,\n", - " recharge=rech,\n", - " pname=\"RCH-1\",\n", - " filename=f\"{gwfname}.rch\",\n", - " )\n", - "\n", - " # Instantiate the wel package\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " print_input=True,\n", - " print_flows=True,\n", - " stress_period_data=wel_mf6_spd,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"WEL-1\",\n", - " filename=f\"{gwfname}.wel\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 output control package for flow model\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[\n", - " (\"HEAD\", \"LAST\"),\n", - " (\"HEAD\", \"STEPS\", \"1\", \"250\", \"375\", \"500\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " printrecord=[\n", - " (\"HEAD\", \"LAST\"),\n", - " (\"BUDGET\", \"FIRST\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 groundwater transport package\n", - " gwtname = \"gwt-\" + name\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=gwtname,\n", - " model_nam_file=f\"{gwtname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # create iterative model solution and register the gwt model with it\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwtname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - "\n", - " # Instantiating MODFLOW 6 transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwtname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{gwtname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 transport advection package\n", - " if mixelm >= 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{gwtname}.adv\")\n", - "\n", - " # Instantiating MODFLOW 6 transport dispersion package\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=al,\n", - " ath1=ath1,\n", - " atv=atv,\n", - " pname=\"DSP-1\",\n", - " filename=f\"{gwtname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport mass storage package\n", - " Kd = sp1\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=\"linear\",\n", - " bulk_density=rhob,\n", - " distcoef=Kd,\n", - " pname=\"MST-1\",\n", - " filename=f\"{gwtname}.mst\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport source-sink mixing package\n", - " sourcerecarray = [(\"CHD-1\", \"AUX\", \"CONCENTRATION\")]\n", - " flopy.mf6.ModflowGwtssm(\n", - " gwt,\n", - " sources=sourcerecarray,\n", - " print_flows=True,\n", - " filename=f\"{gwtname}.ssm\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwtname}.cbc\",\n", - " concentration_filerecord=f\"{gwtname}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[\n", - " (\"CONCENTRATION\", \"LAST\"),\n", - " (\"CONCENTRATION\", \"STEPS\", \"1\", \"250\", \"375\", \"500\"),\n", - " (\"BUDGET\", \"LAST\"),\n", - " ],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " filename=f\"{gwtname}.oc\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 flow-transport exchange mechanism\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname,\n", - " exgmnameb=gwtname,\n", - " filename=f\"{name}.gwfgwt\",\n", - " )\n", - " return mf, mt, sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "3492b488", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "68fb5909", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(mf2k5, mt3d, sim, silent=True):\n", - " if config.writeModel:\n", - " mf2k5.write_input()\n", - " mt3d.write_input()\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "aabedc58", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4848f07a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(mf2k5, mt3d, sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = mf2k5.run_model(silent=silent)\n", - " success, buff = mt3d.run_model(silent=silent)\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "9abc4cc3", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2496bfe9", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mf2k5, mt3d, mf6, idx, ax=None):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " mt3d_out_path = mt3d.model_ws\n", - " mf6_out_path = mf6.simulation_data.mfpath.get_sim_path()\n", - " mf6.simulation_data.mfpath.get_sim_path()\n", - "\n", - " # Get the MT3DMS concentration output\n", - " fname_mt3d = os.path.join(mt3d_out_path, \"MT3D001.UCN\")\n", - " ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d)\n", - " conc_mt3d = ucnobj_mt3d.get_alldata()\n", - "\n", - " # Get the MF6 concentration output\n", - " gwt = mf6.get_model(list(mf6.model_names)[1])\n", - " ucnobj_mf6 = gwt.output.concentration()\n", - " conc_mf6 = ucnobj_mf6.get_alldata()\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_name = mf6.name\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - "\n", - " xc, yc = mf2k5.modelgrid.xycenters\n", - " levels = np.arange(0.2, 10, 0.4)\n", - " stp_idx = 0 # 0-based (out of 2 possible stress periods)\n", - "\n", - " cinit = mt3d.btn.sconc[0].array[2]\n", - " # Plots of concentration\n", - " axWasNone = False\n", - " if ax is None:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(2, 2, 1, aspect=\"equal\")\n", - " axWasNone = True\n", - "\n", - " mm = flopy.plot.PlotMapView(model=mf2k5)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " cs = mm.contour_array(cinit, levels=np.arange(20, 200, 20))\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " plt.clabel(cs, fmt=r\"%3d\")\n", - " for k, i, j, q in mf2k5.wel.stress_period_data[0]:\n", - " plt.plot(xc[j], yc[i], \"ks\")\n", - "\n", - " title = \"Layer 3 Initial Concentration\"\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # 2nd figure\n", - " if axWasNone:\n", - " ax = fig.add_subplot(2, 2, 2, aspect=\"equal\")\n", - "\n", - " c = conc_mt3d[1, 2] # Layer 3 @ 500 days (2nd specified output time)\n", - " mm = flopy.plot.PlotMapView(model=mf2k5)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " cs1 = mm.contour_array(c, levels=np.arange(10, 200, 10), colors=\"black\")\n", - " plt.clabel(cs1, fmt=r\"%3d\")\n", - " c_mf6 = conc_mf6[1, 2] # Layer 3 @ 500 days\n", - " cs2 = mm.contour_array(\n", - " c_mf6, levels=np.arange(10, 200, 10), colors=\"red\", linestyles=\"--\"\n", - " )\n", - " labels = [\"MT3DMS\", \"MODFLOW 6\"]\n", - " lines = [cs1.collections[0], cs2.collections[0]]\n", - " ax.legend(lines, labels, loc=\"upper left\")\n", - "\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - "\n", - " for k, i, j, q in mf2k5.wel.stress_period_data[0]:\n", - " plt.plot(xc[j], yc[i], \"ks\")\n", - "\n", - " title = \"MT3D Layer 3 Time = 500 days\"\n", - " letter = chr(ord(\"@\") + idx + 2)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # 3rd figure\n", - " if axWasNone:\n", - " ax = fig.add_subplot(2, 2, 3, aspect=\"equal\")\n", - " c = conc_mt3d[2, 2]\n", - " mm = flopy.plot.PlotMapView(model=mf2k5)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " cs1 = mm.contour_array(c, levels=np.arange(10, 200, 10), colors=\"black\")\n", - " plt.clabel(cs1, fmt=r\"%3d\")\n", - " c_mf6 = conc_mf6[2, 2]\n", - " cs2 = mm.contour_array(\n", - " c_mf6, levels=np.arange(10, 200, 10), colors=\"red\", linestyles=\"--\"\n", - " )\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " for k, i, j, q in mf2k5.wel.stress_period_data[0]:\n", - " plt.plot(xc[j], yc[i], \"ks\")\n", - "\n", - " title = \"MT3D Layer 3 Time = 750 days\"\n", - " letter = chr(ord(\"@\") + idx + 3)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # 4th figure\n", - " if axWasNone:\n", - " ax = fig.add_subplot(2, 2, 4, aspect=\"equal\")\n", - " c = conc_mt3d[3, 2]\n", - " mm = flopy.plot.PlotMapView(model=mf2k5)\n", - " mm.plot_grid(color=\".5\", alpha=0.2)\n", - " cs1 = mm.contour_array(c, levels=np.arange(10, 200, 10), colors=\"black\")\n", - " plt.clabel(cs1, fmt=r\"%3d\")\n", - " c_mf6 = conc_mf6[3, 2]\n", - " cs2 = mm.contour_array(\n", - " c_mf6, levels=np.arange(10, 200, 10), colors=\"red\", linestyles=\"--\"\n", - " )\n", - " plt.xlim(5100, 5100 + 28 * 50)\n", - " plt.ylim(9100, 9100 + 45 * 50)\n", - " plt.xlabel(\"Distance Along X-Axis, in meters\")\n", - " plt.ylabel(\"Distance Along Y-Axis, in meters\")\n", - " for k, i, j, q in mf2k5.wel.stress_period_data[0]:\n", - " plt.plot(xc[j], yc[i], \"ks\")\n", - "\n", - " title = \"MT3D Layer 3 Time = 1,000 days\"\n", - " letter = chr(ord(\"@\") + idx + 4)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " plt.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(\n", - " sim_name,\n", - " config.figure_ext,\n", - " ),\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "c1eef9ac", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function that wraps all of the steps for each MT3DMS Example 10 Problem scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ace00d93", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " mf2k5, mt3d, sim = build_model(example_name, mixelm=mixelm)\n", - " write_model(mf2k5, mt3d, sim, silent=silent)\n", - " success = run_model(mf2k5, mt3d, sim, silent=silent)\n", - " if success:\n", - " plot_results(mf2k5, mt3d, sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f2c2d524", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=True)" - ] - }, - { - "cell_type": "markdown", - "id": "4041b866", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dae9863b", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Two-Dimensional Transport in a Diagonal Flow Field\n", - " #\n", - " # Compares the standard finite difference solutions between MT3D MF 6\n", - " scenario(0, silent=True)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dsupp631.ipynb b/notebooks/ex-gwt-mt3dsupp631.ipynb deleted file mode 100644 index 08c4f888..00000000 --- a/notebooks/ex-gwt-mt3dsupp631.ipynb +++ /dev/null @@ -1,617 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "0846a13f", - "metadata": {}, - "source": [ - "## Zero-Order Growth in a Uniform Flow Field\n", - "\n", - "MT3DMS Supplemental Guide Problem 6.3.1\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "d415b02c", - "metadata": {}, - "source": [ - "### Zero-Order Growth in a Uniform Flow Field Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ed53bf9a", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b706e948", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "650667c6", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "98d2f6af", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "58ee14a0", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e711a903", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "47a8c217", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6ef27b6b", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (5, 3)" - ] - }, - { - "cell_type": "markdown", - "id": "4f278536", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ee0a6a2c", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-mt3dsupp631\"" - ] - }, - { - "cell_type": "markdown", - "id": "fc3475fc", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b6b5dfb", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "d2bdb65b", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0b3183ff", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 2 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 101 # Number of columns\n", - "delr = 0.16 # Column width ($m$)\n", - "delc = 1.0 # Row width ($m$)\n", - "top = 1.0 # Top of the model ($m$)\n", - "botm = 0 # Layer bottom elevation ($m$)\n", - "specific_discharge = 0.1 # Specific discharge ($md^{-1}$)\n", - "longitudinal_dispersivity = 1.0 # Longitudinal dispersivity ($m$)\n", - "porosity = 0.37 # Porosity of mobile domain (unitless)\n", - "zero_order_decay = -2.0e-3 # Zero-order production rate ($mg/L d^{-1}$)\n", - "source_duration = 160.0 # Source duration ($d$)\n", - "total_time = 840.0 # Simulation time ($t$)\n", - "obs_xloc = 8.0 # Observation x location ($m$)" - ] - }, - { - "cell_type": "markdown", - "id": "5f176d63", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model\n", - "recharge is the only variable\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "df912359", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwf(sim_folder):\n", - " print(f\"Building mf6gwf model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwf\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = (\n", - " (source_duration, 1, 1.0),\n", - " (total_time - source_duration, 1, 1.0),\n", - " )\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(sim)\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " save_saturation=True,\n", - " icelltype=0,\n", - " k=1.0,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=1.0)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=[[(0, 0, ncol - 1), 1.0]])\n", - " wel_spd = {\n", - " 0: [[(0, 0, 0), specific_discharge * delc * top, 1.0]],\n", - " 1: [[(0, 0, 0), specific_discharge * delc * top, 0.0]],\n", - " }\n", - " flopy.mf6.ModflowGwfwel(\n", - " gwf,\n", - " stress_period_data=wel_spd,\n", - " pname=\"WEL-1\",\n", - " auxiliary=[\"CONCENTRATION\"],\n", - " )\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7fc14fb3", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwt(sim_folder):\n", - " print(f\"Building mf6gwt model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwt\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " pertim1 = source_duration\n", - " pertim2 = total_time - source_duration\n", - " tdis_ds = ((pertim1, 16, 1.0), (pertim2, 84, 1.0))\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(sim, linear_acceleration=\"bicgstab\")\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwtic(gwt, strt=0)\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt, zero_order_decay=True, porosity=porosity, decay=zero_order_decay\n", - " )\n", - " flopy.mf6.ModflowGwtadv(gwt)\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " xt3d_off=True,\n", - " alh=longitudinal_dispersivity,\n", - " ath1=longitudinal_dispersivity,\n", - " )\n", - " pd = [\n", - " (\"GWFHEAD\", f\"../mf6gwf/flow.hds\", None),\n", - " (\"GWFBUDGET\", \"../mf6gwf/flow.bud\", None),\n", - " ]\n", - " flopy.mf6.ModflowGwtfmi(gwt, packagedata=pd)\n", - " sourcerecarray = [[\"WEL-1\", \"AUX\", \"CONCENTRATION\"]]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - " obsj = int(obs_xloc / delr) + 1\n", - " obs_data = {\n", - " f\"{name}.obs.csv\": [\n", - " (\"myobs\", \"CONCENTRATION\", (0, 0, obsj)),\n", - " ],\n", - " }\n", - " obs_package = flopy.mf6.ModflowUtlobs(\n", - " gwt, digits=10, print_input=True, continuous=obs_data\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c80d5e0", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf2005(sim_folder):\n", - " print(f\"Building mf2005 model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf2005\")\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=name, model_ws=sim_ws, exe_name=\"mf2005\"\n", - " )\n", - " pertim1 = source_duration\n", - " pertim2 = total_time - source_duration\n", - " perlen = [pertim1, pertim2]\n", - " dis = flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " nper=nper,\n", - " perlen=perlen,\n", - " )\n", - " bas = flopy.modflow.ModflowBas(mf)\n", - " lpf = flopy.modflow.ModflowLpf(mf)\n", - " pcg = flopy.modflow.ModflowPcg(mf)\n", - " lmt = flopy.modflow.ModflowLmt(mf)\n", - " chd = flopy.modflow.ModflowChd(\n", - " mf, stress_period_data=[[0, 0, ncol - 1, 1.0, 1.0]]\n", - " )\n", - " wel_spd = {\n", - " 0: [[0, 0, 0, specific_discharge * delc * top]],\n", - " 1: [[0, 0, 0, specific_discharge * delc * top]],\n", - " }\n", - " wel = flopy.modflow.ModflowWel(mf, stress_period_data=wel_spd)\n", - " return mf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5dc4ee11", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mt3dms(sim_folder, modflowmodel):\n", - " print(f\"Building mt3dms model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mt3d\")\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=name,\n", - " model_ws=sim_ws,\n", - " exe_name=\"mt3dms\",\n", - " modflowmodel=modflowmodel,\n", - " ftlfilename=\"../mf2005/mt3d_link.ftl\",\n", - " )\n", - " dt0 = 10.0\n", - " obsj = int(obs_xloc / delr) + 1\n", - " btn = flopy.mt3d.Mt3dBtn(\n", - " mt, laycon=0, prsity=porosity, obs=[(0, 0, obsj)], dt0=dt0, ifmtcn=1\n", - " )\n", - " adv = flopy.mt3d.Mt3dAdv(mt, mixelm=0)\n", - " dsp = flopy.mt3d.Mt3dDsp(mt, al=longitudinal_dispersivity)\n", - " rc1 = zero_order_decay\n", - " ireact = 100 # zero order decay\n", - " rct = flopy.mt3d.Mt3dRct(mt, igetsc=0, ireact=ireact, rc1=rc1)\n", - " ssm_spd = {0: [0, 0, 0, 1.0, 2], 1: [0, 0, 0, 0.0, 2]}\n", - " ssm = flopy.mt3d.Mt3dSsm(mt, mxss=3, stress_period_data=ssm_spd)\n", - " gcg = flopy.mt3d.Mt3dGcg(mt)\n", - " return mt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "70234a69", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name):\n", - " sims = None\n", - " if config.buildModel:\n", - " sim_mf6gwf = build_mf6gwf(sim_name)\n", - " sim_mf6gwt = build_mf6gwt(sim_name)\n", - " sim_mf2005 = build_mf2005(sim_name)\n", - " sim_mt3dms = build_mt3dms(sim_name, sim_mf2005)\n", - " sims = (sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms)\n", - " return sims" - ] - }, - { - "cell_type": "markdown", - "id": "681e519b", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2d6f097c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sims, silent=True):\n", - " if config.writeModel:\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " sim_mf6gwf.write_simulation(silent=silent)\n", - " sim_mf6gwt.write_simulation(silent=silent)\n", - " sim_mf2005.write_input()\n", - " sim_mt3dms.write_input()\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "60dd5b82", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8d8f8192", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sims, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " success, buff = sim_mf6gwf.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mf6gwt.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mf2005.run_model(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mt3dms.run_model(\n", - " silent=silent, normal_msg=\"Program completed\"\n", - " )\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "73b04f5f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8c238d64", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sims, idx):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " mf6gwt_ra = sim_mf6gwt.get_model(\"trans\").obs.output.obs().data\n", - " fig, axs = plt.subplots(\n", - " 1, 1, figsize=figure_size, dpi=300, tight_layout=True\n", - " )\n", - " axs.plot(\n", - " mf6gwt_ra[\"totim\"],\n", - " mf6gwt_ra[\"MYOBS\"],\n", - " marker=\"o\",\n", - " ls=\"none\",\n", - " mec=\"blue\",\n", - " mfc=\"none\",\n", - " markersize=\"4\",\n", - " label=\"MODFLOW 6 GWT\",\n", - " )\n", - "\n", - " sim_ws = sim_mt3dms.model_ws\n", - " fname = os.path.join(sim_ws, \"MT3D001.OBS\")\n", - " mt3dms_ra = sim_mt3dms.load_obs(fname)\n", - " colname = mt3dms_ra.dtype.names[2]\n", - " axs.plot(\n", - " mt3dms_ra[\"time\"],\n", - " mt3dms_ra[colname],\n", - " linestyle=\"-\",\n", - " color=\"k\",\n", - " label=\"MT3DMS\",\n", - " )\n", - " axs.set_xlabel(\"Time (days)\")\n", - " axs.set_ylabel(\"Normalized Concentration (unitless)\")\n", - " axs.legend()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "b1cd1160", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "700d0581", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sim = build_model(example_name)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2ab47260", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "f8a223f0", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1703529d", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Simulated Zero-Order Growth in a Uniform Flow Field\n", - "\n", - " # Add a description of the plot(s)\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dsupp632.ipynb b/notebooks/ex-gwt-mt3dsupp632.ipynb deleted file mode 100644 index c2c5a419..00000000 --- a/notebooks/ex-gwt-mt3dsupp632.ipynb +++ /dev/null @@ -1,891 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "98fa2295", - "metadata": {}, - "source": [ - "## Zero-Order Production in a Dual-Domain System\n", - "\n", - "MT3DMS Supplemental Guide Problem 6.3.2\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "5a9a47f1", - "metadata": {}, - "source": [ - "### Zero-Order Production in a Dual-Domain System Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "c59820e3", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dc158494", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06c7677f", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "dae19d4e", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0b4f7a8b", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "08e3f64e", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e091361d", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "461bb8cc", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "64b359c7", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (3, 3)" - ] - }, - { - "cell_type": "markdown", - "id": "da5c0dd9", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "63cd1945", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "a92e8faf", - "metadata": {}, - "source": [ - "Scenario parameters - make sure there is at least one blank line before next item" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2a3d208d", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwt-mt3dsupp632a\": {\n", - " \"distribution_coefficient\": 0.25,\n", - " \"decay\": 0.0,\n", - " \"decay_sorbed\": -1.0e-3,\n", - " },\n", - " \"ex-gwt-mt3dsupp632b\": {\n", - " \"distribution_coefficient\": 0.25,\n", - " \"decay\": -5.0e-4,\n", - " \"decay_sorbed\": -5.0e-4,\n", - " },\n", - " \"ex-gwt-mt3dsupp632c\": {\n", - " \"distribution_coefficient\": 0.0,\n", - " \"decay\": -1.0e-3,\n", - " \"decay_sorbed\": 0.0,\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "ced708e6", - "metadata": {}, - "source": [ - "Scenario parameter units - make sure there is at least one blank line before next item\n", - "add parameter_units to add units to the scenario parameter table" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6e5ee3df", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_units = {\n", - " \"distribution_coefficient\": \"$mL g^{-1}$\",\n", - " \"decay\": \"$g/mL d^{-1}$\",\n", - " \"decay_sorbed\": \"$g/mL d^{-1}$\",\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "9de4e3f4", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b181fc5b", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "15070add", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "93c72173", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 2 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 401 # Number of columns\n", - "delr = 2.5 # Column width ($m$)\n", - "delc = 1.0 # Row width ($m$)\n", - "top = 1.0 # Top of the model ($m$)\n", - "botm = 0 # Layer bottom elevation ($m$)\n", - "specific_discharge = 0.06 # Specific discharge ($md^{-1}$)\n", - "longitudinal_dispersivity = 10 # Longitudinal dispersivity ($m$)\n", - "volfrac = 0.2 # volume fraction that is immobile domain (unitless)\n", - "porosity = 0.2 # Porosity of mobile domain (unitless)\n", - "porosity_immobile = 0.05 # Porosity of immobile domain (unitless)\n", - "bulk_density = 4.0 # Bulk density ($gL^{-1})$\n", - "zeta_im = 1.0e-3 # First-order mass transfer rate between the mobile and immobile domains ($d^{-1}$)\n", - "f = 0.8 # Fraction of sorption sites in contact with mobile water (unitless)\n", - "source_duration = 1000 # Source duration ($d$)\n", - "total_time = 10000 # Simulation time ($t$)\n", - "obs_xloc = 200.0 # Observation x location ($m$)" - ] - }, - { - "cell_type": "markdown", - "id": "fd1a5546", - "metadata": {}, - "source": [ - "Flags that can be adjusted to change example configuration" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cfb20d94", - "metadata": {}, - "outputs": [], - "source": [ - "zero_order_decay = True # Flag indicating whether decay is zero or first order\n", - "dual_domain = True # Flag indicating that dual domain is active" - ] - }, - { - "cell_type": "markdown", - "id": "a93761c1", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run and plot models\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9e02dc9a", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwf(sim_folder):\n", - " print(f\"Building mf6gwf model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwf\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = (\n", - " (source_duration, 1, 1.0),\n", - " (total_time - source_duration, 1, 1.0),\n", - " )\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(sim)\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " save_saturation=True,\n", - " icelltype=0,\n", - " k=1.0,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=1.0)\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=[[(0, 0, ncol - 1), 1.0]])\n", - " wel_spd = {\n", - " 0: [[(0, 0, 0), specific_discharge * delc * top]],\n", - " 1: [[(0, 0, 0), specific_discharge * delc * top]],\n", - " }\n", - " flopy.mf6.ModflowGwfwel(gwf, stress_period_data=wel_spd, pname=\"WEL-1\")\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "042aed5c", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwt(sim_folder, distribution_coefficient, decay, decay_sorbed):\n", - " print(f\"Building mf6gwt model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwt\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " pertim1 = source_duration\n", - " pertim2 = total_time - source_duration\n", - " tdis_ds = ((pertim1, 10, 1.0), (pertim2, 90, 1.0))\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(sim, linear_acceleration=\"bicgstab\")\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " if zero_order_decay:\n", - " first_order_decay = False\n", - " else:\n", - " first_order_decay = True\n", - " if distribution_coefficient > 0:\n", - " sorption = \"linear\"\n", - " bd = bulk_density\n", - " kd = distribution_coefficient\n", - " else:\n", - " sorption = None\n", - " bd = None\n", - " kd = None\n", - " flopy.mf6.ModflowGwtic(gwt, strt=0)\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " zero_order_decay=zero_order_decay,\n", - " first_order_decay=first_order_decay,\n", - " sorption=sorption,\n", - " porosity=porosity / (1.0 - volfrac),\n", - " decay=decay,\n", - " decay_sorbed=decay_sorbed,\n", - " bulk_density=bd,\n", - " distcoef=kd,\n", - " )\n", - " istsorption = sorption is not None\n", - " if dual_domain:\n", - " flopy.mf6.ModflowGwtist(\n", - " gwt,\n", - " zero_order_decay=zero_order_decay,\n", - " first_order_decay=first_order_decay,\n", - " sorption=istsorption,\n", - " porosity=porosity_immobile / volfrac,\n", - " volfrac=volfrac,\n", - " zetaim=zeta_im,\n", - " decay=decay,\n", - " decay_sorbed=decay_sorbed,\n", - " bulk_density=bd,\n", - " distcoef=distribution_coefficient,\n", - " )\n", - " flopy.mf6.ModflowGwtadv(gwt)\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " xt3d_off=True,\n", - " alh=longitudinal_dispersivity,\n", - " ath1=longitudinal_dispersivity,\n", - " )\n", - " pd = [\n", - " (\"GWFHEAD\", f\"../mf6gwf/flow.hds\", None),\n", - " (\"GWFBUDGET\", \"../mf6gwf/flow.bud\", None),\n", - " ]\n", - " flopy.mf6.ModflowGwtfmi(gwt, packagedata=pd)\n", - " cnc_spd = {\n", - " 0: [[(0, 0, 0), 1.0]],\n", - " 1: [[(0, 0, 0), 0.0]],\n", - " }\n", - " flopy.mf6.ModflowGwtcnc(gwt, stress_period_data=cnc_spd)\n", - " sourcerecarray = [[]]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - " obsj = int(obs_xloc / delr) + 1\n", - " obs_data = {\n", - " f\"{name}.obs.csv\": [\n", - " (\"myobs\", \"CONCENTRATION\", (0, 0, obsj)),\n", - " ],\n", - " }\n", - " obs_package = flopy.mf6.ModflowUtlobs(\n", - " gwt, digits=10, print_input=True, continuous=obs_data\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b3bb47e4", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf2005(sim_folder):\n", - " print(f\"Building mf2005 model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf2005\")\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=name, model_ws=sim_ws, exe_name=\"mf2005\"\n", - " )\n", - " pertim1 = source_duration\n", - " pertim2 = total_time - source_duration\n", - " perlen = [pertim1, pertim2]\n", - " dis = flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " nper=nper,\n", - " perlen=perlen,\n", - " )\n", - " bas = flopy.modflow.ModflowBas(mf)\n", - " lpf = flopy.modflow.ModflowLpf(mf)\n", - " pcg = flopy.modflow.ModflowPcg(mf)\n", - " lmt = flopy.modflow.ModflowLmt(mf)\n", - " chd = flopy.modflow.ModflowChd(\n", - " mf, stress_period_data=[[0, 0, ncol - 1, 1.0, 1.0]]\n", - " )\n", - " wel_spd = {\n", - " 0: [[0, 0, 0, specific_discharge * delc * top]],\n", - " 1: [[0, 0, 0, specific_discharge * delc * top]],\n", - " }\n", - " wel = flopy.modflow.ModflowWel(mf, stress_period_data=wel_spd)\n", - " return mf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "88919b57", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mt3dms(\n", - " sim_folder, distribution_coefficient, decay, decay_sorbed, modflowmodel\n", - "):\n", - " print(f\"Building mt3dms model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mt3d\")\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=name,\n", - " model_ws=sim_ws,\n", - " exe_name=\"mt3dms\",\n", - " modflowmodel=modflowmodel,\n", - " ftlfilename=\"../mf2005/mt3d_link.ftl\",\n", - " )\n", - " dt0 = source_duration / 10.0\n", - " btn = flopy.mt3d.Mt3dBtn(\n", - " mt, laycon=0, prsity=porosity, obs=[(0, 0, 81)], dt0=dt0, ifmtcn=1\n", - " )\n", - " adv = flopy.mt3d.Mt3dAdv(mt, mixelm=0)\n", - " dsp = flopy.mt3d.Mt3dDsp(mt, al=longitudinal_dispersivity)\n", - " sp1 = distribution_coefficient\n", - " sp2 = 0.0\n", - " rc1 = decay\n", - " rc2 = decay_sorbed\n", - " prsity2 = 0.0\n", - " if dual_domain:\n", - " prsity2 = porosity_immobile\n", - " if distribution_coefficient > 0:\n", - " isothm = 6 # dual domain with sorption\n", - " sp2 = zeta_im\n", - " else:\n", - " isothm = 5 # dual domain without sorption\n", - " sp2 = zeta_im\n", - " rc2 = 0.0\n", - " else:\n", - " isothm = 1\n", - " if distribution_coefficient > 0:\n", - " rc2 = decay_sorbed\n", - " else:\n", - " rc2 = 0\n", - " if zero_order_decay:\n", - " ireact = 100 # zero order decay\n", - " else:\n", - " ireact = 1 # first order decay\n", - " rct = flopy.mt3d.Mt3dRct(\n", - " mt,\n", - " isothm=isothm,\n", - " ireact=ireact,\n", - " igetsc=0,\n", - " rhob=bulk_density,\n", - " sp1=sp1,\n", - " sp2=sp2,\n", - " prsity2=prsity2,\n", - " rc1=rc1,\n", - " rc2=rc2,\n", - " )\n", - " ssm_spd = {0: [0, 0, 0, 1.0, -1], 1: [0, 0, 0, 0.0, -1]}\n", - " ssm = flopy.mt3d.Mt3dSsm(mt, stress_period_data=ssm_spd)\n", - " gcg = flopy.mt3d.Mt3dGcg(mt)\n", - " return mt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3eb57aea", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name, distribution_coefficient, decay, decay_sorbed):\n", - " sims = None\n", - " if config.buildModel:\n", - " sim_mf6gwf = build_mf6gwf(sim_name)\n", - " sim_mf6gwt = build_mf6gwt(\n", - " sim_name, distribution_coefficient, decay, decay_sorbed\n", - " )\n", - " sim_mf2005 = build_mf2005(sim_name)\n", - " sim_mt3dms = build_mt3dms(\n", - " sim_name, distribution_coefficient, decay, decay_sorbed, sim_mf2005\n", - " )\n", - " sims = (sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms)\n", - " return sims" - ] - }, - { - "cell_type": "markdown", - "id": "e65b72b4", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7cbcb52a", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sims, silent=True):\n", - " if config.writeModel:\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " sim_mf6gwf.write_simulation(silent=silent)\n", - " sim_mf6gwt.write_simulation(silent=silent)\n", - " sim_mf2005.write_input()\n", - " sim_mt3dms.write_input()\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "8ea1b3e7", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3f04b05d", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sims, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " success, buff = sim_mf6gwf.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mf6gwt.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mf2005.run_model(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mt3dms.run_model(\n", - " silent=silent, normal_msg=\"Program completed\"\n", - " )\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "aee2a5dd", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Functions to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "403e742d", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_results():\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - "\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " fig, axs = plt.subplots(\n", - " 1, 1, figsize=figure_size, dpi=300, tight_layout=True\n", - " )\n", - "\n", - " case_colors = [\"blue\", \"green\", \"red\"]\n", - " for icase, sim_name in enumerate(parameters.keys()):\n", - " sim_ws = os.path.join(ws, sim_name)\n", - "\n", - " fname = os.path.join(sim_ws, \"mf6gwt\", \"trans.obs.csv\")\n", - " mf6gwt_ra = flopy.utils.Mf6Obs(fname).data\n", - " axs.plot(\n", - " mf6gwt_ra[\"totim\"],\n", - " mf6gwt_ra[\"MYOBS\"],\n", - " markerfacecolor=\"None\",\n", - " markeredgecolor=\"k\",\n", - " marker=\"o\",\n", - " markersize=\"4\",\n", - " linestyle=\"None\",\n", - " )\n", - "\n", - " fname = os.path.join(sim_ws, \"mt3d\", \"MT3D001.OBS\")\n", - " mt3dms_ra = flopy.mt3d.Mt3dms.load_obs(fname)\n", - " axs.plot(\n", - " mt3dms_ra[\"time\"],\n", - " mt3dms_ra[\"(1, 1, 82)\"],\n", - " color=case_colors[icase],\n", - " label=f\"Scenario {icase + 1}\",\n", - " )\n", - "\n", - " axs.set_ylim(0, 16)\n", - " axs.set_xlabel(\"Time (days)\")\n", - " axs.set_ylabel(\"Normalized Concentration (unitless)\")\n", - " axs.legend()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fname = \"{}{}\".format(\"ex-gwt-mt3dsupp632\", config.figure_ext)\n", - " fpth = os.path.join(\"..\", \"figures\", fname)\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "94f6a765", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_scenario_results(sims, idx):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - "\n", - " mf6gwt_ra = sim_mf6gwt.get_model(\"trans\").obs.output.obs().data\n", - " fig, axs = plt.subplots(\n", - " 1, 1, figsize=figure_size, dpi=300, tight_layout=True\n", - " )\n", - " axs.plot(\n", - " mf6gwt_ra[\"totim\"],\n", - " mf6gwt_ra[\"MYOBS\"],\n", - " markerfacecolor=\"None\",\n", - " markeredgecolor=\"b\",\n", - " marker=\"o\",\n", - " markersize=\"4\",\n", - " linestyle=\"None\",\n", - " label=\"MODFLOW 6 GWT\",\n", - " )\n", - " sim_ws = sim_mt3dms.model_ws\n", - " fname = os.path.join(sim_ws, \"MT3D001.OBS\")\n", - " mt3dms_ra = sim_mt3dms.load_obs(fname)\n", - " axs.plot(\n", - " mt3dms_ra[\"time\"],\n", - " mt3dms_ra[\"(1, 1, 82)\"],\n", - " linestyle=\"-\",\n", - " color=\"k\",\n", - " label=\"MT3DMS\",\n", - " )\n", - " axs.legend()\n", - " title = f\"Case {idx + 1} \"\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " fs.heading(letter=letter, heading=title)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "fd1e01a1", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5db70b49", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " parameter_dict = parameters[key]\n", - " sims = build_model(key, **parameter_dict)\n", - " write_model(sims, silent=silent)\n", - " success = run_model(sims, silent=silent)\n", - " if success:\n", - " plot_scenario_results(sims, idx)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "383a5b7c", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "39989ac5", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " scenario(1, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4a4cf95a", - "metadata": {}, - "outputs": [], - "source": [ - "def test_03():\n", - " scenario(2, silent=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ba7b843e", - "metadata": {}, - "outputs": [], - "source": [ - "def test_plot_results():\n", - " plot_results()" - ] - }, - { - "cell_type": "markdown", - "id": "bf8b0fb1", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "957b1328", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Case 1\n", - " #\n", - " # ex-gwt-mt3dsupp632a\n", - " # * distribution_coefficient = 0.25\n", - " # * decay = 0.0\n", - " # * decay_sorbed = -1.0e-3\n", - "\n", - " scenario(0)\n", - "\n", - " # ### Case 2\n", - " #\n", - " # ex-gwt-mt3dsupp632a\n", - " # * distribution_coefficient = 0.25\n", - " # * decay = -5.e-4\n", - " # * decay_sorbed = -5.e-4\n", - "\n", - " scenario(1)\n", - "\n", - " # ### Case 3\n", - " #\n", - " # ex-gwt-mt3dsupp632a\n", - " # * distribution_coefficient = 0.\n", - " # * decay = -1.0e-3\n", - " # * decay_sorbed = 0.\n", - "\n", - " scenario(2)\n", - "\n", - " # ### Plot the Zero-Order Production in a Dual-Domain System Problem results\n", - " #\n", - " # Plot the results for all 3 scenarios in one plot\n", - "\n", - " plot_results()" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-mt3dsupp82.ipynb b/notebooks/ex-gwt-mt3dsupp82.ipynb deleted file mode 100644 index 58be6dd5..00000000 --- a/notebooks/ex-gwt-mt3dsupp82.ipynb +++ /dev/null @@ -1,715 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "c36eec8c", - "metadata": {}, - "source": [ - "## Simulating Effect of Recirculation Well\n", - "\n", - "MT3DMS Supplemental Guide Problem 8.2\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "7cdea745", - "metadata": {}, - "source": [ - "### Simulating Effect of Recirculation Well Problem Setup\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b669106b", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e3ae25a0", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "fc6772f5", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "24d6c12c", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "70cdc3fb", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8570e7c5", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "markdown", - "id": "44fe737f", - "metadata": {}, - "source": [ - "Set figure properties specific to the" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cb80e244", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (5, 3)" - ] - }, - { - "cell_type": "markdown", - "id": "e57a728f", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b56c1918", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-mt3dsupp82\"" - ] - }, - { - "cell_type": "markdown", - "id": "06b6c13c", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "17d77c60", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "5416849d", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8d758a15", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nlay = 1 # Number of layers\n", - "nrow = 31 # Number of rows\n", - "ncol = 46 # Number of columns\n", - "delr = 10.0 # Column width ($m$)\n", - "delc = 10.0 # Row width ($m$)\n", - "top = 10.0 # Top of the model ($m$)\n", - "botm = 0.0 # Layer bottom elevation ($m$)\n", - "hydraulic_conductivity = 10.0 # Hydraulic conductivity ($md^{-1}$)\n", - "alpha_l = 10.0 # Longitudinal dispersivity ($m$)\n", - "alpha_th = 3.0 # Transverse horizontal dispersivity ($m$)\n", - "alpha_tv = 0.3 # Transverse vertical dispersivity ($m$)\n", - "total_time = 365.0 # Simulation time ($d$)\n", - "porosity = 0.3 # Porosity of mobile domain (unitless)" - ] - }, - { - "cell_type": "markdown", - "id": "f411bcbe", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model\n", - "recharge is the only variable\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b239529f", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwf(sim_folder):\n", - " print(f\"Building mf6gwf model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwf\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = ((total_time, 1, 1.0),)\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(sim)\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " save_saturation=True,\n", - " icelltype=0,\n", - " k=hydraulic_conductivity,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=0.0)\n", - " cinflow = 0.0\n", - " chdlist1 = [[(0, i, 0), 1000.0 + 7.29e-4, cinflow] for i in range(nrow)]\n", - " chdlist1 += [[(0, i, ncol - 1), 1000.0 + -4.5, 0.0] for i in range(nrow)]\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chdlist1,\n", - " print_input=True,\n", - " print_flows=True,\n", - " save_flows=False,\n", - " pname=\"CHD-1\",\n", - " auxiliary=[\n", - " (\"CONCENTRATION\"),\n", - " ],\n", - " )\n", - " wellbottom = 0.0\n", - " wellradius = 0.01\n", - " ngwfnodes = 1\n", - " concwell = 1000.0\n", - " strt = 0.0\n", - " mawpackagedata = [\n", - " [iwell, wellradius, wellbottom, strt, \"THIEM\", ngwfnodes, concwell]\n", - " for iwell in range(4)\n", - " ]\n", - " mawconnectiondata = [\n", - " [0, 0, (0, 15, 15), 10.0, 0.0, 10.0, 0.1],\n", - " [1, 0, (0, 15, 20), 10.0, 0.0, 10.0, 0.1],\n", - " [2, 0, (0, 4, 15), 10.0, 0.0, 10.0, 0.1],\n", - " [3, 0, (0, 26, 15), 10.0, 0.0, 10.0, 0.1],\n", - " ]\n", - " mawspd = [[0, \"rate\", 1.0], [1, \"rate\", -1.0]]\n", - "\n", - " flopy.mf6.ModflowGwfmaw(\n", - " gwf,\n", - " print_input=True,\n", - " print_head=True,\n", - " print_flows=True,\n", - " save_flows=True,\n", - " mover=True,\n", - " no_well_storage=True,\n", - " head_filerecord=f\"{name}.maw.hds\",\n", - " budget_filerecord=f\"{name}.maw.bud\",\n", - " packagedata=mawpackagedata,\n", - " connectiondata=mawconnectiondata,\n", - " perioddata=mawspd,\n", - " pname=\"MAW-1\",\n", - " auxiliary=[\"CONCENTRATION\"],\n", - " )\n", - "\n", - " packages = [\n", - " (\"maw-1\",),\n", - " ]\n", - " perioddata = [\n", - " (\"MAW-1\", 1, \"MAW-1\", 2, \"factor\", 0.5),\n", - " (\"MAW-1\", 1, \"MAW-1\", 3, \"factor\", 0.5),\n", - " ]\n", - " flopy.mf6.ModflowGwfmvr(\n", - " gwf,\n", - " maxmvr=len(perioddata),\n", - " budget_filerecord=f\"{name}.mvr.bud\",\n", - " maxpackages=len(packages),\n", - " print_flows=True,\n", - " packages=packages,\n", - " perioddata=perioddata,\n", - " )\n", - "\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d61a5a61", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwt(sim_folder):\n", - " print(f\"Building mf6gwt model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwt\")\n", - " sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\")\n", - " tdis_ds = ((total_time, 20, 1.0),)\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(sim, linear_acceleration=\"bicgstab\")\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwtic(gwt, strt=0)\n", - " flopy.mf6.ModflowGwtmst(gwt, porosity=porosity)\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=\"upstream\")\n", - " flopy.mf6.ModflowGwtdsp(gwt, alh=alpha_l, ath1=alpha_th, atv=alpha_tv)\n", - " pd = [\n", - " (\"GWFHEAD\", f\"../mf6gwf/flow.hds\", None),\n", - " (\"GWFBUDGET\", \"../mf6gwf/flow.bud\", None),\n", - " (\"GWFMOVER\", \"../mf6gwf/flow.mvr.bud\", None),\n", - " (\"MAW-1\", \"../mf6gwf/flow.maw.bud\", None),\n", - " ]\n", - " flopy.mf6.ModflowGwtfmi(gwt, packagedata=pd)\n", - "\n", - " mwtpackagedata = [\n", - " (0, 0.0, 99.0, 999.0, \"inject\"),\n", - " (1, 0.0, 99.0, 999.0, \"extract\"),\n", - " (2, 0.0, 99.0, 999.0, \"reinject1\"),\n", - " (3, 0.0, 99.0, 999.0, \"reinject2\"),\n", - " ]\n", - " mwtperioddata = [\n", - " (0, \"RATE\", 1000.0),\n", - " (0, \"CONCENTRATION\", 1000.0),\n", - " (0, \"STATUS\", \"ACTIVE\"),\n", - " (1, \"STATUS\", \"ACTIVE\"),\n", - " (2, \"STATUS\", \"ACTIVE\"),\n", - " (3, \"STATUS\", \"ACTIVE\"),\n", - " ]\n", - " flopy.mf6.modflow.ModflowGwtmwt(\n", - " gwt,\n", - " boundnames=True,\n", - " save_flows=True,\n", - " print_input=True,\n", - " print_flows=True,\n", - " print_concentration=True,\n", - " concentration_filerecord=name + \".mwt.bin\",\n", - " budget_filerecord=name + \".mwt.bud\",\n", - " packagedata=mwtpackagedata,\n", - " mwtperioddata=mwtperioddata,\n", - " observations=None,\n", - " pname=\"MAW-1\",\n", - " auxiliary=[\"aux1\", \"aux2\"],\n", - " )\n", - "\n", - " flopy.mf6.modflow.ModflowGwtmvt(gwt, print_flows=True)\n", - " sourcerecarray = [\n", - " (\"CHD-1\", \"AUX\", \"CONCENTRATION\"),\n", - " ]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{name}.cbc\",\n", - " concentration_filerecord=f\"{name}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", ncol, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"ALL\")],\n", - " printrecord=[\n", - " (\"CONCENTRATION\", \"ALL\"),\n", - " (\n", - " \"BUDGET\",\n", - " \"ALL\",\n", - " ),\n", - " ],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cc39993b", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf2005(sim_folder):\n", - " print(f\"Building mf2005 model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf2005\")\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=name, model_ws=sim_ws, exe_name=\"mf2005\"\n", - " )\n", - " perlen = [total_time]\n", - " dis = flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " nper=nper,\n", - " perlen=perlen,\n", - " )\n", - " bas = flopy.modflow.ModflowBas(mf)\n", - " lpf = flopy.modflow.ModflowLpf(mf, hk=hydraulic_conductivity)\n", - " pcg = flopy.modflow.ModflowPcg(mf)\n", - " lmt = flopy.modflow.ModflowLmt(mf)\n", - "\n", - " h = 1000.0 + 7.29e-4\n", - " chdspd = [[0, i, 0, h, h] for i in range(nrow)]\n", - " h = 1000.0 + -4.5\n", - " chdspd += [[0, i, ncol - 1, h, h] for i in range(nrow)]\n", - " chd = flopy.modflow.ModflowChd(mf, stress_period_data=chdspd)\n", - "\n", - " q = 1.0\n", - " welspd = [\n", - " [0, 15, 15, q], # injection\n", - " [0, 15, 20, -q], # extraction\n", - " [0, 4, 15, 0.5 * q], # reinjection\n", - " [0, 26, 15, 0.5 * q],\n", - " ] # reinjection\n", - " wel = flopy.modflow.ModflowWel(mf, stress_period_data=welspd)\n", - " return mf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8d52fd0a", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mt3dms(sim_folder, modflowmodel):\n", - " print(f\"Building mt3dms model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mt3d\")\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=name,\n", - " model_ws=sim_ws,\n", - " exe_name=\"mt3dms\",\n", - " modflowmodel=modflowmodel,\n", - " ftlfilename=\"../mf2005/mt3d_link.ftl\",\n", - " )\n", - " dt0 = total_time / 20.0\n", - " btn = flopy.mt3d.Mt3dBtn(mt, laycon=0, prsity=porosity, dt0=dt0, ifmtcn=1)\n", - " adv = flopy.mt3d.Mt3dAdv(mt, mixelm=0)\n", - " dsp = flopy.mt3d.Mt3dDsp(\n", - " mt, al=alpha_l, trpt=alpha_th / alpha_l, trpv=alpha_tv / alpha_l\n", - " )\n", - "\n", - " ssmspd = [\n", - " [0, 15, 15, 1000.0, 2],\n", - " [0, 4, 15, -711, 2],\n", - " [0, 26, 15, -711, 2],\n", - " ]\n", - " ssm = flopy.mt3d.Mt3dSsm(mt, mxss=66, stress_period_data=ssmspd)\n", - " gcg = flopy.mt3d.Mt3dGcg(mt)\n", - " return mt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7f709879", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name):\n", - " sims = None\n", - " if config.buildModel:\n", - " sim_mf6gwf = build_mf6gwf(sim_name)\n", - " sim_mf6gwt = build_mf6gwt(sim_name)\n", - " sim_mf2005 = build_mf2005(sim_name)\n", - " sim_mt3dms = build_mt3dms(sim_name, sim_mf2005)\n", - " sims = (sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms)\n", - " return sims" - ] - }, - { - "cell_type": "markdown", - "id": "c2a23109", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2dfe1080", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sims, silent=True):\n", - " if config.writeModel:\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " sim_mf6gwf.write_simulation(silent=silent)\n", - " sim_mf6gwt.write_simulation(silent=silent)\n", - " sim_mf2005.write_input()\n", - " sim_mt3dms.write_input()\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "571d964a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "36c1907e", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sims, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " success, buff = sim_mf6gwf.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mf6gwt.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mf2005.run_model(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mt3dms.run_model(\n", - " silent=silent, normal_msg=\"Program completed\"\n", - " )\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "c2195988", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "69435591", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sims, idx):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " gwf = sim_mf6gwf.flow\n", - " gwt = sim_mf6gwt.trans\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - "\n", - " conc = gwt.output.concentration().get_data()\n", - "\n", - " sim_ws = sim_mt3dms.model_ws\n", - " fname = os.path.join(sim_ws, \"MT3D001.UCN\")\n", - " cobjmt = flopy.utils.UcnFile(fname)\n", - " concmt = cobjmt.get_data()\n", - "\n", - " fig, ax = plt.subplots(\n", - " 1, 1, figsize=figure_size, dpi=300, tight_layout=True\n", - " )\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax)\n", - " pmv.plot_bc(ftype=\"MAW\", color=\"red\")\n", - " pmv.plot_bc(ftype=\"CHD\")\n", - " pmv.plot_grid(linewidths=0.25)\n", - "\n", - " a = np.ma.masked_less(conc, 0.01)\n", - " pa = pmv.plot_array(a, cmap=\"jet\", alpha=0.25)\n", - " plt.colorbar(pa, shrink=0.5)\n", - "\n", - " levels = [0.01, 0.1, 1, 10, 100]\n", - " cs1 = pmv.contour_array(concmt, levels=levels, colors=\"r\")\n", - "\n", - " cs2 = pmv.contour_array(\n", - " conc, levels=levels, colors=\"b\", linestyles=\"--\"\n", - " )\n", - " ax.clabel(cs2, cs2.levels[::1], fmt=\"%3.2f\", colors=\"b\")\n", - "\n", - " labels = [\"MT3DMS\", \"MODFLOW 6\"]\n", - " lines = [cs1.collections[0], cs2.collections[0]]\n", - " ax.legend(lines, labels, loc=\"lower right\")\n", - "\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_ylabel(\"y position (m)\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-map{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "85527e58", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b5a50c7d", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sim = build_model(example_name)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aed42eac", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "a4e8d007", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e4a621ba", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Simulated Zero-Order Growth in a Uniform Flow Field\n", - "\n", - " # Add a description of the plot(s)\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-prudic2004t2.ipynb b/notebooks/ex-gwt-prudic2004t2.ipynb deleted file mode 100644 index 8d3bdabe..00000000 --- a/notebooks/ex-gwt-prudic2004t2.ipynb +++ /dev/null @@ -1,1030 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "851f2e6d", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Stream-Lake Interaction with Solute Transport\n", - "\n", - "SFR1 Package Documentation Test Problem 2\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "0a96304f", - "metadata": {}, - "source": [ - "### Stream-Lake Interaction with Solute Transport Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "c93fd680", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b58d829e", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "229b3397", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "517e3d7a", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7cb38b9f", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "f6620336", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "665f9c49", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "04405e9e", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "5bfbfc2c", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "123806eb", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 6)" - ] - }, - { - "cell_type": "markdown", - "id": "e80509e9", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f52930ca", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-prudic2004t2\"\n", - "data_ws = os.path.join(config.data_ws, example_name)" - ] - }, - { - "cell_type": "markdown", - "id": "0ff20a57", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "11d6d864", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"feet\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "4bf27090", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e1188cf3", - "metadata": {}, - "outputs": [], - "source": [ - "hk = 250.0 # Horizontal hydraulic conductivity ($ft d^{-1}$)\n", - "vk = 125.0 # Vertical hydraulic conductivity ($ft d^{-1}$)\n", - "ss = 0.0 # Storage coefficient (unitless)\n", - "aquifer_thickness = 120.0 # Aquifer thickness ($ft$)\n", - "porosity = 0.30 # Porosity of mobile domain (unitless)\n", - "recharge = 4.79e-3 # Recharge rate ($ft d^{-1}$)\n", - "lakebed_leakance = 1.0 # Lakebed leakance ($ft^{-1}$)\n", - "streambed_k = 100.0 # Streambed hydraulic conductivity ($ft d^{-1}$)\n", - "streambed_thick = 1.0 # Streambed thickness ($ft$)\n", - "stream_width = 5.0 # Stream width ($ft$)\n", - "manning = 0.03 # Manning's roughness coefficient (unitless)\n", - "alpha_l = 20.0 # Longitudinal dispersivity ($ft$)\n", - "alpha_th = 2.0 # Transverse horizontal dispersivity ($ft$)\n", - "alpha_tv = 0.2 # Transverse vertical dispersivity ($ft$)\n", - "diffc = 0.0 # Diffusion coefficient ($ft^2 d^{-1}$)\n", - "cstrt = 0.0 # Initial concentration (micrograms per liter)\n", - "source_concentration = 500.0 # Source concentration (micrograms per liter)\n", - "nlay = 8 # Number of layers\n", - "nrow = 36 # Number of rows\n", - "ncol = 23 # Number of columns\n", - "delr = 405.665 # Column width ($ft$)\n", - "delc = 403.717 # Row width ($ft$)\n", - "delv = 15.0 # Layer thickness ($ft$)\n", - "top = 100.0 # Top of the model ($ft$)\n", - "total_time = 9131.0 # Total simulation time ($d$)" - ] - }, - { - "cell_type": "markdown", - "id": "5578630f", - "metadata": {}, - "source": [ - "Load Data Arrays" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bd475dcc", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "fname = os.path.join(data_ws, \"bot1.dat\")\n", - "bot0 = np.loadtxt(fname)\n", - "botm = [bot0] + [bot0 - (15.0 * k) for k in range(1, nlay)]\n", - "fname = os.path.join(data_ws, \"idomain1.dat\")\n", - "idomain0 = np.loadtxt(fname, dtype=int)\n", - "idomain = nlay * [idomain0]\n", - "fname = os.path.join(data_ws, \"lakibd.dat\")\n", - "lakibd = np.loadtxt(fname, dtype=int)" - ] - }, - { - "cell_type": "markdown", - "id": "5c3e1714", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Other model information" - ] - }, - { - "cell_type": "markdown", - "id": "36835199", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy GWF simulation object (sim) is returned\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c491dc26", - "metadata": {}, - "outputs": [], - "source": [ - "def get_stream_data():\n", - " fname = os.path.join(data_ws, \"stream.csv\")\n", - " dt = 5 * [int] + [float]\n", - " streamdata = np.genfromtxt(fname, names=True, delimiter=\",\", dtype=dt)\n", - " connectiondata = [[ireach] for ireach in range(streamdata.shape[0])]\n", - " isegold = -1\n", - " distance_along_segment = []\n", - " for ireach, row in enumerate(streamdata):\n", - " iseg = row[\"seg\"] - 1\n", - " if iseg == isegold:\n", - " connectiondata[ireach].append(ireach - 1)\n", - " connectiondata[ireach - 1].append(-ireach)\n", - " distance += (\n", - " streamdata[\"length\"][ireach - 1] * 0.5\n", - " + streamdata[\"length\"][ireach] * 0.5\n", - " )\n", - " else:\n", - " distance = 0.5 * streamdata[\"length\"][ireach]\n", - " isegold = iseg\n", - " distance_along_segment.append(distance)\n", - " # add a few additional connections\n", - " connectiondata[17].append(-31)\n", - " connectiondata[31].append(17)\n", - " connectiondata[30].append(-31)\n", - " connectiondata[31].append(30)\n", - " packagedata = []\n", - " segment_lengths = []\n", - " for iseg in [1, 2, 3, 4]:\n", - " idx = np.where(streamdata[\"seg\"] == iseg)\n", - " segment_length = streamdata[\"length\"][idx].sum()\n", - " segment_lengths.append(segment_length)\n", - " emaxmin = [(49, 45), (44.5, 34), (41.5, 34.0), (34.0, 27.2)]\n", - " segment_gradients = []\n", - " for iseg, (emax, emin) in enumerate(emaxmin):\n", - " segment_gradients.append((emax - emin) / segment_lengths[iseg])\n", - " ustrf = 1.0\n", - " ndv = 0\n", - " for ireach, row in enumerate(streamdata):\n", - " k, i, j = row[\"layer\"] - 1, row[\"row\"] - 1, row[\"col\"] - 1\n", - " length = row[\"length\"]\n", - " iseg = row[\"seg\"] - 1\n", - " rgrd = segment_gradients[iseg]\n", - " emax, emin = emaxmin[iseg]\n", - " rtp = distance_along_segment[ireach] / segment_lengths[iseg] * (emax - emin)\n", - " rtp = emax - rtp\n", - " boundname = f\"SEG{iseg + 1}\"\n", - " rec = (\n", - " ireach,\n", - " (k, i, j),\n", - " length,\n", - " stream_width,\n", - " rgrd,\n", - " rtp,\n", - " streambed_thick,\n", - " streambed_k,\n", - " manning,\n", - " len(connectiondata[ireach]) - 1,\n", - " ustrf,\n", - " ndv,\n", - " boundname,\n", - " )\n", - " packagedata.append(rec)\n", - "\n", - " return packagedata, connectiondata" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "397a05d5", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_mf6gwf(sim_folder):\n", - " global idomain\n", - " print(f\"Building mf6gwf model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwf\")\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " tdis_data = [(total_time, 1, 1.0)]\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=len(tdis_data), perioddata=tdis_data, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " outer_maximum=1000,\n", - " inner_maximum=50,\n", - " outer_dvclose=0.01,\n", - " inner_dvclose=0.01,\n", - " relaxation_factor=0.99,\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " dis = flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " save_saturation=True,\n", - " icelltype=[1] + 7 * [0],\n", - " k=hk,\n", - " k33=vk,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=50.0)\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " flopy.mf6.ModflowGwfrcha(gwf, recharge={0: recharge}, pname=\"RCH-1\")\n", - "\n", - " chdlist = []\n", - " fname = os.path.join(data_ws, \"chd.dat\")\n", - " for line in open(fname).readlines():\n", - " ll = line.strip().split()\n", - " if len(ll) == 4:\n", - " k, i, j, hd = ll\n", - " chdlist.append(\n", - " [\n", - " (\n", - " int(k) - 1,\n", - " int(i) - 1,\n", - " int(j) - 1,\n", - " ),\n", - " float(hd),\n", - " ]\n", - " )\n", - " flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chdlist, pname=\"CHD-1\")\n", - "\n", - " idomain = dis.idomain.array\n", - " lake_map = np.ones((nlay, nrow, ncol), dtype=np.int32) * -1\n", - " lake_map[0, :, :] = lakibd[:, :] - 1\n", - " (\n", - " idomain,\n", - " lakepakdata_dict,\n", - " lakeconnectiondata,\n", - " ) = flopy.mf6.utils.get_lak_connections(\n", - " gwf.modelgrid,\n", - " lake_map,\n", - " idomain=idomain,\n", - " bedleak=lakebed_leakance,\n", - " )\n", - "\n", - " gwf.dis.idomain.set_data(idomain[0], layer=0, multiplier=[1])\n", - " lakpackagedata = [\n", - " [0, 44.0, lakepakdata_dict[0], \"lake1\"],\n", - " [1, 35.2, lakepakdata_dict[1], \"lake2\"],\n", - " ]\n", - " # \n", - " outlets = [[0, 0, -1, \"MANNING\", 44.5, 3.36493214532915, 0.03, 0.2187500e-02]]\n", - " flopy.mf6.ModflowGwflak(\n", - " gwf,\n", - " time_conversion=86400.000,\n", - " length_conversion=3.28081,\n", - " print_stage=True,\n", - " print_flows=True,\n", - " stage_filerecord=name + \".lak.bin\",\n", - " budget_filerecord=name + \".lak.bud\",\n", - " mover=True,\n", - " pname=\"LAK-1\",\n", - " boundnames=True,\n", - " nlakes=len(lakpackagedata),\n", - " noutlets=len(outlets),\n", - " outlets=outlets,\n", - " packagedata=lakpackagedata,\n", - " connectiondata=lakeconnectiondata,\n", - " )\n", - "\n", - " sfrpackagedata, sfrconnectiondata = get_stream_data()\n", - " sfrperioddata = {0: [[0, \"inflow\", 86400], [18, \"inflow\", 8640.0]]}\n", - " sfr_obs = {\n", - " (name + \".sfr.obs.csv\",): [\n", - " (\"reach1leakage\", \"SFR\", \"SEG1\"),\n", - " (\"reach2leakage\", \"SFR\", \"SEG2\"),\n", - " (\"reach3leakage\", \"SFR\", \"SEG3\"),\n", - " (\"reach4leakage\", \"SFR\", \"SEG4\"),\n", - " ],\n", - " }\n", - " sfr_obs[\"digits\"] = 7\n", - " sfr_obs[\"print_input\"] = True\n", - " sfr_obs[\"filename\"] = name + \".sfr.obs\"\n", - " flopy.mf6.ModflowGwfsfr(\n", - " gwf,\n", - " print_stage=True,\n", - " print_flows=True,\n", - " stage_filerecord=name + \".sfr.bin\",\n", - " budget_filerecord=name + \".sfr.bud\",\n", - " mover=True,\n", - " pname=\"SFR-1\",\n", - " time_conversion=86400.000,\n", - " length_conversion=3.28081,\n", - " boundnames=True,\n", - " nreaches=len(sfrconnectiondata),\n", - " packagedata=sfrpackagedata,\n", - " connectiondata=sfrconnectiondata,\n", - " perioddata=sfrperioddata,\n", - " observations=sfr_obs,\n", - " )\n", - " maxmvr, maxpackages = 2, 2\n", - " mvrpack = [[\"SFR-1\"], [\"LAK-1\"]]\n", - " mvrperioddata = [\n", - " [\"SFR-1\", 5, \"LAK-1\", 0, \"FACTOR\", 1.0],\n", - " [\"LAK-1\", 0, \"SFR-1\", 6, \"FACTOR\", 1.0],\n", - " ]\n", - " flopy.mf6.ModflowGwfmvr(\n", - " gwf,\n", - " maxmvr=maxmvr,\n", - " print_flows=True,\n", - " budget_filerecord=name + \".mvr.bud\",\n", - " maxpackages=maxpackages,\n", - " packages=mvrpack,\n", - " perioddata=mvrperioddata,\n", - " )\n", - "\n", - " return sim" - ] - }, - { - "cell_type": "markdown", - "id": "f831c98a", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "MODFLOW 6 flopy GWF simulation object (sim) is returned" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "01127c36", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwt(sim_folder):\n", - " print(f\"Building mf6gwt model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwt\")\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name, sim_ws=sim_ws, exe_name=\"mf6\"\n", - " )\n", - " tdis_data = ((total_time, 300, 1.0),)\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=len(tdis_data), perioddata=tdis_data, time_units=time_units\n", - " )\n", - " flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"SUMMARY\",\n", - " outer_maximum=50,\n", - " under_relaxation=\"DBD\",\n", - " under_relaxation_theta=0.7,\n", - " linear_acceleration=\"bicgstab\",\n", - " relaxation_factor=0.97,\n", - " )\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=name, save_flows=True)\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " )\n", - " flopy.mf6.ModflowGwtic(gwt, strt=0)\n", - " flopy.mf6.ModflowGwtmst(gwt, porosity=porosity)\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=\"TVD\")\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=alpha_l,\n", - " ath1=alpha_th,\n", - " ath2=alpha_tv,\n", - " )\n", - " sourcerecarray = [[]]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - " cnclist = [\n", - " [(0, 0, 11), 500.0],\n", - " [(0, 0, 12), 500.0],\n", - " [(0, 0, 13), 500.0],\n", - " [(0, 0, 14), 500.0],\n", - " [(1, 0, 11), 500.0],\n", - " [(1, 0, 12), 500.0],\n", - " [(1, 0, 13), 500.0],\n", - " [(1, 0, 14), 500.0],\n", - " ]\n", - " flopy.mf6.ModflowGwtcnc(\n", - " gwt,\n", - " maxbound=len(cnclist),\n", - " stress_period_data=cnclist,\n", - " save_flows=False,\n", - " pname=\"CNC-1\",\n", - " )\n", - "\n", - " lktpackagedata = [\n", - " (0, 0.0, 99.0, 999.0, \"mylake1\"),\n", - " (1, 0.0, 99.0, 999.0, \"mylake2\"),\n", - " ]\n", - " lktperioddata = [\n", - " (0, \"STATUS\", \"ACTIVE\"),\n", - " (1, \"STATUS\", \"ACTIVE\"),\n", - " ]\n", - " lkt_obs = {\n", - " (name + \".lkt.obs.csv\",): [\n", - " (\"lkt1conc\", \"CONCENTRATION\", 1),\n", - " (\"lkt2conc\", \"CONCENTRATION\", 2),\n", - " (\"lkt1frommvr\", \"FROM-MVR\", (0,)),\n", - " (\"lkt2frommvr\", \"FROM-MVR\", (1,)),\n", - " (\"lkt1tomvr\", \"TO-MVR\", (0,)),\n", - " (\"lkt1bntomvr\", \"TO-MVR\", \"mylake1\"),\n", - " ],\n", - " }\n", - " lkt_obs[\"digits\"] = 7\n", - " lkt_obs[\"print_input\"] = True\n", - " lkt_obs[\"filename\"] = name + \".lkt.obs\"\n", - " flopy.mf6.modflow.ModflowGwtlkt(\n", - " gwt,\n", - " boundnames=True,\n", - " save_flows=True,\n", - " print_input=True,\n", - " print_flows=True,\n", - " print_concentration=True,\n", - " concentration_filerecord=name + \".lkt.bin\",\n", - " budget_filerecord=name + \".lkt.bud\",\n", - " packagedata=lktpackagedata,\n", - " lakeperioddata=lktperioddata,\n", - " observations=lkt_obs,\n", - " pname=\"LAK-1\",\n", - " auxiliary=[\"aux1\", \"aux2\"],\n", - " )\n", - "\n", - " nreach = 38\n", - " sftpackagedata = []\n", - " for irno in range(nreach):\n", - " t = (irno, 0.0, 99.0, 999.0, f\"myreach{irno + 1}\")\n", - " sftpackagedata.append(t)\n", - "\n", - " sftperioddata = [\n", - " (0, \"STATUS\", \"ACTIVE\"),\n", - " ]\n", - "\n", - " sft_obs = {\n", - " (name + \".sft.obs.csv\",): [\n", - " (f\"sft{i + 1}conc\", \"CONCENTRATION\", i + 1) for i in range(nreach)\n", - " ]\n", - " }\n", - " # append additional obs attributes to obs dictionary\n", - " sft_obs[\"digits\"] = 7\n", - " sft_obs[\"print_input\"] = True\n", - " sft_obs[\"filename\"] = name + \".sft.obs\"\n", - " flopy.mf6.modflow.ModflowGwtsft(\n", - " gwt,\n", - " boundnames=True,\n", - " save_flows=True,\n", - " print_input=True,\n", - " print_flows=True,\n", - " print_concentration=True,\n", - " concentration_filerecord=name + \".sft.bin\",\n", - " budget_filerecord=name + \".sft.bud\",\n", - " packagedata=sftpackagedata,\n", - " reachperioddata=sftperioddata,\n", - " observations=sft_obs,\n", - " pname=\"SFR-1\",\n", - " auxiliary=[\"aux1\", \"aux2\"],\n", - " )\n", - "\n", - " pd = [\n", - " (\"GWFHEAD\", \"../mf6gwf/flow.hds\", None),\n", - " (\"GWFBUDGET\", \"../mf6gwf/flow.bud\", None),\n", - " (\"GWFMOVER\", \"../mf6gwf/flow.mvr.bud\", None),\n", - " (\"LAK-1\", \"../mf6gwf/flow.lak.bud\", None),\n", - " (\"SFR-1\", \"../mf6gwf/flow.sfr.bud\", None),\n", - " ]\n", - " flopy.mf6.ModflowGwtfmi(gwt, packagedata=pd)\n", - "\n", - " # mover transport package\n", - " flopy.mf6.modflow.ModflowGwtmvt(gwt, print_flows=True)\n", - "\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{name}.bud\",\n", - " concentration_filerecord=f\"{name}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", ncol, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "783f9c1b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name):\n", - " sims = None\n", - " if config.buildModel:\n", - " sim_mf6gwf = build_mf6gwf(sim_name)\n", - " sim_mf6gwt = build_mf6gwt(sim_name)\n", - " sims = (sim_mf6gwf, sim_mf6gwt)\n", - " return sims" - ] - }, - { - "cell_type": "markdown", - "id": "52d3d46f", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "094c6743", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sims, silent=True):\n", - " if config.writeModel:\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " sim_mf6gwf.write_simulation(silent=silent)\n", - " sim_mf6gwt.write_simulation(silent=silent)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "5fa26714", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a5938f93", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sims, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " success, buff = sim_mf6gwf.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " success, buff = sim_mf6gwt.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "1e8b0fae", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b3bf7fce", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_bcmap(ax, gwf, layer=0):\n", - " pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=layer)\n", - " # pmv.plot_grid()\n", - " pmv.plot_inactive(color_noflow=\"gray\", alpha=0.25)\n", - " pmv.plot_array(lakibd, masked_values=[0], alpha=0.2)\n", - " pmv.plot_bc(name=\"CHD-1\", color=\"blue\")\n", - " # pmv.plot_bc(name=\"LAK-1\", color=\"yellow\")\n", - " pmv.plot_bc(name=\"SFR-1\", color=\"green\")\n", - " ax.set_xlabel(\"x position (ft)\")\n", - " ax.set_ylabel(\"y position (ft)\")\n", - " ax.set_aspect(\"equal\")\n", - " return pmv" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "adfbbdb4", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_results(sims):\n", - " plot_gwf_results(sims)\n", - " plot_gwt_results(sims)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ac4017db", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_gwf_results(sims):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " gwf = sim_mf6gwf.flow\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - "\n", - " sim_ws = sim_mf6gwf.simulation_data.mfpath.get_sim_path()\n", - "\n", - " head = gwf.output.head().get_data()\n", - " stage = gwf.lak.output.stage().get_data().flatten()\n", - "\n", - " il, jl = np.where(lakibd > 0)\n", - " for i, j in zip(il, jl):\n", - " ilak = lakibd[i, j] - 1\n", - " lake_stage = stage[ilak]\n", - " head[0, i, j] = lake_stage\n", - "\n", - " fig, axs = plt.subplots(1, 2, figsize=figure_size, dpi=300, tight_layout=True)\n", - "\n", - " for ilay in [0, 1]:\n", - " ax = axs[ilay]\n", - " pmv = plot_bcmap(ax, gwf, ilay)\n", - " levels = np.arange(20, 60, 1)\n", - " cs = pmv.contour_array(\n", - " head,\n", - " colors=\"blue\",\n", - " linestyles=\"-\",\n", - " levels=levels,\n", - " masked_values=[1.0e30],\n", - " )\n", - " ax.clabel(cs, cs.levels[::5], fmt=\"%1.0f\", colors=\"b\")\n", - " title = f\"Model Layer {ilay + 1}\"\n", - " letter = chr(ord(\"@\") + ilay + 1)\n", - " fs.heading(letter=letter, heading=title, ax=ax)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-head{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5b8d2d2b", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_gwt_results(sims):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " sim_mf6gwf, sim_mf6gwt = sims\n", - " gwf = sim_mf6gwf.flow\n", - " gwt = sim_mf6gwt.trans\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - "\n", - " sim_ws = sim_mf6gwt.simulation_data.mfpath.get_sim_path()\n", - "\n", - " conc = gwt.output.concentration().get_data()\n", - " lakconc = gwt.lak.output.concentration().get_data().flatten()\n", - "\n", - " il, jl = np.where(lakibd > 0)\n", - " for i, j in zip(il, jl):\n", - " ilak = lakibd[i, j] - 1\n", - " lake_conc = lakconc[ilak]\n", - " conc[0, i, j] = lake_conc\n", - "\n", - " fig, axs = plt.subplots(2, 2, figsize=(5, 7), dpi=300, tight_layout=True)\n", - "\n", - " for iplot, ilay in enumerate([0, 2, 4, 7]):\n", - " ax = axs.flatten()[iplot]\n", - " pmv = plot_bcmap(ax, gwf, ilay)\n", - " levels = levels = [\n", - " 1,\n", - " 10,\n", - " 25,\n", - " 50,\n", - " 100,\n", - " 150,\n", - " 200,\n", - " 250,\n", - " 300,\n", - " 350,\n", - " 400,\n", - " 450,\n", - " 500,\n", - " ]\n", - " cs = pmv.contour_array(\n", - " conc,\n", - " colors=\"blue\",\n", - " linestyles=\"-\",\n", - " levels=levels,\n", - " linewidths=1.0,\n", - " masked_values=[1.0e30],\n", - " )\n", - " ax.clabel(cs, cs.levels[::1], fmt=\"%1.0f\", colors=\"b\")\n", - " title = f\"Model Layer {ilay + 1}\"\n", - " letter = chr(ord(\"@\") + iplot + 1)\n", - " fs.heading(letter=letter, heading=title, ax=ax)\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-conc{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)\n", - "\n", - " # create concentration timeseries plot\n", - " lkaconc = gwt.lak.output.concentration().get_alldata()[:, 0, 0, :]\n", - " bobj = gwt.sfr.output.concentration()\n", - " sfaconc = bobj.get_alldata()[:, 0, 0, :]\n", - " times = bobj.times\n", - "\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " fig, axs = plt.subplots(1, 1, figsize=(5, 3), dpi=300, tight_layout=True)\n", - " ax = axs\n", - " times = np.array(times) / 365.0\n", - " ax.plot(times, lkaconc[:, 0], \"b-\", label=\"Lake 1 and Stream Segment 2\")\n", - " ax.plot(times, sfaconc[:, 30], \"r-\", label=\"Stream Segment 3\")\n", - " ax.plot(times, sfaconc[:, 37], \"g-\", label=\"Stream Segment 4\")\n", - "\n", - " fname = os.path.join(data_ws, \"teststrm.sg2\")\n", - " sg = np.genfromtxt(fname, comments='\"')\n", - " ax.plot(sg[:, 0] / 365.0, sg[:, 6], \"b--\")\n", - "\n", - " fname = os.path.join(data_ws, \"teststrm.sg3\")\n", - " sg = np.genfromtxt(fname, comments='\"')\n", - " ax.plot(sg[:, 0] / 365.0, sg[:, 6], \"r--\")\n", - "\n", - " fname = os.path.join(data_ws, \"teststrm.sg4\")\n", - " sg = np.genfromtxt(fname, comments='\"')\n", - " ax.plot(sg[:, 0] / 365.0, sg[:, 3], \"g--\")\n", - "\n", - " fs.graph_legend()\n", - " ax.set_ylim(0, 50)\n", - " ax.set_xlim(0, 25)\n", - " ax.set_xlabel(\"TIME, IN YEARS\")\n", - " ax.set_ylabel(\"SIMULATED BORON CONCENTRATION,\\nIN MICROGRAMS PER LITER\")\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-cvt{config.figure_ext}\"\n", - " fpth = os.path.join(ws, \"..\", \"figures\", fname)\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "b948f955", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1df2a91a", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sims = build_model(example_name)\n", - " write_model(sims, silent=silent)\n", - " success = run_model(sims, silent=silent)\n", - " if success:\n", - " plot_results(sims)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f7a22204", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "730db190", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1dfb2135", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Model\n", - "\n", - " # Model run\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-rotate.ipynb b/notebooks/ex-gwt-rotate.ipynb deleted file mode 100644 index 7adf832a..00000000 --- a/notebooks/ex-gwt-rotate.ipynb +++ /dev/null @@ -1,745 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "bdbcd082", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Rotating Interface Problem\n", - "\n", - "Density driven groundwater flow\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "d4422fd3", - "metadata": {}, - "source": [ - "### Rotating Interface Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "d64fc478", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c2d38ad7", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "88373711", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "d6428717", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a224c47d", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "d90339d5", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bbcbe685", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from analytical import BakkerRotatingInterface\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fac92e5a", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "ceb9c4b0", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "71fe7cb4", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 4)" - ] - }, - { - "cell_type": "markdown", - "id": "988edf2c", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d97672bc", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-rotate\"" - ] - }, - { - "cell_type": "markdown", - "id": "37ec7768", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8b44c95c", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "eef59589", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e89ea512", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nstp = 1000 # Number of time steps\n", - "perlen = 10000 # Simulation time length ($d$)\n", - "length = 300 # Length of box ($m$)\n", - "height = 40.0 # Height of box ($m$)\n", - "nlay = 80 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 300 # Number of columns\n", - "system_length = 150.0 # Length of system ($m$)\n", - "delr = 1.0 # Column width ($m$)\n", - "delc = 1.0 # Row width ($m$)\n", - "delv = 0.5 # Layer thickness\n", - "top = height / 2 # Top of the model ($m$)\n", - "hydraulic_conductivity = 2.0 # Hydraulic conductivity ($m d^{-1}$)\n", - "denseref = 1000.0 # Reference density\n", - "denseslp = 0.7 # Density and concentration slope\n", - "rho1 = 1000.0 # Density of zone 1 ($kg m^3$)\n", - "rho2 = 1012.5 # Density of zone 2 ($kg m^3$)\n", - "rho3 = 1025.0 # Density of zone 3 ($kg m^3$)\n", - "c1 = 0.0 # Concentration of zone 1 ($kg m^3$)\n", - "c2 = 17.5 # Concentration of zone 2 ($kg m^3$)\n", - "c3 = 35 # Concentration of zone 3 ($kg m^3$)\n", - "a1 = 40.0 # Interface extent for zone 1 and 2\n", - "a2 = 40.0 # Interface extent for zone 2 and 3\n", - "b = height / 2.0\n", - "x1 = 170.0 # X-midpoint location for zone 1 and 2 interface\n", - "x2 = 130.0 # X-midpoint location for zone 2 and 3 interface\n", - "porosity = 0.2 # Porosity (unitless)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f0c1545a", - "metadata": {}, - "outputs": [], - "source": [ - "botm = [top - k * delv for k in range(1, nlay + 1)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "79e639fe", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-8, 1e-8, 0.97" - ] - }, - { - "cell_type": "markdown", - "id": "94bb0334", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy GWF simulation object (sim) is returned\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3095cabc", - "metadata": {}, - "outputs": [], - "source": [ - "def get_cstrt(nlay, ncol, length, x1, x2, a1, a2, b, c1, c2, c3):\n", - " cstrt = c1 * np.ones((nlay, ncol), dtype=float)\n", - " from flopy.utils.gridintersect import GridIntersect\n", - " from shapely.geometry import Polygon\n", - "\n", - " p3 = Polygon([(0, b), (x2 - a2, b), (x2 + a2, 0), (0, 0)])\n", - " p2 = Polygon([(x2 - a2, b), (x1 - a1, b), (x1 + a1, 0), (x1 - a1, 0)])\n", - " delc = b / nlay * np.ones(nlay)\n", - " delr = length / ncol * np.ones(ncol)\n", - " sgr = flopy.discretization.StructuredGrid(delc, delr)\n", - " ix = GridIntersect(sgr, method=\"structured\")\n", - " for ival, p in [(c2, p2), (c3, p3)]:\n", - " result = ix.intersect(p)\n", - " for i, j in list(result[\"cellids\"]):\n", - " cstrt[i, j] = ival\n", - " return cstrt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3d39c599", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_folder):\n", - " print(f\"Building model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name,\n", - " sim_ws=sim_ws,\n", - " exe_name=\"mf6\",\n", - " continue_=True,\n", - " )\n", - " tdis_ds = ((perlen, nstp, 1.0),)\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=tdis_ds, time_units=time_units\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " ims = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"ALL\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwf.name}.ims\",\n", - " )\n", - " sim.register_ims_package(ims, [gwf.name])\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " icelltype=0,\n", - " k=hydraulic_conductivity,\n", - " )\n", - " flopy.mf6.ModflowGwfic(gwf, strt=top)\n", - " pd = [(0, denseslp, 0.0, \"trans\", \"concentration\")]\n", - " flopy.mf6.ModflowGwfbuy(gwf, denseref=denseref, packagedata=pd)\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - "\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=\"trans\")\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"ALL\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwt.name}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwtmst(gwt, porosity=porosity)\n", - " cstrt = get_cstrt(nlay, ncol, length, x1, x2, a1, a2, height, c1, c2, c3)\n", - " flopy.mf6.ModflowGwtic(gwt, strt=cstrt)\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=\"TVD\")\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwt.name}.cbc\",\n", - " concentration_filerecord=f\"{gwt.name}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"ALL\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim, exgtype=\"GWF6-GWT6\", exgmnamea=gwf.name, exgmnameb=gwt.name\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "markdown", - "id": "409f3356", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6609fe90", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "05a07e44", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "23c75bd9", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "f19a5e27", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "04c4073f", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_velocity_profile(sim, idx):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = example_name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(\"flow\")\n", - " gwt = sim.get_model(\"trans\")\n", - " print(\"Creating velocity profile plot...\")\n", - "\n", - " # find line of cells on left side of first interface\n", - " cstrt = gwt.ic.strt.array\n", - " cstrt = cstrt.reshape((nlay, ncol))\n", - " interface_coords = []\n", - " for k in range(nlay):\n", - " crow = cstrt[k]\n", - " j = (np.abs(crow - c2)).argmin() - 1\n", - " interface_coords.append((k, j))\n", - "\n", - " # plot velocity\n", - " xc, yc, zc = gwt.modelgrid.xyzcellcenters\n", - " xg = []\n", - " zg = []\n", - " for k, j in interface_coords:\n", - " x = xc[0, j]\n", - " z = zc[k, 0, j]\n", - " xg.append(x)\n", - " zg.append(z)\n", - " xg = np.array(xg)\n", - " zg = np.array(zg)\n", - "\n", - " # set up plot\n", - " fig = plt.figure(figsize=(4, 6))\n", - " ax = fig.add_subplot(1, 1, 1)\n", - "\n", - " # plot analytical solution\n", - " qx1, qz1 = BakkerRotatingInterface.get_w(\n", - " xg, zg, hydraulic_conductivity, rho1, rho2, a1, b, x1\n", - " )\n", - " qx2, qz2 = BakkerRotatingInterface.get_w(\n", - " xg, zg, hydraulic_conductivity, rho2, rho3, a2, b, x2\n", - " )\n", - " qx = qx1 + qx2\n", - " qz = qz1 + qz2\n", - " vh = qx + qz * a1 / b\n", - " vh = vh / porosity\n", - " ax.plot(vh, zg, \"k-\")\n", - "\n", - " # plot numerical results\n", - " file_name = gwf.oc.budget_filerecord.get_data()[0][0]\n", - " fpth = os.path.join(sim_ws, file_name)\n", - " bobj = flopy.utils.CellBudgetFile(fpth, precision=\"double\")\n", - " kstpkper = bobj.get_kstpkper()\n", - " spdis = bobj.get_data(text=\"DATA-SPDIS\", kstpkper=kstpkper[0])[0]\n", - " qxsim = spdis[\"qx\"].reshape((nlay, ncol))\n", - " qzsim = spdis[\"qz\"].reshape((nlay, ncol))\n", - " qx = []\n", - " qz = []\n", - " for k, j in interface_coords:\n", - " qx.append(qxsim[k, j])\n", - " qz.append(qzsim[k, j])\n", - " qx = np.array(qx)\n", - " qz = np.array(qz)\n", - " vh = qx + qz * a1 / b\n", - " vh = vh / porosity\n", - " ax.plot(vh, zg, \"bo\", mfc=\"none\")\n", - "\n", - " # configure plot and save\n", - " ax.plot([0, 0], [-b, b], \"k--\", linewidth=0.5)\n", - " ax.set_xlim(-0.1, 0.1)\n", - " ax.set_ylim(-b, b)\n", - " ax.set_ylabel(\"z location of left interface (m)\")\n", - " ax.set_xlabel(\"$v_h$ (m/d) of left interface at t=0\")\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\", \"figures\", f\"{sim_name}-vh{config.figure_ext}\"\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a7649db8", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_conc(sim, idx):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = example_name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(\"flow\")\n", - " gwt = sim.get_model(\"trans\")\n", - "\n", - " # make initial conditions figure\n", - " print(\"Creating initial conditions figure...\")\n", - " fig = plt.figure(figsize=(6, 4))\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 0})\n", - " pxs.plot_array(gwt.ic.strt.array, cmap=\"jet\", vmin=c1, vmax=c3)\n", - " pxs.plot_grid(linewidth=0.1)\n", - " ax.set_ylabel(\"z position (m)\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\", \"figures\", f\"{sim_name}-bc{config.figure_ext}\"\n", - " )\n", - " fig.savefig(fpth)\n", - " plt.close(\"all\")\n", - "\n", - " # make results plot\n", - " print(\"Making results plot...\")\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " # create MODFLOW 6 head object\n", - " cobj = gwt.output.concentration()\n", - " times = cobj.get_times()\n", - " times = np.array(times)\n", - "\n", - " # plot times in the original publication\n", - " plot_times = [\n", - " 2000.0,\n", - " 10000.0,\n", - " ]\n", - "\n", - " nplots = len(plot_times)\n", - " for iplot in range(nplots):\n", - " time_in_pub = plot_times[iplot]\n", - " idx_conc = (np.abs(times - time_in_pub)).argmin()\n", - " time_this_plot = times[idx_conc]\n", - " conc = cobj.get_data(totim=time_this_plot)\n", - "\n", - " ax = fig.add_subplot(2, 1, iplot + 1)\n", - " pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 0})\n", - " pxs.plot_array(conc, cmap=\"jet\", vmin=c1, vmax=c3)\n", - " ax.set_xlim(0, length)\n", - " ax.set_ylim(-height / 2.0, height / 2.0)\n", - " ax.set_ylabel(\"z position (m)\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_title(f\"Time = {time_this_plot} days\")\n", - " plt.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\", \"figures\", f\"{sim_name}-conc{config.figure_ext}\"\n", - " )\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1c1ee2ee", - "metadata": {}, - "outputs": [], - "source": [ - "def make_animated_gif(sim, idx):\n", - " from matplotlib.animation import FuncAnimation, PillowWriter\n", - "\n", - " print(\"Creating animation...\")\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = example_name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(\"flow\")\n", - " gwt = sim.get_model(\"trans\")\n", - "\n", - " cobj = gwt.output.concentration()\n", - " times = cobj.get_times()\n", - " times = np.array(times)\n", - " conc = cobj.get_alldata()\n", - "\n", - " fig = plt.figure(figsize=(6, 4))\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 0})\n", - " pc = pxs.plot_array(conc[0], cmap=\"jet\", vmin=c1, vmax=c3)\n", - "\n", - " def init():\n", - " ax.set_xlim(0, length)\n", - " ax.set_ylim(-height / 2, height / 2)\n", - " ax.set_title(f\"Time = {times[0]} seconds\")\n", - "\n", - " def update(i):\n", - " pc.set_array(conc[i].flatten())\n", - " ax.set_title(f\"Time = {times[i]} days\")\n", - "\n", - " ani = FuncAnimation(\n", - " fig, update, range(1, times.shape[0], 5), init_func=init\n", - " )\n", - " writer = PillowWriter(fps=50)\n", - " fpth = os.path.join(\"..\", \"figures\", \"{}{}\".format(sim_name, \".gif\"))\n", - " ani.save(fpth, writer=writer)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8ca92c49", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, idx):\n", - " if config.plotModel:\n", - " plot_conc(sim, idx)\n", - " plot_velocity_profile(sim, idx)\n", - " if config.plotSave and config.createGif:\n", - " make_animated_gif(sim, idx)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "93edaec9", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "550aa0de", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sim = build_model(example_name)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "624b4ba1", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "9ee083b4", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3f679389", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Rotating Interface Problem\n", - "\n", - " # Plot showing MODFLOW 6 results\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-saltlake.ipynb b/notebooks/ex-gwt-saltlake.ipynb deleted file mode 100644 index 9cc393ed..00000000 --- a/notebooks/ex-gwt-saltlake.ipynb +++ /dev/null @@ -1,653 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "ad3f2063", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "## Salt Lake Problem\n", - "\n", - "Density driven groundwater flow\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "98773a8a", - "metadata": {}, - "source": [ - "### Salt Lake Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "fbfff7d7", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6fc1f3f5", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "436ce8ae", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "b0ce4789", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "550dca77", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "5a235486", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fc924ace", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aa7329c5", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mf2005\"\n", - "exe_name_mt = \"mt3dms\"" - ] - }, - { - "cell_type": "markdown", - "id": "3baae9a6", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "044c875f", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 8)" - ] - }, - { - "cell_type": "markdown", - "id": "24be04fc", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5409b7b2", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-saltlake\"" - ] - }, - { - "cell_type": "markdown", - "id": "1c676abb", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "757bdb0c", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"mm\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "d05e7f33", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f19ae1ae", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 1 # Number of periods\n", - "nstp = 400 # Number of time steps\n", - "perlen = 24000 # Simulation time length ($s$)\n", - "nlay = 57 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 135 # Number of columns\n", - "system_length = 150.0 # Length of system ($mm$)\n", - "delr_str = \"ranges from 0.75 to 1.5\" # Column width ($mm$)\n", - "delc = 1.5 # Row width ($mm$)\n", - "delv_str = \"ranges from 0.75 to 1.5\" # Layer thickness\n", - "top = 75.0 # Top of the model ($mm$)\n", - "hydraulic_conductivity = 3.05 # Hydraulic conductivity ($mm s^{-1}$)\n", - "ss = 3.8e-10 # Specific storage ($mm^{-1}$)\n", - "denseref = 0.001065 # Reference density\n", - "denseslp = 0.646 # Density and concentration slope\n", - "conc_inflow = 8.4e-5 # Initial and inflow concentration ($g L^{-1}$)\n", - "conc_sat = 1.1e-4 # Saturated concentration ($g L^{-1}$)\n", - "porosity = 1.0 # Porosity (unitless)\n", - "evap_rate = 1.03e-3 # Evaporation rate ($mm s^{-1}$)\n", - "alphal = 9.0e-7 # Longitudinal dispersivity ($mm$)\n", - "alphat = 9.0e-7 # Transverse dispersivity ($mm$)\n", - "diffc = 9.0e-4 # Diffusion coefficient ($mm s^{-1}$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f1bcac85", - "metadata": {}, - "outputs": [], - "source": [ - "delv = 14 * [0.75] + 43 * [1.5]\n", - "delr = 70 * [0.75] + 65 * [1.5]\n", - "tp = top\n", - "botm = []\n", - "for k in range(nlay):\n", - " bt = tp - delv[k]\n", - " botm.append(bt)\n", - " tp = bt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "68f651de", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-8, 1e-8, 0.97" - ] - }, - { - "cell_type": "markdown", - "id": "109f6e14", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy GWF simulation object (sim) is returned\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1713b490", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_folder):\n", - " print(f\"Building model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name,\n", - " sim_ws=sim_ws,\n", - " exe_name=\"mf6\",\n", - " )\n", - " tdis_ds = ((perlen, nstp, 1.0),)\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " ims = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"ALL\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwf.name}.ims\",\n", - " )\n", - " sim.register_ims_package(ims, [gwf.name])\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " icelltype=0,\n", - " k=hydraulic_conductivity,\n", - " )\n", - " flopy.mf6.ModflowGwfsto(gwf, ss=ss)\n", - " flopy.mf6.ModflowGwfic(gwf, strt=top)\n", - " pd = [(0, denseslp, 0.0, \"trans\", \"concentration\")]\n", - " flopy.mf6.ModflowGwfbuy(gwf, denseref=denseref, packagedata=pd)\n", - " chdspd = [[(0, 0, j), top, conc_inflow] for j in range(101, ncol)]\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chdspd,\n", - " pname=\"CHD-1\",\n", - " auxiliary=\"CONCENTRATION\",\n", - " )\n", - " rchspd = [[(0, 0, j), -evap_rate] for j in range(0, 67)]\n", - " flopy.mf6.ModflowGwfrch(\n", - " gwf,\n", - " stress_period_data=rchspd,\n", - " pname=\"RCH-1\",\n", - " )\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - "\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=\"trans\")\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"ALL\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwt.name}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwtmst(gwt, porosity=porosity)\n", - " flopy.mf6.ModflowGwtic(gwt, strt=conc_inflow)\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=\"UPSTREAM\")\n", - " flopy.mf6.ModflowGwtdsp(gwt, xt3d_off=True, alh=alphal, ath1=alphat, diffc=diffc)\n", - " sourcerecarray = [\n", - " (\"CHD-1\", \"AUX\", \"CONCENTRATION\"),\n", - " ]\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - " conc_rand = (np.random.random(67) - 0.5) * 0.01 * (\n", - " conc_sat - conc_inflow\n", - " ) + conc_sat\n", - " cncspd = [[(0, 0, j), conc_rand[j]] for j in range(0, 67)]\n", - " flopy.mf6.ModflowGwtcnc(\n", - " gwt,\n", - " stress_period_data=cncspd,\n", - " pname=\"CNC-1\",\n", - " )\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwt.name}.cbc\",\n", - " concentration_filerecord=f\"{gwt.name}.ucn\",\n", - " concentrationprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"CONCENTRATION\", \"ALL\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim, exgtype=\"GWF6-GWT6\", exgmnamea=gwf.name, exgmnameb=gwt.name\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "markdown", - "id": "5141d5fb", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1b9d1397", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "758e5168", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bd4716de", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "fc6b7389", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "78d0e1b7", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_conc(sim, idx):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = example_name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(\"flow\")\n", - " gwt = sim.get_model(\"trans\")\n", - "\n", - " # make bc figure\n", - " fig = plt.figure(figsize=(6, 4))\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 0})\n", - " pxs.plot_grid(linewidth=0.1)\n", - " pxs.plot_bc(\"RCH-1\", color=\"red\")\n", - " pxs.plot_bc(\"CHD-1\", color=\"blue\")\n", - " ax.set_ylabel(\"z position (m)\")\n", - " ax.set_xlabel(\"x position (m)\")\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-bc{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " plt.close(\"all\")\n", - "\n", - " # make results plot\n", - " fig = plt.figure(figsize=figure_size)\n", - " fig.tight_layout()\n", - "\n", - " # create MODFLOW 6 head object\n", - " cobj = gwt.output.concentration()\n", - " times = cobj.get_times()\n", - " times = np.array(times)\n", - "\n", - " # plot times in the original publication\n", - " plot_times = [\n", - " 2581.0,\n", - " 15485.0,\n", - " 5162.0,\n", - " 18053.0,\n", - " 10311.0,\n", - " 20634.0,\n", - " 12904.0,\n", - " 23215.0,\n", - " ]\n", - "\n", - " nplots = len(plot_times)\n", - " for iplot in range(nplots):\n", - " time_in_pub = plot_times[iplot]\n", - " idx_conc = (np.abs(times - time_in_pub)).argmin()\n", - " time_this_plot = times[idx_conc]\n", - " conc = cobj.get_data(totim=time_this_plot)\n", - "\n", - " ax = fig.add_subplot(4, 2, iplot + 1)\n", - " pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 0})\n", - " pxs.plot_array(conc, cmap=\"jet\", vmin=conc_inflow, vmax=conc_sat)\n", - " ax.set_xlim(0, 75.0)\n", - " ax.set_ylabel(\"z position (m)\")\n", - " if iplot in [6, 7]:\n", - " ax.set_xlabel(\"x position (m)\")\n", - " ax.set_title(f\"Time = {time_this_plot} seconds\")\n", - " plt.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\"..\", \"figures\", f\"{sim_name}-conc{config.figure_ext}\")\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "af6e5668", - "metadata": {}, - "outputs": [], - "source": [ - "def make_animated_gif(sim, idx):\n", - " from matplotlib.animation import FuncAnimation, PillowWriter\n", - "\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = example_name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(\"flow\")\n", - " gwt = sim.get_model(\"trans\")\n", - "\n", - " cobj = gwt.output.concentration()\n", - " times = cobj.get_times()\n", - " times = np.array(times)\n", - " conc = cobj.get_alldata()\n", - "\n", - " fig = plt.figure(figsize=(6, 4))\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={\"row\": 0})\n", - " pc = pxs.plot_array(conc[0], cmap=\"jet\", vmin=conc_inflow, vmax=conc_sat)\n", - "\n", - " def init():\n", - " ax.set_xlim(0, 75.0)\n", - " ax.set_ylim(0, 75.0)\n", - " ax.set_title(f\"Time = {times[0]} seconds\")\n", - "\n", - " def update(i):\n", - " pc.set_array(conc[i].flatten())\n", - " ax.set_title(f\"Time = {times[i]} seconds\")\n", - "\n", - " ani = FuncAnimation(fig, update, range(1, times.shape[0]), init_func=init)\n", - " writer = PillowWriter(fps=50)\n", - " fpth = os.path.join(\"..\", \"figures\", \"{}{}\".format(sim_name, \".gif\"))\n", - " ani.save(fpth, writer=writer)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "639f5f3c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, idx):\n", - " if config.plotModel:\n", - " plot_conc(sim, idx)\n", - " if config.plotSave and config.createGif:\n", - " make_animated_gif(sim, idx)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "2119b988", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0fe4aaeb", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sim = build_model(example_name)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "65cd9c65", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "48ef756b", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d7be4bd6", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Salt Lake Problem\n", - "\n", - " # Plot showing MODFLOW 6 results\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-stallman.ipynb b/notebooks/ex-gwt-stallman.ipynb deleted file mode 100644 index 900c5852..00000000 --- a/notebooks/ex-gwt-stallman.ipynb +++ /dev/null @@ -1,741 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "99b30e7a", - "metadata": {}, - "source": [ - "## Stallman Problem\n", - "\n", - "Periodic heat boundary condition at surface\n", - "Transient heat transfer problem in vertical\n" - ] - }, - { - "cell_type": "markdown", - "id": "675f283f", - "metadata": {}, - "source": [ - "### Stallman Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "00a0c65b", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c514c302", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "61a78035", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import matplotlib.animation as animation\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "id": "4b91834a", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5efa4acf", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "73262243", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eefbbf39", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from analytical import Stallman\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f210489d", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"" - ] - }, - { - "cell_type": "markdown", - "id": "db4efc27", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8b699a07", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 8)" - ] - }, - { - "cell_type": "markdown", - "id": "95ec61fb", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1470eb67", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-stallman\"" - ] - }, - { - "cell_type": "markdown", - "id": "2419f5b7", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0b2cbc99", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"seconds\"" - ] - }, - { - "cell_type": "markdown", - "id": "5107395d", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef5f4c3a", - "metadata": {}, - "outputs": [], - "source": [ - "nper = 600 # Number of periods\n", - "nstp = 6 # Number of time steps\n", - "perlen = 525600 # Simulation time length ($s$)\n", - "nlay = 120 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 1 # Number of columns\n", - "system_length = 60.0 # Length of system ($m$)\n", - "delr = 1.0 # Column width ($m$)\n", - "delc = 1.0 # Row width ($m$)\n", - "delv_str = \"ranges from 0.1 to 1\" # Layer thickness\n", - "top = 60.0 # Top of the model ($m$)\n", - "hydraulic_conductivity = 1.0e-4 # Hydraulic conductivity ($m s^{-1}$)\n", - "porosity = 0.35 # Porosity (unitless)\n", - "alphal = 0.0 # Longitudinal dispersivity ($m$)\n", - "alphat = 0.0 # Transverse dispersivity ($m$)\n", - "diffc = 1.02882e-06 # Diffusion coefficient ($m s^{-1}$)\n", - "T_az = 10 # Ambient temperature ($^o C$)\n", - "dT = 5 # Temperature variation ($^o C$)\n", - "bulk_dens = 2630 # Bulk density ($kg/m^3$)\n", - "kd = 0.000191663 # Distribution coefficient (unitless)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "755cf496", - "metadata": {}, - "outputs": [], - "source": [ - "# Stress period input\n", - "per_data = []\n", - "for k in range(nper):\n", - " per_data.append((perlen, nstp, 1.0))\n", - "per_mf6 = per_data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d768c242", - "metadata": {}, - "outputs": [], - "source": [ - "# Geometry input\n", - "tp = top\n", - "botm = []\n", - "for i in range(nlay):\n", - " if i == 0:\n", - " botm.append(59.9)\n", - " elif i == 119:\n", - " botm.append(0.0)\n", - " else:\n", - " botm.append(60 - i * 0.5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b3fffd27", - "metadata": {}, - "outputs": [], - "source": [ - "# Head input\n", - "chd_data = {}\n", - "for k in range(nper):\n", - " chd_data[k] = [[(0, 0, 0), 60.000000], [(119, 0, 0), 59.701801]]\n", - "chd_mf6 = chd_data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a0c8677b", - "metadata": {}, - "outputs": [], - "source": [ - "# Initial temperature input\n", - "strt_conc = T_az * np.ones((nlay, 1, 1), dtype=np.float32)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2048e36c", - "metadata": {}, - "outputs": [], - "source": [ - "# Boundary temperature input\n", - "cnc_data = {}\n", - "for k in range(nper):\n", - " cnc_temp = T_az + dT * np.sin(2 * np.pi * k * perlen / 365 / 86400)\n", - " cnc_data[k] = [[(0, 0, 0), cnc_temp]]\n", - "cnc_mf6 = cnc_data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2bf7465c", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-8, 1e-8, 0.97" - ] - }, - { - "cell_type": "markdown", - "id": "5b79137e", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy GWF simulation object (sim) is returned\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6d251308", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_folder):\n", - " print(f\"Building model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder)\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name,\n", - " sim_ws=sim_ws,\n", - " exe_name=\"mf6\",\n", - " )\n", - " flopy.mf6.ModflowTdis(\n", - " sim, nper=nper, perioddata=per_mf6, time_units=time_units\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)\n", - " ims = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"ALL\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"CG\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwf.name}.ims\",\n", - " )\n", - " sim.register_ims_package(ims, [gwf.name])\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_specific_discharge=True,\n", - " icelltype=0,\n", - " k=hydraulic_conductivity,\n", - " )\n", - "\n", - " flopy.mf6.ModflowGwfic(gwf, strt=top)\n", - "\n", - " flopy.mf6.ModflowGwfchd(\n", - " gwf,\n", - " stress_period_data=chd_mf6,\n", - " )\n", - "\n", - " head_filerecord = f\"{name}.hds\"\n", - " budget_filerecord = f\"{name}.bud\"\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=head_filerecord,\n", - " budget_filerecord=budget_filerecord,\n", - " saverecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - "\n", - " gwt = flopy.mf6.ModflowGwt(sim, modelname=\"trans\")\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"ALL\",\n", - " outer_dvclose=hclose,\n", - " outer_maximum=nouter,\n", - " under_relaxation=\"NONE\",\n", - " inner_maximum=ninner,\n", - " inner_dvclose=hclose,\n", - " rcloserecord=rclose,\n", - " linear_acceleration=\"BICGSTAB\",\n", - " scaling_method=\"NONE\",\n", - " reordering_method=\"NONE\",\n", - " relaxation_factor=relax,\n", - " filename=f\"{gwt.name}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " )\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=porosity,\n", - " sorption=\"linear\",\n", - " bulk_density=bulk_dens * (1 - porosity),\n", - " distcoef=kd,\n", - " )\n", - " flopy.mf6.ModflowGwtic(gwt, strt=strt_conc)\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=\"TVD\")\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt, xt3d_off=True, alh=alphal, ath1=alphat, diffc=diffc\n", - " )\n", - " flopy.mf6.ModflowGwtssm(gwt, sources=[[]])\n", - " flopy.mf6.ModflowGwtcnc(\n", - " gwt,\n", - " stress_period_data=cnc_mf6,\n", - " )\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwt.name}.cbc\",\n", - " concentration_filerecord=f\"{gwt.name}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"LAST\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"LAST\")],\n", - " )\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim, exgtype=\"GWF6-GWT6\", exgmnamea=gwf.name, exgmnameb=gwt.name\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "markdown", - "id": "db2819ae", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ea01acd0", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sim, silent=True):\n", - " if config.writeModel:\n", - " sim.write_simulation(silent=silent)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "96087415", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bcc1e789", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sim, silent=True):\n", - " print(\"Running model...\")\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "81b76fef", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e1ab86ec", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_conc(sim, idx):\n", - " fs = USGSFigure(figure_type=\"map\", verbose=False)\n", - " sim_name = example_name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(\"flow\")\n", - " gwt = sim.get_model(\"trans\")\n", - "\n", - " # create MODFLOW 6 head object\n", - " cobj = gwt.output.concentration()\n", - " times = cobj.get_times()\n", - " times = np.array(times)\n", - "\n", - " time_in_pub = 284349600.0\n", - " idx_conc = (np.abs(times - time_in_pub)).argmin()\n", - " time_this_plot = times[idx_conc]\n", - " conc = cobj.get_data(totim=time_this_plot)\n", - "\n", - " zconc = np.zeros(nlay)\n", - " zbotm = np.zeros(nlay)\n", - " for i in range(len(zconc)):\n", - " zconc[i] = conc[i][0][0]\n", - " if i != (nlay - 1):\n", - " zbotm[i + 1] = -(60 - botm[i])\n", - "\n", - " # Analytical solution - Stallman analysis\n", - " tau = 365 * 86400\n", - " # t = 283824000.0\n", - " t = 284349600.0\n", - " c_w = 4174\n", - " rho_w = 1000\n", - " c_r = 800\n", - " rho_r = bulk_dens\n", - " c_rho = c_r * rho_r * (1 - porosity) + c_w * rho_w * porosity\n", - " darcy_flux = 5.00e-07\n", - " ko = 1.503\n", - " zanal = Stallman(\n", - " T_az, dT, tau, t, c_rho, darcy_flux, ko, c_w, rho_w, zbotm, nlay\n", - " )\n", - "\n", - " # make conc figure\n", - " fig = plt.figure(figsize=(6, 4))\n", - " ax = fig.add_subplot(1, 1, 1)\n", - "\n", - " # configure plot and save\n", - " ax.plot(zconc, zbotm, \"bo\", mfc=\"none\", label=\"MODFLOW6-GWT\")\n", - " ax.plot(\n", - " zanal[:, 1],\n", - " zanal[:, 0],\n", - " \"k--\",\n", - " linewidth=1.0,\n", - " label=\"Analytical solution\",\n", - " )\n", - " ax.set_xlim(T_az - dT, T_az + dT)\n", - " ax.set_ylim(-top, 0)\n", - " ax.set_ylabel(\"Depth (m)\")\n", - " ax.set_xlabel(\"Temperature (deg C)\")\n", - " ax.legend()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\", \"figures\", f\"{sim_name}-conc{config.figure_ext}\"\n", - " )\n", - " fig.savefig(fpth)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "d52927c9", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to make animation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e7196b74", - "metadata": {}, - "outputs": [], - "source": [ - "def make_animated_gif(sim, idx):\n", - " sim_name = example_name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " gwf = sim.get_model(\"flow\")\n", - " gwt = sim.get_model(\"trans\")\n", - "\n", - " cobj = gwt.output.concentration()\n", - " times = cobj.get_times()\n", - " times = np.array(times)\n", - " conc = cobj.get_alldata()\n", - "\n", - " zconc = np.zeros(nlay)\n", - " zbotm = np.zeros(nlay)\n", - " for i in range(len(zconc)):\n", - " zconc[i] = conc[0][i][0][0]\n", - " if i != (nlay - 1):\n", - " zbotm[i + 1] = -(60 - botm[i])\n", - "\n", - " # Analytical solution - Stallman analysis\n", - " tau = 365 * 86400\n", - " t = times[0]\n", - " c_w = 4174\n", - " rho_w = 1000\n", - " c_r = 800\n", - " rho_r = bulk_dens\n", - " c_rho = c_r * rho_r * (1 - porosity) + c_w * rho_w * porosity\n", - " darcy_flux = 5.00e-07\n", - " ko = 1.503\n", - " zanal = Stallman(\n", - " T_az, dT, tau, t, c_rho, darcy_flux, ko, c_w, rho_w, zbotm, nlay\n", - " )\n", - "\n", - " fig, ax = plt.subplots(figsize=(6, 4))\n", - " ax.set_ylabel(\"Depth (m)\")\n", - " ax.set_xlabel(\"Temperature (deg C)\")\n", - " (l0,) = ax.plot([], [], \"bo\", mfc=\"none\", label=\"MODFLOW6-GWT\")\n", - " (l1,) = ax.plot([], [], \"k--\", linewidth=1.0, label=\"Analytical solution\")\n", - " line = [l0, l1]\n", - " ax.legend(loc=\"lower left\")\n", - " ax.set_xlim(T_az - dT, T_az + dT)\n", - " ax.set_ylim(-top, 0)\n", - "\n", - " def init():\n", - " ax.set_title(f\"Time = {times[0]} seconds\")\n", - "\n", - " def update(j):\n", - " for i in range(len(zconc)):\n", - " zconc[i] = conc[j][i][0][0]\n", - " t = times[j]\n", - " zanal = Stallman(\n", - " T_az, dT, tau, t, c_rho, darcy_flux, ko, c_w, rho_w, zbotm, nlay\n", - " )\n", - " line[0].set_data(zconc, zbotm)\n", - " line[1].set_data(zanal[:, 1], zanal[:, 0])\n", - " ax.set_title(f\"Time = {times[j]} seconds\")\n", - " return line\n", - "\n", - " ani = animation.FuncAnimation(fig, update, times.shape[0], init_func=init)\n", - " fpth = os.path.join(\"..\", \"figures\", \"{}{}\".format(sim_name, \".gif\"))\n", - " ani.save(fpth, fps=50)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "438700be", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(sim, idx):\n", - " print(\"Plotting results...\")\n", - " if config.plotModel:\n", - " plot_conc(sim, idx)\n", - " if config.plotSave and config.createGif:\n", - " print(\"Making animation...\")\n", - " make_animated_gif(sim, idx)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "9b181dba", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d5ef0263", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sim = build_model(example_name)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "24b12073", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "5b078d2f", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8420d8a6", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Salt Lake Problem\n", - "\n", - " # Plot showing MODFLOW 6 results\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-synthetic-valley.ipynb b/notebooks/ex-gwt-synthetic-valley.ipynb deleted file mode 100644 index 483470ff..00000000 --- a/notebooks/ex-gwt-synthetic-valley.ipynb +++ /dev/null @@ -1,1605 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "2e741541", - "metadata": {}, - "source": [ - "## Synthetic Valley Problem\n", - "\n", - "This problem is described in Hughes and others (2023).\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "1bbe9549", - "metadata": {}, - "source": [ - "### Synthetic Valley Problem\n", - "\n", - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1335e91f", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import pathlib as pl\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ebeb7243", - "metadata": {}, - "outputs": [], - "source": [ - "import flopy\n", - "import flopy.plot.styles as styles\n", - "import matplotlib.gridspec as gridspec\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib.ticker as mticker\n", - "import numpy as np\n", - "from flopy.discretization import StructuredGrid, VertexGrid\n", - "from flopy.utils.triangle import Triangle\n", - "from flopy.utils.voronoi import VoronoiGrid\n", - "from matplotlib import colors\n", - "from shapely.geometry import LineString, Polygon" - ] - }, - { - "cell_type": "markdown", - "id": "a8662e94", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e058cefe", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "8b2b0b17", - "metadata": {}, - "source": [ - "Import common functionality" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1f04684c", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "from groundwater2023_utils import (\n", - " circle_function,\n", - " densify_geometry,\n", - " geometries,\n", - " string2geom,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "0bb0123c", - "metadata": {}, - "source": [ - "Set figure properties specific to the example" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4f82efa6", - "metadata": {}, - "outputs": [], - "source": [ - "two_panel_figsize = (17.15 / 2.541, 0.8333 * 17.15 / 2.541)\n", - "one_panel_figsize = (8.25 / 2.541, 13.25 / 2.541)\n", - "six_panel_figsize = (17.15 / 2.541, 1.4 * 0.8333 * 17.15 / 2.541)" - ] - }, - { - "cell_type": "markdown", - "id": "f76b5620", - "metadata": {}, - "source": [ - "set figure element defaults" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2647b5e3", - "metadata": {}, - "outputs": [], - "source": [ - "levels = np.arange(10, 110, 10)\n", - "contour_color = \"black\"\n", - "contour_style = \"--\"\n", - "sv_contour_dict = {\n", - " \"linewidths\": 0.5,\n", - " \"colors\": contour_color,\n", - " \"linestyles\": contour_style,\n", - "}\n", - "sv_contour_dict = {\n", - " \"linewidths\": 0.5,\n", - " \"colors\": contour_color,\n", - " \"linestyles\": contour_style,\n", - "}\n", - "sv_gwt_contour_dict = {\n", - " \"linewidths\": 0.75,\n", - " \"colors\": contour_color,\n", - " \"linestyles\": contour_style,\n", - "}\n", - "contour_label_dict = {\n", - " \"linewidth\": 0.5,\n", - " \"color\": contour_color,\n", - " \"linestyle\": contour_style,\n", - "}\n", - "contour_gwt_label_dict = {\n", - " \"linewidth\": 0.75,\n", - " \"color\": contour_color,\n", - " \"linestyle\": contour_style,\n", - "}\n", - "clabel_dict = {\n", - " \"inline\": True,\n", - " \"fmt\": \"%1.0f\",\n", - " \"fontsize\": 6,\n", - " \"inline_spacing\": 0.5,\n", - "}\n", - "font_dict = {\"fontsize\": 5, \"color\": \"black\"}\n", - "grid_dict = {\"lw\": 0.25, \"color\": \"0.5\"}\n", - "arrowprops = dict(\n", - " arrowstyle=\"-\",\n", - " edgecolor=\"red\",\n", - " lw=0.5,\n", - " shrinkA=0.15,\n", - " shrinkB=0.15,\n", - ")\n", - "river_dict = {\"color\": \"blue\", \"linestyle\": \"-\", \"linewidth\": 1}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef8797d3", - "metadata": {}, - "outputs": [], - "source": [ - "lake_cmap = colors.ListedColormap([\"cyan\"])\n", - "clay_cmap = colors.ListedColormap([\"brown\"])" - ] - }, - { - "cell_type": "markdown", - "id": "9ba1951f", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "be24e713", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws\n", - "example_name = \"ex-gwt-synthetic-valley\"" - ] - }, - { - "cell_type": "markdown", - "id": "f3feedd6", - "metadata": {}, - "source": [ - "Conversion factors" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6a7fe79f", - "metadata": {}, - "outputs": [], - "source": [ - "ft2m = 1.0 / 3.28081\n", - "ft3tom3 = 1.0 * ft2m * ft2m * ft2m\n", - "ftpd2cmpy = 1000.0 * 365.25 * ft2m\n", - "mpd2cmpy = 100.0 * 365.25\n", - "mpd2inpy = 12.0 * 365.25 * 3.28081" - ] - }, - { - "cell_type": "markdown", - "id": "d5d12d44", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e5c8eaf9", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meters\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "cc156d3c", - "metadata": {}, - "source": [ - "Table of model parameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "57a89012", - "metadata": {}, - "outputs": [], - "source": [ - "pertim = 10957.5 # Simulation length ($d$)\n", - "ntransport_steps = 60 # Number of transport time steps\n", - "nlay = 6 # Number of layers\n", - "rainfall = 0.0025 # Rainfall ($m/d$)\n", - "evaporation = 0.0019 # Potential evaporation ($m/d$)\n", - "sfr_length_conversion = 1.0 # SFR package length unit conversion\n", - "sfr_time_conversion = 86400.0 # SFR package time conversion\n", - "sfr_width = 3.048 # Stream width ($m$)\n", - "sfr_bedthick = 0.3048 # Stream bed thickness ($m$)\n", - "sfr_mann = 0.030 # Stream Manning's roughness coefficient\n", - "lake_bedleak = 0.0013 # Lake bed leakance ($1/d$)\n", - "lak_length_conversion = 1.0 # LAK package length unit conversion\n", - "lak_time_conversion = 86400.0 # LAK package time conversion\n", - "drn_kv = 0.03048 # Drain vertical hydraulic conductivity ($m/d$)\n", - "drn_bed_thickness = 0.3048 # Drain bed thickness ($m$)\n", - "drn_depth = 0.3048 # Drain linear scaling depth ($m$)\n", - "alpha_l = 75.0 # Longitudinal dispersivity ($m$)\n", - "alpha_th = 7.5 # Transverse horizontal dispersivity ($m$)\n", - "porosity = 0.2 # Aquifer porosity (unitless)\n", - "confining_porosity = 0.4 # Confining unit porosity (unitless)" - ] - }, - { - "cell_type": "markdown", - "id": "79f09423", - "metadata": {}, - "source": [ - "build voronoi grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d85a386a", - "metadata": {}, - "outputs": [], - "source": [ - "maximum_area = 150.0 * 150.0\n", - "well_dv = 300.0\n", - "boundary_refinement = 100.0\n", - "river_refinement = 25.0\n", - "lake_refinement = 30.0\n", - "max_boundary_area = boundary_refinement * boundary_refinement\n", - "max_river_area = river_refinement * river_refinement\n", - "max_lake_area = lake_refinement * lake_refinement\n", - "\n", - "boundary_polygon = string2geom(geometries[\"sv_boundary\"], conversion=ft2m)\n", - "bp = np.array(boundary_polygon)\n", - "bp_densify = np.array(densify_geometry(bp, boundary_refinement))\n", - "\n", - "river_polyline = string2geom(geometries[\"sv_river\"], conversion=ft2m)\n", - "sg = np.array(river_polyline)\n", - "sg_densify = np.array(densify_geometry(sg, river_refinement))\n", - "\n", - "river_boundary = string2geom(geometries[\"sv_river_box\"], conversion=ft2m)\n", - "rb = np.array(river_boundary)\n", - "rb_densify = np.array(densify_geometry(rb, river_refinement))\n", - "\n", - "lake_polygon = string2geom(geometries[\"sv_lake\"], conversion=ft2m)\n", - "lake_plot = string2geom(geometries[\"sv_lake\"], conversion=ft2m)\n", - "lake_plot += [lake_plot[0]]\n", - "lake_plot = np.array(lake_plot)\n", - "lp = np.array(lake_polygon)\n", - "lp_densify = np.array(densify_geometry(lp, lake_refinement))\n", - "\n", - "well_points = string2geom(geometries[\"sv_wells\"], conversion=ft2m)\n", - "wp = np.array(well_points)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e39c699d", - "metadata": {}, - "outputs": [], - "source": [ - "# create the voronoi grid\n", - "temp_path = pl.Path(\"temp/triangle_data\")\n", - "temp_path.mkdir(parents=True, exist_ok=True)\n", - "tri = Triangle(\n", - " angle=30,\n", - " nodes=sg_densify,\n", - " model_ws=temp_path,\n", - ")\n", - "tri.add_polygon(bp_densify)\n", - "tri.add_polygon(rb_densify)\n", - "tri.add_polygon(lp_densify)\n", - "tri.add_region((10, 10), attribute=10, maximum_area=max_boundary_area)\n", - "tri.add_region(\n", - " (3050.0, 3050.0),\n", - " attribute=10,\n", - " maximum_area=max_boundary_area,\n", - ")\n", - "tri.add_region((900.0, 4600.0), attribute=11, maximum_area=max_lake_area)\n", - "tri.add_region((1200.0, 150.0), attribute=10, maximum_area=max_river_area)\n", - "for idx, w in enumerate(wp):\n", - " center = (w[0], w[1])\n", - " tri.add_polygon(circle_function(center=center, radius=100.0))\n", - " tri.add_region(center, attribute=idx, maximum_area=500.0)\n", - "tri.build(verbose=False)\n", - "vor = VoronoiGrid(tri)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7b72022e", - "metadata": {}, - "outputs": [], - "source": [ - "# create a vertex grid from the voronoi grid\n", - "gridprops = vor.get_gridprops_vertexgrid()\n", - "idomain_vor = np.ones((1, vor.ncpl), dtype=int)\n", - "voronoi_grid = VertexGrid(**gridprops, nlay=1, idomain=idomain_vor)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0ff9ee79", - "metadata": {}, - "outputs": [], - "source": [ - "# load raster data files\n", - "raster_path = pl.Path(config.data_ws) / example_name\n", - "kaq = flopy.utils.Raster.load(raster_path / \"k_aq_SI.tif\")\n", - "kclay = flopy.utils.Raster.load(raster_path / \"k_clay_SI.tif\")\n", - "top_base = flopy.utils.Raster.load(raster_path / \"top_SI.tif\")\n", - "bot = flopy.utils.Raster.load(raster_path / \"bottom_SI.tif\")\n", - "lake_location = flopy.utils.Raster.load(raster_path / \"lake_location_SI.tif\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "da9119c7", - "metadata": {}, - "outputs": [], - "source": [ - "# a few variables for plotting\n", - "xcv, ycv = voronoi_grid.xcellcenters, voronoi_grid.ycellcenters\n", - "x0 = x1 = sg[:, 0].min()\n", - "y0, y1 = sg[:, 1].max(), sg[:, 1].min()\n", - "top_range = (0, 20)\n", - "top_levels = np.arange(0, 25, 5)\n", - "head_range = (-1, 5)\n", - "head_levels = np.arange(1, head_range[1] + 1, 1)\n", - "\n", - "extent = voronoi_grid.extent" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "73782982", - "metadata": {}, - "outputs": [], - "source": [ - "# intersect the rasters with the vertex grid\n", - "top_vg = top_base.resample_to_grid(\n", - " voronoi_grid,\n", - " band=top_base.bands[0],\n", - " method=\"linear\",\n", - " extrapolate_edges=True,\n", - ")\n", - "bot_vg = bot.resample_to_grid(\n", - " voronoi_grid,\n", - " band=bot.bands[0],\n", - " method=\"linear\",\n", - " extrapolate_edges=True,\n", - ")\n", - "lake_cells_vg = lake_location.resample_to_grid(\n", - " voronoi_grid,\n", - " band=lake_location.bands[0],\n", - " method=\"nearest\",\n", - " extrapolate_edges=True,\n", - ")\n", - "kaq_vg = kaq.resample_to_grid(\n", - " voronoi_grid,\n", - " band=kaq.bands[0],\n", - " method=\"nearest\",\n", - " extrapolate_edges=True,\n", - ")\n", - "kclay_vg = kclay.resample_to_grid(\n", - " voronoi_grid,\n", - " band=kclay.bands[0],\n", - " method=\"nearest\",\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0f5c666d", - "metadata": {}, - "outputs": [], - "source": [ - "# create confining unit location map\n", - "kclay_loc_vg = np.zeros(kclay_vg.shape, dtype=int)\n", - "kclay_loc_vg[kclay_vg < 60.0] = 1\n", - "idomain_2 = np.ones(kclay_vg.shape, dtype=int)\n", - "idomain_2[kclay_loc_vg == 0] = -1\n", - "\n", - "# set the porosity based on the clay location\n", - "porosity_2 = np.full(kclay_vg.shape, porosity, dtype=float)\n", - "porosity_2[kclay_loc_vg == 1] = confining_porosity" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4ee608aa", - "metadata": {}, - "outputs": [], - "source": [ - "# set the bottom of each layer\n", - "bot_l2 = np.full(bot_vg.shape, -51.0 * ft2m, dtype=float)\n", - "bot_l3 = np.full(bot_vg.shape, -100.0 * ft2m, dtype=float)\n", - "bot_l4 = bot_vg + 0.5 * (bot_l3 - bot_vg)\n", - "# set the bottom of the 3rd layer in areas where the confining unit exists\n", - "bot_l2[idomain_2] = -50.0 * ft2m\n", - "# create a list with bottom data\n", - "botm = [-5.0 * ft2m, -50.0 * ft2m, bot_l2, -100.0 * ft2m, bot_l4, bot_vg]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c15b4a08", - "metadata": {}, - "outputs": [], - "source": [ - "# create a modelgrid for the lake\n", - "lake_grid_top = np.full((vor.ncpl), 50.0, dtype=float)\n", - "lake_vg_grid = flopy.discretization.VertexGrid(\n", - " **gridprops,\n", - " nlay=1,\n", - " idomain=idomain_vor,\n", - " top=lake_grid_top,\n", - " botm=top_vg.reshape(1, vor.ncpl),\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "da2bc071", - "metadata": {}, - "outputs": [], - "source": [ - "# intersect stream features with the grid\n", - "ixs = flopy.utils.GridIntersect(voronoi_grid, method=\"vertex\")\n", - "sg_result = ixs.intersect(LineString(sg_densify), sort_by_cellid=False)\n", - "\n", - "# build sfr package datasets\n", - "sfr_plt_array = np.zeros(voronoi_grid.ncpl, dtype=int)\n", - "sfr_nodes = np.arange(0, sg_result.shape[0])\n", - "gwf_nodes = sg_result[\"cellids\"][::-1]\n", - "sfr_lengths = sg_result[\"lengths\"][::-1]\n", - "total_cond = 1800000.0 * ft3tom3\n", - "sfr_hk = total_cond * sfr_bedthick / (sfr_width * sfr_lengths.sum())\n", - "b0, b1 = -0.3 * ft2m, -2.05 * ft2m\n", - "sfr_slope = -0.0002\n", - "cum_dist = np.zeros(sfr_nodes.shape, dtype=float)\n", - "cum_dist[0] = 0.5 * sfr_lengths[0]\n", - "for idx in range(1, sfr_nodes.shape[0]):\n", - " cum_dist[idx] = cum_dist[idx - 1] + 0.5 * (\n", - " sfr_lengths[idx - 1] + sfr_lengths[idx]\n", - " )\n", - "sfr_bot = b0 + sfr_slope * cum_dist\n", - "sfr_conn = []\n", - "for idx, node in enumerate(sfr_nodes):\n", - " iconn = [node]\n", - " if idx > 0:\n", - " iconn.append(sfr_nodes[idx - 1])\n", - " if idx < sfr_nodes.shape[0] - 1:\n", - " iconn.append(-sfr_nodes[idx + 1])\n", - " sfr_conn.append(iconn)\n", - "\n", - "# \n", - "sfrpak_data = []\n", - "for idx, (cellid, rlen, rtp) in enumerate(\n", - " zip(gwf_nodes, sfr_lengths, sfr_bot)\n", - "):\n", - " sfr_plt_array[cellid] = 1\n", - " sfrpak_data.append(\n", - " (\n", - " idx,\n", - " (\n", - " 0,\n", - " cellid,\n", - " ),\n", - " rlen,\n", - " sfr_width,\n", - " -sfr_slope,\n", - " rtp,\n", - " sfr_bedthick,\n", - " sfr_hk,\n", - " sfr_mann,\n", - " (len(sfr_conn[idx]) - 1),\n", - " 1.0,\n", - " 0,\n", - " )\n", - " )\n", - "sfr_spd = [(node, \"rainfall\", rainfall) for node in sfr_nodes] + [\n", - " (node, \"evaporation\", evaporation) for node in sfr_nodes\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1a7cbe26", - "metadata": {}, - "outputs": [], - "source": [ - "# build lake package datasets\n", - "lake_ic = 11.3 * ft2m\n", - "idx = np.where(lake_cells_vg == 1.0)\n", - "\n", - "lake_map = np.ones(voronoi_grid.ncpl, dtype=int) * -1\n", - "lake_map[idx] = 0\n", - "\n", - "(idomain, lakpak_dict, lak_connections) = flopy.mf6.utils.get_lak_connections(\n", - " voronoi_grid,\n", - " lake_map,\n", - " bedleak=lake_bedleak,\n", - ")\n", - "\n", - "# add concentration to lake data as aux\n", - "lakpak_data = [(0, lake_ic, lakpak_dict[0], 1.0)]\n", - "lake_spd = [\n", - " (0, \"rainfall\", rainfall),\n", - " (0, \"evaporation\", evaporation),\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c81c91d", - "metadata": {}, - "outputs": [], - "source": [ - "# build drain package datasets\n", - "areas = []\n", - "for idx in range(voronoi_grid.ncpl):\n", - " vertices = np.array(voronoi_grid.get_cell_vertices(idx))\n", - " area = Polygon(vertices).area\n", - " areas.append(area)\n", - "drn_spd = []\n", - "for idx, elev in enumerate(top_vg):\n", - " if lake_cells_vg[idx] > 0:\n", - " cond = drn_kv * areas[idx] / drn_bed_thickness\n", - " drn_spd.append([(0, idx), elev, cond, -drn_depth])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d0f0c59c", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "# build well package datasets\n", - "well_loc = []\n", - "for x, y in well_points:\n", - " well_loc.append(voronoi_grid.intersect(x, y))\n", - "\n", - "# first well is Virginia City well site 2\n", - "# second well is Reilly well\n", - "# third well is Virginia City well site 1\n", - "well_boundnames = [\"P3\", \"P1\", \"P2\"]\n", - "rates = [-1900.0, -7600.0, -7600.0]\n", - "welspd = [\n", - " [nlay - 1, cellid, rates[idx], well_boundnames[idx]]\n", - " for idx, cellid in enumerate(well_loc)\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "31a5bb17", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, run, and plot models\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model\n", - "recharge is the only variable\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2ab1a7c7", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwf(sim_folder):\n", - " print(f\"Building mf6gwf model...{sim_folder}\")\n", - " name = \"flow\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwf\")\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name,\n", - " sim_ws=sim_ws,\n", - " exe_name=\"mf6\",\n", - " continue_=True,\n", - " )\n", - " tdis = flopy.mf6.ModflowTdis(\n", - " sim, time_units=\"days\", perioddata=((pertim, 1, 1.0),)\n", - " )\n", - " ims = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"all\",\n", - " complexity=\"simple\",\n", - " linear_acceleration=\"bicgstab\",\n", - " )\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=name,\n", - " save_flows=True,\n", - " newtonoptions=\"NEWTON UNDER_RELAXATION\",\n", - " )\n", - " dis = flopy.mf6.ModflowGwfdisv(\n", - " gwf,\n", - " length_units=\"meters\",\n", - " nlay=nlay,\n", - " ncpl=vor.ncpl,\n", - " nvert=vor.nverts,\n", - " top=top_vg,\n", - " botm=botm,\n", - " vertices=vor.get_disv_gridprops()[\"vertices\"],\n", - " cell2d=vor.get_disv_gridprops()[\"cell2d\"],\n", - " idomain=[1, 1, idomain_2, 1, 1, 1],\n", - " )\n", - " ic = flopy.mf6.ModflowGwfic(gwf, strt=11.0)\n", - " npf = flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " xt3doptions=True,\n", - " save_specific_discharge=True,\n", - " save_saturation=True,\n", - " icelltype=[1, 0, 0, 0, 0, 0],\n", - " k=[kaq_vg, kaq_vg, kclay_vg, kaq_vg, kaq_vg, kaq_vg],\n", - " k33=[\n", - " 0.25 * kaq_vg,\n", - " 0.25 * kaq_vg,\n", - " kclay_vg,\n", - " 0.25 * kaq_vg,\n", - " 0.25 * kaq_vg,\n", - " 0.25 * kaq_vg,\n", - " ],\n", - " )\n", - " rch = flopy.mf6.ModflowGwfrcha(gwf, recharge=rainfall)\n", - " evt = flopy.mf6.ModflowGwfevta(\n", - " gwf, surface=top_vg, rate=evaporation, depth=1.0\n", - " )\n", - " wel = flopy.mf6.ModflowGwfwel(\n", - " gwf, stress_period_data=welspd, boundnames=True\n", - " )\n", - " drn = flopy.mf6.ModflowGwfdrn(\n", - " gwf,\n", - " auxiliary=[\"depth\"],\n", - " auxdepthname=\"depth\",\n", - " stress_period_data=drn_spd,\n", - " )\n", - " sfr = flopy.mf6.ModflowGwfsfr(\n", - " gwf,\n", - " print_stage=True,\n", - " print_flows=True,\n", - " length_conversion=sfr_length_conversion,\n", - " time_conversion=sfr_time_conversion,\n", - " stage_filerecord=f\"{name}.sfr.stage.bin\",\n", - " budget_filerecord=f\"{name}.sfr.cbc\",\n", - " nreaches=len(sfrpak_data),\n", - " packagedata=sfrpak_data,\n", - " connectiondata=sfr_conn,\n", - " perioddata=sfr_spd,\n", - " )\n", - " lak = flopy.mf6.ModflowGwflak(\n", - " gwf,\n", - " pname=\"LAK-1\",\n", - " time_conversion=lak_time_conversion,\n", - " length_conversion=lak_length_conversion,\n", - " auxiliary=[\"concentration\"],\n", - " print_stage=True,\n", - " print_flows=True,\n", - " stage_filerecord=f\"{name}.lak.stage.bin\",\n", - " budget_filerecord=f\"{name}.lak.cbc\",\n", - " nlakes=1,\n", - " packagedata=lakpak_data,\n", - " connectiondata=lak_connections,\n", - " perioddata=lake_spd,\n", - " )\n", - " oc = flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " head_filerecord=name + \".hds\",\n", - " budget_filerecord=name + \".cbc\",\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " printrecord=[(\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f3cb7d1b", - "metadata": {}, - "outputs": [], - "source": [ - "def build_mf6gwt(sim_folder):\n", - " print(f\"Building mf6gwt model...{sim_folder}\")\n", - " name = \"trans\"\n", - " sim_ws = os.path.join(ws, sim_folder, \"mf6gwt\")\n", - " sim = flopy.mf6.MFSimulation(\n", - " sim_name=name,\n", - " sim_ws=sim_ws,\n", - " exe_name=\"mf6\",\n", - " continue_=True,\n", - " )\n", - " tdis = flopy.mf6.ModflowTdis(\n", - " sim, time_units=\"days\", perioddata=((pertim, ntransport_steps, 1.0),)\n", - " )\n", - " ims = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"all\",\n", - " complexity=\"simple\",\n", - " linear_acceleration=\"bicgstab\",\n", - " )\n", - " gwt = flopy.mf6.ModflowGwt(\n", - " sim,\n", - " modelname=name,\n", - " )\n", - " dis = flopy.mf6.ModflowGwtdisv(\n", - " gwt,\n", - " length_units=\"meters\",\n", - " nlay=nlay,\n", - " ncpl=vor.ncpl,\n", - " nvert=vor.nverts,\n", - " top=top_vg,\n", - " botm=botm,\n", - " vertices=vor.get_disv_gridprops()[\"vertices\"],\n", - " cell2d=vor.get_disv_gridprops()[\"cell2d\"],\n", - " idomain=[1, 1, idomain_2, 1, 1, 1],\n", - " )\n", - " ic = flopy.mf6.ModflowGwtic(gwt, strt=0.0)\n", - " adv = flopy.mf6.ModflowGwtadv(\n", - " gwt,\n", - " scheme=\"tvd\",\n", - " )\n", - " dsp = flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " diffc=0.0e-12,\n", - " alh=alpha_l,\n", - " ath1=alpha_th,\n", - " )\n", - " mst = flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=[\n", - " porosity_2,\n", - " porosity,\n", - " porosity_2,\n", - " porosity,\n", - " porosity,\n", - " porosity,\n", - " ],\n", - " )\n", - " pd = [\n", - " (\"GWFHEAD\", f\"../mf6gwf/flow.hds\", None),\n", - " (\"GWFBUDGET\", f\"../mf6gwf/flow.cbc\", None),\n", - " ]\n", - " fmi = flopy.mf6.ModflowGwtfmi(gwt, packagedata=pd)\n", - " sourcerecarray = [\n", - " (\"LAK-1\", \"AUX\", \"CONCENTRATION\"),\n", - " ]\n", - " ssm = flopy.mf6.ModflowGwtssm(gwt, sources=sourcerecarray)\n", - "\n", - " oc = flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " concentration_filerecord=f\"{name}.ucn\",\n", - " saverecord=[\n", - " (\"CONCENTRATION\", \"LAST\"),\n", - " ],\n", - " printrecord=[(\"BUDGET\", \"ALL\")],\n", - " )\n", - " return sim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6f5296fa", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(sim_name):\n", - " sims = None\n", - " if config.buildModel:\n", - " sim_mf6gwf = build_mf6gwf(sim_name)\n", - " sim_mf6gwt = build_mf6gwt(sim_name)\n", - " sim_mf2005 = None # build_mf2005(sim_name)\n", - " sim_mt3dms = None # build_mt3dms(sim_name, sim_mf2005)\n", - " sims = (sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms)\n", - " return sims" - ] - }, - { - "cell_type": "markdown", - "id": "7f6c6a12", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e44bcf39", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(sims, silent=True):\n", - " if config.writeModel:\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " sim_mf6gwf.write_simulation(silent=silent)\n", - " sim_mf6gwt.write_simulation(silent=silent)\n", - " return" - ] - }, - { - "cell_type": "markdown", - "id": "f620cd56", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model\n", - "True is returned if the model runs successfully" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "268d71f1", - "metadata": {}, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(sims, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success = False\n", - " sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims\n", - " print(\"Running mf6gwf model...\")\n", - " success, buff = sim_mf6gwf.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " print(\"Running mf6gwt model...\")\n", - " success, buff = sim_mf6gwt.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5e7aa392", - "metadata": {}, - "outputs": [], - "source": [ - "# Functions to plot the model results\n", - "def plot_wells(ax=None, ms=None):\n", - " if ax is None:\n", - " ax = plt.gca()\n", - " ax.plot(wp[:, 0], wp[:, 1], \"ro\", ms=ms)\n", - " return ax" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "48348608", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_river(ax=None):\n", - " if ax is None:\n", - " ax = plt.gca()\n", - " ax.plot(sg_densify[:, 0], sg_densify[:, 1], **river_dict)\n", - " return ax" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4aef6aac", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_lake(ax=None, lw=0.5, color=\"cyan\", marker=None, densify=False):\n", - " if ax is None:\n", - " ax = plt.gca()\n", - " if densify:\n", - " arr = lp_densify\n", - " else:\n", - " arr = lake_plot\n", - " ax.plot(arr[:, 0], arr[:, 1], ls=\"-\", color=color, lw=lw, marker=marker)\n", - " return ax" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7bafa51c", - "metadata": {}, - "outputs": [], - "source": [ - "def set_ticklabels(\n", - " ax,\n", - " fmt=\"{:.1f}\",\n", - " skip_xticklabels=False,\n", - " skip_yticklabels=False,\n", - " skip_xlabel=False,\n", - " skip_ylabel=False,\n", - " xticks=None,\n", - " yticks=None,\n", - "):\n", - " if xticks is None:\n", - " labels = [ax.get_xticks().tolist()]\n", - " else:\n", - " ax.set_xticks(xticks, labels=[str(value) for value in xticks])\n", - " labels = [xticks]\n", - "\n", - " if yticks is None:\n", - " labels += [ax.get_yticks().tolist()]\n", - " else:\n", - " ax.set_yticks(yticks, labels=[str(value) for value in yticks])\n", - " labels += [yticks]\n", - "\n", - " for idx, label in enumerate(labels):\n", - " for jdx, value in enumerate(label):\n", - " labels[idx][jdx] = fmt.format(float(value) / 1000.0)\n", - "\n", - " if skip_xticklabels:\n", - " ax.set_xticklabels([])\n", - " else:\n", - " ax.xaxis.set_major_locator(mticker.FixedLocator(ax.get_xticks()))\n", - " ax.set_xticklabels(labels[0])\n", - "\n", - " if skip_yticklabels:\n", - " ax.set_yticklabels([])\n", - " else:\n", - " ax.yaxis.set_major_locator(mticker.FixedLocator(ax.get_yticks()))\n", - " ax.set_yticklabels(labels[1])\n", - "\n", - " if not skip_xlabel:\n", - " ax.set_xlabel(\"x position (km)\")\n", - " if not skip_ylabel:\n", - " ax.set_ylabel(\"y position (km)\")\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "515f96be", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_well_labels(ax):\n", - " for xy, name in zip(well_points, well_boundnames):\n", - " styles.add_annotation(\n", - " ax=ax,\n", - " text=name,\n", - " xy=xy,\n", - " xytext=(-15, 10),\n", - " bold=False,\n", - " textcoords=\"offset points\",\n", - " arrowprops=arrowprops,\n", - " )\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dfb51b49", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_feature_labels(ax):\n", - " styles.add_text(\n", - " ax=ax,\n", - " text=\"Blue\\nLake\",\n", - " x=610,\n", - " y=5000.0,\n", - " transform=False,\n", - " bold=False,\n", - " ha=\"center\",\n", - " va=\"center\",\n", - " )\n", - " styles.add_text(\n", - " ax=ax,\n", - " text=\"Straight River\",\n", - " x=1425,\n", - " y=1500.0,\n", - " transform=False,\n", - " bold=False,\n", - " va=\"center\",\n", - " ha=\"center\",\n", - " rotation=90,\n", - " )\n", - " plot_well_labels(ax)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "de83fc64", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_results(sims, idx):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " plot_river_mapping(sims, idx)\n", - " plot_head_results(sims, idx)\n", - " plot_conc_results(sims, idx)\n", - " return" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "457805dc", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_river_mapping(sims, idx):\n", - " print(\"Plotting river mapping...\")\n", - " sim_mf6gwf, _, _, _ = sims\n", - " sim_ws = sim_mf6gwf.simulation_data.mfpath.get_sim_path()\n", - " dv = 100.0 # m\n", - "\n", - " with styles.USGSMap():\n", - " fig = plt.figure(figsize=one_panel_figsize, constrained_layout=False)\n", - " gs = gridspec.GridSpec(ncols=1, nrows=24, figure=fig)\n", - " ax0 = fig.add_subplot(gs[:18])\n", - " ax_leg = fig.add_subplot(gs[18:])\n", - "\n", - " ax = ax0\n", - " ax.set_aspect(\"equal\", \"box\")\n", - " mm = flopy.plot.PlotMapView(modelgrid=voronoi_grid, ax=ax)\n", - " mm.plot_array(\n", - " kclay_loc_vg,\n", - " masked_values=[\n", - " 0,\n", - " ],\n", - " cmap=clay_cmap,\n", - " alpha=0.5,\n", - " )\n", - " mm.plot_array(\n", - " lake_cells_vg,\n", - " masked_values=[\n", - " 0,\n", - " ],\n", - " cmap=lake_cmap,\n", - " alpha=0.5,\n", - " )\n", - " mm.plot_grid(**grid_dict)\n", - " plot_river(ax)\n", - " plot_wells(ax, ms=3)\n", - " plot_feature_labels(ax)\n", - "\n", - " xticks = np.arange(mm.extent[0], mm.extent[1], 1000.0).tolist()\n", - " yticks = np.arange(mm.extent[2], mm.extent[3], 1000.0).tolist()\n", - " set_ticklabels(ax, fmt=\"{:.0f}\", xticks=xticks, yticks=yticks)\n", - "\n", - " # legend\n", - " ax = ax_leg\n", - " xy0 = (-100, -100)\n", - " ax.set_ylim(0, 1)\n", - " ax.set_axis_off()\n", - "\n", - " # fake data to set up legend\n", - " ax.plot(\n", - " xy0,\n", - " xy0,\n", - " lw=0.0,\n", - " marker=\".\",\n", - " ms=5,\n", - " mfc=\"red\",\n", - " mec=\"none\",\n", - " mew=0.0,\n", - " label=\"Well\",\n", - " )\n", - " ax.plot(\n", - " xy0,\n", - " xy0,\n", - " lw=0.0,\n", - " marker=\"s\",\n", - " mfc=\"cyan\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " alpha=0.5,\n", - " label=\"Lake\",\n", - " )\n", - " ax.plot(\n", - " xy0,\n", - " xy0,\n", - " lw=0.0,\n", - " marker=\"s\",\n", - " mfc=\"brown\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " alpha=0.5,\n", - " label=\"Confining unit\",\n", - " )\n", - " ax.axhline(xy0[0], **river_dict, label=\"River\")\n", - " styles.graph_legend(\n", - " ax,\n", - " ncol=2,\n", - " loc=\"lower center\",\n", - " labelspacing=0.1,\n", - " columnspacing=0.6,\n", - " handletextpad=0.3,\n", - " )\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.basename(os.path.split(sim_ws)[0])\n", - " fname = f\"{sim_folder}-river-discretization{config.figure_ext}\"\n", - " fig.savefig(os.path.join(ws, \"..\", \"figures\", fname))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b3b7023b", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_head_results(sims, idx):\n", - " print(\"Plotting gwf model results...\")\n", - " sim_mf6gwf, _, _, _ = sims\n", - " sim_ws = sim_mf6gwf.simulation_data.mfpath.get_sim_path()\n", - " gwf = sim_mf6gwf.flow\n", - "\n", - " xlims = (extent[0], extent[1])\n", - " ylims = (extent[2], extent[3])\n", - "\n", - " p2_loc = tuple(welspd[-1][0:2])\n", - " p2_z = gwf.modelgrid.zcellcenters[p2_loc]\n", - "\n", - " head = gwf.output.head().get_data().squeeze()\n", - " cbc = gwf.output.budget()\n", - " spdis = cbc.get_data(text=\"DATA-SPDIS\")[0]\n", - " qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(\n", - " spdis, gwf, head=head\n", - " )\n", - " lake_q = cbc.get_data(text=\"LAK\", full3D=True)[0]\n", - " lake_q_dir = np.zeros(lake_q.shape, dtype=int)\n", - " lake_q_dir[lake_q < 0.0] = -1\n", - " lake_q_dir[lake_q > 0.0] = 1\n", - "\n", - " lake_stage = float(gwf.lak.output.stage().get_data().squeeze())\n", - " lake_stage_vg = np.full(vor.ncpl, 1e30, dtype=float)\n", - " idx = (lake_stage > top_vg) & (lake_cells_vg > 0)\n", - " lake_stage_vg[idx] = lake_stage\n", - "\n", - " with styles.USGSMap():\n", - " fig = plt.figure(figsize=two_panel_figsize, constrained_layout=True)\n", - " gs = gridspec.GridSpec(ncols=2, nrows=24, figure=fig)\n", - " ax0 = fig.add_subplot(gs[:22, 0])\n", - " ax1 = fig.add_subplot(gs[:22, 1])\n", - " ax2 = fig.add_subplot(gs[22:, :])\n", - "\n", - " xticks = np.arange(extent[0], extent[1], 1000.0).tolist()\n", - " yticks = np.arange(extent[2], extent[3], 1000.0).tolist()\n", - "\n", - " for ax in (ax0, ax1):\n", - " ax.set_xlim(xlims)\n", - " ax.set_xticks(xticks)\n", - " ax.set_ylim(ylims)\n", - " ax.set_yticks(yticks)\n", - " ax.set_aspect(\"equal\", \"box\")\n", - "\n", - " # topography\n", - " ax = ax0\n", - " styles.heading(ax=ax, idx=0)\n", - " mm = flopy.plot.PlotMapView(\n", - " model=gwf,\n", - " ax=ax,\n", - " extent=voronoi_grid.extent,\n", - " )\n", - " cb = mm.plot_array(top_vg, vmin=top_range[0], vmax=top_range[1])\n", - " mm.plot_grid(**grid_dict)\n", - " plot_wells(ax=ax, ms=3)\n", - " plot_river(ax=ax)\n", - " plot_lake(ax=ax)\n", - " cs = mm.contour_array(\n", - " top_vg,\n", - " **sv_contour_dict,\n", - " levels=top_levels,\n", - " )\n", - " ax.clabel(\n", - " cs,\n", - " **clabel_dict,\n", - " )\n", - " set_ticklabels(ax, fmt=\"{:.0f}\")\n", - "\n", - " # topography colorbar\n", - " cbar = plt.colorbar(cb, ax=ax, orientation=\"horizontal\", shrink=0.65)\n", - " cbar.ax.tick_params(\n", - " labelsize=5,\n", - " labelcolor=\"black\",\n", - " color=\"black\",\n", - " length=6,\n", - " pad=2,\n", - " )\n", - " cbar.ax.set_title(\n", - " \"Elevation (m)\",\n", - " pad=2.5,\n", - " loc=\"left\",\n", - " fontdict=font_dict,\n", - " )\n", - "\n", - " # head\n", - " ax = ax1\n", - " styles.heading(ax=ax, idx=1)\n", - " mm = flopy.plot.PlotMapView(\n", - " model=gwf,\n", - " ax=ax,\n", - " extent=voronoi_grid.extent,\n", - " )\n", - " cb = mm.plot_array(head, vmin=head_range[0], vmax=head_range[1])\n", - "\n", - " mm.plot_grid(**grid_dict)\n", - " q = mm.plot_vector(qx, qy, normalize=False)\n", - " qk = plt.quiverkey(\n", - " q,\n", - " -0.35,\n", - " -0.31,\n", - " 1.0,\n", - " label=\"Specific discharge vector\",\n", - " labelsep=0.05,\n", - " labelpos=\"E\",\n", - " labelcolor=\"black\",\n", - " fontproperties={\"size\": 9, \"weight\": \"bold\"},\n", - " )\n", - "\n", - " plot_wells(ax=ax, ms=3)\n", - " plot_river(ax=ax)\n", - " plot_lake(ax=ax)\n", - " cs = mm.contour_array(\n", - " head,\n", - " **sv_contour_dict,\n", - " levels=head_levels,\n", - " )\n", - " ax.clabel(\n", - " cs,\n", - " **clabel_dict,\n", - " )\n", - " set_ticklabels(ax, fmt=\"{:.0f}\", xticks=xticks, yticks=yticks)\n", - "\n", - " # head colorbar\n", - " cbar = plt.colorbar(cb, ax=ax, orientation=\"horizontal\", shrink=0.65)\n", - " cbar.ax.tick_params(\n", - " labelsize=5,\n", - " labelcolor=\"black\",\n", - " color=\"black\",\n", - " length=6,\n", - " pad=2,\n", - " )\n", - " cbar.ax.set_title(\n", - " \"Head (m)\",\n", - " pad=2.5,\n", - " loc=\"left\",\n", - " fontdict=font_dict,\n", - " )\n", - "\n", - " # legend\n", - " ax = ax2\n", - " xy0 = (-100, -100)\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - " ax.set_axis_off()\n", - "\n", - " # fake data to set up legend\n", - " well_patch = ax.plot(\n", - " xy0,\n", - " xy0,\n", - " lw=0.0,\n", - " marker=\".\",\n", - " ms=5,\n", - " mfc=\"red\",\n", - " mec=\"none\",\n", - " mew=0.0,\n", - " label=\"Well\",\n", - " )\n", - " lake_patch = ax.axhline(xy0[0], color=\"cyan\", lw=0.5, label=\"Lake\")\n", - " river_patch = ax.axhline(xy0[0], **river_dict, label=\"River\")\n", - " contour_patch = ax.axhline(\n", - " xy0[0], **contour_label_dict, label=\"Contour line (m)\"\n", - " )\n", - " styles.graph_legend(\n", - " ax,\n", - " ncol=3,\n", - " loc=\"lower center\",\n", - " labelspacing=0.1,\n", - " columnspacing=0.6,\n", - " handletextpad=0.3,\n", - " )\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.basename(os.path.split(sim_ws)[0])\n", - " fname = f\"{sim_folder}-head{config.figure_ext}\"\n", - " fig.savefig(os.path.join(ws, \"..\", \"figures\", fname))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "51ae77ea", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_conc_results(sims, idx):\n", - " print(\"Plotting gwt model results...\")\n", - " _, sim_mf6gwt, _, _ = sims\n", - " sim_ws = sim_mf6gwt.simulation_data.mfpath.get_sim_path()\n", - " gwt = sim_mf6gwt.trans\n", - " with styles.USGSMap():\n", - " fig = plt.figure(figsize=six_panel_figsize, constrained_layout=True)\n", - " gs = gridspec.GridSpec(ncols=3, nrows=24, figure=fig)\n", - " ax0 = fig.add_subplot(gs[:11, 0])\n", - " ax1 = fig.add_subplot(gs[:11, 1])\n", - " ax2 = fig.add_subplot(gs[:11, 2])\n", - " ax3 = fig.add_subplot(gs[11:22, 0])\n", - " ax4 = fig.add_subplot(gs[11:22, 1])\n", - " ax5 = fig.add_subplot(gs[11:22, 2])\n", - " ax6 = fig.add_subplot(gs[22:, :])\n", - "\n", - " axs = [ax0, ax1, ax2, ax3, ax4, ax5]\n", - "\n", - " times = gwt.output.concentration().get_times()\n", - " conc = gwt.output.concentration().get_data(totim=times[-1])\n", - "\n", - " for k in range(6):\n", - " ax = axs[k]\n", - " ax.set_title(f\"Layer {k + 1}\")\n", - " mm = flopy.plot.PlotMapView(\n", - " model=gwt,\n", - " ax=ax,\n", - " extent=gwt.modelgrid.extent,\n", - " layer=k,\n", - " )\n", - "\n", - " xticks = np.arange(extent[0], extent[1], 1000.0).tolist()\n", - " yticks = np.arange(extent[2], extent[3], 1000.0).tolist()\n", - "\n", - " mm.plot_grid(**grid_dict)\n", - "\n", - " # plot confining unit\n", - " if k == 2:\n", - " mm.plot_array(\n", - " kclay_loc_vg,\n", - " masked_values=[\n", - " 0,\n", - " ],\n", - " cmap=clay_cmap,\n", - " alpha=0.5,\n", - " )\n", - " plot_river(ax=ax)\n", - " plot_lake(ax=ax)\n", - " if k == nlay - 1:\n", - " plot_wells(ax=ax, ms=3)\n", - " plot_well_labels(ax)\n", - " cs = mm.contour_array(\n", - " conc,\n", - " masked_values=[0],\n", - " levels=[0.001, 0.01, 0.1, 1],\n", - " **sv_gwt_contour_dict,\n", - " )\n", - "\n", - " ax.clabel(\n", - " cs,\n", - " inline=True,\n", - " fmt=\"%1.3g\",\n", - " fontsize=6,\n", - " inline_spacing=0.5,\n", - " )\n", - "\n", - " set_ticklabels(ax, fmt=\"{:.0f}\", xticks=xticks, yticks=yticks)\n", - "\n", - " styles.heading(ax, idx=k)\n", - "\n", - " # legend\n", - " ax = ax6\n", - " xy0 = (-100, -100)\n", - " ax.set_xlim(0, 1)\n", - " ax.set_ylim(0, 1)\n", - " ax.set_axis_off()\n", - "\n", - " # fake data to set up legend\n", - " ax.plot(\n", - " xy0,\n", - " xy0,\n", - " lw=0.0,\n", - " marker=\".\",\n", - " ms=5,\n", - " mfc=\"red\",\n", - " mec=\"none\",\n", - " mew=0.0,\n", - " label=\"Well\",\n", - " )\n", - " ax.axhline(xy0[0], color=\"cyan\", lw=0.5, label=\"Lake\")\n", - " ax.axhline(xy0[0], **river_dict, label=\"River\")\n", - " ax.axhline(\n", - " xy0[0], **contour_gwt_label_dict, label=\"Concentration (mg/L)\"\n", - " )\n", - " ax.plot(\n", - " xy0,\n", - " xy0,\n", - " lw=0.0,\n", - " marker=\"s\",\n", - " mfc=\"brown\",\n", - " mec=\"black\",\n", - " mew=0.5,\n", - " alpha=0.5,\n", - " label=\"Confining unit\",\n", - " )\n", - " styles.graph_legend(\n", - " ax,\n", - " ncol=5,\n", - " loc=\"lower center\",\n", - " labelspacing=0.1,\n", - " columnspacing=0.6,\n", - " handletextpad=0.3,\n", - " frameon=False,\n", - " )\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " sim_folder = os.path.split(sim_ws)[0]\n", - " sim_folder = os.path.basename(sim_folder)\n", - " fname = f\"{sim_folder}-conc{config.figure_ext}\"\n", - " fig.savefig(os.path.join(ws, \"..\", \"figures\", fname))" - ] - }, - { - "cell_type": "markdown", - "id": "0ce8dd20", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function that wraps all of the steps for each scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "769f4ade", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " sim = build_model(example_name)\n", - " write_model(sim, silent=silent)\n", - " success = run_model(sim, silent=silent)\n", - " if success:\n", - " plot_results(sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4990100b", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=False)" - ] - }, - { - "cell_type": "markdown", - "id": "67ef157a", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "faea71df", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Simulate Synthetic Valley Problem (Hughes and others 2023)\n", - "\n", - " # Plot showing MODFLOW 6 results\n", - "\n", - " scenario(0)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/ex-gwt-uzt-2d.ipynb b/notebooks/ex-gwt-uzt-2d.ipynb deleted file mode 100644 index e3925195..00000000 --- a/notebooks/ex-gwt-uzt-2d.ipynb +++ /dev/null @@ -1,1304 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "54824a9b", - "metadata": {}, - "source": [ - "## Two-Dimensional Transport with the UZF and UZT packages active.\n", - "\n", - "The purpose of this script is to test transport in the unsaturated zone\n", - "package. This test originally appeared in Morway et al. (2013)." - ] - }, - { - "cell_type": "markdown", - "id": "bbbe4aed", - "metadata": {}, - "source": [ - "### MODFLOW 6 2D UZT/GWT Problem Setup" - ] - }, - { - "cell_type": "markdown", - "id": "14b7b0d6", - "metadata": {}, - "source": [ - "Append to system path to include the common subdirectory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "721b855f", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "003250c1", - "metadata": {}, - "outputs": [], - "source": [ - "sys.path.append(os.path.join(\"..\", \"common\"))" - ] - }, - { - "cell_type": "markdown", - "id": "db77311f", - "metadata": {}, - "source": [ - "Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c63307d", - "metadata": {}, - "outputs": [], - "source": [ - "import config\n", - "import flopy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from figspecs import USGSFigure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2241df4e", - "metadata": {}, - "outputs": [], - "source": [ - "mf6exe = \"mf6\"\n", - "exe_name_mf = \"mfnwt\"\n", - "exe_name_mt = \"mt3dusgs\"" - ] - }, - { - "cell_type": "markdown", - "id": "d4aeebf9", - "metadata": {}, - "source": [ - "Set figure properties specific to this problem" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "52c8d4ca", - "metadata": {}, - "outputs": [], - "source": [ - "figure_size = (6, 4)" - ] - }, - { - "cell_type": "markdown", - "id": "24f73ecf", - "metadata": {}, - "source": [ - "Base simulation and model name and workspace" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c39c914d", - "metadata": {}, - "outputs": [], - "source": [ - "ws = config.base_ws" - ] - }, - { - "cell_type": "markdown", - "id": "d49a33df", - "metadata": {}, - "source": [ - "Set scenario parameters (make sure there is at least one blank line before next item)\n", - "This entire dictionary is passed to _build_model()_ using the kwargs argument" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "97d2bf2b", - "metadata": {}, - "outputs": [], - "source": [ - "parameters = {\n", - " \"ex-gwt-uzt-2d-a\": {\n", - " \"longitudinal_dispersivity\": [0.5],\n", - " \"ratio_horizontal_to_longitudinal_dispersivity\": [0.4],\n", - " \"ratio_vertical_to_longitudinal_dispersivity\": [0.4],\n", - " },\n", - " \"ex-gwt-uzt-2d-b\": {\n", - " \"longitudinal_dispersivity\": [\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.5,\n", - " 0.5,\n", - " 0.5,\n", - " 0.5,\n", - " 0.5,\n", - " 0.5,\n", - " 0.5,\n", - " 0.5,\n", - " ],\n", - " \"ratio_horizontal_to_longitudinal_dispersivity\": [\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " ],\n", - " \"ratio_vertical_to_longitudinal_dispersivity\": [\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.0,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " 0.4,\n", - " ],\n", - " },\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "7222eaed", - "metadata": {}, - "source": [ - "Scenario parameter units\n", - "\n", - "add parameter_units to add units to the scenario parameter table that is automatically\n", - "built and used by the .tex input" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "04ab87c8", - "metadata": {}, - "outputs": [], - "source": [ - "parameter_units = {\n", - " \"longitudinal_dispersivity\": \"$m$\",\n", - " \"ratio_horizontal_to_longitudinal_dispersivity\": \"unitless\",\n", - " \"ratio_horizontal_to_longitudinal_dispersivity\": \"unitless\",\n", - "}" - ] - }, - { - "cell_type": "markdown", - "id": "f8b90fd7", - "metadata": {}, - "source": [ - "Model units" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "88ffdcce", - "metadata": {}, - "outputs": [], - "source": [ - "length_units = \"meter\"\n", - "time_units = \"days\"" - ] - }, - { - "cell_type": "markdown", - "id": "7e59ef1c", - "metadata": {}, - "source": [ - "Table MODFLOW 6 GWT MT3DMS Example 8" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "404416c2", - "metadata": {}, - "outputs": [], - "source": [ - "nlay = 20 # Number of layers\n", - "nrow = 1 # Number of rows\n", - "ncol = 40 # Number of columns\n", - "delr = 0.25 # Column width ($m$)\n", - "delc = 0.25 # Row width ($m$)\n", - "delz = 0.25 # Layer thickness ($m$)\n", - "top = 5.0 # Top of the model ($m$)\n", - "k1 = 2.5 # Horizontal hydraulic conductivity ($m/day$)\n", - "vk = 0.5 # Vertical hydraulic conductivity ($m/day$)\n", - "Ss = 1e-5 # Aquifer storativity\n", - "sy = 0.35 # Specific yield\n", - "thtr = 0.1 # Residual water content\n", - "thts = 0.45 # Saturated water content\n", - "thti = 0.105 # Initial water content\n", - "eps = 4.0 # Brooks-Corey Epsilon\n", - "finf = 0.1 # Infiltration rate ($m/d$)\n", - "cfinf = 1.0 # Concentration of recharge in select cells($ppm$)\n", - "prsity = 0.45 # Porosity\n", - "al = 0.5 # Longitudinal dispersivity ($ft$)\n", - "trpt = 0.4 # Ratio of horizontal transverse dispersivity to longitudinal dispersivity\n", - "trpv = 0.4 # Ratio of vertical transverse dispersivity to longitudinal dispersivity\n", - "perlen = 60.0 # Simulation time ($days$)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "85abcd70", - "metadata": {}, - "outputs": [], - "source": [ - "# Additional model input\n", - "botm = [top - delz * k for k in range(1, nlay + 1)]\n", - "perlen = [perlen]\n", - "nper = len(perlen)\n", - "nstp = [120]\n", - "tsmult = [1.0]\n", - "laytyp = icelltype = 1\n", - "iconvert = 1\n", - "# Hydraulic Conductivity\n", - "hk = k1 * np.ones((nlay, nrow, ncol), dtype=float)\n", - "hk33 = vk * np.ones((nlay, nrow, ncol), dtype=float)\n", - "# Starting Heads:\n", - "s0 = np.empty((nrow * ncol), dtype=float)\n", - "strt = np.zeros((nlay, nrow, ncol), dtype=float)\n", - "for k in range(nlay):\n", - " strt[k] = s0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e077f367", - "metadata": {}, - "outputs": [], - "source": [ - "# Active model domain\n", - "ibound = np.ones((nlay, nrow, ncol), dtype=int)\n", - "ibound_mf2k5 = ibound.copy()\n", - "ibound_mf2k5[0:15, 0, 0] = 0\n", - "ibound_mf2k5[0:15, 0, -1] = 0\n", - "ibound_mf2k5[0:11, 0, :] = 0 # upper lays w/ UZF don't need to be active\n", - "# ibound_mf2k5[ 0:11, 0, 0:3] = ibound_mf2k5[ 0:11, 0, 37:40] = 0\n", - "ibound_mf2k5[13:20, 0, 0] = -1\n", - "ibound_mf2k5[13:20, 0, -1] = -1\n", - "idomain = np.ones_like(ibound)\n", - "idomain[0:13, 0, 0] = idomain[0:13, 0, -1] = 0\n", - "strt = np.ones((nlay, nrow, ncol), dtype=float) * 1.625\n", - "sconc = 0.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dca023ed", - "metadata": {}, - "outputs": [], - "source": [ - "# UZF related boundary conditions\n", - "nuztop = 3\n", - "iuzfopt = 2\n", - "irunflg = 0\n", - "ietflg = 0\n", - "iuzfcb1 = 0\n", - "iuzfcb2 = 0\n", - "ntrail2 = 25\n", - "nsets2 = 80\n", - "iuzfbnd = np.ones((nrow, ncol), dtype=int)\n", - "iuzfbnd[0, 0] = iuzfbnd[0, ncol - 1] = 0\n", - "# Fixed properties\n", - "surfdep = 0.00001\n", - "vks = k1\n", - "thtr = 0.1\n", - "thts = 0.45\n", - "thti = 0.105\n", - "eps = 4.0\n", - "# UZF boundary stresses\n", - "finf_mfnwt = np.ones((nrow, ncol), dtype=float) * finf\n", - "finf_mfnwt[0, 0] = finf_mfnwt[0, ncol - 1] = 0 # Shut off the outer cells\n", - "pet = 0.0\n", - "extdp = 0.0\n", - "extwc = 0.0\n", - "ha = 0.0\n", - "hroot = 0.0\n", - "rootact = 0.0\n", - "packagedata = []\n", - "uztpackagedata = []\n", - "pd0 = []\n", - "for k in range(nlay):\n", - " for j in range(1, ncol - 1): # outside columns are not UZF cells\n", - " iuzno = k * (ncol - 2) + (j - 1) # in flopy, iuzno is 0-based\n", - " if k == 0:\n", - " lflag = 1\n", - " surfdep = 0.1\n", - " else:\n", - " lflag = 0\n", - " surfdep = 0.001\n", - " ivertcon = iuzno + len(range(1, ncol - 1))\n", - " # adjust if on bottom layer (no underlying conn.)\n", - " # remember, setting ivertcon=0, which means there is no vertical\n", - " # connection results in vertical connection being equal to 1 in the\n", - " # model input...SET equal to -1 to compensate\n", - " if k == nlay - 1:\n", - " ivertcon = -1\n", - " # []\n", - " uz = [\n", - " iuzno,\n", - " (k, 0, j),\n", - " lflag,\n", - " ivertcon,\n", - " surfdep,\n", - " vk,\n", - " thtr,\n", - " thts,\n", - " thti,\n", - " eps,\n", - " ]\n", - " packagedata.append(uz)\n", - "\n", - " # now some transport book keeping\n", - " transp = (iuzno, 0.0) # sets the starting concentration\n", - " uztpackagedata.append(transp)\n", - "\n", - " # Enter boundary conditions only for land surface cells\n", - " if lflag:\n", - " pd0.append((iuzno, finf, pet, extdp, extwc, ha, hroot, rootact))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4fd316bc", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "nuzfcells = len(packagedata)\n", - "uzf_perioddata = {0: pd0}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4be500f9", - "metadata": {}, - "outputs": [], - "source": [ - "# Transport related\n", - "mixelm = -1 # -1: TVD; 0: FD\n", - "dmcoef = 0.0 # ft^2/day" - ] - }, - { - "cell_type": "markdown", - "id": "b8b8cbdf", - "metadata": {}, - "source": [ - "Solver settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fde68829", - "metadata": {}, - "outputs": [], - "source": [ - "nouter, ninner = 100, 300\n", - "hclose, rclose, relax = 1e-6, 1e-6, 1.0\n", - "percel = 1.0\n", - "itrack = 3\n", - "wd = 0.5\n", - "dceps = 1.0e-5\n", - "nplane = 0\n", - "npl = 0\n", - "nph = 10\n", - "npmin = 2\n", - "npmax = 20\n", - "dchmoc = 1.0e-3\n", - "nlsink = nplane\n", - "npsink = nph" - ] - }, - { - "cell_type": "markdown", - "id": "cbbb8a28", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Functions to build, write, and run models and plot MT3DMS Example 9\n", - "\n", - "MODFLOW 6 flopy simulation object (sim) is returned if building the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "02d8fbc7", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def build_model(\n", - " sim_name,\n", - " mixelm=0,\n", - " longitudinal_dispersivity=[0.5],\n", - " ratio_horizontal_to_longitudinal_dispersivity=[0.4],\n", - " ratio_vertical_to_longitudinal_dispersivity=[0.4],\n", - " silent=False,\n", - "):\n", - " if config.buildModel:\n", - " print(f\"Building mf-nwt model...{sim_name}\")\n", - " model_ws = os.path.join(ws, sim_name, \"mt3d\")\n", - " modelname_mf = \"uzt-2d-mf\"\n", - "\n", - " # Instantiate the MODFLOW model\n", - " mf = flopy.modflow.Modflow(\n", - " modelname=modelname_mf,\n", - " model_ws=model_ws,\n", - " exe_name=exe_name_mf,\n", - " version=\"mfnwt\",\n", - " )\n", - "\n", - " # Instantiate discretization package\n", - " # units: itmuni=4 (days), lenuni=2 (m)\n", - " flopy.modflow.ModflowDis(\n", - " mf,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " nper=nper,\n", - " botm=botm,\n", - " perlen=perlen,\n", - " nstp=nstp,\n", - " steady=[False],\n", - " itmuni=4,\n", - " lenuni=2,\n", - " )\n", - "\n", - " # Instantiate basic package\n", - " flopy.modflow.ModflowBas(mf, ibound=ibound_mf2k5, strt=strt)\n", - "\n", - " # Instantiate layer property flow package\n", - " flopy.modflow.ModflowUpw(mf, hk=k1, vka=vk, sy=sy, ss=Ss, laytyp=laytyp)\n", - "\n", - " # Instantiate unsaturated-zone flow package\n", - " flopy.modflow.ModflowUzf1(\n", - " mf,\n", - " nuztop=nuztop,\n", - " iuzfopt=iuzfopt,\n", - " irunflg=irunflg,\n", - " ietflg=ietflg,\n", - " ipakcb=iuzfcb1,\n", - " iuzfcb2=iuzfcb2,\n", - " ntrail2=ntrail2,\n", - " nsets=nsets2,\n", - " surfdep=0.1,\n", - " iuzfbnd=iuzfbnd,\n", - " eps=eps,\n", - " thts=thts,\n", - " thti=thti,\n", - " thtr=thtr,\n", - " finf=finf_mfnwt,\n", - " specifythti=True,\n", - " specifythtr=True,\n", - " )\n", - "\n", - " # Instantiate output control (OC) package\n", - " flopy.modflow.ModflowOc(\n", - " mf,\n", - " # stress_period_data={(0, nstp[0] - 1): [\"save head\", \"save budget\"]}\n", - " stress_period_data={(0, nstp[0] - 1): [\"save head\", \"save budget\"]},\n", - " )\n", - "\n", - " # Instantiate solver package\n", - " flopy.modflow.ModflowNwt(mf)\n", - "\n", - " # Instantiate link mass transport package (for writing linker file)\n", - " flopy.modflow.ModflowLmt(mf, package_flows=[\"UZF\"])\n", - "\n", - " # Transport\n", - " print(f\"Building mt3d-usgs model...{sim_name}\")\n", - "\n", - " modelname_mt = \"uzt-2d-mt\"\n", - " mt = flopy.mt3d.Mt3dms(\n", - " modelname=modelname_mt,\n", - " model_ws=model_ws,\n", - " exe_name=exe_name_mt,\n", - " modflowmodel=mf,\n", - " version=\"mt3d-usgs\",\n", - " )\n", - "\n", - " # Instantiate basic transport package\n", - " flopy.mt3d.Mt3dBtn(\n", - " mt,\n", - " icbund=1,\n", - " prsity=prsity,\n", - " sconc=sconc,\n", - " nper=nper,\n", - " perlen=perlen,\n", - " timprs=np.arange(1, 121),\n", - " dt0=0.05,\n", - " )\n", - "\n", - " # Instatiate the advection package\n", - " flopy.mt3d.Mt3dAdv(\n", - " mt,\n", - " mixelm=mixelm,\n", - " dceps=dceps,\n", - " nplane=nplane,\n", - " npl=npl,\n", - " nph=nph,\n", - " npmin=npmin,\n", - " npmax=npmax,\n", - " nlsink=nlsink,\n", - " npsink=npsink,\n", - " percel=percel,\n", - " itrack=itrack,\n", - " wd=wd,\n", - " )\n", - "\n", - " # Instantiate the dispersion package\n", - " if len(longitudinal_dispersivity) > 1:\n", - " disp = np.ones_like(ibound_mf2k5)\n", - " trpt = []\n", - " trpv = []\n", - " for i, (dispx, ratio1, ratio2) in enumerate(\n", - " zip(\n", - " longitudinal_dispersivity,\n", - " ratio_horizontal_to_longitudinal_dispersivity,\n", - " ratio_vertical_to_longitudinal_dispersivity,\n", - " )\n", - " ):\n", - " disp[i, :, :] = dispx\n", - " trpt.append(ratio1)\n", - " trpv.append(ratio2)\n", - " trpt = np.array(trpt)\n", - " trpv = np.array(trpv)\n", - " else:\n", - " # Dispersion\n", - " disp = longitudinal_dispersivity[0]\n", - " trpt = ratio_horizontal_to_longitudinal_dispersivity[0]\n", - " trpv = ratio_vertical_to_longitudinal_dispersivity[0]\n", - " flopy.mt3d.Mt3dDsp(mt, al=disp, trpt=trpt, trpv=trpv, dmcoef=dmcoef)\n", - "\n", - " # Instantiate source/sink mixing package; -1 below indicates constant\n", - " # concentration boundary condition (the form of this input is specific\n", - " # to MT3DMS and doesn't carry over to MF6)\n", - " cnc0_left = [(k, 0, 0, 0.0, 1) for k in range(0, nlay)]\n", - " cnc0_right = [(k, 0, ncol - 1, 0.0, 1) for k in range(0, nlay)]\n", - " cnc0 = cnc0_left + cnc0_right\n", - " ssmspd = {0: cnc0}\n", - " mxss = len(cnc0)\n", - " flopy.mt3d.Mt3dSsm(mt, mxss=mxss, stress_period_data=ssmspd)\n", - "\n", - " # Instantiate unsaturated zone tranport package\n", - " cuzinf = np.zeros((nrow, ncol), dtype=int)\n", - " cuzinf[0, 15:25] = 1.0\n", - " uzt = flopy.mt3d.Mt3dUzt(mt, iuzfbnd=iuzfbnd, iet=0, cuzinf=cuzinf)\n", - "\n", - " # Instantiate the GCG solver in MT3DMS\n", - " flopy.mt3d.Mt3dGcg(mt, iter1=2000, isolve=3, ncrs=1)\n", - "\n", - " # MODFLOW 6\n", - " print(f\"Building mf6gwt model...{sim_name}\")\n", - "\n", - " name = \"uzt-2d-mf6\"\n", - " gwfname = \"gwf-\" + name\n", - " sim_ws = os.path.join(ws, sim_name)\n", - " sim = flopy.mf6.MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name=mf6exe)\n", - "\n", - " # How much output to write?\n", - " from flopy.mf6.mfbase import VerbosityLevel\n", - "\n", - " sim.simulation_data.verbosity_level = VerbosityLevel.quiet\n", - " sim.name_file.memory_print_option = \"all\"\n", - "\n", - " # Instantiating MODFLOW 6 time discretization\n", - " tdis_rc = []\n", - " for i in range(nper):\n", - " tdis_rc.append((perlen[i], nstp[i], tsmult[i]))\n", - " flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_rc, time_units=time_units)\n", - "\n", - " # Instantiating MODFLOW 6 groundwater flow model\n", - " gwf = flopy.mf6.ModflowGwf(\n", - " sim,\n", - " modelname=gwfname,\n", - " save_flows=True,\n", - " newtonoptions=\"newton\",\n", - " model_nam_file=f\"{gwfname}.nam\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 solver for flow model\n", - " imsgwf = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " complexity=\"complex\",\n", - " no_ptcrecord=\"all\",\n", - " outer_dvclose=1.0e-4,\n", - " outer_maximum=2000,\n", - " under_relaxation=\"dbd\",\n", - " linear_acceleration=\"BICGSTAB\",\n", - " under_relaxation_theta=0.7,\n", - " under_relaxation_kappa=0.08,\n", - " under_relaxation_gamma=0.05,\n", - " under_relaxation_momentum=0.0,\n", - " backtracking_number=20,\n", - " backtracking_tolerance=2.0,\n", - " backtracking_reduction_factor=0.2,\n", - " backtracking_residual_limit=5.0e-4,\n", - " inner_dvclose=1.0e-5,\n", - " rcloserecord=\"0.0001 relative_rclose\",\n", - " inner_maximum=100,\n", - " relaxation_factor=0.0,\n", - " number_orthogonalizations=2,\n", - " preconditioner_levels=8,\n", - " preconditioner_drop_tolerance=0.001,\n", - " filename=f\"{gwfname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwf, [gwf.name])\n", - "\n", - " # Instantiating MODFLOW 6 discretization package\n", - " flopy.mf6.ModflowGwfdis(\n", - " gwf,\n", - " length_units=length_units,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwfname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 initial conditions package for flow model\n", - " flopy.mf6.ModflowGwfic(gwf, strt=strt, filename=f\"{gwfname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 node-property flow package\n", - " flopy.mf6.ModflowGwfnpf(\n", - " gwf,\n", - " save_flows=False,\n", - " icelltype=laytyp,\n", - " k=hk,\n", - " k33=hk33,\n", - " save_specific_discharge=True,\n", - " filename=f\"{gwfname}.npf\",\n", - " )\n", - "\n", - " # Instantiate storage package\n", - " flopy.mf6.ModflowGwfsto(\n", - " gwf,\n", - " ss=Ss,\n", - " sy=sy,\n", - " iconvert=iconvert,\n", - " filename=f\"{gwfname}.sto\",\n", - " )\n", - "\n", - " # Instantiate constant head package\n", - " chdspd = []\n", - " # Model domain is symmetric\n", - " for k in np.arange(nlay):\n", - " if botm[k] <= strt[k, 0, 0]:\n", - " # (l, r, c), head, conc\n", - " chdspd.append([(k, 0, 0), strt[k, 0, 0], 0.0])\n", - " chdspd.append([(k, 0, ncol - 1), strt[k, 0, ncol - 1], 0.0])\n", - " chdspd = {0: chdspd}\n", - " flopy.mf6.modflow.mfgwfchd.ModflowGwfchd(\n", - " gwf,\n", - " maxbound=len(chdspd),\n", - " stress_period_data=chdspd,\n", - " save_flows=False,\n", - " auxiliary=\"CONCENTRATION\",\n", - " pname=\"CHD-1\",\n", - " filename=f\"{gwfname}.chd\",\n", - " )\n", - "\n", - " # Instantiate unsaturated zone flow package\n", - " flopy.mf6.ModflowGwfuzf(\n", - " gwf,\n", - " nuzfcells=nuzfcells,\n", - " ntrailwaves=15,\n", - " nwavesets=40,\n", - " print_flows=True,\n", - " packagedata=packagedata,\n", - " perioddata=uzf_perioddata,\n", - " pname=\"UZF-1\",\n", - " budget_filerecord=f\"{gwfname}.uzf.bud\",\n", - " )\n", - "\n", - " # Instantiate output control package\n", - " flopy.mf6.ModflowGwfoc(\n", - " gwf,\n", - " budget_filerecord=f\"{gwfname}.bud\",\n", - " head_filerecord=f\"{gwfname}.hds\",\n", - " headprintrecord=[(\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")],\n", - " saverecord=[(\"HEAD\", \"ALL\"), (\"BUDGET\", \"ALL\")],\n", - " printrecord=[(\"HEAD\", \"LAST\"), (\"BUDGET\", \"ALL\")],\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 groundwater transport package\n", - " gwtname = \"gwt-\" + name\n", - " gwt = flopy.mf6.MFModel(\n", - " sim,\n", - " model_type=\"gwt6\",\n", - " modelname=gwtname,\n", - " model_nam_file=f\"{gwtname}.nam\",\n", - " )\n", - " gwt.name_file.save_flows = True\n", - "\n", - " # create iterative model solution and register the gwt model with it\n", - " imsgwt = flopy.mf6.ModflowIms(\n", - " sim,\n", - " print_option=\"summary\",\n", - " complexity=\"complex\",\n", - " no_ptcrecord=\"all\",\n", - " outer_dvclose=1.0e-4,\n", - " outer_maximum=2000,\n", - " under_relaxation=\"dbd\",\n", - " linear_acceleration=\"BICGSTAB\",\n", - " under_relaxation_theta=0.7,\n", - " under_relaxation_kappa=0.08,\n", - " under_relaxation_gamma=0.05,\n", - " under_relaxation_momentum=0.0,\n", - " backtracking_number=20,\n", - " backtracking_tolerance=2.0,\n", - " backtracking_reduction_factor=0.2,\n", - " backtracking_residual_limit=5.0e-4,\n", - " inner_dvclose=1.0e-5,\n", - " rcloserecord=\"0.0001 relative_rclose\",\n", - " inner_maximum=100,\n", - " relaxation_factor=0.0,\n", - " number_orthogonalizations=2,\n", - " preconditioner_levels=8,\n", - " preconditioner_drop_tolerance=0.001,\n", - " filename=f\"{gwtname}.ims\",\n", - " )\n", - " sim.register_ims_package(imsgwt, [gwt.name])\n", - "\n", - " # Instantiating MODFLOW 6 transport discretization package\n", - " flopy.mf6.ModflowGwtdis(\n", - " gwt,\n", - " nlay=nlay,\n", - " nrow=nrow,\n", - " ncol=ncol,\n", - " delr=delr,\n", - " delc=delc,\n", - " top=top,\n", - " botm=botm,\n", - " idomain=idomain,\n", - " filename=f\"{gwtname}.dis\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport initial concentrations\n", - " flopy.mf6.ModflowGwtic(gwt, strt=sconc, filename=f\"{gwtname}.ic\")\n", - "\n", - " # Instantiating MODFLOW 6 transport advection package\n", - " if mixelm >= 0:\n", - " scheme = \"UPSTREAM\"\n", - " elif mixelm == -1:\n", - " scheme = \"TVD\"\n", - " else:\n", - " raise Exception()\n", - " flopy.mf6.ModflowGwtadv(gwt, scheme=scheme, filename=f\"{gwtname}.adv\")\n", - "\n", - " # Instantiating MODFLOW 6 transport dispersion package\n", - " if len(longitudinal_dispersivity) > 1:\n", - " disp = np.ones_like(ibound_mf2k5)\n", - " ath1 = np.ones_like(ibound_mf2k5)\n", - " atv = np.ones_like(ibound_mf2k5)\n", - " for i, (dispx, ratio1, ratio2) in enumerate(\n", - " zip(\n", - " longitudinal_dispersivity,\n", - " ratio_horizontal_to_longitudinal_dispersivity,\n", - " ratio_vertical_to_longitudinal_dispersivity,\n", - " )\n", - " ):\n", - " disp[i, :, :] = dispx\n", - " ath1[i, :, :] = dispx * ratio1\n", - " atv[i, :, :] = dispx * ratio2\n", - " else:\n", - " # Dispersion\n", - " disp = longitudinal_dispersivity[0]\n", - " ath1 = (\n", - " longitudinal_dispersivity[0]\n", - " * ratio_horizontal_to_longitudinal_dispersivity[0]\n", - " )\n", - " atv = (\n", - " longitudinal_dispersivity[0]\n", - " * ratio_vertical_to_longitudinal_dispersivity[0]\n", - " )\n", - "\n", - " if al != 0:\n", - " flopy.mf6.ModflowGwtdsp(\n", - " gwt,\n", - " alh=disp,\n", - " ath1=ath1,\n", - " atv=atv,\n", - " pname=\"DSP-1\",\n", - " filename=f\"{gwtname}.dsp\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport mass storage package\n", - " flopy.mf6.ModflowGwtmst(\n", - " gwt,\n", - " porosity=prsity,\n", - " first_order_decay=False,\n", - " decay=None,\n", - " decay_sorbed=None,\n", - " sorption=None,\n", - " bulk_density=None,\n", - " distcoef=None,\n", - " pname=\"MST-1\",\n", - " filename=f\"{gwtname}.mst\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport source-sink mixing package\n", - " sourcerecarray = [(\"CHD-1\", \"AUX\", \"CONCENTRATION\")]\n", - " flopy.mf6.ModflowGwtssm(\n", - " gwt,\n", - " sources=sourcerecarray,\n", - " print_flows=True,\n", - " filename=f\"{gwtname}.ssm\",\n", - " )\n", - "\n", - " # Instantiate unsaturated zone transport package.\n", - " # * use iuzno to set the concentration of infiltrating water\n", - " # * only set the middle 10 cells at the top of the domain\n", - " # * first and last 15 cells have concentration of 0\n", - " pd0 = []\n", - " for i in range(14, 24):\n", - " pd0.append((i, \"INFILTRATION\", 1.0))\n", - " uztperioddata = {0: pd0}\n", - " flopy.mf6.modflow.ModflowGwtuzt(\n", - " gwt,\n", - " save_flows=True,\n", - " print_input=True,\n", - " print_flows=True,\n", - " print_concentration=True,\n", - " concentration_filerecord=gwtname + \".uzt.bin\",\n", - " budget_filerecord=gwtname + \".uzt.bud\",\n", - " packagedata=uztpackagedata,\n", - " uztperioddata=uztperioddata,\n", - " pname=\"UZF-1\",\n", - " filename=f\"{gwtname}.uzt\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 transport output control package\n", - " flopy.mf6.ModflowGwtoc(\n", - " gwt,\n", - " budget_filerecord=f\"{gwtname}.cbc\",\n", - " concentration_filerecord=f\"{gwtname}.ucn\",\n", - " concentrationprintrecord=[\n", - " (\"COLUMNS\", 10, \"WIDTH\", 15, \"DIGITS\", 6, \"GENERAL\")\n", - " ],\n", - " saverecord=[(\"CONCENTRATION\", \"ALL\")],\n", - " printrecord=[(\"CONCENTRATION\", \"LAST\"), (\"BUDGET\", \"ALL\")],\n", - " filename=f\"{gwtname}.oc\",\n", - " )\n", - "\n", - " # Instantiating MODFLOW 6 flow-transport exchange mechanism\n", - " flopy.mf6.ModflowGwfgwt(\n", - " sim,\n", - " exgtype=\"GWF6-GWT6\",\n", - " exgmnamea=gwfname,\n", - " exgmnameb=gwtname,\n", - " filename=f\"{name}.gwfgwt\",\n", - " )\n", - " return mf, mt, sim\n", - " return None" - ] - }, - { - "cell_type": "markdown", - "id": "d89d95c4", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to write model files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "739e1223", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def write_model(mf2k5, mt3d, sim, silent=True):\n", - " if config.writeModel:\n", - " mf2k5.write_input()\n", - " mt3d.write_input()\n", - " sim.write_simulation(silent=silent)" - ] - }, - { - "cell_type": "markdown", - "id": "33131248", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to run the model. True is returned if the model runs successfully." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b06d9637", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "@config.timeit\n", - "def run_model(mf2k5, mt3d, sim, silent=True):\n", - " success = True\n", - " if config.runModel:\n", - " success, buff = mf2k5.run_model(silent=silent)\n", - " success, buff = mt3d.run_model(silent=silent)\n", - " success, buff = sim.run_simulation(silent=silent)\n", - " if not success:\n", - " print(buff)\n", - " return success" - ] - }, - { - "cell_type": "markdown", - "id": "c5e30101", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "Function to plot the model results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3b86f466", - "metadata": { - "lines_to_next_cell": 2 - }, - "outputs": [], - "source": [ - "def plot_results(mf2k5, mt3d, mf6, idx, ax=None):\n", - " if config.plotModel:\n", - " print(\"Plotting model results...\")\n", - " mt3d_out_path = mt3d.model_ws\n", - " mf6_out_path = mf6.simulation_data.mfpath.get_sim_path()\n", - " mf6.simulation_data.mfpath.get_sim_path()\n", - "\n", - " # Get the MF-NWT heads\n", - " fname_mfnwt = os.path.join(mt3d_out_path, \"uzt-2d-mf.hds\")\n", - " hds_mfnwt = flopy.utils.HeadFile(fname_mfnwt)\n", - " hds = hds_mfnwt.get_alldata()\n", - " # Make list of verticies for plotting the saturated zone as a polygon\n", - " # Start by adding fixed locations\n", - " satzn = []\n", - " satzn.append([40 * delr, 0])\n", - " satzn.append([0 * delr, 0])\n", - " for j in range(ncol):\n", - " hd_in_col = hds[0, :, 0, j].max()\n", - " if j == 0:\n", - " satzn.append([j * delr, hd_in_col])\n", - " elif j == ncol - 1:\n", - " satzn.append([(j + 1) * delr, hd_in_col])\n", - " else:\n", - " satzn.append([(j * delr) + (delr / 2), hd_in_col])\n", - "\n", - " poly_pts = np.array(satzn)\n", - "\n", - " # Get the MT3DMS concentration output\n", - " fname_mt3d = os.path.join(mt3d_out_path, \"MT3D001.UCN\")\n", - " ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d)\n", - " times_mt3d = ucnobj_mt3d.get_times()\n", - " conc_mt3d = ucnobj_mt3d.get_alldata()\n", - "\n", - " # get the MODFLOW 6 results from the UZF package and the GWT model\n", - " gwt = mf6.get_model(\"gwt-uzt-2d-mf6\")\n", - " uzconc_mf6 = gwt.uzf.output.concentration().get_alldata()\n", - " mf6_satconc = gwt.output.concentration().get_alldata()\n", - "\n", - " uzconc_mf6_shpd = []\n", - " for i in np.arange(0, uzconc_mf6.shape[0]):\n", - " tmp = uzconc_mf6[i, 0, 0, :].reshape((20, 1, 38))\n", - " # insert column of np.nan on left and right sides of reshaped array\n", - " tmp2 = np.insert(tmp, 0, np.nan, axis=2)\n", - " tmp_apnd = np.empty((tmp2.shape[0], 1, 1))\n", - " tmp_apnd[:] = np.nan\n", - " tmp3 = np.append(tmp2, tmp_apnd, axis=2)\n", - " uzconc_mf6_shpd.append(tmp3)\n", - "\n", - " uzconc_mf6_shpd = np.array(uzconc_mf6_shpd)\n", - " i = 0\n", - " hds_bool = np.zeros_like(hds[0, :, i, :])\n", - " for k in range(nlay):\n", - " for j in range(ncol):\n", - " if hds[0, k, i, j] > ((nlay - 1) - k) * 0.25:\n", - " hds_bool[k, j] = 1\n", - "\n", - " combined_concs = np.where(\n", - " hds_bool > 0,\n", - " mf6_satconc[-1, :, 0, :],\n", - " uzconc_mf6_shpd[-1, :, 0, :],\n", - " )\n", - "\n", - " combined_conc_3d = combined_concs[np.newaxis, :, np.newaxis, :]\n", - "\n", - " contourLevels = np.arange(0.2, 1.01, 0.2)\n", - "\n", - " # Create figure for scenario\n", - " fs = USGSFigure(figure_type=\"graph\", verbose=False)\n", - " sim_name = mf6.name\n", - " plt.rcParams[\"lines.dashed_pattern\"] = [5.0, 5.0]\n", - "\n", - " axWasNone = False\n", - " if ax is None:\n", - " fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True)\n", - " ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n", - " axWasNone = True\n", - "\n", - " mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={\"row\": 0})\n", - " mx.plot_grid(color=\"0.5\", alpha=0.1)\n", - "\n", - " cs1 = mx.contour_array(\n", - " conc_mt3d[-1],\n", - " colors=\"k\",\n", - " linestyles=\"-\",\n", - " levels=contourLevels[0:4],\n", - " masked_values=[1.0e30],\n", - " )\n", - " plt.clabel(cs1, fmt=r\"%4.2f\")\n", - " plt.fill(poly_pts[:, 0], poly_pts[:, 1], alpha=0.2)\n", - " cs2 = mx.contour_array(\n", - " combined_conc_3d[0],\n", - " levels=contourLevels[0:4],\n", - " colors=\"red\",\n", - " linestyles=\"--\",\n", - " )\n", - " plt.clabel(cs2, fmt=r\"%4.2f\")\n", - "\n", - " labels = [\"MF-NWT/MT3D-USGS\", \"MODFLOW 6\"]\n", - " lines = [cs1.collections[0], cs2.collections[0]]\n", - " for x in np.linspace(0.25, 9.75, 11):\n", - " ax.arrow(\n", - " x,\n", - " 5.25,\n", - " 0.0,\n", - " -0.25,\n", - " head_width=0.05,\n", - " head_length=0.1,\n", - " fc=\"b\",\n", - " ec=\"b\",\n", - " clip_on=False,\n", - " length_includes_head=True,\n", - " )\n", - "\n", - " ax.arrow(0.25, 5.25, 9.5, 0.0, fc=\"b\", ec=\"b\", clip_on=False)\n", - " ax.annotate(\n", - " \"Infiltration = 0.10 m/day\",\n", - " xy=(0.025, 1.06),\n", - " xycoords=\"axes fraction\",\n", - " clip_on=False,\n", - " )\n", - " for x in np.linspace(3.75, 6.25, 6):\n", - " ax.arrow(\n", - " x,\n", - " 5.5,\n", - " 0.0,\n", - " -0.5,\n", - " head_width=0.05,\n", - " head_length=0.1,\n", - " fc=\"r\",\n", - " ec=\"r\",\n", - " clip_on=False,\n", - " length_includes_head=True,\n", - " )\n", - "\n", - " ax.arrow(3.75, 5.5, 2.5, 0.0, fc=\"b\", ec=\"r\", clip_on=False)\n", - " ax.annotate(\n", - " \"Concentration = 1.00 mg/L\",\n", - " xy=(0.38, 1.12),\n", - " xycoords=\"axes fraction\",\n", - " clip_on=False,\n", - " )\n", - " ax.legend(lines, labels, loc=\"upper left\")\n", - "\n", - " title = \"Unsaturated/saturated zone concentration X-section, time = 60 days\"\n", - " letter = chr(ord(\"@\") + idx + 1)\n", - " # fs.heading(letter=letter, heading=title)\n", - " plt.tight_layout()\n", - "\n", - " # save figure\n", - " if config.plotSave:\n", - " fpth = os.path.join(\n", - " \"..\",\n", - " \"figures\",\n", - " \"{}{}\".format(\n", - " sim_name,\n", - " config.figure_ext,\n", - " ),\n", - " )\n", - " fig.savefig(fpth)" - ] - }, - { - "cell_type": "markdown", - "id": "ef2b0860", - "metadata": { - "lines_to_next_cell": 2 - }, - "source": [ - "### Function that wraps all of the steps for each MT3DMS Example 10 Problem scenario\n", - "\n", - "1. build_model,\n", - "2. write_model,\n", - "3. run_model, and\n", - "4. plot_results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "00e75b40", - "metadata": {}, - "outputs": [], - "source": [ - "def scenario(idx, silent=True):\n", - " key = list(parameters.keys())[idx]\n", - " parameter_dict = parameters[key]\n", - " mf2k5, mt3d, sim = build_model(key, mixelm=mixelm, **parameter_dict)\n", - "\n", - " write_model(mf2k5, mt3d, sim, silent=silent)\n", - " success = run_model(mf2k5, mt3d, sim, silent=silent)\n", - " if success:\n", - " plot_results(mf2k5, mt3d, sim, idx)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cbcbc473", - "metadata": {}, - "outputs": [], - "source": [ - "# nosetest - exclude block from this nosetest to the next nosetest\n", - "def test_01():\n", - " scenario(0, silent=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c6b21293", - "metadata": {}, - "outputs": [], - "source": [ - "def test_02():\n", - " scenario(1, silent=True)" - ] - }, - { - "cell_type": "markdown", - "id": "70e30a34", - "metadata": {}, - "source": [ - "nosetest end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1ffa424f", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # ### Two-Dimensional Transport in a Diagonal Flow Field\n", - " #\n", - " # Compares the standard finite difference solutions between MT3D & MF 6\n", - " scenario(0, silent=True)\n", - "\n", - " scenario(1, silent=True)" - ] - } - ], - "metadata": { - "jupytext": { - "cell_metadata_filter": "-all", - "main_language": "python", - "notebook_metadata_filter": "-all" - }, - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -}